# `subscriptions.ts` _(no submodules)_ ## Purpose Bridges the `WsBroker` contract from `@suaveplan/api-ws` to GraphQL `Subscription` resolvers via `AsyncIterable`. 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` 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 & { close(): Promise }`. ## 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.