@lostgradient/weft 0.2.1 → 0.4.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 +123 -43
- package/dist/cli/conformance.js +7 -1
- package/dist/cli/generated/operation-client.generated.d.ts +55 -13
- package/dist/cli/generated/operation-client.generated.js +3 -0
- package/dist/cli/help-text.d.ts +1 -1
- package/dist/cli/help-text.js +1 -0
- package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
- package/dist/cli/operation-catalog-snapshot.js +11 -0
- package/dist/cli/parse-schedule-arguments.js +3 -1
- package/dist/cli/schedule.js +2 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli-main.js +80 -79
- package/dist/client/handle-delegation.d.ts +7 -2
- package/dist/client/handle-delegation.js +9 -1
- package/dist/client/http-client-requests.d.ts +4 -1
- package/dist/client/http-client-requests.js +10 -0
- package/dist/client/http-client.d.ts +10 -4
- package/dist/client/http-client.js +18 -1
- package/dist/client/http-request.d.ts +11 -1
- package/dist/client/http-request.js +17 -7
- package/dist/client/index.d.ts +1 -1
- package/dist/client/interface.d.ts +100 -4
- package/dist/client/local.d.ts +7 -1
- package/dist/client/local.js +17 -2
- package/dist/client/start-body.d.ts +9 -2
- package/dist/client/start-body.js +13 -4
- package/dist/core/byte-arrays.d.ts +5 -0
- package/dist/core/byte-arrays.js +5 -0
- package/dist/core/checkpoint/lifecycle.d.ts +3 -0
- package/dist/core/checkpoint/lifecycle.js +9 -4
- package/dist/core/checkpoint/serialization.js +12 -5
- package/dist/core/codec/extension-codec.d.ts +16 -0
- package/dist/core/codec/extension-codec.js +104 -8
- package/dist/core/codec/index.d.ts +1 -0
- package/dist/core/codec/index.js +1 -0
- package/dist/core/codec/serializer-registry.d.ts +122 -0
- package/dist/core/codec/serializer-registry.js +51 -0
- package/dist/core/context/activity-retry-state.d.ts +38 -0
- package/dist/core/context/activity-retry-state.js +89 -0
- package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
- package/dist/core/context/activity-schedule-to-close.js +69 -0
- package/dist/core/context/child-workflow-pipe.d.ts +5 -5
- package/dist/core/context/child-workflow-pipe.js +15 -2
- package/dist/core/context/context-presence.d.ts +19 -0
- package/dist/core/context/context-presence.js +13 -0
- package/dist/core/context/durable-operations.d.ts +25 -0
- package/dist/core/context/durable-operations.js +64 -0
- package/dist/core/context/index.d.ts +18 -5
- package/dist/core/context/index.js +17 -12
- package/dist/core/context/internals.d.ts +29 -0
- package/dist/core/context/internals.js +6 -1
- package/dist/core/context/operation-request.d.ts +35 -0
- package/dist/core/context/parallel-cache-entry.d.ts +14 -5
- package/dist/core/context/run-operation.d.ts +21 -3
- package/dist/core/context/run-operation.js +56 -93
- package/dist/core/context/session-state.js +7 -8
- package/dist/core/context/speculative-child.js +2 -0
- package/dist/core/context/types.d.ts +15 -0
- package/dist/core/context/version-patching.d.ts +8 -0
- package/dist/core/context/version-patching.js +40 -0
- package/dist/core/context/workflow-logger.d.ts +98 -0
- package/dist/core/context/workflow-logger.js +68 -0
- package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
- package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
- package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
- package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +12 -1
- package/dist/core/engine/activity-resolution.d.ts +23 -0
- package/dist/core/engine/activity-resolution.js +37 -0
- package/dist/core/engine/aggregate.js +66 -30
- package/dist/core/engine/async-activity-completion.d.ts +23 -6
- package/dist/core/engine/async-activity-completion.js +53 -12
- package/dist/core/engine/attributes-tags.js +9 -4
- package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
- package/dist/core/engine/bulk-operations-purge.js +38 -3
- package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
- package/dist/core/engine/bulk-operations-shared.js +8 -2
- package/dist/core/engine/bulk-operations.d.ts +4 -1
- package/dist/core/engine/bulk-operations.js +235 -24
- package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
- package/dist/core/engine/callback-creators-bundles.js +30 -2
- package/dist/core/engine/callback-creators-core.js +6 -4
- package/dist/core/engine/callback-creators-router.js +10 -0
- package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
- package/dist/core/engine/callback-creators-schedule.js +12 -8
- package/dist/core/engine/candidate-read-batching.d.ts +6 -0
- package/dist/core/engine/candidate-read-batching.js +1 -0
- package/dist/core/engine/checkpoint-io.js +61 -25
- package/dist/core/engine/checkpoint-reads.js +3 -2
- package/dist/core/engine/checkpoint-replay.d.ts +20 -0
- package/dist/core/engine/checkpoint-replay.js +242 -0
- package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
- package/dist/core/engine/checkpoint-side-effects.js +35 -0
- package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
- package/dist/core/engine/child-workflow-cancellation.js +40 -0
- package/dist/core/engine/child-workflow.js +27 -4
- package/dist/core/engine/condition-waiters.d.ts +14 -0
- package/dist/core/engine/condition-waiters.js +5 -0
- package/dist/core/engine/construction.d.ts +3 -1
- package/dist/core/engine/construction.js +30 -8
- package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
- package/dist/core/engine/coordination-branch-executors.js +107 -0
- package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
- package/dist/core/engine/deferred-consume-envelope.js +14 -0
- package/dist/core/engine/disposal.js +25 -0
- package/dist/core/engine/engine-create-types.d.ts +14 -18
- package/dist/core/engine/engine-internal-types.d.ts +38 -3
- package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
- package/dist/core/engine/engine-leak-warnings.js +4 -0
- package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
- package/dist/core/engine/engine-runtime-helpers.js +26 -5
- package/dist/core/engine/errors.d.ts +121 -0
- package/dist/core/engine/errors.js +45 -1
- package/dist/core/engine/event-log-compaction.d.ts +8 -0
- package/dist/core/engine/event-log-compaction.js +20 -2
- package/dist/core/engine/fenced-write.d.ts +65 -0
- package/dist/core/engine/fenced-write.js +71 -0
- package/dist/core/engine/finalizer-state.d.ts +28 -0
- package/dist/core/engine/finalizer-state.js +16 -0
- package/dist/core/engine/handle-result.js +1 -1
- package/dist/core/engine/handles.d.ts +97 -40
- package/dist/core/engine/handles.js +25 -27
- package/dist/core/engine/index.d.ts +125 -15
- package/dist/core/engine/index.js +207 -11
- package/dist/core/engine/inline-launch-queue.d.ts +14 -0
- package/dist/core/engine/inline-launch-queue.js +32 -7
- package/dist/core/engine/inline-parking.js +3 -2
- package/dist/core/engine/internals.d.ts +125 -13
- package/dist/core/engine/lease-codec.d.ts +35 -0
- package/dist/core/engine/lease-codec.js +32 -0
- package/dist/core/engine/lease-deposition.d.ts +66 -0
- package/dist/core/engine/lease-deposition.js +10 -0
- package/dist/core/engine/lease-errors.d.ts +99 -0
- package/dist/core/engine/lease-errors.js +30 -0
- package/dist/core/engine/lease-manager.d.ts +114 -0
- package/dist/core/engine/lease-manager.js +135 -0
- package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
- package/dist/core/engine/lifecycle/persist.js +15 -52
- package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
- package/dist/core/engine/lifecycle/recovered-services.js +18 -3
- package/dist/core/engine/lifecycle/resume.js +39 -11
- package/dist/core/engine/lifecycle/shared.d.ts +8 -1
- package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
- package/dist/core/engine/lifecycle/start-batch.js +2 -1
- package/dist/core/engine/lifecycle/start-commit.d.ts +56 -0
- package/dist/core/engine/lifecycle/start-commit.js +69 -0
- package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
- package/dist/core/engine/lifecycle/start-exec.js +38 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
- package/dist/core/engine/lifecycle/start-or-signal.d.ts +46 -0
- package/dist/core/engine/lifecycle/start-or-signal.js +71 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
- package/dist/core/engine/lifecycle/start.d.ts +6 -6
- package/dist/core/engine/lifecycle/start.js +47 -45
- package/dist/core/engine/lifecycle/transition.js +17 -5
- package/dist/core/engine/lifecycle.d.ts +3 -2
- package/dist/core/engine/lifecycle.js +9 -2
- package/dist/core/engine/list-candidate-resolution.js +2 -2
- package/dist/core/engine/listing.js +10 -6
- package/dist/core/engine/operations-activity.d.ts +4 -11
- package/dist/core/engine/operations-activity.js +22 -49
- package/dist/core/engine/operations-coordination.d.ts +10 -0
- package/dist/core/engine/operations-coordination.js +43 -8
- package/dist/core/engine/operations-router.d.ts +6 -0
- package/dist/core/engine/operations-router.js +2 -0
- package/dist/core/engine/operations-speculate.js +6 -2
- package/dist/core/engine/operations-stream.js +12 -2
- package/dist/core/engine/operations-time.d.ts +4 -2
- package/dist/core/engine/operations-time.js +14 -2
- package/dist/core/engine/operations-wait-condition.d.ts +23 -0
- package/dist/core/engine/operations-wait-condition.js +62 -0
- package/dist/core/engine/ownership-options.d.ts +23 -0
- package/dist/core/engine/ownership-options.js +26 -0
- package/dist/core/engine/payload-size-policy.d.ts +3 -0
- package/dist/core/engine/payload-size-policy.js +4 -0
- package/dist/core/engine/pending-updates.d.ts +17 -0
- package/dist/core/engine/pending-updates.js +33 -11
- package/dist/core/engine/persisted-data-version.d.ts +5 -9
- package/dist/core/engine/persisted-data-version.js +4 -5
- package/dist/core/engine/queries.js +1 -1
- package/dist/core/engine/registration.d.ts +1 -0
- package/dist/core/engine/registration.js +18 -3
- package/dist/core/engine/schedule-handle.d.ts +45 -0
- package/dist/core/engine/schedule-handle.js +26 -0
- package/dist/core/engine/schedule-jitter.d.ts +5 -0
- package/dist/core/engine/schedule-jitter.js +10 -0
- package/dist/core/engine/schedule-run.d.ts +17 -0
- package/dist/core/engine/schedule-run.js +38 -0
- package/dist/core/engine/schedule-timer.js +81 -17
- package/dist/core/engine/schedules.d.ts +8 -5
- package/dist/core/engine/schedules.js +44 -19
- package/dist/core/engine/search-attribute-records.d.ts +4 -0
- package/dist/core/engine/search-attribute-records.js +17 -0
- package/dist/core/engine/second-instance-detector.d.ts +96 -0
- package/dist/core/engine/second-instance-detector.js +108 -0
- package/dist/core/engine/signals.d.ts +38 -0
- package/dist/core/engine/signals.js +55 -19
- package/dist/core/engine/state-utilities.d.ts +49 -2
- package/dist/core/engine/state-utilities.js +114 -3
- package/dist/core/engine/storage-io.d.ts +16 -2
- package/dist/core/engine/storage-io.js +26 -5
- package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
- package/dist/core/engine/stream-chunk-loading.js +24 -1
- package/dist/core/engine/sub-operation.js +22 -3
- package/dist/core/engine/termination/cleanup.d.ts +28 -1
- package/dist/core/engine/termination/cleanup.js +44 -2
- package/dist/core/engine/termination/complete.js +48 -9
- package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
- package/dist/core/engine/termination/finalizer-activity.js +30 -0
- package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
- package/dist/core/engine/termination/finalizer-claim.js +80 -0
- package/dist/core/engine/termination/finalizer.d.ts +48 -0
- package/dist/core/engine/termination/finalizer.js +159 -0
- package/dist/core/engine/termination/suspend.d.ts +70 -0
- package/dist/core/engine/termination/suspend.js +41 -0
- package/dist/core/engine/termination.d.ts +5 -2
- package/dist/core/engine/termination.js +6 -0
- package/dist/core/engine/updates.js +5 -25
- package/dist/core/engine/validation/schedule.d.ts +2 -1
- package/dist/core/engine/validation/schedule.js +51 -2
- package/dist/core/engine/validation.js +54 -3
- package/dist/core/engine/waiting-update-response.d.ts +8 -0
- package/dist/core/engine/waiting-update-response.js +22 -0
- package/dist/core/engine/workflow-concurrency.d.ts +10 -0
- package/dist/core/engine/workflow-concurrency.js +136 -0
- package/dist/core/engine/workflow-feed.d.ts +9 -8
- package/dist/core/engine/workflow-feed.js +4 -1
- package/dist/core/engine/workflow-indexes.d.ts +9 -0
- package/dist/core/engine/workflow-indexes.js +10 -0
- package/dist/core/engine/workflow-state-stream.js +33 -13
- package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
- package/dist/core/engine-helpers.js +1 -0
- package/dist/core/events/activity-events.d.ts +43 -12
- package/dist/core/events/activity-events.js +28 -0
- package/dist/core/events/attribute-events.d.ts +2 -3
- package/dist/core/events/event-map.d.ts +19 -12
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -0
- package/dist/core/events/schedule-events.d.ts +71 -0
- package/dist/core/events/schedule-events.js +29 -0
- package/dist/core/events/signal-events.d.ts +4 -6
- package/dist/core/events/system-events.d.ts +29 -19
- package/dist/core/events/system-events.js +26 -0
- package/dist/core/events/update-events.d.ts +6 -8
- package/dist/core/events/workflow-events.d.ts +108 -20
- package/dist/core/events/workflow-events.js +35 -0
- package/dist/core/failure-categories.js +5 -17
- package/dist/core/fault-code.d.ts +9 -3
- package/dist/core/fault-code.js +1 -0
- package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
- package/dist/core/inline-execution-strategy.context-options.js +56 -0
- package/dist/core/inline-execution-strategy.d.ts +31 -36
- package/dist/core/inline-execution-strategy.js +16 -27
- package/dist/core/list-filter-validation.d.ts +1 -1
- package/dist/core/list-filter-validation.js +2 -1
- package/dist/core/payload-size.d.ts +1 -1
- package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
- package/dist/core/review/events.d.ts +6 -8
- package/dist/core/scheduler/scheduler-class.d.ts +10 -1
- package/dist/core/scheduler/scheduler-class.js +38 -11
- package/dist/core/scheduler/timer-batch.js +9 -1
- package/dist/core/scheduler/timer-sources.d.ts +1 -0
- package/dist/core/scheduler/timer-sources.js +11 -5
- package/dist/core/session-state.d.ts +0 -1
- package/dist/core/session-state.js +2 -2
- package/dist/core/start-workflow-validation.d.ts +56 -0
- package/dist/core/start-workflow-validation.js +30 -1
- package/dist/core/step-context.d.ts +10 -6
- package/dist/core/step-context.js +7 -15
- package/dist/core/types/activity-verification.d.ts +67 -0
- package/dist/core/types/activity-verification.js +0 -0
- package/dist/core/types/activity.d.ts +86 -64
- package/dist/core/types/bulk.d.ts +50 -9
- package/dist/core/types/checkpoint.d.ts +44 -8
- package/dist/core/types/identity.d.ts +8 -1
- package/dist/core/types/launch-metadata.d.ts +33 -0
- package/dist/core/types/launch-metadata.js +0 -0
- package/dist/core/types/list-options.d.ts +146 -0
- package/dist/core/types/list-options.js +0 -0
- package/dist/core/types/message-handles.d.ts +25 -0
- package/dist/core/types/options.d.ts +165 -215
- package/dist/core/types/reviews.d.ts +2 -1
- package/dist/core/types/schedules.d.ts +39 -3
- package/dist/core/types/services-resolution.d.ts +47 -0
- package/dist/core/types/services-resolution.js +0 -0
- package/dist/core/types/state.d.ts +11 -11
- package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
- package/dist/core/types/workflow-builder-runtime.js +11 -2
- package/dist/core/types/workflow-builder.d.ts +47 -15
- package/dist/core/types/workflow-concurrency.d.ts +39 -0
- package/dist/core/types/workflow-concurrency.js +0 -0
- package/dist/core/types/workflow-context.d.ts +157 -14
- package/dist/core/types/workflow-definition.d.ts +53 -10
- package/dist/core/types/workflow-function.d.ts +101 -9
- package/dist/core/types/workflow-log.d.ts +98 -0
- package/dist/core/types/workflow-log.js +0 -0
- package/dist/core/types/workflow-registries.d.ts +14 -3
- package/dist/core/types/workflow-registry.d.ts +3 -0
- package/dist/core/types/workflow-snapshot.d.ts +29 -0
- package/dist/core/types/workflow-snapshot.js +0 -0
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.js +7 -0
- package/dist/core/versioning.d.ts +9 -39
- package/dist/core/versioning.js +2 -12
- package/dist/core/weft-error.d.ts +44 -1
- package/dist/core/weft-error.js +19 -1
- package/dist/core/worker-execution-strategy-options.d.ts +26 -0
- package/dist/core/worker-execution-strategy.js +40 -36
- package/dist/core/worker-inbound-message.d.ts +38 -0
- package/dist/core/worker-inbound-message.js +37 -0
- package/dist/core/worker-log-abuse-counter.d.ts +175 -0
- package/dist/core/worker-log-abuse-counter.js +107 -0
- package/dist/core/worker-message-helpers.d.ts +47 -0
- package/dist/core/worker-message-helpers.js +26 -0
- package/dist/core/worker-protocol-guard.js +1 -1
- package/dist/core/worker-protocol-log.d.ts +56 -0
- package/dist/core/worker-protocol-log.js +18 -0
- package/dist/core/worker-protocol.d.ts +23 -0
- package/dist/core/worker-protocol.js +12 -2
- package/dist/core/workflow-version-tuple.d.ts +3 -9
- package/dist/core/workflow-version-tuple.js +2 -3
- package/dist/diagnostics/doctor.js +6 -3
- package/dist/diagnostics/format.js +3 -8
- package/dist/diagnostics/types.d.ts +5 -5
- package/dist/diagnostics/validate.d.ts +0 -1
- package/dist/diagnostics/version-check.d.ts +1 -1
- package/dist/diagnostics/version-check.js +10 -13
- package/dist/index.d.ts +13 -11
- package/dist/index.js +39 -4
- package/dist/json-schema.js +3 -3
- package/dist/mcp/cli.js +35 -35
- package/dist/mcp/dispatcher.js +1 -1
- package/dist/mcp/http.js +16 -6
- package/dist/mcp/list-filter.js +2 -1
- package/dist/mcp/protocol.d.ts +2 -0
- package/dist/mcp/protocol.js +1 -1
- package/dist/mcp/session.d.ts +16 -0
- package/dist/mcp/session.js +60 -6
- package/dist/mcp/tools.js +73 -6
- package/dist/observability/index.js +2 -2
- package/dist/server/asyncapi-channels.js +5 -2
- package/dist/server/attribute-filters.d.ts +8 -3
- package/dist/server/attribute-filters.js +6 -1
- package/dist/server/authentication/api-key.d.ts +2 -1
- package/dist/server/authentication/api-key.js +5 -2
- package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
- package/dist/server/authentication/constant-time-api-key.js +24 -0
- package/dist/server/authentication/index.d.ts +1 -1
- package/dist/server/authentication/index.js +7 -4
- package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
- package/dist/server/authentication/rotating-api-key-store.js +19 -11
- package/dist/server/engine-event-feed-backend.d.ts +4 -5
- package/dist/server/fault-to-http.js +8 -1
- package/dist/server/fault-to-json-rpc.js +1 -0
- package/dist/server/fleet-event-feed.d.ts +31 -0
- package/dist/server/fleet-event-feed.js +157 -0
- package/dist/server/handler/index.js +1 -1
- package/dist/server/handler/response-helpers.js +2 -1
- package/dist/server/handler/route-dispatch.d.ts +6 -3
- package/dist/server/handler/route-dispatch.js +2 -2
- package/dist/server/handler.js +31 -31
- package/dist/server/index.d.ts +32 -2
- package/dist/server/index.js +35 -35
- package/dist/server/interactive-operations.js +1 -0
- package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
- package/dist/server/json-rpc-transport-helpers.js +2 -1
- package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
- package/dist/server/json-rpc-websocket-runtime.js +1 -0
- package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
- package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
- package/dist/server/json-rpc-websocket-types.d.ts +22 -0
- package/dist/server/json-rpc-websocket-types.js +0 -0
- package/dist/server/json-rpc-websocket-validation.js +20 -4
- package/dist/server/json-rpc-websocket.d.ts +2 -43
- package/dist/server/json-rpc-websocket.js +57 -74
- package/dist/server/openapi.d.ts +2 -1
- package/dist/server/openapi.js +1 -3
- package/dist/server/openrpc-document-schema.d.ts +78 -0
- package/dist/server/openrpc-document-schema.js +27 -1
- package/dist/server/openrpc-errors.d.ts +3 -0
- package/dist/server/openrpc-errors.js +2 -1
- package/dist/server/openrpc.js +32 -0
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
- package/dist/server/operation-catalog/pipeline-stages.js +26 -12
- package/dist/server/operation-catalog/pipeline.js +8 -1
- package/dist/server/operation-catalog/registry.js +13 -0
- package/dist/server/operation-catalog/types.d.ts +20 -9
- package/dist/server/operation-fault.d.ts +10 -0
- package/dist/server/operation-fault.js +2 -0
- package/dist/server/operation-registry.d.ts +12 -11
- package/dist/server/operation-registry.js +12 -3
- package/dist/server/operations/aggregate-workflows.d.ts +15 -15
- package/dist/server/operations/async-activity.d.ts +2 -2
- package/dist/server/operations/async-activity.js +12 -7
- package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-cancel-workflows.js +2 -2
- package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-delete-workflows.js +2 -2
- package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
- package/dist/server/operations/bulk-filter-helpers.js +54 -24
- package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
- package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
- package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
- package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
- package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
- package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
- package/dist/server/operations/bulk-signal-workflows.js +2 -2
- package/dist/server/operations/cancel-schedule.d.ts +1 -1
- package/dist/server/operations/create-schedule.d.ts +3 -1
- package/dist/server/operations/create-schedule.js +29 -11
- package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
- package/dist/server/operations/fleet-events-subscription.js +99 -0
- package/dist/server/operations/fork-workflow.d.ts +1 -1
- package/dist/server/operations/fork-workflow.js +3 -2
- package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
- package/dist/server/operations/get-registry.d.ts +1 -1
- package/dist/server/operations/get-retention-overview.d.ts +1 -1
- package/dist/server/operations/get-review.d.ts +1 -1
- package/dist/server/operations/get-schedule.d.ts +1 -1
- package/dist/server/operations/get-stream-chunks.d.ts +1 -1
- package/dist/server/operations/get-system-metrics.d.ts +2 -2
- package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
- package/dist/server/operations/get-task-diagnostics.js +101 -7
- package/dist/server/operations/get-update-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/get-workflow-events.d.ts +1 -1
- package/dist/server/operations/get-workflow-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
- package/dist/server/operations/get-workflow.d.ts +1 -1
- package/dist/server/operations/list-checkpoints.d.ts +1 -1
- package/dist/server/operations/list-reviews.d.ts +1 -1
- package/dist/server/operations/list-schedules.d.ts +1 -1
- package/dist/server/operations/list-task-queues.d.ts +2 -2
- package/dist/server/operations/list-workers.d.ts +2 -2
- package/dist/server/operations/list-workflows.d.ts +1 -1
- package/dist/server/operations/operation-helpers.d.ts +16 -1
- package/dist/server/operations/operation-helpers.js +15 -3
- package/dist/server/operations/pause-schedule.d.ts +1 -1
- package/dist/server/operations/purge-workflows.d.ts +5 -5
- package/dist/server/operations/purge-workflows.js +2 -2
- package/dist/server/operations/query-workflow.d.ts +1 -1
- package/dist/server/operations/query-workflow.js +3 -2
- package/dist/server/operations/recover-all.d.ts +1 -1
- package/dist/server/operations/replay-workflow.d.ts +1 -1
- package/dist/server/operations/resume-schedule.d.ts +1 -1
- package/dist/server/operations/resume-workflow.js +2 -2
- package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/set-workflow-attributes.js +6 -3
- package/dist/server/operations/signal-workflow.js +8 -3
- package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
- package/dist/server/operations/start-or-signal-workflow.d.ts +44 -0
- package/dist/server/operations/start-or-signal-workflow.js +130 -0
- package/dist/server/operations/start-workflow-options.d.ts +38 -0
- package/dist/server/operations/start-workflow-options.js +63 -0
- package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
- package/dist/server/operations/start-workflow-rest-input.js +31 -0
- package/dist/server/operations/start-workflow.d.ts +1 -1
- package/dist/server/operations/start-workflow.js +15 -92
- package/dist/server/operations/storage.d.ts +6 -6
- package/dist/server/operations/storage.js +24 -14
- package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.js +6 -3
- package/dist/server/operations/suspend-workflow.d.ts +13 -0
- package/dist/server/operations/suspend-workflow.js +36 -0
- package/dist/server/operations/update-schedule.d.ts +1 -1
- package/dist/server/operations/update-schedule.js +7 -4
- package/dist/server/operations/update-workflow.d.ts +1 -1
- package/dist/server/operations/update-workflow.js +7 -3
- package/dist/server/operations/worker-drain.d.ts +8 -8
- package/dist/server/operations/worker-drain.js +11 -8
- package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
- package/dist/server/operations/workflow-events-subscription.js +43 -8
- package/dist/server/rest-binding.d.ts +21 -8
- package/dist/server/rest-bindings.js +24 -0
- package/dist/server/rest-body.d.ts +10 -0
- package/dist/server/rest-body.js +80 -0
- package/dist/server/runtime/authentication-bridge.d.ts +1 -0
- package/dist/server/runtime/authentication-bridge.js +33 -6
- package/dist/server/runtime/client-visible-events.d.ts +3 -0
- package/dist/server/runtime/client-visible-events.js +65 -0
- package/dist/server/runtime/context.d.ts +7 -0
- package/dist/server/runtime/event-broadcasting.d.ts +6 -0
- package/dist/server/runtime/event-broadcasting.js +72 -38
- package/dist/server/runtime/retry.d.ts +1 -0
- package/dist/server/runtime/retry.js +14 -0
- package/dist/server/runtime/shutdown.d.ts +7 -6
- package/dist/server/runtime/shutdown.js +6 -1
- package/dist/server/runtime/task-dispatch.js +5 -3
- package/dist/server/runtime/task-polling.d.ts +16 -2
- package/dist/server/runtime/task-polling.js +80 -24
- package/dist/server/runtime/task-reconciliation.js +9 -1
- package/dist/server/runtime/task-result-resolution.d.ts +15 -0
- package/dist/server/runtime/task-result-resolution.js +81 -0
- package/dist/server/runtime/websocket-stream.d.ts +20 -1
- package/dist/server/runtime/websocket-stream.js +173 -7
- package/dist/server/runtime/websocket-upgrade.js +22 -3
- package/dist/server/runtime/websocket-worker.d.ts +1 -1
- package/dist/server/runtime/websocket-worker.js +46 -30
- package/dist/server/serve-internals.d.ts +11 -1
- package/dist/server/serve-internals.js +20 -2
- package/dist/server/task-state.d.ts +38 -0
- package/dist/server/task-state.js +28 -0
- package/dist/server/workflow-event-feed.d.ts +36 -115
- package/dist/server/workflow-event-feed.js +92 -27
- package/dist/service-worker/index.js +31 -31
- package/dist/storage/auto.js +1 -1
- package/dist/storage/bun-sql.js +24 -0
- package/dist/storage/capabilities.d.ts +10 -2
- package/dist/storage/capabilities.js +2 -2
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/default-scope.d.ts +7 -4
- package/dist/storage/http.js +2 -2
- package/dist/storage/index.d.ts +81 -4
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/interface.d.ts +189 -0
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +12 -0
- package/dist/storage/lmdb.d.ts +4 -3
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon-batch.d.ts +30 -0
- package/dist/storage/neon-batch.js +30 -0
- package/dist/storage/neon-value-mapping.d.ts +74 -0
- package/dist/storage/neon-value-mapping.js +23 -0
- package/dist/storage/neon.d.ts +124 -0
- package/dist/storage/neon.js +15 -0
- package/dist/storage/node-sqlite-loader.d.ts +71 -0
- package/dist/storage/node-sqlite-loader.js +41 -0
- package/dist/storage/node-sqlite.d.ts +1 -19
- package/dist/storage/node-sqlite.js +61 -32
- package/dist/storage/postgres-key-value-queries.d.ts +104 -0
- package/dist/storage/postgres-key-value-queries.js +101 -0
- package/dist/storage/resolve.d.ts +2 -165
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +209 -0
- package/dist/storage/storage-configuration.js +0 -0
- package/dist/storage/testing.d.ts +168 -0
- package/dist/storage/testing.js +2 -0
- package/dist/storage/text-value-store.d.ts +9 -9
- package/dist/storage/turso.d.ts +8 -0
- package/dist/storage/turso.js +2 -2
- package/dist/storage/typed-storage.js +1 -1
- package/dist/storage/web-extension.js +1 -1
- package/dist/testing/index.js +35 -35
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/index.js +9 -5
- package/dist/worker/long-poll.js +4 -0
- package/dist/worker/protocol-messages.d.ts +20 -0
- package/dist/worker/protocol-schemas.d.ts +32 -0
- package/dist/worker/protocol-schemas.js +8 -4
- package/dist/worker/protocol-task-result.d.ts +28 -0
- package/dist/worker/protocol-task-result.js +76 -0
- package/dist/worker/protocol.d.ts +4 -15
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/registry/fair-share.d.ts +29 -0
- package/dist/worker/registry/fair-share.js +30 -0
- package/dist/worker/registry/routing.d.ts +18 -0
- package/dist/worker/registry/routing.js +14 -0
- package/dist/worker/registry/types.d.ts +7 -0
- package/dist/worker/registry.d.ts +16 -1
- package/dist/worker/registry.js +24 -36
- package/dist/workers/worker-replay-state.d.ts +32 -0
- package/dist/workers/worker-replay-state.js +35 -0
- package/dist/workers/worker-state-namespace.d.ts +21 -0
- package/dist/workers/worker-state-namespace.js +13 -0
- package/dist/workers/workflow-runner.d.ts +19 -15
- package/dist/workers/workflow-runner.js +72 -60
- package/dist/workers/workflow-worker-entry.js +5 -2
- package/package.json +21 -4
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
2
|
+
function digestApiKey(key) {
|
|
3
|
+
return createHash("sha256").update(key, "utf8").digest();
|
|
4
|
+
}
|
|
5
|
+
export function createConstantTimeApiKeyEntry(key, value) {
|
|
6
|
+
return { digest: digestApiKey(key), value };
|
|
7
|
+
}
|
|
8
|
+
export function createConstantTimeApiKeyMatcher(keys) {
|
|
9
|
+
const entries = keys.map((entry) => typeof entry === "string" ? createConstantTimeApiKeyEntry(entry, void 0) : createConstantTimeApiKeyEntry(entry.key, entry.value));
|
|
10
|
+
return {
|
|
11
|
+
entries,
|
|
12
|
+
matches(presentedKey) {
|
|
13
|
+
return findConstantTimeApiKeyMatch(presentedKey, entries) !== null;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function findConstantTimeApiKeyMatch(presentedKey, entries) {
|
|
18
|
+
const presentedDigest = digestApiKey(presentedKey);
|
|
19
|
+
let matchedIndex = -1;
|
|
20
|
+
for (let index = 0;index < entries.length; index += 1)
|
|
21
|
+
if (timingSafeEqual(presentedDigest, entries[index].digest))
|
|
22
|
+
matchedIndex = index;
|
|
23
|
+
return matchedIndex === -1 ? null : entries[matchedIndex];
|
|
24
|
+
}
|
|
@@ -36,7 +36,7 @@ export declare function validateAuthConfig(config: AuthConfig): void;
|
|
|
36
36
|
*
|
|
37
37
|
* The returned function checks each configured method in order:
|
|
38
38
|
* 1. Public path bypass
|
|
39
|
-
* 2. API key (
|
|
39
|
+
* 2. API key (constant-time digest scan)
|
|
40
40
|
* 3. JWT (signature + claims verification)
|
|
41
41
|
* 4. mTLS (transport-level — any request that reaches the handler is authenticated)
|
|
42
42
|
*
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { tryAdmitApiKey } from "./api-key.js";
|
|
2
2
|
import { defaultAuthAuditSink, emitAuthAuditEvent } from "./audit.js";
|
|
3
|
+
import {
|
|
4
|
+
createConstantTimeApiKeyMatcher
|
|
5
|
+
} from "./constant-time-api-key.js";
|
|
3
6
|
import { importJWTKey, verifyJWT } from "./crypto.js";
|
|
4
7
|
import {
|
|
5
8
|
DEFAULT_PUBLIC_PATHS,
|
|
@@ -52,10 +55,10 @@ function assertNoConflictingMethods(config) {
|
|
|
52
55
|
throw Error("AuthConfig cannot combine resolveApiKeyPrincipal with jwt: the resolver consumes every Authorization: Bearer token before JWT verification, so the JWT method would be unreachable.");
|
|
53
56
|
}
|
|
54
57
|
async function authenticateViaApiKey(request, options) {
|
|
55
|
-
const presentedKey = extractApiKey(request), hasApiKeyPath = options.resolver !== void 0 || options.
|
|
58
|
+
const presentedKey = extractApiKey(request), hasApiKeyPath = options.resolver !== void 0 || options.apiKeyEntries !== null;
|
|
56
59
|
if (!presentedKey || !hasApiKeyPath)
|
|
57
60
|
return { explicitAuthAttempted: !1, result: null };
|
|
58
|
-
const result = await tryAdmitApiKey(presentedKey, options.resolver, options.
|
|
61
|
+
const result = await tryAdmitApiKey(presentedKey, options.resolver, options.apiKeyEntries, options.defaultApiKeyScopes);
|
|
59
62
|
return {
|
|
60
63
|
explicitAuthAttempted: !0,
|
|
61
64
|
result: result === "continue" ? null : result
|
|
@@ -83,13 +86,13 @@ export function validateAuthConfig(config) {
|
|
|
83
86
|
}
|
|
84
87
|
export async function createAuthenticator(config) {
|
|
85
88
|
validateAuthConfig(config);
|
|
86
|
-
const
|
|
89
|
+
const apiKeyEntries = config.apiKeys?.length ? createConstantTimeApiKeyMatcher(config.apiKeys).entries : null, resolver = config.resolveApiKeyPrincipal, defaultApiKeyScopes = config.defaultApiKeyScopes ?? [], jwtKey = config.jwt ? await importJWTKey(config.jwt) : null, publicPaths = new Set(config.publicPaths ?? DEFAULT_PUBLIC_PATHS), auditSink = config.auditSink ?? defaultAuthAuditSink;
|
|
87
90
|
return async (request) => {
|
|
88
91
|
if (publicPaths.has(normalizeRequestPathname(request)))
|
|
89
92
|
return { authenticated: !0, method: "public" };
|
|
90
93
|
const apiKeyAttempt = await authenticateViaApiKey(request, {
|
|
91
94
|
resolver,
|
|
92
|
-
|
|
95
|
+
apiKeyEntries,
|
|
93
96
|
defaultApiKeyScopes
|
|
94
97
|
});
|
|
95
98
|
if (apiKeyAttempt.result !== null)
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
* authenticate. Each key may also carry an absolute `expiresAt`, after which it
|
|
16
16
|
* is rejected automatically without an explicit revoke.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Registration hashes stored keys to fixed-length digests once. Authentication
|
|
19
|
+
* lookups hash the presented key, then compare it with every stored digest via
|
|
20
|
+
* `timingSafeEqual` without early exit. The digest step avoids raw length
|
|
21
|
+
* checks, and scanning every digest avoids key-position leaks during the
|
|
22
|
+
* overlap window.
|
|
21
23
|
*
|
|
22
24
|
* @module server/authentication/rotating-api-key-store
|
|
23
25
|
*/
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
import { principalFromApiKey } from "../principal.js";
|
|
2
|
+
import {
|
|
3
|
+
createConstantTimeApiKeyEntry,
|
|
4
|
+
findConstantTimeApiKeyMatch
|
|
5
|
+
} from "./constant-time-api-key.js";
|
|
2
6
|
function isExpired(stored, currentTime) {
|
|
3
7
|
return stored.expiresAt !== void 0 && currentTime >= stored.expiresAt;
|
|
4
8
|
}
|
|
5
9
|
export function createRotatingApiKeyStore(now = Date.now) {
|
|
6
10
|
const keys = new Map;
|
|
11
|
+
function findStoredKey(presentedKey) {
|
|
12
|
+
return findConstantTimeApiKeyMatch(presentedKey, [...keys.values()])?.value ?? null;
|
|
13
|
+
}
|
|
7
14
|
return {
|
|
8
15
|
add(key, registration) {
|
|
9
16
|
if (key.length === 0)
|
|
10
17
|
throw Error("Cannot register an empty API key");
|
|
11
|
-
|
|
18
|
+
const stored = {
|
|
12
19
|
subject: registration.subject,
|
|
13
20
|
scopes: registration.scopes ?? [],
|
|
14
21
|
expiresAt: registration.expiresAt
|
|
15
|
-
}
|
|
22
|
+
};
|
|
23
|
+
keys.set(key, createConstantTimeApiKeyEntry(key, { key, stored }));
|
|
16
24
|
},
|
|
17
25
|
revoke(key) {
|
|
18
26
|
return keys.delete(key);
|
|
19
27
|
},
|
|
20
28
|
has(key) {
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
29
|
+
const match = findStoredKey(key);
|
|
30
|
+
if (match === null)
|
|
23
31
|
return !1;
|
|
24
|
-
if (isExpired(stored, now())) {
|
|
25
|
-
keys.delete(key);
|
|
32
|
+
if (isExpired(match.stored, now())) {
|
|
33
|
+
keys.delete(match.key);
|
|
26
34
|
return !1;
|
|
27
35
|
}
|
|
28
36
|
return !0;
|
|
@@ -31,13 +39,13 @@ export function createRotatingApiKeyStore(now = Date.now) {
|
|
|
31
39
|
return keys.size;
|
|
32
40
|
},
|
|
33
41
|
resolve(presentedKey) {
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
if (
|
|
37
|
-
keys.delete(
|
|
42
|
+
const match = findStoredKey(presentedKey);
|
|
43
|
+
if (match === null || isExpired(match.stored, now())) {
|
|
44
|
+
if (match !== null)
|
|
45
|
+
keys.delete(match.key);
|
|
38
46
|
return Promise.resolve(null);
|
|
39
47
|
}
|
|
40
|
-
return Promise.resolve(principalFromApiKey({ subject: stored.subject, scopes: stored.scopes }));
|
|
48
|
+
return Promise.resolve(principalFromApiKey({ subject: match.stored.subject, scopes: match.stored.scopes }));
|
|
41
49
|
}
|
|
42
50
|
};
|
|
43
51
|
}
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
* share the same source of truth — the unified
|
|
10
10
|
* `replayWorkflowFeed` / `snapshotWorkflowFeedTail` /
|
|
11
11
|
* `subscribeWorkflowFeedCommits` triple on `Engine`. The subscription
|
|
12
|
-
* fires only AFTER
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* replay-then-drain) relies on.
|
|
12
|
+
* fires only AFTER the storage commit resolves, so an event in the live buffer
|
|
13
|
+
* is already durable and scannable by `replayWorkflowFeed`. This is the
|
|
14
|
+
* invariant the feed's atomic-handoff (buffer-then-snapshot-then-replay-then-
|
|
15
|
+
* drain) relies on.
|
|
17
16
|
*
|
|
18
17
|
* The backend is intentionally stateless — it holds only the `Engine`
|
|
19
18
|
* reference. Listener state lives on the engine and is cleaned up by
|
|
@@ -18,7 +18,14 @@ function shapeTimeoutBody(base, data) {
|
|
|
18
18
|
return Object.keys(defined).length === 0 ? base : { ...base, data: defined };
|
|
19
19
|
}
|
|
20
20
|
function shapeNotFoundBody(base, data) {
|
|
21
|
-
|
|
21
|
+
const shaped = {
|
|
22
|
+
resource: data.resource
|
|
23
|
+
};
|
|
24
|
+
if (data.identifier !== void 0)
|
|
25
|
+
shaped.identifier = data.identifier;
|
|
26
|
+
if (data.weftCode !== void 0)
|
|
27
|
+
shaped.weftCode = data.weftCode;
|
|
28
|
+
return { ...base, data: shaped };
|
|
22
29
|
}
|
|
23
30
|
function filterDefined(input) {
|
|
24
31
|
const output = {};
|
|
@@ -19,6 +19,7 @@ const EMPTY = {}, FAULT_DATA_EXTRACTORS = {
|
|
|
19
19
|
Conflict: dataForConflict,
|
|
20
20
|
NotFound: dataForNotFound,
|
|
21
21
|
Timeout: dataForTimeout,
|
|
22
|
+
PayloadTooLarge: (data) => ({ maxBytes: data.maxBytes }),
|
|
22
23
|
UnsupportedTransport: dataForUnsupportedTransport,
|
|
23
24
|
SubscriptionOverflow: dataForSubscriptionOverflow,
|
|
24
25
|
InvalidParams: dataForInvalidParams,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Storage } from '../storage/interface.ts';
|
|
2
|
+
import { type Cursor, type FeedEventKind, type ReplayLiveSubscribeOptions, type WorkflowEventFeedOptions } from './workflow-event-feed.ts';
|
|
3
|
+
export type FleetEventEnvelope = {
|
|
4
|
+
readonly kind: FeedEventKind;
|
|
5
|
+
readonly workflowId?: string | undefined;
|
|
6
|
+
readonly sequence: number;
|
|
7
|
+
readonly cursor: Cursor;
|
|
8
|
+
readonly emittedAtMs: number;
|
|
9
|
+
readonly payload: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type FleetEventInput = {
|
|
12
|
+
readonly kind: FeedEventKind;
|
|
13
|
+
readonly workflowId?: string | undefined;
|
|
14
|
+
readonly emittedAtMs: number;
|
|
15
|
+
readonly payload: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type FleetWorkflowEventInput = FleetEventInput & {
|
|
18
|
+
readonly workflowId: string;
|
|
19
|
+
};
|
|
20
|
+
export type FleetEventFeed = {
|
|
21
|
+
append(event: FleetEventInput): Promise<FleetEventEnvelope>;
|
|
22
|
+
appendWorkflowEventIfPresent(event: FleetWorkflowEventInput): Promise<FleetEventEnvelope | null>;
|
|
23
|
+
replay(options?: {
|
|
24
|
+
fromCursor?: Cursor;
|
|
25
|
+
limit?: number;
|
|
26
|
+
}): AsyncIterable<FleetEventEnvelope>;
|
|
27
|
+
subscribe(options?: ReplayLiveSubscribeOptions<FleetEventEnvelope>): AsyncIterable<FleetEventEnvelope>;
|
|
28
|
+
snapshotTailSequence(): Promise<number>;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
};
|
|
31
|
+
export declare function createFleetEventFeed(storage: Storage, feedOptions?: WorkflowEventFeedOptions): FleetEventFeed;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { decode, encode } from "../core/codec.js";
|
|
2
|
+
import {
|
|
3
|
+
KEYS,
|
|
4
|
+
storageConditionalBatch
|
|
5
|
+
} from "../storage/interface.js";
|
|
6
|
+
import {
|
|
7
|
+
createReplayLiveFeed,
|
|
8
|
+
decodeCursor,
|
|
9
|
+
encodeCursor
|
|
10
|
+
} from "./workflow-event-feed.js";
|
|
11
|
+
const MAX_WORKFLOW_OWNED_APPEND_ATTEMPTS = 5;
|
|
12
|
+
export function createFleetEventFeed(storage, feedOptions) {
|
|
13
|
+
const listeners = new Set;
|
|
14
|
+
let sequenceInitPromise = null, nextSequence = null, appendChain = Promise.resolve();
|
|
15
|
+
const replayLiveFeed = createReplayLiveFeed({
|
|
16
|
+
replay: replayPersistedFleetEvents,
|
|
17
|
+
snapshotTailSequence,
|
|
18
|
+
subscribeLive
|
|
19
|
+
}, feedOptions);
|
|
20
|
+
async function initializeNextSequence() {
|
|
21
|
+
if (nextSequence !== null)
|
|
22
|
+
return nextSequence;
|
|
23
|
+
if (sequenceInitPromise)
|
|
24
|
+
return sequenceInitPromise;
|
|
25
|
+
sequenceInitPromise = snapshotTailSequence().then((tailSequence) => {
|
|
26
|
+
nextSequence = tailSequence + 1;
|
|
27
|
+
return nextSequence;
|
|
28
|
+
}).catch((error) => {
|
|
29
|
+
sequenceInitPromise = null;
|
|
30
|
+
throw error;
|
|
31
|
+
});
|
|
32
|
+
return sequenceInitPromise;
|
|
33
|
+
}
|
|
34
|
+
async function append(event) {
|
|
35
|
+
return appendInternal(event);
|
|
36
|
+
}
|
|
37
|
+
async function appendWorkflowEventIfPresent(event) {
|
|
38
|
+
return appendInternal(event, async () => {
|
|
39
|
+
const workflowValue = await storage.get(KEYS.workflow(event.workflowId));
|
|
40
|
+
if (workflowValue === null)
|
|
41
|
+
return null;
|
|
42
|
+
return [{ key: KEYS.workflow(event.workflowId), expectedValue: workflowValue }];
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function appendInternal(event, loadConditions) {
|
|
46
|
+
const appended = appendChain.then(async () => {
|
|
47
|
+
for (let attempt = 1;attempt <= MAX_WORKFLOW_OWNED_APPEND_ATTEMPTS; attempt += 1) {
|
|
48
|
+
const conditions = loadConditions === void 0 ? void 0 : await loadConditions();
|
|
49
|
+
if (conditions === null)
|
|
50
|
+
return null;
|
|
51
|
+
const sequence = await initializeNextSequence(), envelope = {
|
|
52
|
+
kind: event.kind,
|
|
53
|
+
sequence,
|
|
54
|
+
cursor: encodeCursor(sequence),
|
|
55
|
+
emittedAtMs: event.emittedAtMs,
|
|
56
|
+
...event.workflowId !== void 0 ? { workflowId: event.workflowId } : {},
|
|
57
|
+
payload: event.payload
|
|
58
|
+
}, operations = [
|
|
59
|
+
{ type: "put", key: KEYS.fleetEvent(sequence), value: encode(envelope) },
|
|
60
|
+
{ type: "put", key: KEYS.fleetEventTail(), value: encode({ sequence }) }
|
|
61
|
+
];
|
|
62
|
+
if (event.workflowId !== void 0)
|
|
63
|
+
operations.push({
|
|
64
|
+
type: "put",
|
|
65
|
+
key: KEYS.fleetEventByWorkflow(event.workflowId, sequence),
|
|
66
|
+
value: new Uint8Array
|
|
67
|
+
});
|
|
68
|
+
if (conditions === void 0)
|
|
69
|
+
await storage.batch(operations);
|
|
70
|
+
else if (!await storageConditionalBatch(storage, [...conditions], operations))
|
|
71
|
+
continue;
|
|
72
|
+
nextSequence = sequence + 1;
|
|
73
|
+
fireLive(envelope);
|
|
74
|
+
return envelope;
|
|
75
|
+
}
|
|
76
|
+
throw Error(`Fleet event append for workflow "${event.workflowId ?? "<none>"}" lost its storage precondition after ${MAX_WORKFLOW_OWNED_APPEND_ATTEMPTS} attempts.`);
|
|
77
|
+
});
|
|
78
|
+
appendChain = appended.then(() => {
|
|
79
|
+
return;
|
|
80
|
+
}, () => {
|
|
81
|
+
return;
|
|
82
|
+
});
|
|
83
|
+
return appended;
|
|
84
|
+
}
|
|
85
|
+
async function* replayPersistedFleetEvents(options) {
|
|
86
|
+
const scanOptions = options.afterSequence >= 0 ? { gt: KEYS.fleetEvent(options.afterSequence) } : void 0;
|
|
87
|
+
for await (const [key, value] of storage.scan(KEYS.fleetEventPrefix(), scanOptions)) {
|
|
88
|
+
const sequence = parseFleetEventSequenceFromKey(key);
|
|
89
|
+
if (sequence === null || sequence <= options.afterSequence)
|
|
90
|
+
continue;
|
|
91
|
+
const decoded = decodeStorageValue(value);
|
|
92
|
+
if (!isFleetEventEnvelope(decoded))
|
|
93
|
+
continue;
|
|
94
|
+
yield decoded;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function snapshotTailSequence() {
|
|
98
|
+
const storedTail = await storage.get(KEYS.fleetEventTail()), decodedTail = storedTail === null ? null : decodeStorageValue(storedTail);
|
|
99
|
+
if (isTailRecord(decodedTail))
|
|
100
|
+
return decodedTail.sequence;
|
|
101
|
+
for await (const [key] of storage.scan(KEYS.fleetEventPrefix(), { reverse: !0 })) {
|
|
102
|
+
const sequence = parseFleetEventSequenceFromKey(key);
|
|
103
|
+
if (sequence !== null)
|
|
104
|
+
return sequence;
|
|
105
|
+
}
|
|
106
|
+
return -1;
|
|
107
|
+
}
|
|
108
|
+
function subscribeLive(listener) {
|
|
109
|
+
listeners.add(listener);
|
|
110
|
+
return () => {
|
|
111
|
+
listeners.delete(listener);
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function fireLive(envelope) {
|
|
115
|
+
const listenerSnapshot = Array.from(listeners);
|
|
116
|
+
for (const listener of listenerSnapshot)
|
|
117
|
+
try {
|
|
118
|
+
listener(envelope);
|
|
119
|
+
} catch {}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
append,
|
|
123
|
+
appendWorkflowEventIfPresent,
|
|
124
|
+
replay: (options) => replayLiveFeed.replay(options),
|
|
125
|
+
subscribe: (options) => replayLiveFeed.subscribe(options),
|
|
126
|
+
snapshotTailSequence,
|
|
127
|
+
dispose() {
|
|
128
|
+
listeners.clear();
|
|
129
|
+
replayLiveFeed.dispose();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function decodeStorageValue(value) {
|
|
134
|
+
try {
|
|
135
|
+
return decode(value);
|
|
136
|
+
} catch {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function parseFleetEventSequenceFromKey(key) {
|
|
141
|
+
if (!key.startsWith(KEYS.fleetEventPrefix()))
|
|
142
|
+
return null;
|
|
143
|
+
const rawSequence = key.slice(KEYS.fleetEventPrefix().length);
|
|
144
|
+
if (!/^\d+$/.test(rawSequence))
|
|
145
|
+
return null;
|
|
146
|
+
const sequence = Number(rawSequence);
|
|
147
|
+
return Number.isSafeInteger(sequence) ? sequence : null;
|
|
148
|
+
}
|
|
149
|
+
function isTailRecord(value) {
|
|
150
|
+
return typeof value === "object" && value !== null && "sequence" in value && Number.isSafeInteger(value.sequence);
|
|
151
|
+
}
|
|
152
|
+
function isFleetEventEnvelope(value) {
|
|
153
|
+
if (typeof value !== "object" || value === null)
|
|
154
|
+
return !1;
|
|
155
|
+
const record = value;
|
|
156
|
+
return typeof record.kind === "string" && Number.isSafeInteger(record.sequence) && typeof record.cursor === "string" && decodeCursor(record.cursor) === record.sequence && Number.isFinite(record.emittedAtMs) && (record.workflowId === void 0 || typeof record.workflowId === "string") && Object.hasOwn(record, "payload");
|
|
157
|
+
}
|
|
@@ -37,7 +37,7 @@ function validateHandlerOptions(options) {
|
|
|
37
37
|
async function dispatchRestBinding(request, engine, bindingMatch, operationRegistry, options, url) {
|
|
38
38
|
try {
|
|
39
39
|
const principal = authContextToPrincipal(options?.authContext);
|
|
40
|
-
return await dispatchViaExecuteOperation(request, engine, bindingMatch.binding, bindingMatch.pathParams, operationRegistry, principal, options?.pipelineTrace);
|
|
40
|
+
return await dispatchViaExecuteOperation(request, engine, bindingMatch.binding, bindingMatch.pathParams, operationRegistry, principal, options?.pipelineTrace, options?.maxRequestBodyBytes);
|
|
41
41
|
} catch (error) {
|
|
42
42
|
console.error("Unhandled error in dispatchViaExecuteOperation", {
|
|
43
43
|
method: request.method,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { copyBytesToArrayBuffer } from "../../core/byte-arrays.js";
|
|
1
2
|
import { encode } from "../../core/codec.js";
|
|
2
3
|
export function jsonResponse(body, status = 200) {
|
|
3
4
|
return new Response(JSON.stringify(body), {
|
|
@@ -6,7 +7,7 @@ export function jsonResponse(body, status = 200) {
|
|
|
6
7
|
});
|
|
7
8
|
}
|
|
8
9
|
function msgpackResponse(body, status = 200) {
|
|
9
|
-
return new Response(encode(body), {
|
|
10
|
+
return new Response(copyBytesToArrayBuffer(encode(body)), {
|
|
10
11
|
status,
|
|
11
12
|
headers: { "Content-Type": "application/msgpack" }
|
|
12
13
|
});
|
|
@@ -81,6 +81,8 @@ export interface HandlerOptions {
|
|
|
81
81
|
* can otherwise poison the discovery URLs.
|
|
82
82
|
*/
|
|
83
83
|
trustedHosts?: ReadonlyArray<string>;
|
|
84
|
+
/** Maximum REST operation request body size in bytes. Defaults to 1 MB. */
|
|
85
|
+
maxRequestBodyBytes?: number;
|
|
84
86
|
/**
|
|
85
87
|
* Optional pipeline-trace observer. **Internal test seam** used by the
|
|
86
88
|
* dispatch-audit suite to prove every transport drives the full
|
|
@@ -98,7 +100,7 @@ export type RouteExecutionContext = {
|
|
|
98
100
|
};
|
|
99
101
|
export type RouteExecutor = (context: RouteExecutionContext) => Promise<Response>;
|
|
100
102
|
export declare const DIRECT_ROUTE_EXECUTORS: Record<DirectRouteHandlerName, RouteExecutor>;
|
|
101
|
-
export declare function dispatchViaExecuteOperation(request: Request, engine: Engine, binding: UnknownRestBinding, pathParams: Record<string, string>, registry: OperationRegistry, principal: Principal, pipelineTrace?: PipelineTrace): Promise<Response>;
|
|
103
|
+
export declare function dispatchViaExecuteOperation(request: Request, engine: Engine, binding: UnknownRestBinding, pathParams: Record<string, string>, registry: OperationRegistry, principal: Principal, pipelineTrace?: PipelineTrace, maxRequestBodyBytes?: number): Promise<Response>;
|
|
102
104
|
/**
|
|
103
105
|
* Type guard that returns true if the value structurally resembles an
|
|
104
106
|
* {@link OperationFault} (carries `code`, `message`, and `data` properties).
|
|
@@ -125,8 +127,9 @@ export declare function dispatchViaExecuteOperation(request: Request, engine: En
|
|
|
125
127
|
export declare function isOperationFaultLike(value: unknown): value is OperationFault;
|
|
126
128
|
/**
|
|
127
129
|
* Convert the REST transport's `authContext` into a `Principal`. The
|
|
128
|
-
* authenticator (`serve()`)
|
|
129
|
-
*
|
|
130
|
+
* authenticator (`serve()`) reports method + optional claims; this maps
|
|
131
|
+
* that transport authentication result into the `Principal` used by the
|
|
132
|
+
* operation pipeline.
|
|
130
133
|
* Returns `anonymousPrincipal()` when no context is provided (public
|
|
131
134
|
* request).
|
|
132
135
|
*
|
|
@@ -113,10 +113,10 @@ export const DIRECT_ROUTE_EXECUTORS = {
|
|
|
113
113
|
...options?.discoveryInfo !== void 0 ? { discoveryInfo: options.discoveryInfo } : {}
|
|
114
114
|
}))
|
|
115
115
|
};
|
|
116
|
-
export async function dispatchViaExecuteOperation(request, engine, binding, pathParams, registry, principal, pipelineTrace) {
|
|
116
|
+
export async function dispatchViaExecuteOperation(request, engine, binding, pathParams, registry, principal, pipelineTrace, maxRequestBodyBytes) {
|
|
117
117
|
let input;
|
|
118
118
|
try {
|
|
119
|
-
input = await binding.extractInput(request, pathParams);
|
|
119
|
+
input = await binding.extractInput(request, pathParams, maxRequestBodyBytes !== void 0 ? { maxBodyBytes: maxRequestBodyBytes } : {});
|
|
120
120
|
} catch (error) {
|
|
121
121
|
if (isOperationFaultLike(error))
|
|
122
122
|
return binding.shapeFault ? binding.shapeFault(error) : faultToHttpResponse(error);
|