diff --git a/package.json b/package.json index b820421..c0467da 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "files": [ "src" ], + "types": "src/index.d.ts", "exports": { "require": "./src/index.js", "import": "./src/index.mjs" diff --git a/src/index.d.ts b/src/index.d.ts new file mode 100644 index 0000000..f8b53cb --- /dev/null +++ b/src/index.d.ts @@ -0,0 +1,74 @@ +import * as ws from 'ws'; +import * as uWS from 'uWebSockets.js'; +import {IncomingMessage} from 'http'; + +declare namespace WebSocket { + type HandleUpgradeResult = (ws: T, request: U) => void | false | void; + + interface ServerOptions< + T extends typeof WebSocketClient = typeof WebSocketClient, + U extends typeof IncomingMessage = typeof IncomingMessage, + > extends Omit, 'noServer' | 'skipUTF8Validation' | 'backlog'> { + // pass true for DEDICATED_COMPRESSOR_4KB | DEDICATED_DECOMPRESSOR or your own CompressOptions number. + // Options are not supported and if this is an object it will be treated as true. + // https://github.com/uNetworking/uWebSockets.js/blob/master/docs/index.d.ts#L360-L361 + perMessageDeflate?: boolean | uWS.CompressOptions | ws.PerMessageDeflateOptions; + + uwsOptions?: uWS.AppOptions; + + /** + * Custom upgrade handler + * By default (handleUpgrade: undefined), the connection will be handled as usual, and "connection" event will be emitted. + * @returns + * - function: Callback to handle the WebSocket instance manually + * - false: Reject the connection (remember to destroy the socket) + * - void/other: Handle normally, will emit 'connection' event + */ + handleUpgrade?: (request: T) => Promise> | HandleUpgradeResult; + } + + class WebSocketServer< + T extends typeof WebSocketClient = typeof WebSocketClient, + U extends typeof IncomingMessage = typeof IncomingMessage, + > extends ws.Server { + constructor(options: WebSocket.ServerOptions); + + // Override ws.Server's handleUpgrade to prevent usage + // passing a custom handleUpgrade function in constructor option for alternatives. + override handleUpgrade: never; + } + + type SendReturnType = 0 | 1 | 2; + interface SendOptions { + binary?: boolean; + compress?: boolean; + } + + class WebSocketClient extends ws.WebSocket { + /** + * Send a message. Support binary/compress options only. + * Callback will only get error if it returns 2 + * @returns + * - 1 for success + * - 2 for dropped due to backpressure limit + * - 0 for built up backpressure that will drain over time. + */ + override send( + message: uWS.RecognizedString, + callback?: (err?: Error) => void, + ): SendReturnType; + override send( + message: uWS.RecognizedString, + options: SendOptions, callback?: (err?: Error) => void, + ): SendReturnType; + + override ping(data?: uWS.RecognizedString): void; + override pong(): void; + } +} + +export = { + ...ws, + Server: WebSocket.WebSocketServer, + WebSocketServer: WebSocket.WebSocketServer, +}; \ No newline at end of file