import { t as Interceptor } from "../../interceptor-dtJZ_9QT.js"; import { TypedEvent } from "rettime"; //#region src/events/websocket.d.ts /** * The connection information. */ interface WebSocketConnectionInfo { /** * The protocols supported by the WebSocket client. */ protocols: string | Array | undefined; } /** * An intercepted WebSocket connection: the client and the server handles. * * @note Typed against the handles, not the connection classes, * so that a connection living anywhere (in this process, in another * runtime, or in a custom implementation) can be given to whoever * consumes intercepted connections (e.g. a handler). */ interface WebSocketConnectionEventData { /** * The incoming WebSocket client connection. */ client: WebSocketClientHandle; /** * The original WebSocket server connection. */ server: WebSocketServerHandle; info: WebSocketConnectionInfo; } /** * The connection intercepted by the `WebSocketInterceptor`: * both the client and the server live in this process. */ interface WebSocketInterceptedConnection extends WebSocketConnectionEventData { client: WebSocketClientConnection; server: WebSocketServerConnection; } declare class WebSocketConnectionEvent extends TypedEvent, void, 'connection'> implements WebSocketInterceptedConnection { client: WebSocketClientConnection; server: WebSocketServerConnection; info: WebSocketConnectionInfo; constructor(data: WebSocketInterceptedConnection); } type WebSocketEventMap$1 = { connection: WebSocketConnectionEvent & Extension; }; //#endregion //#region src/interceptors/WebSocket/utils/events.d.ts declare const kCancelable: unique symbol; declare const kDefaultPrevented: unique symbol; /** * A `MessageEvent` superset that supports event cancellation * in Node.js. It's rather non-intrusive so it can be safely * used in the browser as well. * * @see https://github.com/nodejs/node/issues/51767 */ declare class CancelableMessageEvent extends MessageEvent { [kCancelable]: boolean; [kDefaultPrevented]: boolean; constructor(type: string, init: MessageEventInit); get cancelable(): boolean; set cancelable(nextCancelable: boolean); get defaultPrevented(): boolean; set defaultPrevented(nextDefaultPrevented: boolean); preventDefault(): void; } interface CloseEventInit extends EventInit { code?: number; reason?: string; wasClean?: boolean; } declare class CloseEvent extends Event { code: number; reason: string; wasClean: boolean; constructor(type: string, init?: CloseEventInit); } declare class CancelableCloseEvent extends CloseEvent { [kCancelable]: boolean; [kDefaultPrevented]: boolean; constructor(type: string, init?: CloseEventInit); get cancelable(): boolean; set cancelable(nextCancelable: boolean); get defaultPrevented(): boolean; set defaultPrevented(nextDefaultPrevented: boolean); preventDefault(): void; } //#endregion //#region src/interceptors/WebSocket/web-socket-transport.d.ts type WebSocketData = string | ArrayBuffer | Blob | ArrayBufferView; type WebSocketTransportEventMap = { incoming: MessageEvent; outgoing: MessageEvent; close: CloseEvent; }; type StrictEventListenerOrEventListenerObject = ((this: WebSocket, event: EventType) => void) | { handleEvent(this: WebSocket, event: EventType): void; }; interface WebSocketTransport { addEventListener(event: EventType, listener: StrictEventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void; dispatchEvent(event: WebSocketTransportEventMap[EventType]): boolean; /** * Send the data from the server to this client. */ send(data: WebSocketData): void; /** * Close the client connection. */ close(code?: number, reason?: string): void; } //#endregion //#region src/interceptors/WebSocket/web-socket-override.d.ts type WebSocketEventListener = (this: WebSocket, event: EventType) => void; declare const kPassthroughPromise: unique symbol; declare const kOnSend: unique symbol; declare const kClose: unique symbol; declare class WebSocketOverride extends EventTarget implements WebSocket { static readonly CONNECTING = 0; static readonly OPEN = 1; static readonly CLOSING = 2; static readonly CLOSED = 3; readonly CONNECTING = 0; readonly OPEN = 1; readonly CLOSING = 2; readonly CLOSED = 3; url: string; protocol: string; extensions: string; binaryType: BinaryType; readyState: WebSocket['readyState']; bufferedAmount: number; private _onopen; private _onmessage; private _onerror; private _onclose; private [kPassthroughPromise]; private [kOnSend]?; constructor(url: string | URL, protocols?: string | Array); set onopen(listener: WebSocketEventListener | null); get onopen(): WebSocketEventListener | null; set onmessage(listener: WebSocketEventListener> | null); get onmessage(): WebSocketEventListener> | null; set onerror(listener: WebSocketEventListener | null); get onerror(): WebSocketEventListener | null; set onclose(listener: WebSocketEventListener | null); get onclose(): WebSocketEventListener | null; /** * @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0 */ send(data: WebSocketData): void; close(code?: number, reason?: string): void; private [kClose]; addEventListener(type: K, listener: (this: WebSocket, event: WebSocketEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, callback: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void; } //#endregion //#region src/interceptors/WebSocket/web-socket-class-transport.d.ts /** * Abstraction over the given mock `WebSocket` instance that allows * for controlling that instance (e.g. sending and receiving messages). */ declare class WebSocketClassTransport extends EventTarget implements WebSocketTransport { protected readonly socket: WebSocketOverride; constructor(socket: WebSocketOverride); addEventListener(type: EventType, callback: StrictEventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void; dispatchEvent(event: WebSocketTransportEventMap[EventType]): boolean; send(data: WebSocketData): void; close(code: number, reason?: string): void; } //#endregion //#region src/interceptors/WebSocket/web-socket-server-connection.d.ts declare const kEmitter$1: unique symbol; declare const kSend: unique symbol; interface WebSocketServerEventMap { open: Event; message: MessageEvent; error: Event; close: CloseEvent; } /** * The handle to the original WebSocket server connection: its controls. * A `WebSocketServerConnection` is a handle bound to a connection * in this process. */ declare abstract class WebSocketServerHandle { extension?: WebSocketExtension; abstract connect(): void; abstract send(data: Message): void; abstract close(): void; abstract addEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: AddEventListenerOptions | boolean): void; abstract removeEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: EventListenerOptions | boolean): void; } /** * The WebSocket server instance represents the actual production * WebSocket server connection. It's idle by default but you can * establish it by calling `server.connect()`. */ declare class WebSocketServerConnection implements WebSocketServerHandle { #private; private readonly client; private readonly transport; private readonly createConnection; /** * A WebSocket instance connected to the original server. */ private realWebSocket?; private mockCloseController; private realCloseController; private [kEmitter$1]; /** * An optional extension applied to the data crossing this connection: * `send()` encodes, incoming server frames are decoded * before being dispatched as `message` events. */ extension?: WebSocketExtension; /** * The intercepted connection this server belongs to. * Provided by the interceptor once both connections exist. */ [kExtensionContext]?: WebSocketExtensionContext; constructor(client: WebSocketOverride, transport: WebSocketClassTransport, createConnection: () => WebSocket); /** * The `WebSocket` instance connected to the original server. * Accessing this before calling `server.connect()` will throw. */ get socket(): WebSocket; /** * The ready state of the connection to the original WebSocket server. * Equals `WebSocket.CLOSED` until `server.connect()` is called. */ get readyState(): number; /** * Open connection to the original WebSocket server. */ connect(): void; /** * Listen for the incoming events from the original WebSocket server. */ addEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: AddEventListenerOptions | boolean): void; /** * Remove the listener for the given event. */ removeEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: EventListenerOptions | boolean): void; /** * Send data to the original WebSocket server. * @example * server.send('hello') * server.send(new Blob(['hello'])) * server.send(new TextEncoder().encode('hello')) */ send(data: Message): void; /** * Return the original WebSocket, throwing if * the connection to the original server was not established. */ private assertConnected; private [kSend]; /** * Close the actual server connection. */ close(): void; private handleIncomingMessage; private handleMockClose; private handleRealClose; } //#endregion //#region src/interceptors/WebSocket/web-socket-extension.d.ts declare const kExtensionContext: unique symbol; /** * The messages the given extension encodes and decodes. * * @note Inferred from the `encode()` parameter alone. Inferring from the * whole class would also consider the return type of `decode()`, where a * `Generator` (whose return type defaults to `any`) would widen * the messages to `any`. */ type WebSocketExtensionMessage = Extension extends { encode(message: infer Message, context: never): unknown; } ? Message : never; /** * The API the given extension adds to the connection event. */ type WebSocketExtensionApi = Extension extends WebSocketExtension ? Api : never; /** * The result of an extension method: a single value, an iterator * over multiple values, or `undefined` for no values at all. * * @note Only iterators (objects with a `next()` method, like generators) * are unfolded. Iterables that are not iterators, like strings, arrays, * or typed arrays, are treated as a single value so array-shaped * messages remain unambiguous. */ type WebSocketExtensionResult = Value | Iterator | undefined; /** * The intercepted connection an extension operates on. */ interface WebSocketExtensionContext { client: WebSocketClientHandle; server: WebSocketServerHandle; info: WebSocketConnectionInfo; } interface WebSocketExtensionMessageContext extends WebSocketExtensionContext { /** * The connection whose data is being encoded or decoded: * the `client` for data crossing the client connection, * the `server` for data crossing the original server connection. */ connection: WebSocketClientHandle | WebSocketServerHandle; } /** * A WebSocket extension: the server-side implementation of a protocol layered on top of * WebSocket (e.g. Socket.IO): its message framing (`encode`/`decode`), * its session as spoken by a server endpoint (`connect`/`receive`), * and the server API it adds to every connection (`extend`). * * The interceptor decides *when* each part applies: `send()` encodes, * frames are decoded before being dispatched as `message` events, * `connect` and `receive` frames are sent while the mocked connection * plays the server, and the extension is exposed on the connection event. * * An extension is invisible to the connection consumer: `client.send()`, * `server.send()`, and the `message` events all operate on messages, * and the session frames never surface. Raw frames forwarded between * the client and the original server (passthrough) are never touched. * * A method returns a single value for a one-to-one mapping, * an iterator (e.g. a generator) to unfold one input into many, * or nothing to drop the input. * * @example * class SocketIo extends WebSocketExtension { * match({ client }) { * return client.url.searchParams.has('EIO') * } * encode(message) { ... } * decode(data) { ... } * connect() { ... } * receive(data) { ... } * extend({ client }) { * return { rooms: new Rooms(client) } * } * } * * new WebSocketInterceptor({ extensions: [new SocketIo()] }) */ declare abstract class WebSocketExtension { /** * Whether this extension applies to the given connection. * Allows applying the extension to a subset of intercepted connections. */ match?(context: WebSocketExtensionContext): boolean; /** * Encode the given message into the raw frame(s) to send to the peer. */ abstract encode(message: Message, context: WebSocketExtensionMessageContext): WebSocketExtensionResult; /** * Decode the given raw frame into the message(s) to dispatch * as `message` events. Return nothing to swallow the frame * (e.g. protocol control frames). */ abstract decode(data: WebSocketData, context: WebSocketExtensionMessageContext): WebSocketExtensionResult; /** * The raw frame(s) a server of this extension's protocol sends once the * connection is established (e.g. a session handshake). * Sent to the client by the interceptor when the mocked connection * opens, unless a connection to the original server was established, * in which case the original server speaks for itself. */ connect?(context: WebSocketExtensionContext): WebSocketExtensionResult; /** * The raw frame(s) a server of this extension's protocol sends back in response * to the given client frame (e.g. a control frame acknowledgement), * the way a WebSocket endpoint answers a ping with a pong. * Applied by the interceptor under the same condition as `connect`. */ receive?(data: WebSocketData, context: WebSocketExtensionContext): WebSocketExtensionResult; /** * The server API this extension adds to the given connection * (e.g. rooms). Exposed on the connection event alongside * the `client` and the `server`. */ extend?(context: WebSocketExtensionContext): Extension; /** * Apply this extension to the given connection. * From then on, both the client and the server of that connection * encode the data they send and decode the data they receive. */ apply(connection: { client: WebSocketClientHandle; server: WebSocketServerHandle; }): void; } //#endregion //#region src/interceptors/WebSocket/web-socket-client-connection.d.ts declare const kEmitter: unique symbol; interface WebSocketClientEventMap { open: Event; message: MessageEvent; close: CloseEvent; } /** * The handle to a WebSocket client connection: its identity and controls. * A handle is what a connection is regardless of where it lives. * A `WebSocketClientConnection` is a handle bound to a connection in this * process; a handle can also be revived from a serialized connection * in another process (e.g. a connection stored by a worker). * * `Message` is what crosses this connection: raw WebSocket data, or the * messages of the extension applied to it. */ declare abstract class WebSocketClientHandle { abstract id: string; abstract url: URL; extension?: WebSocketExtension; abstract send(data: Message): void; abstract close(code?: number, reason?: string): void; abstract addEventListener>(type: EventType, listener: WebSocketEventListener[EventType]>, options?: AddEventListenerOptions | boolean): void; abstract removeEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: EventListenerOptions | boolean): void; } /** * The WebSocket client instance represents an incoming * client connection. The user can control the connection, * send and receive events. */ declare class WebSocketClientConnection implements WebSocketClientHandle { #private; readonly socket: WebSocket; private readonly transport; readonly id: string; readonly url: URL; /** * An optional extension applied to the data crossing this connection: * `send()` encodes, outgoing client frames are decoded * before being dispatched as `message` events. */ extension?: WebSocketExtension; /** * The intercepted connection this client belongs to. * Provided by the interceptor once both connections exist. */ [kExtensionContext]?: WebSocketExtensionContext; private [kEmitter]; constructor(socket: WebSocket, transport: WebSocketTransport); /** * Listen for the outgoing events from the connected WebSocket client. */ addEventListener>(type: EventType, listener: WebSocketEventListener[EventType]>, options?: AddEventListenerOptions | boolean): void; /** * Removes the listener for the given event. */ removeEventListener>(event: EventType, listener: WebSocketEventListener[EventType]>, options?: EventListenerOptions | boolean): void; /** * Send data to the connected client. */ send(data: Message): void; /** * Close the WebSocket connection. * @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1). * @param {string} reason A custom connection close reason. */ close(code?: number, reason?: string): void; } //#endregion //#region src/interceptors/WebSocket/index.d.ts type WebSocketExtensions = ReadonlyArray>; /** * The messages crossing the connections intercepted with the given * extensions: the messages of the extension applied to a connection, * or raw WebSocket data when there are no extensions. * * @note The types assume one of the extensions matches the connection. */ type WebSocketInterceptorMessage = [Extensions] extends [readonly []] ? WebSocketData : WebSocketExtensionMessage; /** * The API the extension applied to a connection adds to the connection event. */ type WebSocketInterceptorApi = [Extensions] extends [readonly []] ? {} : WebSocketExtensionApi; interface WebSocketInterceptorOptions { /** * Extensions to apply to the intercepted connections. * The first extension whose `match()` accepts a connection is applied * to it. An extension without `match()` accepts every connection. */ extensions?: Extensions; } /** * Intercept the outgoing WebSocket connections created using * the global `WebSocket` class. */ declare class WebSocketInterceptor extends Interceptor, WebSocketInterceptorApi>> { static symbol: symbol; private readonly extensions; constructor(options?: WebSocketInterceptorOptions); protected predicate(): boolean; protected setup(): void; } //#endregion export { CancelableCloseEvent, CancelableMessageEvent, CloseEvent, WebSocketClientConnection, type WebSocketClientEventMap, WebSocketClientHandle, WebSocketConnectionEvent, type WebSocketConnectionEventData, type WebSocketConnectionInfo, type WebSocketData, type WebSocketEventMap$1 as WebSocketEventMap, WebSocketExtension, type WebSocketExtensionApi, type WebSocketExtensionContext, type WebSocketExtensionMessage, type WebSocketExtensionMessageContext, type WebSocketExtensionResult, type WebSocketInterceptedConnection, WebSocketInterceptor, WebSocketInterceptorApi, WebSocketInterceptorMessage, WebSocketInterceptorOptions, WebSocketServerConnection, type WebSocketServerEventMap, WebSocketServerHandle, type WebSocketTransport }; //# sourceMappingURL=index.d.ts.map