Files
2026-06-09 21:06:27 +01:00

5.5 KiB

@suaveplan/api-events-in-memory - In-memory EventsBus adapter for the @suaveplan/api testing kit. Wraps @suaveplan/events' EventBus with a per-topic recording layer so tests can assert that side-effect publishes happened. Exposes published(topic) and reset() helpers, options-bounded history with EVENTS_IN_MEMORY.HISTORY_OVERFLOW protection, Zod-validated options at the boundary, and a small waitFor harness for async assertions. No mocks — the real production bus delivers events to subscribers; this adapter only records publish history.

In-memory events bus adapter for the @suaveplan/api testing kit. Wraps @suaveplan/events' production EventBus with a per-topic recording layer so tests can assert that side-effect publishes happened, without booting cross-process IPC and without mocks. The real bus delivers events to subscribers; this adapter only adds a queryable publish history.

Documentation tree

  • bus — createInMemoryEventsBus is the factory entry point of @suaveplan/api-events-in-memory. It returns a fresh {@link In…
    • bus — createInMemoryEventsBus is the factory entry point of @suaveplan/api-events-in-memory. It returns a fresh {@link In…
  • error-codes — The error-code registry pins the two failure modes that the in-memory events bus exposes to test code. Together they le…
    • error-codes — The error-code registry pins the two failure modes that the in-memory events bus exposes to test code. Together they le…
  • history — History is the per-topic append-only payload store that backs bus.published(topic). Each publish invocation appen…
    • history — History is the per-topic append-only payload store that backs bus.published(topic). Each publish invocation appen…
  • options — The options module is the single boundary at which user-supplied configuration enters the in-memory events bus. It owns…
    • options — The options module is the single boundary at which user-supplied configuration enters the in-memory events bus. It owns…
  • testing — The testing harness packages an {@link InMemoryEventsBus} with a waitFor helper for tests that publish asynchronously…
    • testing — The testing harness packages an {@link InMemoryEventsBus} with a waitFor helper for tests that publish asynchronously…

Why

Per the API Plugin Foundation design (§13.2), the testing kit needs an events bus whose publishes are observable from the test code:

import { createInMemoryEventsBus } from "@suaveplan/api-events-in-memory";

const bus = createInMemoryEventsBus();

// app code under test
bus.publish("billing.invoice.created", { invoiceId: "inv_1", amount: 100 });

// test
expect(bus.published("billing.invoice.created")).toHaveLength(1);

The simplest correct implementation wraps the production bus and adds a recording layer around publish / publishAsync. Subscribers fire as usual; ordering and FIFO invariants from the real bus are preserved.

Install

bun add -d @suaveplan/api-events-in-memory

Surface

  • ./ — createInMemoryEventsBus, createInMemoryEventBus (alias), InMemoryEventsBus, History, error codes, options.
  • ./bus (a.k.a. ./adapter) — factory + types only.
  • ./testing — createInMemoryEventsBusHarness with a waitFor helper for async assertions.
  • ./error-codes — EVENTS_IN_MEMORY_CODES + EventsInMemoryError.
  • ./options — Zod schema + resolveInMemoryEventsBusOptions.
  • ./history — standalone history ring (used by the bus internally).

Quick reference

import { createInMemoryEventsBus } from "@suaveplan/api-events-in-memory";
import { createInMemoryEventsBusHarness } from "@suaveplan/api-events-in-memory/testing";

const bus = createInMemoryEventsBus({ maxHistoryPerTopic: 100 });
bus.on("user.signup", (payload) => doStuff(payload));
await bus.publishAsync("user.signup", { userId: "u1" });
expect(bus.published("user.signup")).toEqual([{ userId: "u1" }]);

const harness = createInMemoryEventsBusHarness();
await harness.waitFor((b) => b.published("welcome.email").length === 1);
harness.dispose();

Options

Option Default Notes
maxHistoryPerTopic 1000 Strict-throw cap; publish raises HISTORY_OVERFLOW past the cap

Invalid options raise EVENTS_IN_MEMORY.INVALID_OPTIONS with the underlying z.ZodError on cause.

Error codes

Code Raised when
EVENTS_IN_MEMORY.HISTORY_OVERFLOW publish would exceed maxHistoryPerTopic
EVENTS_IN_MEMORY.INVALID_OPTIONS factory options fail Zod validation

Out of scope

  • Persistence across process restarts — by design, in-memory.
  • Multi-host fan-out — see future api-events-redis.
  • Bounded-queue backpressure — @suaveplan/events already provides this and the in-memory adapter inherits it through delegation.

License

MIT — Suaveplan Team.