transport-io 0.8.0 → 0.9.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 +3 -1
- package/dist/client.d.ts +5 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +21 -8
- package/dist/client.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/protocol.d.ts +5 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +5 -0
- package/dist/protocol.js.map +1 -1
- package/dist/transport/fails.node.d.ts +0 -6
- package/dist/transport/fails.node.d.ts.map +1 -1
- package/dist/transport/fails.node.js +0 -10
- package/dist/transport/fails.node.js.map +1 -1
- package/dist/transport/websocket-connection.d.ts +52 -0
- package/dist/transport/websocket-connection.d.ts.map +1 -0
- package/dist/transport/websocket-connection.js +236 -0
- package/dist/transport/websocket-connection.js.map +1 -0
- package/dist/transport/websocket.d.ts +1 -53
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/transport/websocket.js +5 -176
- package/dist/transport/websocket.js.map +1 -1
- package/dist/transport/websocket.node.d.ts.map +1 -1
- package/dist/transport/websocket.node.js +8 -17
- package/dist/transport/websocket.node.js.map +1 -1
- package/package.json +4 -11
package/README.md
CHANGED
|
@@ -22,7 +22,9 @@ before you start.** It lists what this library will not do. Full documentation i
|
|
|
22
22
|
[repository README](https://github.com/transport-io/transport-io#readme). The short version:
|
|
23
23
|
|
|
24
24
|
- **WebTransport first.** The WebSocket fallback carries emits only, where the contract
|
|
25
|
-
declares it; calls and streams need WebTransport.
|
|
25
|
+
declares it; calls and streams need WebTransport. The
|
|
26
|
+
[fallback guide](https://transport-io.github.io/transport-io/guides/fallback/) has it end
|
|
27
|
+
to end.
|
|
26
28
|
- **Chrome and Firefox.** Safari cannot talk to a quiche-backed server and is unsupported.
|
|
27
29
|
- **The server needs a separate native install**, and its Linux prebuild needs glibc 2.38 -
|
|
28
30
|
no default Node `-slim` image has it, and Alpine has no prebuild at all.
|
package/dist/client.d.ts
CHANGED
|
@@ -20,8 +20,8 @@ export interface ClientState {
|
|
|
20
20
|
/** What carries the current session. `null` until connected. */
|
|
21
21
|
readonly transport: Transport | null;
|
|
22
22
|
/**
|
|
23
|
-
* Why the current session is a fallback: the runtime has no WebTransport, or the
|
|
24
|
-
*
|
|
23
|
+
* Why the current session is a fallback: the runtime has no WebTransport, or the
|
|
24
|
+
* WebTransport handshake failed and the WebSocket connected. `null` on a native session.
|
|
25
25
|
*/
|
|
26
26
|
readonly fallbackReason: FallbackReason | null;
|
|
27
27
|
}
|
|
@@ -89,9 +89,9 @@ export type FallbackClient<M extends AnyMap> = Omit<Client<M>, 'call' | 'stream'
|
|
|
89
89
|
/**
|
|
90
90
|
* A client with a second transport behind the first (D121).
|
|
91
91
|
*
|
|
92
|
-
* The native connector is tried first, every time. The fallback is used
|
|
93
|
-
*
|
|
94
|
-
* the snapshot says which. The type argument is the gate: `FallbackReady<M>` is `unknown`
|
|
92
|
+
* The native connector is tried first, every time. The fallback is used when the runtime
|
|
93
|
+
* has no WebTransport, and when the WebTransport handshake fails and the WebSocket connects,
|
|
94
|
+
* and the snapshot says which. The type argument is the gate: `FallbackReady<M>` is `unknown`
|
|
95
95
|
* when every unreliable event in the map declares a fallback, and otherwise a required
|
|
96
96
|
* property naming the event that has not, so this call fails to compile rather than an
|
|
97
97
|
* emit failing in production.
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAW,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEjE,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE/E,sFAAsF;AACtF,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,aAAa,CAAA;AAE1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAAA;IACzC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IACpC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;CAC/C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAErC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAA;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,mFAAmF;IACnF,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;IACpD,gFAAgF;IAChF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,qBAAa,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU;;IA0B/C,YAAY,IAAI,EAAE,aAAa,EAE9B;IAED;;;;OAIG;IACH,WAAW,IAAI,WAAW,CAEzB;IAED,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAK1C;IAED;oFACgF;IAC1E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAS7B;IAED,UAAU,IAAI,IAAI,CA2BjB;IAED,mEAAmE;IACnE,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,CAEzE;IAED,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC3B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,IAAI,GAC1C,MAAM,IAAI,CAYZ;IAED,qFAAqF;IAC/E,IAAI,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,EACzC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EACxB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAE1B;IAED;;;;;OAKG;IACH,MAAM,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,EACvC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EACxB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAI9B;IAED,KAAK,IAAI,YAAY,GAAG,SAAS,CAEhC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -210,9 +210,13 @@ export class Client {
|
|
|
210
210
|
}
|
|
211
211
|
/**
|
|
212
212
|
* The native connector, then the fallback if one was installed and the failure is one a
|
|
213
|
-
* fallback answers
|
|
214
|
-
*
|
|
215
|
-
*
|
|
213
|
+
* fallback answers. No WebTransport in this runtime: the fallback carries the session. A
|
|
214
|
+
* WebTransport handshake that failed: the fallback is dialled, because a connector is a
|
|
215
|
+
* closure and the WebSocket handshake is the one fact this client can obtain about whether
|
|
216
|
+
* the server is up over TCP (D125). If that fails too, the WebTransport error is the one
|
|
217
|
+
* thrown: it names the primary transport, and its message says what its probe found. Every
|
|
218
|
+
* other failure is thrown as it is, because a certificate past its validity or a dev
|
|
219
|
+
* connector outside the dev command is configuration, not a path to route around.
|
|
216
220
|
*/
|
|
217
221
|
async #open() {
|
|
218
222
|
const fallback = fallbacks.get(this);
|
|
@@ -225,7 +229,16 @@ export class Client {
|
|
|
225
229
|
const reason = fallbackReasonFor(e);
|
|
226
230
|
if (reason === undefined)
|
|
227
231
|
throw e;
|
|
228
|
-
|
|
232
|
+
if (reason === 'unsupported')
|
|
233
|
+
return { conn: await fallback(), fallbackReason: reason };
|
|
234
|
+
let conn;
|
|
235
|
+
try {
|
|
236
|
+
conn = await fallback();
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
throw e;
|
|
240
|
+
}
|
|
241
|
+
return { conn, fallbackReason: reason };
|
|
229
242
|
}
|
|
230
243
|
}
|
|
231
244
|
#requireSession() {
|
|
@@ -251,16 +264,16 @@ function fallbackReasonFor(e) {
|
|
|
251
264
|
return undefined;
|
|
252
265
|
if (e.code === 'WT_NO_SUPPORT')
|
|
253
266
|
return 'unsupported';
|
|
254
|
-
if (e.code === 'WT_UDP_UNREACHABLE')
|
|
267
|
+
if (e.code === 'WT_UDP_UNREACHABLE' || e.code === 'WT_HANDSHAKE_FAILED')
|
|
255
268
|
return 'unreachable';
|
|
256
269
|
return undefined;
|
|
257
270
|
}
|
|
258
271
|
/**
|
|
259
272
|
* A client with a second transport behind the first (D121).
|
|
260
273
|
*
|
|
261
|
-
* The native connector is tried first, every time. The fallback is used
|
|
262
|
-
*
|
|
263
|
-
* the snapshot says which. The type argument is the gate: `FallbackReady<M>` is `unknown`
|
|
274
|
+
* The native connector is tried first, every time. The fallback is used when the runtime
|
|
275
|
+
* has no WebTransport, and when the WebTransport handshake fails and the WebSocket connects,
|
|
276
|
+
* and the snapshot says which. The type argument is the gate: `FallbackReady<M>` is `unknown`
|
|
264
277
|
* when every unreliable event in the map declares a fallback, and otherwise a required
|
|
265
278
|
* property naming the event that has not, so this call fails to compile rather than an
|
|
266
279
|
* emit failing in production.
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,5 +14,5 @@ export { createServer, Server, } from './server.js';
|
|
|
14
14
|
* `changeset version` moves the manifest, so this moves in the same commit - which the test
|
|
15
15
|
* enforces rather than trusting anyone to remember.
|
|
16
16
|
*/
|
|
17
|
-
export const VERSION = '0.
|
|
17
|
+
export const VERSION = '0.9.0';
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
package/dist/protocol.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export declare const FALLBACK_UNRELIABLE_LOW_WATER = 32;
|
|
|
24
24
|
export declare const WS_CLOSE_NORMAL = 1000;
|
|
25
25
|
export declare const WS_CLOSE_OFFSET = 3000;
|
|
26
26
|
export declare const WS_CLOSE_REASON_MAX_BYTES = 123;
|
|
27
|
+
/** PROTOCOL.md §3.3 - a peer that has sent nothing for this long sends an empty message. */
|
|
28
|
+
export declare const WS_KEEPALIVE_INTERVAL_MS = 15000;
|
|
29
|
+
/** PROTOCOL.md §3.3 - a peer that has received nothing for this long closes as WT_IDLE_TIMEOUT. */
|
|
30
|
+
export declare const WS_IDLE_TIMEOUT_MS = 45000;
|
|
27
31
|
/** PROTOCOL.md §5.2 */
|
|
28
32
|
export declare const FrameType: {
|
|
29
33
|
readonly HANDSHAKE: 1;
|
|
@@ -105,6 +109,7 @@ export declare const CloseCode: {
|
|
|
105
109
|
readonly WT_HANDSHAKE_TIMEOUT: 1002;
|
|
106
110
|
readonly WT_PEER_TOO_SLOW: 1003;
|
|
107
111
|
readonly WT_PROTOCOL_ERROR: 1004;
|
|
112
|
+
readonly WT_IDLE_TIMEOUT: 1005;
|
|
108
113
|
readonly WT_RELIABILITY_REFUSED: 1006;
|
|
109
114
|
};
|
|
110
115
|
export type CloseCode = (typeof CloseCode)[keyof typeof CloseCode];
|
package/dist/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,IAAI,CAAA;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,yBAAyB,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/protocol.js
CHANGED
|
@@ -24,6 +24,10 @@ export const FALLBACK_UNRELIABLE_LOW_WATER = 32;
|
|
|
24
24
|
export const WS_CLOSE_NORMAL = 1000;
|
|
25
25
|
export const WS_CLOSE_OFFSET = 3000;
|
|
26
26
|
export const WS_CLOSE_REASON_MAX_BYTES = 123;
|
|
27
|
+
/** PROTOCOL.md §3.3 - a peer that has sent nothing for this long sends an empty message. */
|
|
28
|
+
export const WS_KEEPALIVE_INTERVAL_MS = 15_000;
|
|
29
|
+
/** PROTOCOL.md §3.3 - a peer that has received nothing for this long closes as WT_IDLE_TIMEOUT. */
|
|
30
|
+
export const WS_IDLE_TIMEOUT_MS = 45_000;
|
|
27
31
|
/** PROTOCOL.md §5.2 */
|
|
28
32
|
export const FrameType = {
|
|
29
33
|
HANDSHAKE: 0x01,
|
|
@@ -103,6 +107,7 @@ export const CloseCode = {
|
|
|
103
107
|
WT_HANDSHAKE_TIMEOUT: 1002,
|
|
104
108
|
WT_PEER_TOO_SLOW: 1003,
|
|
105
109
|
WT_PROTOCOL_ERROR: 1004,
|
|
110
|
+
WT_IDLE_TIMEOUT: 1005,
|
|
106
111
|
WT_RELIABILITY_REFUSED: 1006,
|
|
107
112
|
};
|
|
108
113
|
//# sourceMappingURL=protocol.js.map
|
package/dist/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAA;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAA;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAA;AACnC,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { Client, type ClientOptions } from '../client.ts';
|
|
2
2
|
import type { AnyMap, Registered } from '../contract.ts';
|
|
3
3
|
import type { Connection } from './types.ts';
|
|
4
|
-
/**
|
|
5
|
-
* The reset code is only recoverable from the message text, because the error type omits
|
|
6
|
-
* the field the specification defines. Parsing lives in exactly this one function, with a
|
|
7
|
-
* test pinning the observed format, so the upstream defect stays contained.
|
|
8
|
-
*/
|
|
9
|
-
export declare function resetCodeFromError(error: unknown): number | undefined;
|
|
10
4
|
export interface Http3ServerOptions {
|
|
11
5
|
readonly port: number;
|
|
12
6
|
readonly host?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fails.node.d.ts","sourceRoot":"","sources":["../../src/transport/fails.node.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAIxD,OAAO,KAAK,EAAyB,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"fails.node.d.ts","sourceRoot":"","sources":["../../src/transport/fails.node.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAIxD,OAAO,KAAK,EAAyB,UAAU,EAAE,MAAM,YAAY,CAAA;AAqHnE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,IAAI,aAAa,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,IAAI,IAAI,CAAA;CACb;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiClF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAYxD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAA;IACpC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAChC;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiCjF;AAED,sFAAsF;AACtF,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,EACpC,mBAAmB;CAAG;AAE1B;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU,EAC7D,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAIpB"}
|
|
@@ -18,16 +18,6 @@ import { Client } from '../client.js';
|
|
|
18
18
|
import { TransportError } from '../errors.js';
|
|
19
19
|
import { DATAGRAM_CONSERVATIVE_FLOOR } from '../protocol.js';
|
|
20
20
|
import { handshakeFailure, probe, probeTarget } from './probe.js';
|
|
21
|
-
/**
|
|
22
|
-
* The reset code is only recoverable from the message text, because the error type omits
|
|
23
|
-
* the field the specification defines. Parsing lives in exactly this one function, with a
|
|
24
|
-
* test pinning the observed format, so the upstream defect stays contained.
|
|
25
|
-
*/
|
|
26
|
-
export function resetCodeFromError(error) {
|
|
27
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
-
const m = /code:\s*(\d+)/i.exec(message);
|
|
29
|
-
return m?.[1] === undefined ? undefined : Number(m[1]);
|
|
30
|
-
}
|
|
31
21
|
class FailsConnection {
|
|
32
22
|
#session;
|
|
33
23
|
closed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fails.node.js","sourceRoot":"","sources":["../../src/transport/fails.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AACxF,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAmBjE
|
|
1
|
+
{"version":3,"file":"fails.node.js","sourceRoot":"","sources":["../../src/transport/fails.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BidiStream, CloseInfo, Connection } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* What this needs from a socket: the WHATWG surface, which browsers, Node and `ws` share.
|
|
4
|
+
* `readyState` 1 is open on every one of them.
|
|
5
|
+
*/
|
|
6
|
+
export interface SocketLike {
|
|
7
|
+
binaryType: string;
|
|
8
|
+
readonly bufferedAmount: number;
|
|
9
|
+
readonly readyState: number;
|
|
10
|
+
send(data: Uint8Array): void;
|
|
11
|
+
close(code?: number, reason?: string): void;
|
|
12
|
+
addEventListener(type: 'message', listener: (ev: {
|
|
13
|
+
readonly data: unknown;
|
|
14
|
+
}) => void): void;
|
|
15
|
+
addEventListener(type: 'close', listener: (ev: {
|
|
16
|
+
readonly code: number;
|
|
17
|
+
readonly reason: string;
|
|
18
|
+
}) => void): void;
|
|
19
|
+
addEventListener(type: 'error', listener: () => void): void;
|
|
20
|
+
addEventListener(type: 'open', listener: () => void): void;
|
|
21
|
+
}
|
|
22
|
+
export interface WebSocketConnectionOptions {
|
|
23
|
+
/** For the test that proves the bound; production never sets it. */
|
|
24
|
+
readonly lowWaterBytes?: number;
|
|
25
|
+
/** For the tests that prove the deadline; production never sets them. */
|
|
26
|
+
readonly keepaliveIntervalMs?: number;
|
|
27
|
+
readonly idleTimeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare class WebSocketConnection implements Connection {
|
|
30
|
+
#private;
|
|
31
|
+
readonly closed: Promise<CloseInfo>;
|
|
32
|
+
constructor(socket: SocketLike, opts?: WebSocketConnectionOptions);
|
|
33
|
+
openEmitStream(): Promise<WritableStream<Uint8Array>>;
|
|
34
|
+
/** The socket is the peer's emit stream, so it is delivered at once rather than awaited. */
|
|
35
|
+
onEmitStream(cb: (readable: ReadableStream<Uint8Array>) => void): void;
|
|
36
|
+
openBidi(): Promise<BidiStream>;
|
|
37
|
+
onBidi(): void;
|
|
38
|
+
sendDatagram(): void;
|
|
39
|
+
onDatagram(): void;
|
|
40
|
+
/** The same ceiling as the native transport, so an application's limit never moves with it. */
|
|
41
|
+
maxDatagramSize(): number;
|
|
42
|
+
reliability(): 'reliable-only';
|
|
43
|
+
kind(): 'websocket';
|
|
44
|
+
close(code: number, reason: string): void;
|
|
45
|
+
}
|
|
46
|
+
/** §3.3: `WT_NO_ERROR` is a normal closure; every other session code rides in the private range. */
|
|
47
|
+
export declare function toWebSocketCloseCode(code: number): number;
|
|
48
|
+
/** The inverse, with the socket's own codes (a lost connection is 1006) passed through as they are. */
|
|
49
|
+
export declare function fromWebSocketCloseCode(code: number): number;
|
|
50
|
+
/** Whole characters only, so a cut never leaves half a code point on the wire. */
|
|
51
|
+
export declare function truncateCloseReason(reason: string): string;
|
|
52
|
+
//# sourceMappingURL=websocket-connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-connection.d.ts","sourceRoot":"","sources":["../../src/transport/websocket-connection.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEnE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;IAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAA;IAC3F,gBAAgB,CACd,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACzE,IAAI,CAAA;IACP,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;IAC3D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;CAC3D;AAcD,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,qBAAa,mBAAoB,YAAW,UAAU;;IAYpD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAEnC,YAAY,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,0BAA+B,EAwCpE;IAEK,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CA0B1D;IAED,4FAA4F;IAC5F,YAAY,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,IAAI,GAAG,IAAI,CAErE;IAED,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAE9B;IAED,MAAM,IAAI,IAAI,CAEb;IAED,YAAY,IAAI,IAAI,CAQnB;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,+FAA+F;IAC/F,eAAe,IAAI,MAAM,CAExB;IAED,WAAW,IAAI,eAAe,CAE7B;IAED,IAAI,IAAI,WAAW,CAElB;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAexC;CAkCF;AAkBD,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,uGAAuG;AACvG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS1D"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emit lane over a WebSocket: the mapping, PROTOCOL.md §3.3. Internal (D127):
|
|
3
|
+
* `transport-io/websocket-transport` exports the connector alone and
|
|
4
|
+
* `transport-io/websocket-node-transport` the listener, and this class is what both hand to
|
|
5
|
+
* a session. The transport seam it implements is not exported either (D21).
|
|
6
|
+
*
|
|
7
|
+
* A WebSocket is one ordered, reliable pipe per direction, which is what the emit lane
|
|
8
|
+
* already is (D32), so this Connection is the socket itself: `openEmitStream` writes to it,
|
|
9
|
+
* `onEmitStream` reads from it, and the framer above runs untouched, treating each message
|
|
10
|
+
* as bytes of the same stream. Everything else on the seam refuses. There are no
|
|
11
|
+
* bidirectional streams, so a session on this transport carries no calls and no `stream()`,
|
|
12
|
+
* and there are no datagrams: an unreliable event whose contract declared a fallback travels
|
|
13
|
+
* as a `DATAGRAM` frame on the emit lane instead, wrapped and unwrapped by the session (D122).
|
|
14
|
+
*
|
|
15
|
+
* What the socket does not give for free is write completion. A browser exposes only
|
|
16
|
+
* `bufferedAmount`, with no event when it drains, so the sink polls it before resolving a
|
|
17
|
+
* write. Without that every write would resolve at once, and the emit queue's 256-frame
|
|
18
|
+
* bound would measure nothing: `writer.ready` on the reference binding in a new costume
|
|
19
|
+
* (D93). `websocket.node.test.ts` reaches the bound on a real socket with the peer paused,
|
|
20
|
+
* and shows it unreachable with the polling off.
|
|
21
|
+
*
|
|
22
|
+
* Nor does it give liveness. TCP reports a dead path late or never, and a WebSocket has no
|
|
23
|
+
* idle timeout of its own, so the mapping carries one (D126): an empty message after
|
|
24
|
+
* `WS_KEEPALIVE_INTERVAL_MS` with nothing sent, consumed by the receiver as no bytes at all,
|
|
25
|
+
* and a close as `WT_IDLE_TIMEOUT` after `WS_IDLE_TIMEOUT_MS` with nothing received.
|
|
26
|
+
*/
|
|
27
|
+
import { TransportError } from '../errors.js';
|
|
28
|
+
import { CloseCode, DATAGRAM_CONSERVATIVE_FLOOR, WS_CLOSE_NORMAL, WS_CLOSE_OFFSET, WS_CLOSE_REASON_MAX_BYTES, WS_IDLE_TIMEOUT_MS, WS_KEEPALIVE_INTERVAL_MS, } from '../protocol.js';
|
|
29
|
+
import { OwnedTimers } from '../timers.js';
|
|
30
|
+
const OPEN = 1;
|
|
31
|
+
/**
|
|
32
|
+
* Bytes a write may leave queued in the socket and still count as complete. Absolute. Above
|
|
33
|
+
* it the write parks, which is what lets the emit queue fill and its bound fire.
|
|
34
|
+
*/
|
|
35
|
+
const WS_SEND_LOW_WATER_BYTES = 65_536;
|
|
36
|
+
/** How long a parked write waits between looks at `bufferedAmount`. */
|
|
37
|
+
const POLL_MS = 4;
|
|
38
|
+
/** §3.3: the keepalive is an empty message, which carries no bytes of the stream. */
|
|
39
|
+
const KEEPALIVE = new Uint8Array(0);
|
|
40
|
+
export class WebSocketConnection {
|
|
41
|
+
#socket;
|
|
42
|
+
#lowWater;
|
|
43
|
+
#keepaliveMs;
|
|
44
|
+
#idleMs;
|
|
45
|
+
#timers = new OwnedTimers();
|
|
46
|
+
#idleTimer;
|
|
47
|
+
#sentAt = Date.now();
|
|
48
|
+
#readable;
|
|
49
|
+
#inbound;
|
|
50
|
+
#closing = false;
|
|
51
|
+
#settleClosed;
|
|
52
|
+
closed;
|
|
53
|
+
constructor(socket, opts = {}) {
|
|
54
|
+
this.#socket = socket;
|
|
55
|
+
this.#lowWater = opts.lowWaterBytes ?? WS_SEND_LOW_WATER_BYTES;
|
|
56
|
+
this.#keepaliveMs = opts.keepaliveIntervalMs ?? WS_KEEPALIVE_INTERVAL_MS;
|
|
57
|
+
this.#idleMs = opts.idleTimeoutMs ?? WS_IDLE_TIMEOUT_MS;
|
|
58
|
+
socket.binaryType = 'arraybuffer';
|
|
59
|
+
this.#readable = new ReadableStream({
|
|
60
|
+
start: (controller) => {
|
|
61
|
+
this.#inbound = controller;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
this.closed = new Promise((resolve) => {
|
|
65
|
+
this.#settleClosed = resolve;
|
|
66
|
+
});
|
|
67
|
+
socket.addEventListener('close', (ev) => {
|
|
68
|
+
this.#closing = true;
|
|
69
|
+
this.#timers.clearAll();
|
|
70
|
+
this.#endInbound();
|
|
71
|
+
this.#settleClosed({ code: fromWebSocketCloseCode(ev.code), reason: ev.reason });
|
|
72
|
+
});
|
|
73
|
+
socket.addEventListener('error', () => {
|
|
74
|
+
// A close event follows every error, and that is the one report `closed` makes.
|
|
75
|
+
});
|
|
76
|
+
socket.addEventListener('message', (ev) => {
|
|
77
|
+
const bytes = toBytes(ev.data);
|
|
78
|
+
if (bytes === undefined) {
|
|
79
|
+
// §3.3: binary messages only. A text frame is not a framing accident, it is another
|
|
80
|
+
// protocol, and the lane cannot recover from it any more than from a bad length.
|
|
81
|
+
this.close(CloseCode.WT_PROTOCOL_ERROR, 'a text message on the emit lane');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Anything from the peer, a keepalive included, is proof of life.
|
|
85
|
+
this.#armIdle();
|
|
86
|
+
// §3.3: an empty message is the keepalive, and carries no bytes of the stream.
|
|
87
|
+
if (bytes.byteLength === 0)
|
|
88
|
+
return;
|
|
89
|
+
this.#inbound?.enqueue(bytes);
|
|
90
|
+
});
|
|
91
|
+
// Neither timer holds a process open: the socket does that, for as long as it is open.
|
|
92
|
+
this.#timers.every(this.#keepaliveMs, () => this.#keepalive()).unref();
|
|
93
|
+
this.#armIdle();
|
|
94
|
+
}
|
|
95
|
+
async openEmitStream() {
|
|
96
|
+
const socket = this.#socket;
|
|
97
|
+
const lowWater = this.#lowWater;
|
|
98
|
+
const gone = () => new TransportError('WT_SESSION_CLOSED', 'the WebSocket closed with a write pending', 'Connect again. A frame handed to a closed socket was never sent.');
|
|
99
|
+
return new WritableStream({
|
|
100
|
+
write: async (chunk) => {
|
|
101
|
+
if (socket.readyState !== OPEN)
|
|
102
|
+
throw gone();
|
|
103
|
+
socket.send(chunk);
|
|
104
|
+
this.#sentAt = Date.now();
|
|
105
|
+
// The bound above this sink counts frames whose write has not completed. A socket
|
|
106
|
+
// reports completion through `bufferedAmount` alone, so this is where a write waits
|
|
107
|
+
// while the peer is slow, and where a resolve-at-once would hide the whole backlog.
|
|
108
|
+
while (socket.bufferedAmount > lowWater) {
|
|
109
|
+
if (socket.readyState !== OPEN)
|
|
110
|
+
throw gone();
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_MS));
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
abort: (reason) => {
|
|
115
|
+
this.close(CloseCode.WT_PROTOCOL_ERROR, String(reason));
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/** The socket is the peer's emit stream, so it is delivered at once rather than awaited. */
|
|
120
|
+
onEmitStream(cb) {
|
|
121
|
+
cb(this.#readable);
|
|
122
|
+
}
|
|
123
|
+
openBidi() {
|
|
124
|
+
return Promise.reject(laneUnavailable());
|
|
125
|
+
}
|
|
126
|
+
onBidi() {
|
|
127
|
+
// Nothing will ever arrive: the peer has no bidirectional streams to open either.
|
|
128
|
+
}
|
|
129
|
+
sendDatagram() {
|
|
130
|
+
// The session wraps unreliable frames on the emit lane on this transport, so a datagram
|
|
131
|
+
// reaching here is a bug in transport-io rather than a condition to absorb quietly.
|
|
132
|
+
throw new TransportError('WT_PROTOCOL_ERROR', 'a datagram reached the WebSocket connection', 'Unreliable frames travel as DATAGRAM frames on the emit lane here. Report this.');
|
|
133
|
+
}
|
|
134
|
+
onDatagram() {
|
|
135
|
+
// Datagrams arrive as DATAGRAM frames on the emit stream; see the session.
|
|
136
|
+
}
|
|
137
|
+
/** The same ceiling as the native transport, so an application's limit never moves with it. */
|
|
138
|
+
maxDatagramSize() {
|
|
139
|
+
return DATAGRAM_CONSERVATIVE_FLOOR;
|
|
140
|
+
}
|
|
141
|
+
reliability() {
|
|
142
|
+
return 'reliable-only';
|
|
143
|
+
}
|
|
144
|
+
kind() {
|
|
145
|
+
return 'websocket';
|
|
146
|
+
}
|
|
147
|
+
close(code, reason) {
|
|
148
|
+
if (this.#closing)
|
|
149
|
+
return;
|
|
150
|
+
this.#closing = true;
|
|
151
|
+
this.#timers.clearAll();
|
|
152
|
+
try {
|
|
153
|
+
this.#socket.close(toWebSocketCloseCode(code), truncateCloseReason(reason));
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Already closing underneath us.
|
|
157
|
+
}
|
|
158
|
+
// Closed from this side is closed now, as it is on every other transport. The closing
|
|
159
|
+
// handshake continues underneath, and against a peer that has stopped reading it never
|
|
160
|
+
// completes: `ws` waits thirty seconds before giving up on it, and a session that has
|
|
161
|
+
// decided to disconnect a slow peer must not sit behind that peer's silence.
|
|
162
|
+
this.#endInbound();
|
|
163
|
+
this.#settleClosed({ code, reason });
|
|
164
|
+
}
|
|
165
|
+
#endInbound() {
|
|
166
|
+
try {
|
|
167
|
+
this.#inbound?.close();
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Closed twice, which is the peer and the socket both saying the same thing.
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Sent when nothing else has been for an interval. The check runs on a timer of the same
|
|
175
|
+
* period, so the longest silence before a keepalive is two intervals, well inside the
|
|
176
|
+
* peer's deadline.
|
|
177
|
+
*/
|
|
178
|
+
#keepalive() {
|
|
179
|
+
if (this.#closing || this.#socket.readyState !== OPEN)
|
|
180
|
+
return;
|
|
181
|
+
if (Date.now() - this.#sentAt < this.#keepaliveMs)
|
|
182
|
+
return;
|
|
183
|
+
try {
|
|
184
|
+
this.#socket.send(KEEPALIVE);
|
|
185
|
+
this.#sentAt = Date.now();
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Closing underneath us; the close event releases the timer.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Re-armed by every message. When it fires, the path is dead or the peer sends no keepalive. */
|
|
192
|
+
#armIdle() {
|
|
193
|
+
this.#idleTimer?.cancel();
|
|
194
|
+
this.#idleTimer = this.#timers.after(this.#idleMs, () => {
|
|
195
|
+
this.close(CloseCode.WT_IDLE_TIMEOUT, `no message from the peer for ${this.#idleMs} ms`);
|
|
196
|
+
});
|
|
197
|
+
this.#idleTimer.unref();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function laneUnavailable() {
|
|
201
|
+
return new TransportError('WT_LANE_UNAVAILABLE', 'call() and stream() need a WebTransport session, and this one is on a WebSocket', 'Check client.native before calling: it is null on a fallback session. Emits, and unreliable events that declare a fallback, still work here.');
|
|
202
|
+
}
|
|
203
|
+
function toBytes(data) {
|
|
204
|
+
if (data instanceof ArrayBuffer)
|
|
205
|
+
return new Uint8Array(data);
|
|
206
|
+
if (ArrayBuffer.isView(data)) {
|
|
207
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
/** §3.3: `WT_NO_ERROR` is a normal closure; every other session code rides in the private range. */
|
|
212
|
+
export function toWebSocketCloseCode(code) {
|
|
213
|
+
return code === CloseCode.WT_NO_ERROR ? WS_CLOSE_NORMAL : WS_CLOSE_OFFSET + code;
|
|
214
|
+
}
|
|
215
|
+
/** The inverse, with the socket's own codes (a lost connection is 1006) passed through as they are. */
|
|
216
|
+
export function fromWebSocketCloseCode(code) {
|
|
217
|
+
if (code === WS_CLOSE_NORMAL)
|
|
218
|
+
return CloseCode.WT_NO_ERROR;
|
|
219
|
+
if (code >= WS_CLOSE_OFFSET + 1000 && code <= WS_CLOSE_OFFSET + 1999)
|
|
220
|
+
return code - WS_CLOSE_OFFSET;
|
|
221
|
+
return code;
|
|
222
|
+
}
|
|
223
|
+
/** Whole characters only, so a cut never leaves half a code point on the wire. */
|
|
224
|
+
export function truncateCloseReason(reason) {
|
|
225
|
+
const encoder = new TextEncoder();
|
|
226
|
+
if (encoder.encode(reason).byteLength <= WS_CLOSE_REASON_MAX_BYTES)
|
|
227
|
+
return reason;
|
|
228
|
+
let out = '';
|
|
229
|
+
for (const ch of reason) {
|
|
230
|
+
if (encoder.encode(out + ch).byteLength > WS_CLOSE_REASON_MAX_BYTES)
|
|
231
|
+
break;
|
|
232
|
+
out += ch;
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=websocket-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-connection.js","sourceRoot":"","sources":["../../src/transport/websocket-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,56 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/**
|
|
3
|
-
* What this needs from a socket: the WHATWG surface, which browsers, Node and `ws` share.
|
|
4
|
-
* `readyState` 1 is open on every one of them.
|
|
5
|
-
*/
|
|
6
|
-
export interface SocketLike {
|
|
7
|
-
binaryType: string;
|
|
8
|
-
readonly bufferedAmount: number;
|
|
9
|
-
readonly readyState: number;
|
|
10
|
-
send(data: Uint8Array): void;
|
|
11
|
-
close(code?: number, reason?: string): void;
|
|
12
|
-
addEventListener(type: 'message', listener: (ev: {
|
|
13
|
-
readonly data: unknown;
|
|
14
|
-
}) => void): void;
|
|
15
|
-
addEventListener(type: 'close', listener: (ev: {
|
|
16
|
-
readonly code: number;
|
|
17
|
-
readonly reason: string;
|
|
18
|
-
}) => void): void;
|
|
19
|
-
addEventListener(type: 'error', listener: () => void): void;
|
|
20
|
-
addEventListener(type: 'open', listener: () => void): void;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Bytes a write may leave queued in the socket and still count as complete. Absolute. Above
|
|
24
|
-
* it the write parks, which is what lets the emit queue fill and its bound fire.
|
|
25
|
-
*/
|
|
26
|
-
export declare const WS_SEND_LOW_WATER_BYTES = 65536;
|
|
27
|
-
export interface WebSocketConnectionOptions {
|
|
28
|
-
/** For the test that proves the bound; production never sets it. */
|
|
29
|
-
readonly lowWaterBytes?: number;
|
|
30
|
-
}
|
|
31
|
-
export declare class WebSocketConnection implements Connection {
|
|
32
|
-
#private;
|
|
33
|
-
readonly closed: Promise<CloseInfo>;
|
|
34
|
-
constructor(socket: SocketLike, opts?: WebSocketConnectionOptions);
|
|
35
|
-
openEmitStream(): Promise<WritableStream<Uint8Array>>;
|
|
36
|
-
/** The socket is the peer's emit stream, so it is delivered at once rather than awaited. */
|
|
37
|
-
onEmitStream(cb: (readable: ReadableStream<Uint8Array>) => void): void;
|
|
38
|
-
openBidi(): Promise<BidiStream>;
|
|
39
|
-
onBidi(): void;
|
|
40
|
-
sendDatagram(): void;
|
|
41
|
-
onDatagram(): void;
|
|
42
|
-
/** The same ceiling as the native transport, so an application's limit never moves with it. */
|
|
43
|
-
maxDatagramSize(): number;
|
|
44
|
-
reliability(): 'reliable-only';
|
|
45
|
-
kind(): 'websocket';
|
|
46
|
-
close(code: number, reason: string): void;
|
|
47
|
-
}
|
|
48
|
-
/** §3.3: `WT_NO_ERROR` is a normal closure; every other session code rides in the private range. */
|
|
49
|
-
export declare function toWebSocketCloseCode(code: number): number;
|
|
50
|
-
/** The inverse, with the socket's own codes (a lost connection is 1006) passed through as they are. */
|
|
51
|
-
export declare function fromWebSocketCloseCode(code: number): number;
|
|
52
|
-
/** Whole characters only, so a cut never leaves half a code point on the wire. */
|
|
53
|
-
export declare function truncateCloseReason(reason: string): string;
|
|
1
|
+
import type { Connection } from './types.ts';
|
|
54
2
|
export interface WebSocketConnectOptions {
|
|
55
3
|
/** `ws://` or `wss://`. A `wss://` origin needs a certificate the platform trusts. */
|
|
56
4
|
readonly url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,MAAM,WAAW,uBAAuB;IACtC,sFAAsF;IACtF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BzF"}
|
|
@@ -1,183 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* `transport-io/websocket-transport`: the fallback connector, for `withFallback`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* as bytes of the same stream. Everything else on the seam refuses. There are no
|
|
8
|
-
* bidirectional streams, so a session on this transport carries no calls and no `stream()`,
|
|
9
|
-
* and there are no datagrams: an unreliable event whose contract declared a fallback travels
|
|
10
|
-
* as a `DATAGRAM` frame on the emit lane instead, wrapped and unwrapped by the session (D122).
|
|
11
|
-
*
|
|
12
|
-
* What the socket does not give for free is write completion. A browser exposes only
|
|
13
|
-
* `bufferedAmount`, with no event when it drains, so the sink polls it before resolving a
|
|
14
|
-
* write. Without that every write would resolve at once, and the emit queue's 256-frame
|
|
15
|
-
* bound would measure nothing: `writer.ready` on the reference binding in a new costume
|
|
16
|
-
* (D93). `websocket.node.test.ts` reaches the bound on a real socket with the peer paused,
|
|
17
|
-
* and shows it unreachable with the polling off.
|
|
4
|
+
* This is the whole entry. The connection it returns, the socket interface, the close-code
|
|
5
|
+
* mapping and the sink's low-water mark live in `websocket-connection.ts` and are not
|
|
6
|
+
* exported from the package, as the transport seam is not (D21, D127).
|
|
18
7
|
*/
|
|
19
8
|
import { TransportError } from '../errors.js';
|
|
20
|
-
import {
|
|
21
|
-
const OPEN = 1;
|
|
22
|
-
/**
|
|
23
|
-
* Bytes a write may leave queued in the socket and still count as complete. Absolute. Above
|
|
24
|
-
* it the write parks, which is what lets the emit queue fill and its bound fire.
|
|
25
|
-
*/
|
|
26
|
-
export const WS_SEND_LOW_WATER_BYTES = 65_536;
|
|
27
|
-
/** How long a parked write waits between looks at `bufferedAmount`. */
|
|
28
|
-
const POLL_MS = 4;
|
|
29
|
-
export class WebSocketConnection {
|
|
30
|
-
#socket;
|
|
31
|
-
#lowWater;
|
|
32
|
-
#readable;
|
|
33
|
-
#inbound;
|
|
34
|
-
#closing = false;
|
|
35
|
-
#settleClosed;
|
|
36
|
-
closed;
|
|
37
|
-
constructor(socket, opts = {}) {
|
|
38
|
-
this.#socket = socket;
|
|
39
|
-
this.#lowWater = opts.lowWaterBytes ?? WS_SEND_LOW_WATER_BYTES;
|
|
40
|
-
socket.binaryType = 'arraybuffer';
|
|
41
|
-
this.#readable = new ReadableStream({
|
|
42
|
-
start: (controller) => {
|
|
43
|
-
this.#inbound = controller;
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
this.closed = new Promise((resolve) => {
|
|
47
|
-
this.#settleClosed = resolve;
|
|
48
|
-
});
|
|
49
|
-
socket.addEventListener('close', (ev) => {
|
|
50
|
-
this.#closing = true;
|
|
51
|
-
this.#endInbound();
|
|
52
|
-
this.#settleClosed({ code: fromWebSocketCloseCode(ev.code), reason: ev.reason });
|
|
53
|
-
});
|
|
54
|
-
socket.addEventListener('error', () => {
|
|
55
|
-
// A close event follows every error, and that is the one report `closed` makes.
|
|
56
|
-
});
|
|
57
|
-
socket.addEventListener('message', (ev) => {
|
|
58
|
-
const bytes = toBytes(ev.data);
|
|
59
|
-
if (bytes === undefined) {
|
|
60
|
-
// §3.3: binary messages only. A text frame is not a framing accident, it is another
|
|
61
|
-
// protocol, and the lane cannot recover from it any more than from a bad length.
|
|
62
|
-
this.close(CloseCode.WT_PROTOCOL_ERROR, 'a text message on the emit lane');
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
this.#inbound?.enqueue(bytes);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
async openEmitStream() {
|
|
69
|
-
const socket = this.#socket;
|
|
70
|
-
const lowWater = this.#lowWater;
|
|
71
|
-
const gone = () => new TransportError('WT_SESSION_CLOSED', 'the WebSocket closed with a write pending', 'Connect again. A frame handed to a closed socket was never sent.');
|
|
72
|
-
return new WritableStream({
|
|
73
|
-
write: async (chunk) => {
|
|
74
|
-
if (socket.readyState !== OPEN)
|
|
75
|
-
throw gone();
|
|
76
|
-
socket.send(chunk);
|
|
77
|
-
// The bound above this sink counts frames whose write has not completed. A socket
|
|
78
|
-
// reports completion through `bufferedAmount` alone, so this is where a write waits
|
|
79
|
-
// while the peer is slow, and where a resolve-at-once would hide the whole backlog.
|
|
80
|
-
while (socket.bufferedAmount > lowWater) {
|
|
81
|
-
if (socket.readyState !== OPEN)
|
|
82
|
-
throw gone();
|
|
83
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_MS));
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
abort: (reason) => {
|
|
87
|
-
this.close(CloseCode.WT_PROTOCOL_ERROR, String(reason));
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/** The socket is the peer's emit stream, so it is delivered at once rather than awaited. */
|
|
92
|
-
onEmitStream(cb) {
|
|
93
|
-
cb(this.#readable);
|
|
94
|
-
}
|
|
95
|
-
openBidi() {
|
|
96
|
-
return Promise.reject(laneUnavailable());
|
|
97
|
-
}
|
|
98
|
-
onBidi() {
|
|
99
|
-
// Nothing will ever arrive: the peer has no bidirectional streams to open either.
|
|
100
|
-
}
|
|
101
|
-
sendDatagram() {
|
|
102
|
-
// The session wraps unreliable frames on the emit lane on this transport, so a datagram
|
|
103
|
-
// reaching here is a bug in transport-io rather than a condition to absorb quietly.
|
|
104
|
-
throw new TransportError('WT_PROTOCOL_ERROR', 'a datagram reached the WebSocket connection', 'Unreliable frames travel as DATAGRAM frames on the emit lane here. Report this.');
|
|
105
|
-
}
|
|
106
|
-
onDatagram() {
|
|
107
|
-
// Datagrams arrive as DATAGRAM frames on the emit stream; see the session.
|
|
108
|
-
}
|
|
109
|
-
/** The same ceiling as the native transport, so an application's limit never moves with it. */
|
|
110
|
-
maxDatagramSize() {
|
|
111
|
-
return DATAGRAM_CONSERVATIVE_FLOOR;
|
|
112
|
-
}
|
|
113
|
-
reliability() {
|
|
114
|
-
return 'reliable-only';
|
|
115
|
-
}
|
|
116
|
-
kind() {
|
|
117
|
-
return 'websocket';
|
|
118
|
-
}
|
|
119
|
-
close(code, reason) {
|
|
120
|
-
if (this.#closing)
|
|
121
|
-
return;
|
|
122
|
-
this.#closing = true;
|
|
123
|
-
try {
|
|
124
|
-
this.#socket.close(toWebSocketCloseCode(code), truncateCloseReason(reason));
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
// Already closing underneath us.
|
|
128
|
-
}
|
|
129
|
-
// Closed from this side is closed now, as it is on every other transport. The closing
|
|
130
|
-
// handshake continues underneath, and against a peer that has stopped reading it never
|
|
131
|
-
// completes: `ws` waits thirty seconds before giving up on it, and a session that has
|
|
132
|
-
// decided to disconnect a slow peer must not sit behind that peer's silence.
|
|
133
|
-
this.#endInbound();
|
|
134
|
-
this.#settleClosed({ code, reason });
|
|
135
|
-
}
|
|
136
|
-
#endInbound() {
|
|
137
|
-
try {
|
|
138
|
-
this.#inbound?.close();
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
// Closed twice, which is the peer and the socket both saying the same thing.
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function laneUnavailable() {
|
|
146
|
-
return new TransportError('WT_LANE_UNAVAILABLE', 'call() and stream() need a WebTransport session, and this one is on a WebSocket', 'Check client.native before calling: it is null on a fallback session. Emits, and unreliable events that declare a fallback, still work here.');
|
|
147
|
-
}
|
|
148
|
-
function toBytes(data) {
|
|
149
|
-
if (data instanceof ArrayBuffer)
|
|
150
|
-
return new Uint8Array(data);
|
|
151
|
-
if (ArrayBuffer.isView(data)) {
|
|
152
|
-
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
153
|
-
}
|
|
154
|
-
return undefined;
|
|
155
|
-
}
|
|
156
|
-
/** §3.3: `WT_NO_ERROR` is a normal closure; every other session code rides in the private range. */
|
|
157
|
-
export function toWebSocketCloseCode(code) {
|
|
158
|
-
return code === CloseCode.WT_NO_ERROR ? WS_CLOSE_NORMAL : WS_CLOSE_OFFSET + code;
|
|
159
|
-
}
|
|
160
|
-
/** The inverse, with the socket's own codes (a lost connection is 1006) passed through as they are. */
|
|
161
|
-
export function fromWebSocketCloseCode(code) {
|
|
162
|
-
if (code === WS_CLOSE_NORMAL)
|
|
163
|
-
return CloseCode.WT_NO_ERROR;
|
|
164
|
-
if (code >= WS_CLOSE_OFFSET + 1000 && code <= WS_CLOSE_OFFSET + 1999)
|
|
165
|
-
return code - WS_CLOSE_OFFSET;
|
|
166
|
-
return code;
|
|
167
|
-
}
|
|
168
|
-
/** Whole characters only, so a cut never leaves half a code point on the wire. */
|
|
169
|
-
export function truncateCloseReason(reason) {
|
|
170
|
-
const encoder = new TextEncoder();
|
|
171
|
-
if (encoder.encode(reason).byteLength <= WS_CLOSE_REASON_MAX_BYTES)
|
|
172
|
-
return reason;
|
|
173
|
-
let out = '';
|
|
174
|
-
for (const ch of reason) {
|
|
175
|
-
if (encoder.encode(out + ch).byteLength > WS_CLOSE_REASON_MAX_BYTES)
|
|
176
|
-
break;
|
|
177
|
-
out += ch;
|
|
178
|
-
}
|
|
179
|
-
return out;
|
|
180
|
-
}
|
|
9
|
+
import { WebSocketConnection } from './websocket-connection.js';
|
|
181
10
|
/**
|
|
182
11
|
* The fallback connector, for `withFallback`. Runtime-neutral: it reads the global
|
|
183
12
|
* `WebSocket`, which browsers, Node and Bun all provide.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAmB,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAOhF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA6B;IAClE,MAAM,EAAE,GAAI,UAA8D,CAAC,SAAS,CAAA;IACpF,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,CACtB,eAAe,EACf,+BAA+B,EAC/B,0CAA0C,CAC3C,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/B,MAAM,CAAC,UAAU,GAAG,aAAa,CAAA;IACjC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QAChD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACtC,MAAM,CACJ,IAAI,cAAc,CAChB,qBAAqB,EACrB,8BAA8B,IAAI,CAAC,GAAG,uBAAuB,EAAE,CAAC,IAAI,EAAE,EACtE,iJAAiJ,CAClJ,CACF,CAAA;QACH,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACpC,oFAAoF;QACtF,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.node.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.node.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,sFAAsF;IACtF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,IAAI,aAAa,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,IAAI,IAAI,CAAA;CACb;
|
|
1
|
+
{"version":3,"file":"websocket.node.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.node.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,sFAAsF;IACtF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,IAAI,aAAa,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,IAAI,IAAI,CAAA;CACb;AAQD,wBAAsB,eAAe,CACnC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAoD5B"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The WebSocket listener. PROTOCOL.md §3.3.
|
|
3
3
|
*
|
|
4
|
-
* Node has no WebSocket server of its own, so this one is `ws`,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* also the probe target from D120: any request gets an answer, so a client that reaches
|
|
8
|
-
* port over TCP and not the QUIC port over UDP learns which it is.
|
|
4
|
+
* Node has no WebSocket server of its own, so this one is `ws`, a dependency of the package:
|
|
5
|
+
* a few hundred kilobytes of JavaScript beside a native QUIC binding that is already
|
|
6
|
+
* required, so nothing is gained by making it optional (D122). The HTTP server underneath it
|
|
7
|
+
* is also the probe target from D120: any request gets an answer, so a client that reaches
|
|
8
|
+
* this port over TCP and not the QUIC port over UDP learns which it is.
|
|
9
9
|
*
|
|
10
10
|
* `cert` and `privKey` make it `wss://`, on the certificate the site already serves. Without
|
|
11
11
|
* them it is `ws://`, which is what development on loopback uses, since a browser pins no
|
|
@@ -13,28 +13,19 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { createServer as createHttpServer, } from 'node:http';
|
|
15
15
|
import { createServer as createHttpsServer } from 'node:https';
|
|
16
|
-
import {
|
|
16
|
+
import { WebSocketServer } from 'ws';
|
|
17
17
|
import { PROBE_PATH } from './probe.js';
|
|
18
|
-
import { WebSocketConnection } from './websocket.js';
|
|
19
|
-
async function loadWs() {
|
|
20
|
-
try {
|
|
21
|
-
return await import('ws');
|
|
22
|
-
}
|
|
23
|
-
catch (cause) {
|
|
24
|
-
throw new TransportError('WT_NO_SUPPORT', 'the WebSocket listener needs the ws package, and it is not installed', 'Run `npm install ws`. It is an optional peer of transport-io, needed only by a process that listens for the fallback.', cause);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
18
|
+
import { WebSocketConnection } from './websocket-connection.js';
|
|
27
19
|
function answer(req, res) {
|
|
28
20
|
// Any status is an answer to the probe. 204 at its path, 404 elsewhere, and nothing else
|
|
29
21
|
// is served: this is a transport listener, not a web server.
|
|
30
22
|
res.writeHead(req.url === PROBE_PATH ? 204 : 404).end();
|
|
31
23
|
}
|
|
32
24
|
export async function listenWebSocket(opts) {
|
|
33
|
-
const ws = await loadWs();
|
|
34
25
|
const http = opts.cert !== undefined && opts.privKey !== undefined
|
|
35
26
|
? createHttpsServer({ cert: opts.cert, key: opts.privKey }, answer)
|
|
36
27
|
: createHttpServer(answer);
|
|
37
|
-
const wss = new
|
|
28
|
+
const wss = new WebSocketServer({ server: http, path: opts.path ?? '/' });
|
|
38
29
|
const queue = [];
|
|
39
30
|
let waiting;
|
|
40
31
|
let stopped = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.node.js","sourceRoot":"","sources":["../../src/transport/websocket.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,YAAY,IAAI,gBAAgB,GAGjC,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,YAAY,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"websocket.node.js","sourceRoot":"","sources":["../../src/transport/websocket.node.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "transport-io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Real-time apps over WebTransport. Two lanes, one contract, no fallback.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@fails-components/webtransport": "1.6.8",
|
|
54
|
-
"@standard-schema/spec": "^1.1.0"
|
|
54
|
+
"@standard-schema/spec": "^1.1.0",
|
|
55
|
+
"ws": "^8.21.3"
|
|
55
56
|
},
|
|
56
57
|
"optionalDependencies": {
|
|
57
58
|
"@moq/web-transport-darwin-arm64": "0.1.4",
|
|
@@ -79,13 +80,5 @@
|
|
|
79
80
|
"streaming",
|
|
80
81
|
"typescript",
|
|
81
82
|
"websocket-alternative"
|
|
82
|
-
]
|
|
83
|
-
"peerDependencies": {
|
|
84
|
-
"ws": "^8.21.3"
|
|
85
|
-
},
|
|
86
|
-
"peerDependenciesMeta": {
|
|
87
|
-
"ws": {
|
|
88
|
-
"optional": true
|
|
89
|
-
}
|
|
90
|
-
}
|
|
83
|
+
]
|
|
91
84
|
}
|