@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
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { resolveWorkflowTypeTarget } from "./registration.js";
|
|
19
19
|
import { cleanupReviews } from "./reviews.js";
|
|
20
20
|
import {
|
|
21
|
-
|
|
21
|
+
commitFencedWorkflowStateOperations,
|
|
22
22
|
loadWorkflowState,
|
|
23
23
|
runSerializedWorkflowStateWrite
|
|
24
24
|
} from "./storage-io.js";
|
|
@@ -75,7 +75,8 @@ export function createLifecycleCallbacks(engine) {
|
|
|
75
75
|
handleCleanupError: (source, error, workflowId) => createTerminationCallbacks(engine).handleCleanupError(source, error, workflowId),
|
|
76
76
|
swallowPromiseRejection: (promise) => swallowPromiseRejection(promise),
|
|
77
77
|
enforceHistoryCircuitBreaker: (workflowId) => terminateWorkflow(getInternals(engine), workflowId, "timed-out", createTerminationCallbacks(engine), HISTORY_CIRCUIT_BREAKER_REASON),
|
|
78
|
-
failWorkflowForUnavailableServices: (workflowId, error) => failWorkflow(getInternals(engine), workflowId, error, createTerminationCallbacks(engine), "system")
|
|
78
|
+
failWorkflowForUnavailableServices: (workflowId, error) => failWorkflow(getInternals(engine), workflowId, error, createTerminationCallbacks(engine), "system"),
|
|
79
|
+
failWorkflowForCheckpointDecodeError: (workflowId, error) => failWorkflow(getInternals(engine), workflowId, error, createTerminationCallbacks(engine), "system")
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
export function createTerminationCallbacksWith(engine, handleScheduledWorkflowTerminal) {
|
|
@@ -91,7 +92,7 @@ export function createTerminationCallbacksWith(engine, handleScheduledWorkflowTe
|
|
|
91
92
|
handleScheduledWorkflowTerminal,
|
|
92
93
|
loadWorkflowState: (workflowId) => loadWorkflowState(getInternals(engine), workflowId),
|
|
93
94
|
runSerializedWorkflowStateWrite: (workflowId, writeOperation) => runSerializedWorkflowStateWrite(getInternals(engine), workflowId, writeOperation),
|
|
94
|
-
commitWorkflowStateOperations: (state, operations) =>
|
|
95
|
+
commitWorkflowStateOperations: (state, operations, options) => commitFencedWorkflowStateOperations(getInternals(engine), state, operations, options),
|
|
95
96
|
cleanupReviews: (workflowId) => cleanupReviews(getInternals(engine), workflowId)
|
|
96
97
|
};
|
|
97
98
|
}
|
|
@@ -106,7 +107,8 @@ export function createTerminationCallbacks(engine) {
|
|
|
106
107
|
}
|
|
107
108
|
export function createRegistrationCallbacks(engine) {
|
|
108
109
|
return {
|
|
109
|
-
ensureRetentionSweepInterval: () => ensureRetentionSweepIntervalCallable(engine)
|
|
110
|
+
ensureRetentionSweepInterval: () => ensureRetentionSweepIntervalCallable(engine),
|
|
111
|
+
dispatchEvent: (event) => engine.dispatchEvent(event)
|
|
110
112
|
};
|
|
111
113
|
}
|
|
112
114
|
let retentionSweepIntervalCallable = () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createActivityOperationCallbacks,
|
|
3
3
|
createChildWorkflowOperationCallbacks,
|
|
4
|
+
createConditionOperationCallbacks,
|
|
4
5
|
createCoordinationOperationCallbacks,
|
|
5
6
|
createDataOperationCallbacks,
|
|
6
7
|
createStateOperationCallbacks,
|
|
@@ -28,10 +29,12 @@ import {
|
|
|
28
29
|
processMemoOperation,
|
|
29
30
|
processOffloadOperation
|
|
30
31
|
} from "./operations-data.js";
|
|
32
|
+
import { completeOperation } from "./operations-router.js";
|
|
31
33
|
import { processSpeculateOperation } from "./operations-speculate.js";
|
|
32
34
|
import { processStateCommitOperation, processStateReadOperation } from "./operations-state.js";
|
|
33
35
|
import { processStreamOperation } from "./operations-stream.js";
|
|
34
36
|
import { processSleepOperation } from "./operations-time.js";
|
|
37
|
+
import { processWaitConditionOperation } from "./operations-wait-condition.js";
|
|
35
38
|
import { feedOperationResult } from "./strategy-helpers.js";
|
|
36
39
|
import { processWaitReviewOperation } from "./sub-operation.js";
|
|
37
40
|
import { finalizePendingTimelineEntry } from "./termination.js";
|
|
@@ -42,6 +45,13 @@ export function createOperationRouterCallbacks(engine) {
|
|
|
42
45
|
processSleepOperation: (workflowId, operation) => processSleepOperation(getInternals(engine), workflowId, operation, createTimeOperationCallbacks(engine)),
|
|
43
46
|
processWaitSignalOperation: (workflowId, operation) => processWaitSignalOperation(getInternals(engine), workflowId, operation, createCoordinationOperationCallbacks(engine)),
|
|
44
47
|
processWaitUpdateOperation: (workflowId, operation) => processWaitUpdateOperation(getInternals(engine), workflowId, operation, createUpdateCallbacks(engine)),
|
|
48
|
+
processWaitConditionOperation: (workflowId, operation) => processWaitConditionOperation(getInternals(engine), workflowId, operation, createConditionOperationCallbacks(engine)),
|
|
49
|
+
processGetVersionOperation: async (workflowId, operation) => {
|
|
50
|
+
completeOperation(getInternals(engine), workflowId, operation.version, {
|
|
51
|
+
finalizePendingTimelineEntry: (id, status, value) => finalizePendingTimelineEntry(getInternals(engine), id, status, value),
|
|
52
|
+
feedOperationResult: (id, result, error) => feedOperationResult(getInternals(engine), id, result, error)
|
|
53
|
+
});
|
|
54
|
+
},
|
|
45
55
|
processParallelOperation: (workflowId, operation) => processParallelOperation(getInternals(engine), workflowId, operation, createCoordinationOperationCallbacks(engine)),
|
|
46
56
|
processRaceOperation: (workflowId, operation) => processRaceOperation(getInternals(engine), workflowId, operation, createCoordinationOperationCallbacks(engine)),
|
|
47
57
|
processMemoOperation: (workflowId, operation) => processMemoOperation(getInternals(engine), workflowId, operation, createDataOperationCallbacks(engine)),
|
|
@@ -6,8 +6,8 @@ export declare function createScheduleCallbacks<TWorkflows extends object, TActi
|
|
|
6
6
|
export declare function createReviewOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): ReviewOperationCallbacks;
|
|
7
7
|
export declare function createSubmitReviewCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): SubmitReviewCallbacks;
|
|
8
8
|
export declare function refreshScheduledWorkflowStateForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState): Promise<RefreshedScheduleState>;
|
|
9
|
-
export declare function startScheduledRunForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState): Promise<string>;
|
|
10
|
-
export declare function applyScheduleOccurrenceForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState): Promise<ScheduleState>;
|
|
9
|
+
export declare function startScheduledRunForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState, occurrence?: number): Promise<string>;
|
|
10
|
+
export declare function applyScheduleOccurrenceForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState, occurrence?: number): Promise<ScheduleState>;
|
|
11
11
|
export declare function settleBackfillScheduleStateForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, state: ScheduleState): Promise<ScheduleState>;
|
|
12
12
|
export declare function handleScheduleTimerForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, entry: TimerEntry): Promise<void>;
|
|
13
13
|
export declare function handleScheduledWorkflowTerminalForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string): Promise<void>;
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./schedules.js";
|
|
18
18
|
import { loadWorkflowState } from "./storage-io.js";
|
|
19
19
|
import { feedOperationResult } from "./strategy-helpers.js";
|
|
20
|
-
import { ensureTerminalCleanupTracked, failWorkflow } from "./termination.js";
|
|
20
|
+
import { ensureTerminalCleanupTracked, failWorkflow, handleCleanupError } from "./termination.js";
|
|
21
21
|
export function createScheduleCallbacks(engine) {
|
|
22
22
|
return {
|
|
23
23
|
startWorkflow: async (type, input, options, additionalStartOperations) => {
|
|
@@ -27,10 +27,14 @@ export function createScheduleCallbacks(engine) {
|
|
|
27
27
|
cancelWorkflow: (workflowId) => engine.cancel(workflowId),
|
|
28
28
|
getWorkflowResult: (workflowId) => engine.getHandle(workflowId).result(),
|
|
29
29
|
refreshScheduledWorkflowState: (state) => refreshScheduledWorkflowStateForEngine(engine, state),
|
|
30
|
-
startScheduledRun: (state) => startScheduledRunForEngine(engine, state),
|
|
31
|
-
applyScheduleOccurrence: (state) => applyScheduleOccurrenceForEngine(engine, state),
|
|
30
|
+
startScheduledRun: (state, occurrence) => startScheduledRunForEngine(engine, state, occurrence),
|
|
31
|
+
applyScheduleOccurrence: (state, occurrence) => applyScheduleOccurrenceForEngine(engine, state, occurrence),
|
|
32
32
|
settleBackfillScheduleState: (state) => settleBackfillScheduleStateForEngine(engine, state),
|
|
33
|
-
flushQueuedInlineWorkflowStartsDirectly: () => flushQueuedInlineWorkflowStartsDirectly(getInternals(engine), createInlineLaunchQueueCallbacks(engine))
|
|
33
|
+
flushQueuedInlineWorkflowStartsDirectly: () => flushQueuedInlineWorkflowStartsDirectly(getInternals(engine), createInlineLaunchQueueCallbacks(engine)),
|
|
34
|
+
failWorkflow: (workflowId, error) => failWorkflow(getInternals(engine), workflowId, error, createTerminationCallbacks(engine)),
|
|
35
|
+
handleCleanupError: (source, error, workflowId) => handleCleanupError(getInternals(engine), source, error, workflowId, {
|
|
36
|
+
dispatchEvent: (event) => engine.dispatchEvent(event)
|
|
37
|
+
})
|
|
34
38
|
};
|
|
35
39
|
}
|
|
36
40
|
export function createReviewOperationCallbacks(engine) {
|
|
@@ -47,11 +51,11 @@ export function createSubmitReviewCallbacks(engine) {
|
|
|
47
51
|
export async function refreshScheduledWorkflowStateForEngine(engine, state) {
|
|
48
52
|
return refreshScheduledWorkflowState(getInternals(engine), state, createScheduleCallbacks(engine));
|
|
49
53
|
}
|
|
50
|
-
export async function startScheduledRunForEngine(engine, state) {
|
|
51
|
-
return startScheduledRun(getInternals(engine), state, createScheduleCallbacks(engine));
|
|
54
|
+
export async function startScheduledRunForEngine(engine, state, occurrence) {
|
|
55
|
+
return startScheduledRun(getInternals(engine), state, createScheduleCallbacks(engine), occurrence);
|
|
52
56
|
}
|
|
53
|
-
export async function applyScheduleOccurrenceForEngine(engine, state) {
|
|
54
|
-
return applyScheduleOccurrence(getInternals(engine), state, createScheduleCallbacks(engine));
|
|
57
|
+
export async function applyScheduleOccurrenceForEngine(engine, state, occurrence) {
|
|
58
|
+
return applyScheduleOccurrence(getInternals(engine), state, createScheduleCallbacks(engine), occurrence);
|
|
55
59
|
}
|
|
56
60
|
export async function settleBackfillScheduleStateForEngine(engine, state) {
|
|
57
61
|
return settleBackfillScheduleState(getInternals(engine), state, createScheduleCallbacks(engine));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CONSTRAINED_ID_CHUNK_SIZE = 64;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KEYS
|
|
1
|
+
import { KEYS } from "../../storage/interface.js";
|
|
2
2
|
import {
|
|
3
3
|
advanceCheckpoint,
|
|
4
4
|
deserializeCheckpoint,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
validateCheckpointRoundTrip
|
|
7
7
|
} from "../checkpoint.js";
|
|
8
8
|
import { encode } from "../codec.js";
|
|
9
|
+
import { hasPendingAttributeChanges } from "../context/context-presence.js";
|
|
9
10
|
import { EMPTY_EVENT_HEAD, EventLog } from "../event-log.js";
|
|
10
11
|
import {
|
|
11
12
|
AttributesChangedEvent,
|
|
@@ -17,10 +18,22 @@ import {
|
|
|
17
18
|
getCommittedCheckpointBytes,
|
|
18
19
|
rememberCommittedCheckpointBytes
|
|
19
20
|
} from "./checkpoint-commit-snapshots.js";
|
|
21
|
+
import {
|
|
22
|
+
attachTransientCheckpointReplayPayload,
|
|
23
|
+
createCheckpointEventPayload,
|
|
24
|
+
mergeCheckpointReplayPayloads,
|
|
25
|
+
pruneCheckpointReplayState,
|
|
26
|
+
readCheckpointReplayPayload
|
|
27
|
+
} from "./checkpoint-replay.js";
|
|
28
|
+
import {
|
|
29
|
+
clearPendingAtomicWorkflowCommitSideEffects,
|
|
30
|
+
takePendingAtomicWorkflowCommitSideEffects
|
|
31
|
+
} from "./checkpoint-side-effects.js";
|
|
20
32
|
import {
|
|
21
33
|
appendCompactionOperations,
|
|
22
34
|
serializeDeletedEntries
|
|
23
35
|
} from "./event-log-compaction.js";
|
|
36
|
+
import { commitFencedEngineWrite } from "./fenced-write.js";
|
|
24
37
|
import { getTimelineInputSummary, getTimelineOperationLabel } from "./state-utilities.js";
|
|
25
38
|
import { buildPendingTimelineOperation } from "./termination.js";
|
|
26
39
|
import { notifyWorkflowFeedCommit } from "./workflow-feed.js";
|
|
@@ -57,21 +70,21 @@ async function persistInlineCheckpoint(internals, workflowId, operation, callbac
|
|
|
57
70
|
const current = internals.checkpoints.get(workflowId), context = internals.inlineStrategy?.getContext(workflowId);
|
|
58
71
|
if (!current || !context)
|
|
59
72
|
return;
|
|
60
|
-
const previousAttributes = { ...current.searchAttributes }, pendingAttributeChanges = context.checkpointPendingAttributeChanges,
|
|
73
|
+
const previousAttributes = { ...current.searchAttributes }, pendingAttributeChanges = context.checkpointPendingAttributeChanges, hasPendingAttributeChangesValue = hasPendingAttributeChanges(context), advanced = advanceCheckpoint(current, context.checkpointLocals, {
|
|
61
74
|
accumulatedResults: context.checkpointAccumulatedResults,
|
|
62
75
|
now: internals.options.getNow(),
|
|
63
76
|
...pendingAttributeChanges !== void 0 ? { searchAttributes: pendingAttributeChanges } : {}
|
|
64
|
-
}), commit = createCheckpointCommit(internals, workflowId,
|
|
65
|
-
appendAttributeOperations(workflowId, commit, previousAttributes, pendingAttributeChanges,
|
|
77
|
+
}), pruned = pruneCheckpointReplayState(advanced, resolvePendingOperationStep(operation, context.stepIndex)), commit = createCheckpointCommit(internals, workflowId, pruned.checkpoint, serializeCheckpoint(attachTransientCheckpointReplayPayload(pruned.checkpoint, pruned.replayPayload)), pruned.replayPayload);
|
|
78
|
+
appendAttributeOperations(workflowId, commit, previousAttributes, pendingAttributeChanges, hasPendingAttributeChangesValue, callbacks);
|
|
66
79
|
await commitCheckpoint(internals, workflowId, operation, commit, callbacks);
|
|
67
|
-
if (
|
|
80
|
+
if (hasPendingAttributeChangesValue)
|
|
68
81
|
callbacks.dispatchEvent(new AttributesChangedEvent(workflowId, { ...pendingAttributeChanges }));
|
|
69
82
|
}
|
|
70
83
|
async function persistWorkerCheckpoint(internals, workflowId, operation, workerCheckpointBytes, callbacks) {
|
|
71
|
-
const serialized = new Uint8Array(workerCheckpointBytes), checkpoint = deserializeCheckpoint(serialized);
|
|
72
|
-
await commitCheckpoint(internals, workflowId, operation, createCheckpointCommit(internals, workflowId, checkpoint,
|
|
84
|
+
const serialized = new Uint8Array(workerCheckpointBytes), checkpoint = deserializeCheckpoint(serialized), workerReplayPayload = readCheckpointReplayPayload(checkpoint), pruned = pruneCheckpointReplayState(checkpoint, resolvePendingOperationStep(operation, checkpoint.step)), replayPayload = mergeCheckpointReplayPayloads(workerReplayPayload, pruned.replayPayload), prunedSerialized = serializeCheckpoint(attachTransientCheckpointReplayPayload(pruned.checkpoint, replayPayload));
|
|
85
|
+
await commitCheckpoint(internals, workflowId, operation, createCheckpointCommit(internals, workflowId, pruned.checkpoint, prunedSerialized, replayPayload), callbacks);
|
|
73
86
|
}
|
|
74
|
-
function createCheckpointCommit(internals, workflowId, checkpoint, serialized) {
|
|
87
|
+
function createCheckpointCommit(internals, workflowId, checkpoint, serialized, replayPayload) {
|
|
75
88
|
const operations = [
|
|
76
89
|
{ type: "put", key: KEYS.checkpoint(workflowId), value: serialized }
|
|
77
90
|
];
|
|
@@ -85,14 +98,15 @@ function createCheckpointCommit(internals, workflowId, checkpoint, serialized) {
|
|
|
85
98
|
return {
|
|
86
99
|
checkpoint,
|
|
87
100
|
serialized,
|
|
101
|
+
...replayPayload === void 0 ? {} : { replayPayload },
|
|
88
102
|
...expectedSerialized !== void 0 ? { expectedSerialized } : {},
|
|
89
103
|
step: checkpoint.step,
|
|
90
104
|
timestamp: checkpoint.createdAt,
|
|
91
105
|
operations
|
|
92
106
|
};
|
|
93
107
|
}
|
|
94
|
-
function appendAttributeOperations(workflowId, commit, previousAttributes, pendingAttributeChanges,
|
|
95
|
-
if (!
|
|
108
|
+
function appendAttributeOperations(workflowId, commit, previousAttributes, pendingAttributeChanges, hasPendingAttributeChangesValue, callbacks) {
|
|
109
|
+
if (!hasPendingAttributeChangesValue)
|
|
96
110
|
return;
|
|
97
111
|
callbacks.validateAttributeValueSizes(pendingAttributeChanges ?? {});
|
|
98
112
|
commit.operations.push({
|
|
@@ -104,11 +118,15 @@ function appendAttributeOperations(workflowId, commit, previousAttributes, pendi
|
|
|
104
118
|
}
|
|
105
119
|
async function commitCheckpoint(internals, workflowId, operation, commit, callbacks) {
|
|
106
120
|
dispatchCheckpointSizeWarning(internals, workflowId, commit, callbacks);
|
|
107
|
-
const nextPendingTimelineEntry = callbacks.appendTimelineBatchOperations(workflowId, operation, commit.step, commit.timestamp, commit.operations), { newHead, timestamp } = appendCheckpointEventLog(internals, workflowId, commit), retentionWindow = internals.options.historyPolicy.retentionWindow, compaction = retentionWindow === null ? null : await appendCompactionOperations(internals.storage, workflowId, newHead.sequence, retentionWindow, commit.operations);
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
121
|
+
const nextPendingTimelineEntry = callbacks.appendTimelineBatchOperations(workflowId, operation, commit.step, commit.timestamp, commit.operations), { newHead, timestamp } = appendCheckpointEventLog(internals, workflowId, commit), retentionWindow = internals.options.historyPolicy.retentionWindow, compaction = retentionWindow === null ? null : await appendCompactionOperations(internals.storage, workflowId, newHead.sequence, retentionWindow, commit.operations), pendingSideEffects = takePendingAtomicWorkflowCommitSideEffects(internals, workflowId);
|
|
122
|
+
if (pendingSideEffects !== void 0)
|
|
123
|
+
commit.operations.push(...pendingSideEffects.operations);
|
|
124
|
+
const storageSupportsConditionalBatch = internals.storage.capabilities().conditionalBatch, sideEffectConditions = checkpointSideEffectConditions(pendingSideEffects, storageSupportsConditionalBatch), conditions = buildCheckpointCommitConditions(workflowId, commit, storageSupportsConditionalBatch, sideEffectConditions);
|
|
125
|
+
await commitFencedEngineWrite(internals, commit.operations, conditions, () => {
|
|
126
|
+
return Error(`Checkpoint commit for workflow "${workflowId}" lost its CAS race against a newer checkpoint.`);
|
|
127
|
+
});
|
|
128
|
+
if (pendingSideEffects !== void 0)
|
|
129
|
+
clearPendingAtomicWorkflowCommitSideEffects(internals, workflowId);
|
|
112
130
|
if (commit.expectedSerialized !== void 0)
|
|
113
131
|
rememberCommittedCheckpointBytes(internals, workflowId, commit.serialized);
|
|
114
132
|
internals.pendingTimelineEntries.set(workflowId, nextPendingTimelineEntry);
|
|
@@ -128,15 +146,20 @@ async function commitCheckpoint(internals, workflowId, operation, commit, callba
|
|
|
128
146
|
if (historyEventLimitBreached(internals, newHead.sequence))
|
|
129
147
|
await callbacks.enforceHistoryCircuitBreaker(workflowId);
|
|
130
148
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
function checkpointSideEffectConditions(pendingSideEffects, storageSupportsConditionalBatch) {
|
|
150
|
+
if (!storageSupportsConditionalBatch)
|
|
151
|
+
return [];
|
|
152
|
+
return pendingSideEffects?.conditions ?? [];
|
|
153
|
+
}
|
|
154
|
+
function buildCheckpointCommitConditions(workflowId, commit, includeCheckpointCondition, sideEffectConditions) {
|
|
155
|
+
const conditions = [];
|
|
156
|
+
if (includeCheckpointCondition && commit.expectedSerialized !== void 0)
|
|
157
|
+
conditions.push({
|
|
134
158
|
key: KEYS.checkpoint(workflowId),
|
|
135
|
-
expectedValue: expectedSerialized
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
throw Error(`Checkpoint commit for workflow "${workflowId}" lost its CAS race against a newer checkpoint.`);
|
|
159
|
+
expectedValue: commit.expectedSerialized
|
|
160
|
+
});
|
|
161
|
+
conditions.push(...sideEffectConditions);
|
|
162
|
+
return conditions;
|
|
140
163
|
}
|
|
141
164
|
function historyEventLimitBreached(internals, sequence) {
|
|
142
165
|
const maxEvents = internals.options.historyPolicy.maxEvents;
|
|
@@ -154,7 +177,16 @@ function dispatchCheckpointSizeWarning(internals, workflowId, commit, callbacks)
|
|
|
154
177
|
callbacks.dispatchEvent(new CheckpointSizeWarningEvent(workflowId, commit.serialized.byteLength, commit.step));
|
|
155
178
|
}
|
|
156
179
|
function appendCheckpointEventLog(internals, workflowId, commit) {
|
|
157
|
-
return new EventLog(internals.storage, workflowId).appendToBatch({
|
|
180
|
+
return new EventLog(internals.storage, workflowId).appendToBatch({
|
|
181
|
+
type: "workflow:checkpoint",
|
|
182
|
+
payload: createCheckpointEventPayload(commit.step, commit.replayPayload)
|
|
183
|
+
}, commit.operations, internals.eventLogHeads.get(workflowId) ?? EMPTY_EVENT_HEAD, internals.workflowVersionTuples.get(workflowId));
|
|
184
|
+
}
|
|
185
|
+
function resolvePendingOperationStep(operation, fallbackStepIndex) {
|
|
186
|
+
const operationStep = "step" in operation ? operation.step : void 0;
|
|
187
|
+
if (typeof operationStep === "number" && Number.isSafeInteger(operationStep) && operationStep >= 0)
|
|
188
|
+
return operationStep;
|
|
189
|
+
return Math.max(0, fallbackStepIndex - 1);
|
|
158
190
|
}
|
|
159
191
|
export async function pruneCheckpointHistory(internals, workflowId, currentStep) {
|
|
160
192
|
const limit = internals.options.checkpointHistory;
|
|
@@ -175,7 +207,11 @@ export function validateDevelopmentCheckpoint(internals, workflowId, callbacks)
|
|
|
175
207
|
const step = context.stepIndex, current = internals.checkpoints.get(workflowId);
|
|
176
208
|
if (!current)
|
|
177
209
|
return;
|
|
178
|
-
const result = validateCheckpointRoundTrip(
|
|
210
|
+
const result = validateCheckpointRoundTrip({
|
|
211
|
+
...current,
|
|
212
|
+
locals: context.checkpointLocals,
|
|
213
|
+
accumulatedResults: context.checkpointAccumulatedResults
|
|
214
|
+
});
|
|
179
215
|
if (!result.valid) {
|
|
180
216
|
const fieldPaths = result.divergences.map((divergence) => divergence.path), message = `Checkpoint at step ${step} has ${result.divergences.length} non-serializable field(s)`;
|
|
181
217
|
callbacks.dispatchEvent(new DevelopmentWarningEvent(workflowId, message, fieldPaths));
|
|
@@ -3,6 +3,7 @@ import { deserializeCheckpoint } from "../checkpoint.js";
|
|
|
3
3
|
import { decode } from "../codec.js";
|
|
4
4
|
import { sanitizeDebugValueForDisplay } from "../debug-output.js";
|
|
5
5
|
import { EventLog } from "../event-log.js";
|
|
6
|
+
import { hydrateCheckpointReplayState } from "./checkpoint-replay.js";
|
|
6
7
|
import { readEventLogWatermark } from "./event-log-compaction.js";
|
|
7
8
|
import {
|
|
8
9
|
sanitizeCheckpointState,
|
|
@@ -41,7 +42,7 @@ export async function getCheckpointAt(internals, workflowId, step) {
|
|
|
41
42
|
const bytes = await internals.storage.get(KEYS.checkpointHistory(workflowId, step));
|
|
42
43
|
if (!bytes)
|
|
43
44
|
return null;
|
|
44
|
-
const checkpoint = deserializeCheckpoint(bytes);
|
|
45
|
+
const checkpoint = await hydrateCheckpointReplayState(internals.storage, workflowId, deserializeCheckpoint(bytes));
|
|
45
46
|
return sanitizeCheckpointState({
|
|
46
47
|
step: checkpoint.step,
|
|
47
48
|
locals: checkpoint.locals,
|
|
@@ -75,7 +76,7 @@ export async function replayTo(internals, workflowId, step) {
|
|
|
75
76
|
const bytes = await internals.storage.get(KEYS.checkpointHistory(workflowId, step));
|
|
76
77
|
if (!bytes)
|
|
77
78
|
return null;
|
|
78
|
-
const
|
|
79
|
+
const entries = await new EventLog(internals.storage, workflowId).replay(Math.max(step - 1, -1)), checkpoint = await hydrateCheckpointReplayState(internals.storage, workflowId, deserializeCheckpoint(bytes)), watermark = await readEventLogWatermark(internals.storage, workflowId);
|
|
79
80
|
return {
|
|
80
81
|
checkpoint: sanitizeCheckpointState({
|
|
81
82
|
step: checkpoint.step,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Storage } from '../../storage/interface.ts';
|
|
2
|
+
import type { Checkpoint, WorkerReplayOperationFailure, WorkerReplayOperationSignature } from '../types.ts';
|
|
3
|
+
export declare const CHECKPOINT_REPLAY_PAYLOAD_KEY = "__weftCheckpointReplay";
|
|
4
|
+
export type CheckpointReplayPayload = {
|
|
5
|
+
accumulatedResults?: Array<[number, unknown]>;
|
|
6
|
+
workerReplaySignatures?: Array<[number, WorkerReplayOperationSignature]>;
|
|
7
|
+
workerReplayFailures?: Array<[number, WorkerReplayOperationFailure]>;
|
|
8
|
+
};
|
|
9
|
+
export type PrunedCheckpointReplayState = {
|
|
10
|
+
checkpoint: Checkpoint;
|
|
11
|
+
replayPayload: CheckpointReplayPayload | undefined;
|
|
12
|
+
};
|
|
13
|
+
export declare function pruneCheckpointReplayState(checkpoint: Checkpoint, pendingOperationStep: number): PrunedCheckpointReplayState;
|
|
14
|
+
export declare function hydrateCheckpointReplayState(storage: Storage, workflowId: string, checkpoint: Checkpoint): Promise<Checkpoint>;
|
|
15
|
+
export declare function hydrateCheckpointReplayStateFromPayload(checkpoint: Checkpoint, replayPayload: CheckpointReplayPayload | undefined): Checkpoint;
|
|
16
|
+
export declare function attachTransientCheckpointReplayPayload(checkpoint: Checkpoint, replayPayload: CheckpointReplayPayload | undefined): Checkpoint;
|
|
17
|
+
export declare function createCheckpointEventPayload(checkpointStep: number, replayPayload: CheckpointReplayPayload | undefined): Record<string, unknown>;
|
|
18
|
+
export declare function mergeCheckpointReplayPayloads(left: CheckpointReplayPayload | undefined, right: CheckpointReplayPayload | undefined): CheckpointReplayPayload | undefined;
|
|
19
|
+
export declare function readCheckpointReplayPayload(payload: unknown): CheckpointReplayPayload | undefined;
|
|
20
|
+
export declare function stripInternalCheckpointReplayPayload(payload: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { KEYS } from "../../storage/interface.js";
|
|
2
|
+
import { decode } from "../codec.js";
|
|
3
|
+
import { isWorkflowLogEntry } from "../event-log-shared.js";
|
|
4
|
+
import { WORKER_REPLAY_SIGNATURE_FORMAT } from "../types/checkpoint.js";
|
|
5
|
+
export const CHECKPOINT_REPLAY_PAYLOAD_KEY = "__weftCheckpointReplay";
|
|
6
|
+
const NO_REPLAY_WATERMARK = -1;
|
|
7
|
+
export function pruneCheckpointReplayState(checkpoint, pendingOperationStep) {
|
|
8
|
+
const checkpointWithoutReplayPayload = stripTransientCheckpointReplayPayload(checkpoint), previousWatermark = checkpointWithoutReplayPayload.accumulatedResultReplayWatermark ?? NO_REPLAY_WATERMARK, consumedResults = entriesBeforeStep(checkpointWithoutReplayPayload.accumulatedResults, pendingOperationStep), consumedSignatures = entriesBeforeStep(checkpointWithoutReplayPayload.workerReplaySignatures ?? [], pendingOperationStep), consumedFailures = entriesBeforeStep(checkpointWithoutReplayPayload.workerReplayFailures ?? [], pendingOperationStep), replayPayload = buildReplayPayload({
|
|
9
|
+
accumulatedResults: entriesAfterWatermark(consumedResults, previousWatermark),
|
|
10
|
+
workerReplaySignatures: entriesAfterWatermark(consumedSignatures, previousWatermark),
|
|
11
|
+
workerReplayFailures: entriesAfterWatermark(consumedFailures, previousWatermark)
|
|
12
|
+
}), nextWatermark = resolveNextReplayWatermark(previousWatermark, replayPayload), retainedWorkerReplaySignatures = entriesAtOrAfterStep(checkpointWithoutReplayPayload.workerReplaySignatures ?? [], pendingOperationStep), retainedWorkerReplayFailures = entriesAtOrAfterStep(checkpointWithoutReplayPayload.workerReplayFailures ?? [], pendingOperationStep), prunedCheckpoint = {
|
|
13
|
+
...checkpointWithoutReplayPayload,
|
|
14
|
+
accumulatedResults: entriesAtOrAfterStep(checkpointWithoutReplayPayload.accumulatedResults, pendingOperationStep),
|
|
15
|
+
...nextWatermark === NO_REPLAY_WATERMARK ? {} : { accumulatedResultReplayWatermark: nextWatermark },
|
|
16
|
+
...optionalEntries("workerReplaySignatures", retainedWorkerReplaySignatures),
|
|
17
|
+
...optionalEntries("workerReplayFailures", retainedWorkerReplayFailures)
|
|
18
|
+
};
|
|
19
|
+
if (nextWatermark === NO_REPLAY_WATERMARK)
|
|
20
|
+
delete prunedCheckpoint.accumulatedResultReplayWatermark;
|
|
21
|
+
if (retainedWorkerReplaySignatures.length === 0)
|
|
22
|
+
delete prunedCheckpoint.workerReplaySignatures;
|
|
23
|
+
if (retainedWorkerReplayFailures.length === 0)
|
|
24
|
+
delete prunedCheckpoint.workerReplayFailures;
|
|
25
|
+
return {
|
|
26
|
+
checkpoint: prunedCheckpoint,
|
|
27
|
+
replayPayload
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export async function hydrateCheckpointReplayState(storage, workflowId, checkpoint) {
|
|
31
|
+
const replayPayloads = [], checkpointReplayPayload = readCheckpointReplayPayload(checkpoint);
|
|
32
|
+
if (checkpointReplayPayload !== void 0)
|
|
33
|
+
replayPayloads.push(checkpointReplayPayload);
|
|
34
|
+
const compactedReplayPayload = await readCompactedCheckpointReplayPayload(storage, workflowId);
|
|
35
|
+
if (compactedReplayPayload !== void 0)
|
|
36
|
+
replayPayloads.push(compactedReplayPayload);
|
|
37
|
+
for await (const [, entryBytes] of storage.scan(KEYS.eventPrefix(workflowId))) {
|
|
38
|
+
const decoded = decode(entryBytes);
|
|
39
|
+
if (!isWorkflowLogEntry(decoded))
|
|
40
|
+
continue;
|
|
41
|
+
const entry = decoded, checkpointStep = getCheckpointEventStep(entry.payload);
|
|
42
|
+
if (checkpointStep === void 0)
|
|
43
|
+
continue;
|
|
44
|
+
if (checkpointStep > checkpoint.step)
|
|
45
|
+
break;
|
|
46
|
+
const replayPayload = readCheckpointReplayPayload(entry.payload);
|
|
47
|
+
if (replayPayload === void 0)
|
|
48
|
+
continue;
|
|
49
|
+
replayPayloads.push(replayPayload);
|
|
50
|
+
}
|
|
51
|
+
return hydrateCheckpointReplayStateFromPayloads(stripTransientCheckpointReplayPayload(checkpoint), replayPayloads);
|
|
52
|
+
}
|
|
53
|
+
export function hydrateCheckpointReplayStateFromPayload(checkpoint, replayPayload) {
|
|
54
|
+
return hydrateCheckpointReplayStateFromPayloads(stripTransientCheckpointReplayPayload(checkpoint), replayPayload === void 0 ? [] : [replayPayload]);
|
|
55
|
+
}
|
|
56
|
+
function hydrateCheckpointReplayStateFromPayloads(checkpoint, replayPayloads) {
|
|
57
|
+
const accumulatedResults = new Map, workerReplaySignatures = new Map, workerReplayFailures = new Map;
|
|
58
|
+
for (const replayPayload of replayPayloads)
|
|
59
|
+
mergeReplayPayload({
|
|
60
|
+
accumulatedResults,
|
|
61
|
+
workerReplaySignatures,
|
|
62
|
+
workerReplayFailures
|
|
63
|
+
}, replayPayload);
|
|
64
|
+
mergeEntries(accumulatedResults, checkpoint.accumulatedResults);
|
|
65
|
+
mergeEntries(workerReplaySignatures, checkpoint.workerReplaySignatures ?? []);
|
|
66
|
+
mergeEntries(workerReplayFailures, checkpoint.workerReplayFailures ?? []);
|
|
67
|
+
return {
|
|
68
|
+
...checkpoint,
|
|
69
|
+
accumulatedResults: sortedEntries(accumulatedResults),
|
|
70
|
+
...optionalEntries("workerReplaySignatures", sortedEntries(workerReplaySignatures)),
|
|
71
|
+
...optionalEntries("workerReplayFailures", sortedEntries(workerReplayFailures))
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function attachTransientCheckpointReplayPayload(checkpoint, replayPayload) {
|
|
75
|
+
if (replayPayload === void 0)
|
|
76
|
+
return checkpoint;
|
|
77
|
+
return {
|
|
78
|
+
...checkpoint,
|
|
79
|
+
[CHECKPOINT_REPLAY_PAYLOAD_KEY]: replayPayload
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function createCheckpointEventPayload(checkpointStep, replayPayload) {
|
|
83
|
+
return replayPayload === void 0 ? { step: checkpointStep } : { step: checkpointStep, [CHECKPOINT_REPLAY_PAYLOAD_KEY]: replayPayload };
|
|
84
|
+
}
|
|
85
|
+
export function mergeCheckpointReplayPayloads(left, right) {
|
|
86
|
+
if (left === void 0)
|
|
87
|
+
return right;
|
|
88
|
+
if (right === void 0)
|
|
89
|
+
return left;
|
|
90
|
+
return buildReplayPayload({
|
|
91
|
+
accumulatedResults: [...left.accumulatedResults ?? [], ...right.accumulatedResults ?? []],
|
|
92
|
+
workerReplaySignatures: [
|
|
93
|
+
...left.workerReplaySignatures ?? [],
|
|
94
|
+
...right.workerReplaySignatures ?? []
|
|
95
|
+
],
|
|
96
|
+
workerReplayFailures: [
|
|
97
|
+
...left.workerReplayFailures ?? [],
|
|
98
|
+
...right.workerReplayFailures ?? []
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function readCheckpointReplayPayload(payload) {
|
|
103
|
+
if (!isRecord(payload))
|
|
104
|
+
return;
|
|
105
|
+
const replayPayload = payload[CHECKPOINT_REPLAY_PAYLOAD_KEY];
|
|
106
|
+
if (!isRecord(replayPayload))
|
|
107
|
+
return;
|
|
108
|
+
return readCheckpointReplayPayloadRecord(replayPayload);
|
|
109
|
+
}
|
|
110
|
+
export function stripInternalCheckpointReplayPayload(payload) {
|
|
111
|
+
const { [CHECKPOINT_REPLAY_PAYLOAD_KEY]: _internalReplayPayload, ...publicPayload } = payload;
|
|
112
|
+
return publicPayload;
|
|
113
|
+
}
|
|
114
|
+
function buildReplayPayload(payload) {
|
|
115
|
+
const replayPayload = {}, accumulatedResults = payload.accumulatedResults, workerReplaySignatures = payload.workerReplaySignatures, workerReplayFailures = payload.workerReplayFailures;
|
|
116
|
+
if (accumulatedResults !== void 0 && accumulatedResults.length > 0)
|
|
117
|
+
replayPayload.accumulatedResults = accumulatedResults;
|
|
118
|
+
if (workerReplaySignatures !== void 0 && workerReplaySignatures.length > 0)
|
|
119
|
+
replayPayload.workerReplaySignatures = workerReplaySignatures;
|
|
120
|
+
if (workerReplayFailures !== void 0 && workerReplayFailures.length > 0)
|
|
121
|
+
replayPayload.workerReplayFailures = workerReplayFailures;
|
|
122
|
+
return Object.keys(replayPayload).length === 0 ? void 0 : replayPayload;
|
|
123
|
+
}
|
|
124
|
+
function resolveNextReplayWatermark(previousWatermark, replayPayload) {
|
|
125
|
+
if (replayPayload === void 0)
|
|
126
|
+
return previousWatermark;
|
|
127
|
+
let nextWatermark = previousWatermark;
|
|
128
|
+
for (const entries of [
|
|
129
|
+
replayPayload.accumulatedResults ?? [],
|
|
130
|
+
replayPayload.workerReplaySignatures ?? [],
|
|
131
|
+
replayPayload.workerReplayFailures ?? []
|
|
132
|
+
])
|
|
133
|
+
for (const [step] of entries)
|
|
134
|
+
nextWatermark = Math.max(nextWatermark, step);
|
|
135
|
+
return nextWatermark;
|
|
136
|
+
}
|
|
137
|
+
function entriesBeforeStep(entries, step) {
|
|
138
|
+
return entries.filter(([entryStep]) => entryStep < step);
|
|
139
|
+
}
|
|
140
|
+
function entriesAtOrAfterStep(entries, step) {
|
|
141
|
+
return entries.filter(([entryStep]) => entryStep >= step);
|
|
142
|
+
}
|
|
143
|
+
function entriesAfterWatermark(entries, watermark) {
|
|
144
|
+
return entries.filter(([entryStep]) => entryStep > watermark);
|
|
145
|
+
}
|
|
146
|
+
function optionalEntries(key, entries) {
|
|
147
|
+
return entries.length === 0 ? {} : { [key]: entries };
|
|
148
|
+
}
|
|
149
|
+
function stripTransientCheckpointReplayPayload(checkpoint) {
|
|
150
|
+
const checkpointWithReplayPayload = checkpoint, { [CHECKPOINT_REPLAY_PAYLOAD_KEY]: _replayPayload, ...checkpointWithoutReplayPayload } = checkpointWithReplayPayload;
|
|
151
|
+
return checkpointWithoutReplayPayload;
|
|
152
|
+
}
|
|
153
|
+
function sortedEntries(entries) {
|
|
154
|
+
return [...entries.entries()].toSorted(([leftStep], [rightStep]) => leftStep - rightStep);
|
|
155
|
+
}
|
|
156
|
+
function mergeEntries(target, entries) {
|
|
157
|
+
for (const [step, value] of entries)
|
|
158
|
+
target.set(step, value);
|
|
159
|
+
}
|
|
160
|
+
function mergeReplayPayload(target, replayPayload) {
|
|
161
|
+
mergeEntries(target.accumulatedResults, replayPayload.accumulatedResults ?? []);
|
|
162
|
+
mergeEntries(target.workerReplaySignatures, replayPayload.workerReplaySignatures ?? []);
|
|
163
|
+
mergeEntries(target.workerReplayFailures, replayPayload.workerReplayFailures ?? []);
|
|
164
|
+
}
|
|
165
|
+
function getCheckpointEventStep(payload) {
|
|
166
|
+
if (!isRecord(payload))
|
|
167
|
+
return;
|
|
168
|
+
const step = payload.step;
|
|
169
|
+
return typeof step === "number" && Number.isSafeInteger(step) && step >= 0 ? step : void 0;
|
|
170
|
+
}
|
|
171
|
+
function readCheckpointReplayPayloadRecord(replayPayload) {
|
|
172
|
+
const accumulatedResults = readUnknownEntries(replayPayload.accumulatedResults), workerReplaySignatures = readWorkerReplaySignatureEntries(replayPayload.workerReplaySignatures), workerReplayFailures = readWorkerReplayFailureEntries(replayPayload.workerReplayFailures);
|
|
173
|
+
return buildReplayPayload({
|
|
174
|
+
...accumulatedResults === void 0 ? {} : { accumulatedResults },
|
|
175
|
+
...workerReplaySignatures === void 0 ? {} : { workerReplaySignatures },
|
|
176
|
+
...workerReplayFailures === void 0 ? {} : { workerReplayFailures }
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function readCompactedCheckpointReplayPayload(storage, workflowId) {
|
|
180
|
+
const watermarkBytes = await storage.get(KEYS.eventWatermark(workflowId));
|
|
181
|
+
if (watermarkBytes === null)
|
|
182
|
+
return;
|
|
183
|
+
const watermark = decode(watermarkBytes);
|
|
184
|
+
if (!isRecord(watermark))
|
|
185
|
+
return;
|
|
186
|
+
const replayPayload = watermark.checkpointReplay;
|
|
187
|
+
return isRecord(replayPayload) ? readCheckpointReplayPayloadRecord(replayPayload) : void 0;
|
|
188
|
+
}
|
|
189
|
+
function readUnknownEntries(value) {
|
|
190
|
+
if (!Array.isArray(value))
|
|
191
|
+
return;
|
|
192
|
+
const entries = [];
|
|
193
|
+
for (const entry of value) {
|
|
194
|
+
if (!Array.isArray(entry) || entry.length !== 2 || !isReplayStep(entry[0]))
|
|
195
|
+
continue;
|
|
196
|
+
entries.push([entry[0], entry[1]]);
|
|
197
|
+
}
|
|
198
|
+
return entries;
|
|
199
|
+
}
|
|
200
|
+
function readWorkerReplaySignatureEntries(value) {
|
|
201
|
+
if (!Array.isArray(value))
|
|
202
|
+
return;
|
|
203
|
+
const entries = [];
|
|
204
|
+
for (const entry of value) {
|
|
205
|
+
if (!Array.isArray(entry) || entry.length !== 2 || !isReplayStep(entry[0]))
|
|
206
|
+
continue;
|
|
207
|
+
if (!isWorkerReplaySignature(entry[1]))
|
|
208
|
+
continue;
|
|
209
|
+
entries.push([entry[0], entry[1]]);
|
|
210
|
+
}
|
|
211
|
+
return entries;
|
|
212
|
+
}
|
|
213
|
+
function readWorkerReplayFailureEntries(value) {
|
|
214
|
+
if (!Array.isArray(value))
|
|
215
|
+
return;
|
|
216
|
+
const entries = [];
|
|
217
|
+
for (const entry of value) {
|
|
218
|
+
if (!Array.isArray(entry) || entry.length !== 2 || !isReplayStep(entry[0]))
|
|
219
|
+
continue;
|
|
220
|
+
if (!isWorkerReplayFailure(entry[1]))
|
|
221
|
+
continue;
|
|
222
|
+
entries.push([entry[0], entry[1]]);
|
|
223
|
+
}
|
|
224
|
+
return entries;
|
|
225
|
+
}
|
|
226
|
+
function isRecord(value) {
|
|
227
|
+
return typeof value === "object" && value !== null;
|
|
228
|
+
}
|
|
229
|
+
function isReplayStep(value) {
|
|
230
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
231
|
+
}
|
|
232
|
+
function isWorkerReplaySignature(value) {
|
|
233
|
+
if (!isRecord(value))
|
|
234
|
+
return !1;
|
|
235
|
+
return value.format === WORKER_REPLAY_SIGNATURE_FORMAT && typeof value.operationType === "string" && typeof value.stableFieldsDigest === "string" && isReplayStep(value.stableFieldsByteLength);
|
|
236
|
+
}
|
|
237
|
+
function isWorkerReplayFailure(value) {
|
|
238
|
+
if (!isRecord(value))
|
|
239
|
+
return !1;
|
|
240
|
+
const failureCategory = value.failureCategory;
|
|
241
|
+
return value.status === "failed" && typeof value.error === "string" && (value.errorName === void 0 || typeof value.errorName === "string") && (failureCategory === void 0 || failureCategory === "application" || failureCategory === "cancellation" || failureCategory === "resource" || failureCategory === "system" || failureCategory === "timeout");
|
|
242
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BatchOperation, ConditionalBatchCondition } from '../../storage/interface.ts';
|
|
2
|
+
import type { EngineInternals } from './internals.ts';
|
|
3
|
+
export type AtomicWorkflowCommitSideEffects = {
|
|
4
|
+
conditions: ConditionalBatchCondition[];
|
|
5
|
+
operations: BatchOperation[];
|
|
6
|
+
};
|
|
7
|
+
export declare function stageAtomicWorkflowCommitSideEffects(internals: EngineInternals, workflowId: string, sideEffects: AtomicWorkflowCommitSideEffects): void;
|
|
8
|
+
export declare function takePendingAtomicWorkflowCommitSideEffects(internals: EngineInternals, workflowId: string): AtomicWorkflowCommitSideEffects | undefined;
|
|
9
|
+
export declare function clearPendingAtomicWorkflowCommitSideEffects(internals: EngineInternals, workflowId: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* Non-destructively report whether a workflow's pending atomic side-effect buffer
|
|
12
|
+
* already stages a `put` to `key`. Unlike {@link takePendingAtomicWorkflowCommitSideEffects},
|
|
13
|
+
* this does NOT consume the buffer, so it is safe to call at a gate that runs before the
|
|
14
|
+
* commit that will flush those same side-effects.
|
|
15
|
+
*
|
|
16
|
+
* The terminal-transition path (#446) needs this: `ctx.setFinalizerState()` stages the
|
|
17
|
+
* `wf-finalizer-state:` put as a pending side-effect that the terminal batch flushes, but
|
|
18
|
+
* a pre-batch `storage.get()` cannot see a staged-but-unflushed write. Peeking the buffer
|
|
19
|
+
* lets the terminal batch stage its teardown marker atomically alongside that put — without
|
|
20
|
+
* it, a `setFinalizerState` with no intervening checkpoint would commit the resource state
|
|
21
|
+
* yet skip the teardown marker, silently leaking the external resource.
|
|
22
|
+
*/
|
|
23
|
+
export declare function pendingAtomicWorkflowCommitSideEffectsStagePut(internals: EngineInternals, workflowId: string, key: string): boolean;
|