@orkestrel/websocket 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -8
- package/dist/src/server/index.cjs +458 -226
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +404 -147
- package/dist/src/server/index.d.ts +404 -147
- package/dist/src/server/index.js +453 -223
- package/dist/src/server/index.js.map +1 -1
- package/package.json +19 -16
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Duplex } from 'node:stream';
|
|
2
|
-
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
3
|
-
import { EmitterHooks } from '@orkestrel/emitter';
|
|
4
|
-
import { EmitterInterface } from '@orkestrel/emitter';
|
|
1
|
+
import type { Duplex } from 'node:stream';
|
|
2
|
+
import type { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
3
|
+
import type { EmitterHooks } from '@orkestrel/emitter';
|
|
4
|
+
import type { EmitterInterface } from '@orkestrel/emitter';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Computes the `Sec-WebSocket-Accept` response value for an RFC 6455 upgrade.
|
|
8
8
|
*
|
|
9
9
|
* @remarks
|
|
10
10
|
* The base64-encoded SHA-1 of the client's `Sec-WebSocket-Key` concatenated with the
|
|
@@ -17,61 +17,69 @@ import { EmitterInterface } from '@orkestrel/emitter';
|
|
|
17
17
|
export declare function computeWebSocketAccept(key: string): string;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Creates a server-native WebSocket over a raw upgraded `node:stream` Duplex socket —
|
|
21
|
+
* server mode when a `key` is given, client mode otherwise.
|
|
21
22
|
*
|
|
22
23
|
* @remarks
|
|
23
|
-
* The construction entry point for the {@link NodeWebSocketInterface}
|
|
24
|
-
* the
|
|
25
|
-
* mode
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* later chunk) is built ON it. It is the WebSocket counterpart to
|
|
29
|
-
* `createSQLiteDatabase` / `createIndexedDBDatabase`.
|
|
24
|
+
* The construction entry point for the {@link NodeWebSocketInterface}. In server mode the
|
|
25
|
+
* wrapper writes the `101 Switching Protocols` handshake and sends unmasked frames; in
|
|
26
|
+
* client mode it writes no handshake and masks every outgoing frame. This is the
|
|
27
|
+
* lean-native handle: it speaks the WebSocket wire protocol and nothing above it, so a
|
|
28
|
+
* message transport is built on it rather than into it.
|
|
30
29
|
*
|
|
31
30
|
* @param options - The {@link NodeWebSocketOptions} (`socket`, optional `key` / `head` /
|
|
32
31
|
* `protocol` / `on`)
|
|
33
32
|
* @returns A typed {@link NodeWebSocketInterface}
|
|
33
|
+
* @throws A `WebSocketError` coded `OPTION` when `payload`, `timeout`, `key`, or `protocol` is refused, thrown before the wrapper writes to or assumes ownership of the `socket`
|
|
34
34
|
*
|
|
35
|
-
* @example
|
|
35
|
+
* @example Accept an upgrade and echo messages (server mode)
|
|
36
36
|
* ```ts
|
|
37
|
-
* import { createNodeWebSocket } from '@
|
|
37
|
+
* import { createNodeWebSocket } from '@orkestrel/websocket'
|
|
38
38
|
*
|
|
39
|
-
* // In a node:http 'upgrade' handler — server mode, identified by the client key:
|
|
40
39
|
* server.on('upgrade', (request, socket, head) => {
|
|
40
|
+
* const key = request.headers['sec-websocket-key']
|
|
41
|
+
* if (typeof key !== 'string') {
|
|
42
|
+
* socket.destroy()
|
|
43
|
+
* return
|
|
44
|
+
* }
|
|
41
45
|
* const ws = createNodeWebSocket({
|
|
42
46
|
* socket,
|
|
43
|
-
* key
|
|
44
|
-
* head,
|
|
45
|
-
* on: { message: (text) => ws.send(`echo: ${text}`) },
|
|
47
|
+
* key,
|
|
48
|
+
* head, // any bytes already buffered after the upgrade headers
|
|
49
|
+
* on: { message: (text) => ws.send(`echo: ${text}`) }, // wired before the first frame arrives
|
|
46
50
|
* })
|
|
51
|
+
* ws.emitter.on('message', (text) => log('echoed', text)) // a second observer of the same event
|
|
52
|
+
* ws.emitter.on('close', (code, reason) => log('closed', code, reason))
|
|
47
53
|
* })
|
|
48
54
|
* ```
|
|
49
55
|
*/
|
|
50
56
|
export declare function createNodeWebSocket(options: NodeWebSocketOptions): NodeWebSocketInterface;
|
|
51
57
|
|
|
52
58
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
59
|
+
* Encodes a single RFC 6455 frame to its wire bytes — the inverse of
|
|
60
|
+
* `parseWebSocketFrame`.
|
|
55
61
|
*
|
|
56
62
|
* @remarks
|
|
57
63
|
* Builds a final (FIN-set) frame: byte 0 is `0x80 | opcode`; the payload length uses
|
|
58
64
|
* the 7-bit form below 126, the `126` + 16-bit form below 65 536, or the `127` +
|
|
59
65
|
* 64-bit form beyond; when `masked` is set the mask bit is set, a 4-byte key (supplied
|
|
60
|
-
*
|
|
61
|
-
* client frames are unmasked (the default); pass `masked: true` to encode a
|
|
62
|
-
* frame (
|
|
63
|
-
* Returns one contiguous `Buffer` (header + payload), so the wrapper writes it
|
|
64
|
-
* single `socket.write`. Pure.
|
|
66
|
+
* through `options.mask`, else random) is written, and the payload is XOR-masked. Server→
|
|
67
|
+
* client frames are unmasked (the default); pass `masked: true` to encode a client
|
|
68
|
+
* frame (for example to feed the parser in a test). A `string` payload is encoded as
|
|
69
|
+
* UTF-8. Returns one contiguous `Buffer` (header + payload), so the wrapper writes it
|
|
70
|
+
* with a single `socket.write`. Pure.
|
|
65
71
|
*
|
|
66
72
|
* @param opcode - The frame opcode (a `WEBSOCKET_OPCODE_*` value)
|
|
67
73
|
* @param payload - The payload, a `Buffer` or a UTF-8 `string`
|
|
68
74
|
* @param options - Masking control ({@link WebSocketEncodeOptions}); defaults to unmasked
|
|
69
75
|
* @returns The complete frame as wire bytes
|
|
76
|
+
* @throws A {@link WebSocketError} coded `FRAME` when `opcode` is outside the four-bit wire field, when `options.mask` is not 4 bytes, or when `options.mask` is supplied without `masked: true`
|
|
70
77
|
*/
|
|
71
78
|
export declare function encodeWebSocketFrame(opcode: number, payload: Buffer | string, options?: WebSocketEncodeOptions): Buffer;
|
|
72
79
|
|
|
73
80
|
/**
|
|
74
|
-
*
|
|
81
|
+
* Checks whether a numeric value is a close status code an RFC 6455 endpoint may
|
|
82
|
+
* receive (§7.4.1).
|
|
75
83
|
*
|
|
76
84
|
* @remarks
|
|
77
85
|
* True for `1000`–`1003`, `1007`–`1014`, and the application range `3000`–`4999`; false
|
|
@@ -84,7 +92,7 @@ export declare function encodeWebSocketFrame(opcode: number, payload: Buffer | s
|
|
|
84
92
|
* never throws.
|
|
85
93
|
*
|
|
86
94
|
* @param code - The close status code to validate
|
|
87
|
-
* @returns
|
|
95
|
+
* @returns True if `code` is a valid RFC 6455 close code; false otherwise
|
|
88
96
|
*
|
|
89
97
|
* @example
|
|
90
98
|
* ```ts
|
|
@@ -94,25 +102,27 @@ export declare function encodeWebSocketFrame(opcode: number, payload: Buffer | s
|
|
|
94
102
|
export declare function isCloseCode(code: number): boolean;
|
|
95
103
|
|
|
96
104
|
/**
|
|
97
|
-
*
|
|
105
|
+
* Checks whether a caught value is a {@link WebSocketError}, narrowing it so a `catch` can
|
|
106
|
+
* branch on `error.code`.
|
|
98
107
|
*
|
|
99
|
-
* @
|
|
100
|
-
*
|
|
101
|
-
* is canonical only for lengths at least 126; the 64-bit form only for lengths at
|
|
102
|
-
* least 65,536 and with its most-significant bit clear (RFC 6455 §5.2).
|
|
103
|
-
*
|
|
104
|
-
* @param buffer - The accumulation buffer containing the next frame header
|
|
105
|
-
* @returns Its canonicality, or `undefined` while the length prefix is incomplete
|
|
108
|
+
* @param value - The value to test (typically a `catch` binding)
|
|
109
|
+
* @returns True if `value` is a `WebSocketError`; false otherwise
|
|
106
110
|
*
|
|
107
111
|
* @example
|
|
108
112
|
* ```ts
|
|
109
|
-
*
|
|
113
|
+
* import { isWebSocketError } from '@src/server'
|
|
114
|
+
*
|
|
115
|
+
* try {
|
|
116
|
+
* ws.close(1000.5)
|
|
117
|
+
* } catch (error) {
|
|
118
|
+
* if (isWebSocketError(error) && error.code === 'CLOSE') ws.close()
|
|
119
|
+
* }
|
|
110
120
|
* ```
|
|
111
121
|
*/
|
|
112
|
-
export declare function
|
|
122
|
+
export declare function isWebSocketError(value: unknown): value is WebSocketError;
|
|
113
123
|
|
|
114
124
|
/**
|
|
115
|
-
*
|
|
125
|
+
* Checks whether a value is a canonical RFC 6455 `Sec-WebSocket-Key`.
|
|
116
126
|
*
|
|
117
127
|
* @remarks
|
|
118
128
|
* A valid key is exactly 16 random bytes encoded as 24 characters of base64, ending
|
|
@@ -120,7 +130,7 @@ export declare function isWebSocketFrameCanonical(buffer: Buffer): boolean | und
|
|
|
120
130
|
* malformed or non-canonical encodings return `false`; nothing is thrown.
|
|
121
131
|
*
|
|
122
132
|
* @param key - The proposed `Sec-WebSocket-Key` header value
|
|
123
|
-
* @returns
|
|
133
|
+
* @returns True if `key` is the canonical base64 encoding of 16 bytes; false otherwise
|
|
124
134
|
*
|
|
125
135
|
* @example
|
|
126
136
|
* ```ts
|
|
@@ -131,7 +141,7 @@ export declare function isWebSocketFrameCanonical(buffer: Buffer): boolean | und
|
|
|
131
141
|
export declare function isWebSocketKey(key: string): boolean;
|
|
132
142
|
|
|
133
143
|
/**
|
|
134
|
-
*
|
|
144
|
+
* Checks whether a value is one valid WebSocket subprotocol token.
|
|
135
145
|
*
|
|
136
146
|
* @remarks
|
|
137
147
|
* Subprotocols use the HTTP `token` grammar. Whitespace, separators, commas, and
|
|
@@ -139,25 +149,45 @@ export declare function isWebSocketKey(key: string): boolean;
|
|
|
139
149
|
* second handshake header.
|
|
140
150
|
*
|
|
141
151
|
* @param protocol - The negotiated subprotocol to validate
|
|
142
|
-
* @returns
|
|
152
|
+
* @returns True if `protocol` is one non-empty HTTP token; false otherwise
|
|
143
153
|
*
|
|
144
154
|
* @example
|
|
145
155
|
* ```ts
|
|
146
|
-
* if (!isWebSocketProtocol(protocol))
|
|
156
|
+
* if (!isWebSocketProtocol(protocol)) socket.destroy()
|
|
147
157
|
* ```
|
|
148
158
|
*/
|
|
149
159
|
export declare function isWebSocketProtocol(protocol: string): boolean;
|
|
150
160
|
|
|
151
161
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
162
|
+
* Checks whether the next frame uses the shortest valid RFC 6455 payload-length
|
|
163
|
+
* encoding, answering `undefined` until its length prefix is complete.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* The 16-bit form is canonical only for lengths at least 126; the 64-bit form only for
|
|
167
|
+
* lengths at least 65,536 and with its most-significant bit clear (RFC 6455 §5.2). Reads
|
|
168
|
+
* the same length prefix as {@link measureWebSocketFrame}, under the same
|
|
169
|
+
* incomplete-buffer contract. Pure; never throws.
|
|
170
|
+
*
|
|
171
|
+
* @param buffer - The accumulation buffer containing the next frame header
|
|
172
|
+
* @returns Its canonicality, or `undefined` while the length prefix is incomplete
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* if (matchesWebSocketCanonical(buffer) === false) fail(WEBSOCKET_CLOSE_PROTOCOL)
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export declare function matchesWebSocketCanonical(buffer: Buffer): boolean | undefined;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Reads the declared payload length off the front of a buffer without buffering or
|
|
183
|
+
* reading the payload itself, answering `undefined` until the length field is complete.
|
|
154
184
|
*
|
|
155
185
|
* @remarks
|
|
156
186
|
* Decodes only byte 1's 7-bit length field, extended by the 16-bit (`126`) or 64-bit
|
|
157
|
-
* (`127`) form exactly like
|
|
187
|
+
* (`127`) form exactly like `parseWebSocketFrame` — but stops there, so a caller
|
|
158
188
|
* can reject an over-cap frame the moment its length is known, before the payload
|
|
159
|
-
* bytes have even arrived.
|
|
160
|
-
*
|
|
189
|
+
* bytes have even arrived. The incomplete-buffer contract mirrors the parser's. Pure;
|
|
190
|
+
* never throws.
|
|
161
191
|
*
|
|
162
192
|
* @param buffer - The accumulation buffer to read the next frame's length from
|
|
163
193
|
* @returns The declared payload length, or `undefined` when the buffer is too short to know it yet
|
|
@@ -165,53 +195,79 @@ export declare function isWebSocketProtocol(protocol: string): boolean;
|
|
|
165
195
|
* @example
|
|
166
196
|
* ```ts
|
|
167
197
|
* const declared = measureWebSocketFrame(buffer)
|
|
168
|
-
* if (declared !== undefined && declared > limit) fail(
|
|
198
|
+
* if (declared !== undefined && declared > limit) fail(WEBSOCKET_CLOSE_TOO_BIG)
|
|
169
199
|
* ```
|
|
170
200
|
*/
|
|
171
201
|
export declare function measureWebSocketFrame(buffer: Buffer): number | undefined;
|
|
172
202
|
|
|
173
203
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
204
|
+
* Implements the wrapper contract over a raw upgraded `node:stream` Duplex socket,
|
|
205
|
+
* driving the RFC 6455 handshake, the frame codec, auto-pong, and the close handshake,
|
|
206
|
+
* and surfacing every event on an owned `emitter`.
|
|
176
207
|
*
|
|
177
208
|
* @remarks
|
|
178
|
-
* Created by `createNodeWebSocket`. When given a client `key` it runs in
|
|
209
|
+
* Created by `createNodeWebSocket`. When given a client `key` it runs in server mode —
|
|
179
210
|
* it writes the `101 Switching Protocols` handshake (`computeWebSocketAccept(key)`) and
|
|
180
|
-
* emits `open`; given no key it runs in
|
|
211
|
+
* emits `open`; given no key it runs in client mode (no handshake, frames masked). It
|
|
181
212
|
* then listens on the socket's `data`, accumulating bytes in `#buffer` and decoding
|
|
182
213
|
* every complete frame with {@link parseWebSocketFrame} (slicing `consumed` and
|
|
183
|
-
* re-parsing the remainder): a
|
|
184
|
-
* `fin: false` frames — decodes to UTF-8 and emits `message`; a
|
|
185
|
-
* with a
|
|
214
|
+
* re-parsing the remainder): a text frame — reassembling continuation fragments across
|
|
215
|
+
* `fin: false` frames — decodes to UTF-8 and emits `message`; a ping is auto-answered
|
|
216
|
+
* with a pong and emits `ping`; a pong emits `pong`; a close frame is echoed and ends the
|
|
186
217
|
* socket, emitting `close`. `send` writes a text frame, `ping` a ping, `close` a close
|
|
187
|
-
* frame; `destroy` tears down immediately. It owns a typed `#emitter`
|
|
188
|
-
* isolates a throwing listener and routes the error to its own `error` handler
|
|
189
|
-
* option) — the socket never crashes. An underlying socket error emits the
|
|
190
|
-
* `error` event and terminates the wrapper. The untyped socket `data` is narrowed
|
|
191
|
-
* `Buffer` with a guard, never an assertion
|
|
218
|
+
* frame; `destroy` tears down immediately. It owns a typed `#emitter` by composition, and
|
|
219
|
+
* the emitter isolates a throwing listener and routes the error to its own `error` handler
|
|
220
|
+
* (the `error` option) — the socket never crashes. An underlying socket error emits the
|
|
221
|
+
* domain `error` event and terminates the wrapper. The untyped socket `data` is narrowed
|
|
222
|
+
* to a `Buffer` with a guard, never an assertion.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```ts
|
|
226
|
+
* import { NodeWebSocket } from '@src/server'
|
|
227
|
+
*
|
|
228
|
+
* // In a node:http 'upgrade' handler, over the socket the server already handed over:
|
|
229
|
+
* const key = request.headers['sec-websocket-key']
|
|
230
|
+
* if (typeof key !== 'string') {
|
|
231
|
+
* socket.destroy()
|
|
232
|
+
* return
|
|
233
|
+
* }
|
|
234
|
+
* const ws = new NodeWebSocket({ socket, key, head })
|
|
235
|
+
* ws.emitter.on('message', (text) => ws.send(`echo: ${text}`))
|
|
236
|
+
* ```
|
|
192
237
|
*/
|
|
193
238
|
export declare class NodeWebSocket implements NodeWebSocketInterface {
|
|
194
239
|
#private;
|
|
240
|
+
/**
|
|
241
|
+
* Creates a WebSocket wrapper over an already-upgraded Duplex socket.
|
|
242
|
+
*
|
|
243
|
+
* @remarks
|
|
244
|
+
* `key` selects the mode: present runs server mode and writes the `101 Switching
|
|
245
|
+
* Protocols` handshake, omitted runs client mode and masks every outgoing frame.
|
|
246
|
+
* {@link NodeWebSocketOptions} describes every member.
|
|
247
|
+
*
|
|
248
|
+
* @param options - The {@link NodeWebSocketOptions} the wrapper is built from
|
|
249
|
+
* @throws A {@link WebSocketError} coded `OPTION` when `payload`, `timeout`, `key`, or `protocol` is refused, or when `protocol` is supplied without a server `key`, thrown before the wrapper writes to or assumes ownership of the `socket`
|
|
250
|
+
*/
|
|
195
251
|
constructor(options: NodeWebSocketOptions);
|
|
196
252
|
get emitter(): EmitterInterface<NodeWebSocketEventMap>;
|
|
197
253
|
get readyState(): WebSocketReadyState;
|
|
198
|
-
send(
|
|
199
|
-
ping(
|
|
254
|
+
send(message: string): void;
|
|
255
|
+
ping(payload?: string): void;
|
|
200
256
|
close(code?: number, reason?: string): void;
|
|
201
257
|
destroy(): void;
|
|
202
258
|
}
|
|
203
259
|
|
|
204
260
|
/**
|
|
205
|
-
*
|
|
261
|
+
* Represents the event map a {@link NodeWebSocketInterface} emitter carries.
|
|
206
262
|
*
|
|
207
263
|
* @remarks
|
|
208
264
|
* `open` — the handshake completed and the socket is ready. `message` — a text frame
|
|
209
|
-
* arrived (its decoded UTF-8 string). `close` — the connection ended
|
|
210
|
-
*
|
|
211
|
-
* event and then terminates the wrapper).
|
|
212
|
-
* (a ping is auto-answered with a pong).
|
|
213
|
-
* Listener isolation is the emitter's
|
|
214
|
-
*
|
|
265
|
+
* arrived (its decoded UTF-8 string). `close` — the connection ended, carrying the
|
|
266
|
+
* labeled `[code, reason]` tuple (each `undefined` when the peer sent none). `error` —
|
|
267
|
+
* the underlying socket faulted (a domain event, and then terminates the wrapper).
|
|
268
|
+
* `ping` / `pong` — a control frame arrived (a ping is auto-answered with a pong).
|
|
269
|
+
* Listener isolation is the emitter's: a listener throw is routed to the emitter's
|
|
270
|
+
* `error` handler (the `error` option), never onto this map, so a buggy observer
|
|
215
271
|
* never breaks the socket.
|
|
216
272
|
*/
|
|
217
273
|
export declare type NodeWebSocketEventMap = {
|
|
@@ -224,7 +280,8 @@ export declare type NodeWebSocketEventMap = {
|
|
|
224
280
|
};
|
|
225
281
|
|
|
226
282
|
/**
|
|
227
|
-
*
|
|
283
|
+
* Represents the behavioral contract a server-native WebSocket exposes over a raw
|
|
284
|
+
* upgraded socket.
|
|
228
285
|
*
|
|
229
286
|
* @remarks
|
|
230
287
|
* Created by `createNodeWebSocket`. In server mode it writes the RFC 6455 handshake
|
|
@@ -234,38 +291,86 @@ export declare type NodeWebSocketEventMap = {
|
|
|
234
291
|
* frame is echoed and ends the socket, emitting `close`. `send` writes a text frame;
|
|
235
292
|
* `ping` writes a ping; `close` writes a close frame (the 2-byte code + optional
|
|
236
293
|
* reason); `destroy` tears the socket down immediately. `readyState` tracks the
|
|
237
|
-
* lifecycle. It owns a typed `emitter`
|
|
294
|
+
* lifecycle. It owns a typed `emitter` by composition and never throws on a faulty
|
|
238
295
|
* listener — the emitter routes it to its `error` handler (the `error` option).
|
|
296
|
+
* `ping` throws a `LIMIT`-coded `WebSocketError` when its UTF-8 payload exceeds
|
|
297
|
+
* `WEBSOCKET_CONTROL_MAX_LENGTH`; `close` throws a `CLOSE`-coded one for a status code
|
|
298
|
+
* `isCloseCode` refuses and a `LIMIT`-coded one for a reason past
|
|
299
|
+
* `WEBSOCKET_CLOSE_REASON_MAX_LENGTH`, in each case without changing `readyState`.
|
|
239
300
|
*/
|
|
240
301
|
export declare interface NodeWebSocketInterface {
|
|
241
302
|
readonly emitter: EmitterInterface<NodeWebSocketEventMap>;
|
|
242
303
|
readonly readyState: WebSocketReadyState;
|
|
243
|
-
|
|
244
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Writes a message as a UTF-8 text frame, masked in client mode and unmasked in server
|
|
306
|
+
* mode, and does nothing unless `readyState` is open.
|
|
307
|
+
*
|
|
308
|
+
* @remarks
|
|
309
|
+
* The peer's reply arrives back as a `message` event.
|
|
310
|
+
*
|
|
311
|
+
* @param message - The text to carry as the frame's payload
|
|
312
|
+
*/
|
|
313
|
+
send(message: string): void;
|
|
314
|
+
/**
|
|
315
|
+
* Writes a ping frame with an optional payload, which the peer answers with a pong, and
|
|
316
|
+
* does nothing unless `readyState` is open.
|
|
317
|
+
*
|
|
318
|
+
* @remarks
|
|
319
|
+
* The answering pong arrives as the `pong` event.
|
|
320
|
+
*
|
|
321
|
+
* @param payload - The optional UTF-8 payload to carry
|
|
322
|
+
* @throws A `WebSocketError` coded `LIMIT` when the UTF-8 payload exceeds
|
|
323
|
+
* `WEBSOCKET_CONTROL_MAX_LENGTH`
|
|
324
|
+
*/
|
|
325
|
+
ping(payload?: string): void;
|
|
326
|
+
/**
|
|
327
|
+
* Starts the closing handshake: moves to the closing ready state, writes a close frame
|
|
328
|
+
* carrying the two-byte big-endian `code` and an optional `reason`, and ends the
|
|
329
|
+
* writable side.
|
|
330
|
+
*
|
|
331
|
+
* @remarks
|
|
332
|
+
* The final `close` event fires after the peer echoes or the socket ends, and a second
|
|
333
|
+
* call is a no-op. Each refusal leaves `readyState` unchanged.
|
|
334
|
+
*
|
|
335
|
+
* @param code - The close status code, defaulting to `WEBSOCKET_CLOSE_NORMAL`
|
|
336
|
+
* @param reason - The optional UTF-8 reason to carry after the code
|
|
337
|
+
* @throws A `WebSocketError` coded `CLOSE` for an invalid or fractional `code`, and one
|
|
338
|
+
* coded `LIMIT` for a `reason` over `WEBSOCKET_CLOSE_REASON_MAX_LENGTH`
|
|
339
|
+
*/
|
|
245
340
|
close(code?: number, reason?: string): void;
|
|
341
|
+
/**
|
|
342
|
+
* Tears the socket down immediately: detaches the wrapper's domain socket listeners,
|
|
343
|
+
* destroys the socket, emits a final `close`, and tears the emitter down.
|
|
344
|
+
*
|
|
345
|
+
* @remarks
|
|
346
|
+
* Idempotent, and a hard stop rather than a handshake.
|
|
347
|
+
*/
|
|
246
348
|
destroy(): void;
|
|
247
349
|
}
|
|
248
350
|
|
|
249
351
|
/**
|
|
250
|
-
*
|
|
352
|
+
* Represents the options for `createNodeWebSocket` — the upgraded `socket`, the `key`
|
|
353
|
+
* that selects server or client mode, and the listeners, caps, and cancellation signal
|
|
354
|
+
* the wrapper runs under.
|
|
251
355
|
*
|
|
252
356
|
* @remarks
|
|
253
357
|
* `socket` is the upgraded `node:stream` Duplex (the raw TCP stream after the HTTP
|
|
254
|
-
* upgrade). `key` is the client's `Sec-WebSocket-Key`: present it to run in
|
|
255
|
-
* mode — the wrapper writes the `101 Switching Protocols` handshake and sends
|
|
256
|
-
* frames; omit it for
|
|
358
|
+
* upgrade). `key` is the client's `Sec-WebSocket-Key`: present it to run in server
|
|
359
|
+
* mode — the wrapper writes the `101 Switching Protocols` handshake and sends unmasked
|
|
360
|
+
* frames; omit it for client mode — no handshake is written and frames are masked (RFC
|
|
257
361
|
* 6455 §5.3). `head` is any bytes buffered after the upgrade headers (replayed through
|
|
258
362
|
* the parser). `protocol` is a negotiated subprotocol to echo in the handshake. `on`
|
|
259
|
-
* wires initial listeners at construction
|
|
260
|
-
* emitter's listener-error handler
|
|
261
|
-
* both a single inbound frame's declared length
|
|
363
|
+
* wires initial listeners at construction — the reserved `on` option; `error` is the
|
|
364
|
+
* emitter's listener-error handler, where a listener throw routes. `payload` caps
|
|
365
|
+
* both a single inbound frame's declared length and the total bytes of a reassembled
|
|
262
366
|
* fragmented message (default `WEBSOCKET_MAX_PAYLOAD`) — a breach closes 1009. `timeout`
|
|
263
367
|
* is how long the wrapper waits, after sending a close frame, for the peer's echo before
|
|
264
368
|
* it gives up and tears the socket down (default `WEBSOCKET_CLOSE_TIMEOUT_MS`). `signal`
|
|
265
369
|
* is the external cancellation seam — on abort the socket destroys; composes with the
|
|
266
370
|
* line's `@orkestrel/abort` and `@orkestrel/timeout` primitives, which expose native
|
|
267
371
|
* `AbortSignal`s. An already-aborted signal tears the socket down immediately after
|
|
268
|
-
* construction.
|
|
372
|
+
* construction. A refused member throws an `OPTION`-coded `WebSocketError` before the
|
|
373
|
+
* wrapper writes to or assumes ownership of the `socket`.
|
|
269
374
|
*/
|
|
270
375
|
export declare interface NodeWebSocketOptions {
|
|
271
376
|
readonly socket: Duplex;
|
|
@@ -273,7 +378,7 @@ export declare interface NodeWebSocketOptions {
|
|
|
273
378
|
readonly head?: Buffer;
|
|
274
379
|
readonly protocol?: string;
|
|
275
380
|
readonly on?: EmitterHooks<NodeWebSocketEventMap>;
|
|
276
|
-
/**
|
|
381
|
+
/** Holds the emitter's listener-error handler — a listener throw routes here, not to a domain event. */
|
|
277
382
|
readonly error?: EmitterErrorHandler;
|
|
278
383
|
readonly payload?: number;
|
|
279
384
|
readonly timeout?: number;
|
|
@@ -281,12 +386,13 @@ export declare interface NodeWebSocketOptions {
|
|
|
281
386
|
}
|
|
282
387
|
|
|
283
388
|
/**
|
|
284
|
-
*
|
|
389
|
+
* Decodes a byte sequence as strict UTF-8, answering `undefined` when the sequence is
|
|
390
|
+
* malformed.
|
|
285
391
|
*
|
|
286
392
|
* @remarks
|
|
287
|
-
* Wraps `TextDecoder('utf-8', { fatal: true })` in a try/catch so a malformed sequence
|
|
288
|
-
* returns
|
|
289
|
-
*
|
|
393
|
+
* Wraps `TextDecoder('utf-8', { fatal: true })` in a try/catch, so a malformed sequence
|
|
394
|
+
* returns rather than throwing — a guard-adjacent coercer never throws on bad input.
|
|
395
|
+
* Pure.
|
|
290
396
|
*
|
|
291
397
|
* @param bytes - The raw bytes to decode
|
|
292
398
|
* @returns The decoded string, or `undefined` when `bytes` is not valid UTF-8
|
|
@@ -300,119 +406,225 @@ export declare interface NodeWebSocketOptions {
|
|
|
300
406
|
export declare function parseUTF8(bytes: Buffer): string | undefined;
|
|
301
407
|
|
|
302
408
|
/**
|
|
303
|
-
*
|
|
409
|
+
* Decodes a single RFC 6455 frame from the front of a buffer, answering `undefined`
|
|
410
|
+
* while the buffer is incomplete so the caller accumulates and retries.
|
|
304
411
|
*
|
|
305
412
|
* @remarks
|
|
306
413
|
* Reads the FIN bit and opcode (byte 0), the mask bit and 7-bit payload length (byte
|
|
307
414
|
* 1) — extended to a 16-bit length when the 7-bit field is `126`, or a 64-bit length
|
|
308
415
|
* when it is `127` — the optional 4-byte mask key, then the payload, XOR-unmasking it
|
|
309
|
-
* against the key when the mask bit is set (client→server frames
|
|
416
|
+
* against the key when the mask bit is set (client→server frames must be masked, RFC
|
|
310
417
|
* 6455 §5.3; an unmasked frame still decodes, leaving the payload as-is, so the caller
|
|
311
|
-
* can enforce policy).
|
|
312
|
-
* part it is up to
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
* remainder. Pure; never throws on a short buffer.
|
|
418
|
+
* can enforce policy). The incomplete answer comes the moment the buffer is too short
|
|
419
|
+
* for the part it is up to: the length prefix, the mask, or the full payload.
|
|
420
|
+
* `consumed` is the total bytes the frame occupied, so the caller slices the remainder.
|
|
421
|
+
* Pure; never throws on a short buffer.
|
|
316
422
|
*
|
|
317
423
|
* @param buffer - The accumulation buffer to decode the next frame from
|
|
318
424
|
* @returns The parsed {@link WebSocketFrame}, or `undefined` when the buffer is incomplete
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const frame = parseWebSocketFrame(buffer)
|
|
429
|
+
* if (frame === undefined) return // incomplete — wait for more bytes
|
|
430
|
+
* ```
|
|
319
431
|
*/
|
|
320
432
|
export declare function parseWebSocketFrame(buffer: Buffer): WebSocketFrame | undefined;
|
|
321
433
|
|
|
322
|
-
/**
|
|
434
|
+
/**
|
|
435
|
+
* Names the invalid-frame-payload-data status code, 1007.
|
|
436
|
+
*
|
|
437
|
+
* @remarks
|
|
438
|
+
* Sent for non-UTF-8 text or an unparseable close reason (RFC 6455 §7.4.1).
|
|
439
|
+
*/
|
|
323
440
|
export declare const WEBSOCKET_CLOSE_INVALID = 1007;
|
|
324
441
|
|
|
325
|
-
/**
|
|
442
|
+
/**
|
|
443
|
+
* Names the normal-closure status code, 1000.
|
|
444
|
+
*
|
|
445
|
+
* @remarks
|
|
446
|
+
* The default `close` code (RFC 6455 §7.4.1).
|
|
447
|
+
*/
|
|
326
448
|
export declare const WEBSOCKET_CLOSE_NORMAL = 1000;
|
|
327
449
|
|
|
328
|
-
/**
|
|
450
|
+
/**
|
|
451
|
+
* Names the protocol-error status code, 1002.
|
|
452
|
+
*
|
|
453
|
+
* @remarks
|
|
454
|
+
* Sent when a framing or state rule was violated (RFC 6455 §7.4.1).
|
|
455
|
+
*/
|
|
329
456
|
export declare const WEBSOCKET_CLOSE_PROTOCOL = 1002;
|
|
330
457
|
|
|
331
|
-
/**
|
|
332
|
-
|
|
458
|
+
/**
|
|
459
|
+
* Names the maximum UTF-8 close-reason length after the two-byte status code, 123.
|
|
460
|
+
*
|
|
461
|
+
* @remarks
|
|
462
|
+
* What is left of {@link WEBSOCKET_CONTROL_MAX_LENGTH} after the close frame's status
|
|
463
|
+
* code.
|
|
464
|
+
*/
|
|
465
|
+
export declare const WEBSOCKET_CLOSE_REASON_MAX_LENGTH: number;
|
|
333
466
|
|
|
334
|
-
/**
|
|
467
|
+
/**
|
|
468
|
+
* Names the default close-handshake timeout, 30,000 milliseconds — how long `close` waits
|
|
469
|
+
* for the peer's echo.
|
|
470
|
+
*
|
|
471
|
+
* @remarks
|
|
472
|
+
* After it expires the wrapper tears the socket down, so a silent peer cannot leak the
|
|
473
|
+
* handle open.
|
|
474
|
+
*/
|
|
335
475
|
export declare const WEBSOCKET_CLOSE_TIMEOUT_MS = 30000;
|
|
336
476
|
|
|
337
|
-
/**
|
|
338
|
-
|
|
477
|
+
/**
|
|
478
|
+
* Names the message-too-big status code, 1009.
|
|
479
|
+
*
|
|
480
|
+
* @remarks
|
|
481
|
+
* Sent when a reassembled message exceeded the payload cap (RFC 6455 §7.4.1).
|
|
482
|
+
*/
|
|
483
|
+
export declare const WEBSOCKET_CLOSE_TOO_BIG = 1009;
|
|
339
484
|
|
|
340
|
-
/**
|
|
485
|
+
/**
|
|
486
|
+
* Names the unsupported-data status code, 1003.
|
|
487
|
+
*
|
|
488
|
+
* @remarks
|
|
489
|
+
* Sent when the endpoint received a data type it cannot accept (RFC 6455 §7.4.1), for
|
|
490
|
+
* example binary on a text-only endpoint.
|
|
491
|
+
*/
|
|
341
492
|
export declare const WEBSOCKET_CLOSE_UNSUPPORTED = 1003;
|
|
342
493
|
|
|
343
|
-
/**
|
|
344
|
-
|
|
494
|
+
/**
|
|
495
|
+
* Names the maximum control-frame payload length, 125 bytes.
|
|
496
|
+
*
|
|
497
|
+
* @remarks
|
|
498
|
+
* The cap RFC 6455 §5.5 sets on every control frame's payload.
|
|
499
|
+
*/
|
|
500
|
+
export declare const WEBSOCKET_CONTROL_MAX_LENGTH = 125;
|
|
345
501
|
|
|
346
|
-
/**
|
|
502
|
+
/**
|
|
503
|
+
* Names the flush grace, 1,000 milliseconds, a validation-breach close frame is given
|
|
504
|
+
* before the hard teardown fallback destroys the socket.
|
|
505
|
+
*
|
|
506
|
+
* @remarks
|
|
507
|
+
* Armed after `#fail` writes the close frame, so the frame drains through the socket's
|
|
508
|
+
* write buffer rather than being discarded. The normal path destroys sooner, on the
|
|
509
|
+
* `end()` flush callback.
|
|
510
|
+
*/
|
|
347
511
|
export declare const WEBSOCKET_FAIL_TIMEOUT_MS = 1000;
|
|
348
512
|
|
|
349
513
|
/**
|
|
350
|
-
*
|
|
351
|
-
* hash
|
|
514
|
+
* Names the accept GUID concatenated to a client's `Sec-WebSocket-Key` before the accept
|
|
515
|
+
* hash, '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'.
|
|
352
516
|
*
|
|
353
517
|
* @remarks
|
|
354
|
-
*
|
|
518
|
+
* The base64-encoded SHA-1 of that concatenation is the `Sec-WebSocket-Accept` response
|
|
519
|
+
* value. A fixed, spec-mandated constant (RFC 6455 §4.2.2) — read only by
|
|
355
520
|
* {@link computeWebSocketAccept}.
|
|
356
521
|
*/
|
|
357
522
|
export declare const WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
358
523
|
|
|
359
|
-
/**
|
|
524
|
+
/**
|
|
525
|
+
* Names the default cap on both an inbound frame's declared length and a reassembled
|
|
526
|
+
* message's total byte count, 104,857,600 bytes (100 MiB).
|
|
527
|
+
*
|
|
528
|
+
* @remarks
|
|
529
|
+
* The same value the `ws` package defaults to. Either breach closes
|
|
530
|
+
* {@link WEBSOCKET_CLOSE_TOO_BIG}.
|
|
531
|
+
*/
|
|
360
532
|
export declare const WEBSOCKET_MAX_PAYLOAD = 104857600;
|
|
361
533
|
|
|
362
|
-
/**
|
|
534
|
+
/**
|
|
535
|
+
* Names the binary frame opcode, 0x02.
|
|
536
|
+
*
|
|
537
|
+
* @remarks
|
|
538
|
+
* A raw byte payload (RFC 6455 §5.6).
|
|
539
|
+
*/
|
|
363
540
|
export declare const WEBSOCKET_OPCODE_BINARY = 2;
|
|
364
541
|
|
|
365
|
-
/**
|
|
542
|
+
/**
|
|
543
|
+
* Names the close frame opcode, 0x08.
|
|
544
|
+
*
|
|
545
|
+
* @remarks
|
|
546
|
+
* A control frame ending the connection (RFC 6455 §5.5.1).
|
|
547
|
+
*/
|
|
366
548
|
export declare const WEBSOCKET_OPCODE_CLOSE = 8;
|
|
367
549
|
|
|
368
|
-
/**
|
|
550
|
+
/**
|
|
551
|
+
* Names the continuation frame opcode, 0x00.
|
|
552
|
+
*
|
|
553
|
+
* @remarks
|
|
554
|
+
* The next fragment of an open data message (RFC 6455 §5.4).
|
|
555
|
+
*/
|
|
369
556
|
export declare const WEBSOCKET_OPCODE_CONTINUATION = 0;
|
|
370
557
|
|
|
371
|
-
/**
|
|
558
|
+
/**
|
|
559
|
+
* Names the ping frame opcode, 0x09.
|
|
560
|
+
*
|
|
561
|
+
* @remarks
|
|
562
|
+
* A control frame the peer must answer with a pong (RFC 6455 §5.5.2).
|
|
563
|
+
*/
|
|
372
564
|
export declare const WEBSOCKET_OPCODE_PING = 9;
|
|
373
565
|
|
|
374
|
-
/**
|
|
566
|
+
/**
|
|
567
|
+
* Names the pong frame opcode, 0x0a.
|
|
568
|
+
*
|
|
569
|
+
* @remarks
|
|
570
|
+
* A control frame answering a ping (RFC 6455 §5.5.3).
|
|
571
|
+
*/
|
|
375
572
|
export declare const WEBSOCKET_OPCODE_PONG = 10;
|
|
376
573
|
|
|
377
|
-
/**
|
|
574
|
+
/**
|
|
575
|
+
* Names the text frame opcode, 0x01.
|
|
576
|
+
*
|
|
577
|
+
* @remarks
|
|
578
|
+
* A UTF-8 payload (RFC 6455 §5.6).
|
|
579
|
+
*/
|
|
378
580
|
export declare const WEBSOCKET_OPCODE_TEXT = 1;
|
|
379
581
|
|
|
380
|
-
/**
|
|
582
|
+
/**
|
|
583
|
+
* Names the closed ready state, 3.
|
|
584
|
+
*
|
|
585
|
+
* @remarks
|
|
586
|
+
* The state a WebSocket holds after the socket ends.
|
|
587
|
+
*/
|
|
381
588
|
export declare const WEBSOCKET_READY_CLOSED: WebSocketReadyState;
|
|
382
589
|
|
|
383
|
-
/**
|
|
590
|
+
/**
|
|
591
|
+
* Names the closing ready state, 2.
|
|
592
|
+
*
|
|
593
|
+
* @remarks
|
|
594
|
+
* The state a WebSocket holds after a close frame is sent or received.
|
|
595
|
+
*/
|
|
384
596
|
export declare const WEBSOCKET_READY_CLOSING: WebSocketReadyState;
|
|
385
597
|
|
|
386
|
-
/**
|
|
598
|
+
/**
|
|
599
|
+
* Names the connecting ready state, 0.
|
|
600
|
+
*
|
|
601
|
+
* @remarks
|
|
602
|
+
* The state a WebSocket holds before its handshake completes.
|
|
603
|
+
*/
|
|
387
604
|
export declare const WEBSOCKET_READY_CONNECTING: WebSocketReadyState;
|
|
388
605
|
|
|
389
|
-
/**
|
|
606
|
+
/**
|
|
607
|
+
* Names the open ready state, 1.
|
|
608
|
+
*
|
|
609
|
+
* @remarks
|
|
610
|
+
* The state a WebSocket holds after the handshake completes and while frames flow.
|
|
611
|
+
*/
|
|
390
612
|
export declare const WEBSOCKET_READY_OPEN: WebSocketReadyState;
|
|
391
613
|
|
|
392
|
-
/** The WebSocket protocol version this wrapper speaks (`Sec-WebSocket-Version: 13`). */
|
|
393
|
-
export declare const WEBSOCKET_VERSION = "13";
|
|
394
|
-
|
|
395
614
|
/**
|
|
396
|
-
*
|
|
615
|
+
* Names the supported protocol version, '13'.
|
|
397
616
|
*
|
|
398
617
|
* @remarks
|
|
399
|
-
*
|
|
400
|
-
* payload); `reason` is the optional UTF-8 reason text (undefined when empty).
|
|
618
|
+
* The value this wrapper speaks, carried by the `Sec-WebSocket-Version` handshake header.
|
|
401
619
|
*/
|
|
402
|
-
export declare
|
|
403
|
-
readonly code: number | undefined;
|
|
404
|
-
readonly reason: string | undefined;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/** A WebSocket close status code (RFC 6455 §7.4) — e.g. `WEBSOCKET_CLOSE_NORMAL` (1000). */
|
|
408
|
-
export declare type WebSocketCloseCode = number;
|
|
620
|
+
export declare const WEBSOCKET_VERSION = "13";
|
|
409
621
|
|
|
410
622
|
/**
|
|
411
|
-
*
|
|
623
|
+
* Represents the options for {@link encodeWebSocketFrame} — how a frame is masked on the wire.
|
|
412
624
|
*
|
|
413
625
|
* @remarks
|
|
414
|
-
* `masked` toggles the mask bit (server→client frames are
|
|
415
|
-
* client→server frames
|
|
626
|
+
* `masked` toggles the mask bit (server→client frames are not masked, the default;
|
|
627
|
+
* client→server frames must be, RFC 6455 §5.3). `mask` supplies an explicit 4-byte
|
|
416
628
|
* mask key (deterministic, for tests); when `masked` is true and `mask` is omitted a
|
|
417
629
|
* random key is generated.
|
|
418
630
|
*/
|
|
@@ -422,7 +634,57 @@ export declare interface WebSocketEncodeOptions {
|
|
|
422
634
|
}
|
|
423
635
|
|
|
424
636
|
/**
|
|
425
|
-
*
|
|
637
|
+
* Represents an error the WebSocket wrapper throws for a refused caller-supplied value,
|
|
638
|
+
* carrying a machine-readable `code` and an optional `context`.
|
|
639
|
+
*
|
|
640
|
+
* @remarks
|
|
641
|
+
* The `code` is a {@link WebSocketErrorCode}; the `context` record holds the refused
|
|
642
|
+
* value under a key naming it: an `'OPTION'` carries the offending option (`payload`,
|
|
643
|
+
* `timeout`, `key`, or `protocol`), a `'LIMIT'` carries `size` and the `limit` it
|
|
644
|
+
* exceeded, a `'CLOSE'` carries the refused close `code`, and a `'FRAME'` carries
|
|
645
|
+
* `opcode` or the mask's `size`. Narrow a caught value with {@link isWebSocketError}.
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* import { createNodeWebSocket, isWebSocketError } from '@src/server'
|
|
650
|
+
*
|
|
651
|
+
* try {
|
|
652
|
+
* createNodeWebSocket({ socket, key: 'not-base64' })
|
|
653
|
+
* } catch (error) {
|
|
654
|
+
* if (isWebSocketError(error) && error.code === 'OPTION') socket.destroy()
|
|
655
|
+
* }
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
export declare class WebSocketError extends Error {
|
|
659
|
+
readonly code: WebSocketErrorCode;
|
|
660
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
661
|
+
/**
|
|
662
|
+
* Creates a WebSocket error carrying a machine-readable code.
|
|
663
|
+
*
|
|
664
|
+
* @param code - The machine-readable {@link WebSocketErrorCode} a `catch` branches on
|
|
665
|
+
* @param message - The human-readable description, carried as the `Error` message
|
|
666
|
+
* @param context - The refused value keyed by name; omitted leaves `context` `undefined`
|
|
667
|
+
*/
|
|
668
|
+
constructor(code: WebSocketErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Represents the subject a `WebSocketError` names as refused.
|
|
673
|
+
*
|
|
674
|
+
* @remarks
|
|
675
|
+
* `OPTION` — a {@link NodeWebSocketOptions} member was refused at construction
|
|
676
|
+
* (`payload`, `timeout`, `key`, `protocol`, or a `protocol` given without a server
|
|
677
|
+
* `key`). `LIMIT` — an outbound control-frame payload exceeded its RFC 6455 §5.5 cap
|
|
678
|
+
* (a `ping` payload past `WEBSOCKET_CONTROL_MAX_LENGTH`, a `close` reason past
|
|
679
|
+
* `WEBSOCKET_CLOSE_REASON_MAX_LENGTH`). `CLOSE` — a close status code `isCloseCode` refuses
|
|
680
|
+
* was passed to `close`. `FRAME` — an `encodeWebSocketFrame` frame-header argument was
|
|
681
|
+
* refused (an opcode outside the four-bit wire field, a mask that is not 4 bytes, or a
|
|
682
|
+
* mask supplied without `masked: true`).
|
|
683
|
+
*/
|
|
684
|
+
export declare type WebSocketErrorCode = 'OPTION' | 'LIMIT' | 'CLOSE' | 'FRAME';
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Represents a parsed RFC 6455 frame — the structured result of decoding one frame off the wire.
|
|
426
688
|
*
|
|
427
689
|
* @remarks
|
|
428
690
|
* `fin` is the final-fragment bit (false for a continued fragment); `opcode`
|
|
@@ -430,7 +692,7 @@ export declare interface WebSocketEncodeOptions {
|
|
|
430
692
|
* the already-unmasked application data; `consumed` is the total byte count the frame
|
|
431
693
|
* occupied (header + mask + payload), so the caller slices it off the front of its
|
|
432
694
|
* accumulation buffer and re-parses the remainder. `masked` is the mask bit off byte 1
|
|
433
|
-
* (client→server frames
|
|
695
|
+
* (client→server frames must be masked, RFC 6455 §5.1); `rsv` is the three reserved
|
|
434
696
|
* bits off byte 0 packed into a single 0–7 value (RFC 6455 §5.2) — non-zero means an
|
|
435
697
|
* extension the wrapper does not negotiate, so the caller rejects it. Produced by
|
|
436
698
|
* {@link parseWebSocketFrame}.
|
|
@@ -444,18 +706,13 @@ export declare interface WebSocketFrame {
|
|
|
444
706
|
readonly rsv: number;
|
|
445
707
|
}
|
|
446
708
|
|
|
447
|
-
/** A decoded text message received from, or to send to, a WebSocket peer. */
|
|
448
|
-
export declare interface WebSocketMessage {
|
|
449
|
-
readonly data: string;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
709
|
/**
|
|
453
|
-
*
|
|
710
|
+
* Represents a WebSocket ready state — the stage a connection has reached between the
|
|
711
|
+
* handshake and the socket's end.
|
|
454
712
|
*
|
|
455
713
|
* @remarks
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* `WEBSOCKET_READY_*` constants spell each value.
|
|
714
|
+
* The same numbering the DOM `WebSocket.readyState` uses, so the wrapper reads like the
|
|
715
|
+
* platform API. The named `WEBSOCKET_READY_*` constants spell each value.
|
|
459
716
|
*/
|
|
460
717
|
export declare type WebSocketReadyState = 0 | 1 | 2 | 3;
|
|
461
718
|
|