# Gateway internal dep factory ## Purpose Centralises the cross-module dependency-bundle construction the daemon needs once at construction time. Without this module the gateway class re-builds `RoomOpsDeps`, `ChannelOpsDeps`, and `ClientLifecycleDeps` inline at every public method, blowing the file's line count past the 300-line cap. The factory builds every dep bundle once and the daemon caches the references. ## Features - One pure factory function (`buildGatewayDepFactories`) returning every bundle the daemon needs. - Helper builders (`buildRunGate`, `buildFirePresence`, `buildEmit`, `buildRequireAuthCtx`) exposed individually for unit tests that want to wire a sub-bundle without a full daemon. - The synthetic auth-context fallback inside `buildRequireAuthCtx` is captured here so tests can drive ops paths without going through the full handshake. ## Usage: Basic Example ```ts import { buildGatewayDepFactories } from "@suaveplan/websocket-gateway"; const factories = buildGatewayDepFactories({ state, resolved, clock, authContexts, idempotency, }); ``` ## Usage: Advanced Example ```ts import { buildEmit, buildFirePresence, buildGatewayDepFactories, buildRequireAuthCtx, buildRunGate, } from "@suaveplan/websocket-gateway"; const emit = buildEmit(internals); const runGate = buildRunGate(internals); const fire = buildFirePresence(internals); const requireAuthCtx = buildRequireAuthCtx(internals); // Wire each builder individually when testing one op path in isolation. ``` ## API Reference - `GatewayInternals` — state + resolved-config + idempotency-guard snapshot the factory needs. - `GatewayDepFactories` — the four dep bundles the daemon hands to the op modules. - `buildGatewayDepFactories(internals): GatewayDepFactories` - `buildRunGate(internals): (ctx, action) => Promise` - `buildFirePresence(internals): (kind, clientId, roomId, status) => Promise` - `buildEmit(internals): (topic, payload) => void` - `buildRequireAuthCtx(internals): (clientId) => AuthContext` ## Implementation Notes The factory closes over `internals.state` and `internals.resolved` by reference, so when the daemon mutates either, the dep bundles stay current — there is no per-call re-bundle cost beyond what the constructor pays once. The synthetic auth-context fallback uses `internals.authContexts` rather than holding its own state because every consumer (including the public `getAuthContext` method) shares the same lookup table.