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,70 @@
# `subscriptions.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Bridges the `WsBroker` contract from `@suaveplan/api-ws` to GraphQL
`Subscription` resolvers via `AsyncIterable<Payload>`. The Yoga engine
wires `graphql-ws` over the host's already-mounted WebSocket transport;
this module is the per-subscription helper that converts a broker `topic`
+ `tenant` pair into an iterator the engine can consume.
Tenant filtering is enforced at the bridge: only `BrokerEnvelope` items
whose `tenant === tenantArg` reach the GraphQL iterator. Closing the
iterator (`return()` or the explicit `close()` method) calls
`subscription.unsubscribe()` on the broker so the WS slot is released
within one tick.
## Features
- Returns `AsyncIterable<Payload>` with an explicit `close()` accessor.
- Queues payloads when no consumer is awaiting; resolves immediately when
a consumer is parked.
- Calls `GraphqlYogaError("SUBSCRIPTION_TRANSPORT_UNAVAILABLE")` when the
host hands a `null` broker, satisfying the design doc §10.4 contract.
## Usage: Basic
```ts
import { createInMemoryWsBroker } from "@suaveplan/api-ws-broker-in-memory";
import { subscribeBrokerTopic } from "@suaveplan/api-graphql-yoga";
const broker = createInMemoryWsBroker();
const iterable = subscribeBrokerTopic(
broker,
"billing.invoice.created",
"tenant-a" as never
);
for await (const event of iterable) {
console.log(event);
break;
}
await iterable.close();
```
## Usage: Advanced
```ts
import { subscribeBrokerTopic } from "@suaveplan/api-graphql-yoga";
const subscription = {
invoiceCreated(_parent: unknown, _args: unknown, ctx: { broker: never; tenantId: never }) {
return subscribeBrokerTopic(ctx.broker, "billing.invoice.created", ctx.tenantId);
},
};
```
## API Reference
- `subscribeBrokerTopic(broker, topic, tenant)` — returns
`AsyncIterable<Payload> & { close(): Promise<void> }`.
## Implementation Notes
The internal `queue` + `waiters` arrays form a simple bounded mailbox.
Backpressure (queue cap, drop oldest, etc.) is intentionally not modelled
here — the in-memory broker enforces its own bounds, and the Redis broker
will inherit the same back-end contract.