@opendatalabs/personal-server-ts-lite 0.0.1-canary.01ca694 → 0.0.1-canary.052d47e
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/dist/browser-runtime.d.ts +26 -1
- package/dist/browser-runtime.d.ts.map +1 -1
- package/dist/browser-runtime.js +130 -26
- package/dist/browser-runtime.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +40 -8
- package/dist/client.js.map +1 -1
- package/dist/derivatives.d.ts +51 -0
- package/dist/derivatives.d.ts.map +1 -0
- package/dist/derivatives.js +85 -0
- package/dist/derivatives.js.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/persistence.d.ts +69 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/persistence.js +58 -0
- package/dist/persistence.js.map +1 -0
- package/dist/relay-tls.d.ts +42 -0
- package/dist/relay-tls.d.ts.map +1 -1
- package/dist/relay-tls.js +176 -86
- package/dist/relay-tls.js.map +1 -1
- package/dist/relay.d.ts +83 -4
- package/dist/relay.d.ts.map +1 -1
- package/dist/relay.js +299 -21
- package/dist/relay.js.map +1 -1
- package/dist/runtime.d.ts +97 -4
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +208 -44
- package/dist/runtime.js.map +1 -1
- package/dist/state.d.ts +11 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +77 -7
- package/dist/state.js.map +1 -1
- package/dist/storage.d.ts +6 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +182 -39
- package/dist/storage.js.map +1 -1
- package/dist/sync.d.ts +23 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +56 -6
- package/dist/sync.js.map +1 -1
- package/package.json +4 -4
package/dist/relay-tls.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-tls.js","sourceRoot":"","sources":["../src/relay-tls.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"relay-tls.js","sourceRoot":"","sources":["../src/relay-tls.ts"],"names":[],"mappings":"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"}
|
package/dist/relay.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { PersonalServerReadFulfillmentReporter } from "@opendatalabs/personal-server-ts-core/api";
|
|
1
2
|
import { type PsLiteBridgeResponse } from "./bridge.js";
|
|
3
|
+
import type { PsLiteRelayTlsIdentityStore } from "./relay-tls.js";
|
|
2
4
|
import type { PsLiteRuntime } from "./runtime.js";
|
|
3
5
|
export interface PsLiteRelayClientOptions {
|
|
4
6
|
sessionId: string;
|
|
@@ -9,28 +11,87 @@ export interface PsLiteRelayClientOptions {
|
|
|
9
11
|
origin?: string;
|
|
10
12
|
webSocketFactory?: PsLiteRelayWebSocketFactory;
|
|
11
13
|
tls?: PsLiteRelayTlsFactory | false;
|
|
14
|
+
/** Host-owned cache for the issued relay certificate identity. */
|
|
15
|
+
tlsIdentityStore?: PsLiteRelayTlsIdentityStore;
|
|
12
16
|
logger?: (line: string) => void;
|
|
13
|
-
onStatus?: (status: PsLiteRelayStatus) => void;
|
|
17
|
+
onStatus?: (status: PsLiteRelayStatus, detail?: PsLiteRelayStatusDetail) => void;
|
|
18
|
+
/** Heartbeat ping cadence (ms). Default 20_000. */
|
|
19
|
+
heartbeatIntervalMs?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Force-reconnect when a ping the client actually sent goes unanswered by
|
|
22
|
+
* ANY relay frame for this long, measured by wall clock (ms). Default 45_000.
|
|
23
|
+
*/
|
|
24
|
+
heartbeatTimeoutMs?: number;
|
|
25
|
+
/** First reconnect backoff delay (ms); doubles up to the max. Default 1_000. */
|
|
26
|
+
reconnectInitialDelayMs?: number;
|
|
27
|
+
/** Max reconnect backoff delay (ms). Default 30_000. */
|
|
28
|
+
reconnectMaxDelayMs?: number;
|
|
14
29
|
}
|
|
15
|
-
export type PsLiteRelayStatus = "connecting" | "connected" | "disconnected" | "closed" | "error";
|
|
30
|
+
export type PsLiteRelayStatus = "connecting" | "connected" | "disconnected" | "closed" | "replaced" | "error";
|
|
31
|
+
/**
|
|
32
|
+
* Extra context for a relay status transition — the WebSocket close code/reason
|
|
33
|
+
* on `disconnected` / `closed` / `replaced`. Lets consumers distinguish an
|
|
34
|
+
* abnormal drop (1006) from a takeover (1012) or a clean close (1000) for
|
|
35
|
+
* reliability telemetry. Optional and additive: 1-arg `onStatus` handlers stay
|
|
36
|
+
* valid.
|
|
37
|
+
*/
|
|
38
|
+
export interface PsLiteRelayStatusDetail {
|
|
39
|
+
code?: number;
|
|
40
|
+
reason?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Close code the relay sends to the losing side when a new connection claims
|
|
44
|
+
* the same sessionId. Terminal for this client: reconnecting would evict the
|
|
45
|
+
* winner right back and the two tabs would trade the session every backoff
|
|
46
|
+
* tick (observed live as a 1012 eviction loop every ~2s with two app tabs).
|
|
47
|
+
*/
|
|
48
|
+
export declare const RELAY_CLOSE_SESSION_REPLACED = 1012;
|
|
16
49
|
export interface PsLiteRelayClient {
|
|
17
50
|
readonly sessionId: string;
|
|
18
51
|
readonly url: string;
|
|
19
52
|
close(reason?: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Resolves once the relay has finished delivering everything in flight: no
|
|
55
|
+
* HTTP streams open and the socket's send buffer empty. A non-OPEN socket
|
|
56
|
+
* counts as drained (its buffered bytes died with it and reconnect starts
|
|
57
|
+
* from a clean slate). Resolves after `timeoutMs` regardless, so callers can
|
|
58
|
+
* never deadlock on a wedged tunnel.
|
|
59
|
+
*/
|
|
60
|
+
whenDrained(options?: {
|
|
61
|
+
/** Max time to wait before resolving anyway (ms). Default 20_000. */
|
|
62
|
+
timeoutMs?: number;
|
|
63
|
+
/** Drain-state poll cadence (ms). Default 50. */
|
|
64
|
+
pollIntervalMs?: number;
|
|
65
|
+
}): Promise<void>;
|
|
20
66
|
}
|
|
21
67
|
export interface PsLiteRelayWebSocketFactory {
|
|
22
68
|
(url: string): PsLiteRelayWebSocket;
|
|
23
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Subset of the standard CloseEvent the relay client reads. Browser
|
|
72
|
+
* WebSockets pass a full CloseEvent here; fakes may call onclose with
|
|
73
|
+
* nothing (treated as an abnormal close).
|
|
74
|
+
*/
|
|
75
|
+
export interface PsLiteRelayCloseEvent {
|
|
76
|
+
code?: number;
|
|
77
|
+
reason?: string;
|
|
78
|
+
}
|
|
24
79
|
export interface PsLiteRelayWebSocket {
|
|
25
80
|
binaryType: string;
|
|
26
81
|
readonly readyState: number;
|
|
27
82
|
readonly OPEN: number;
|
|
28
83
|
readonly CONNECTING: number;
|
|
84
|
+
/**
|
|
85
|
+
* Bytes accepted by send() but not yet flushed to the network (standard
|
|
86
|
+
* WebSocket.bufferedAmount). Optional so lightweight fakes can omit it;
|
|
87
|
+
* treated as 0 when absent.
|
|
88
|
+
*/
|
|
89
|
+
readonly bufferedAmount?: number;
|
|
29
90
|
onopen: (() => void) | null;
|
|
30
91
|
onmessage: ((event: {
|
|
31
92
|
data: string | ArrayBuffer | Uint8Array;
|
|
32
93
|
}) => void) | null;
|
|
33
|
-
onclose: (() => void) | null;
|
|
94
|
+
onclose: ((event?: PsLiteRelayCloseEvent) => void) | null;
|
|
34
95
|
onerror: (() => void) | null;
|
|
35
96
|
send(data: string | Uint8Array): void;
|
|
36
97
|
close(code?: number, reason?: string): void;
|
|
@@ -60,8 +121,26 @@ export interface PsLiteRelayTlsStep {
|
|
|
60
121
|
}
|
|
61
122
|
export declare function psLiteRelayControlUrl(sessionId: string, controlUrl?: string): string;
|
|
62
123
|
export declare function psLiteRelayPublicUrl(sessionId: string, publicSuffix?: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Defers read-fulfillment reports until the relay has delivered the in-flight
|
|
126
|
+
* response. The core data handler reports fulfillment as soon as it BUILDS the
|
|
127
|
+
* response, but over the relay the (potentially multi-MB) body still has to be
|
|
128
|
+
* pumped through TLS over the WebSocket. Consumers act on the report
|
|
129
|
+
* immediately — the DCR approval page closes the tab hosting this PS — so an
|
|
130
|
+
* eager report kills the tunnel mid-transfer and the builder gets a truncated
|
|
131
|
+
* body (UND_ERR_RES_CONTENT_LENGTH_MISMATCH) after escrow already settled.
|
|
132
|
+
* Gating the report on relay drain makes "fulfilled" mean "delivered".
|
|
133
|
+
*
|
|
134
|
+
* `getRelayClient` is late-bound: the runtime needs the reporter at
|
|
135
|
+
* construction time, before the relay client exists. When it returns
|
|
136
|
+
* undefined (relay disabled / not started yet), reports pass straight through.
|
|
137
|
+
*/
|
|
138
|
+
export declare function createRelayDrainGatedReadFulfillmentReporter(reporter: PersonalServerReadFulfillmentReporter, getRelayClient: () => Pick<PsLiteRelayClient, "whenDrained"> | undefined): PersonalServerReadFulfillmentReporter;
|
|
63
139
|
export declare function startPsLiteRelayClient(options: PsLiteRelayClientOptions): PsLiteRelayClient;
|
|
64
|
-
export declare function buildHttpResponse(response: PsLiteBridgeResponse
|
|
140
|
+
export declare function buildHttpResponse(response: PsLiteBridgeResponse, opts?: {
|
|
141
|
+
bodyOverride?: Uint8Array;
|
|
142
|
+
contentEncoding?: string;
|
|
143
|
+
}): string;
|
|
65
144
|
export declare function encodeDataFrame(streamId: number, payload: Uint8Array): Uint8Array;
|
|
66
145
|
export declare function decodeDataFrame(data: string | ArrayBuffer | Uint8Array): {
|
|
67
146
|
streamId: number;
|
package/dist/relay.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,2CAA2C,CAAC;AACvG,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AASlD,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,2BAA2B,CAAC;IAC/C,GAAG,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAC;IACpC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,2BAA2B,CAAC;IAC/C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,iBAAiB,EACzB,MAAM,CAAC,EAAE,uBAAuB,KAC7B,IAAI,CAAC;IACV,mDAAmD;IACnD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAC3B,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAUjD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE;QACpB,qEAAqE;QACrE,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,iDAAiD;QACjD,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,SAAS,EACP,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,kBAAkB,CAAC;IACpD,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAC5E,KAAK,CAAC,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,UAAU,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAuBD,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,SAAsB,GAC/B,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,SAAwB,GACnC,MAAM,CAER;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4CAA4C,CAC1D,QAAQ,EAAE,qCAAqC,EAC/C,cAAc,EAAE,MAAM,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,GAAG,SAAS,GACvE,qCAAqC,CAOvC;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CA2ZnB;AA+ED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,UAAU,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,MAAM,CA+BR;AAeD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,GAClB,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GACtC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAclD"}
|
package/dist/relay.js
CHANGED
|
@@ -2,34 +2,93 @@ import { handlePsLiteBridgeRequest, } from "./bridge.js";
|
|
|
2
2
|
import { createRustlsPsLiteRelayTlsFactory } from "./relay-tls.js";
|
|
3
3
|
const DATA_FRAME_TYPE = 1;
|
|
4
4
|
const HEADER_BYTES = 5;
|
|
5
|
+
const RESPONSE_CHUNK_BYTES = 16 * 1024;
|
|
5
6
|
const DEFAULT_CONTROL_URL = "wss://control.34.16.49.200.sslip.io:8443";
|
|
6
7
|
const DEFAULT_PUBLIC_SUFFIX = "34.16.49.200.sslip.io";
|
|
7
8
|
const DEFAULT_ORIGIN = "https://ps-lite.local";
|
|
9
|
+
/**
|
|
10
|
+
* Close code the relay sends to the losing side when a new connection claims
|
|
11
|
+
* the same sessionId. Terminal for this client: reconnecting would evict the
|
|
12
|
+
* winner right back and the two tabs would trade the session every backoff
|
|
13
|
+
* tick (observed live as a 1012 eviction loop every ~2s with two app tabs).
|
|
14
|
+
*/
|
|
15
|
+
export const RELAY_CLOSE_SESSION_REPLACED = 1012;
|
|
16
|
+
/**
|
|
17
|
+
* A heartbeat tick arriving more than this many intervals after the previous
|
|
18
|
+
* one means the tab's timers were throttled (Chrome backgrounds clamp them to
|
|
19
|
+
* >= 1/min), not that the tunnel is dead. Such a tick probes with a fresh ping
|
|
20
|
+
* instead of closing on stale elapsed time (BUI-665).
|
|
21
|
+
*/
|
|
22
|
+
const HEARTBEAT_LATE_FIRE_FACTOR = 2;
|
|
8
23
|
export function psLiteRelayControlUrl(sessionId, controlUrl = DEFAULT_CONTROL_URL) {
|
|
9
24
|
return `${controlUrl.replace(/\/+$/, "")}/browser/${sessionId}`;
|
|
10
25
|
}
|
|
11
26
|
export function psLiteRelayPublicUrl(sessionId, publicSuffix = DEFAULT_PUBLIC_SUFFIX) {
|
|
12
27
|
return `https://${sessionId}.${publicSuffix.replace(/^\./, "")}`;
|
|
13
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Defers read-fulfillment reports until the relay has delivered the in-flight
|
|
31
|
+
* response. The core data handler reports fulfillment as soon as it BUILDS the
|
|
32
|
+
* response, but over the relay the (potentially multi-MB) body still has to be
|
|
33
|
+
* pumped through TLS over the WebSocket. Consumers act on the report
|
|
34
|
+
* immediately — the DCR approval page closes the tab hosting this PS — so an
|
|
35
|
+
* eager report kills the tunnel mid-transfer and the builder gets a truncated
|
|
36
|
+
* body (UND_ERR_RES_CONTENT_LENGTH_MISMATCH) after escrow already settled.
|
|
37
|
+
* Gating the report on relay drain makes "fulfilled" mean "delivered".
|
|
38
|
+
*
|
|
39
|
+
* `getRelayClient` is late-bound: the runtime needs the reporter at
|
|
40
|
+
* construction time, before the relay client exists. When it returns
|
|
41
|
+
* undefined (relay disabled / not started yet), reports pass straight through.
|
|
42
|
+
*/
|
|
43
|
+
export function createRelayDrainGatedReadFulfillmentReporter(reporter, getRelayClient) {
|
|
44
|
+
return {
|
|
45
|
+
async report(event) {
|
|
46
|
+
await getRelayClient()?.whenDrained();
|
|
47
|
+
return reporter.report(event);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
14
51
|
export function startPsLiteRelayClient(options) {
|
|
15
52
|
const baseControlUrl = options.controlUrl ?? DEFAULT_CONTROL_URL;
|
|
16
53
|
const controlUrl = psLiteRelayControlUrl(options.sessionId, baseControlUrl);
|
|
17
|
-
const socket = createSocket(options.webSocketFactory, controlUrl);
|
|
18
54
|
const tls = options.tls === undefined
|
|
19
55
|
? createRustlsPsLiteRelayTlsFactory({
|
|
20
56
|
controlUrl: baseControlUrl,
|
|
21
57
|
publicSuffix: options.publicSuffix,
|
|
22
58
|
certIssuerUrl: options.certIssuerUrl,
|
|
59
|
+
identityStore: options.tlsIdentityStore,
|
|
23
60
|
logger: options.logger,
|
|
24
61
|
})
|
|
25
62
|
: options.tls;
|
|
26
63
|
const streams = new Map();
|
|
27
64
|
const pendingStreamData = new Map();
|
|
28
65
|
const origin = options.origin ?? DEFAULT_ORIGIN;
|
|
66
|
+
// Resilience knobs. Defaults chosen so a backgrounded mobile tab whose socket
|
|
67
|
+
// went half-open (no `onclose` ever fires) is detected within ~1 missed
|
|
68
|
+
// heartbeat and reconnected with capped exponential backoff.
|
|
69
|
+
const heartbeatIntervalMs = options.heartbeatIntervalMs ?? 20_000;
|
|
70
|
+
const heartbeatTimeoutMs = options.heartbeatTimeoutMs ?? 45_000;
|
|
71
|
+
const reconnectInitialDelayMs = options.reconnectInitialDelayMs ?? 1_000;
|
|
72
|
+
const reconnectMaxDelayMs = options.reconnectMaxDelayMs ?? 30_000;
|
|
29
73
|
let issueToken;
|
|
30
74
|
let closed = false;
|
|
31
|
-
socket
|
|
32
|
-
|
|
75
|
+
// `socket` is reassigned on every (re)connect; all the closures below read it
|
|
76
|
+
// lazily at call time, so they always act on the current socket.
|
|
77
|
+
let socket;
|
|
78
|
+
let reconnectAttempts = 0;
|
|
79
|
+
let heartbeatTimer;
|
|
80
|
+
let reconnectTimer;
|
|
81
|
+
// Liveness is evidence-based (BUI-665): ANY frame from the relay — data,
|
|
82
|
+
// control, pong — proves the tunnel is alive. The heartbeat declares it dead
|
|
83
|
+
// only when a ping it actually SENT went unanswered by any frame for the
|
|
84
|
+
// full timeout window, measured by wall clock. A late-firing throttled timer
|
|
85
|
+
// that finds recent frames must never kill a healthy socket.
|
|
86
|
+
let lastFrameReceivedAt = 0;
|
|
87
|
+
// Wall-clock send time of the oldest ping not yet answered by any frame;
|
|
88
|
+
// undefined when the tunnel has proven itself since the last ping.
|
|
89
|
+
let unansweredPingSentAt;
|
|
90
|
+
let lastHeartbeatCheckAt = 0;
|
|
91
|
+
let heartbeatGraceUsed = false;
|
|
33
92
|
const log = (line) => options.logger?.(line);
|
|
34
93
|
const sendText = (message) => {
|
|
35
94
|
if (socket.readyState === socket.OPEN) {
|
|
@@ -50,12 +109,19 @@ export function startPsLiteRelayClient(options) {
|
|
|
50
109
|
};
|
|
51
110
|
const writePlaintextResponse = (stream, responseBytes) => {
|
|
52
111
|
if (!stream.tls) {
|
|
53
|
-
|
|
112
|
+
for (const chunk of chunks(responseBytes, RESPONSE_CHUNK_BYTES)) {
|
|
113
|
+
sendData(stream.streamId, chunk);
|
|
114
|
+
}
|
|
54
115
|
return;
|
|
55
116
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
117
|
+
const responseChunks = chunks(responseBytes, RESPONSE_CHUNK_BYTES);
|
|
118
|
+
for (let index = 0; index < responseChunks.length; index += 1) {
|
|
119
|
+
const step = stream.tls.writePlaintext(responseChunks[index], index === responseChunks.length - 1);
|
|
120
|
+
for (const chunk of chunks(step.tls, RESPONSE_CHUNK_BYTES)) {
|
|
121
|
+
if (chunk.length > 0) {
|
|
122
|
+
sendData(stream.streamId, chunk);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
59
125
|
}
|
|
60
126
|
};
|
|
61
127
|
const drainHttpRequests = async (stream) => {
|
|
@@ -141,6 +207,8 @@ export function startPsLiteRelayClient(options) {
|
|
|
141
207
|
return;
|
|
142
208
|
}
|
|
143
209
|
if (message.type === "pong") {
|
|
210
|
+
// Liveness is recorded for every frame in socket.onmessage; the pong
|
|
211
|
+
// carries no other payload.
|
|
144
212
|
return;
|
|
145
213
|
}
|
|
146
214
|
if (message.type === "stream.open" &&
|
|
@@ -174,26 +242,164 @@ export function startPsLiteRelayClient(options) {
|
|
|
174
242
|
}
|
|
175
243
|
processPayload(stream, frame.payload);
|
|
176
244
|
};
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
245
|
+
const stopHeartbeat = () => {
|
|
246
|
+
if (heartbeatTimer !== undefined) {
|
|
247
|
+
clearInterval(heartbeatTimer);
|
|
248
|
+
heartbeatTimer = undefined;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
const heartbeatTick = () => {
|
|
252
|
+
if (socket.readyState !== socket.OPEN) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const now = Date.now();
|
|
256
|
+
// A tick arriving well past its cadence means the tab's timers were
|
|
257
|
+
// throttled — the elapsed time says nothing about the tunnel.
|
|
258
|
+
const firedLate = now - lastHeartbeatCheckAt >
|
|
259
|
+
heartbeatIntervalMs * HEARTBEAT_LATE_FIRE_FACTOR;
|
|
260
|
+
lastHeartbeatCheckAt = now;
|
|
261
|
+
if (unansweredPingSentAt !== undefined &&
|
|
262
|
+
lastFrameReceivedAt >= unansweredPingSentAt) {
|
|
263
|
+
// A frame arrived since the ping went out — pong, data, or control all
|
|
264
|
+
// count as proof of life.
|
|
265
|
+
unansweredPingSentAt = undefined;
|
|
266
|
+
heartbeatGraceUsed = false;
|
|
267
|
+
}
|
|
268
|
+
const pingUnansweredForFullWindow = unansweredPingSentAt !== undefined &&
|
|
269
|
+
now - unansweredPingSentAt > heartbeatTimeoutMs;
|
|
270
|
+
if (pingUnansweredForFullWindow && firedLate && !heartbeatGraceUsed) {
|
|
271
|
+
// Throttling, not deadness: the ping (and its answer) may have been
|
|
272
|
+
// stalled along with the tab. Probe with a fresh ping and re-check on
|
|
273
|
+
// the next tick instead of killing a usually-healthy socket.
|
|
274
|
+
heartbeatGraceUsed = true;
|
|
275
|
+
unansweredPingSentAt = undefined;
|
|
276
|
+
}
|
|
277
|
+
else if (pingUnansweredForFullWindow) {
|
|
278
|
+
// A backgrounded/suspended tab can leave the socket half-open: it never
|
|
279
|
+
// fires `onclose`, so reconnect-on-close alone never triggers. A ping we
|
|
280
|
+
// actually sent drew no frame at all for the full wall-clock window —
|
|
281
|
+
// the tunnel really is dead; force it closed → onclose → reconnect.
|
|
282
|
+
log("relay heartbeat timeout — forcing reconnect");
|
|
283
|
+
try {
|
|
284
|
+
socket.close(4000, "heartbeat_timeout");
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// Ignore: a socket that can't be closed will be replaced on reconnect.
|
|
288
|
+
}
|
|
181
289
|
return;
|
|
182
290
|
}
|
|
183
|
-
|
|
291
|
+
sendText({ type: "ping" });
|
|
292
|
+
if (unansweredPingSentAt === undefined) {
|
|
293
|
+
unansweredPingSentAt = now;
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
const startHeartbeat = () => {
|
|
297
|
+
stopHeartbeat();
|
|
298
|
+
lastFrameReceivedAt = Date.now();
|
|
299
|
+
lastHeartbeatCheckAt = Date.now();
|
|
300
|
+
unansweredPingSentAt = undefined;
|
|
301
|
+
heartbeatGraceUsed = false;
|
|
302
|
+
heartbeatTimer = setInterval(heartbeatTick, heartbeatIntervalMs);
|
|
184
303
|
};
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
304
|
+
const scheduleReconnect = () => {
|
|
305
|
+
if (closed || reconnectTimer !== undefined) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const delay = Math.min(reconnectMaxDelayMs, reconnectInitialDelayMs * 2 ** reconnectAttempts);
|
|
309
|
+
reconnectAttempts += 1;
|
|
310
|
+
reconnectTimer = setTimeout(() => {
|
|
311
|
+
reconnectTimer = undefined;
|
|
312
|
+
connect();
|
|
313
|
+
}, delay);
|
|
314
|
+
};
|
|
315
|
+
function connect() {
|
|
316
|
+
// Terminal states (intentional close, or a 1012 session takeover) must
|
|
317
|
+
// never re-open a socket, even if a stale timer or event slips through.
|
|
318
|
+
if (closed) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
issueToken = undefined;
|
|
322
|
+
socket = createSocket(options.webSocketFactory, controlUrl);
|
|
323
|
+
socket.binaryType = "arraybuffer";
|
|
324
|
+
options.onStatus?.("connecting");
|
|
325
|
+
socket.onopen = () => {
|
|
326
|
+
reconnectAttempts = 0;
|
|
327
|
+
startHeartbeat();
|
|
328
|
+
options.onStatus?.("connected");
|
|
329
|
+
};
|
|
330
|
+
socket.onmessage = (event) => {
|
|
331
|
+
lastFrameReceivedAt = Date.now();
|
|
332
|
+
if (typeof event.data === "string") {
|
|
333
|
+
handleControl(JSON.parse(event.data));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
handleDataFrame(event.data);
|
|
337
|
+
};
|
|
338
|
+
socket.onclose = (event) => {
|
|
339
|
+
stopHeartbeat();
|
|
340
|
+
streams.forEach((stream) => stream.tls?.close?.());
|
|
341
|
+
streams.clear();
|
|
342
|
+
pendingStreamData.clear();
|
|
343
|
+
issueToken = undefined;
|
|
344
|
+
const detail = { code: event?.code, reason: event?.reason };
|
|
345
|
+
if (closed) {
|
|
346
|
+
options.onStatus?.("closed", detail);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (event?.code === RELAY_CLOSE_SESSION_REPLACED) {
|
|
350
|
+
// Another connection (typically a second tab) now owns this session.
|
|
351
|
+
// Reconnecting would evict it and start a session tug-of-war, so this
|
|
352
|
+
// client steps down for good and lets the host surface the handoff.
|
|
353
|
+
closed = true;
|
|
354
|
+
// Cancel any reconnect already scheduled by an earlier drop so a
|
|
355
|
+
// pending timer can't fire connect() after we've stepped down.
|
|
356
|
+
if (reconnectTimer !== undefined) {
|
|
357
|
+
clearTimeout(reconnectTimer);
|
|
358
|
+
reconnectTimer = undefined;
|
|
359
|
+
}
|
|
360
|
+
log("relay session replaced by another connection — not reconnecting");
|
|
361
|
+
options.onStatus?.("replaced", detail);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
options.onStatus?.("disconnected", detail);
|
|
365
|
+
scheduleReconnect();
|
|
366
|
+
};
|
|
367
|
+
socket.onerror = () => {
|
|
368
|
+
if (closed) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
options.onStatus?.("error");
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
connect();
|
|
375
|
+
// Drained = no HTTP streams in flight and nothing queued in the socket's
|
|
376
|
+
// send buffer. Only an OPEN socket can still be flushing; a closed or
|
|
377
|
+
// reconnecting socket's buffered bytes are gone either way.
|
|
378
|
+
const isDrained = () => {
|
|
379
|
+
if (streams.size > 0) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
if (!closed && socket.readyState === socket.OPEN) {
|
|
383
|
+
return (socket.bufferedAmount ?? 0) === 0;
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
190
386
|
};
|
|
191
|
-
socket.onerror = () => options.onStatus?.("error");
|
|
192
387
|
return {
|
|
193
388
|
sessionId: options.sessionId,
|
|
194
389
|
url: controlUrl,
|
|
390
|
+
async whenDrained({ timeoutMs = 20_000, pollIntervalMs = 50 } = {}) {
|
|
391
|
+
const deadline = Date.now() + timeoutMs;
|
|
392
|
+
while (!isDrained() && Date.now() < deadline) {
|
|
393
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
394
|
+
}
|
|
395
|
+
},
|
|
195
396
|
close(reason = "closed") {
|
|
196
397
|
closed = true;
|
|
398
|
+
stopHeartbeat();
|
|
399
|
+
if (reconnectTimer !== undefined) {
|
|
400
|
+
clearTimeout(reconnectTimer);
|
|
401
|
+
reconnectTimer = undefined;
|
|
402
|
+
}
|
|
197
403
|
streams.forEach((stream) => stream.tls?.close?.());
|
|
198
404
|
streams.clear();
|
|
199
405
|
pendingStreamData.clear();
|
|
@@ -213,15 +419,78 @@ async function handleRelayHttpRequest(runtime, request, origin) {
|
|
|
213
419
|
const bridgeResponse = await handlePsLiteBridgeRequest(runtime, bridgeRequest, {
|
|
214
420
|
origin,
|
|
215
421
|
});
|
|
216
|
-
|
|
422
|
+
// Large exports (e.g. chatgpt.conversations) are big JSON streamed over the
|
|
423
|
+
// relay's WebSocket tunnel; an uncompressed body inflates transfer time and the
|
|
424
|
+
// window for a mid-stream drop (truncated read → UND_ERR_RES_CONTENT_LENGTH_MISMATCH).
|
|
425
|
+
// gzip when the client accepts it and the payload is large enough to be worth it;
|
|
426
|
+
// the SDK/undici sends Accept-Encoding and auto-decompresses. See BUI-591.
|
|
427
|
+
const bodyBytes = decodeBase64(bridgeResponse.body);
|
|
428
|
+
const acceptsGzip = (request.headers["accept-encoding"] ?? "").includes("gzip");
|
|
429
|
+
const alreadyEncoded = Boolean(bridgeResponse.headers?.["content-encoding"]);
|
|
430
|
+
if (acceptsGzip &&
|
|
431
|
+
!alreadyEncoded &&
|
|
432
|
+
bodyBytes.length >= GZIP_MIN_BYTES &&
|
|
433
|
+
typeof CompressionStream !== "undefined") {
|
|
434
|
+
const gzipped = await gzipBytes(bodyBytes);
|
|
435
|
+
return buildHttpResponse(bridgeResponse, {
|
|
436
|
+
bodyOverride: gzipped,
|
|
437
|
+
contentEncoding: "gzip",
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
return buildHttpResponse(bridgeResponse, { bodyOverride: bodyBytes });
|
|
441
|
+
}
|
|
442
|
+
// Responses below this size aren't worth the gzip overhead, and small reads
|
|
443
|
+
// already complete reliably over the relay.
|
|
444
|
+
const GZIP_MIN_BYTES = 1024;
|
|
445
|
+
async function gzipBytes(input) {
|
|
446
|
+
const cs = new CompressionStream("gzip");
|
|
447
|
+
const writer = cs.writable.getWriter();
|
|
448
|
+
// Copy into a fresh ArrayBuffer-backed view: TS types the stream's chunk as
|
|
449
|
+
// BufferSource, which excludes the generic Uint8Array<ArrayBufferLike>.
|
|
450
|
+
const chunk = new Uint8Array(input);
|
|
451
|
+
const writeDone = writer.write(chunk).then(() => writer.close());
|
|
452
|
+
const reader = cs.readable.getReader();
|
|
453
|
+
const chunks = [];
|
|
454
|
+
let total = 0;
|
|
455
|
+
for (;;) {
|
|
456
|
+
const { value, done } = await reader.read();
|
|
457
|
+
if (done)
|
|
458
|
+
break;
|
|
459
|
+
if (value) {
|
|
460
|
+
chunks.push(value);
|
|
461
|
+
total += value.length;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
await writeDone;
|
|
465
|
+
const out = new Uint8Array(total);
|
|
466
|
+
let offset = 0;
|
|
467
|
+
for (const chunk of chunks) {
|
|
468
|
+
out.set(chunk, offset);
|
|
469
|
+
offset += chunk.length;
|
|
470
|
+
}
|
|
471
|
+
return out;
|
|
217
472
|
}
|
|
218
|
-
export function buildHttpResponse(response) {
|
|
473
|
+
export function buildHttpResponse(response, opts) {
|
|
219
474
|
const responseHeaders = {
|
|
220
475
|
"cache-control": "no-store",
|
|
221
476
|
connection: "close",
|
|
222
477
|
...response.headers,
|
|
223
478
|
};
|
|
224
|
-
|
|
479
|
+
// We always emit an authoritative content-length below, computed from the
|
|
480
|
+
// exact bytes we write (gzip changes the length vs. the upstream value). Drop
|
|
481
|
+
// any upstream copy first — the core raw-data path sets Content-Length and the
|
|
482
|
+
// bridge lowercases it, so without this the head would carry two conflicting
|
|
483
|
+
// content-length values and clients reject that (the same mismatch class this
|
|
484
|
+
// change fixes). Match case-insensitively in case the name wasn't normalized.
|
|
485
|
+
for (const key of Object.keys(responseHeaders)) {
|
|
486
|
+
if (key.toLowerCase() === "content-length") {
|
|
487
|
+
delete responseHeaders[key];
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (opts?.contentEncoding) {
|
|
491
|
+
responseHeaders["content-encoding"] = opts.contentEncoding;
|
|
492
|
+
}
|
|
493
|
+
const bodyBytes = opts?.bodyOverride ?? decodeBase64(response.body);
|
|
225
494
|
const head = [
|
|
226
495
|
`HTTP/1.1 ${response.status} ${httpStatusText(response.status)}`,
|
|
227
496
|
...Object.entries(responseHeaders).map(([key, value]) => `${key}: ${value}`),
|
|
@@ -309,6 +578,15 @@ function encodeBase64(bytes) {
|
|
|
309
578
|
? globalThis.btoa(binary)
|
|
310
579
|
: Buffer.from(binary, "binary").toString("base64");
|
|
311
580
|
}
|
|
581
|
+
function chunks(bytes, chunkBytes) {
|
|
582
|
+
if (bytes.length === 0)
|
|
583
|
+
return [bytes];
|
|
584
|
+
const result = [];
|
|
585
|
+
for (let offset = 0; offset < bytes.length; offset += chunkBytes) {
|
|
586
|
+
result.push(bytes.slice(offset, offset + chunkBytes));
|
|
587
|
+
}
|
|
588
|
+
return result;
|
|
589
|
+
}
|
|
312
590
|
function decodeBase64(input) {
|
|
313
591
|
if (!input)
|
|
314
592
|
return new Uint8Array();
|