elit 3.5.6 → 3.5.7

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.
Files changed (113) hide show
  1. package/Cargo.toml +1 -1
  2. package/README.md +1 -1
  3. package/desktop/build.rs +83 -0
  4. package/desktop/icon.rs +106 -0
  5. package/desktop/lib.rs +2 -0
  6. package/desktop/main.rs +235 -0
  7. package/desktop/native_main.rs +128 -0
  8. package/desktop/native_renderer/action_widgets.rs +184 -0
  9. package/desktop/native_renderer/app_models.rs +171 -0
  10. package/desktop/native_renderer/app_runtime.rs +140 -0
  11. package/desktop/native_renderer/container_rendering.rs +610 -0
  12. package/desktop/native_renderer/content_widgets.rs +634 -0
  13. package/desktop/native_renderer/css_models.rs +371 -0
  14. package/desktop/native_renderer/embedded_surfaces.rs +414 -0
  15. package/desktop/native_renderer/form_controls.rs +516 -0
  16. package/desktop/native_renderer/interaction_dispatch.rs +89 -0
  17. package/desktop/native_renderer/runtime_support.rs +135 -0
  18. package/desktop/native_renderer/utilities.rs +495 -0
  19. package/desktop/native_renderer/vector_drawing.rs +491 -0
  20. package/desktop/native_renderer.rs +4122 -0
  21. package/desktop/runtime/external.rs +422 -0
  22. package/desktop/runtime/mod.rs +67 -0
  23. package/desktop/runtime/quickjs.rs +106 -0
  24. package/desktop/window.rs +383 -0
  25. package/package.json +6 -3
  26. package/dist/build.d.mts +0 -20
  27. package/dist/chokidar.d.mts +0 -134
  28. package/dist/cli.d.mts +0 -81
  29. package/dist/config.d.mts +0 -254
  30. package/dist/coverage.d.mts +0 -85
  31. package/dist/database.d.mts +0 -52
  32. package/dist/desktop.d.mts +0 -68
  33. package/dist/dom.d.mts +0 -87
  34. package/dist/el.d.mts +0 -208
  35. package/dist/fs.d.mts +0 -255
  36. package/dist/hmr.d.mts +0 -38
  37. package/dist/http.d.mts +0 -169
  38. package/dist/https.d.mts +0 -108
  39. package/dist/index.d.mts +0 -13
  40. package/dist/mime-types.d.mts +0 -48
  41. package/dist/native.d.mts +0 -136
  42. package/dist/path.d.mts +0 -163
  43. package/dist/router.d.mts +0 -49
  44. package/dist/runtime.d.mts +0 -97
  45. package/dist/server-D0Dp4R5z.d.mts +0 -449
  46. package/dist/server.d.mts +0 -7
  47. package/dist/state.d.mts +0 -117
  48. package/dist/style.d.mts +0 -232
  49. package/dist/test-reporter.d.mts +0 -77
  50. package/dist/test-runtime.d.mts +0 -122
  51. package/dist/test.d.mts +0 -39
  52. package/dist/types.d.mts +0 -586
  53. package/dist/universal.d.mts +0 -21
  54. package/dist/ws.d.mts +0 -200
  55. package/dist/wss.d.mts +0 -108
  56. package/src/build.ts +0 -362
  57. package/src/chokidar.ts +0 -427
  58. package/src/cli.ts +0 -1162
  59. package/src/config.ts +0 -509
  60. package/src/coverage.ts +0 -1479
  61. package/src/database.ts +0 -1410
  62. package/src/desktop-auto-render.ts +0 -317
  63. package/src/desktop-cli.ts +0 -1533
  64. package/src/desktop.ts +0 -99
  65. package/src/dev-build.ts +0 -340
  66. package/src/dom.ts +0 -901
  67. package/src/el.ts +0 -183
  68. package/src/fs.ts +0 -609
  69. package/src/hmr.ts +0 -149
  70. package/src/http.ts +0 -856
  71. package/src/https.ts +0 -411
  72. package/src/index.ts +0 -16
  73. package/src/mime-types.ts +0 -222
  74. package/src/mobile-cli.ts +0 -2313
  75. package/src/native-background.ts +0 -444
  76. package/src/native-border.ts +0 -343
  77. package/src/native-canvas.ts +0 -260
  78. package/src/native-cli.ts +0 -414
  79. package/src/native-color.ts +0 -904
  80. package/src/native-estimation.ts +0 -194
  81. package/src/native-grid.ts +0 -590
  82. package/src/native-interaction.ts +0 -1289
  83. package/src/native-layout.ts +0 -568
  84. package/src/native-link.ts +0 -76
  85. package/src/native-render-support.ts +0 -361
  86. package/src/native-spacing.ts +0 -231
  87. package/src/native-state.ts +0 -318
  88. package/src/native-strings.ts +0 -46
  89. package/src/native-transform.ts +0 -120
  90. package/src/native-types.ts +0 -439
  91. package/src/native-typography.ts +0 -254
  92. package/src/native-units.ts +0 -441
  93. package/src/native-vector.ts +0 -910
  94. package/src/native.ts +0 -5606
  95. package/src/path.ts +0 -493
  96. package/src/pm-cli.ts +0 -2498
  97. package/src/preview-build.ts +0 -294
  98. package/src/render-context.ts +0 -138
  99. package/src/router.ts +0 -260
  100. package/src/runtime.ts +0 -97
  101. package/src/server.ts +0 -2294
  102. package/src/state.ts +0 -556
  103. package/src/style.ts +0 -1790
  104. package/src/test-globals.d.ts +0 -184
  105. package/src/test-reporter.ts +0 -609
  106. package/src/test-runtime.ts +0 -1359
  107. package/src/test.ts +0 -368
  108. package/src/types.ts +0 -381
  109. package/src/universal.ts +0 -81
  110. package/src/wapk-cli.ts +0 -3213
  111. package/src/workspace-package.ts +0 -102
  112. package/src/ws.ts +0 -648
  113. package/src/wss.ts +0 -241
