UNPKG

opinionated-machine

Version:

Very opinionated DI framework for fastify, built on top of awilix

79 lines 3.04 kB
import { AbstractSSEController } from "../sse/AbstractSSEController.js"; /** * Abstract base class for dual-mode controllers. * * Dual-mode controllers handle both SSE streaming and sync responses on the * same route path, automatically branching based on the `Accept` header. * * This class extends `AbstractSSEController` to reuse connection management, * broadcasting, and lifecycle hooks for the SSE mode. * * @template APIContracts - Map of route names to dual-mode route definitions * * @example * ```typescript * class ChatController extends AbstractDualModeController<typeof contracts> { * public static contracts = { * chatCompletion: buildSseContract({ requestBodySchema: ..., successResponseBodySchema: ..., ... }), * } as const * * constructor(deps: Dependencies, config?: DualModeControllerConfig) { * super(deps, config) * } * * public buildDualModeRoutes() { * return { * chatCompletion: this.handleChatCompletion, * } * } * * private handleChatCompletion = buildHandler(ChatController.contracts.chatCompletion, { * sync: async (request, reply) => { * // Return complete response * return { reply: 'Hello', usage: { tokens: 5 } } * }, * sse: async (request, sse) => { * // Stream SSE events with autoClose mode * const session = sse.start('autoClose') * await session.send('chunk', { delta: 'Hello' }) * await session.send('done', { usage: { total: 5 } }) * // Connection closes automatically when handler returns * }, * }) * } * ``` */ export class AbstractDualModeController extends AbstractSSEController { /** * Dual-mode controllers must override this constructor and call super with their * dependencies object and the dual-mode config. * * @param _dependencies - The dependencies object (cradle proxy in awilix) * @param config - Optional dual-mode controller configuration */ constructor(_dependencies, config) { // Pass config to AbstractSSEController (it accepts SSEControllerConfig which has the same shape) super(_dependencies, config); } /** * SSE routes are not used directly - dual-mode uses buildDualModeRoutes() instead. * This returns an empty object to satisfy the AbstractSSEController contract. */ buildSSERoutes() { return {}; } /** * Send an event to a connection with type-safe event names and data. * * This method provides autocomplete and type checking for event names and data * that match any event defined in the controller's dual-mode contracts. * * @param connectionId - The connection to send to * @param message - The event message with typed event name and data * @returns true if sent successfully, false if connection not found */ sendDualModeEventInternal(connectionId, message) { return this._sendEventRaw(connectionId, message); } } //# sourceMappingURL=AbstractDualModeController.js.map