@gjsify/ws 0.52.0 → 0.53.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 +13 -0
- package/lib/esm/validation.js +1 -0
- package/lib/esm/websocket-server.js +2 -2
- package/lib/esm/websocket.js +1 -1
- package/lib/types/close-lifecycle.spec.d.ts +2 -0
- package/lib/types/validation.d.ts +9 -0
- package/lib/types/websocket-server.d.ts +1 -0
- package/lib/types/websocket.d.ts +12 -3
- package/lib/types/wss-lifecycle.spec.d.ts +2 -0
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -33,6 +33,19 @@ wss.on('connection', (client) => {
|
|
|
33
33
|
|
|
34
34
|
`WebSocketServer` supports `{ port }`, `{ server }` shared-port, and `{ noServer: true }` + `handleUpgrade()` modes, as well as `verifyClient`, `handleProtocols`, and `createWebSocketStream` (Duplex bridge). Validated against the Autobahn test suite: 510 OK / 4 NON-STRICT / 3 INFO / 0 FAILED.
|
|
35
35
|
|
|
36
|
+
## Differences from npm `ws`
|
|
37
|
+
|
|
38
|
+
- **Close codes libsoup refuses.** libsoup puts only RFC 6455's original codes in a Close
|
|
39
|
+
frame, and not 1011 from a client or 1010 from a server. For those, and for 1012–1014 from
|
|
40
|
+
either side, `close(code)` sends **1002** (protocol error) instead of the requested code — the
|
|
41
|
+
code libsoup itself falls back to. The connection still closes, and both sides' `'close'`
|
|
42
|
+
report 1002. A peer's 1012–1014 arrives as its code, but libsoup
|
|
43
|
+
answers it with 1002. A libsoup limit, tracked in the repo's `status/upstream-patch-candidates.md`.
|
|
44
|
+
- **TLS client options.** `rejectUnauthorized` is honoured (as is
|
|
45
|
+
`NODE_TLS_REJECT_UNAUTHORIZED=0`); `agent`, `ca`, `cert`, `key`, `passphrase`, `pfx`, `crl`,
|
|
46
|
+
`ciphers`, `secureProtocol`, `maxPayload`, `followRedirects`, `maxRedirects`,
|
|
47
|
+
`skipUTF8Validation` and `allowSynchronousEvents` are not.
|
|
48
|
+
|
|
36
49
|
## License
|
|
37
50
|
|
|
38
51
|
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Buffer as e}from"@gjsify/buffer";function isValidStatusCode(e){return e>=1e3&&e<=1014&&e!==1004&&e!==1005&&e!==1006||e>=3e3&&e<=4999}function closeReason(t,n){if(t!==void 0&&(typeof t!=`number`||!isValidStatusCode(t)))throw TypeError(`First argument must be a valid error code number`);if(n===void 0)return;let r=e.isBuffer(n)?n.toString(`utf8`):String(n);if(e.byteLength(r)>123)throw RangeError(`The message must not be greater than 123 bytes`);return r}export{closeReason,isValidStatusCode};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import"./constants.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"./constants.js";import{closeReason as e}from"./validation.js";import{EventEmitter as t}from"@gjsify/events";import{Buffer as n}from"@gjsify/buffer";import{abortConnection as r,isRefusedEcho as i,isTransportFailure as a,soupCloseCode as o}from"@gjsify/websocket";import{createHash as s}from"@gjsify/crypto";import c from"@girs/soup-3.0";import l from"@girs/glib-2.0";import u from"@girs/gio-2.0";import{createNodeError as d,ensureMainLoop as f}from"@gjsify/utils/core";const p=/^[+/0-9A-Za-z]{22}==$/,m=new Set;var ServerSideWebSocket=class extends t{static CONNECTING=0;static OPEN=1;static CLOSING=2;static CLOSED=3;CONNECTING=0;OPEN=1;CLOSING=2;CLOSED=3;readyState=1;protocol=``;extensions=``;url=``;_conn;constructor(e,t){super(),this._conn=e,this.url=t,e.connect(`message`,(e,t,r)=>{let i=r.get_data();if(t===c.WebsocketDataType.TEXT){let e=typeof i==`string`?i:i?new TextDecoder(`utf-8`).decode(i):``;this.emit(`message`,e,!1)}else{let e=i?n.from(i):n.alloc(0);this.emit(`message`,e,!0)}}),e.connect(`closing`,()=>{this.readyState===1&&(this.readyState=2)}),e.connect(`closed`,()=>{this.readyState=3;let t=e.get_close_code()||1006,r=e.get_close_data()||``;this.emit(`close`,t,n.from(r))}),e.connect(`error`,(e,t)=>{a(t)||i(e,t)||this.emit(`error`,Error(t.message))})}send(e,t,r){let i=typeof t==`function`?t:r;if(!this._soupOpen()){if(this.readyState===1&&(this.readyState=2),i){let e=this.readyState===3?`CLOSED`:`CLOSING`,t=Error(`WebSocket is not open: readyState ${this.readyState} (${e})`);queueMicrotask(()=>i(t))}return}try{if(typeof e==`string`){let t=new TextEncoder().encode(e);this._conn.send_message(c.WebsocketDataType.TEXT,new l.Bytes(t))}else{let t;if(n.isBuffer(e)){let n=e;t=new l.Bytes(new Uint8Array(n.buffer,n.byteOffset,n.byteLength))}else if(e instanceof ArrayBuffer)t=new l.Bytes(new Uint8Array(e));else if(ArrayBuffer.isView(e)){let n=e;t=new l.Bytes(new Uint8Array(n.buffer,n.byteOffset,n.byteLength))}else throw TypeError(`Unsupported send() payload type`);this._conn.send_message(c.WebsocketDataType.BINARY,t)}i&&queueMicrotask(()=>i())}catch(e){let t=e instanceof Error?e:Error(String(e));queueMicrotask(i?()=>i(t):()=>this.emit(`error`,t))}}close(t,n){if(this.readyState===3||this.readyState===2)return;let r=e(t,n);if(this.readyState=2,this._soupOpen())try{this._conn.close(o(this._conn,t??1e3),r??null)}catch(e){this.emit(`error`,e instanceof Error?e:Error(String(e)))}}terminate(){this.readyState!==3&&(this.readyState=2,r(this._conn))}_soupOpen(){return this._conn.get_state()===c.WebsocketState.OPEN}},WebSocketServer=class extends t{options;clients=new Set;path;_server=null;_address=null;constructor(e={},t){if(super(),this.options=e,this.path=e.path??`/`,e.noServer){if(e.port!==void 0||e.server!==void 0)throw Error(`ws.WebSocketServer: { noServer: true } is mutually exclusive with port and server.`);t&&this.once(`listening`,t);return}if(e.port===void 0&&!e.server)throw Error(`ws.WebSocketServer requires either options.port or options.server on Gjs.`);t&&this.once(`listening`,t),this._start(e)}_buildVerifyClientInfo(e){let t=e.get_request_headers(),n={};t.foreach((e,t)=>{let r=e.toLowerCase(),i=n[r];i===void 0?n[r]=t:Array.isArray(i)?i.push(t):n[r]=[i,t]});let r=e.get_uri(),i=r.get_path()??`/`,a=r.get_query(),o=a?`${i}?${a}`:i,s=e.get_remote_host()??`127.0.0.1`,c=e.get_remote_address(),l=c instanceof u.InetSocketAddress?c.get_port():0;return{origin:n.origin??``,secure:!1,req:{method:e.get_method(),url:o,headers:n,socket:{remoteAddress:s,remotePort:l}}}}_setupHandlers(e,t){try{e.remove_websocket_extension(c.WebsocketExtensionDeflate.$gtype)}catch{}if(t.verifyClient){let n=t.verifyClient;e.add_handler(this.path,(e,t)=>{if((t.get_request_headers().get_one(`Upgrade`)??``).toLowerCase()!==`websocket`)return;let r=this._buildVerifyClientInfo(t);n.length>=2?(t.pause(),n(r,(e,n=401)=>{e||t.set_status(n,null),t.unpause()})):n(r)||t.set_status(401,null)})}e.add_websocket_handler(this.path,null,null,(e,n,r,i)=>{let a=new ServerSideWebSocket(i,n.get_uri()?.to_string()??this.path),o=this._buildVerifyClientInfo(n).req;if(t.handleProtocols){let e=n.get_request_headers().get_one(`Sec-WebSocket-Protocol`)??``,r=new Set(e.split(`,`).map(e=>e.trim()).filter(Boolean)),i=t.handleProtocols(r,o);i&&(a.protocol=i)}t.clientTracking!==!1&&(this.clients.add(a),a.on(`close`,()=>this.clients.delete(a))),this.emit(`connection`,a,o)})}_start(e){try{if(e.server){let t=e.server,n=t.soupServer;if(!n)throw Error(`options.server has no active Soup.Server. Ensure httpServer.listen() was called before creating WebSocketServer.`);this._server=n,this._setupHandlers(n,e),f();let r=t.address();r&&(this._address={address:r.address,family:r.family,port:r.port}),m.add(this),queueMicrotask(()=>this.emit(`listening`))}else{this._server=new c.Server({}),this._setupHandlers(this._server,e);let t=e.host??`0.0.0.0`,n=e.port;t===`127.0.0.1`||t===`localhost`?this._server.listen_local(n,c.ServerListenOptions.IPV4_ONLY):t===`::1`?this._server.listen_local(n,c.ServerListenOptions.IPV6_ONLY):this._server.listen_all(n,0);let r=this._server.get_listeners(),i=n;if(r&&r.length>0){let e=r[0].get_local_address();e&&typeof e.get_port==`function`&&(i=e.get_port())}f(),this._address={address:t,family:`IPv4`,port:i},m.add(this),queueMicrotask(()=>this.emit(`listening`))}}catch(t){let n=d(t,`listen`,{address:e.host,port:e.port});queueMicrotask(()=>this.emit(`error`,n))}}address(){return this._address}close(e){try{m.delete(this);for(let e of this.clients)e.close();this.clients.clear(),this.options.server||this._server?.disconnect(),this._server=null,this._address=null,this.emit(`close`),e&&queueMicrotask(()=>e())}catch(t){let n=t instanceof Error?t:Error(String(t));this.emit(`error`,n),e&&queueMicrotask(()=>e(n))}}handleUpgrade(e,t,n,r){if(!this._validateUpgradeHeaders(e,t))return;let i=e.headers?.[`sec-websocket-key`]??``,doUpgrade=()=>this._completeUpgrade(e,t,i,r);if(this.options.verifyClient){let n=this.options.verifyClient,r=this._buildVerifyClientInfoFromReq(e);if(n.length>=2){n(r,(e,n=401)=>{if(!e){this._abortHandshake(t,n);return}doUpgrade()});return}if(!n(r)){this._abortHandshake(t,401);return}}doUpgrade()}shouldHandle(e){if(this.path===`/`)return!0;let t=e?.url??`/`;return t===this.path||t.startsWith(this.path+`?`)||t.startsWith(this.path+`/`)}_validateUpgradeHeaders(e,t){let n=e.headers??{};if(e.method!==`GET`)return this._abortHandshake(t,405),!1;if((n.upgrade??``).toLowerCase()!==`websocket`||!p.test(n[`sec-websocket-key`]??``))return this._abortHandshake(t,400),!1;let r=Number(n[`sec-websocket-version`]??`0`);return r!==13&&r!==8?(this._abortHandshake(t,426),!1):this.shouldHandle(e)?!0:(this._abortHandshake(t,400),!1)}_completeUpgrade(e,t,n,r){let i=[`HTTP/1.1 101 Switching Protocols`,`Upgrade: websocket`,`Connection: Upgrade`,`Sec-WebSocket-Accept: ${s(`sha1`).update(n+`258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest(`base64`)}`],a=null;if(this.options.handleProtocols){let t=e.headers?.[`sec-websocket-protocol`]??``,n=new Set(t.split(`,`).map(e=>e.trim()).filter(Boolean)),r=this.options.handleProtocols(n,this._buildVerifyClientInfoFromReq(e).req);r&&(a=r,i.push(`Sec-WebSocket-Protocol: ${r}`))}this.emit(`headers`,i,e);let o=i.join(`\r
|
|
2
2
|
`)+`\r
|
|
3
3
|
\r
|
|
4
|
-
`;t.write(
|
|
4
|
+
`;t.write(o,()=>{let n=typeof t._releaseIOStream==`function`?t._releaseIOStream():null;if(!n){t.destroy?.();return}let i=e.url??`/`,o=l.Uri.parse(`ws://localhost${i}`,l.UriFlags.NONE),s=new ServerSideWebSocket(c.WebsocketConnection.new(n,o,c.WebsocketConnectionType.SERVER,null,a,[]),i);a&&(s.protocol=a),this.options.clientTracking!==!1&&(this.clients.add(s),s.on(`close`,()=>this.clients.delete(s))),r(s,e)})}_abortHandshake(e,t){let n={400:`Bad Request`,401:`Unauthorized`,403:`Forbidden`,405:`Method Not Allowed`,426:`Upgrade Required`}[t]??`Error`;e.write?.(`HTTP/1.1 ${t} ${n}\r\nContent-Length: 0\r\nConnection: close\r\n\r\n`,()=>{e.destroy?.()})}_buildVerifyClientInfoFromReq(e){let t=e.headers??{};return{origin:t.origin??``,secure:!1,req:{method:e.method??`GET`,url:e.url??`/`,headers:t,socket:{remoteAddress:e.socket?.remoteAddress??`127.0.0.1`,remotePort:e.socket?.remotePort??0}}}}};export{WebSocketServer};
|
package/lib/esm/websocket.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{BINARY_TYPES as e}from"./constants.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{BINARY_TYPES as e}from"./constants.js";import{closeReason as t}from"./validation.js";import{EventEmitter as n}from"@gjsify/events";import{Buffer as r}from"@gjsify/buffer";import{WebSocket as i,isTransportFailure as a,kClose as o}from"@gjsify/websocket";var WebSocket=class extends n{static CONNECTING=0;static OPEN=1;static CLOSING=2;static CLOSED=3;CONNECTING=0;OPEN=1;CLOSING=2;CLOSED=3;readyState=0;url=``;protocol=``;extensions=``;bufferedAmount=0;binaryType=`nodebuffer`;_native=null;constructor(e,t,n={}){if(super(),e===null){queueMicrotask(()=>this._fail(`Constructing ws.WebSocket with null address is not supported on Gjs`));return}this.url=typeof e==`string`?e:String(e);let r=n,i;typeof t==`string`||Array.isArray(t)?i=t:t!=null&&(r=t);let a=this._resolveProtocols(i,r);this._openNative(this.url,a,r)}_resolveProtocols(e,t){if(e!==void 0)return Array.isArray(e)?e:[e];if(t.protocols!==void 0)return Array.isArray(t.protocols)?t.protocols:[t.protocols];if(t.protocol!==void 0)return[t.protocol]}_openNative(e,t,n){if(typeof i!=`function`){queueMicrotask(()=>this._fail("@gjsify/websocket provided no WebSocket constructor. On Node.js 22+ globalThis.WebSocket is native; on older Node install `ws` directly, or ensure globalThis.WebSocket is set before @gjsify/ws is imported."));return}let r={perMessageDeflate:n.perMessageDeflate!==!1,headers:n.headers,origin:n.origin,handshakeTimeout:n.handshakeTimeout,rejectUnauthorized:n.rejectUnauthorized};try{this._native=new i(e,t,r)}catch(e){queueMicrotask(()=>this._fail(e instanceof Error?e:Error(String(e))));return}this._native.binaryType=`arraybuffer`,this._native.addEventListener(`open`,()=>this._onOpen()),this._native.addEventListener(`message`,e=>this._onMessage(e)),this._native.addEventListener(`close`,e=>this._onClose(e)),this._native.addEventListener(`error`,e=>this._onError(e))}_fail(e){let t=typeof e==`string`?Error(e):e;this.readyState=3,this.emit(`error`,t),this._dispatchEvent(`error`,{error:t,message:t.message}),this.emit(`close`,1006,r.from(t.message)),this._dispatchEvent(`close`,{code:1006,reason:t.message,wasClean:!1})}_onOpen(){this.readyState=1,typeof this._native?.protocol==`string`&&(this.protocol=this._native.protocol),typeof this._native?.extensions==`string`&&(this.extensions=this._native.extensions),this.emit(`open`),this._dispatchEvent(`open`,{})}_onMessage(e){let t=e?.data,n,r=!1;typeof t==`string`?(n=t,r=!1):t instanceof ArrayBuffer?(r=!0,n=this._decodeBinary(t)):ArrayBuffer.isView(t)?(r=!0,n=this._decodeBinary(t.buffer)):(n=t,r=!1),this.emit(`message`,n,r),this._dispatchEvent(`message`,{data:n,type:r?`binary`:`text`})}_decodeBinary(e){switch(this.binaryType){case`arraybuffer`:return e;case`fragments`:return[r.from(e)];case`blob`:{let t=globalThis.Blob;return t?new t([new Uint8Array(e)]):r.from(e)}default:return r.from(e)}}_onClose(e){let t=typeof e?.code==`number`?e.code:1006,n=typeof e?.reason==`string`?e.reason:``;this.readyState=3,this.emit(`close`,t,r.from(n)),this._dispatchEvent(`close`,{code:t,reason:n,wasClean:!!e?.wasClean})}_onError(e){if(e?.error instanceof Error&&a(e.error.cause))return;let t=typeof e?.message==`string`&&e.message||`WebSocket error`,n=e?.error instanceof Error?e.error:Error(t);this.emit(`error`,n),this._dispatchEvent(`error`,{error:n,message:t})}send(e,t,n){let r=typeof t==`function`?t:n;if(this.readyState===0)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(this.readyState===1&&this._native?.readyState===2&&(this.readyState=2),this.readyState!==1){let e=Error(`WebSocket is not open: readyState `+this.readyState);queueMicrotask(r?()=>r(e):()=>this.emit(`error`,e));return}this._nativeSend(e,r)}_nativeSend(e,t){try{let n;n=typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):r.isBuffer(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e:String(e),this._native?.send(n),t&&queueMicrotask(()=>t())}catch(e){let n=e instanceof Error?e:Error(String(e));queueMicrotask(t?()=>t(n):()=>this.emit(`error`,n))}}_sizeOf(e){return typeof e==`string`?e.length:e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:0}close(e,n){if(this.readyState===3)return;if(this.readyState===0){this.readyState=2,this._nativeClose();return}if(this.readyState===2)return;let r=t(e,n);this.readyState=2;try{this._nativeClose(e,r)}catch(e){this.emit(`error`,e instanceof Error?e:Error(String(e)))}}_nativeClose(e,t){let n=this._native;n&&(n[o]?n[o](e,t):e===void 0?n.close():t===void 0?n.close(e):n.close(e,t))}terminate(){if(this.readyState===3)return;this.readyState=2;let e=this._native;e&&(e[o]?e[o](1006):e.close())}get isPaused(){return this.readyState===2||this.readyState===3}_eventTargetListeners=new Map;addEventListener(e,t){let n=this._eventTargetListeners.get(e);n||(n=new Set,this._eventTargetListeners.set(e,n)),n.add(t)}removeEventListener(e,t){this._eventTargetListeners.get(e)?.delete(t)}_dispatchEvent(e,t){let n=this._eventTargetListeners.get(e);if(!n||n.size===0)return;let r=Object.assign({type:e,target:this},t);for(let e of n)try{e(r)}catch(e){queueMicrotask(()=>this.emit(`error`,e))}}static get BINARY_TYPES(){return e}};WebSocket.WebSocket=WebSocket;export{WebSocket};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Buffer } from '@gjsify/buffer';
|
|
2
|
+
/** The status codes ws lets an endpoint send: RFC 6455's defined codes minus
|
|
3
|
+
* the three that must never go on the wire (1004 reserved, 1005/1006
|
|
4
|
+
* local-only), plus the registered and private ranges. */
|
|
5
|
+
export declare function isValidStatusCode(code: number): boolean;
|
|
6
|
+
/** Validate close(code, reason) the way ws does before anything is sent, and
|
|
7
|
+
* return the reason as a string. ws throws these to the caller of close();
|
|
8
|
+
* Soup would instead log a CRITICAL for 1005/1006 and send nothing. */
|
|
9
|
+
export declare function closeReason(code: unknown, reason: string | Buffer | undefined): string | undefined;
|
|
@@ -96,6 +96,7 @@ declare class ServerSideWebSocket extends EventEmitter {
|
|
|
96
96
|
send(data: string | Buffer | ArrayBuffer | ArrayBufferView, optionsOrCb?: ((err?: Error) => void) | object, cb?: (err?: Error) => void): void;
|
|
97
97
|
close(code?: number, reason?: string | Buffer): void;
|
|
98
98
|
terminate(): void;
|
|
99
|
+
private _soupOpen;
|
|
99
100
|
}
|
|
100
101
|
/** `ws.WebSocketServer` — listens on a TCP port (or attaches to an existing
|
|
101
102
|
* @gjsify/http Server) and emits 'connection' events wrapping
|
package/lib/types/websocket.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ export interface ClientOptions {
|
|
|
25
25
|
origin?: string;
|
|
26
26
|
headers?: Record<string, string | string[]>;
|
|
27
27
|
handshakeTimeout?: number;
|
|
28
|
+
/** `false` accepts a self-signed or otherwise unverifiable server
|
|
29
|
+
* certificate on `wss:`. */
|
|
30
|
+
rejectUnauthorized?: boolean;
|
|
28
31
|
/** Enable permessage-deflate (RFC 7692). Defaults to true, matching the real
|
|
29
32
|
* ws npm package. Set to false to disable deflate negotiation (useful when
|
|
30
33
|
* the remote server has buggy deflate handling). */
|
|
@@ -77,6 +80,7 @@ export declare class WebSocket extends EventEmitter {
|
|
|
77
80
|
* because the W3C ambient type comes from multiple realms depending on where
|
|
78
81
|
* this bundle ends up (GJS browser-like globals vs. Node's undici). */
|
|
79
82
|
private _native;
|
|
83
|
+
constructor(address: string | URL | null, options?: ClientOptions);
|
|
80
84
|
constructor(address: string | URL | null, protocols?: string | string[], options?: ClientOptions);
|
|
81
85
|
/** Merge `protocols` arg and `options.protocols` / `options.protocol`. */
|
|
82
86
|
private _resolveProtocols;
|
|
@@ -99,9 +103,14 @@ export declare class WebSocket extends EventEmitter {
|
|
|
99
103
|
private _nativeSend;
|
|
100
104
|
private _sizeOf;
|
|
101
105
|
close(code?: number, reason?: string | Buffer): void;
|
|
102
|
-
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
106
|
+
/** The W3C close() rejects 1001–1014, which ws sends; @gjsify/websocket
|
|
107
|
+
* takes them through its internal hook. A host's own WebSocket has no
|
|
108
|
+
* hook and keeps its W3C rules. */
|
|
109
|
+
private _nativeClose;
|
|
110
|
+
/** ws-only: drop the connection without a Close frame; 'close' follows
|
|
111
|
+
* with 1006. The W3C close() cannot express that (it rejects 1006);
|
|
112
|
+
* @gjsify/websocket's close hook reads 1006 — RFC 6455's code for a
|
|
113
|
+
* connection closed without a Close frame — as exactly this. */
|
|
105
114
|
terminate(): void;
|
|
106
115
|
/** Convenience: returns true if the socket is closed or closing. Matches
|
|
107
116
|
* ws.isPaused() / internal state checks that some consumers rely on. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/ws",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "Drop-in replacement for the `ws` npm package on Gjs — wraps globalThis.WebSocket (Soup.WebsocketConnection) and Soup.Server for the WebSocketServer side",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -41,15 +41,16 @@
|
|
|
41
41
|
"@girs/gio-2.0": "5.4.0",
|
|
42
42
|
"@girs/glib-2.0": "5.4.0",
|
|
43
43
|
"@girs/soup-3.0": "5.4.0",
|
|
44
|
-
"@gjsify/buffer": "^0.
|
|
45
|
-
"@gjsify/crypto": "^0.
|
|
46
|
-
"@gjsify/events": "^0.
|
|
47
|
-
"@gjsify/utils": "^0.
|
|
48
|
-
"@gjsify/websocket": "^0.
|
|
44
|
+
"@gjsify/buffer": "^0.53.0",
|
|
45
|
+
"@gjsify/crypto": "^0.53.0",
|
|
46
|
+
"@gjsify/events": "^0.53.0",
|
|
47
|
+
"@gjsify/utils": "^0.53.0",
|
|
48
|
+
"@gjsify/websocket": "^0.53.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@gjsify/cli": "^0.
|
|
52
|
-
"@gjsify/
|
|
51
|
+
"@gjsify/cli": "^0.53.0",
|
|
52
|
+
"@gjsify/runtime": "^0.53.0",
|
|
53
|
+
"@gjsify/unit": "^0.53.0",
|
|
53
54
|
"@types/node": "^25.9.2",
|
|
54
55
|
"typescript": "^6.0.3"
|
|
55
56
|
},
|