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:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -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.