@daloyjs/core 0.9.1 → 0.11.0
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 +50 -36
- package/dist/adapters/bun.d.ts.map +1 -1
- package/dist/adapters/bun.js +178 -2
- package/dist/adapters/bun.js.map +1 -1
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +272 -10
- package/dist/adapters/node.js.map +1 -1
- package/dist/app.d.ts +13 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +76 -19
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/websocket.d.ts +275 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +505 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket primitives — runtime-agnostic types, handshake, and RFC 6455
|
|
3
|
+
* frame protocol. Adapter packages (`@daloyjs/core/node`, `@daloyjs/core/bun`)
|
|
4
|
+
* wire these primitives into their respective servers.
|
|
5
|
+
*
|
|
6
|
+
* The public API mirrors the WHATWG `WebSocket` interface where it makes
|
|
7
|
+
* sense for the server side (`readyState`, `send`, `close`, `protocol`,
|
|
8
|
+
* `extensions`, `bufferedAmount`, `binaryType`) and uses Bun-style handler
|
|
9
|
+
* callbacks (`open`, `message`, `close`, `drain`, `error`) so the same
|
|
10
|
+
* handler shape runs on both Node and Bun.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { App } from "@daloyjs/core";
|
|
14
|
+
* import { serve } from "@daloyjs/core/node";
|
|
15
|
+
*
|
|
16
|
+
* const app = new App();
|
|
17
|
+
*
|
|
18
|
+
* app.ws("/chat/:room", {
|
|
19
|
+
* open(conn, ctx) {
|
|
20
|
+
* conn.data = { user: ctx.query.user ?? "anon", room: ctx.params.room };
|
|
21
|
+
* conn.send(`welcome ${(conn.data as any).user}`);
|
|
22
|
+
* },
|
|
23
|
+
* message(conn, data) {
|
|
24
|
+
* conn.send(typeof data === "string" ? data.toUpperCase() : data);
|
|
25
|
+
* },
|
|
26
|
+
* close(conn, code, reason) {
|
|
27
|
+
* // cleanup
|
|
28
|
+
* },
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* serve(app, { port: 3000 });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import { Router } from "./router.js";
|
|
35
|
+
/** RFC 6455 magic GUID used to compute `Sec-WebSocket-Accept`. */
|
|
36
|
+
export const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
37
|
+
/** WHATWG `WebSocket.readyState` constants. */
|
|
38
|
+
export const WS_READY_STATE = {
|
|
39
|
+
CONNECTING: 0,
|
|
40
|
+
OPEN: 1,
|
|
41
|
+
CLOSING: 2,
|
|
42
|
+
CLOSED: 3,
|
|
43
|
+
};
|
|
44
|
+
/** RFC 6455 opcodes. */
|
|
45
|
+
export const WS_OPCODE = {
|
|
46
|
+
CONTINUATION: 0x0,
|
|
47
|
+
TEXT: 0x1,
|
|
48
|
+
BINARY: 0x2,
|
|
49
|
+
CLOSE: 0x8,
|
|
50
|
+
PING: 0x9,
|
|
51
|
+
PONG: 0xa,
|
|
52
|
+
};
|
|
53
|
+
/** Common RFC 6455 / IANA close codes. */
|
|
54
|
+
export const WS_CLOSE_CODE = {
|
|
55
|
+
NORMAL_CLOSURE: 1000,
|
|
56
|
+
GOING_AWAY: 1001,
|
|
57
|
+
PROTOCOL_ERROR: 1002,
|
|
58
|
+
UNSUPPORTED_DATA: 1003,
|
|
59
|
+
NO_STATUS_RECEIVED: 1005,
|
|
60
|
+
ABNORMAL_CLOSURE: 1006,
|
|
61
|
+
INVALID_PAYLOAD: 1007,
|
|
62
|
+
POLICY_VIOLATION: 1008,
|
|
63
|
+
MESSAGE_TOO_BIG: 1009,
|
|
64
|
+
INTERNAL_ERROR: 1011,
|
|
65
|
+
};
|
|
66
|
+
/** Maximum payload length permitted on a single control frame (RFC 6455 §5.5). */
|
|
67
|
+
export const WS_MAX_CONTROL_PAYLOAD = 125;
|
|
68
|
+
/** Helper for declaring a handler with full type-inference. */
|
|
69
|
+
export function defineWebSocket(handler) {
|
|
70
|
+
return handler;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Per-app registry of WebSocket routes. Uses the same trie router as HTTP so
|
|
74
|
+
* `:param` and static-route fast paths work identically.
|
|
75
|
+
*
|
|
76
|
+
* Adapters call {@link WebSocketRegistry.find} during the HTTP `upgrade`
|
|
77
|
+
* event (Node) or inside `fetch` (Bun / Workers).
|
|
78
|
+
*/
|
|
79
|
+
export class WebSocketRegistry {
|
|
80
|
+
router = new Router();
|
|
81
|
+
_size = 0;
|
|
82
|
+
add(path, handler, createState = () => ({})) {
|
|
83
|
+
this.router.add("GET", path, { path, handler, createState });
|
|
84
|
+
this._size += 1;
|
|
85
|
+
}
|
|
86
|
+
find(pathname) {
|
|
87
|
+
return this.router.find("GET", pathname);
|
|
88
|
+
}
|
|
89
|
+
get size() {
|
|
90
|
+
return this._size;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ---------- Handshake helpers ----------
|
|
94
|
+
const enc = new TextEncoder();
|
|
95
|
+
function bytesToBase64(bytes) {
|
|
96
|
+
let bin = "";
|
|
97
|
+
for (let i = 0; i < bytes.length; i++)
|
|
98
|
+
bin += String.fromCharCode(bytes[i]);
|
|
99
|
+
return btoa(bin);
|
|
100
|
+
}
|
|
101
|
+
function getSubtle() {
|
|
102
|
+
const c = globalThis.crypto;
|
|
103
|
+
if (!c?.subtle) {
|
|
104
|
+
throw new Error("websocket: Web Crypto (crypto.subtle) is required to compute Sec-WebSocket-Accept.");
|
|
105
|
+
}
|
|
106
|
+
return c.subtle;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Compute the `Sec-WebSocket-Accept` response header value for a given
|
|
110
|
+
* `Sec-WebSocket-Key` per RFC 6455 §4.2.2:
|
|
111
|
+
*
|
|
112
|
+
* `base64(SHA1(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))`
|
|
113
|
+
*/
|
|
114
|
+
export async function computeAcceptKey(key) {
|
|
115
|
+
const digest = await getSubtle().digest("SHA-1", enc.encode(key + WS_GUID));
|
|
116
|
+
return bytesToBase64(new Uint8Array(digest));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Parse the offered subprotocols from a `Sec-WebSocket-Protocol` header.
|
|
120
|
+
* Returns trimmed, non-empty tokens in client preference order.
|
|
121
|
+
*/
|
|
122
|
+
export function parseSubprotocols(header) {
|
|
123
|
+
if (!header)
|
|
124
|
+
return [];
|
|
125
|
+
return header
|
|
126
|
+
.split(",")
|
|
127
|
+
.map((s) => s.trim())
|
|
128
|
+
.filter((s) => s.length > 0);
|
|
129
|
+
}
|
|
130
|
+
const WS_TOKEN_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
131
|
+
/**
|
|
132
|
+
* Validate a server-selected subprotocol before it is written to the 101
|
|
133
|
+
* response. RFC 6455 requires the value to be one of the client-offered
|
|
134
|
+
* tokens; enforcing it also prevents accidental response-header injection.
|
|
135
|
+
*/
|
|
136
|
+
export function validateSelectedSubprotocol(protocol, offered) {
|
|
137
|
+
if (!WS_TOKEN_RE.test(protocol)) {
|
|
138
|
+
throw new WebSocketProtocolError("Selected WebSocket subprotocol must be a valid HTTP token");
|
|
139
|
+
}
|
|
140
|
+
if (!offered.includes(protocol)) {
|
|
141
|
+
throw new WebSocketProtocolError("Selected WebSocket subprotocol was not offered by the client");
|
|
142
|
+
}
|
|
143
|
+
return protocol;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Validate the upgrade request headers and compute the accept key when
|
|
147
|
+
* valid. This helper does **not** touch the wire — it only decides whether
|
|
148
|
+
* the handshake should succeed and what the response key should be.
|
|
149
|
+
*/
|
|
150
|
+
export async function validateUpgrade(headers) {
|
|
151
|
+
const upgrade = headers.get("upgrade");
|
|
152
|
+
if (!upgrade || upgrade.toLowerCase() !== "websocket") {
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
status: 400,
|
|
156
|
+
reason: "Missing or invalid Upgrade header",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const connection = headers.get("connection");
|
|
160
|
+
if (!connection || !/\bupgrade\b/i.test(connection)) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
status: 400,
|
|
164
|
+
reason: "Missing or invalid Connection header",
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const version = headers.get("sec-websocket-version");
|
|
168
|
+
if (version !== "13") {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
status: 426,
|
|
172
|
+
reason: "Unsupported Sec-WebSocket-Version",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const key = headers.get("sec-websocket-key");
|
|
176
|
+
if (!key || !isValidWebSocketKey(key)) {
|
|
177
|
+
return {
|
|
178
|
+
ok: false,
|
|
179
|
+
status: 400,
|
|
180
|
+
reason: "Missing or invalid Sec-WebSocket-Key",
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const acceptKey = await computeAcceptKey(key);
|
|
184
|
+
return {
|
|
185
|
+
ok: true,
|
|
186
|
+
acceptKey,
|
|
187
|
+
protocols: parseSubprotocols(headers.get("sec-websocket-protocol")),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function isValidWebSocketKey(key) {
|
|
191
|
+
try {
|
|
192
|
+
const bytes = Uint8Array.from(atob(key), (char) => char.charCodeAt(0));
|
|
193
|
+
return bytes.length === 16;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** Returned from `parseFrame` when the buffer doesn't yet hold a full frame. */
|
|
200
|
+
export const FRAME_INCOMPLETE = Symbol("daloy.ws.frameIncomplete");
|
|
201
|
+
/**
|
|
202
|
+
* Parse a single frame from `buf` starting at offset 0. Returns
|
|
203
|
+
* {@link FRAME_INCOMPLETE} when the buffer is too short for a complete
|
|
204
|
+
* frame; throws {@link WebSocketProtocolError} for RFC 6455 violations.
|
|
205
|
+
*
|
|
206
|
+
* The parser unmasks payloads in-place when needed. The returned `payload`
|
|
207
|
+
* is a subarray view over `buf`; copy it if you intend to retain it past
|
|
208
|
+
* the next call.
|
|
209
|
+
*/
|
|
210
|
+
export function parseFrame(buf, opts = {}) {
|
|
211
|
+
if (buf.length < 2)
|
|
212
|
+
return FRAME_INCOMPLETE;
|
|
213
|
+
const b0 = buf[0];
|
|
214
|
+
const b1 = buf[1];
|
|
215
|
+
const fin = (b0 & 0x80) !== 0;
|
|
216
|
+
const rsv = b0 & 0x70;
|
|
217
|
+
if (rsv !== 0)
|
|
218
|
+
throw new WebSocketProtocolError("RSV bits must be zero (no extensions negotiated)");
|
|
219
|
+
const opcode = b0 & 0x0f;
|
|
220
|
+
const masked = (b1 & 0x80) !== 0;
|
|
221
|
+
let payloadLen = b1 & 0x7f;
|
|
222
|
+
let offset = 2;
|
|
223
|
+
if ((opcode & 0x8) !== 0) {
|
|
224
|
+
if (!fin)
|
|
225
|
+
throw new WebSocketProtocolError("Control frames must not be fragmented");
|
|
226
|
+
if (payloadLen > WS_MAX_CONTROL_PAYLOAD)
|
|
227
|
+
throw new WebSocketProtocolError("Control frame payload exceeds 125 bytes");
|
|
228
|
+
if (opcode !== WS_OPCODE.CLOSE &&
|
|
229
|
+
opcode !== WS_OPCODE.PING &&
|
|
230
|
+
opcode !== WS_OPCODE.PONG)
|
|
231
|
+
throw new WebSocketProtocolError(`Unknown control opcode 0x${opcode.toString(16)}`);
|
|
232
|
+
}
|
|
233
|
+
else if (opcode !== WS_OPCODE.CONTINUATION &&
|
|
234
|
+
opcode !== WS_OPCODE.TEXT &&
|
|
235
|
+
opcode !== WS_OPCODE.BINARY) {
|
|
236
|
+
throw new WebSocketProtocolError(`Unknown data opcode 0x${opcode.toString(16)}`);
|
|
237
|
+
}
|
|
238
|
+
if (payloadLen === 126) {
|
|
239
|
+
if (buf.length < offset + 2)
|
|
240
|
+
return FRAME_INCOMPLETE;
|
|
241
|
+
payloadLen = (buf[offset] << 8) | buf[offset + 1];
|
|
242
|
+
offset += 2;
|
|
243
|
+
}
|
|
244
|
+
else if (payloadLen === 127) {
|
|
245
|
+
if (buf.length < offset + 8)
|
|
246
|
+
return FRAME_INCOMPLETE;
|
|
247
|
+
// JS numbers safely represent up to 2^53 - 1. RFC permits 64-bit; we cap.
|
|
248
|
+
const hi = buf[offset] * 2 ** 24 +
|
|
249
|
+
(buf[offset + 1] << 16) +
|
|
250
|
+
(buf[offset + 2] << 8) +
|
|
251
|
+
buf[offset + 3];
|
|
252
|
+
const lo = buf[offset + 4] * 2 ** 24 +
|
|
253
|
+
(buf[offset + 5] << 16) +
|
|
254
|
+
(buf[offset + 6] << 8) +
|
|
255
|
+
buf[offset + 7];
|
|
256
|
+
if (hi > 0x1fffff)
|
|
257
|
+
throw new WebSocketProtocolError("Frame payload exceeds Number.MAX_SAFE_INTEGER");
|
|
258
|
+
payloadLen = hi * 2 ** 32 + lo;
|
|
259
|
+
offset += 8;
|
|
260
|
+
}
|
|
261
|
+
if (opts.requireMask && !masked) {
|
|
262
|
+
throw new WebSocketProtocolError("Client frames must be masked");
|
|
263
|
+
}
|
|
264
|
+
let mask;
|
|
265
|
+
if (masked) {
|
|
266
|
+
if (buf.length < offset + 4)
|
|
267
|
+
return FRAME_INCOMPLETE;
|
|
268
|
+
mask = buf.subarray(offset, offset + 4);
|
|
269
|
+
offset += 4;
|
|
270
|
+
}
|
|
271
|
+
if (buf.length < offset + payloadLen)
|
|
272
|
+
return FRAME_INCOMPLETE;
|
|
273
|
+
const payload = buf.subarray(offset, offset + payloadLen);
|
|
274
|
+
if (mask) {
|
|
275
|
+
for (let i = 0; i < payload.length; i++) {
|
|
276
|
+
payload[i] = payload[i] ^ mask[i & 3];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return { fin, opcode, payload, consumed: offset + payloadLen };
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Encode a single frame. By default the frame is emitted unmasked (server
|
|
283
|
+
* → client). Pass `mask: true` to generate a client-style masked frame (used
|
|
284
|
+
* mainly for testing).
|
|
285
|
+
*/
|
|
286
|
+
export function encodeFrame(opts) {
|
|
287
|
+
const fin = opts.fin !== false;
|
|
288
|
+
const opcode = opts.opcode & 0x0f;
|
|
289
|
+
const payload = opts.payload ?? new Uint8Array(0);
|
|
290
|
+
const masked = opts.mask === true;
|
|
291
|
+
if ((opcode & 0x8) !== 0 && payload.length > WS_MAX_CONTROL_PAYLOAD) {
|
|
292
|
+
throw new WebSocketProtocolError("Control frame payload exceeds 125 bytes");
|
|
293
|
+
}
|
|
294
|
+
let headerLen = 2;
|
|
295
|
+
let extLen = 0;
|
|
296
|
+
if (payload.length >= 65536)
|
|
297
|
+
extLen = 8;
|
|
298
|
+
else if (payload.length > 125)
|
|
299
|
+
extLen = 2;
|
|
300
|
+
headerLen += extLen;
|
|
301
|
+
if (masked)
|
|
302
|
+
headerLen += 4;
|
|
303
|
+
const out = new Uint8Array(headerLen + payload.length);
|
|
304
|
+
out[0] = (fin ? 0x80 : 0) | opcode;
|
|
305
|
+
if (extLen === 0)
|
|
306
|
+
out[1] = (masked ? 0x80 : 0) | payload.length;
|
|
307
|
+
else if (extLen === 2) {
|
|
308
|
+
out[1] = (masked ? 0x80 : 0) | 126;
|
|
309
|
+
out[2] = (payload.length >> 8) & 0xff;
|
|
310
|
+
out[3] = payload.length & 0xff;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
out[1] = (masked ? 0x80 : 0) | 127;
|
|
314
|
+
// High 4 bytes are always 0 because JS numbers can't exceed 2^53.
|
|
315
|
+
const len = payload.length;
|
|
316
|
+
out[2] = 0;
|
|
317
|
+
out[3] = 0;
|
|
318
|
+
out[4] = 0;
|
|
319
|
+
out[5] = 0;
|
|
320
|
+
out[6] = Math.floor(len / 2 ** 24) & 0xff;
|
|
321
|
+
out[7] = (len >> 16) & 0xff;
|
|
322
|
+
out[8] = (len >> 8) & 0xff;
|
|
323
|
+
out[9] = len & 0xff;
|
|
324
|
+
// Fix high-32 bits when length actually exceeds 2^32 (defensive; JS arrays cap).
|
|
325
|
+
if (len > 0xffffffff) {
|
|
326
|
+
out[2] = Math.floor(len / 2 ** 56) & 0xff;
|
|
327
|
+
out[3] = Math.floor(len / 2 ** 48) & 0xff;
|
|
328
|
+
out[4] = Math.floor(len / 2 ** 40) & 0xff;
|
|
329
|
+
out[5] = Math.floor(len / 2 ** 32) & 0xff;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (masked) {
|
|
333
|
+
const maskOff = 2 + extLen;
|
|
334
|
+
const c = globalThis.crypto;
|
|
335
|
+
if (!c?.getRandomValues) {
|
|
336
|
+
throw new Error("websocket: Web Crypto getRandomValues required to mask frames");
|
|
337
|
+
}
|
|
338
|
+
c.getRandomValues(out.subarray(maskOff, maskOff + 4));
|
|
339
|
+
const mask = out.subarray(maskOff, maskOff + 4);
|
|
340
|
+
const dataOff = maskOff + 4;
|
|
341
|
+
for (let i = 0; i < payload.length; i++) {
|
|
342
|
+
out[dataOff + i] = payload[i] ^ mask[i & 3];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
out.set(payload, 2 + extLen);
|
|
347
|
+
}
|
|
348
|
+
return out;
|
|
349
|
+
}
|
|
350
|
+
/** Encode a CLOSE frame payload (`uint16 code` + optional UTF-8 reason). */
|
|
351
|
+
export function encodeClosePayload(code, reason = "") {
|
|
352
|
+
const reasonBytes = enc.encode(reason);
|
|
353
|
+
if (reasonBytes.length > WS_MAX_CONTROL_PAYLOAD - 2) {
|
|
354
|
+
throw new WebSocketProtocolError("Close reason exceeds 123 bytes");
|
|
355
|
+
}
|
|
356
|
+
const out = new Uint8Array(2 + reasonBytes.length);
|
|
357
|
+
out[0] = (code >> 8) & 0xff;
|
|
358
|
+
out[1] = code & 0xff;
|
|
359
|
+
out.set(reasonBytes, 2);
|
|
360
|
+
return out;
|
|
361
|
+
}
|
|
362
|
+
/** Decode a CLOSE frame payload. Returns `{ code: 1005, reason: "" }` when empty. */
|
|
363
|
+
export function decodeClosePayload(payload) {
|
|
364
|
+
if (payload.length === 0)
|
|
365
|
+
return { code: WS_CLOSE_CODE.NO_STATUS_RECEIVED, reason: "" };
|
|
366
|
+
if (payload.length === 1)
|
|
367
|
+
throw new WebSocketProtocolError("Close payload must be empty or ≥2 bytes");
|
|
368
|
+
const code = (payload[0] << 8) | payload[1];
|
|
369
|
+
const reason = new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(2));
|
|
370
|
+
return { code, reason };
|
|
371
|
+
}
|
|
372
|
+
/** Thrown on RFC 6455 violations. Adapters map these to a CLOSE(1002) frame. */
|
|
373
|
+
export class WebSocketProtocolError extends Error {
|
|
374
|
+
constructor(message) {
|
|
375
|
+
super(message);
|
|
376
|
+
this.name = "WebSocketProtocolError";
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Stream-oriented assembler. Push chunks via {@link FrameSink.push}; callbacks
|
|
381
|
+
* fire as whole messages and control frames become available. Designed to be
|
|
382
|
+
* driven by an adapter's socket `data` event.
|
|
383
|
+
*/
|
|
384
|
+
export class FrameSink {
|
|
385
|
+
opts;
|
|
386
|
+
buffer = new Uint8Array(0);
|
|
387
|
+
fragments = [];
|
|
388
|
+
fragmentOpcode = -1;
|
|
389
|
+
closed = false;
|
|
390
|
+
constructor(opts) {
|
|
391
|
+
this.opts = opts;
|
|
392
|
+
}
|
|
393
|
+
push(chunk) {
|
|
394
|
+
if (this.closed)
|
|
395
|
+
return;
|
|
396
|
+
if (this.buffer.length === 0) {
|
|
397
|
+
this.buffer = chunk.slice();
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
const next = new Uint8Array(this.buffer.length + chunk.length);
|
|
401
|
+
next.set(this.buffer, 0);
|
|
402
|
+
next.set(chunk, this.buffer.length);
|
|
403
|
+
this.buffer = next;
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
while (this.buffer.length > 0) {
|
|
407
|
+
const frame = parseFrame(this.buffer, {
|
|
408
|
+
requireMask: this.opts.requireMask,
|
|
409
|
+
});
|
|
410
|
+
if (frame === FRAME_INCOMPLETE)
|
|
411
|
+
return;
|
|
412
|
+
this.buffer = this.buffer.subarray(frame.consumed);
|
|
413
|
+
this.handle(frame);
|
|
414
|
+
if (this.closed)
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
if (err instanceof WebSocketProtocolError) {
|
|
420
|
+
this.closed = true;
|
|
421
|
+
this.opts.onProtocolError(err);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
throw err;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
handle(frame) {
|
|
429
|
+
if ((frame.opcode & 0x8) !== 0) {
|
|
430
|
+
// Control frame — copy payload because the buffer slice may be reused.
|
|
431
|
+
const copy = frame.payload.slice();
|
|
432
|
+
if (frame.opcode === WS_OPCODE.CLOSE) {
|
|
433
|
+
const { code, reason } = decodeClosePayload(copy);
|
|
434
|
+
this.closed = true;
|
|
435
|
+
this.opts.onClose(code, reason);
|
|
436
|
+
}
|
|
437
|
+
else if (frame.opcode === WS_OPCODE.PING) {
|
|
438
|
+
this.opts.onPing(copy);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
this.opts.onPong(copy);
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (frame.opcode === WS_OPCODE.CONTINUATION) {
|
|
446
|
+
if (this.fragmentOpcode === -1) {
|
|
447
|
+
throw new WebSocketProtocolError("Continuation frame without an initial data frame");
|
|
448
|
+
}
|
|
449
|
+
this.fragments.push(frame.payload.slice());
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
if (this.fragmentOpcode !== -1) {
|
|
453
|
+
throw new WebSocketProtocolError("New data frame received while a fragmented message is in progress");
|
|
454
|
+
}
|
|
455
|
+
this.fragmentOpcode = frame.opcode;
|
|
456
|
+
this.fragments.push(frame.payload.slice());
|
|
457
|
+
}
|
|
458
|
+
if (frame.fin) {
|
|
459
|
+
const total = this.fragments.reduce((n, p) => n + p.length, 0);
|
|
460
|
+
const joined = new Uint8Array(total);
|
|
461
|
+
let offset = 0;
|
|
462
|
+
for (const p of this.fragments) {
|
|
463
|
+
joined.set(p, offset);
|
|
464
|
+
offset += p.length;
|
|
465
|
+
}
|
|
466
|
+
const isBinary = this.fragmentOpcode === WS_OPCODE.BINARY;
|
|
467
|
+
this.fragments = [];
|
|
468
|
+
this.fragmentOpcode = -1;
|
|
469
|
+
if (isBinary) {
|
|
470
|
+
this.opts.onMessage({ data: joined, isBinary: true });
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
let text;
|
|
474
|
+
try {
|
|
475
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(joined);
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
throw new WebSocketProtocolError("Invalid UTF-8 in text message");
|
|
479
|
+
}
|
|
480
|
+
this.opts.onMessage({ data: text, isBinary: false });
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
// ---------- Helpers shared by adapters ----------
|
|
486
|
+
/** Coerce arbitrary `send()` payloads to a `Uint8Array` + opcode pair. */
|
|
487
|
+
export function encodeSendPayload(data) {
|
|
488
|
+
if (typeof data === "string") {
|
|
489
|
+
return { opcode: WS_OPCODE.TEXT, payload: enc.encode(data) };
|
|
490
|
+
}
|
|
491
|
+
if (data instanceof Uint8Array) {
|
|
492
|
+
return { opcode: WS_OPCODE.BINARY, payload: data };
|
|
493
|
+
}
|
|
494
|
+
if (ArrayBuffer.isView(data)) {
|
|
495
|
+
return {
|
|
496
|
+
opcode: WS_OPCODE.BINARY,
|
|
497
|
+
payload: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
opcode: WS_OPCODE.BINARY,
|
|
502
|
+
payload: new Uint8Array(data),
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daloyjs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "DaloyJS is a runtime-portable, contract-first TypeScript web framework with built-in OpenAPI (Hey API), typed client generation, large-scale maintainability, and security-first defaults. Hono-grade portability, Elysia-grade DX, FastAPI-grade docs, Fastify-grade ops — distributed via pnpm.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -93,6 +93,10 @@
|
|
|
93
93
|
"types": "./dist/streaming.d.ts",
|
|
94
94
|
"import": "./dist/streaming.js"
|
|
95
95
|
},
|
|
96
|
+
"./websocket": {
|
|
97
|
+
"types": "./dist/websocket.d.ts",
|
|
98
|
+
"import": "./dist/websocket.js"
|
|
99
|
+
},
|
|
96
100
|
"./tracing": {
|
|
97
101
|
"types": "./dist/tracing.d.ts",
|
|
98
102
|
"import": "./dist/tracing.js"
|
|
@@ -138,8 +142,8 @@
|
|
|
138
142
|
"example": "node --import tsx examples/basic.ts",
|
|
139
143
|
"bench": "node --import tsx bench/router.bench.ts",
|
|
140
144
|
"test": "node --import tsx --test tests/**/*.test.ts",
|
|
141
|
-
"coverage": "node --import tsx --test --experimental-test-coverage --test-coverage-include='src/**' --test-coverage-lines=
|
|
142
|
-
"coverage:branches": "tsc -p tsconfig.coverage.json && node --test --experimental-test-coverage --test-coverage-include='dist-coverage/src/**' --test-coverage-branches=
|
|
145
|
+
"coverage": "node --import tsx --test --experimental-test-coverage --test-coverage-include='src/**' --test-coverage-lines=99.9 --test-coverage-functions=100 tests/**/*.test.ts",
|
|
146
|
+
"coverage:branches": "tsc -p tsconfig.coverage.json && node --test --experimental-test-coverage --test-coverage-include='dist-coverage/src/**' --test-coverage-branches=94 dist-coverage/tests/**/*.test.js",
|
|
143
147
|
"typecheck": "tsc --noEmit",
|
|
144
148
|
"gen:openapi": "node --import tsx scripts/dump-openapi.ts",
|
|
145
149
|
"gen:client": "openapi-ts",
|