package/src/ws.ts DELETED
@@ -1,648 +0,0 @@
1
- /**
2
- * WebSocket module with unified API across runtimes
3
- * Pure implementation without external dependencies
4
- * - Node.js: uses native 'ws' module (built-in WebSocket implementation)
5
- * - Bun: uses native WebSocket
6
- * - Deno: uses native WebSocket
7
- */
8
-
9
- import { EventEmitter } from 'events';
10
- import type { IncomingMessage } from './http';
11
- import { runtime } from './runtime';
12
-
13
- /**
14
- * WebSocket ready state
15
- */
16
- export enum ReadyState {
17
- CONNECTING = 0,
18
- OPEN = 1,
19
- CLOSING = 2,
20
- CLOSED = 3,
21
- }
22
-
23
- /**
24
- * WebSocket close codes
25
- */
26
- export const CLOSE_CODES = {
27
- NORMAL: 1000,
28
- GOING_AWAY: 1001,
29
- PROTOCOL_ERROR: 1002,
30
- UNSUPPORTED_DATA: 1003,
31
- NO_STATUS: 1005,
32
- ABNORMAL: 1006,
33
- INVALID_DATA: 1007,
34
- POLICY_VIOLATION: 1008,
35
- MESSAGE_TOO_BIG: 1009,
36
- EXTENSION_REQUIRED: 1010,
37
- INTERNAL_ERROR: 1011,
38
- SERVICE_RESTART: 1012,
39
- TRY_AGAIN_LATER: 1013,
40
- BAD_GATEWAY: 1014,
41
- TLS_HANDSHAKE_FAIL: 1015,
42
- } as const;
43
-
44
- /**
45
- * WebSocket data types
46
- */
47
- export type Data = string | Buffer | ArrayBuffer | Buffer[];
48
-
49
- /**
50
- * WebSocket send options
51
- */
52
- export interface SendOptions {
53
- binary?: boolean;
54
- compress?: boolean;
55
- fin?: boolean;
56
- mask?: boolean;
57
- }
58
-
59
- /**
60
- * WebSocket server options
61
- */
62
- export interface ServerOptions {
63
- host?: string;
64
- port?: number;
65
- backlog?: number;
66
- server?: any;
67
- verifyClient?: VerifyClientCallback;
68
- handleProtocols?: (protocols: Set<string>, request: IncomingMessage) => string | false;
69
- path?: string;
70
- noServer?: boolean;
71
- clientTracking?: boolean;
72
- perMessageDeflate?: boolean | object;
73
- maxPayload?: number;
74
- }
75
-
76
- /**
77
- * Verify client callback
78
- */
79
- export type VerifyClientCallback = (
80
- info: {
81
- origin: string;
82
- secure: boolean;
83
- req: IncomingMessage;
84
- },
85
- callback?: (result: boolean, code?: number, message?: string) => void
86
- ) => boolean | void;
87
-
88
- /**
89
- * Helper: Queue callback with optional error (eliminates duplication in callback handling)
90
- */
91
- function queueCallback(callback?: (err?: Error) => void, error?: Error): void {
92
- if (callback) {
93
- queueMicrotask(() => callback(error));
94
- }
95
- }
96
-
97
- /**
98
- * Helper: Create native WebSocket instance (eliminates duplication in constructor)
99
- */
100
- function createNativeWebSocket(url: string, protocols?: string[]): any {
101
- // @ts-ignore - WebSocket is available in Node.js 18+ and all modern runtimes
102
- if (runtime === 'node' && typeof globalThis.WebSocket === 'undefined') {
103
- throw new Error('WebSocket is not available. Please use Node.js 18+ or install ws package.');
104
- }
105
- // @ts-ignore
106
- return new globalThis.WebSocket(url, protocols);
107
- }
108
-
109
- function getRequestPath(url?: string): string {
110
- const [pathname = '/'] = (url || '/').split('?');
111
- return pathname || '/';
112
- }
113
-
114
- /**
115
- * WebSocket class - Pure implementation
116
- */
117
- export class WebSocket extends EventEmitter {
118
- public readyState: ReadyState = ReadyState.CONNECTING;
119
- public url: string;
120
- public protocol: string = '';
121
- public extensions: string = '';
122
- public binaryType: 'nodebuffer' | 'arraybuffer' | 'fragments' = 'nodebuffer';
123
-
124
- /** @internal */
125
- public _socket: any;
126
-
127
- constructor(address: string | URL, protocols?: string | string[], _options?: any) {
128
- super();
129
- this.url = typeof address === 'string' ? address : address.toString();
130
- const protocolsArray = Array.isArray(protocols) ? protocols : protocols ? [protocols] : undefined;
131
- this._socket = createNativeWebSocket(this.url, protocolsArray);
132
- this._setupNativeSocket();
133
- }
134
-
135
- private _setupNativeSocket(): void {
136
- this._socket.onopen = () => {
137
- this.readyState = ReadyState.OPEN;
138
- this.emit('open');
139
- };
140
-
141
- this._socket.onmessage = (event: MessageEvent) => {
142
- const isBinary = event.data instanceof ArrayBuffer || event.data instanceof Blob;
143
- this.emit('message', event.data, isBinary);
144
- };
145
-
146
- this._socket.onclose = (event: CloseEvent) => {
147
- this.readyState = ReadyState.CLOSED;
148
- this.emit('close', event.code, event.reason);
149
- };
150
-
151
- this._socket.onerror = () => {
152
- this.emit('error', new Error('WebSocket error'));
153
- };
154
- }
155
-
156
- /**
157
- * Send data through WebSocket
158
- */
159
- send(data: Data, options?: SendOptions | ((err?: Error) => void), callback?: (err?: Error) => void): void {
160
- const cb = typeof options === 'function' ? options : callback;
161
-
162
- if (this.readyState !== ReadyState.OPEN) {
163
- return queueCallback(cb, new Error('WebSocket is not open'));
164
- }
165
-
166
- try {
167
- this._socket.send(data);
168
- queueCallback(cb);
169
- } catch (error) {
170
- queueCallback(cb, error as Error);
171
- }
172
- }
173
-
174
- /**
175
- * Close the WebSocket connection
176
- */
177
- close(code?: number, reason?: string | Buffer): void {
178
- if (this.readyState === ReadyState.CLOSED || this.readyState === ReadyState.CLOSING) {
179
- return;
180
- }
181
-
182
- this.readyState = ReadyState.CLOSING;
183
- this._socket.close(code, typeof reason === 'string' ? reason : reason?.toString());
184
- }
185
-
186
- /**
187
- * Pause the socket (no-op for native WebSocket)
188
- */
189
- pause(): void {
190
- // Native WebSocket doesn't support pause
191
- }
192
-
193
- /**
194
- * Resume the socket (no-op for native WebSocket)
195
- */
196
- resume(): void {
197
- // Native WebSocket doesn't support resume
198
- }
199
-
200
- /**
201
- * Send a ping frame (no-op for native WebSocket)
202
- */
203
- ping(_data?: Data, _mask?: boolean, callback?: (err?: Error) => void): void {
204
- queueCallback(callback); // Native WebSocket doesn't expose ping
205
- }
206
-
207
- /**
208
- * Send a pong frame (no-op for native WebSocket)
209
- */
210
- pong(_data?: Data, _mask?: boolean, callback?: (err?: Error) => void): void {
211
- queueCallback(callback); // Native WebSocket doesn't expose pong
212
- }
213
-
214
- /**
215
- * Terminate the connection
216
- */
217
- terminate(): void {
218
- this._socket.close();
219
- this.readyState = ReadyState.CLOSED;
220
- }
221
-
222
- /**
223
- * Get buffered amount
224
- */
225
- get bufferedAmount(): number {
226
- return this._socket.bufferedAmount || 0;
227
- }
228
- }
229
-
230
- /**
231
- * WebSocket Server - Server-side WebSocket implementation
232
- */
233
- export class WebSocketServer extends EventEmitter {
234
- public clients: Set<WebSocket> = new Set();
235
- public options: ServerOptions;
236
- public path?: string;
237
-
238
- private _httpServer: any;
239
- private _ownsHttpServer: boolean = false;
240
-
241
- constructor(options?: ServerOptions, callback?: () => void) {
242
- super();
243
- this.options = options || {};
244
- this.path = options?.path;
245
-
246
- if (runtime === 'node') {
247
- // Node.js - create HTTP server with WebSocket upgrade
248
- if (options?.server) {
249
- this._httpServer = options.server;
250
- this._setupUpgradeHandler();
251
- } else if (options?.noServer) {
252
- // No server mode - user will call handleUpgrade manually
253
- } else {
254
- // Create new HTTP server
255
- const http = require('http');
256
- this._httpServer = http.createServer();
257
- this._ownsHttpServer = true;
258
- this._setupUpgradeHandler();
259
-
260
- if (options?.port) {
261
- this._httpServer.listen(options.port, options.host, callback);
262
- }
263
- }
264
- } else if (runtime === 'bun') {
265
- if (options?.server?.registerWebSocketServer) {
266
- this._httpServer = options.server;
267
- options.server.registerWebSocketServer(this);
268
- }
269
- queueCallback(callback as any);
270
- } else {
271
- // Bun/Deno - WebSocket server setup
272
- queueCallback(callback as any);
273
- }
274
- }
275
-
276
- private _setupUpgradeHandler(): void {
277
- this._httpServer.on('upgrade', (request: any, socket: any, head: Buffer) => {
278
- const requestPath = getRequestPath(request.url);
279
-
280
- console.log('[WebSocket] Upgrade request:', requestPath, 'Expected:', this.path || '(any)');
281
- if (this.path && requestPath !== this.path) {
282
- console.log('[WebSocket] Path mismatch, ignoring');
283
- return;
284
- }
285
-
286
- this.handleUpgrade(request, socket, head, (client) => {
287
- console.log('[WebSocket] Client connected');
288
- this.emit('connection', client, request);
289
- });
290
- });
291
- }
292
-
293
- /**
294
- * Handle HTTP upgrade for WebSocket
295
- */
296
- handleUpgrade(request: IncomingMessage, socket: any, _head: Buffer, callback: (client: WebSocket) => void): void {
297
- // Simple WebSocket handshake
298
- const key = request.headers['sec-websocket-key'];
299
- if (!key) {
300
- socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
301
- return;
302
- }
303
-
304
- // Generate accept key
305
- const crypto = require('crypto');
306
- const acceptKey = crypto
307
- .createHash('sha1')
308
- .update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
309
- .digest('base64');
310
-
311
- // Send handshake response
312
- const headers = [
313
- 'HTTP/1.1 101 Switching Protocols',
314
- 'Upgrade: websocket',
315
- 'Connection: Upgrade',
316
- `Sec-WebSocket-Accept: ${acceptKey}`,
317
- '',
318
- ''
319
- ];
320
-
321
- socket.write(headers.join('\r\n'));
322
-
323
- // Create WebSocket client from raw socket
324
- const client = this._createClientFromSocket(socket);
325
-
326
- if (this.options.clientTracking !== false) {
327
- this.clients.add(client);
328
- client.on('close', () => {
329
- this.clients.delete(client);
330
- });
331
- }
332
-
333
- callback(client);
334
- }
335
-
336
- private _createClientFromSocket(socket: any): WebSocket {
337
- const client = Object.create(WebSocket.prototype);
338
- EventEmitter.call(client);
339
-
340
- client.readyState = ReadyState.OPEN;
341
- client.url = 'ws://localhost';
342
- client.protocol = '';
343
- client.extensions = '';
344
- client.binaryType = 'nodebuffer';
345
- client._socket = socket;
346
-
347
- // Handle incoming frames
348
- socket.on('data', (data: Buffer) => {
349
- // Simple frame parsing (minimal implementation)
350
- try {
351
- const message = this._parseFrame(data);
352
- if (message) {
353
- client.emit('message', message, false);
354
- }
355
- } catch (error) {
356
- client.emit('error', error);
357
- }
358
- });
359
-
360
- socket.on('end', () => {
361
- client.readyState = ReadyState.CLOSED;
362
- client.emit('close', CLOSE_CODES.NORMAL, '');
363
- });
364
-
365
- socket.on('error', (error: Error) => {
366
- // Silently ignore connection errors (ECONNABORTED, ECONNRESET, etc.)
367
- // These are normal when clients disconnect during HMR
368
- const errorCode = (error as any).code;
369
- if (errorCode === 'ECONNABORTED' || errorCode === 'ECONNRESET' || errorCode === 'EPIPE') {
370
- // Silently ignore - connection was closed by client
371
- return;
372
- }
373
- // Only emit other errors
374
- client.emit('error', error);
375
- });
376
-
377
- // Override send method
378
- client.send = (data: Data, _options?: any, callback?: (err?: Error) => void) => {
379
- // Check if socket is still writable
380
- if (!socket.writable || client.readyState !== ReadyState.OPEN) {
381
- const err = new Error('WebSocket is not open');
382
- (err as any).code = 'WS_NOT_OPEN';
383
- queueCallback(callback, err);
384
- return;
385
- }
386
-
387
- try {
388
- const frame = this._createFrame(data);
389
- socket.write(frame, (err?: Error) => {
390
- // Handle async write errors (ECONNABORTED, ECONNRESET, etc.)
391
- if (err) {
392
- const errorCode = (err as any).code;
393
- // Silently ignore connection errors - these are normal during HMR
394
- if (errorCode !== 'ECONNABORTED' && errorCode !== 'ECONNRESET' && errorCode !== 'EPIPE') {
395
- queueCallback(callback, err);
396
- } else {
397
- // Connection closed - mark client as closed
398
- client.readyState = ReadyState.CLOSED;
399
- queueCallback(callback); // Call without error for graceful handling
400
- }
401
- } else {
402
- queueCallback(callback);
403
- }
404
- });
405
- } catch (error) {
406
- queueCallback(callback, error as Error);
407
- }
408
- };
409
-
410
- // Override close method
411
- client.close = (_code?: number, _reason?: string) => {
412
- socket.end();
413
- client.readyState = ReadyState.CLOSED;
414
- };
415
-
416
- return client;
417
- }
418
-
419
- private _createClientFromBunSocket(socket: any): WebSocket {
420
- const client = Object.create(WebSocket.prototype);
421
- EventEmitter.call(client);
422
-
423
- client.readyState = ReadyState.OPEN;
424
- client.url = 'ws://localhost';
425
- client.protocol = '';
426
- client.extensions = '';
427
- client.binaryType = 'nodebuffer';
428
- client._socket = socket;
429
-
430
- client.send = (data: Data, _options?: any, callback?: (err?: Error) => void) => {
431
- if (client.readyState !== ReadyState.OPEN) {
432
- queueCallback(callback, new Error('WebSocket is not open'));
433
- return;
434
- }
435
-
436
- try {
437
- socket.send(data);
438
- queueCallback(callback);
439
- } catch (error) {
440
- queueCallback(callback, error as Error);
441
- }
442
- };
443
-
444
- client.close = (code?: number, reason?: string) => {
445
- if (client.readyState === ReadyState.CLOSED) {
446
- return;
447
- }
448
-
449
- client.readyState = ReadyState.CLOSING;
450
- socket.close(code ?? CLOSE_CODES.NORMAL, reason);
451
- };
452
-
453
- client.terminate = () => {
454
- socket.close();
455
- client.readyState = ReadyState.CLOSED;
456
- };
457
-
458
- return client;
459
- }
460
-
461
- _handleBunOpen(socket: any, request: Partial<IncomingMessage> = {}): void {
462
- const client = this._createClientFromBunSocket(socket);
463
-
464
- if (socket.data) {
465
- socket.data.client = client;
466
- }
467
-
468
- if (this.options.clientTracking !== false) {
469
- this.clients.add(client);
470
- client.on('close', () => {
471
- this.clients.delete(client);
472
- });
473
- }
474
-
475
- const incomingRequest = {
476
- url: request.url || this.path,
477
- headers: request.headers || {},
478
- socket: request.socket || { remoteAddress: undefined },
479
- } as IncomingMessage;
480
-
481
- this.emit('connection', client, incomingRequest);
482
- }
483
-
484
- _handleBunMessage(socket: any, message: any): void {
485
- const client = socket.data?.client;
486
- if (!client) {
487
- return;
488
- }
489
-
490
- const isBinary = typeof message !== 'string';
491
- const payload = typeof message === 'string'
492
- ? message
493
- : message instanceof ArrayBuffer
494
- ? Buffer.from(message)
495
- : ArrayBuffer.isView(message)
496
- ? Buffer.from(message.buffer, message.byteOffset, message.byteLength)
497
- : Buffer.from(String(message));
498
-
499
- client.emit('message', payload, isBinary);
500
- }
501
-
502
- _handleBunClose(socket: any, code: number, reason: any): void {
503
- const client = socket.data?.client;
504
- if (!client) {
505
- return;
506
- }
507
-
508
- client.readyState = ReadyState.CLOSED;
509
- client.emit('close', code, typeof reason === 'string' ? reason : reason?.toString() || '');
510
- this.clients.delete(client);
511
- }
512
-
513
- private _parseFrame(data: Buffer): string | null {
514
- // Minimal WebSocket frame parsing
515
- if (data.length < 2) return null;
516
-
517
- const firstByte = data[0];
518
- const secondByte = data[1];
519
-
520
- const opcode = firstByte & 0x0f;
521
- const isMasked = (secondByte & 0x80) === 0x80;
522
- let payloadLength = secondByte & 0x7f;
523
- let offset = 2;
524
-
525
- if (payloadLength === 126) {
526
- payloadLength = data.readUInt16BE(2);
527
- offset = 4;
528
- } else if (payloadLength === 127) {
529
- payloadLength = Number(data.readBigUInt64BE(2));
530
- offset = 10;
531
- }
532
-
533
- let payload = data.subarray(offset);
534
-
535
- if (isMasked) {
536
- const maskKey = data.subarray(offset, offset + 4);
537
- payload = data.subarray(offset + 4, offset + 4 + payloadLength);
538
-
539
- // Unmask payload
540
- for (let i = 0; i < payload.length; i++) {
541
- payload[i] ^= maskKey[i % 4];
542
- }
543
- }
544
-
545
- // Text frame (opcode 1)
546
- if (opcode === 1) {
547
- return payload.toString('utf8');
548
- }
549
-
550
- return null;
551
- }
552
-
553
- private _createFrame(data: Data): Buffer {
554
- // Create simple text frame (opcode 1, no masking)
555
- const payload = typeof data === 'string' ? Buffer.from(data) : data;
556
- const payloadLength = Buffer.isBuffer(payload) ? payload.length : 0;
557
-
558
- let frame: Buffer;
559
- let offset = 2;
560
-
561
- if (payloadLength < 126) {
562
- frame = Buffer.allocUnsafe(2 + payloadLength);
563
- frame[1] = payloadLength;
564
- } else if (payloadLength < 65536) {
565
- frame = Buffer.allocUnsafe(4 + payloadLength);
566
- frame[1] = 126;
567
- frame.writeUInt16BE(payloadLength, 2);
568
- offset = 4;
569
- } else {
570
- frame = Buffer.allocUnsafe(10 + payloadLength);
571
- frame[1] = 127;
572
- frame.writeBigUInt64BE(BigInt(payloadLength), 2);
573
- offset = 10;
574
- }
575
-
576
- frame[0] = 0x81; // FIN + text frame
577
-
578
- if (Buffer.isBuffer(payload)) {
579
- payload.copy(frame, offset);
580
- }
581
-
582
- return frame;
583
- }
584
-
585
- /**
586
- * Close the server
587
- */
588
- close(callback?: (err?: Error) => void): void {
589
- this.clients.forEach(client => client.close());
590
- this.clients.clear();
591
-
592
- if (this._httpServer && this._ownsHttpServer) {
593
- this._httpServer.close(callback);
594
- } else {
595
- if (runtime === 'bun' && this._httpServer?.unregisterWebSocketServer) {
596
- this._httpServer.unregisterWebSocketServer(this);
597
- }
598
- this.emit('close');
599
- queueCallback(callback);
600
- }
601
- }
602
-
603
- /**
604
- * Check if server should handle request
605
- */
606
- shouldHandle(request: IncomingMessage): boolean {
607
- if (this.path && getRequestPath(request.url) !== this.path) {
608
- return false;
609
- }
610
- return true;
611
- }
612
-
613
- /**
614
- * Get server address
615
- */
616
- address(): { port: number; family: string; address: string } | null {
617
- if (this._httpServer && this._httpServer.address) {
618
- return this._httpServer.address();
619
- }
620
- return null;
621
- }
622
- }
623
-
624
- /**
625
- * Create WebSocket server
626
- */
627
- export function createWebSocketServer(options?: ServerOptions, callback?: () => void): WebSocketServer {
628
- return new WebSocketServer(options, callback);
629
- }
630
-
631
- /**
632
- * Get current runtime
633
- */
634
- export function getRuntime(): 'node' | 'bun' | 'deno' {
635
- return runtime;
636
- }
637
-
638
- /**
639
- * Default export
640
- */
641
- export default {
642
- WebSocket,
643
- WebSocketServer,
644
- createWebSocketServer,
645
- ReadyState,
646
- CLOSE_CODES,
647
- getRuntime,
648
- };