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

@playfast/reform-proof

v1.0.1

Published

Headless testing toolkit for reform — drive a scene's compositions and assert on the props they compute, with no DOM, timers, or text matching.

Readme

@playfast/reform-proof

A headless testing toolkit for reform. Drive a scene's compositions and assert on what they compute — deterministically, with no DOM, no timers, and no text matching.

npm license built with Effect


A reform scene is renderer-neutral, so it can be exercised without a host. @playfast/reform-proof runs that same scene against a capturing UI: it dispatches typed events, settles the engine, and lets you assert on the props a composition computed — pure data, never rendered markup. The scene you prove is the exact scene @playfast/reform-react renders, so there is no seam between a passing test and production behavior.

Install

bun add -d @playfast/reform-proof @playfast/reform effect react

Peers: effect, react (^19), and @playfast/reform.

Quick start

A proof binds a human-readable requirement to a composition, then implements it as a generator that drives the scene's app facade:

import { Layer } from 'effect'
import { scene } from '@playfast/reform'
import { Product, Proof, ProductRequirement, expect } from '@playfast/reform-proof'
import { Counter } from './counter.compose'
import { CounterLive } from './counter.layer'

const CounterScene = scene(Counter, { provide: [CounterLive] })

class Bumps extends ProductRequirement.make(Counter, 'bumps the count') {}

const bumps = Proof.implement(Bumps, CounterScene, function* (app) {
  yield* app.actions.bump({})         // dispatch a contract event, settle
  const props = yield* app.props      // read what the composition computed
  yield* expect(props.count).toBe(1)
})

const product = Product.make(Counter, { requirements: [Bumps] })
const suite = Proof.suite(product, { proofs: [bumps] })

const result = await Proof.run(suite)  // { product, results, ok }

The workflow

| step | API | | --- | --- | | Declare a requirement | ProductRequirement.make(composition, statement) | | Group requirements | Product.make(composition, { requirements }) | | Implement a proof | Proof.implement(requirement, scene, function* (app) { … }) | | Compose a suite | Proof.suite(product, { proofs }) | | Run it | Proof.run(suite) → Promise<SuiteResult> | | Step it (for tooling) | Proof.driver(suite) → ProofDriver[] |

The statement is a string-literal type, matched at Proof.implement so a requirement's name and its proof can never drift apart.

The facade

Inside a proof body, app is a typed handle derived from the composition's UI contract:

  • yield* app.actions.<event>(payload) — dispatch a contract event and settle.
  • yield* app.props — re-render and return the latest computed props struct.
  • yield* app.slots.<name>.first / .at(i) / .all — descend into child composition facades; a slot used directly defaults to its first instance.
  • yield* app.frame — force a settle (re-render and wait for engine stability).

Assertions are Effects: expect(actual).toBe(…), .toEqual(…), .toContain(…). Mis-targeting a contract surfaces as a tagged failure — UnknownAction, UnknownSlot, or AssertionFailed — rather than an undefined read.

Why it's deterministic

There is no real clock. settle cooperatively drains forked fibers and loops until the render tree reaches a two-frame fixpoint, so genuinely async flows (queries, procedures, remote state) resolve without flakiness from timing races. Proof.driver exposes the same run one frame at a time, capturing what each step saw — which is what powers the editor's test-play timeline.

The reform family

Core @playfast/reform · hosts @playfast/reform-react / @playfast/reform-react-native · forms @playfast/reform-forms + @playfast/reform-forms-react

License

MIT