@floegence/flowersec-core 3.2.1 → 5.0.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 +57 -200
- package/THIRD_PARTY_NOTICES.md +11 -11
- package/dist/browser/index.d.ts +0 -5
- package/dist/browser/index.js +0 -3
- package/dist/cli.js +93 -64
- package/dist/facade.d.ts +0 -17
- package/dist/facade.js +0 -11
- package/dist/generated/unicode151.d.ts +2 -0
- package/dist/generated/unicode151.js +83 -0
- package/dist/interop/proxyServerPeer.js +34 -20
- package/dist/interop/serverParityPeer.js +11 -252
- package/dist/node/acceptor.d.ts +1 -57
- package/dist/node/acceptor.js +3 -420
- package/dist/node/acceptorV3.js +2 -2
- package/dist/node/connectSessionV3.js +2 -2
- package/dist/node/index.d.ts +2 -17
- package/dist/node/index.js +1 -9
- package/dist/node/nativeTransportAddon.d.ts +7 -36
- package/dist/node/nativeTransportAddon.js +7 -27
- package/dist/node/proxyServer.d.ts +2 -2
- package/dist/node/proxyServer.js +2 -2
- package/dist/node/rawQuicAdapterV3.d.ts +2 -2
- package/dist/node/rawQuicAdapterV3.js +1 -1
- package/dist/node/rawQuicServerV3.d.ts +2 -2
- package/dist/node/rawQuicServerV3.js +1 -1
- package/dist/node/rawQuicTls.d.ts +2 -0
- package/dist/node/{rawQuicAdapter.js → rawQuicTls.js} +30 -45
- package/dist/node/tunnelRuntimeV3.js +2 -2
- package/dist/proxy/index.d.ts +1 -1
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/integration.d.ts +5 -5
- package/dist/proxy/integration.js +2 -2
- package/dist/proxy/runtime.js +11 -26
- package/dist/proxy/serviceWorkerRuntime.d.ts +7 -0
- package/dist/proxy/serviceWorkerRuntime.js +75 -0
- package/dist/proxy/types.d.ts +0 -1
- package/dist/proxy/windowBridge.d.ts +2 -0
- package/dist/proxy/windowBridge.js +53 -6
- package/dist/public/contract.d.ts +1 -3
- package/dist/public/streamHandlers.d.ts +0 -3
- package/dist/public/streamHandlers.js +2 -4
- package/dist/public/streamMetadata.js +2 -2
- package/dist/runtime/errors.d.ts +2 -2
- package/dist/testSupport/tlsFixture.d.ts +2 -0
- package/dist/testSupport/tlsFixture.js +8 -0
- package/dist/utils/errors.d.ts +0 -2
- package/dist/utils/errors.js +0 -80
- package/dist/v3/artifact.js +17 -3
- package/dist/v3/carrier.d.ts +2 -2
- package/dist/v3/controller.js +2 -6
- package/dist/v3/protocol.js +2 -103
- package/dist/v3/retryDisposition.d.ts +2 -2
- package/dist/v3/retryDisposition.js +0 -7
- package/dist/v3/security.d.ts +1 -10
- package/dist/v3/security.js +2 -9
- package/dist/vendor/tr46.d.ts +4 -0
- package/dist/vendor/tr46.js +37 -32
- package/package.json +19 -17
- package/sbom/cyclonedx.json +62 -62
- package/sbom/spdx.json +65 -65
- package/dist/browser/connectSession.d.ts +0 -13
- package/dist/browser/connectSession.js +0 -40
- package/dist/browser/runtimeCapability.d.ts +0 -13
- package/dist/browser/runtimeCapability.js +0 -27
- package/dist/browser/sessionRuntime.d.ts +0 -2
- package/dist/browser/sessionRuntime.js +0 -21
- package/dist/browser/v2.d.ts +0 -3
- package/dist/browser/v2.js +0 -2
- package/dist/browser/webTransportClient.d.ts +0 -8
- package/dist/browser/webTransportClient.js +0 -55
- package/dist/connectionController.d.ts +0 -55
- package/dist/connectionController.js +0 -441
- package/dist/connector/adapters/rawQuicCandidate.d.ts +0 -5
- package/dist/connector/adapters/rawQuicCandidate.js +0 -71
- package/dist/connector/adapters/webSocketCandidate.d.ts +0 -7
- package/dist/connector/adapters/webSocketCandidate.js +0 -116
- package/dist/connector/adapters/webTransportCandidate.d.ts +0 -5
- package/dist/connector/adapters/webTransportCandidate.js +0 -73
- package/dist/connector/admissionCommit.d.ts +0 -31
- package/dist/connector/admissionCommit.js +0 -239
- package/dist/connector/sessionAcceptor.d.ts +0 -38
- package/dist/connector/sessionAcceptor.js +0 -158
- package/dist/connector/sessionConfig.d.ts +0 -3
- package/dist/connector/sessionConfig.js +0 -30
- package/dist/connector/sessionConnector.d.ts +0 -47
- package/dist/connector/sessionConnector.js +0 -606
- package/dist/node/connectSession.d.ts +0 -23
- package/dist/node/connectSession.js +0 -93
- package/dist/node/controlplane.d.ts +0 -137
- package/dist/node/controlplane.js +0 -443
- package/dist/node/rawQuicAdapter.d.ts +0 -9
- package/dist/node/rawQuicServer.d.ts +0 -24
- package/dist/node/rawQuicServer.js +0 -37
- package/dist/node/runtimeCapability.d.ts +0 -14
- package/dist/node/runtimeCapability.js +0 -24
- package/dist/node/sessionRuntime.d.ts +0 -2
- package/dist/node/sessionRuntime.js +0 -13
- package/dist/node/tunnelRuntime.d.ts +0 -42
- package/dist/node/tunnelRuntime.js +0 -559
- package/dist/node/v2.d.ts +0 -11
- package/dist/node/v2.js +0 -6
- package/dist/node/webSocketServer.d.ts +0 -24
- package/dist/node/webSocketServer.js +0 -135
- package/dist/public/artifact.d.ts +0 -11
- package/dist/public/artifact.js +0 -44
- package/dist/public/artifactLease.d.ts +0 -10
- package/dist/public/artifactLease.js +0 -41
- package/dist/public/connectError.d.ts +0 -6
- package/dist/public/connectError.js +0 -9
- package/dist/transport/webSocketAdapter.d.ts +0 -31
- package/dist/transport/webSocketAdapter.js +0 -370
- package/dist/transport/webTransportAdapter.d.ts +0 -27
- package/dist/transport/webTransportAdapter.js +0 -534
- package/dist/v2/admissionError.d.ts +0 -4
- package/dist/v2/admissionError.js +0 -8
- package/dist/v2/artifact.d.ts +0 -128
- package/dist/v2/artifact.js +0 -1131
- package/dist/v2/artifactLease.d.ts +0 -1
- package/dist/v2/artifactLease.js +0 -7
- package/dist/v2/capability.d.ts +0 -29
- package/dist/v2/capability.js +0 -190
- package/dist/v2/carrier.d.ts +0 -84
- package/dist/v2/carrier.js +0 -411
- package/dist/v2/contract.d.ts +0 -46
- package/dist/v2/contract.js +0 -1
- package/dist/v2/handshake.d.ts +0 -80
- package/dist/v2/handshake.js +0 -470
- package/dist/v2/index.d.ts +0 -14
- package/dist/v2/index.js +0 -7
- package/dist/v2/opaqueArtifact.d.ts +0 -1
- package/dist/v2/opaqueArtifact.js +0 -2
- package/dist/v2/protocol.d.ts +0 -99
- package/dist/v2/protocol.js +0 -737
- package/dist/v2/publicSession.d.ts +0 -1
- package/dist/v2/publicSession.js +0 -281
- package/dist/v2/retryDisposition.d.ts +0 -16
- package/dist/v2/retryDisposition.js +0 -30
- package/dist/v2/session.d.ts +0 -310
- package/dist/v2/session.js +0 -2127
- package/dist/v2/streamLifetimeLedger.d.ts +0 -31
- package/dist/v2/streamLifetimeLedger.js +0 -131
- package/dist/v2/streamMetadata.d.ts +0 -1
- package/dist/v2/streamMetadata.js +0 -7
- package/dist/v2/unreliableMessage.d.ts +0 -43
- package/dist/v2/unreliableMessage.js +0 -254
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { CarrierError
|
|
3
|
-
export const NATIVE_TRANSPORT_CONTRACT_VERSION =
|
|
2
|
+
import { CarrierError } from "../v3/carrier.js";
|
|
3
|
+
export const NATIVE_TRANSPORT_CONTRACT_VERSION = 3;
|
|
4
4
|
const NATIVE_PACKAGE = "@floegence/flowersec-node-native";
|
|
5
5
|
const SERVER_PARITY_NATIVE_ADDON = "FLOWERSEC_SERVER_PARITY_NATIVE_ADDON";
|
|
6
6
|
export class NativeTransportUnavailableError extends Error {
|
|
@@ -45,31 +45,13 @@ export function createNativeRawQuicDriver(addon = loadNativeTransportAddon()) {
|
|
|
45
45
|
return Object.freeze({
|
|
46
46
|
async connectRawQuic(options, operation = {}) {
|
|
47
47
|
const native = await settle(addon.connectRawQuic(options), operation.signal);
|
|
48
|
-
return wrapSession(native
|
|
48
|
+
return wrapSession(native);
|
|
49
49
|
},
|
|
50
50
|
async bindRawQuic(options) {
|
|
51
51
|
const native = await addon.bindRawQuic(options);
|
|
52
52
|
return Object.freeze({
|
|
53
53
|
address: () => native.address(),
|
|
54
|
-
accept: async (operation = {}) => wrapSession(await settle(native.accept(), operation.signal)
|
|
55
|
-
async close() {
|
|
56
|
-
await native.close();
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
export function createNativeRawQuicDriverV3(addon = loadNativeTransportAddon()) {
|
|
63
|
-
return Object.freeze({
|
|
64
|
-
async connectRawQuic(options, operation = {}) {
|
|
65
|
-
const native = await settle(addon.connectRawQuicV3(options), operation.signal);
|
|
66
|
-
return wrapSession(native, 3);
|
|
67
|
-
},
|
|
68
|
-
async bindRawQuic(options) {
|
|
69
|
-
const native = await addon.bindRawQuicV3(options);
|
|
70
|
-
return Object.freeze({
|
|
71
|
-
address: () => native.address(),
|
|
72
|
-
accept: async (operation = {}) => wrapSession(await settle(native.accept(), operation.signal), 3),
|
|
54
|
+
accept: async (operation = {}) => wrapSession(await settle(native.accept(), operation.signal)),
|
|
73
55
|
async close() {
|
|
74
56
|
await native.close();
|
|
75
57
|
},
|
|
@@ -92,12 +74,10 @@ function isNativeTransportAddon(value) {
|
|
|
92
74
|
}
|
|
93
75
|
return contractVersion === NATIVE_TRANSPORT_CONTRACT_VERSION &&
|
|
94
76
|
typeof candidate.connectRawQuic === "function" &&
|
|
95
|
-
typeof candidate.bindRawQuic === "function"
|
|
96
|
-
typeof candidate.connectRawQuicV3 === "function" &&
|
|
97
|
-
typeof candidate.bindRawQuicV3 === "function";
|
|
77
|
+
typeof candidate.bindRawQuic === "function";
|
|
98
78
|
}
|
|
99
|
-
function wrapSession(native
|
|
100
|
-
if (native.wireVersion !==
|
|
79
|
+
function wrapSession(native) {
|
|
80
|
+
if (native.wireVersion !== 3) {
|
|
101
81
|
native.abort();
|
|
102
82
|
throw new NativeTransportUnavailableError();
|
|
103
83
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StreamHandlers } from "../public/streamHandlers.js";
|
|
2
|
-
import {
|
|
3
|
-
export type StreamHandlerRegistrar = StreamHandlers |
|
|
2
|
+
import { SessionHandlersV3 } from "./acceptor.js";
|
|
3
|
+
export type StreamHandlerRegistrar = StreamHandlers | SessionHandlersV3;
|
|
4
4
|
export type ProxyServerOptions = Readonly<{
|
|
5
5
|
upstream: string;
|
|
6
6
|
upstreamOrigin: string;
|
package/dist/node/proxyServer.js
CHANGED
|
@@ -3,7 +3,7 @@ import { SessionError } from "../public/contract.js";
|
|
|
3
3
|
import { writeJsonFrame } from "../framing/jsonframe.js";
|
|
4
4
|
import { ProxyByteReader, writeAll } from "../proxy/stream.js";
|
|
5
5
|
import { StreamHandlers, registerStreamHandlersAtomically, } from "../public/streamHandlers.js";
|
|
6
|
-
import {
|
|
6
|
+
import { SessionHandlersV3, registerSessionStreamHandlersAtomically, } from "./acceptor.js";
|
|
7
7
|
const HTTP_KIND = "flowersec-proxy/http1";
|
|
8
8
|
const WS_KIND = "flowersec-proxy/ws";
|
|
9
9
|
const WIRE_VERSION = 1;
|
|
@@ -47,7 +47,7 @@ export class ProxyServer {
|
|
|
47
47
|
if (handlers instanceof StreamHandlers) {
|
|
48
48
|
registerStreamHandlersAtomically(handlers, registrations);
|
|
49
49
|
}
|
|
50
|
-
else if (handlers instanceof
|
|
50
|
+
else if (handlers instanceof SessionHandlersV3) {
|
|
51
51
|
registerSessionStreamHandlersAtomically(handlers, registrations);
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ArtifactV3, CanonicalArtifactCandidateV3 } from "../v3/artifact.js";
|
|
2
2
|
import type { NativeCarrierSessionV3 } from "../v3/carrier.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { NativeRawQuicDriver } from "./nativeTransportAddon.js";
|
|
4
4
|
type NodeTLSRootsV3 = string | Uint8Array | readonly (string | Uint8Array)[];
|
|
5
|
-
export declare function createNodeRawQuicClientV3(driver:
|
|
5
|
+
export declare function createNodeRawQuicClientV3(driver: NativeRawQuicDriver, candidate: CanonicalArtifactCandidateV3, artifact: ArtifactV3, attemptNowUnixSeconds: number, options?: Readonly<{
|
|
6
6
|
roots?: NodeTLSRootsV3;
|
|
7
7
|
signal?: AbortSignal;
|
|
8
8
|
handshakeTimeoutMs?: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { rootCertificates } from "node:tls";
|
|
2
2
|
import { snapshotTransportSecurityPolicyV3, TransportFailureV3, } from "../v3/security.js";
|
|
3
|
-
import { normalizeCertificateChain } from "./
|
|
3
|
+
import { normalizeCertificateChain } from "./rawQuicTls.js";
|
|
4
4
|
import { alpnForPathV3 } from "../v3/transportConstants.js";
|
|
5
5
|
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
|
|
6
6
|
export async function createNodeRawQuicClientV3(driver, candidate, artifact, attemptNowUnixSeconds, options = {}) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type CarrierSessionV3 } from "../v3/carrier.js";
|
|
2
2
|
import type { PathKind } from "../v3/contract.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { NativeRawQuicDriver } from "./nativeTransportAddon.js";
|
|
4
4
|
export type NodeRawQuicListenerOptionsV3 = Readonly<{
|
|
5
5
|
host: string;
|
|
6
6
|
port: number;
|
|
@@ -21,4 +21,4 @@ export type NodeRawQuicListenerV3 = Readonly<{
|
|
|
21
21
|
}>): Promise<CarrierSessionV3>;
|
|
22
22
|
close(): Promise<void>;
|
|
23
23
|
}>;
|
|
24
|
-
export declare function startNodeRawQuicListenerV3(driver:
|
|
24
|
+
export declare function startNodeRawQuicListenerV3(driver: NativeRawQuicDriver, options: NodeRawQuicListenerOptionsV3): Promise<NodeRawQuicListenerV3>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { adaptNativeCarrierSessionV3 } from "../v3/carrier.js";
|
|
2
|
-
import { normalizeCertificateChain, normalizePrivateKey } from "./
|
|
2
|
+
import { normalizeCertificateChain, normalizePrivateKey } from "./rawQuicTls.js";
|
|
3
3
|
export async function startNodeRawQuicListenerV3(driver, options) {
|
|
4
4
|
validateOptions(options);
|
|
5
5
|
let listener;
|
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
import { X509Certificate, createPrivateKey } from "node:crypto";
|
|
2
|
-
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
|
|
3
2
|
const CERTIFICATE_PEM_BEGIN = "-----BEGIN CERTIFICATE-----";
|
|
4
3
|
const CERTIFICATE_PEM_END = "-----END CERTIFICATE-----";
|
|
5
4
|
const MAX_CERTIFICATE_PEM_BYTES = 256 * 1024;
|
|
6
5
|
const MAX_CERTIFICATE_CHAIN_LENGTH = 32;
|
|
7
|
-
export async function createNodeRawQuicClientV2(driver, candidate, artifact, tls, signal, handshakeTimeoutMs = DEFAULT_HANDSHAKE_TIMEOUT_MS) {
|
|
8
|
-
const url = new URL(candidate.normalized_url);
|
|
9
|
-
if (candidate.carrier !== "raw_quic" || url.protocol !== "quic:" || url.port === "") {
|
|
10
|
-
throw new TypeError("invalid raw QUIC candidate");
|
|
11
|
-
}
|
|
12
|
-
const options = {
|
|
13
|
-
host: unbracket(url.hostname),
|
|
14
|
-
port: Number(url.port),
|
|
15
|
-
serverName: unbracket(url.hostname),
|
|
16
|
-
path: artifact.path.kind,
|
|
17
|
-
trustRootsDer: normalizeCertificateChain(tls.ca),
|
|
18
|
-
inboundBidirectionalStreamCapacity: artifact.session.max_inbound_streams + 2,
|
|
19
|
-
handshakeTimeoutMs,
|
|
20
|
-
};
|
|
21
|
-
return await driver.connectRawQuic(options, { signal });
|
|
22
|
-
}
|
|
23
6
|
export function normalizeCertificateChain(input) {
|
|
24
7
|
const values = Array.isArray(input) ? input : [input];
|
|
25
8
|
const certificates = [];
|
|
@@ -28,32 +11,46 @@ export function normalizeCertificateChain(input) {
|
|
|
28
11
|
if (typeof value !== "string" && !(value instanceof Uint8Array)) {
|
|
29
12
|
throw new TypeError("invalid raw QUIC certificate");
|
|
30
13
|
}
|
|
31
|
-
totalInputBytes += typeof value === "string"
|
|
32
|
-
|
|
14
|
+
totalInputBytes += typeof value === "string"
|
|
15
|
+
? Buffer.byteLength(value, "utf8")
|
|
16
|
+
: value.byteLength;
|
|
17
|
+
if (totalInputBytes > MAX_CERTIFICATE_PEM_BYTES) {
|
|
33
18
|
throw new TypeError("invalid raw QUIC certificate");
|
|
19
|
+
}
|
|
34
20
|
if (typeof value === "string") {
|
|
35
21
|
const blocks = splitCertificatePEM(value);
|
|
36
|
-
if (blocks.length === 0)
|
|
37
|
-
throw new TypeError("invalid raw QUIC certificate");
|
|
38
|
-
if (certificates.length + blocks.length > MAX_CERTIFICATE_CHAIN_LENGTH) {
|
|
22
|
+
if (blocks.length === 0 || certificates.length + blocks.length > MAX_CERTIFICATE_CHAIN_LENGTH) {
|
|
39
23
|
throw new TypeError("invalid raw QUIC certificate");
|
|
40
24
|
}
|
|
41
25
|
for (const block of blocks)
|
|
42
26
|
certificates.push(parseCertificate(block));
|
|
43
27
|
}
|
|
44
|
-
else if (value
|
|
45
|
-
if (certificates.length >= MAX_CERTIFICATE_CHAIN_LENGTH)
|
|
28
|
+
else if (value.length > 0) {
|
|
29
|
+
if (certificates.length >= MAX_CERTIFICATE_CHAIN_LENGTH) {
|
|
46
30
|
throw new TypeError("invalid raw QUIC certificate");
|
|
31
|
+
}
|
|
47
32
|
certificates.push(parseCertificate(value));
|
|
48
33
|
}
|
|
49
34
|
else {
|
|
50
35
|
throw new TypeError("invalid raw QUIC certificate");
|
|
51
36
|
}
|
|
52
37
|
}
|
|
53
|
-
if (certificates.length === 0)
|
|
38
|
+
if (certificates.length === 0) {
|
|
54
39
|
throw new TypeError("raw QUIC requires explicit trust roots");
|
|
40
|
+
}
|
|
55
41
|
return certificates;
|
|
56
42
|
}
|
|
43
|
+
export function normalizePrivateKey(input) {
|
|
44
|
+
if (input.length === 0)
|
|
45
|
+
throw new TypeError("invalid raw QUIC private key");
|
|
46
|
+
try {
|
|
47
|
+
const key = createPrivateKey(input);
|
|
48
|
+
return new Uint8Array(key.export({ format: "der", type: "pkcs8" }));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new TypeError("invalid raw QUIC private key");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
57
54
|
function splitCertificatePEM(value) {
|
|
58
55
|
if (Buffer.byteLength(value, "utf8") > MAX_CERTIFICATE_PEM_BYTES) {
|
|
59
56
|
throw new TypeError("invalid raw QUIC certificate");
|
|
@@ -63,37 +60,28 @@ function splitCertificatePEM(value) {
|
|
|
63
60
|
while (cursor < value.length) {
|
|
64
61
|
const begin = value.indexOf(CERTIFICATE_PEM_BEGIN, cursor);
|
|
65
62
|
if (begin < 0) {
|
|
66
|
-
if (value.slice(cursor).trim().length !== 0)
|
|
63
|
+
if (value.slice(cursor).trim().length !== 0) {
|
|
67
64
|
throw new TypeError("invalid raw QUIC certificate");
|
|
65
|
+
}
|
|
68
66
|
break;
|
|
69
67
|
}
|
|
70
|
-
if (value.slice(cursor, begin).trim().length !== 0)
|
|
68
|
+
if (value.slice(cursor, begin).trim().length !== 0) {
|
|
71
69
|
throw new TypeError("invalid raw QUIC certificate");
|
|
70
|
+
}
|
|
72
71
|
const contentStart = begin + CERTIFICATE_PEM_BEGIN.length;
|
|
73
72
|
const end = value.indexOf(CERTIFICATE_PEM_END, contentStart);
|
|
74
|
-
|
|
73
|
+
const nested = value.indexOf(CERTIFICATE_PEM_BEGIN, contentStart);
|
|
74
|
+
if (end < 0 || nested >= 0 && nested < end) {
|
|
75
75
|
throw new TypeError("invalid raw QUIC certificate");
|
|
76
76
|
}
|
|
77
77
|
blocks.push(value.slice(begin, end + CERTIFICATE_PEM_END.length));
|
|
78
|
-
if (blocks.length > MAX_CERTIFICATE_CHAIN_LENGTH)
|
|
78
|
+
if (blocks.length > MAX_CERTIFICATE_CHAIN_LENGTH) {
|
|
79
79
|
throw new TypeError("invalid raw QUIC certificate");
|
|
80
|
+
}
|
|
80
81
|
cursor = end + CERTIFICATE_PEM_END.length;
|
|
81
82
|
}
|
|
82
83
|
return blocks;
|
|
83
84
|
}
|
|
84
|
-
export function normalizePrivateKey(input) {
|
|
85
|
-
if ((typeof input === "string" && input.length === 0) ||
|
|
86
|
-
(input instanceof Uint8Array && input.length === 0)) {
|
|
87
|
-
throw new TypeError("invalid raw QUIC private key");
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
const key = createPrivateKey(input);
|
|
91
|
-
return new Uint8Array(key.export({ format: "der", type: "pkcs8" }));
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
throw new TypeError("invalid raw QUIC private key");
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
85
|
function parseCertificate(input) {
|
|
98
86
|
try {
|
|
99
87
|
return new Uint8Array(new X509Certificate(input).raw);
|
|
@@ -102,6 +90,3 @@ function parseCertificate(input) {
|
|
|
102
90
|
throw new TypeError("invalid raw QUIC certificate");
|
|
103
91
|
}
|
|
104
92
|
}
|
|
105
|
-
function unbracket(host) {
|
|
106
|
-
return host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
107
|
-
}
|
|
@@ -2,7 +2,7 @@ import { createAdmissionReasonRegistryV3, receiveSessionAdmissionV3, rejectSessi
|
|
|
2
2
|
import { configureServerWebSocketCarrierRoleV3 } from "../v3/webSocketCarrier.js";
|
|
3
3
|
import { AdmissionStatusV3, encodeFSA3ResponseV3, } from "../v3/artifact.js";
|
|
4
4
|
import { startNodeWebSocketListenerV3 } from "./webSocketServerV3.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createNativeRawQuicDriver } from "./nativeTransportAddon.js";
|
|
6
6
|
import { startNodeRawQuicListenerV3 } from "./rawQuicServerV3.js";
|
|
7
7
|
import { consumeTunnelAuthorizationGrantV3, inspectTunnelAuthorizationGrantV3, retireTunnelAuthorizationGrantV3, runtimeAuthorizationRequestV3FromDecoded, validateTunnelAuthorizationGrantV3, } from "./runtimeAuthorizationV3.js";
|
|
8
8
|
const DEFAULT_PAIR_TIMEOUT_MS = 10_000;
|
|
@@ -107,7 +107,7 @@ async function startTunnelRuntimeV3(state) {
|
|
|
107
107
|
pendingSessionTimeoutMs: state.limits.admissionTimeoutMs,
|
|
108
108
|
cleanupTimeoutMs: state.limits.cleanupTimeoutMs,
|
|
109
109
|
})
|
|
110
|
-
: await startNodeRawQuicListenerV3(rawQuicDriver ??=
|
|
110
|
+
: await startNodeRawQuicListenerV3(rawQuicDriver ??= createNativeRawQuicDriver(), {
|
|
111
111
|
...listener,
|
|
112
112
|
path: "tunnel",
|
|
113
113
|
inboundBidirectionalStreamCapacity: state.options.maxInboundStreams + 2,
|
package/dist/proxy/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.j
|
|
|
7
7
|
export type { RegisterServiceWorkerOptions } from "./registerServiceWorker.js";
|
|
8
8
|
export { createServiceWorkerControllerGuard } from "./controllerGuard.js";
|
|
9
9
|
export type { ServiceWorkerControllerGuardConflictPolicy, ServiceWorkerControllerGuardHandle, ServiceWorkerControllerGuardMismatchContext, ServiceWorkerControllerGuardMonitorOptions, ServiceWorkerControllerGuardOptions, ServiceWorkerControllerGuardRepairOptions, } from "./controllerGuard.js";
|
|
10
|
-
export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyControllerWindow, } from "./windowBridge.js";
|
|
10
|
+
export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyAppWindowWithServiceWorkerRuntime, registerProxyControllerWindow, } from "./windowBridge.js";
|
|
11
11
|
export type { ProxyAppServiceWorkerControlOptions, ProxyAppWindowHandle, ProxyControllerWindowHandle, RegisterProxyAppWindowOptions, RegisterProxyAppWindowWithServiceWorkerControlOptions, RegisterProxyControllerWindowOptions, } from "./windowBridge.js";
|
|
12
12
|
export { installWebSocketPatch } from "./wsPatch.js";
|
|
13
13
|
export type { WebSocketPatchOptions } from "./wsPatch.js";
|
package/dist/proxy/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { createProxyRuntime, ensureServiceWorkerRuntimeRegistered } from "./runt
|
|
|
3
3
|
export { createProxyServiceWorkerScript } from "./serviceWorker.js";
|
|
4
4
|
export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
5
5
|
export { createServiceWorkerControllerGuard } from "./controllerGuard.js";
|
|
6
|
-
export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyControllerWindow, } from "./windowBridge.js";
|
|
6
|
+
export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyAppWindowWithServiceWorkerRuntime, registerProxyControllerWindow, } from "./windowBridge.js";
|
|
7
7
|
export { installWebSocketPatch } from "./wsPatch.js";
|
|
8
8
|
export { disableUpstreamServiceWorkerRegister } from "./disableUpstreamServiceWorkerRegister.js";
|
|
9
9
|
export { connectProxyBrowser, connectProxyControllerBrowser, } from "./integration.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
1
|
+
import { type SessionOptionsV3 } from "../browser/connectSessionV3.js";
|
|
2
|
+
import type { ArtifactLeaseV3 } from "../v3/artifactLease.js";
|
|
3
3
|
import type { Session } from "../public/contract.js";
|
|
4
4
|
import type { ProxyRuntime, ProxyRuntimeOptions } from "./types.js";
|
|
5
5
|
import { type ProxyControllerWindowHandle, type RegisterProxyControllerWindowOptions } from "./windowBridge.js";
|
|
6
6
|
export type ProxyBrowserConnectOptions = Readonly<{
|
|
7
|
-
connect?:
|
|
7
|
+
connect?: SessionOptionsV3;
|
|
8
8
|
runtime?: Omit<ProxyRuntimeOptions, "session">;
|
|
9
9
|
serviceWorker?: Readonly<{
|
|
10
10
|
scriptUrl: string;
|
|
@@ -19,11 +19,11 @@ export type ProxyBrowserHandle = Readonly<{
|
|
|
19
19
|
runtime: ProxyRuntime;
|
|
20
20
|
dispose(): Promise<void>;
|
|
21
21
|
}>;
|
|
22
|
-
export declare function connectProxyBrowser(lease:
|
|
22
|
+
export declare function connectProxyBrowser(lease: ArtifactLeaseV3, options?: ProxyBrowserConnectOptions): Promise<ProxyBrowserHandle>;
|
|
23
23
|
export type ProxyControllerBrowserConnectOptions = ProxyBrowserConnectOptions & Readonly<{
|
|
24
24
|
controller: Omit<RegisterProxyControllerWindowOptions, "runtime">;
|
|
25
25
|
}>;
|
|
26
26
|
export type ProxyControllerBrowserHandle = ProxyBrowserHandle & Readonly<{
|
|
27
27
|
controller: ProxyControllerWindowHandle;
|
|
28
28
|
}>;
|
|
29
|
-
export declare function connectProxyControllerBrowser(lease:
|
|
29
|
+
export declare function connectProxyControllerBrowser(lease: ArtifactLeaseV3, options: ProxyControllerBrowserConnectOptions): Promise<ProxyControllerBrowserHandle>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { connectV3 } from "../browser/connectSessionV3.js";
|
|
2
2
|
import { createProxyRuntime } from "./runtime.js";
|
|
3
3
|
import { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
4
4
|
import { registerProxyControllerWindow, } from "./windowBridge.js";
|
|
5
5
|
export async function connectProxyBrowser(lease, options = {}) {
|
|
6
|
-
const session = await
|
|
6
|
+
const session = await connectV3(lease, options.connect);
|
|
7
7
|
let runtime;
|
|
8
8
|
try {
|
|
9
9
|
if (options.serviceWorker !== undefined)
|
package/dist/proxy/runtime.js
CHANGED
|
@@ -5,6 +5,7 @@ import { readU32be, u32be } from "../utils/bin.js";
|
|
|
5
5
|
import { SessionError } from "../public/contract.js";
|
|
6
6
|
import { createStreamMetadata } from "../public/streamMetadata.js";
|
|
7
7
|
import { ProxyByteReader, writeAll } from "./stream.js";
|
|
8
|
+
import { registerProxyRuntimeServiceWorkerBridge, usesServiceWorkerResponseFlowControl, } from "./serviceWorkerRuntime.js";
|
|
8
9
|
const PROXY_HTTP_STREAM_KIND = "flowersec-proxy/http1";
|
|
9
10
|
const PROXY_WEBSOCKET_STREAM_KIND = "flowersec-proxy/ws";
|
|
10
11
|
const PROXY_WIRE_VERSION = 1;
|
|
@@ -160,19 +161,6 @@ function filterHeaders(input, base, extra) {
|
|
|
160
161
|
}
|
|
161
162
|
return result;
|
|
162
163
|
}
|
|
163
|
-
function parseRuntimeRequest(raw) {
|
|
164
|
-
const headers = Array.isArray(raw.headers) ? raw.headers.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.name === "string" && typeof entry.value === "string") : [];
|
|
165
|
-
const body = raw.body instanceof ArrayBuffer ? raw.body : undefined;
|
|
166
|
-
return {
|
|
167
|
-
id: typeof raw.id === "string" ? raw.id : "",
|
|
168
|
-
method: typeof raw.method === "string" ? raw.method : "GET",
|
|
169
|
-
path: typeof raw.path === "string" ? raw.path : "",
|
|
170
|
-
headers,
|
|
171
|
-
...(typeof raw.external_origin === "string" ? { externalOrigin: raw.external_origin } : {}),
|
|
172
|
-
...(raw.response_flow_control === "chunk_credit_v2" ? { responseFlowControl: "chunk_credit_v2" } : {}),
|
|
173
|
-
...(body === undefined ? {} : { body }),
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
164
|
class StreamAdmission {
|
|
177
165
|
concurrent;
|
|
178
166
|
queued;
|
|
@@ -317,22 +305,15 @@ export function createProxyRuntime(options) {
|
|
|
317
305
|
...(runtimeRegistrationToken === undefined ? {} : { runtimeRegistrationToken }),
|
|
318
306
|
}).catch(() => undefined);
|
|
319
307
|
const serviceWorker = globalThis.navigator?.serviceWorker;
|
|
320
|
-
const onMessage = (event) => {
|
|
321
|
-
if (event.data === null || typeof event.data !== "object" || event.data.type !== "flowersec-proxy:fetch")
|
|
322
|
-
return;
|
|
323
|
-
const port = event.ports?.[0];
|
|
324
|
-
if (port === undefined)
|
|
325
|
-
return;
|
|
326
|
-
dispatchFetch(parseRuntimeRequest(event.data.req), port);
|
|
327
|
-
};
|
|
328
|
-
serviceWorker?.addEventListener("message", onMessage);
|
|
329
308
|
serviceWorker?.addEventListener("controllerchange", register);
|
|
330
309
|
register();
|
|
310
|
+
let serviceWorkerBridge;
|
|
331
311
|
function dispatchFetch(request, port) {
|
|
332
312
|
const controller = new AbortController();
|
|
333
313
|
let stream;
|
|
334
314
|
let release;
|
|
335
|
-
|
|
315
|
+
const flowControlled = usesServiceWorkerResponseFlowControl(request);
|
|
316
|
+
let credit = !flowControlled;
|
|
336
317
|
let creditWake;
|
|
337
318
|
port.onmessage = (event) => {
|
|
338
319
|
if (event.data?.type === "flowersec-proxy:abort") {
|
|
@@ -351,7 +332,7 @@ export function createProxyRuntime(options) {
|
|
|
351
332
|
await new Promise((resolve) => { creditWake = resolve; });
|
|
352
333
|
creditWake = undefined;
|
|
353
334
|
}
|
|
354
|
-
credit =
|
|
335
|
+
credit = !flowControlled;
|
|
355
336
|
};
|
|
356
337
|
void (async () => {
|
|
357
338
|
try {
|
|
@@ -439,7 +420,7 @@ export function createProxyRuntime(options) {
|
|
|
439
420
|
throw error instanceof SessionError ? error : new SessionError("operation_failed");
|
|
440
421
|
}
|
|
441
422
|
}
|
|
442
|
-
|
|
423
|
+
const runtime = Object.freeze({
|
|
443
424
|
limits: Object.freeze({
|
|
444
425
|
maxJsonFrameBytes,
|
|
445
426
|
maxChunkBytes,
|
|
@@ -457,10 +438,14 @@ export function createProxyRuntime(options) {
|
|
|
457
438
|
return;
|
|
458
439
|
disposed = true;
|
|
459
440
|
admission.close();
|
|
460
|
-
serviceWorker?.removeEventListener("message", onMessage);
|
|
461
441
|
serviceWorker?.removeEventListener("controllerchange", register);
|
|
442
|
+
serviceWorkerBridge?.dispose();
|
|
462
443
|
},
|
|
463
444
|
});
|
|
445
|
+
if (serviceWorker !== undefined) {
|
|
446
|
+
serviceWorkerBridge = registerProxyRuntimeServiceWorkerBridge(runtime, serviceWorker);
|
|
447
|
+
}
|
|
448
|
+
return runtime;
|
|
464
449
|
}
|
|
465
450
|
export async function ensureServiceWorkerRuntimeRegistered(options = {}) {
|
|
466
451
|
const controller = globalThis.navigator?.serviceWorker?.controller;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProxyFetchRequest, ProxyRuntime } from "./types.js";
|
|
2
|
+
type ProxyRuntimeServiceWorkerBridgeHandle = Readonly<{
|
|
3
|
+
dispose(): void;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function usesServiceWorkerResponseFlowControl(request: ProxyFetchRequest): boolean;
|
|
6
|
+
export declare function registerProxyRuntimeServiceWorkerBridge(runtime: ProxyRuntime, serviceWorker: ServiceWorkerContainer): ProxyRuntimeServiceWorkerBridgeHandle;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const responseFlowControl = new WeakSet();
|
|
2
|
+
function record(value) {
|
|
3
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
4
|
+
? value
|
|
5
|
+
: undefined;
|
|
6
|
+
}
|
|
7
|
+
function parseRuntimeRequest(value) {
|
|
8
|
+
const raw = record(value);
|
|
9
|
+
if (raw === undefined || typeof raw.id !== "string" || typeof raw.method !== "string" ||
|
|
10
|
+
typeof raw.path !== "string" || !Array.isArray(raw.headers)) {
|
|
11
|
+
throw new TypeError("invalid proxy service worker request");
|
|
12
|
+
}
|
|
13
|
+
const headers = raw.headers.map((value) => {
|
|
14
|
+
const header = record(value);
|
|
15
|
+
if (header === undefined || typeof header.name !== "string" || typeof header.value !== "string") {
|
|
16
|
+
throw new TypeError("invalid proxy service worker request headers");
|
|
17
|
+
}
|
|
18
|
+
return Object.freeze({ name: header.name, value: header.value });
|
|
19
|
+
});
|
|
20
|
+
if (raw.body !== undefined && !(raw.body instanceof ArrayBuffer)) {
|
|
21
|
+
throw new TypeError("invalid proxy service worker request body");
|
|
22
|
+
}
|
|
23
|
+
if (raw.external_origin !== undefined && typeof raw.external_origin !== "string") {
|
|
24
|
+
throw new TypeError("invalid proxy service worker request origin");
|
|
25
|
+
}
|
|
26
|
+
if (raw.response_flow_control !== undefined && raw.response_flow_control !== "chunk_credit_v2") {
|
|
27
|
+
throw new TypeError("invalid proxy service worker response flow control");
|
|
28
|
+
}
|
|
29
|
+
const request = Object.freeze({
|
|
30
|
+
id: raw.id,
|
|
31
|
+
method: raw.method,
|
|
32
|
+
path: raw.path,
|
|
33
|
+
headers: Object.freeze(headers),
|
|
34
|
+
...(typeof raw.external_origin === "string" ? { externalOrigin: raw.external_origin } : {}),
|
|
35
|
+
...(raw.body instanceof ArrayBuffer ? { body: raw.body } : {}),
|
|
36
|
+
});
|
|
37
|
+
if (raw.response_flow_control === "chunk_credit_v2")
|
|
38
|
+
responseFlowControl.add(request);
|
|
39
|
+
return request;
|
|
40
|
+
}
|
|
41
|
+
export function usesServiceWorkerResponseFlowControl(request) {
|
|
42
|
+
return responseFlowControl.has(request);
|
|
43
|
+
}
|
|
44
|
+
export function registerProxyRuntimeServiceWorkerBridge(runtime, serviceWorker) {
|
|
45
|
+
let disposed = false;
|
|
46
|
+
const onMessage = (event) => {
|
|
47
|
+
const message = record(event.data);
|
|
48
|
+
if (message?.type !== "flowersec-proxy:fetch")
|
|
49
|
+
return;
|
|
50
|
+
const port = event.ports?.[0];
|
|
51
|
+
if (port === undefined)
|
|
52
|
+
return;
|
|
53
|
+
try {
|
|
54
|
+
runtime.dispatchFetch(parseRuntimeRequest(message.req), port);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
port.postMessage({
|
|
58
|
+
type: "flowersec-proxy:response_error",
|
|
59
|
+
status: 400,
|
|
60
|
+
code: "invalid_request",
|
|
61
|
+
message: "invalid proxy request",
|
|
62
|
+
});
|
|
63
|
+
port.close();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
serviceWorker.addEventListener("message", onMessage);
|
|
67
|
+
return Object.freeze({
|
|
68
|
+
dispose: () => {
|
|
69
|
+
if (disposed)
|
|
70
|
+
return;
|
|
71
|
+
disposed = true;
|
|
72
|
+
serviceWorker.removeEventListener("message", onMessage);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
package/dist/proxy/types.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export type ProxyAppWindowHandle = Readonly<{
|
|
|
38
38
|
dispose(): void;
|
|
39
39
|
}>;
|
|
40
40
|
export declare function registerProxyAppWindow(options: RegisterProxyAppWindowOptions): ProxyAppWindowHandle;
|
|
41
|
+
export declare function registerProxyAppWindowWithServiceWorkerRuntime(options: RegisterProxyAppWindowOptions): ProxyAppWindowHandle;
|
|
41
42
|
export type RegisterProxyControllerWindowOptions = Readonly<{
|
|
42
43
|
runtime: ProxyRuntime;
|
|
43
44
|
allowedOrigins: readonly string[];
|
|
@@ -56,6 +57,7 @@ export type ProxyAppServiceWorkerControlOptions = Readonly<{
|
|
|
56
57
|
repair?: ServiceWorkerControllerGuardRepairOptions;
|
|
57
58
|
monitor?: ServiceWorkerControllerGuardMonitorOptions;
|
|
58
59
|
conflicts?: ServiceWorkerControllerGuardConflictPolicy;
|
|
60
|
+
runtimeRegistrationToken?: string;
|
|
59
61
|
}>;
|
|
60
62
|
export type RegisterProxyAppWindowWithServiceWorkerControlOptions = RegisterProxyAppWindowOptions & Readonly<{
|
|
61
63
|
serviceWorker: ProxyAppServiceWorkerControlOptions;
|
|
@@ -2,6 +2,8 @@ import { SDK_DEFAULTS } from "../defaults.js";
|
|
|
2
2
|
import { SessionError } from "../public/contract.js";
|
|
3
3
|
import { createServiceWorkerControllerGuard, } from "./controllerGuard.js";
|
|
4
4
|
import { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
5
|
+
import { ensureServiceWorkerRuntimeRegistered } from "./runtime.js";
|
|
6
|
+
import { registerProxyRuntimeServiceWorkerBridge } from "./serviceWorkerRuntime.js";
|
|
5
7
|
const FETCH_MESSAGE = "flowersec-proxy:window_fetch_v2";
|
|
6
8
|
const WEBSOCKET_OPEN_MESSAGE = "flowersec-proxy:window_ws_open_v2";
|
|
7
9
|
const WEBSOCKET_ACK_MESSAGE = "flowersec-proxy:window_ws_open_ack_v2";
|
|
@@ -292,6 +294,31 @@ export function registerProxyAppWindow(options) {
|
|
|
292
294
|
dispose: () => { disposed = true; },
|
|
293
295
|
});
|
|
294
296
|
}
|
|
297
|
+
export function registerProxyAppWindowWithServiceWorkerRuntime(options) {
|
|
298
|
+
const target = options.targetWindow ?? globalThis.window;
|
|
299
|
+
const serviceWorker = target.navigator?.serviceWorker;
|
|
300
|
+
if (serviceWorker === undefined)
|
|
301
|
+
throw new Error("proxy service worker is unavailable");
|
|
302
|
+
const app = registerProxyAppWindow(options);
|
|
303
|
+
try {
|
|
304
|
+
const serviceWorkerBridge = registerProxyRuntimeServiceWorkerBridge(app.runtime, serviceWorker);
|
|
305
|
+
let disposed = false;
|
|
306
|
+
return Object.freeze({
|
|
307
|
+
runtime: app.runtime,
|
|
308
|
+
dispose: () => {
|
|
309
|
+
if (disposed)
|
|
310
|
+
return;
|
|
311
|
+
disposed = true;
|
|
312
|
+
serviceWorkerBridge.dispose();
|
|
313
|
+
app.dispose();
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
app.dispose();
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
295
322
|
async function bridgeStreams(runtimeStream, port, signal) {
|
|
296
323
|
const bridge = new MessagePortByteStream(port);
|
|
297
324
|
const controller = new AbortController();
|
|
@@ -436,10 +463,30 @@ export async function registerProxyAppWindowWithServiceWorkerControl(options) {
|
|
|
436
463
|
...(options.serviceWorker.monitor === undefined ? {} : { monitor: options.serviceWorker.monitor }),
|
|
437
464
|
...(options.serviceWorker.conflicts === undefined ? {} : { conflicts: options.serviceWorker.conflicts }),
|
|
438
465
|
});
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
466
|
+
let app;
|
|
467
|
+
try {
|
|
468
|
+
await guard.ensure();
|
|
469
|
+
app = registerProxyAppWindowWithServiceWorkerRuntime(options);
|
|
470
|
+
await ensureServiceWorkerRuntimeRegistered({
|
|
471
|
+
...(options.serviceWorker.runtimeRegistrationToken === undefined
|
|
472
|
+
? {}
|
|
473
|
+
: { runtimeRegistrationToken: options.serviceWorker.runtimeRegistrationToken }),
|
|
474
|
+
});
|
|
475
|
+
let disposed = false;
|
|
476
|
+
return Object.freeze({
|
|
477
|
+
runtime: app.runtime,
|
|
478
|
+
dispose: () => {
|
|
479
|
+
if (disposed)
|
|
480
|
+
return;
|
|
481
|
+
disposed = true;
|
|
482
|
+
app?.dispose();
|
|
483
|
+
guard.dispose();
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
app?.dispose();
|
|
489
|
+
guard.dispose();
|
|
490
|
+
throw error;
|
|
491
|
+
}
|
|
445
492
|
}
|
|
@@ -26,9 +26,7 @@ export declare class UnreliableMessageError extends Error {
|
|
|
26
26
|
export type StreamOpenOptions = OperationOptions & Readonly<{
|
|
27
27
|
metadata?: StreamMetadata;
|
|
28
28
|
}>;
|
|
29
|
-
|
|
30
|
-
export type LegacyUnreliableSessionErrorCode = "unreliable_unavailable" | "unreliable_too_large" | "unreliable_dropped";
|
|
31
|
-
export type SessionErrorCode = "canceled" | "timeout" | "closed" | "going_away" | "resource_exhausted" | "stream_rejected" | "stream_reset" | "rekey_failed" | "liveness_failed" | LegacyUnreliableSessionErrorCode | "operation_failed";
|
|
29
|
+
export type SessionErrorCode = "canceled" | "timeout" | "closed" | "going_away" | "resource_exhausted" | "stream_rejected" | "stream_reset" | "rekey_failed" | "liveness_failed" | "operation_failed";
|
|
32
30
|
/** A closed, carrier-neutral session failure with no internal cause or peer detail. */
|
|
33
31
|
export declare class SessionError extends Error {
|
|
34
32
|
readonly code: SessionErrorCode;
|
|
@@ -18,6 +18,3 @@ export declare class StreamHandlers {
|
|
|
18
18
|
handleStream(kind: string, handler: StreamHandler): void;
|
|
19
19
|
serve(session: Session, options?: OperationOptions): Promise<void>;
|
|
20
20
|
}
|
|
21
|
-
/** Explicit-compatibility application-stream handlers. */
|
|
22
|
-
export declare class LegacyStreamHandlers extends StreamHandlers {
|
|
23
|
-
}
|