npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@venn-lang/mock

v0.9.0

Published

The mock namespace: named mocks, HTTP interceptors, feature flags and a virtual clock.

Readme

@venn-lang/mock

The mock namespace: named mocks, HTTP interceptors, feature flags and a virtual clock.

Eight verbs writing to one in-process state object, which the runner hands back at the start of every flow, so what a flow pretends is true belongs to that flow. There is no port and no network here: the whole package is a typed way to record what a run should pretend, and a way to read that record back from TypeScript.

Install

The package ships with the stdlib, so the CLI already loads it. Inside a .vn file, bring the namespace in with import:

import { mock } from "venn/mock"

Usage

module demo.checkout

import { mock } from "venn/mock"

setup {
  mock.start "payments" { from: "./mocks/stripe.yaml" }
  mock.intercept "POST" "**/charge" { respond: { status: 201, body: { id: "ch_1" } } }
  mock.flag "new-checkout"
  mock.flag "rollout" { value: 0.5 }
}

teardown { mock.reset }

flow "Checkout" {
  step "hold time still" {
    mock.clock.freeze 2026-07-23T12:00:00Z
    let now = mock.clock.advance 1h
    expect now > 0
  }
}

Verbs

| Verb | Positional arguments | Options | Result | | --- | --- | --- | --- | | mock.start | name: string | from | mock.Mock | | mock.stop | none | none | void | | mock.intercept | method: string, url: string | respond | mock.Interceptor | | mock.respond | status: number, body: dynamic | status, body | mock.Response | | mock.clock.freeze | at: string \| number \| instant | none | number, epoch ms | | mock.clock.advance | by: string \| number \| duration | none | number, the new virtual now | | mock.flag | name: string | value | dynamic, the value that was set | | mock.reset | none | none | void |

Notes that matter in practice:

  • mock.stop clears the registered mocks and interceptors but leaves flags and the clock alone. mock.reset clears everything, including the frozen instant.
  • mock.flag "x" with no value sets the flag to true.
  • mock.respond accepts its two values positionally or by name, so mock.respond 201 { body: { ok: true } } and mock.respond { status: 201, body: { ok: true } } record the same thing. The respond option of mock.intercept takes either a full { status, body } map or a bare value, which is wrapped as a 200.
  • The clock verbs read the language's own literals. mock.clock.freeze 2026-07-23T12:00:00Z and mock.clock.advance 1h pass an instant and a duration value, not strings, and both are understood. An ISO string or a raw millisecond count works too.
  • Freezing records the instant in mock state. It does not drive the host clock, and no other stdlib plugin reads the interceptors yet: the state is a record, and TypeScript is what reads it.
  • Option names come from each verb's schema, so a typo is VN3001 with a "did you mean" hint before the flow runs.

Types

| Name | Shape | | --- | --- | | mock.Mock | { name: string, from?: string } | | mock.Interceptor | { method: string, path: string, respond: mock.Response } | | mock.Response | { status: number, body: dynamic } |

Reading the state back

Every verb reads and writes one MockState, replaced at the start of every flow. A test that drives the plugin from TypeScript inspects it directly:

import { getMockState, resetMockState } from "@venn-lang/mock";

resetMockState();
// ... run the flow ...
const state = getMockState();
state.flags.get("new-checkout"); // true
state.intercepts[0]?.respond; // { status: 201, body: { id: "ch_1" } }
state.frozenInstant; // epoch ms, or undefined while the clock is live

resetMockState() replaces the state with a fresh one, which is exactly what the mock.reset verb does and what the plugin hands the runner as its atFlowStart. Call it in a beforeEach so one test's flags never reach the next.

API

| Export | What it is | | --- | --- | | mockPlugin (also the default export) | The PluginDefinition: namespace mock, no required capability, eight actions. | | mockActions | The action list, in registration order. | | getMockState() | The live MockState the verbs read and write, one flow at a time. | | resetMockState() | Replaces it with a fresh, empty state. | | createMockState() | Builds a fresh, empty state without touching the shared one. | | MockState, NamedMock, Interceptor, MockResponse | Types only. |

See also