import { JSONValue } from '@zimic/http'; import { PossiblePromise } from '@zimic/utils/types'; import type { WebSocket as ClientSocket } from 'isomorphic-ws'; export interface WebSocketChannelFrame { id: string; channel: Channel; } export interface WebSocketEventMessage< Schema extends WebSocketSchema, Channel extends WebSocketChannel = WebSocketChannel, > extends WebSocketChannelFrame { data: Schema[Channel]['event']; } export interface WebSocketReplyMessage< Schema extends WebSocketSchema, Channel extends WebSocketChannel = WebSocketChannel, > extends WebSocketChannelFrame { data: Schema[Channel]['reply']; requestId: string; } export type WebSocketMessage< Schema extends WebSocketSchema, Channel extends WebSocketChannel = WebSocketChannel, > = WebSocketEventMessage | WebSocketReplyMessage; interface BaseWebSocketSchema { [channel: string]: { event?: JSONValue.Loose; reply?: JSONValue.Loose; }; } export type WebSocketSchema = Schema; export type WebSocketChannel = keyof Schema & string; export type WebSocketChannelWithNoReply = { [Channel in WebSocketChannel]: Schema[Channel]['reply'] extends JSONValue ? never : Channel; }[WebSocketChannel]; export type WebSocketChannelWithReply = Exclude< WebSocketChannel, WebSocketChannelWithNoReply >; export type WebSocketEventMessageListener> = ( message: WebSocketEventMessage, socket: ClientSocket, ) => PossiblePromise['data']>; export type WebSocketReplyMessageListener> = ( message: WebSocketReplyMessage, socket: ClientSocket, ) => PossiblePromise; export type WebSocketMessageListener> = | WebSocketEventMessageListener | WebSocketReplyMessageListener;