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

@nwire/test-chaos

v0.9.2

Published

Chaos + failure-mode scenario suite for Nwire — proves the framework degrades gracefully under stress.

Readme

@nwire/test-chaos

Chaos + failure-mode scenarios for Nwire. Every scenario boots a real createApp + real Runtime + in-memory adapters, then asserts on runtime.onTelemetry records to prove the framework degrades gracefully.

The runtime is never mocked — this package answers "did the framework actually handle this gracefully?", not "did the mock that we wired up fire?".

Running

pnpm vitest packages/nwire-test-chaos

Or run the whole repo suite with pnpm test. The chaos suites are normal vitest files and contribute to the global green bar.

What each scenario proves

| File | Failure mode | Invariant verified | | ------------------------------ | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | slow-handler.test.ts | Handler resolves after long delay; caller aborts early | Caller-side abort doesn't leak; background dispatch completes cleanly; next dispatch on same actor proceeds with up-to-date state; handler that observes ctx.signal bails fast with no DLQ | | crashed-workflow.test.ts | Workflow body throws inside on() | reaction.failed emits with correlationId; error re-raises; other actions unaffected; declared WorkflowRetryPolicy honored and reaction.exhausted emits on final failure | | partial-publish.test.ts | bus.publish() rejects after local commit | Actor + projection state persist; error propagates; recovery path exists | | queue-replay-storm.test.ts | 1000 concurrent dispatches; same-key race | Every event processed; per-correlation-key FIFO order preserved; memory bounded; per-(actor, key, tenant) lock serializes same-key concurrent dispatches | | dlq-explosion.test.ts | Every handler throws | DLQ accepts N records in order; runtime stays responsive to healthy actions | | retry-exhaustion.test.ts | retry: { max: 3 } + always-throwing handler | Exactly 4 attempts; attempt-numbered telemetry; one DLQ entry; before/after hooks fire at the dispatch boundary, not the retry boundary | | idempotency-boundary.test.ts | Same event published twice with same messageId | Apply exactly once; event.deduped telemetry emits on the second delivery; works on both publish and applyExternalEvent paths | | projection-drift.test.ts | Projection reducer throws mid-batch | Drift is observable via actor.transitioned count > projection.folded; projection rebuilds from event log; projection.failed telemetry emits when a reducer throws |

Framework gaps surfaced by this suite

All five gaps documented in earlier revisions of this README are closed (Phase 66). Each scenario file calls the corresponding new contract directly; see repo CHANGELOG.md ([Unreleased]) for the forge changes per gap.

The closed gaps (kept here as a reference for what each scenario now asserts):

  1. HandlerContext.signal — handlers may observe caller-side cancellation via ctx.signal.throwIfAborted(). The runtime checks signal.aborted between retry attempts and skips remaining retries
    • DLQ when the caller has given up.
  2. WorkflowRetryPolicy honoreddefineWorkflow(name, closure, { retry: { max, backoff, baseDelayMs, maxDelayMs } }) retries the saga's _fire per the same back-off math dispatch() uses for actions; final failure emits reaction.exhausted.
  3. Envelope-level idempotencyruntime.idempotencyStore (default InMemoryIdempotencyStore) dedups by envelope.messageId on both the in-process publish path and the bus inbound applyExternalEvent path. Duplicates emit event.deduped.
  4. projection.failed telemetry — the runtime wraps each projection fold in try/catch, emits a first-class projection.failed record on throw, and re-raises so the apply path still fails fast.
  5. Per-key actor lockActorStore.lockKey?(actor, key, tenant) gives the runtime a serialization seam around load → reduce → save. InMemoryActorStore implements it via a per-key Promise chain; persistent adapters (Mongo, file, future SQL) ship a no-op + TODO for storage-native locking.

Adding a new scenario

  1. Create src/scenarios/<verb-noun>.test.ts.
  2. Use harness({ app }) from @nwire/test-kit and defineApp(...) from @nwire/forge. Boot one app per it() block so tests stay isolated.
  3. Compose any helpers you need from src/helpers.ts (or add new ones there + export from src/index.ts).
  4. Assert on h.telemetry.count(kind, predicate) and h.telemetry.ofKind(kind). The telemetry stream is the framework's source of truth for "did this work?".
  5. If your scenario relies on a contract the framework doesn't honor today, mark the it() with .skip and document the gap in a comment — never break CI on a known gap. Add a row to the gaps table above.

Helpers (re-exported from the package)

  • slowHandler(action, { ms, emit? }) — delays then emits.
  • failingHandler(action, { message? }) — throws on every dispatch.
  • flakyHandler(action, { throwTimes, emit? }) — throws N times then succeeds.
  • crashingWorkflow(message?) — workflow closure factory that throws.
  • countingHandler(action, emit?) — records every call + input.
  • rejectOnPublishBus(innerBus, error?) — wraps an EventBus so .publish() rejects until release() is called.

License

MIT