@floegence/flowersec-core 0.26.0 → 2.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 +91 -22
- package/THIRD_PARTY_NOTICES.md +141 -0
- package/dist/browser/connectSession.d.ts +13 -0
- package/dist/browser/connectSession.js +40 -0
- package/dist/browser/index.d.ts +3 -10
- package/dist/browser/index.js +2 -5
- package/dist/browser/runtimeCapability.d.ts +13 -0
- package/dist/browser/runtimeCapability.js +27 -0
- package/dist/browser/sessionRuntime.d.ts +2 -0
- package/dist/browser/sessionRuntime.js +21 -0
- package/dist/browser/webTransportClient.d.ts +8 -0
- package/dist/browser/webTransportClient.js +55 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +126 -0
- package/dist/cliSpendMarker.d.ts +1 -0
- package/dist/cliSpendMarker.js +22 -0
- package/dist/connectionController.d.ts +54 -0
- package/dist/connectionController.js +438 -0
- package/dist/connector/adapters/webSocketCandidate.d.ts +7 -0
- package/dist/connector/adapters/webSocketCandidate.js +116 -0
- package/dist/connector/adapters/webTransportCandidate.d.ts +5 -0
- package/dist/connector/adapters/webTransportCandidate.js +73 -0
- package/dist/connector/admissionCommit.d.ts +31 -0
- package/dist/connector/admissionCommit.js +239 -0
- package/dist/connector/sessionAcceptor.d.ts +16 -0
- package/dist/connector/sessionAcceptor.js +114 -0
- package/dist/connector/sessionConfig.d.ts +3 -0
- package/dist/connector/sessionConfig.js +30 -0
- package/dist/connector/sessionConnector.d.ts +45 -0
- package/dist/connector/sessionConnector.js +603 -0
- package/dist/defaults.d.ts +7 -7
- package/dist/defaults.js +7 -7
- package/dist/facade.d.ts +12 -30
- package/dist/facade.js +6 -30
- package/dist/node/connectSession.d.ts +21 -0
- package/dist/node/connectSession.js +62 -0
- package/dist/node/index.d.ts +3 -11
- package/dist/node/index.js +2 -8
- package/dist/node/runtimeCapability.d.ts +7 -0
- package/dist/node/runtimeCapability.js +10 -0
- package/dist/node/sessionRuntime.d.ts +2 -0
- package/dist/node/sessionRuntime.js +13 -0
- package/dist/node/webTransportClient.d.ts +9 -0
- package/dist/node/webTransportClient.js +56 -0
- package/dist/node/webTransportServer.d.ts +22 -0
- package/dist/node/webTransportServer.js +100 -0
- package/dist/node/wsFactory.d.ts +3 -1
- package/dist/node/wsFactory.js +4 -3
- package/dist/proxy/controllerGuard.d.ts +4 -4
- package/dist/proxy/controllerGuard.js +83 -177
- package/dist/proxy/disableUpstreamServiceWorkerRegister.d.ts +3 -1
- package/dist/proxy/disableUpstreamServiceWorkerRegister.js +19 -17
- package/dist/proxy/index.d.ts +16 -15
- package/dist/proxy/index.js +8 -14
- package/dist/proxy/integration.d.ts +23 -71
- package/dist/proxy/integration.js +37 -340
- package/dist/proxy/registerServiceWorker.d.ts +1 -10
- package/dist/proxy/registerServiceWorker.js +43 -105
- package/dist/proxy/runtime.d.ts +3 -63
- package/dist/proxy/runtime.js +349 -462
- package/dist/proxy/scope.d.ts +6 -0
- package/dist/proxy/scope.js +131 -0
- package/dist/proxy/serviceWorker.d.ts +5 -16
- package/dist/proxy/serviceWorker.js +230 -617
- package/dist/proxy/stream.d.ts +9 -0
- package/dist/proxy/stream.js +40 -0
- package/dist/proxy/types.d.ts +78 -30
- package/dist/proxy/windowBridge.d.ts +61 -0
- package/dist/proxy/windowBridge.js +344 -0
- package/dist/proxy/wsPatch.d.ts +4 -14
- package/dist/proxy/wsPatch.js +173 -268
- package/dist/public/artifact.d.ts +11 -0
- package/dist/public/artifact.js +44 -0
- package/dist/public/artifactLease.d.ts +10 -0
- package/dist/public/artifactLease.js +48 -0
- package/dist/public/connectError.d.ts +6 -0
- package/dist/public/connectError.js +9 -0
- package/dist/public/contract.d.ts +83 -0
- package/dist/public/contract.js +17 -0
- package/dist/public/streamMetadata.d.ts +10 -0
- package/dist/public/streamMetadata.js +40 -0
- package/dist/rpc/caller.d.ts +1 -1
- package/dist/rpc/client.d.ts +1 -4
- package/dist/rpc/client.js +0 -21
- package/dist/rpc/rpcProxy.d.ts +1 -1
- package/dist/rpc/server.d.ts +1 -1
- package/dist/rpc/validate.d.ts +1 -1
- package/dist/rpc/wire.d.ts +15 -0
- package/dist/runtime/errors.d.ts +6 -0
- package/dist/runtime/errors.js +10 -0
- package/dist/transport/webSocketAdapter.d.ts +24 -0
- package/dist/transport/webSocketAdapter.js +234 -0
- package/dist/transport/webTransportAdapter.d.ts +27 -0
- package/dist/transport/webTransportAdapter.js +519 -0
- package/dist/utils/errors.d.ts +2 -20
- package/dist/utils/errors.js +73 -20
- package/dist/v2/admissionError.d.ts +4 -0
- package/dist/v2/admissionError.js +8 -0
- package/dist/v2/artifact.d.ts +128 -0
- package/dist/v2/artifact.js +1126 -0
- package/dist/v2/artifactLease.d.ts +1 -0
- package/dist/v2/artifactLease.js +7 -0
- package/dist/v2/capability.d.ts +29 -0
- package/dist/v2/capability.js +190 -0
- package/dist/v2/carrier.d.ts +79 -0
- package/dist/v2/carrier.js +405 -0
- package/dist/v2/contract.d.ts +37 -0
- package/dist/v2/contract.js +1 -0
- package/dist/v2/handshake.d.ts +80 -0
- package/dist/v2/handshake.js +470 -0
- package/dist/v2/opaqueArtifact.d.ts +1 -0
- package/dist/v2/opaqueArtifact.js +2 -0
- package/dist/v2/protocol.d.ts +99 -0
- package/dist/v2/protocol.js +739 -0
- package/dist/v2/publicSession.d.ts +1 -0
- package/dist/v2/publicSession.js +179 -0
- package/dist/v2/retryDisposition.d.ts +16 -0
- package/dist/v2/retryDisposition.js +30 -0
- package/dist/v2/session.d.ts +277 -0
- package/dist/v2/session.js +1879 -0
- package/dist/v2/streamLifetimeLedger.d.ts +31 -0
- package/dist/v2/streamLifetimeLedger.js +131 -0
- package/dist/v2/streamMetadata.d.ts +1 -0
- package/dist/v2/streamMetadata.js +7 -0
- package/dist/v2/unreliableMessage.d.ts +43 -0
- package/dist/v2/unreliableMessage.js +252 -0
- package/dist/vendor/tr46.d.ts +10 -0
- package/dist/vendor/tr46.js +501 -0
- package/dist/ws-client/binaryTransport.d.ts +0 -3
- package/dist/ws-client/binaryTransport.js +15 -39
- package/dist/yamux/errors.d.ts +0 -4
- package/dist/yamux/errors.js +0 -9
- package/dist/yamux/session.d.ts +0 -5
- package/dist/yamux/session.js +4 -70
- package/dist/yamux/stream.d.ts +1 -0
- package/dist/yamux/stream.js +4 -0
- package/package.json +29 -83
- package/sbom/cyclonedx.json +2764 -0
- package/sbom/spdx.json +1947 -0
- package/YAMUX_ALIGNMENT.md +0 -127
- package/dist/_examples/flowersec/demo/v1.facade.gen.d.ts +0 -12
- package/dist/_examples/flowersec/demo/v1.facade.gen.js +0 -15
- package/dist/_examples/flowersec/demo/v1.gen.d.ts +0 -16
- package/dist/_examples/flowersec/demo/v1.gen.js +0 -86
- package/dist/_examples/flowersec/demo/v1.rpc.gen.d.ts +0 -11
- package/dist/_examples/flowersec/demo/v1.rpc.gen.js +0 -22
- package/dist/browser/connect.d.ts +0 -12
- package/dist/browser/connect.js +0 -31
- package/dist/browser/controlplane.d.ts +0 -15
- package/dist/browser/controlplane.js +0 -64
- package/dist/browser/reconnectConfig.d.ts +0 -15
- package/dist/browser/reconnectConfig.js +0 -20
- package/dist/client-connect/common.d.ts +0 -26
- package/dist/client-connect/common.js +0 -167
- package/dist/client-connect/connectCore.d.ts +0 -61
- package/dist/client-connect/connectCore.js +0 -572
- package/dist/client-connect/contract.d.ts +0 -8
- package/dist/client-connect/contract.js +0 -51
- package/dist/client-connect/termination.d.ts +0 -6
- package/dist/client-connect/termination.js +0 -7
- package/dist/client-connect/transportSecurity.d.ts +0 -27
- package/dist/client-connect/transportSecurity.js +0 -199
- package/dist/client-connect/tunnelAttachCloseReason.d.ts +0 -3
- package/dist/client-connect/tunnelAttachCloseReason.js +0 -23
- package/dist/client.d.ts +0 -23
- package/dist/connect/artifact.d.ts +0 -37
- package/dist/connect/artifact.js +0 -217
- package/dist/connect/internalNormalize.d.ts +0 -22
- package/dist/connect/internalNormalize.js +0 -173
- package/dist/controlplane/channelInit.d.ts +0 -27
- package/dist/controlplane/channelInit.js +0 -116
- package/dist/controlplane/http.d.ts +0 -16
- package/dist/controlplane/http.js +0 -59
- package/dist/controlplane/index.d.ts +0 -6
- package/dist/controlplane/index.js +0 -5
- package/dist/controlplane/issuer.d.ts +0 -18
- package/dist/controlplane/issuer.js +0 -113
- package/dist/controlplane/request.d.ts +0 -51
- package/dist/controlplane/request.js +0 -273
- package/dist/controlplane/token.d.ts +0 -33
- package/dist/controlplane/token.js +0 -119
- package/dist/direct-client/connect.d.ts +0 -9
- package/dist/direct-client/connect.js +0 -90
- package/dist/direct-client/index.d.ts +0 -1
- package/dist/direct-client/index.js +0 -1
- package/dist/e2ee/constants.d.ts +0 -9
- package/dist/e2ee/constants.js +0 -18
- package/dist/e2ee/errors.d.ts +0 -5
- package/dist/e2ee/errors.js +0 -8
- package/dist/e2ee/framing.d.ts +0 -12
- package/dist/e2ee/framing.js +0 -57
- package/dist/e2ee/handshake.d.ts +0 -88
- package/dist/e2ee/handshake.js +0 -353
- package/dist/e2ee/index.d.ts +0 -7
- package/dist/e2ee/index.js +0 -7
- package/dist/e2ee/kdf.d.ts +0 -15
- package/dist/e2ee/kdf.js +0 -39
- package/dist/e2ee/record.d.ts +0 -11
- package/dist/e2ee/record.js +0 -76
- package/dist/e2ee/secureChannel.d.ts +0 -92
- package/dist/e2ee/secureChannel.js +0 -328
- package/dist/e2ee/transcript.d.ts +0 -23
- package/dist/e2ee/transcript.js +0 -31
- package/dist/endpoint/index.d.ts +0 -84
- package/dist/endpoint/index.js +0 -557
- package/dist/endpoint/node.d.ts +0 -9
- package/dist/endpoint/node.js +0 -51
- package/dist/gen/flowersec/controlplane/v1.gen.d.ts +0 -36
- package/dist/gen/flowersec/controlplane/v1.gen.js +0 -135
- package/dist/gen/flowersec/direct/v1.gen.d.ts +0 -21
- package/dist/gen/flowersec/direct/v1.gen.js +0 -101
- package/dist/gen/flowersec/e2ee/v1.gen.d.ts +0 -68
- package/dist/gen/flowersec/e2ee/v1.gen.js +0 -194
- package/dist/gen/flowersec/rpc/v1.gen.d.ts +0 -30
- package/dist/gen/flowersec/rpc/v1.gen.js +0 -107
- package/dist/gen/flowersec/tunnel/v1.gen.d.ts +0 -23
- package/dist/gen/flowersec/tunnel/v1.gen.js +0 -104
- package/dist/index.d.ts +0 -22
- package/dist/index.js +0 -22
- package/dist/node/connect.d.ts +0 -12
- package/dist/node/connect.js +0 -29
- package/dist/node/reconnectConfig.d.ts +0 -16
- package/dist/node/reconnectConfig.js +0 -20
- package/dist/observability/index.d.ts +0 -1
- package/dist/observability/index.js +0 -1
- package/dist/observability/observer.d.ts +0 -52
- package/dist/observability/observer.js +0 -314
- package/dist/proxy/appWindow.d.ts +0 -37
- package/dist/proxy/appWindow.js +0 -273
- package/dist/proxy/bootstrap.d.ts +0 -35
- package/dist/proxy/bootstrap.js +0 -119
- package/dist/proxy/constants.d.ts +0 -7
- package/dist/proxy/constants.js +0 -8
- package/dist/proxy/controllerWindow.d.ts +0 -12
- package/dist/proxy/controllerWindow.js +0 -384
- package/dist/proxy/cookieJar.d.ts +0 -7
- package/dist/proxy/cookieJar.js +0 -136
- package/dist/proxy/headerPolicy.d.ts +0 -14
- package/dist/proxy/headerPolicy.js +0 -134
- package/dist/proxy/portStream.d.ts +0 -5
- package/dist/proxy/portStream.js +0 -256
- package/dist/proxy/preset.d.ts +0 -29
- package/dist/proxy/preset.js +0 -111
- package/dist/proxy/runtimeScope.d.ts +0 -57
- package/dist/proxy/runtimeScope.js +0 -218
- package/dist/proxy/server.d.ts +0 -28
- package/dist/proxy/server.js +0 -833
- package/dist/proxy/windowBridgeProtocol.d.ts +0 -65
- package/dist/proxy/windowBridgeProtocol.js +0 -11
- package/dist/reconnect/artifactControlplane.d.ts +0 -16
- package/dist/reconnect/artifactControlplane.js +0 -35
- package/dist/reconnect/index.d.ts +0 -36
- package/dist/reconnect/index.js +0 -388
- package/dist/rpc-proxy/index.d.ts +0 -1
- package/dist/rpc-proxy/index.js +0 -1
- package/dist/rpc-proxy/rpcProxy.d.ts +0 -1
- package/dist/rpc-proxy/rpcProxy.js +0 -1
- package/dist/streamhello/index.d.ts +0 -1
- package/dist/streamhello/index.js +0 -1
- package/dist/streamhello/streamHello.d.ts +0 -3
- package/dist/streamhello/streamHello.js +0 -13
- package/dist/streamio/index.d.ts +0 -32
- package/dist/streamio/index.js +0 -87
- package/dist/tunnel-client/connect.d.ts +0 -9
- package/dist/tunnel-client/connect.js +0 -157
- package/dist/tunnel-client/index.d.ts +0 -1
- package/dist/tunnel-client/index.js +0 -1
- package/dist/ws/index.d.ts +0 -1
- package/dist/ws/index.js +0 -1
- /package/dist/{client.js → rpc/wire.js} +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ByteStream, OperationOptions } from "../public/contract.js";
|
|
2
|
+
export declare class ProxyByteReader {
|
|
3
|
+
private readonly stream;
|
|
4
|
+
private readonly options;
|
|
5
|
+
private buffered;
|
|
6
|
+
constructor(stream: ByteStream, options?: OperationOptions);
|
|
7
|
+
readExactly(length: number): Promise<Uint8Array>;
|
|
8
|
+
}
|
|
9
|
+
export declare function writeAll(stream: ByteStream, input: Uint8Array, options?: OperationOptions): Promise<void>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class ProxyByteReader {
|
|
2
|
+
stream;
|
|
3
|
+
options;
|
|
4
|
+
buffered = new Uint8Array();
|
|
5
|
+
constructor(stream, options = {}) {
|
|
6
|
+
this.stream = stream;
|
|
7
|
+
this.options = options;
|
|
8
|
+
}
|
|
9
|
+
async readExactly(length) {
|
|
10
|
+
if (!Number.isSafeInteger(length) || length < 0)
|
|
11
|
+
throw new TypeError("invalid proxy read length");
|
|
12
|
+
const output = new Uint8Array(length);
|
|
13
|
+
let offset = 0;
|
|
14
|
+
while (offset < length) {
|
|
15
|
+
if (this.buffered.length === 0) {
|
|
16
|
+
const next = await this.stream.read(this.options);
|
|
17
|
+
if (next === null)
|
|
18
|
+
throw new Error("proxy stream ended unexpectedly");
|
|
19
|
+
if (next.length === 0)
|
|
20
|
+
continue;
|
|
21
|
+
this.buffered = next;
|
|
22
|
+
}
|
|
23
|
+
const take = Math.min(length - offset, this.buffered.length);
|
|
24
|
+
output.set(this.buffered.subarray(0, take), offset);
|
|
25
|
+
offset += take;
|
|
26
|
+
this.buffered = this.buffered.subarray(take);
|
|
27
|
+
}
|
|
28
|
+
return output;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function writeAll(stream, input, options = {}) {
|
|
32
|
+
let offset = 0;
|
|
33
|
+
while (offset < input.length) {
|
|
34
|
+
const written = await stream.write(input.subarray(offset), options);
|
|
35
|
+
if (!Number.isSafeInteger(written) || written <= 0 || written > input.length - offset) {
|
|
36
|
+
throw new Error("proxy stream write made no progress");
|
|
37
|
+
}
|
|
38
|
+
offset += written;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/dist/proxy/types.d.ts
CHANGED
|
@@ -1,38 +1,86 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ByteStream, Session } from "../public/contract.js";
|
|
2
|
+
export type ProxyHeader = Readonly<{
|
|
2
3
|
name: string;
|
|
3
4
|
value: string;
|
|
4
5
|
}>;
|
|
5
|
-
export type
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
export type ProxyRuntimeLimits = Readonly<{
|
|
7
|
+
maxJsonFrameBytes: number;
|
|
8
|
+
maxChunkBytes: number;
|
|
9
|
+
maxBodyBytes: number;
|
|
10
|
+
maxWsFrameBytes: number;
|
|
11
|
+
maxWsBufferedAmountBytes: number;
|
|
12
|
+
maxConcurrentHttpStreams: number;
|
|
13
|
+
maxQueuedHttpRequests: number;
|
|
14
|
+
maxQueuedHttpBodyBytes: number;
|
|
8
15
|
}>;
|
|
9
|
-
export type
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
export type ProxyRuntimePathPolicy = Readonly<{
|
|
17
|
+
allowedPathPrefixes?: readonly string[];
|
|
18
|
+
deniedPathPrefixes?: readonly string[];
|
|
19
|
+
allowedWebSocketPathPrefixes?: readonly string[];
|
|
20
|
+
deniedWebSocketPathPrefixes?: readonly string[];
|
|
21
|
+
}>;
|
|
22
|
+
export type ProxyRuntimeOptions = Readonly<{
|
|
23
|
+
session: Session;
|
|
24
|
+
maxJsonFrameBytes?: number;
|
|
25
|
+
maxChunkBytes?: number;
|
|
26
|
+
maxBodyBytes?: number;
|
|
27
|
+
maxWsFrameBytes?: number;
|
|
28
|
+
maxWsBufferedAmountBytes?: number;
|
|
29
|
+
maxConcurrentHttpStreams?: number;
|
|
30
|
+
maxQueuedHttpRequests?: number;
|
|
31
|
+
maxQueuedHttpBodyBytes?: number;
|
|
32
|
+
timeoutMs?: number;
|
|
33
|
+
extraRequestHeaders?: readonly string[];
|
|
34
|
+
extraResponseHeaders?: readonly string[];
|
|
35
|
+
extraWebSocketHeaders?: readonly string[];
|
|
36
|
+
pathPolicy?: ProxyRuntimePathPolicy;
|
|
37
|
+
externalOrigin?: string;
|
|
38
|
+
runtimeRegistrationToken?: string;
|
|
39
|
+
}>;
|
|
40
|
+
export type ProxyFetchRequest = Readonly<{
|
|
41
|
+
id: string;
|
|
12
42
|
method: string;
|
|
13
43
|
path: string;
|
|
14
|
-
headers:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
headers: readonly ProxyHeader[];
|
|
45
|
+
externalOrigin?: string;
|
|
46
|
+
responseFlowControl?: "chunk_credit_v2";
|
|
47
|
+
body?: ArrayBuffer;
|
|
48
|
+
}>;
|
|
49
|
+
export type ProxyRuntime = Readonly<{
|
|
50
|
+
limits: ProxyRuntimeLimits;
|
|
51
|
+
dispatchFetch(request: ProxyFetchRequest, port: MessagePort): void;
|
|
52
|
+
openWebSocketStream(path: string, options?: Readonly<{
|
|
53
|
+
protocols?: readonly string[];
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
}>): Promise<Readonly<{
|
|
56
|
+
stream: ByteStream;
|
|
57
|
+
protocol: string;
|
|
58
|
+
}>>;
|
|
59
|
+
dispose(): void;
|
|
60
|
+
}>;
|
|
61
|
+
export type ProxyRuntimeScopeLimits = Readonly<{
|
|
62
|
+
timeoutMs?: number;
|
|
63
|
+
maxJsonFrameBytes?: number;
|
|
64
|
+
maxChunkBytes?: number;
|
|
65
|
+
maxBodyBytes?: number;
|
|
66
|
+
maxWsFrameBytes?: number;
|
|
67
|
+
}>;
|
|
68
|
+
type ProxyRuntimeScopeBase = Readonly<{
|
|
69
|
+
appBasePath?: string;
|
|
70
|
+
limits?: ProxyRuntimeScopeLimits;
|
|
71
|
+
}>;
|
|
72
|
+
export type ProxyRuntimeServiceWorkerScope = ProxyRuntimeScopeBase & Readonly<{
|
|
73
|
+
mode: "service_worker";
|
|
74
|
+
serviceWorker: Readonly<{
|
|
75
|
+
scriptUrl: string;
|
|
76
|
+
scope: string;
|
|
77
|
+
}>;
|
|
31
78
|
}>;
|
|
32
|
-
export type
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
error?: ProxyError;
|
|
79
|
+
export type ProxyRuntimeControllerBridgeScope = ProxyRuntimeScopeBase & Readonly<{
|
|
80
|
+
mode: "controller_bridge";
|
|
81
|
+
controllerBridge: Readonly<{
|
|
82
|
+
allowedOrigins: readonly string[];
|
|
83
|
+
}>;
|
|
38
84
|
}>;
|
|
85
|
+
export type ProxyRuntimeScope = ProxyRuntimeServiceWorkerScope | ProxyRuntimeControllerBridgeScope;
|
|
86
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { SessionError, type ByteStream, type OperationOptions } from "../public/contract.js";
|
|
2
|
+
import { type ServiceWorkerControllerGuardConflictPolicy, type ServiceWorkerControllerGuardMonitorOptions, type ServiceWorkerControllerGuardRepairOptions } from "./controllerGuard.js";
|
|
3
|
+
import type { ProxyRuntime } from "./types.js";
|
|
4
|
+
export declare class MessagePortByteStream implements ByteStream {
|
|
5
|
+
private readonly port;
|
|
6
|
+
readonly kind = "flowersec.proxy.window.v2";
|
|
7
|
+
terminalError: SessionError | undefined;
|
|
8
|
+
private readonly reads;
|
|
9
|
+
private readonly readWaiters;
|
|
10
|
+
private readonly writeWaiters;
|
|
11
|
+
private nextWrite;
|
|
12
|
+
private buffered;
|
|
13
|
+
private readBuffered;
|
|
14
|
+
private ended;
|
|
15
|
+
private closed;
|
|
16
|
+
constructor(port: MessagePort);
|
|
17
|
+
read(options?: OperationOptions): Promise<Uint8Array | null>;
|
|
18
|
+
write(data: Uint8Array, options?: OperationOptions): Promise<number>;
|
|
19
|
+
closeWrite(): Promise<void>;
|
|
20
|
+
reset(): Promise<void>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
private handle;
|
|
23
|
+
private finish;
|
|
24
|
+
private fail;
|
|
25
|
+
}
|
|
26
|
+
export type RegisterProxyAppWindowOptions = Readonly<{
|
|
27
|
+
controllerOrigin: string;
|
|
28
|
+
controllerWindow?: Window | null;
|
|
29
|
+
targetWindow?: Window;
|
|
30
|
+
maxWsFrameBytes?: number;
|
|
31
|
+
maxWsBufferedAmountBytes?: number;
|
|
32
|
+
capabilityNonce?: string;
|
|
33
|
+
}>;
|
|
34
|
+
export type ProxyAppWindowHandle = Readonly<{
|
|
35
|
+
runtime: ProxyRuntime;
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}>;
|
|
38
|
+
export declare function registerProxyAppWindow(options: RegisterProxyAppWindowOptions): ProxyAppWindowHandle;
|
|
39
|
+
export type RegisterProxyControllerWindowOptions = Readonly<{
|
|
40
|
+
runtime: ProxyRuntime;
|
|
41
|
+
allowedOrigins: readonly string[];
|
|
42
|
+
targetWindow?: Window;
|
|
43
|
+
expectedSource?: Window | null;
|
|
44
|
+
capabilityNonce?: string;
|
|
45
|
+
}>;
|
|
46
|
+
export type ProxyControllerWindowHandle = Readonly<{
|
|
47
|
+
dispose(): void;
|
|
48
|
+
}>;
|
|
49
|
+
export declare function registerProxyControllerWindow(options: RegisterProxyControllerWindowOptions): ProxyControllerWindowHandle;
|
|
50
|
+
export type ProxyAppServiceWorkerControlOptions = Readonly<{
|
|
51
|
+
scriptUrl: string;
|
|
52
|
+
scope?: string;
|
|
53
|
+
expectedScriptPathSuffix: string;
|
|
54
|
+
repair?: ServiceWorkerControllerGuardRepairOptions;
|
|
55
|
+
monitor?: ServiceWorkerControllerGuardMonitorOptions;
|
|
56
|
+
conflicts?: ServiceWorkerControllerGuardConflictPolicy;
|
|
57
|
+
}>;
|
|
58
|
+
export type RegisterProxyAppWindowWithServiceWorkerControlOptions = RegisterProxyAppWindowOptions & Readonly<{
|
|
59
|
+
serviceWorker: ProxyAppServiceWorkerControlOptions;
|
|
60
|
+
}>;
|
|
61
|
+
export declare function registerProxyAppWindowWithServiceWorkerControl(options: RegisterProxyAppWindowWithServiceWorkerControlOptions): Promise<ProxyAppWindowHandle>;
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { SDK_DEFAULTS } from "../defaults.js";
|
|
2
|
+
import { SessionError } from "../public/contract.js";
|
|
3
|
+
import { createServiceWorkerControllerGuard, } from "./controllerGuard.js";
|
|
4
|
+
import { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
5
|
+
const FETCH_MESSAGE = "flowersec-proxy:window_fetch_v2";
|
|
6
|
+
const WEBSOCKET_OPEN_MESSAGE = "flowersec-proxy:window_ws_open_v2";
|
|
7
|
+
const WEBSOCKET_ACK_MESSAGE = "flowersec-proxy:window_ws_open_ack_v2";
|
|
8
|
+
const MAX_BRIDGE_CHUNK_BYTES = 1024 * 1024;
|
|
9
|
+
const MAX_BRIDGE_BUFFER_BYTES = 4 * 1024 * 1024;
|
|
10
|
+
export class MessagePortByteStream {
|
|
11
|
+
port;
|
|
12
|
+
kind = "flowersec.proxy.window.v2";
|
|
13
|
+
terminalError;
|
|
14
|
+
reads = [];
|
|
15
|
+
readWaiters = [];
|
|
16
|
+
writeWaiters = new Map();
|
|
17
|
+
nextWrite = 1;
|
|
18
|
+
buffered = 0;
|
|
19
|
+
readBuffered = 0;
|
|
20
|
+
ended = false;
|
|
21
|
+
closed = false;
|
|
22
|
+
constructor(port) {
|
|
23
|
+
this.port = port;
|
|
24
|
+
port.onmessage = (event) => this.handle(event.data);
|
|
25
|
+
port.onmessageerror = () => this.fail(new SessionError("operation_failed"));
|
|
26
|
+
port.start();
|
|
27
|
+
}
|
|
28
|
+
async read(options = {}) {
|
|
29
|
+
if (options.signal?.aborted === true)
|
|
30
|
+
throw new SessionError("canceled");
|
|
31
|
+
const queued = this.reads.shift();
|
|
32
|
+
if (queued !== undefined) {
|
|
33
|
+
this.readBuffered -= queued.byteLength;
|
|
34
|
+
return queued;
|
|
35
|
+
}
|
|
36
|
+
if (this.ended)
|
|
37
|
+
return null;
|
|
38
|
+
if (this.terminalError !== undefined)
|
|
39
|
+
throw this.terminalError;
|
|
40
|
+
return await new Promise((resolve, reject) => {
|
|
41
|
+
const waiter = { resolve, reject };
|
|
42
|
+
const onAbort = () => {
|
|
43
|
+
const index = this.readWaiters.indexOf(waiter);
|
|
44
|
+
if (index >= 0)
|
|
45
|
+
this.readWaiters.splice(index, 1);
|
|
46
|
+
reject(new SessionError("canceled"));
|
|
47
|
+
};
|
|
48
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
49
|
+
this.readWaiters.push(waiter);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async write(data, options = {}) {
|
|
53
|
+
if (this.closed || this.terminalError !== undefined)
|
|
54
|
+
throw this.terminalError ?? new SessionError("closed");
|
|
55
|
+
if (options.signal?.aborted === true)
|
|
56
|
+
throw new SessionError("canceled");
|
|
57
|
+
if (data.length === 0)
|
|
58
|
+
return 0;
|
|
59
|
+
if (data.length > MAX_BRIDGE_CHUNK_BYTES || this.buffered + data.length > MAX_BRIDGE_BUFFER_BYTES) {
|
|
60
|
+
throw new SessionError("resource_exhausted");
|
|
61
|
+
}
|
|
62
|
+
const id = this.nextWrite++;
|
|
63
|
+
const copy = data.slice();
|
|
64
|
+
this.buffered += copy.length;
|
|
65
|
+
await new Promise((resolve, reject) => {
|
|
66
|
+
this.writeWaiters.set(id, {
|
|
67
|
+
resolve: () => { this.buffered -= copy.length; resolve(); },
|
|
68
|
+
reject: (error) => { this.buffered -= copy.length; reject(error); },
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
this.port.postMessage({ type: "chunk", id, data: copy.buffer }, [copy.buffer]);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
this.writeWaiters.delete(id);
|
|
75
|
+
this.buffered -= copy.length;
|
|
76
|
+
reject(new SessionError("operation_failed"));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return data.length;
|
|
80
|
+
}
|
|
81
|
+
async closeWrite() {
|
|
82
|
+
if (this.closed)
|
|
83
|
+
return;
|
|
84
|
+
this.port.postMessage({ type: "end" });
|
|
85
|
+
}
|
|
86
|
+
async reset() {
|
|
87
|
+
if (this.closed)
|
|
88
|
+
return;
|
|
89
|
+
this.port.postMessage({ type: "reset" });
|
|
90
|
+
this.fail(new SessionError("stream_reset"));
|
|
91
|
+
}
|
|
92
|
+
async close() {
|
|
93
|
+
if (this.closed)
|
|
94
|
+
return;
|
|
95
|
+
this.port.postMessage({ type: "close" });
|
|
96
|
+
this.finish();
|
|
97
|
+
}
|
|
98
|
+
handle(value) {
|
|
99
|
+
if (value === null || typeof value !== "object" || !("type" in value))
|
|
100
|
+
return;
|
|
101
|
+
const message = value;
|
|
102
|
+
if (message.type === "chunk") {
|
|
103
|
+
if (!Number.isSafeInteger(message.id) || !(message.data instanceof ArrayBuffer) || message.data.byteLength > MAX_BRIDGE_CHUNK_BYTES) {
|
|
104
|
+
this.fail(new SessionError("operation_failed"));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const chunk = new Uint8Array(message.data);
|
|
108
|
+
const id = message.id;
|
|
109
|
+
const waiter = this.readWaiters.shift();
|
|
110
|
+
if (waiter === undefined) {
|
|
111
|
+
if (this.readBuffered + chunk.byteLength > MAX_BRIDGE_BUFFER_BYTES) {
|
|
112
|
+
this.fail(new SessionError("resource_exhausted"));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.reads.push(chunk);
|
|
116
|
+
this.readBuffered += chunk.byteLength;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
waiter.resolve(chunk);
|
|
120
|
+
}
|
|
121
|
+
this.port.postMessage({ type: "ack", id });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (message.type === "ack" && Number.isSafeInteger(message.id)) {
|
|
125
|
+
const waiter = this.writeWaiters.get(message.id);
|
|
126
|
+
if (waiter !== undefined) {
|
|
127
|
+
this.writeWaiters.delete(message.id);
|
|
128
|
+
waiter.resolve();
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (message.type === "end") {
|
|
133
|
+
this.ended = true;
|
|
134
|
+
for (const waiter of this.readWaiters.splice(0))
|
|
135
|
+
waiter.resolve(null);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (message.type === "reset")
|
|
139
|
+
this.fail(new SessionError("stream_reset"));
|
|
140
|
+
else if (message.type === "close")
|
|
141
|
+
this.finish();
|
|
142
|
+
}
|
|
143
|
+
finish() {
|
|
144
|
+
if (this.closed)
|
|
145
|
+
return;
|
|
146
|
+
this.closed = true;
|
|
147
|
+
this.ended = true;
|
|
148
|
+
this.reads.length = 0;
|
|
149
|
+
this.readBuffered = 0;
|
|
150
|
+
for (const waiter of this.readWaiters.splice(0))
|
|
151
|
+
waiter.resolve(null);
|
|
152
|
+
for (const waiter of this.writeWaiters.values())
|
|
153
|
+
waiter.reject(new SessionError("closed"));
|
|
154
|
+
this.writeWaiters.clear();
|
|
155
|
+
this.port.close();
|
|
156
|
+
}
|
|
157
|
+
fail(error) {
|
|
158
|
+
if (this.terminalError !== undefined)
|
|
159
|
+
return;
|
|
160
|
+
this.terminalError = error;
|
|
161
|
+
this.closed = true;
|
|
162
|
+
this.reads.length = 0;
|
|
163
|
+
this.readBuffered = 0;
|
|
164
|
+
for (const waiter of this.readWaiters.splice(0))
|
|
165
|
+
waiter.reject(error);
|
|
166
|
+
for (const waiter of this.writeWaiters.values())
|
|
167
|
+
waiter.reject(error);
|
|
168
|
+
this.writeWaiters.clear();
|
|
169
|
+
this.port.close();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function bridgeLimits(maxWsFrameBytes, maxWsBufferedAmountBytes) {
|
|
173
|
+
const wsFrame = maxWsFrameBytes ?? SDK_DEFAULTS.proxy.maxWsFrameBytes;
|
|
174
|
+
const buffered = maxWsBufferedAmountBytes ?? MAX_BRIDGE_BUFFER_BYTES;
|
|
175
|
+
if (!Number.isSafeInteger(wsFrame) || wsFrame <= 0 || !Number.isSafeInteger(buffered) || buffered <= 0) {
|
|
176
|
+
throw new TypeError("invalid proxy window bridge limits");
|
|
177
|
+
}
|
|
178
|
+
return Object.freeze({
|
|
179
|
+
maxJsonFrameBytes: SDK_DEFAULTS.proxy.maxJsonFrameBytes,
|
|
180
|
+
maxChunkBytes: SDK_DEFAULTS.proxy.maxChunkBytes,
|
|
181
|
+
maxBodyBytes: SDK_DEFAULTS.proxy.maxBodyBytes,
|
|
182
|
+
maxWsFrameBytes: wsFrame,
|
|
183
|
+
maxWsBufferedAmountBytes: buffered,
|
|
184
|
+
maxConcurrentHttpStreams: 24,
|
|
185
|
+
maxQueuedHttpRequests: 128,
|
|
186
|
+
maxQueuedHttpBodyBytes: 64 * 1024 * 1024,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function capability(input) {
|
|
190
|
+
if (input === undefined)
|
|
191
|
+
return undefined;
|
|
192
|
+
if (input === "" || input !== input.trim() || /[\u0000-\u0020\u007f]/u.test(input) || input.length > 256) {
|
|
193
|
+
throw new TypeError("invalid proxy window capability nonce");
|
|
194
|
+
}
|
|
195
|
+
return input;
|
|
196
|
+
}
|
|
197
|
+
export function registerProxyAppWindow(options) {
|
|
198
|
+
const target = options.targetWindow ?? globalThis.window;
|
|
199
|
+
const controller = options.controllerWindow ?? target.opener ?? (target.parent === target ? null : target.parent);
|
|
200
|
+
if (controller === null)
|
|
201
|
+
throw new Error("proxy controller window is unavailable");
|
|
202
|
+
const origin = new URL(options.controllerOrigin).origin;
|
|
203
|
+
if (origin !== options.controllerOrigin)
|
|
204
|
+
throw new TypeError("controllerOrigin must be an origin");
|
|
205
|
+
const nonce = capability(options.capabilityNonce);
|
|
206
|
+
const limits = bridgeLimits(options.maxWsFrameBytes, options.maxWsBufferedAmountBytes);
|
|
207
|
+
let disposed = false;
|
|
208
|
+
const dispatchFetch = (request, port) => {
|
|
209
|
+
if (disposed) {
|
|
210
|
+
port.postMessage({ type: "flowersec-proxy:response_error", status: 503, code: "closed", message: "proxy service unavailable" });
|
|
211
|
+
port.close();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
controller.postMessage({ type: FETCH_MESSAGE, version: 2, request, ...(nonce === undefined ? {} : { capabilityNonce: nonce }) }, origin, [port]);
|
|
215
|
+
};
|
|
216
|
+
const runtime = Object.freeze({
|
|
217
|
+
limits,
|
|
218
|
+
dispatchFetch,
|
|
219
|
+
openWebSocketStream: async (path, openOptions = {}) => {
|
|
220
|
+
if (disposed)
|
|
221
|
+
throw new SessionError("closed");
|
|
222
|
+
const channel = new MessageChannel();
|
|
223
|
+
const response = new Promise((resolve, reject) => {
|
|
224
|
+
const timer = setTimeout(() => { channel.port1.close(); reject(new SessionError("timeout")); }, 10_000);
|
|
225
|
+
channel.port1.onmessage = (event) => {
|
|
226
|
+
if (event.data?.type !== WEBSOCKET_ACK_MESSAGE)
|
|
227
|
+
return;
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
if (event.data.ok !== true) {
|
|
230
|
+
channel.port1.close();
|
|
231
|
+
reject(new SessionError("operation_failed"));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
resolve(Object.freeze({ stream: new MessagePortByteStream(channel.port1), protocol: typeof event.data.protocol === "string" ? event.data.protocol : "" }));
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
controller.postMessage({
|
|
238
|
+
type: WEBSOCKET_OPEN_MESSAGE,
|
|
239
|
+
version: 2,
|
|
240
|
+
path,
|
|
241
|
+
protocols: openOptions.protocols ?? [],
|
|
242
|
+
...(nonce === undefined ? {} : { capabilityNonce: nonce }),
|
|
243
|
+
}, origin, [channel.port2]);
|
|
244
|
+
if (openOptions.signal !== undefined) {
|
|
245
|
+
openOptions.signal.addEventListener("abort", () => channel.port1.close(), { once: true });
|
|
246
|
+
}
|
|
247
|
+
return await response;
|
|
248
|
+
},
|
|
249
|
+
dispose: () => { disposed = true; },
|
|
250
|
+
});
|
|
251
|
+
return Object.freeze({
|
|
252
|
+
runtime,
|
|
253
|
+
dispose: () => { disposed = true; },
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
async function bridgeStreams(runtimeStream, port) {
|
|
257
|
+
const bridge = new MessagePortByteStream(port);
|
|
258
|
+
const left = (async () => {
|
|
259
|
+
while (true) {
|
|
260
|
+
const chunk = await runtimeStream.read();
|
|
261
|
+
if (chunk === null) {
|
|
262
|
+
await bridge.closeWrite();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
await bridge.write(chunk);
|
|
266
|
+
}
|
|
267
|
+
})();
|
|
268
|
+
const right = (async () => {
|
|
269
|
+
while (true) {
|
|
270
|
+
const chunk = await bridge.read();
|
|
271
|
+
if (chunk === null) {
|
|
272
|
+
await runtimeStream.closeWrite();
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
let offset = 0;
|
|
276
|
+
while (offset < chunk.length)
|
|
277
|
+
offset += await runtimeStream.write(chunk.subarray(offset));
|
|
278
|
+
}
|
|
279
|
+
})();
|
|
280
|
+
await Promise.all([left, right]);
|
|
281
|
+
await runtimeStream.close();
|
|
282
|
+
await bridge.close();
|
|
283
|
+
}
|
|
284
|
+
export function registerProxyControllerWindow(options) {
|
|
285
|
+
const target = options.targetWindow ?? globalThis.window;
|
|
286
|
+
const allowed = new Set(options.allowedOrigins.map((origin) => new URL(origin).origin));
|
|
287
|
+
if (allowed.size === 0 || [...allowed].some((origin) => !options.allowedOrigins.includes(origin))) {
|
|
288
|
+
throw new TypeError("allowedOrigins must contain exact origins");
|
|
289
|
+
}
|
|
290
|
+
const nonce = capability(options.capabilityNonce);
|
|
291
|
+
let disposed = false;
|
|
292
|
+
const onMessage = (event) => {
|
|
293
|
+
if (disposed || !allowed.has(event.origin) || (options.expectedSource !== undefined && event.source !== options.expectedSource))
|
|
294
|
+
return;
|
|
295
|
+
if (nonce !== undefined && event.data?.capabilityNonce !== nonce)
|
|
296
|
+
return;
|
|
297
|
+
const port = event.ports?.[0];
|
|
298
|
+
if (port === undefined)
|
|
299
|
+
return;
|
|
300
|
+
if (event.data?.type === FETCH_MESSAGE && event.data.version === 2) {
|
|
301
|
+
options.runtime.dispatchFetch(event.data.request, port);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (event.data?.type === WEBSOCKET_OPEN_MESSAGE && event.data.version === 2) {
|
|
305
|
+
void (async () => {
|
|
306
|
+
try {
|
|
307
|
+
const opened = await options.runtime.openWebSocketStream(String(event.data.path ?? ""), {
|
|
308
|
+
protocols: Array.isArray(event.data.protocols) ? event.data.protocols.map(String) : [],
|
|
309
|
+
});
|
|
310
|
+
port.postMessage({ type: WEBSOCKET_ACK_MESSAGE, ok: true, protocol: opened.protocol });
|
|
311
|
+
await bridgeStreams(opened.stream, port);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
port.postMessage({ type: WEBSOCKET_ACK_MESSAGE, ok: false });
|
|
315
|
+
port.close();
|
|
316
|
+
}
|
|
317
|
+
})();
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
target.addEventListener("message", onMessage);
|
|
321
|
+
return Object.freeze({ dispose: () => { disposed = true; target.removeEventListener("message", onMessage); } });
|
|
322
|
+
}
|
|
323
|
+
export async function registerProxyAppWindowWithServiceWorkerControl(options) {
|
|
324
|
+
await registerServiceWorkerAndEnsureControl({
|
|
325
|
+
scriptUrl: options.serviceWorker.scriptUrl,
|
|
326
|
+
...(options.serviceWorker.scope === undefined ? {} : { scope: options.serviceWorker.scope }),
|
|
327
|
+
...(options.serviceWorker.repair?.queryKey === undefined ? {} : { repairQueryKey: options.serviceWorker.repair.queryKey }),
|
|
328
|
+
...(options.serviceWorker.repair?.maxAttempts === undefined ? {} : { maxRepairAttempts: options.serviceWorker.repair.maxAttempts }),
|
|
329
|
+
...(options.serviceWorker.repair?.controllerTimeoutMs === undefined ? {} : { controllerTimeoutMs: options.serviceWorker.repair.controllerTimeoutMs }),
|
|
330
|
+
});
|
|
331
|
+
const guard = createServiceWorkerControllerGuard({
|
|
332
|
+
...(options.targetWindow === undefined ? {} : { targetWindow: options.targetWindow, navigationWindow: options.targetWindow }),
|
|
333
|
+
expectedScriptPathSuffix: options.serviceWorker.expectedScriptPathSuffix,
|
|
334
|
+
...(options.serviceWorker.repair === undefined ? {} : { repair: options.serviceWorker.repair }),
|
|
335
|
+
...(options.serviceWorker.monitor === undefined ? {} : { monitor: options.serviceWorker.monitor }),
|
|
336
|
+
...(options.serviceWorker.conflicts === undefined ? {} : { conflicts: options.serviceWorker.conflicts }),
|
|
337
|
+
});
|
|
338
|
+
await guard.ensure();
|
|
339
|
+
const app = registerProxyAppWindow(options);
|
|
340
|
+
return Object.freeze({
|
|
341
|
+
runtime: app.runtime,
|
|
342
|
+
dispose: () => { app.dispose(); guard.dispose(); },
|
|
343
|
+
});
|
|
344
|
+
}
|
package/dist/proxy/wsPatch.d.ts
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ProxyRuntimeLimits } from "./runtime.js";
|
|
1
|
+
import type { ProxyRuntime } from "./types.js";
|
|
3
2
|
export type WebSocketPatchOptions = Readonly<{
|
|
4
|
-
runtime:
|
|
5
|
-
limits: Partial<ProxyRuntimeLimits>;
|
|
6
|
-
openWebSocketStream: (path: string, opts?: Readonly<{
|
|
7
|
-
protocols?: readonly string[];
|
|
8
|
-
signal?: AbortSignal;
|
|
9
|
-
}>) => Promise<Readonly<{
|
|
10
|
-
stream: YamuxStream;
|
|
11
|
-
protocol: string;
|
|
12
|
-
}>>;
|
|
13
|
-
}>;
|
|
3
|
+
runtime: Pick<ProxyRuntime, "limits" | "openWebSocketStream">;
|
|
14
4
|
shouldProxy?: (url: URL) => boolean;
|
|
15
5
|
maxWsFrameBytes?: number;
|
|
16
6
|
maxWsBufferedAmountBytes?: number;
|
|
17
7
|
}>;
|
|
18
|
-
export declare function installWebSocketPatch(
|
|
19
|
-
uninstall
|
|
8
|
+
export declare function installWebSocketPatch(options: WebSocketPatchOptions): Readonly<{
|
|
9
|
+
uninstall(): void;
|
|
20
10
|
}>;
|