Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# @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.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [bus](./src/bus/bus.md) — `createInMemoryEventsBus` is the factory entry point of `@suaveplan/api-events-in-memory`. It returns a fresh {@link In…
|
||||
- [bus](./src/bus/bus.md) — `createInMemoryEventsBus` is the factory entry point of `@suaveplan/api-events-in-memory`. It returns a fresh {@link In…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — The error-code registry pins the two failure modes that the in-memory events bus exposes to test code. Together they le…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — The error-code registry pins the two failure modes that the in-memory events bus exposes to test code. Together they le…
|
||||
- [history](./src/history/history.md) — `History` is the per-topic append-only payload store that backs `bus.published(topic)`. Each `publish` invocation appen…
|
||||
- [history](./src/history/history.md) — `History` is the per-topic append-only payload store that backs `bus.published(topic)`. Each `publish` invocation appen…
|
||||
- [options](./src/options/options.md) — The options module is the single boundary at which user-supplied configuration enters the in-memory events bus. It owns…
|
||||
- [options](./src/options/options.md) — The options module is the single boundary at which user-supplied configuration enters the in-memory events bus. It owns…
|
||||
- [testing](./src/testing/testing.md) — The testing harness packages an {@link InMemoryEventsBus} with a `waitFor` helper for tests that publish asynchronously…
|
||||
- [testing](./src/testing/testing.md) — The testing harness packages an {@link InMemoryEventsBus} with a `waitFor` helper for tests that publish asynchronously…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Why
|
||||
|
||||
Per the API Plugin Foundation design (§13.2), the testing kit needs an
|
||||
events bus whose publishes are observable from the test code:
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user