@floegence/flowersec-core 0.17.2 → 0.18.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 +15 -5
- package/dist/browser/controlplane.d.ts +12 -0
- package/dist/browser/controlplane.js +66 -9
- package/dist/browser/index.d.ts +4 -2
- package/dist/browser/index.js +2 -1
- package/dist/browser/reconnectConfig.d.ts +17 -3
- package/dist/browser/reconnectConfig.js +68 -12
- package/dist/client-connect/connectCore.d.ts +5 -0
- package/dist/client-connect/connectCore.js +1 -1
- package/dist/connect/artifact.d.ts +37 -0
- package/dist/connect/artifact.js +217 -0
- package/dist/connect/internalNormalize.d.ts +22 -0
- package/dist/connect/internalNormalize.js +173 -0
- package/dist/facade.d.ts +4 -0
- package/dist/facade.js +15 -47
- package/dist/node/connect.d.ts +3 -0
- package/dist/node/index.d.ts +2 -0
- package/dist/node/index.js +1 -0
- package/dist/observability/observer.d.ts +27 -1
- package/dist/observability/observer.js +268 -12
- package/dist/proxy/bootstrap.d.ts +3 -3
- package/dist/proxy/bootstrap.js +3 -1
- package/dist/proxy/index.d.ts +2 -1
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/integration.d.ts +3 -3
- package/dist/proxy/integration.js +21 -10
- package/dist/proxy/preset.d.ts +31 -0
- package/dist/proxy/preset.js +133 -0
- package/dist/proxy/profiles.d.ts +2 -0
- package/dist/proxy/profiles.js +40 -17
- package/dist/reconnect/index.d.ts +1 -1
- package/dist/reconnect/index.js +13 -6
- package/package.json +1 -1
package/dist/proxy/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from "./constants.js";
|
|
2
2
|
export * from "./types.js";
|
|
3
3
|
export * from "./cookieJar.js";
|
|
4
|
-
export
|
|
4
|
+
export type { ProxyPresetInput, ProxyPresetLimits, ProxyPresetManifest, ResolvedProxyPreset } from "./preset.js";
|
|
5
|
+
export { DEFAULT_PROXY_PRESET_MANIFEST, assertProxyPresetManifest, resolveProxyPreset } from "./preset.js";
|
|
5
6
|
export * from "./runtime.js";
|
|
6
7
|
export * from "./serviceWorker.js";
|
|
7
8
|
export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
package/dist/proxy/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./constants.js";
|
|
2
2
|
export * from "./types.js";
|
|
3
3
|
export * from "./cookieJar.js";
|
|
4
|
-
export
|
|
4
|
+
export { DEFAULT_PROXY_PRESET_MANIFEST, assertProxyPresetManifest, resolveProxyPreset } from "./preset.js";
|
|
5
5
|
export * from "./runtime.js";
|
|
6
6
|
export * from "./serviceWorker.js";
|
|
7
7
|
export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Client } from "../client.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ProxyPresetInput, type ResolvedProxyPreset } from "./preset.js";
|
|
3
3
|
import { type ProxyRuntime } from "./runtime.js";
|
|
4
4
|
import { type ProxyServiceWorkerScriptOptions } from "./serviceWorker.js";
|
|
5
5
|
export type ProxyIntegrationMonitorOptions = Readonly<{
|
|
@@ -26,7 +26,7 @@ export type ProxyIntegrationServiceWorkerOptions = Readonly<{
|
|
|
26
26
|
}>;
|
|
27
27
|
export type RegisterProxyIntegrationOptions = Readonly<{
|
|
28
28
|
client: Client;
|
|
29
|
-
|
|
29
|
+
preset?: ProxyPresetInput;
|
|
30
30
|
runtimeGlobalKey?: string;
|
|
31
31
|
runtime?: Readonly<{
|
|
32
32
|
maxJsonFrameBytes?: number;
|
|
@@ -41,7 +41,7 @@ export type RegisterProxyIntegrationOptions = Readonly<{
|
|
|
41
41
|
export type ProxyIntegrationContext = Readonly<{
|
|
42
42
|
runtime: ProxyRuntime;
|
|
43
43
|
options: RegisterProxyIntegrationOptions;
|
|
44
|
-
|
|
44
|
+
preset: ResolvedProxyPreset;
|
|
45
45
|
}>;
|
|
46
46
|
export type ControllerMismatchContext = Readonly<{
|
|
47
47
|
expectedScriptPathSuffix: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { profileToPresetManifest } from "./profiles.js";
|
|
2
|
+
import { resolveProxyPreset } from "./preset.js";
|
|
2
3
|
import { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
|
|
3
4
|
import { createProxyRuntime } from "./runtime.js";
|
|
4
5
|
import { createProxyServiceWorkerScript } from "./serviceWorker.js";
|
|
@@ -163,13 +164,23 @@ function shouldIgnoreMismatch(plugins, ctx) {
|
|
|
163
164
|
}
|
|
164
165
|
return false;
|
|
165
166
|
}
|
|
166
|
-
function
|
|
167
|
+
function resolveIntegrationPreset(opts) {
|
|
168
|
+
if (opts.preset !== undefined && opts.profile !== undefined) {
|
|
169
|
+
throw new Error("preset and deprecated profile cannot be used together");
|
|
170
|
+
}
|
|
171
|
+
if (opts.preset !== undefined)
|
|
172
|
+
return resolveProxyPreset(opts.preset);
|
|
173
|
+
if (opts.profile !== undefined)
|
|
174
|
+
return resolveProxyPreset(profileToPresetManifest(opts.profile));
|
|
175
|
+
return resolveProxyPreset();
|
|
176
|
+
}
|
|
177
|
+
function buildRuntimeOptions(preset, runtime) {
|
|
167
178
|
return {
|
|
168
|
-
maxJsonFrameBytes: runtime?.maxJsonFrameBytes ??
|
|
169
|
-
maxChunkBytes: runtime?.maxChunkBytes ??
|
|
170
|
-
maxBodyBytes: runtime?.maxBodyBytes ??
|
|
171
|
-
maxWsFrameBytes: runtime?.maxWsFrameBytes ??
|
|
172
|
-
timeoutMs: runtime?.timeoutMs ??
|
|
179
|
+
maxJsonFrameBytes: runtime?.maxJsonFrameBytes ?? preset.limits.max_json_frame_bytes,
|
|
180
|
+
maxChunkBytes: runtime?.maxChunkBytes ?? preset.limits.max_chunk_bytes,
|
|
181
|
+
maxBodyBytes: runtime?.maxBodyBytes ?? preset.limits.max_body_bytes,
|
|
182
|
+
maxWsFrameBytes: runtime?.maxWsFrameBytes ?? preset.limits.max_ws_frame_bytes,
|
|
183
|
+
timeoutMs: runtime?.timeoutMs ?? preset.limits.timeout_ms ?? 0,
|
|
173
184
|
};
|
|
174
185
|
}
|
|
175
186
|
function bindRuntimeGlobal(runtime, key) {
|
|
@@ -221,8 +232,8 @@ export function createProxyIntegrationServiceWorkerScript(opts = {}) {
|
|
|
221
232
|
export async function registerProxyIntegration(input) {
|
|
222
233
|
const plugins = input.plugins ?? [];
|
|
223
234
|
const opts = applyPluginMutations(input, plugins);
|
|
224
|
-
const
|
|
225
|
-
const runtimeOpts = buildRuntimeOptions(
|
|
235
|
+
const preset = resolveIntegrationPreset(opts);
|
|
236
|
+
const runtimeOpts = buildRuntimeOptions(preset, opts.runtime);
|
|
226
237
|
const runtime = createProxyRuntime({ ...runtimeOpts, client: opts.client });
|
|
227
238
|
const releaseRuntimeGlobal = bindRuntimeGlobal(runtime, opts.runtimeGlobalKey);
|
|
228
239
|
const swCfg = opts.serviceWorker;
|
|
@@ -285,7 +296,7 @@ export async function registerProxyIntegration(input) {
|
|
|
285
296
|
const ctx = {
|
|
286
297
|
runtime,
|
|
287
298
|
options: opts,
|
|
288
|
-
|
|
299
|
+
preset,
|
|
289
300
|
};
|
|
290
301
|
for (const plugin of plugins) {
|
|
291
302
|
await plugin.onRegistered?.(ctx);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type ProxyPresetLimits = Readonly<{
|
|
2
|
+
max_json_frame_bytes?: number;
|
|
3
|
+
max_chunk_bytes?: number;
|
|
4
|
+
max_body_bytes?: number;
|
|
5
|
+
max_ws_frame_bytes?: number;
|
|
6
|
+
timeout_ms?: number;
|
|
7
|
+
}>;
|
|
8
|
+
export type ProxyPresetManifest = Readonly<{
|
|
9
|
+
v: 1;
|
|
10
|
+
preset_id: string;
|
|
11
|
+
deprecated?: boolean;
|
|
12
|
+
limits: ProxyPresetLimits;
|
|
13
|
+
}>;
|
|
14
|
+
export type ResolvedProxyPreset = Readonly<{
|
|
15
|
+
v: 1;
|
|
16
|
+
preset_id: string;
|
|
17
|
+
deprecated: boolean;
|
|
18
|
+
limits: Readonly<{
|
|
19
|
+
max_json_frame_bytes: number;
|
|
20
|
+
max_chunk_bytes: number;
|
|
21
|
+
max_body_bytes: number;
|
|
22
|
+
max_ws_frame_bytes: number;
|
|
23
|
+
timeout_ms?: number;
|
|
24
|
+
}>;
|
|
25
|
+
}>;
|
|
26
|
+
export declare const DEFAULT_PROXY_PRESET_MANIFEST: ProxyPresetManifest;
|
|
27
|
+
export declare const CODESERVER_PROXY_PRESET_MANIFEST: ProxyPresetManifest;
|
|
28
|
+
export type ProxyPresetInput = ProxyPresetManifest | Partial<ProxyPresetLimits>;
|
|
29
|
+
export declare function assertProxyPresetManifest(value: unknown): ProxyPresetManifest;
|
|
30
|
+
export declare function resolveNamedProxyPreset(name: string): ProxyPresetManifest;
|
|
31
|
+
export declare function resolveProxyPreset(input?: ProxyPresetInput): ResolvedProxyPreset;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { DEFAULT_MAX_JSON_FRAME_BYTES } from "../framing/jsonframe.js";
|
|
2
|
+
import { DEFAULT_MAX_BODY_BYTES, DEFAULT_MAX_CHUNK_BYTES, DEFAULT_MAX_WS_FRAME_BYTES } from "./constants.js";
|
|
3
|
+
const PRESET_ID_RE = /^[a-z][a-z0-9._-]{0,63}$/;
|
|
4
|
+
const DEFAULT_LIMITS = Object.freeze({
|
|
5
|
+
max_json_frame_bytes: DEFAULT_MAX_JSON_FRAME_BYTES,
|
|
6
|
+
max_chunk_bytes: DEFAULT_MAX_CHUNK_BYTES,
|
|
7
|
+
max_body_bytes: DEFAULT_MAX_BODY_BYTES,
|
|
8
|
+
max_ws_frame_bytes: DEFAULT_MAX_WS_FRAME_BYTES,
|
|
9
|
+
});
|
|
10
|
+
export const DEFAULT_PROXY_PRESET_MANIFEST = Object.freeze({
|
|
11
|
+
v: 1,
|
|
12
|
+
preset_id: "default",
|
|
13
|
+
limits: {
|
|
14
|
+
max_json_frame_bytes: DEFAULT_MAX_JSON_FRAME_BYTES,
|
|
15
|
+
max_chunk_bytes: DEFAULT_MAX_CHUNK_BYTES,
|
|
16
|
+
max_body_bytes: DEFAULT_MAX_BODY_BYTES,
|
|
17
|
+
max_ws_frame_bytes: DEFAULT_MAX_WS_FRAME_BYTES,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
export const CODESERVER_PROXY_PRESET_MANIFEST = Object.freeze({
|
|
21
|
+
v: 1,
|
|
22
|
+
preset_id: "codeserver",
|
|
23
|
+
deprecated: true,
|
|
24
|
+
limits: {
|
|
25
|
+
max_json_frame_bytes: DEFAULT_MAX_JSON_FRAME_BYTES,
|
|
26
|
+
max_chunk_bytes: DEFAULT_MAX_CHUNK_BYTES,
|
|
27
|
+
max_body_bytes: DEFAULT_MAX_BODY_BYTES,
|
|
28
|
+
max_ws_frame_bytes: 32 * 1024 * 1024,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
function isRecord(v) {
|
|
32
|
+
return typeof v === "object" && v != null && !Array.isArray(v);
|
|
33
|
+
}
|
|
34
|
+
function assertNoUnknownFields(kind, value, allowed) {
|
|
35
|
+
const allowedSet = new Set(allowed);
|
|
36
|
+
for (const key of Object.keys(value)) {
|
|
37
|
+
if (!allowedSet.has(key))
|
|
38
|
+
throw new Error(`bad ${kind}.${key}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function assertPositiveInt(name, value) {
|
|
42
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
43
|
+
throw new Error(`${name} must be a positive safe integer`);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
function assertLimits(value) {
|
|
48
|
+
if (!isRecord(value))
|
|
49
|
+
throw new Error("bad ProxyPresetManifest.limits");
|
|
50
|
+
assertNoUnknownFields("ProxyPresetManifest.limits", value, [
|
|
51
|
+
"max_json_frame_bytes",
|
|
52
|
+
"max_chunk_bytes",
|
|
53
|
+
"max_body_bytes",
|
|
54
|
+
"max_ws_frame_bytes",
|
|
55
|
+
"timeout_ms",
|
|
56
|
+
]);
|
|
57
|
+
const out = {};
|
|
58
|
+
if (value.max_json_frame_bytes !== undefined)
|
|
59
|
+
out.max_json_frame_bytes = assertPositiveInt("max_json_frame_bytes", value.max_json_frame_bytes);
|
|
60
|
+
if (value.max_chunk_bytes !== undefined)
|
|
61
|
+
out.max_chunk_bytes = assertPositiveInt("max_chunk_bytes", value.max_chunk_bytes);
|
|
62
|
+
if (value.max_body_bytes !== undefined)
|
|
63
|
+
out.max_body_bytes = assertPositiveInt("max_body_bytes", value.max_body_bytes);
|
|
64
|
+
if (value.max_ws_frame_bytes !== undefined)
|
|
65
|
+
out.max_ws_frame_bytes = assertPositiveInt("max_ws_frame_bytes", value.max_ws_frame_bytes);
|
|
66
|
+
if (value.timeout_ms !== undefined)
|
|
67
|
+
out.timeout_ms = assertPositiveInt("timeout_ms", value.timeout_ms);
|
|
68
|
+
return Object.freeze(out);
|
|
69
|
+
}
|
|
70
|
+
export function assertProxyPresetManifest(value) {
|
|
71
|
+
if (!isRecord(value))
|
|
72
|
+
throw new Error("bad ProxyPresetManifest");
|
|
73
|
+
assertNoUnknownFields("ProxyPresetManifest", value, ["v", "preset_id", "deprecated", "limits"]);
|
|
74
|
+
if (value.v !== 1)
|
|
75
|
+
throw new Error("bad ProxyPresetManifest.v");
|
|
76
|
+
if (typeof value.preset_id !== "string" || !PRESET_ID_RE.test(value.preset_id)) {
|
|
77
|
+
throw new Error("bad ProxyPresetManifest.preset_id");
|
|
78
|
+
}
|
|
79
|
+
if (value.deprecated !== undefined && typeof value.deprecated !== "boolean") {
|
|
80
|
+
throw new Error("bad ProxyPresetManifest.deprecated");
|
|
81
|
+
}
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
v: 1,
|
|
84
|
+
preset_id: value.preset_id,
|
|
85
|
+
...(value.deprecated === undefined ? {} : { deprecated: value.deprecated }),
|
|
86
|
+
limits: assertLimits(value.limits),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function resolveNamedProxyPreset(name) {
|
|
90
|
+
switch (String(name ?? "").trim()) {
|
|
91
|
+
case "":
|
|
92
|
+
case "default":
|
|
93
|
+
return DEFAULT_PROXY_PRESET_MANIFEST;
|
|
94
|
+
case "codeserver":
|
|
95
|
+
return CODESERVER_PROXY_PRESET_MANIFEST;
|
|
96
|
+
default:
|
|
97
|
+
throw new Error(`unknown proxy preset: ${name}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function toResolved(manifest) {
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
v: 1,
|
|
103
|
+
preset_id: manifest.preset_id,
|
|
104
|
+
deprecated: manifest.deprecated === true,
|
|
105
|
+
limits: Object.freeze({
|
|
106
|
+
max_json_frame_bytes: manifest.limits.max_json_frame_bytes ?? DEFAULT_LIMITS.max_json_frame_bytes,
|
|
107
|
+
max_chunk_bytes: manifest.limits.max_chunk_bytes ?? DEFAULT_LIMITS.max_chunk_bytes,
|
|
108
|
+
max_body_bytes: manifest.limits.max_body_bytes ?? DEFAULT_LIMITS.max_body_bytes,
|
|
109
|
+
max_ws_frame_bytes: manifest.limits.max_ws_frame_bytes ?? DEFAULT_LIMITS.max_ws_frame_bytes,
|
|
110
|
+
...(manifest.limits.timeout_ms === undefined ? {} : { timeout_ms: manifest.limits.timeout_ms }),
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export function resolveProxyPreset(input) {
|
|
115
|
+
if (input == null)
|
|
116
|
+
return toResolved(DEFAULT_PROXY_PRESET_MANIFEST);
|
|
117
|
+
if (isRecord(input) && ("v" in input || "presetId" in input || "limits" in input)) {
|
|
118
|
+
return toResolved(assertProxyPresetManifest(input));
|
|
119
|
+
}
|
|
120
|
+
const limits = assertLimits(input);
|
|
121
|
+
return Object.freeze({
|
|
122
|
+
v: 1,
|
|
123
|
+
preset_id: "custom",
|
|
124
|
+
deprecated: false,
|
|
125
|
+
limits: Object.freeze({
|
|
126
|
+
max_json_frame_bytes: limits.max_json_frame_bytes ?? DEFAULT_LIMITS.max_json_frame_bytes,
|
|
127
|
+
max_chunk_bytes: limits.max_chunk_bytes ?? DEFAULT_LIMITS.max_chunk_bytes,
|
|
128
|
+
max_body_bytes: limits.max_body_bytes ?? DEFAULT_LIMITS.max_body_bytes,
|
|
129
|
+
max_ws_frame_bytes: limits.max_ws_frame_bytes ?? DEFAULT_LIMITS.max_ws_frame_bytes,
|
|
130
|
+
...(limits.timeout_ms === undefined ? {} : { timeout_ms: limits.timeout_ms }),
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
}
|
package/dist/proxy/profiles.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ProxyPresetManifest } from "./preset.js";
|
|
1
2
|
export type ProxyProfile = Readonly<{
|
|
2
3
|
maxJsonFrameBytes: number;
|
|
3
4
|
maxChunkBytes: number;
|
|
@@ -21,3 +22,4 @@ export declare const PROXY_PROFILE_CODESERVER: Readonly<{
|
|
|
21
22
|
timeoutMs: number;
|
|
22
23
|
}>;
|
|
23
24
|
export declare function resolveProxyProfile(profile?: ProxyProfileName | Partial<ProxyProfile>): ProxyProfile;
|
|
25
|
+
export declare function profileToPresetManifest(profile?: ProxyProfileName | Partial<ProxyProfile>): ProxyPresetManifest;
|
package/dist/proxy/profiles.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// Keep aligned with redeven/redeven-agent production profile.
|
|
15
|
-
maxWsFrameBytes: 32 * 1024 * 1024,
|
|
16
|
-
timeoutMs: 0,
|
|
17
|
-
});
|
|
1
|
+
import { CODESERVER_PROXY_PRESET_MANIFEST, DEFAULT_PROXY_PRESET_MANIFEST, resolveProxyPreset, } from "./preset.js";
|
|
2
|
+
function toLegacyProfile(manifest) {
|
|
3
|
+
const resolved = resolveProxyPreset(manifest);
|
|
4
|
+
return Object.freeze({
|
|
5
|
+
maxJsonFrameBytes: resolved.limits.max_json_frame_bytes,
|
|
6
|
+
maxChunkBytes: resolved.limits.max_chunk_bytes,
|
|
7
|
+
maxBodyBytes: resolved.limits.max_body_bytes,
|
|
8
|
+
maxWsFrameBytes: resolved.limits.max_ws_frame_bytes,
|
|
9
|
+
timeoutMs: resolved.limits.timeout_ms ?? 0,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
const DEFAULT_PROFILE = toLegacyProfile(DEFAULT_PROXY_PRESET_MANIFEST);
|
|
13
|
+
const CODESERVER_PROFILE = toLegacyProfile(CODESERVER_PROXY_PRESET_MANIFEST);
|
|
18
14
|
export const PROXY_PROFILE_DEFAULT = DEFAULT_PROFILE;
|
|
19
15
|
export const PROXY_PROFILE_CODESERVER = CODESERVER_PROFILE;
|
|
20
16
|
function normalizeSafeInt(name, value) {
|
|
@@ -52,3 +48,30 @@ export function resolveProxyProfile(profile) {
|
|
|
52
48
|
timeoutMs: normalizeSafeInt("timeoutMs", profile.timeoutMs ?? base.timeoutMs),
|
|
53
49
|
});
|
|
54
50
|
}
|
|
51
|
+
export function profileToPresetManifest(profile) {
|
|
52
|
+
if (profile == null)
|
|
53
|
+
return DEFAULT_PROXY_PRESET_MANIFEST;
|
|
54
|
+
if (typeof profile === "string") {
|
|
55
|
+
switch (profile) {
|
|
56
|
+
case "default":
|
|
57
|
+
return DEFAULT_PROXY_PRESET_MANIFEST;
|
|
58
|
+
case "codeserver":
|
|
59
|
+
return CODESERVER_PROXY_PRESET_MANIFEST;
|
|
60
|
+
default:
|
|
61
|
+
throw new Error(`unknown proxy profile: ${profile}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const resolved = resolveProxyProfile(profile);
|
|
65
|
+
return Object.freeze({
|
|
66
|
+
v: 1,
|
|
67
|
+
preset_id: "legacy-profile",
|
|
68
|
+
deprecated: true,
|
|
69
|
+
limits: {
|
|
70
|
+
...(resolved.maxJsonFrameBytes > 0 ? { max_json_frame_bytes: resolved.maxJsonFrameBytes } : {}),
|
|
71
|
+
...(resolved.maxChunkBytes > 0 ? { max_chunk_bytes: resolved.maxChunkBytes } : {}),
|
|
72
|
+
...(resolved.maxBodyBytes > 0 ? { max_body_bytes: resolved.maxBodyBytes } : {}),
|
|
73
|
+
...(resolved.maxWsFrameBytes > 0 ? { max_ws_frame_bytes: resolved.maxWsFrameBytes } : {}),
|
|
74
|
+
...(resolved.timeoutMs > 0 ? { timeout_ms: resolved.timeoutMs } : {}),
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Client } from "../client.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type ClientObserverLike } from "../observability/observer.js";
|
|
3
3
|
export type ConnectionStatus = "disconnected" | "connecting" | "connected" | "error";
|
|
4
4
|
export type AutoReconnectConfig = Readonly<{
|
|
5
5
|
enabled?: boolean;
|
package/dist/reconnect/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withObserverContext } from "../observability/observer.js";
|
|
1
2
|
function normalizeAutoReconnect(cfg) {
|
|
2
3
|
if (!cfg?.enabled) {
|
|
3
4
|
return {
|
|
@@ -59,6 +60,7 @@ export function createReconnectManager() {
|
|
|
59
60
|
let retryTimer = null;
|
|
60
61
|
let retryResolve = null;
|
|
61
62
|
let attemptAbort = null;
|
|
63
|
+
let attemptSeq = 0;
|
|
62
64
|
const cancelRetrySleep = () => {
|
|
63
65
|
if (retryTimer) {
|
|
64
66
|
clearTimeout(retryTimer);
|
|
@@ -90,6 +92,7 @@ export function createReconnectManager() {
|
|
|
90
92
|
active = null;
|
|
91
93
|
activeConnectPromise = null;
|
|
92
94
|
token += 1;
|
|
95
|
+
attemptSeq = 0;
|
|
93
96
|
if (s.client) {
|
|
94
97
|
try {
|
|
95
98
|
s.client.close();
|
|
@@ -138,9 +141,9 @@ export function createReconnectManager() {
|
|
|
138
141
|
// connectWithRetry updates state; keep errors observable via state().
|
|
139
142
|
});
|
|
140
143
|
};
|
|
141
|
-
const createObserver = (t, cfg) => {
|
|
144
|
+
const createObserver = (t, cfg, currentAttemptSeq) => {
|
|
142
145
|
const user = cfg.observer;
|
|
143
|
-
return {
|
|
146
|
+
return withObserverContext({
|
|
144
147
|
onConnect: (...args) => user?.onConnect?.(...args),
|
|
145
148
|
onAttach: (...args) => user?.onAttach?.(...args),
|
|
146
149
|
onHandshake: (...args) => user?.onHandshake?.(...args),
|
|
@@ -156,12 +159,14 @@ export function createReconnectManager() {
|
|
|
156
159
|
},
|
|
157
160
|
onRpcCall: (...args) => user?.onRpcCall?.(...args),
|
|
158
161
|
onRpcNotify: (...args) => user?.onRpcNotify?.(...args),
|
|
159
|
-
}
|
|
162
|
+
}, {
|
|
163
|
+
attemptSeq: currentAttemptSeq,
|
|
164
|
+
});
|
|
160
165
|
};
|
|
161
|
-
const connectOnce = async (t, cfg) => {
|
|
166
|
+
const connectOnce = async (t, cfg, currentAttemptSeq) => {
|
|
162
167
|
abortActiveAttempt();
|
|
163
168
|
attemptAbort = new AbortController();
|
|
164
|
-
return await cfg.connectOnce({ signal: attemptAbort.signal, observer: createObserver(t, cfg) ?? {} });
|
|
169
|
+
return await cfg.connectOnce({ signal: attemptAbort.signal, observer: createObserver(t, cfg, currentAttemptSeq) ?? {} });
|
|
165
170
|
};
|
|
166
171
|
const connectWithRetry = async (t, cfg) => {
|
|
167
172
|
const ar = normalizeAutoReconnect(cfg.autoReconnect);
|
|
@@ -172,8 +177,9 @@ export function createReconnectManager() {
|
|
|
172
177
|
if (active !== cfg)
|
|
173
178
|
return;
|
|
174
179
|
attempts += 1;
|
|
180
|
+
attemptSeq += 1;
|
|
175
181
|
try {
|
|
176
|
-
const client = await connectOnce(t, cfg);
|
|
182
|
+
const client = await connectOnce(t, cfg, attemptSeq);
|
|
177
183
|
if (t !== token) {
|
|
178
184
|
try {
|
|
179
185
|
client.close();
|
|
@@ -218,6 +224,7 @@ export function createReconnectManager() {
|
|
|
218
224
|
token += 1;
|
|
219
225
|
const t = token;
|
|
220
226
|
active = cfg;
|
|
227
|
+
attemptSeq = 0;
|
|
221
228
|
if (s.client) {
|
|
222
229
|
try {
|
|
223
230
|
s.client.close();
|