62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import type { RouteSendOptions, RouteStream } from '../routes/types.ts';
|
|
import type { BaseStream } from './stream/base-stream.ts';
|
|
|
|
/**
|
|
* Binds one application request to a connection-level stream.
|
|
*
|
|
* Request correlation remains immutable even when multiple WebSocket handlers
|
|
* execute concurrently. The underlying connection remains available to
|
|
* connection-level services such as the broadcaster.
|
|
*/
|
|
export class ApplicationRouteStream implements RouteStream {
|
|
/**
|
|
* @param connection - Shared transport stream backing this request.
|
|
* @param body - Transport-decoded application payload for the route handler.
|
|
* @param requestId - Optional correlation ID for multiplexed transports.
|
|
*/
|
|
constructor(
|
|
readonly connection: BaseStream,
|
|
readonly body: unknown,
|
|
private readonly requestId?: string,
|
|
) {}
|
|
|
|
/** Whether the underlying connection can deliver server-pushed events. */
|
|
get streaming(): boolean {
|
|
return this.connection.streaming;
|
|
}
|
|
|
|
/** Whether the underlying connection supports later unsubscribe requests. */
|
|
get bidirectional(): boolean {
|
|
return this.connection.bidirectional;
|
|
}
|
|
|
|
/**
|
|
* Send a response or event envelope through the shared connection.
|
|
*
|
|
* @param data - Response body or event payload.
|
|
* @param options - Controls message type and HTTP status for responses.
|
|
*/
|
|
async send(data: unknown, options: RouteSendOptions = {}): Promise<void> {
|
|
const type = options.type ?? 'response';
|
|
|
|
// Route responses carry an HTTP status and optional correlation ID.
|
|
if (type === 'response') {
|
|
await this.connection.send({
|
|
...(this.requestId === undefined ? {} : { id: this.requestId }),
|
|
type,
|
|
statusCode: options.statusCode ?? (data === undefined ? 204 : 200),
|
|
body: data ?? null,
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
// Non-response messages are application events with a neutral envelope.
|
|
await this.connection.send({
|
|
...(this.requestId === undefined ? {} : { id: this.requestId }),
|
|
type,
|
|
data,
|
|
});
|
|
}
|
|
}
|