@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.50
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/AUTHORING.md +537 -33
- package/CHANGELOG.md +201 -1
- package/README.md +83 -22
- package/SUBMISSION.md +2 -2
- package/bin/apifuse-check.ts +165 -11
- package/bin/apifuse-dev.ts +57 -13
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +357 -38
- package/bin/apifuse-perf.ts +14 -13
- package/bin/apifuse-record.ts +709 -72
- package/bin/apifuse-submit-check.ts +2344 -324
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +27 -0
- package/dist/cli/create.d.ts +4 -1
- package/dist/cli/create.js +42 -37
- package/dist/cli/migrate-operation-declaration.d.ts +59 -0
- package/dist/cli/migrate-operation-declaration.js +1178 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +52 -0
- package/dist/cli/migrate-provider-shape.js +578 -0
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +5 -5
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +179 -16
- package/dist/config/loader.js +435 -127
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +33 -0
- package/dist/declaration-validation.js +266 -0
- package/dist/define.d.ts +66 -29
- package/dist/define.js +778 -69
- package/dist/dev.d.ts +3 -0
- package/dist/dev.js +1 -1
- package/dist/engine.d.ts +78 -0
- package/dist/engine.js +133 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +40 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +227 -0
- package/dist/health-scenario.d.ts +1842 -0
- package/dist/health-scenario.js +624 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.js +12 -7
- package/dist/lint.d.ts +23 -11
- package/dist/lint.js +572 -69
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +10 -2
- package/dist/provider.js +4 -1
- package/dist/runtime/auth-flow.d.ts +5 -1
- package/dist/runtime/auth-flow.js +6 -0
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +492 -49
- package/dist/runtime/cache.d.ts +1 -0
- package/dist/runtime/cache.js +169 -15
- package/dist/runtime/choice-wordlist.d.ts +9 -0
- package/dist/runtime/choice-wordlist.js +138 -0
- package/dist/runtime/choice.d.ts +13 -1
- package/dist/runtime/choice.js +490 -102
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +26 -25
- package/dist/runtime/http.d.ts +1 -0
- package/dist/runtime/http.js +515 -53
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +366 -8
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +96 -0
- package/dist/runtime/native-network.js +1232 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +397 -16
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-telemetry.d.ts +80 -1
- package/dist/runtime/proxy-telemetry.js +154 -47
- package/dist/runtime/redirects.d.ts +29 -0
- package/dist/runtime/redirects.js +36 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/resolver-config.d.ts +6 -0
- package/dist/runtime/resolver-config.js +6 -0
- package/dist/runtime/resolver-public.d.ts +1 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-shared.d.ts +14 -0
- package/dist/runtime/resolver-shared.js +12 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
- package/dist/runtime/resolver-vendors/bindings.js +40 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
- package/dist/runtime/resolver-vendors/browser.js +377 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +531 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
- package/dist/runtime/resolver-vendors/hosts.js +33 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
- package/dist/runtime/resolver-vendors/types.d.ts +94 -0
- package/dist/runtime/resolver-vendors/types.js +96 -0
- package/dist/runtime/resolver.d.ts +72 -0
- package/dist/runtime/resolver.js +771 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +277 -71
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +41 -5
- package/dist/runtime/stealth.js +997 -291
- package/dist/runtime/stt.js +1 -12
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +5 -0
- package/dist/runtime/trace.js +43 -10
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.js +2 -2
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test.d.ts +14 -3
- package/dist/server/self-test.js +129 -58
- package/dist/server/serve-implementation.d.ts +230 -0
- package/dist/server/serve-implementation.js +2265 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1131
- package/dist/server/trace-output.d.ts +6 -0
- package/dist/server/trace-output.js +79 -0
- package/dist/server/types.d.ts +30 -5
- package/dist/server/types.js +13 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
- package/dist/stateful/stateful-provider-runtime-context.js +60 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +9 -4
- package/dist/stealth/profiles.js +160 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +489 -21
- package/dist/trace-sanitization.d.ts +5 -0
- package/dist/trace-sanitization.js +45 -0
- package/dist/types.d.ts +673 -131
- package/dist/types.js +1 -0
- package/package.json +45 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
- package/src/cli/commands.ts +33 -0
- package/src/cli/create.ts +50 -37
- package/src/cli/migrate-operation-declaration.ts +1654 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +772 -0
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +5 -5
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +690 -163
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +330 -0
- package/src/define.ts +1048 -131
- package/src/dev.ts +4 -1
- package/src/engine.ts +279 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +68 -0
- package/src/fixture-sanitization.ts +264 -0
- package/src/health-scenario.ts +875 -0
- package/src/index.ts +220 -13
- package/src/lint.ts +698 -90
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +161 -3
- package/src/runtime/auth-flow.ts +12 -0
- package/src/runtime/browser.ts +661 -63
- package/src/runtime/cache.ts +189 -14
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +631 -120
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/env.ts +13 -0
- package/src/runtime/executor.ts +43 -31
- package/src/runtime/http.ts +641 -61
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +520 -15
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1605 -0
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/otlp.ts +467 -21
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-telemetry.ts +244 -75
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +23 -0
- package/src/runtime/resolver-shared.ts +33 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +533 -0
- package/src/runtime/resolver-vendors/capsolver.ts +707 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
- package/src/runtime/resolver-vendors/types.ts +212 -0
- package/src/runtime/resolver.ts +1157 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +394 -77
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +1280 -336
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +57 -17
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/index.ts +34 -2
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test.ts +191 -68
- package/src/server/serve-implementation.ts +3378 -0
- package/src/server/serve.ts +1 -1632
- package/src/server/trace-output.ts +129 -0
- package/src/server/types.ts +13 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
- package/src/stateful/stateful-provider-runtime-context.ts +92 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +202 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +658 -15
- package/src/trace-sanitization.ts +63 -0
- package/src/types.ts +788 -174
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { OperationErrorResponseSchema, OperationSuccessResponseSchema, } from "../server/index.js";
|
|
3
|
+
import { signStatefulRequestBody, statefulSignedHeaders } from "../stateful-signing.js";
|
|
4
|
+
import { forwardingContextFromStatefulRuntimeContext } from "./stateful-provider-session-routing.js";
|
|
5
|
+
export const STATEFUL_INTERNAL_OPERATIONS_ROUTE = "/__apifuse/stateful/operations";
|
|
6
|
+
export const STATEFUL_FORWARDING_SIGNATURE_HEADER = "x-apifuse-stateful-signature";
|
|
7
|
+
export const STATEFUL_FORWARDING_TIMESTAMP_HEADER = "x-apifuse-stateful-timestamp";
|
|
8
|
+
export const STATEFUL_FORWARDING_NONCE_HEADER = "x-apifuse-stateful-nonce";
|
|
9
|
+
export const STATEFUL_FORWARDING_SOURCE_POD_HEADER = "x-apifuse-stateful-source-pod";
|
|
10
|
+
const MAX_FORWARDED_HEADERS = 32;
|
|
11
|
+
const MAX_FORWARDED_HEADER_BYTES = 8 * 1024;
|
|
12
|
+
// Inbound compatibility boundary for rolling deploys: older owner pods omit
|
|
13
|
+
// top-level retryable. Emitted responses remain strict via
|
|
14
|
+
// OperationErrorResponseSchema.
|
|
15
|
+
const ForwardedOperationErrorResponseSchema = OperationErrorResponseSchema.extend({
|
|
16
|
+
error: OperationErrorResponseSchema.shape.error.extend({
|
|
17
|
+
retryable: z.boolean().optional().default(false),
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
const SENSITIVE_HEADER_NAMES = new Set([
|
|
21
|
+
"authorization",
|
|
22
|
+
"cookie",
|
|
23
|
+
"set-cookie",
|
|
24
|
+
STATEFUL_FORWARDING_SIGNATURE_HEADER,
|
|
25
|
+
STATEFUL_FORWARDING_TIMESTAMP_HEADER,
|
|
26
|
+
STATEFUL_FORWARDING_NONCE_HEADER,
|
|
27
|
+
STATEFUL_FORWARDING_SOURCE_POD_HEADER,
|
|
28
|
+
]);
|
|
29
|
+
/** Builds the standard fail-closed owner-currentness check for serve(). */
|
|
30
|
+
export function createStatefulOwnerFenceValidator(registry) {
|
|
31
|
+
return async (fence, signal) => {
|
|
32
|
+
const current = await registry.resolve(fence.sessionKey, undefined, signal);
|
|
33
|
+
return (current !== null &&
|
|
34
|
+
current.sessionKey === fence.sessionKey &&
|
|
35
|
+
current.ownerPodId === fence.ownerPodId &&
|
|
36
|
+
current.generation === fence.generation);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export class StatefulOwnerForwardingError extends Error {
|
|
40
|
+
code;
|
|
41
|
+
status;
|
|
42
|
+
constructor(input) {
|
|
43
|
+
super(input.message, input.cause === undefined ? undefined : { cause: input.cause });
|
|
44
|
+
this.name = "StatefulOwnerForwardingError";
|
|
45
|
+
this.code = input.code;
|
|
46
|
+
this.status = input.status;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class HttpStatefulOwnerForwarder {
|
|
50
|
+
#currentPodId;
|
|
51
|
+
#secret;
|
|
52
|
+
#fetch;
|
|
53
|
+
#clock;
|
|
54
|
+
constructor(options) {
|
|
55
|
+
if (options.secret.trim().length === 0) {
|
|
56
|
+
throw new Error("Stateful owner forwarding secret is required.");
|
|
57
|
+
}
|
|
58
|
+
this.#currentPodId = options.currentPodId;
|
|
59
|
+
this.#secret = options.secret;
|
|
60
|
+
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
61
|
+
this.#clock = options.clock ?? (() => new Date());
|
|
62
|
+
}
|
|
63
|
+
async forward(owner, request, signal) {
|
|
64
|
+
assertNoRequestScopedFiles(request.input);
|
|
65
|
+
const forwardedAt = this.#clock().toISOString();
|
|
66
|
+
const envelope = buildForwardingEnvelope({
|
|
67
|
+
owner,
|
|
68
|
+
request,
|
|
69
|
+
sourcePodId: this.#currentPodId,
|
|
70
|
+
forwardedAt,
|
|
71
|
+
});
|
|
72
|
+
const rawBody = JSON.stringify(envelope);
|
|
73
|
+
let response;
|
|
74
|
+
try {
|
|
75
|
+
const target = new URL(`${owner.ownerEndpoint.replace(/\/+$/, "")}${STATEFUL_INTERNAL_OPERATIONS_ROUTE}`);
|
|
76
|
+
response = await this.#fetch(target, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
"content-type": "application/json",
|
|
80
|
+
...statefulSignedHeaders({
|
|
81
|
+
secret: this.#secret,
|
|
82
|
+
timestamp: forwardedAt,
|
|
83
|
+
rawBody,
|
|
84
|
+
method: "POST",
|
|
85
|
+
path: STATEFUL_INTERNAL_OPERATIONS_ROUTE,
|
|
86
|
+
}),
|
|
87
|
+
[STATEFUL_FORWARDING_SOURCE_POD_HEADER]: this.#currentPodId,
|
|
88
|
+
},
|
|
89
|
+
body: rawBody,
|
|
90
|
+
signal,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (cause) {
|
|
94
|
+
throw new StatefulOwnerForwardingError({
|
|
95
|
+
code: "STATEFUL_FORWARDING_REQUEST_FAILED",
|
|
96
|
+
message: "Stateful owner forwarding request failed before a response was received.",
|
|
97
|
+
cause,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return parseForwardedResponse(response);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function signStatefulForwardingBody(input) {
|
|
104
|
+
return signStatefulRequestBody(input);
|
|
105
|
+
}
|
|
106
|
+
function assertNoRequestScopedFiles(input) {
|
|
107
|
+
if (!containsRequestScopedFile(input))
|
|
108
|
+
return;
|
|
109
|
+
throw new StatefulOwnerForwardingError({
|
|
110
|
+
code: "STATEFUL_FILE_FORWARDING_UNSUPPORTED",
|
|
111
|
+
message: "Request-scoped files cannot be forwarded to a remote stateful owner. Use staged upload once available so the forwarding envelope carries only durable file_ref values, or route the request to the owner-local provider process.",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function containsRequestScopedFile(value) {
|
|
115
|
+
if (isRequestScopedFileRef(value))
|
|
116
|
+
return true;
|
|
117
|
+
if (Array.isArray(value))
|
|
118
|
+
return value.some((item) => containsRequestScopedFile(item));
|
|
119
|
+
if (!value || typeof value !== "object")
|
|
120
|
+
return false;
|
|
121
|
+
return Object.values(value).some((item) => containsRequestScopedFile(item));
|
|
122
|
+
}
|
|
123
|
+
function isRequestScopedFileRef(value) {
|
|
124
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
125
|
+
return false;
|
|
126
|
+
const record = Object.fromEntries(Object.entries(value));
|
|
127
|
+
return record.type === "request_file" && typeof record.id === "string";
|
|
128
|
+
}
|
|
129
|
+
function buildForwardingEnvelope(input) {
|
|
130
|
+
const metadata = forwardedMetadata(input.request);
|
|
131
|
+
return {
|
|
132
|
+
requestId: input.request.requestId,
|
|
133
|
+
providerId: input.request.providerId,
|
|
134
|
+
operationId: input.request.operationId,
|
|
135
|
+
sessionKey: input.request.sessionKey,
|
|
136
|
+
connectionId: input.request.connectionId,
|
|
137
|
+
serviceAccountId: input.request.serviceAccountId,
|
|
138
|
+
...(input.request.idempotencyKey ? { idempotencyKey: input.request.idempotencyKey } : {}),
|
|
139
|
+
...(input.request.deadlineAt !== undefined ? { deadlineAt: input.request.deadlineAt } : {}),
|
|
140
|
+
sourcePodId: input.sourcePodId,
|
|
141
|
+
forwardedAt: input.forwardedAt,
|
|
142
|
+
ownerPodId: input.owner.ownerPodId,
|
|
143
|
+
generation: input.owner.generation,
|
|
144
|
+
operationRequest: {
|
|
145
|
+
requestId: input.request.requestId,
|
|
146
|
+
input: input.request.input,
|
|
147
|
+
connection: metadata.connection,
|
|
148
|
+
headers: sanitizeForwardedHeaders(metadata.headers),
|
|
149
|
+
...(metadata.trace ? { trace: metadata.trace } : {}),
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function forwardedMetadata(request) {
|
|
154
|
+
const forwardingContext = forwardingContextFromStatefulRuntimeContext(request.runtimeContext);
|
|
155
|
+
if (!forwardingContext) {
|
|
156
|
+
throw new StatefulOwnerForwardingError({
|
|
157
|
+
code: "STATEFUL_FORWARDING_CONTEXT_MISSING",
|
|
158
|
+
message: "Stateful operation forwarding requires request context metadata.",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const operationRequest = forwardingContext.operationRequest;
|
|
162
|
+
const connection = OperationConnectionSchema.parse(operationRequest?.connection);
|
|
163
|
+
return {
|
|
164
|
+
connection,
|
|
165
|
+
...(operationRequest?.headers ? { headers: operationRequest.headers } : {}),
|
|
166
|
+
...(operationRequest?.trace ? { trace: operationRequest.trace } : {}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function sanitizeForwardedHeaders(headers) {
|
|
170
|
+
if (!headers)
|
|
171
|
+
return {};
|
|
172
|
+
const forwarded = {};
|
|
173
|
+
let totalBytes = 0;
|
|
174
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
175
|
+
const normalized = name.toLowerCase();
|
|
176
|
+
if (SENSITIVE_HEADER_NAMES.has(normalized))
|
|
177
|
+
continue;
|
|
178
|
+
const nextBytes = Buffer.byteLength(name) + Buffer.byteLength(value);
|
|
179
|
+
if (Object.keys(forwarded).length >= MAX_FORWARDED_HEADERS ||
|
|
180
|
+
totalBytes + nextBytes > MAX_FORWARDED_HEADER_BYTES) {
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
forwarded[name] = value;
|
|
184
|
+
totalBytes += nextBytes;
|
|
185
|
+
}
|
|
186
|
+
return forwarded;
|
|
187
|
+
}
|
|
188
|
+
async function parseForwardedResponse(response) {
|
|
189
|
+
const body = await response.json().catch(() => undefined);
|
|
190
|
+
const success = OperationSuccessResponseSchema.safeParse(body);
|
|
191
|
+
if (response.ok && success.success) {
|
|
192
|
+
return { output: success.data.data };
|
|
193
|
+
}
|
|
194
|
+
const error = ForwardedOperationErrorResponseSchema.safeParse(body);
|
|
195
|
+
if (error.success) {
|
|
196
|
+
throw new StatefulOwnerForwardingError({
|
|
197
|
+
code: error.data.error.code,
|
|
198
|
+
message: error.data.error.message,
|
|
199
|
+
status: response.status,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
throw new StatefulOwnerForwardingError({
|
|
203
|
+
code: "STATEFUL_FORWARDING_BAD_RESPONSE",
|
|
204
|
+
message: `Stateful owner returned an invalid response with status ${response.status}.`,
|
|
205
|
+
status: response.status,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
const OperationConnectionSchema = z.object({
|
|
209
|
+
id: z.string(),
|
|
210
|
+
mode: z.enum(["oauth2", "credentials", "platform-managed", "none"]),
|
|
211
|
+
secrets: z.record(z.string(), z.string()),
|
|
212
|
+
scopes: z.array(z.string()).optional(),
|
|
213
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
214
|
+
externalRef: z.string(),
|
|
215
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface StatefulLocalRuntimeContext {
|
|
2
|
+
readonly providerContext?: unknown;
|
|
3
|
+
}
|
|
4
|
+
export interface StatefulForwardingRuntimeContext {
|
|
5
|
+
readonly operationRequest?: {
|
|
6
|
+
readonly requestId: string;
|
|
7
|
+
readonly connection?: unknown;
|
|
8
|
+
readonly headers?: Record<string, string>;
|
|
9
|
+
readonly trace?: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface StatefulOperationRuntimeContext {
|
|
13
|
+
readonly local?: StatefulLocalRuntimeContext;
|
|
14
|
+
readonly forwarding?: StatefulForwardingRuntimeContext;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Attaches provider-process-only context for local execution. This value must
|
|
18
|
+
* never be serialized into owner-forwarding envelopes.
|
|
19
|
+
*/
|
|
20
|
+
export declare function withStatefulLocalProviderContext(providerContext: unknown, forwarding?: StatefulForwardingRuntimeContext): StatefulOperationRuntimeContext;
|
|
21
|
+
/**
|
|
22
|
+
* Copies only operation metadata that is safe to serialize across owner pods.
|
|
23
|
+
*/
|
|
24
|
+
export declare function statefulForwardingContextFromProviderRequest(request: {
|
|
25
|
+
readonly requestId: string;
|
|
26
|
+
readonly connection?: unknown;
|
|
27
|
+
readonly headers?: Record<string, string>;
|
|
28
|
+
readonly trace?: Record<string, string>;
|
|
29
|
+
}): StatefulForwardingRuntimeContext;
|
|
30
|
+
export declare function isStatefulOperationRuntimeContext(value: unknown): value is StatefulOperationRuntimeContext;
|
|
31
|
+
export declare function providerContextFromStatefulRuntimeContext(value: unknown): unknown;
|
|
32
|
+
export declare function forwardingContextFromStatefulRuntimeContext(value: unknown): StatefulForwardingRuntimeContext | undefined;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attaches provider-process-only context for local execution. This value must
|
|
3
|
+
* never be serialized into owner-forwarding envelopes.
|
|
4
|
+
*/
|
|
5
|
+
export function withStatefulLocalProviderContext(providerContext, forwarding) {
|
|
6
|
+
return {
|
|
7
|
+
local: { providerContext },
|
|
8
|
+
...(forwarding ? { forwarding } : {}),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Copies only operation metadata that is safe to serialize across owner pods.
|
|
13
|
+
*/
|
|
14
|
+
export function statefulForwardingContextFromProviderRequest(request) {
|
|
15
|
+
return {
|
|
16
|
+
operationRequest: {
|
|
17
|
+
requestId: request.requestId,
|
|
18
|
+
...(request.connection !== undefined ? { connection: request.connection } : {}),
|
|
19
|
+
...(request.headers ? { headers: request.headers } : {}),
|
|
20
|
+
...(request.trace ? { trace: request.trace } : {}),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function isStatefulOperationRuntimeContext(value) {
|
|
25
|
+
if (value === null || typeof value !== "object")
|
|
26
|
+
return false;
|
|
27
|
+
return ("local" in value ||
|
|
28
|
+
"forwarding" in value ||
|
|
29
|
+
"operationRequest" in value ||
|
|
30
|
+
"providerContext" in value);
|
|
31
|
+
}
|
|
32
|
+
export function providerContextFromStatefulRuntimeContext(value) {
|
|
33
|
+
if (!isStatefulOperationRuntimeContext(value))
|
|
34
|
+
return undefined;
|
|
35
|
+
if ("local" in value)
|
|
36
|
+
return value.local?.providerContext;
|
|
37
|
+
// Backward-compatible read for pre-split runtimeContext objects. New code
|
|
38
|
+
// should always use `withStatefulLocalProviderContext` instead.
|
|
39
|
+
if ("providerContext" in value)
|
|
40
|
+
return value.providerContext;
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
export function forwardingContextFromStatefulRuntimeContext(value) {
|
|
44
|
+
if (!isStatefulOperationRuntimeContext(value))
|
|
45
|
+
return undefined;
|
|
46
|
+
if ("forwarding" in value)
|
|
47
|
+
return value.forwarding;
|
|
48
|
+
if ("operationRequest" in value) {
|
|
49
|
+
const operationRequest = value.operationRequest;
|
|
50
|
+
if (isForwardingOperationRequest(operationRequest)) {
|
|
51
|
+
return { operationRequest };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
function isForwardingOperationRequest(value) {
|
|
57
|
+
if (value === null || typeof value !== "object")
|
|
58
|
+
return false;
|
|
59
|
+
return "requestId" in value && typeof value.requestId === "string";
|
|
60
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SessionKey } from "./session-key.js";
|
|
2
|
+
import type { StatefulProviderMetricEmitter } from "./stateful-provider-observability.js";
|
|
3
|
+
import { type StatefulOperationExecutor, type StatefulOperationRequest, type StatefulOperationResult, type StatefulOwnerForwarder, type StatefulOwnerPod } from "./stateful-provider-session-routing.js";
|
|
4
|
+
import type { SessionOwnerRegistry } from "./stateful-provider-session-runtime.js";
|
|
5
|
+
export interface StatefulProviderInvocationMetadata<TInput = unknown> {
|
|
6
|
+
readonly requestId: string;
|
|
7
|
+
readonly sessionKey: SessionKey;
|
|
8
|
+
readonly providerId: string;
|
|
9
|
+
readonly operationId: string;
|
|
10
|
+
readonly connectionId: string;
|
|
11
|
+
readonly serviceAccountId: string;
|
|
12
|
+
readonly input: TInput;
|
|
13
|
+
readonly idempotencyKey?: string;
|
|
14
|
+
readonly deadlineAt?: string;
|
|
15
|
+
readonly runtimeContext?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface StatefulProviderRuntimeExecutorOptions {
|
|
18
|
+
readonly currentPod: StatefulOwnerPod;
|
|
19
|
+
readonly registry: SessionOwnerRegistry;
|
|
20
|
+
readonly forwarder: StatefulOwnerForwarder;
|
|
21
|
+
readonly executor: StatefulOperationExecutor;
|
|
22
|
+
readonly leaseDurationMs: number;
|
|
23
|
+
readonly leaseRenewalFraction?: number;
|
|
24
|
+
readonly clock?: () => Date;
|
|
25
|
+
readonly metricEmitter?: StatefulProviderMetricEmitter;
|
|
26
|
+
}
|
|
27
|
+
export declare class StatefulProviderRuntimeExecutor {
|
|
28
|
+
#private;
|
|
29
|
+
constructor(options: StatefulProviderRuntimeExecutorOptions);
|
|
30
|
+
invoke(request: StatefulOperationRequest): Promise<StatefulOperationResult>;
|
|
31
|
+
release(): Promise<void>;
|
|
32
|
+
releaseSession(sessionKey: SessionKey): Promise<boolean>;
|
|
33
|
+
}
|
|
34
|
+
export declare function buildStatefulOperationRequest<TInput>(metadata: StatefulProviderInvocationMetadata<TInput>): StatefulOperationRequest<TInput>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { StatefulSessionRouter, } from "./stateful-provider-session-routing.js";
|
|
2
|
+
export class StatefulProviderRuntimeExecutor {
|
|
3
|
+
#router;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.#router = new StatefulSessionRouter({
|
|
6
|
+
currentPod: options.currentPod,
|
|
7
|
+
registry: options.registry,
|
|
8
|
+
forwarder: options.forwarder,
|
|
9
|
+
executor: options.executor,
|
|
10
|
+
leaseDurationMs: options.leaseDurationMs,
|
|
11
|
+
...(options.leaseRenewalFraction !== undefined
|
|
12
|
+
? { leaseRenewalFraction: options.leaseRenewalFraction }
|
|
13
|
+
: {}),
|
|
14
|
+
...(options.clock ? { clock: options.clock } : {}),
|
|
15
|
+
...(options.metricEmitter ? { metricEmitter: options.metricEmitter } : {}),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
invoke(request) {
|
|
19
|
+
return this.#router.route(request);
|
|
20
|
+
}
|
|
21
|
+
release() {
|
|
22
|
+
return this.#router.release();
|
|
23
|
+
}
|
|
24
|
+
releaseSession(sessionKey) {
|
|
25
|
+
return this.#router.releaseSession(sessionKey);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function buildStatefulOperationRequest(metadata) {
|
|
29
|
+
requireNonEmpty(metadata.requestId, "requestId");
|
|
30
|
+
requireNonEmpty(metadata.sessionKey, "sessionKey");
|
|
31
|
+
requireNonEmpty(metadata.providerId, "providerId");
|
|
32
|
+
requireNonEmpty(metadata.operationId, "operationId");
|
|
33
|
+
requireNonEmpty(metadata.connectionId, "connectionId");
|
|
34
|
+
requireNonEmpty(metadata.serviceAccountId, "serviceAccountId");
|
|
35
|
+
return {
|
|
36
|
+
requestId: metadata.requestId,
|
|
37
|
+
sessionKey: metadata.sessionKey,
|
|
38
|
+
providerId: metadata.providerId,
|
|
39
|
+
operationId: metadata.operationId,
|
|
40
|
+
connectionId: metadata.connectionId,
|
|
41
|
+
serviceAccountId: metadata.serviceAccountId,
|
|
42
|
+
input: metadata.input,
|
|
43
|
+
...(metadata.idempotencyKey ? { idempotencyKey: metadata.idempotencyKey } : {}),
|
|
44
|
+
...(metadata.deadlineAt ? { deadlineAt: metadata.deadlineAt } : {}),
|
|
45
|
+
...(metadata.runtimeContext !== undefined ? { runtimeContext: metadata.runtimeContext } : {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function requireNonEmpty(value, field) {
|
|
49
|
+
if (value.trim().length === 0) {
|
|
50
|
+
throw new Error(`Stateful provider invocation ${field} is required.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { SessionKey } from "./session-key.js";
|
|
2
|
+
import { type StatefulProviderMetricEmitter } from "./stateful-provider-observability.js";
|
|
3
|
+
import type { SessionOwnerRecord, SessionOwnerRegistry, SessionOwnerStatus } from "./stateful-provider-session-runtime.js";
|
|
4
|
+
export { forwardingContextFromStatefulRuntimeContext, isStatefulOperationRuntimeContext, providerContextFromStatefulRuntimeContext, type StatefulForwardingRuntimeContext, type StatefulLocalRuntimeContext, type StatefulOperationRuntimeContext, statefulForwardingContextFromProviderRequest, withStatefulLocalProviderContext, } from "./stateful-provider-runtime-context.js";
|
|
5
|
+
export interface StatefulOperationRequest<TInput = unknown> {
|
|
6
|
+
readonly requestId: string;
|
|
7
|
+
readonly sessionKey: SessionKey;
|
|
8
|
+
readonly providerId: string;
|
|
9
|
+
readonly operationId: string;
|
|
10
|
+
readonly connectionId: string;
|
|
11
|
+
readonly serviceAccountId: string;
|
|
12
|
+
readonly input: TInput;
|
|
13
|
+
readonly idempotencyKey?: string;
|
|
14
|
+
readonly deadlineAt?: string;
|
|
15
|
+
readonly runtimeContext?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface StatefulOperationResult<TOutput = unknown> {
|
|
18
|
+
readonly output: TOutput;
|
|
19
|
+
}
|
|
20
|
+
export interface StatefulOwnerPod {
|
|
21
|
+
readonly podId: string;
|
|
22
|
+
readonly endpoint: string;
|
|
23
|
+
}
|
|
24
|
+
export interface StatefulOperationExecutor<_TSession = unknown> {
|
|
25
|
+
executeLocal(request: StatefulOperationRequest, owner: SessionOwnerRecord, signal: AbortSignal, validateOwnership?: StatefulOwnershipValidator): Promise<StatefulOperationResult>;
|
|
26
|
+
}
|
|
27
|
+
export type StatefulOwnershipValidator = (owner: SessionOwnerRecord, signal: AbortSignal) => Promise<SessionOwnerRecord>;
|
|
28
|
+
export interface StatefulOwnerForwarder {
|
|
29
|
+
forward(owner: SessionOwnerRecord, request: StatefulOperationRequest, signal: AbortSignal): Promise<StatefulOperationResult>;
|
|
30
|
+
}
|
|
31
|
+
export interface StatefulSessionRouterOptions {
|
|
32
|
+
readonly currentPod: StatefulOwnerPod;
|
|
33
|
+
readonly registry: SessionOwnerRegistry;
|
|
34
|
+
readonly forwarder: StatefulOwnerForwarder;
|
|
35
|
+
readonly executor: StatefulOperationExecutor;
|
|
36
|
+
readonly leaseDurationMs: number;
|
|
37
|
+
readonly leaseRenewalFraction?: number;
|
|
38
|
+
/** @deprecated Acquired sessions always begin in the acquiring state. */
|
|
39
|
+
readonly ownerStatus?: Exclude<SessionOwnerStatus, "expired">;
|
|
40
|
+
readonly clock?: () => Date;
|
|
41
|
+
readonly metricEmitter?: StatefulProviderMetricEmitter;
|
|
42
|
+
}
|
|
43
|
+
export { StatefulRoutingDeadlineError } from "./errors.js";
|
|
44
|
+
export declare class StatefulRoutingOwnershipError extends Error {
|
|
45
|
+
readonly requestId: string;
|
|
46
|
+
readonly sessionKey: SessionKey;
|
|
47
|
+
constructor(requestId: string, sessionKey: SessionKey, message: string);
|
|
48
|
+
}
|
|
49
|
+
export declare class StatefulSessionRouter {
|
|
50
|
+
#private;
|
|
51
|
+
constructor(options: StatefulSessionRouterOptions);
|
|
52
|
+
route<TInput = unknown>(request: StatefulOperationRequest<TInput>): Promise<StatefulOperationResult>;
|
|
53
|
+
release(): Promise<void>;
|
|
54
|
+
releaseSession(sessionKey: SessionKey): Promise<boolean>;
|
|
55
|
+
/** @internal Test-only visibility into local-attempt lifecycle cleanup. */
|
|
56
|
+
get latestLocalAttemptCountForTesting(): number;
|
|
57
|
+
private prepareRouteToOwner;
|
|
58
|
+
private routeToOwner;
|
|
59
|
+
private ensureManagedLease;
|
|
60
|
+
private scheduleRenewal;
|
|
61
|
+
private renewManagedLease;
|
|
62
|
+
private validateLocalOwnership;
|
|
63
|
+
private forgetManagedLease;
|
|
64
|
+
private releaseFailedEstablishment;
|
|
65
|
+
private runEstablishmentTask;
|
|
66
|
+
private stopManagedLease;
|
|
67
|
+
}
|