@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyActivityDefinition, AnyWorkflowDefinition, IsDefaultWorkflowRegistry } from '../types.ts';
|
|
1
|
+
import type { AnyActivityDefinition, AnyWorkflowDefinition, DefaultWorkflowRegistry, InferWorkflowEntries, IsDefaultWorkflowRegistry, WorkflowServicesUnion } from '../types.ts';
|
|
2
2
|
import type { UnknownNameWhenRegistryHasNoKnownNames } from '../types/registry-type-helpers.ts';
|
|
3
3
|
import type { KnownWorkflowNames } from './construction.ts';
|
|
4
4
|
import type { EngineConstructorOptions } from './engine-internal-types.ts';
|
|
@@ -24,37 +24,23 @@ import type { EngineConstructorOptions } from './engine-internal-types.ts';
|
|
|
24
24
|
* void engine;
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
export type EngineCreateOptions<TWorkflowDefinitions extends Record<string, AnyWorkflowDefinition> = {}, TActivityDefinitions extends Record<string, AnyActivityDefinition> = {}> = EngineConstructorOptions & {
|
|
27
|
+
export type EngineCreateOptions<TWorkflowDefinitions extends Record<string, AnyWorkflowDefinition> = {}, TActivityDefinitions extends Record<string, AnyActivityDefinition> = {}> = EngineConstructorOptions<WorkflowServicesUnion<EngineCreateWorkflowRegistry<TWorkflowDefinitions>>> & {
|
|
28
28
|
/** Workflow definitions to register before recovery. */
|
|
29
29
|
workflows?: TWorkflowDefinitions;
|
|
30
30
|
/** Activity definitions to register before workflows. */
|
|
31
31
|
activities?: TActivityDefinitions;
|
|
32
|
-
/**
|
|
33
|
-
* Opt out of the persisted-data schema-version gate when opening a storage
|
|
34
|
-
* that contains workflow data written by `new Engine({ storage })` before
|
|
35
|
-
* the schema-version sentinel existed.
|
|
36
|
-
*
|
|
37
|
-
* The gate normally rejects any storage that already holds workflow records
|
|
38
|
-
* but lacks the sentinel — a safety check against silently classifying
|
|
39
|
-
* pre-sentinel data as schema-current. Set `allowLegacyData: true` only when
|
|
40
|
-
* you knowingly opened the same storage with the legacy constructor path and
|
|
41
|
-
* are intentionally recovering it via `Engine.create`. On success, the
|
|
42
|
-
* current schema-version sentinel is written. Remove the opt-in once the
|
|
43
|
-
* data has been migrated.
|
|
44
|
-
*/
|
|
45
|
-
allowLegacyData?: boolean;
|
|
46
32
|
} & ({
|
|
47
33
|
/**
|
|
48
34
|
* Recover stored running workflows after registration. Defaults to
|
|
49
35
|
* `true`: a fresh engine booting against durable storage resumes any
|
|
50
36
|
* workflows left in flight by a previous process. Pass `recover: false`
|
|
51
|
-
* to opt out (tests, `ScopedStorage` isolation,
|
|
37
|
+
* to opt out (tests, `ScopedStorage` isolation, explicit operator
|
|
52
38
|
* inspection).
|
|
53
39
|
*/
|
|
54
40
|
recover?: true | undefined;
|
|
55
41
|
/**
|
|
56
42
|
* Forwarded to `Engine.recoverAll`. Only use this during rolling
|
|
57
|
-
* deploys or explicit storage
|
|
43
|
+
* deploys or explicit operator storage repair.
|
|
58
44
|
*/
|
|
59
45
|
acknowledgeUnknownWorkflowTypes?: boolean;
|
|
60
46
|
} | {
|
|
@@ -63,6 +49,16 @@ export type EngineCreateOptions<TWorkflowDefinitions extends Record<string, AnyW
|
|
|
63
49
|
/** Only valid when recovery is enabled (the default). Invalid with `recover: false`. */
|
|
64
50
|
acknowledgeUnknownWorkflowTypes?: never;
|
|
65
51
|
});
|
|
52
|
+
/**
|
|
53
|
+
* Resolves the workflow registry type for `Engine.create` return values.
|
|
54
|
+
*
|
|
55
|
+
* When the provided workflow definition map is empty (`{}`), the resulting
|
|
56
|
+
* engine carries the same `DefaultWorkflowRegistry` brand as an engine
|
|
57
|
+
* constructed without a `workflows` map at all — the two are semantically
|
|
58
|
+
* identical. A non-empty map routes to `InferWorkflowEntries` so literal
|
|
59
|
+
* workflow-name inference is preserved.
|
|
60
|
+
*/
|
|
61
|
+
export type EngineCreateWorkflowRegistry<TWorkflowDefinitions extends Record<string, AnyWorkflowDefinition>> = [keyof TWorkflowDefinitions & string] extends [never] ? DefaultWorkflowRegistry : InferWorkflowEntries<TWorkflowDefinitions>;
|
|
66
62
|
export type UnknownWorkflowNameWhenDefaultRegistryIsEmpty<TWorkflows extends object, TName extends string> = IsDefaultWorkflowRegistry<TWorkflows> extends true ? UnknownNameWhenRegistryHasNoKnownNames<TName, KnownWorkflowNames<TWorkflows>> : never;
|
|
67
63
|
export type ActivityDefinitionName<TDefinition extends AnyActivityDefinition> = TDefinition extends {
|
|
68
64
|
readonly name: infer TName extends string;
|
|
@@ -2,7 +2,7 @@ import type { Storage as WeftStorage } from '../../storage/interface.ts';
|
|
|
2
2
|
import type { ConstraintDefinition } from '../constraint.ts';
|
|
3
3
|
import type { ExecutionStrategy } from '../execution-strategy.ts';
|
|
4
4
|
import type { InlineExecutionStrategy } from '../inline-execution-strategy.ts';
|
|
5
|
-
import type { ArchiveAdapter, Checkpoint, DefinitionSchema, EngineOptions, NormalizedHistoryPolicy, NormalizedPayloadSizePolicy, NormalizedRetentionPolicy, SearchAttributeSchema, WorkflowFunction, WorkflowTimelineEntry } from '../types.ts';
|
|
5
|
+
import type { AnyActivityDefinition, ArchiveAdapter, Checkpoint, DefinitionSchema, EngineOptions, NormalizedHistoryPolicy, NormalizedPayloadSizePolicy, NormalizedRetentionPolicy, SearchAttributeSchema, WorkflowConcurrencyOptions, WorkflowFunction, WorkflowTimelineEntry } from '../types.ts';
|
|
6
6
|
export interface RegistrationEntry {
|
|
7
7
|
handler: WorkflowFunction;
|
|
8
8
|
version: string;
|
|
@@ -10,10 +10,16 @@ export interface RegistrationEntry {
|
|
|
10
10
|
tags?: ReadonlyArray<string>;
|
|
11
11
|
inputSchema?: DefinitionSchema;
|
|
12
12
|
outputSchema?: DefinitionSchema;
|
|
13
|
-
migrate?: (checkpoint: unknown, fromVersion: string) => unknown;
|
|
14
13
|
searchAttributes?: SearchAttributeSchema;
|
|
15
14
|
retention?: NormalizedRetentionPolicy;
|
|
15
|
+
concurrency?: WorkflowConcurrencyOptions;
|
|
16
16
|
constraints?: ConstraintDefinition[];
|
|
17
|
+
/**
|
|
18
|
+
* Definition-level teardown activity (issue #446), driven by the engine after a
|
|
19
|
+
* `cancelled`/`timed-out` terminal. Stored on the engine-lifetime registry so it
|
|
20
|
+
* survives per-workflow terminal cleanup; resolved at teardown by workflow type.
|
|
21
|
+
*/
|
|
22
|
+
finalizer?: AnyActivityDefinition;
|
|
17
23
|
}
|
|
18
24
|
export interface ResolvedOptions {
|
|
19
25
|
storage: WeftStorage;
|
|
@@ -29,19 +35,40 @@ export interface ResolvedOptions {
|
|
|
29
35
|
/** Operator-supplied sink for compacted event-log ranges; `null` when none. */
|
|
30
36
|
archiveAdapter: ArchiveAdapter | null;
|
|
31
37
|
payloadSizePolicy: NormalizedPayloadSizePolicy;
|
|
38
|
+
/** Whether the best-effort second-instance liveness detector is enabled. */
|
|
39
|
+
secondInstanceDetectionEnabled: boolean;
|
|
40
|
+
/** Heartbeat interval (ms) for the second-instance detector when enabled. */
|
|
41
|
+
secondInstanceHeartbeatIntervalMs: number;
|
|
42
|
+
/**
|
|
43
|
+
* Single-writer ownership posture. `'none'` recovers immediately (infra owns
|
|
44
|
+
* mutual exclusion); `'lease'` acquires a storage lease before recovery. The
|
|
45
|
+
* lease tuning fields below are only meaningful when this is `'lease'`.
|
|
46
|
+
*/
|
|
47
|
+
ownershipMode: 'none' | 'lease';
|
|
48
|
+
/** Lease time-to-live (ms) when `ownershipMode` is `'lease'`. */
|
|
49
|
+
leaseTtlMs: number;
|
|
50
|
+
/** Lease renewal interval (ms) when `ownershipMode` is `'lease'`. */
|
|
51
|
+
leaseRenewIntervalMs: number;
|
|
52
|
+
/** Boot-time lease acquisition wait window (ms) when `ownershipMode` is `'lease'`. */
|
|
53
|
+
leaseWaitTimeoutMs: number;
|
|
32
54
|
getNow: () => number;
|
|
33
55
|
/**
|
|
34
56
|
* Re-provides the non-serialized per-run `services` value on recovery; `null`
|
|
35
57
|
* when the engine was created without `resolveWorkflowServices`.
|
|
36
58
|
*/
|
|
37
59
|
resolveWorkflowServices: EngineOptions['resolveWorkflowServices'] | null;
|
|
60
|
+
/**
|
|
61
|
+
* Host sink for `ctx.log` records (`EngineOptions.onLog`); `null` when the engine
|
|
62
|
+
* was created without one (the default console behavior).
|
|
63
|
+
*/
|
|
64
|
+
onLog: EngineOptions['onLog'] | null;
|
|
38
65
|
}
|
|
39
66
|
export interface WorkflowResultWaiter {
|
|
40
67
|
promise: Promise<unknown>;
|
|
41
68
|
resolve: (value: unknown) => void;
|
|
42
69
|
reject: (reason: unknown) => void;
|
|
43
70
|
}
|
|
44
|
-
export type EngineConstructorOptions = Partial<EngineOptions
|
|
71
|
+
export type EngineConstructorOptions<TServices = unknown> = Partial<EngineOptions<TServices>> & {
|
|
45
72
|
getNow?: () => number;
|
|
46
73
|
};
|
|
47
74
|
export type ExecutionStrategyBundle = {
|
|
@@ -61,4 +88,12 @@ export type QueuedInlineWorkflowExecutionStart = {
|
|
|
61
88
|
nestingDepth: number;
|
|
62
89
|
executionDeadline: number | undefined;
|
|
63
90
|
executionStateOwnerId: string;
|
|
91
|
+
/**
|
|
92
|
+
* Liveness callback invoked once this queued start has actually begun
|
|
93
|
+
* executing (its generator has been driven). Set only for `defer: false`
|
|
94
|
+
* launches, which await it before `engine.start()` resolves. Fired exactly
|
|
95
|
+
* once; a discarded start (engine disposed without draining) settles it via
|
|
96
|
+
* the dispose path so the `defer: false` awaiter never hangs.
|
|
97
|
+
*/
|
|
98
|
+
onStarted?: () => void;
|
|
64
99
|
};
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
export type EngineCleanupIntervalDisposalTracker = {
|
|
7
7
|
disposed: boolean;
|
|
8
8
|
cleanupInterval: ReturnType<typeof setInterval> | null;
|
|
9
|
+
/**
|
|
10
|
+
* The optional second-instance detector interval, tracked alongside the
|
|
11
|
+
* cleanup interval so the same finalizer clears it when an engine is
|
|
12
|
+
* garbage-collected without `[Symbol.dispose]()`. Null when detection is off.
|
|
13
|
+
*/
|
|
14
|
+
secondInstanceDetectionInterval: ReturnType<typeof setInterval> | null;
|
|
9
15
|
testToken: symbol | undefined;
|
|
10
16
|
};
|
|
11
17
|
export declare const engineCleanupIntervalFinalizer: FinalizationRegistry<EngineCleanupIntervalDisposalTracker>;
|
|
@@ -6,6 +6,10 @@ export const engineCleanupIntervalFinalizer = new FinalizationRegistry((tracker)
|
|
|
6
6
|
clearInterval(tracker.cleanupInterval);
|
|
7
7
|
tracker.cleanupInterval = null;
|
|
8
8
|
}
|
|
9
|
+
if (tracker.secondInstanceDetectionInterval !== null) {
|
|
10
|
+
clearInterval(tracker.secondInstanceDetectionInterval);
|
|
11
|
+
tracker.secondInstanceDetectionInterval = null;
|
|
12
|
+
}
|
|
9
13
|
if (!tracker.disposed && shouldEmitEngineLeakWarning()) {
|
|
10
14
|
if (tracker.testToken !== void 0)
|
|
11
15
|
engineLeakWarningTokensForTesting.add(tracker.testToken);
|
|
@@ -2,7 +2,24 @@ import type { AnyActivityDefinition } from '../types.ts';
|
|
|
2
2
|
import { type EngineCleanupIntervalDisposalTracker } from './engine-leak-warnings.ts';
|
|
3
3
|
import type { Engine } from './index.ts';
|
|
4
4
|
import { type EngineInternals } from './internals.ts';
|
|
5
|
+
import type { SecondInstanceDetector } from './second-instance-detector.ts';
|
|
5
6
|
export declare function isActivityDefinition(value: unknown): value is AnyActivityDefinition;
|
|
6
7
|
export declare function createQueuedInlineWorkflowStartHandler<TWorkflows extends object, TActivities extends object>(weakEngine: WeakRef<Engine<TWorkflows, TActivities>>, channel: MessageChannel): () => void;
|
|
8
|
+
/**
|
|
9
|
+
* Drain pending inline launches for `engine` before teardown. Built with the
|
|
10
|
+
* same inline-launch-queue callbacks as the scheduled flush handler so a drained
|
|
11
|
+
* start advances identically to a normally-flushed one. Called from
|
|
12
|
+
* `[Symbol.asyncDispose]` ahead of synchronous disposal (which aborts the signal
|
|
13
|
+
* and would otherwise discard the queue).
|
|
14
|
+
*/
|
|
15
|
+
export declare function drainQueuedInlineWorkflowStartsForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): Promise<void>;
|
|
7
16
|
export declare function createCleanupIntervalTick<TWorkflows extends object, TActivities extends object>(weakEngine: WeakRef<Engine<TWorkflows, TActivities>>, tracker: EngineCleanupIntervalDisposalTracker): () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Build the resolver the second-instance detection interval uses to find its live
|
|
19
|
+
* detector. Returns `null` when the engine has been garbage-collected or disposed
|
|
20
|
+
* (so the tick is skipped), otherwise the engine's current detector. Extracted
|
|
21
|
+
* here — like {@link createCleanupIntervalTick} — so the deref/disposed guard is
|
|
22
|
+
* directly testable without driving a real interval.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createSecondInstanceDetectorResolver<TWorkflows extends object, TActivities extends object>(weakEngine: WeakRef<Engine<TWorkflows, TActivities>>): () => SecondInstanceDetector | null;
|
|
8
25
|
export declare function disposeEngineCleanupInterval(internals: EngineInternals): void;
|
|
@@ -3,12 +3,22 @@ import { createLifecycleCallbacks, createTerminationCallbacks } from "./callback
|
|
|
3
3
|
import {
|
|
4
4
|
engineCleanupIntervalFinalizer
|
|
5
5
|
} from "./engine-leak-warnings.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
drainQueuedInlineWorkflowStarts,
|
|
8
|
+
flushQueuedInlineWorkflowStarts
|
|
9
|
+
} from "./inline-launch-queue.js";
|
|
7
10
|
import { getInternals } from "./internals.js";
|
|
8
11
|
import { swallowPromiseRejection } from "./strategy-helpers.js";
|
|
9
12
|
export function isActivityDefinition(value) {
|
|
10
13
|
return typeof value === "function" && typeof value.name === "string" && "execute" in value && typeof value.execute === "function";
|
|
11
14
|
}
|
|
15
|
+
function inlineLaunchQueueCallbacksForEngine(engine) {
|
|
16
|
+
const lifecycleCallbacks = createLifecycleCallbacks(engine);
|
|
17
|
+
return {
|
|
18
|
+
processPendingUpdatesAfterInlineAdvance: (workflowId) => lifecycleCallbacks.processPendingUpdatesAfterInlineAdvance(workflowId),
|
|
19
|
+
swallowPromiseRejection: (promise) => swallowPromiseRejection(promise)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
12
22
|
export function createQueuedInlineWorkflowStartHandler(weakEngine, channel) {
|
|
13
23
|
return function handleQueuedInlineWorkflowStart() {
|
|
14
24
|
const engine = weakEngine.deref();
|
|
@@ -18,12 +28,12 @@ export function createQueuedInlineWorkflowStartHandler(weakEngine, channel) {
|
|
|
18
28
|
return;
|
|
19
29
|
}
|
|
20
30
|
getInternals(engine).queuedInlineWorkflowStartFlushScheduled = !1;
|
|
21
|
-
swallowPromiseRejection(flushQueuedInlineWorkflowStarts(getInternals(engine),
|
|
22
|
-
processPendingUpdatesAfterInlineAdvance: (workflowId) => createLifecycleCallbacks(engine).processPendingUpdatesAfterInlineAdvance(workflowId),
|
|
23
|
-
swallowPromiseRejection: (promise) => swallowPromiseRejection(promise)
|
|
24
|
-
}));
|
|
31
|
+
swallowPromiseRejection(flushQueuedInlineWorkflowStarts(getInternals(engine), inlineLaunchQueueCallbacksForEngine(engine)));
|
|
25
32
|
};
|
|
26
33
|
}
|
|
34
|
+
export async function drainQueuedInlineWorkflowStartsForEngine(engine) {
|
|
35
|
+
await drainQueuedInlineWorkflowStarts(getInternals(engine), inlineLaunchQueueCallbacksForEngine(engine));
|
|
36
|
+
}
|
|
27
37
|
export function createCleanupIntervalTick(weakEngine, tracker) {
|
|
28
38
|
return function cleanupExpiredResponsesForLiveEngine() {
|
|
29
39
|
const engine = weakEngine.deref();
|
|
@@ -38,6 +48,17 @@ export function createCleanupIntervalTick(weakEngine, tracker) {
|
|
|
38
48
|
createExpiredResponseCleanupTick(internals.updateCoordinator, (source, error) => createTerminationCallbacks(engine).handleCleanupError(source, error))();
|
|
39
49
|
};
|
|
40
50
|
}
|
|
51
|
+
export function createSecondInstanceDetectorResolver(weakEngine) {
|
|
52
|
+
return function resolveLiveSecondInstanceDetector() {
|
|
53
|
+
const engine = weakEngine.deref();
|
|
54
|
+
if (engine === void 0)
|
|
55
|
+
return null;
|
|
56
|
+
const internals = getInternals(engine);
|
|
57
|
+
if (internals.disposed)
|
|
58
|
+
return null;
|
|
59
|
+
return internals.secondInstanceDetector;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
41
62
|
export function disposeEngineCleanupInterval(internals) {
|
|
42
63
|
if (internals.cleanupInterval !== null) {
|
|
43
64
|
clearInterval(internals.cleanupInterval ?? void 0);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WorkflowStatus } from '../types/identity.ts';
|
|
1
2
|
import { WeftError } from '../weft-error.ts';
|
|
2
3
|
/**
|
|
3
4
|
* Thrown by {@link Engine.start} when a workflow with the requested ID already
|
|
@@ -26,6 +27,29 @@ export declare class WorkflowAlreadyExistsError extends WeftError<'WorkflowAlrea
|
|
|
26
27
|
readonly workflowId: string;
|
|
27
28
|
constructor(workflowId: string);
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Thrown by {@link Engine.start} with `onTerminalConflict: 'start-new'` when the
|
|
32
|
+
* prior terminal run under the requested id still owes an engine-driven finalizer
|
|
33
|
+
* (issue #446). Unlike {@link WorkflowAlreadyExistsError}, this is **transient**:
|
|
34
|
+
* the restart is refused only so the displacing purge cannot delete the finalizer
|
|
35
|
+
* payload before the resource is torn down. Once the finalizer completes (or
|
|
36
|
+
* permanently dead-letters), the marker clears and the same restart succeeds — so a
|
|
37
|
+
* caller should retry after a short delay rather than treat the id as permanently
|
|
38
|
+
* taken.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { WorkflowTeardownPendingError } from '@lostgradient/weft';
|
|
43
|
+
*
|
|
44
|
+
* function shouldRetryRestartLater(error: unknown): boolean {
|
|
45
|
+
* return error instanceof WorkflowTeardownPendingError;
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class WorkflowTeardownPendingError extends WeftError<'WorkflowTeardownPendingError'> {
|
|
50
|
+
readonly workflowId: string;
|
|
51
|
+
constructor(workflowId: string);
|
|
52
|
+
}
|
|
29
53
|
/**
|
|
30
54
|
* Thrown by {@link Engine.deleteAll} when the supplied filter would match
|
|
31
55
|
* non-terminal workflows. Narrow the filter to completed, failed, cancelled,
|
|
@@ -186,6 +210,56 @@ export declare class WorkflowNotRegisteredError extends WeftError<'WorkflowNotRe
|
|
|
186
210
|
readonly workflowType: string;
|
|
187
211
|
constructor(workflowType: string);
|
|
188
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Thrown by {@link Engine.start} when a workflow definition's `concurrency`
|
|
215
|
+
* policy has no free slot for the requested workflow type or partition key.
|
|
216
|
+
* Starts are rejected immediately; Weft does not queue excess starts.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* import { WorkflowConcurrencyLimitExceededError } from '@lostgradient/weft';
|
|
221
|
+
*
|
|
222
|
+
* function isCapacityRejection(error: unknown): boolean {
|
|
223
|
+
* return error instanceof WorkflowConcurrencyLimitExceededError;
|
|
224
|
+
* }
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
export declare class WorkflowConcurrencyLimitExceededError extends WeftError<'WorkflowConcurrencyLimitExceededError'> {
|
|
228
|
+
readonly workflowType: string;
|
|
229
|
+
readonly limit: number;
|
|
230
|
+
readonly partitionKey: string;
|
|
231
|
+
constructor(parameters: {
|
|
232
|
+
workflowType: string;
|
|
233
|
+
limit: number;
|
|
234
|
+
partitionKey: string;
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Thrown by {@link Engine.suspend} when invoked on an engine running in worker
|
|
239
|
+
* execution mode. Suspension parks the live run without aborting it, which the
|
|
240
|
+
* inline strategy supports directly; a worker run cannot be paused without
|
|
241
|
+
* sending it a cancellation, so the engine refuses rather than silently
|
|
242
|
+
* aborting. Suspend/resume in worker mode is a scoped follow-up.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* import { Engine, WorkflowSuspendNotSupportedError } from '@lostgradient/weft';
|
|
247
|
+
*
|
|
248
|
+
* async function trySuspend(engine: Engine, id: string) {
|
|
249
|
+
* try {
|
|
250
|
+
* await engine.suspend(id);
|
|
251
|
+
* } catch (err) {
|
|
252
|
+
* if (err instanceof WorkflowSuspendNotSupportedError) {
|
|
253
|
+
* // worker-mode engine: cancel instead, or run inline
|
|
254
|
+
* }
|
|
255
|
+
* }
|
|
256
|
+
* }
|
|
257
|
+
* void trySuspend;
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export declare class WorkflowSuspendNotSupportedError extends WeftError<'WorkflowSuspendNotSupportedError'> {
|
|
261
|
+
constructor(message: string);
|
|
262
|
+
}
|
|
189
263
|
/**
|
|
190
264
|
* Thrown when the engine cannot resolve an activity name to a registered
|
|
191
265
|
* function during dispatch. The per-workflow {@link ActivityRegistry} (built
|
|
@@ -212,4 +286,51 @@ export declare class ActivityResolutionError extends WeftError<'ActivityResoluti
|
|
|
212
286
|
readonly activityName: string;
|
|
213
287
|
constructor(workflowType: string, activityName: string);
|
|
214
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Thrown by {@link Engine.startOrSignal} when the target workflow already exists
|
|
291
|
+
* and is in a terminal state (completed, failed, cancelled, or timed out). A
|
|
292
|
+
* terminal run cannot accept a signal and must not be silently replaced, so
|
|
293
|
+
* `startOrSignal` surfaces this conflict instead of starting a fresh run under
|
|
294
|
+
* the same id or dropping the signal.
|
|
295
|
+
*
|
|
296
|
+
* Inspect `workflowId` to identify the conflicting run and `status` to see why
|
|
297
|
+
* it was rejected. To deliberately start a new run, choose a different id (or
|
|
298
|
+
* idempotency key); to deliver to a fresh run, terminal-state reuse is not a
|
|
299
|
+
* supported policy.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* import { StartOrSignalConflictError } from '@lostgradient/weft';
|
|
304
|
+
*
|
|
305
|
+
* function isTerminalStartOrSignalConflict(error: unknown): boolean {
|
|
306
|
+
* return error instanceof StartOrSignalConflictError;
|
|
307
|
+
* }
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
export declare class StartOrSignalConflictError extends WeftError<'StartOrSignalConflictError'> {
|
|
311
|
+
readonly workflowId: string;
|
|
312
|
+
readonly status: WorkflowStatus;
|
|
313
|
+
constructor(workflowId: string, status: WorkflowStatus);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Thrown by {@link Engine.start} / {@link Engine.startOrSignal} when an
|
|
317
|
+
* `idempotencyKey` resolves to a workflow that no longer exists — its run was
|
|
318
|
+
* purged or bulk-deleted while the durable `start-idem:` mapping (intentionally
|
|
319
|
+
* not swept on cleanup) lived on. The key is "spent": it can neither return the
|
|
320
|
+
* gone run nor safely start a fresh one under the same key (a concurrent caller
|
|
321
|
+
* may still hold the mapping). Use a different idempotency key to start anew.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* import { IdempotencyKeyPurgedError } from '@lostgradient/weft';
|
|
326
|
+
*
|
|
327
|
+
* function isPurgedIdempotencyKey(error: unknown): boolean {
|
|
328
|
+
* return error instanceof IdempotencyKeyPurgedError;
|
|
329
|
+
* }
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
export declare class IdempotencyKeyPurgedError extends WeftError<'IdempotencyKeyPurgedError'> {
|
|
333
|
+
readonly workflowId: string;
|
|
334
|
+
constructor(workflowId: string);
|
|
335
|
+
}
|
|
215
336
|
export { PersistedDataIncompatibleError } from '../persisted-data-incompatible-error.ts';
|
|
@@ -8,6 +8,14 @@ export class WorkflowAlreadyExistsError extends WeftError {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export class WorkflowTeardownPendingError extends WeftError {
|
|
12
|
+
workflowId;
|
|
13
|
+
constructor(workflowId) {
|
|
14
|
+
super("WorkflowTeardownPendingError", `Cannot restart workflow "${workflowId}" under the same id: its prior run is tearing down a resource (finalizer in progress). Retry after the teardown completes.`);
|
|
15
|
+
this.workflowId = workflowId;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
export class BulkDeleteRequiresTerminalWorkflowsError extends WeftError {
|
|
12
20
|
constructor() {
|
|
13
21
|
super("BulkDeleteRequiresTerminalWorkflowsError", "Bulk delete matches non-terminal workflows");
|
|
@@ -78,13 +86,49 @@ export class WorkflowNotRegisteredError extends WeftError {
|
|
|
78
86
|
}
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
export class WorkflowConcurrencyLimitExceededError extends WeftError {
|
|
90
|
+
workflowType;
|
|
91
|
+
limit;
|
|
92
|
+
partitionKey;
|
|
93
|
+
constructor(parameters) {
|
|
94
|
+
super("WorkflowConcurrencyLimitExceededError", `Workflow "${parameters.workflowType}" concurrency limit ${parameters.limit} reached for partition key "${parameters.partitionKey}"`);
|
|
95
|
+
this.workflowType = parameters.workflowType;
|
|
96
|
+
this.limit = parameters.limit;
|
|
97
|
+
this.partitionKey = parameters.partitionKey;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export class WorkflowSuspendNotSupportedError extends WeftError {
|
|
102
|
+
constructor(message) {
|
|
103
|
+
super("WorkflowSuspendNotSupportedError", message);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
81
107
|
export class ActivityResolutionError extends WeftError {
|
|
82
108
|
workflowType;
|
|
83
109
|
activityName;
|
|
84
110
|
constructor(workflowType, activityName) {
|
|
85
|
-
super("ActivityResolutionError", `No activity registered with name "${activityName}" for workflow type "${workflowType}". Register the activity via \`workflow({ name }).activities({ ... })\` on the workflow that runs it, or via \`engine.register(activityDefinition)\`
|
|
111
|
+
super("ActivityResolutionError", `No activity registered with name "${activityName}" for workflow type "${workflowType}". Register the activity via \`workflow({ name }).activities({ ... })\` on the workflow that runs it, or via \`engine.register(activityDefinition)\` to make it available to every workflow on that engine instance.`);
|
|
86
112
|
this.workflowType = workflowType;
|
|
87
113
|
this.activityName = activityName;
|
|
88
114
|
}
|
|
89
115
|
}
|
|
116
|
+
|
|
117
|
+
export class StartOrSignalConflictError extends WeftError {
|
|
118
|
+
workflowId;
|
|
119
|
+
status;
|
|
120
|
+
constructor(workflowId, status) {
|
|
121
|
+
super("StartOrSignalConflictError", `Workflow "${workflowId}" is already in terminal state "${status}" and cannot accept a startOrSignal: a terminal run cannot be signalled and is not replaced. Use a different id or idempotency key to start a new run.`);
|
|
122
|
+
this.workflowId = workflowId;
|
|
123
|
+
this.status = status;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class IdempotencyKeyPurgedError extends WeftError {
|
|
128
|
+
workflowId;
|
|
129
|
+
constructor(workflowId) {
|
|
130
|
+
super("IdempotencyKeyPurgedError", `The idempotency key maps to workflow "${workflowId}", which no longer exists (it was purged or deleted). Use a different idempotency key to start a new run.`);
|
|
131
|
+
this.workflowId = workflowId;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
90
134
|
export { PersistedDataIncompatibleError } from "../persisted-data-incompatible-error.js";
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* @module core/engine/event-log-compaction
|
|
19
19
|
*/
|
|
20
20
|
import type { BatchOperation, Storage } from '../../storage/interface.ts';
|
|
21
|
+
import { type CheckpointReplayPayload } from './checkpoint-replay.ts';
|
|
21
22
|
/**
|
|
22
23
|
* Upper bound on event-log records deleted in a single compaction (one
|
|
23
24
|
* checkpoint commit). A workflow that enables `retentionWindow` with a large
|
|
@@ -52,6 +53,13 @@ export type EventLogWatermark = {
|
|
|
52
53
|
* deleted prefix — unambiguous across incremental batches.
|
|
53
54
|
*/
|
|
54
55
|
deletedThrough: number;
|
|
56
|
+
/**
|
|
57
|
+
* Internal replay deltas folded from compacted checkpoint events. Canonical
|
|
58
|
+
* checkpoints can prune consumed results only because recovery can seed replay
|
|
59
|
+
* from the event log; when old events are compacted, their replay deltas move
|
|
60
|
+
* here before deletion.
|
|
61
|
+
*/
|
|
62
|
+
checkpointReplay?: CheckpointReplayPayload;
|
|
55
63
|
};
|
|
56
64
|
/**
|
|
57
65
|
* Narrow an unknown decoded value to {@link EventLogWatermark}, rejecting
|
|
@@ -2,6 +2,10 @@ import { hashBytes } from "../../runtime/portable.js";
|
|
|
2
2
|
import { KEYS } from "../../storage/interface.js";
|
|
3
3
|
import { decode, encode } from "../codec.js";
|
|
4
4
|
import { isWorkflowLogEntry } from "../event-log-shared.js";
|
|
5
|
+
import {
|
|
6
|
+
mergeCheckpointReplayPayloads,
|
|
7
|
+
readCheckpointReplayPayload
|
|
8
|
+
} from "./checkpoint-replay.js";
|
|
5
9
|
export const MAX_COMPACTION_BATCH = 1000;
|
|
6
10
|
export function isEventLogWatermark(value) {
|
|
7
11
|
if (typeof value !== "object" || value === null)
|
|
@@ -27,7 +31,7 @@ export async function readEventLogWatermark(storage, workflowId) {
|
|
|
27
31
|
export async function appendCompactionOperations(storage, workflowId, headSequence, retentionWindow, operations) {
|
|
28
32
|
if (retentionWindow === null)
|
|
29
33
|
return null;
|
|
30
|
-
const targetFirstSurviving = Math.max(0, headSequence - retentionWindow + 1),
|
|
34
|
+
const targetFirstSurviving = Math.max(0, headSequence - retentionWindow + 1), existing = await readEventLogWatermark(storage, workflowId), currentFloor = existing?.sequence ?? 0, batchFirstSurviving = Math.min(targetFirstSurviving, currentFloor + MAX_COMPACTION_BATCH);
|
|
31
35
|
if (batchFirstSurviving <= currentFloor)
|
|
32
36
|
return null;
|
|
33
37
|
const collected = await collectDeleteRange(storage, workflowId, currentFloor, batchFirstSurviving);
|
|
@@ -38,7 +42,8 @@ export async function appendCompactionOperations(storage, workflowId, headSequen
|
|
|
38
42
|
version: 1,
|
|
39
43
|
sequence: batchFirstSurviving,
|
|
40
44
|
prevHash,
|
|
41
|
-
deletedThrough: batchFirstSurviving - 1
|
|
45
|
+
deletedThrough: batchFirstSurviving - 1,
|
|
46
|
+
...optionalCheckpointReplay(mergeDeletedCheckpointReplayPayloads(existing?.checkpointReplay, collected.deletedEntries))
|
|
42
47
|
};
|
|
43
48
|
for (let sequence = currentFloor;sequence < batchFirstSurviving; sequence += 1)
|
|
44
49
|
operations.push({ type: "delete", key: KEYS.event(workflowId, sequence) });
|
|
@@ -53,6 +58,19 @@ export async function appendCompactionOperations(storage, workflowId, headSequen
|
|
|
53
58
|
deletedRange: { from: currentFloor, to: batchFirstSurviving - 1 }
|
|
54
59
|
};
|
|
55
60
|
}
|
|
61
|
+
function optionalCheckpointReplay(checkpointReplay) {
|
|
62
|
+
return checkpointReplay === void 0 ? {} : { checkpointReplay };
|
|
63
|
+
}
|
|
64
|
+
function mergeDeletedCheckpointReplayPayloads(existing, deletedEntries) {
|
|
65
|
+
let merged = existing;
|
|
66
|
+
for (const bytes of deletedEntries) {
|
|
67
|
+
const decoded = decode(bytes);
|
|
68
|
+
if (!isWorkflowLogEntry(decoded))
|
|
69
|
+
continue;
|
|
70
|
+
merged = mergeCheckpointReplayPayloads(merged, readCheckpointReplayPayload(decoded.payload));
|
|
71
|
+
}
|
|
72
|
+
return merged;
|
|
73
|
+
}
|
|
56
74
|
async function collectDeleteRange(storage, workflowId, currentFloor, batchFirstSurviving) {
|
|
57
75
|
const deletedEntries = [];
|
|
58
76
|
let expected = currentFloor;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step-2 epoch fencing for `ownership: 'lease'` (issue #470).
|
|
3
|
+
*
|
|
4
|
+
* Step 1 made a rolling deploy a clean lease handoff but added no correctness
|
|
5
|
+
* backstop: a deposed zombie instance (GC pause, partition) that emerged after
|
|
6
|
+
* its lease expired could still issue a plain durable write and corrupt the
|
|
7
|
+
* successor's state. Step 2 closes that hole by conditioning every
|
|
8
|
+
* engine-generator-owned per-workflow durable write on the held lease epoch, so
|
|
9
|
+
* a deposed instance's write loses its CAS instead of landing.
|
|
10
|
+
*
|
|
11
|
+
* The correctness guarantee lives entirely in the epoch CONDITION: a deposed
|
|
12
|
+
* instance's commit CAS-fails regardless of any in-process flag, because the
|
|
13
|
+
* successor bumped `lease:epoch` when it took over. The {@link EngineInternals.deposed}
|
|
14
|
+
* flag and the engine teardown are hygiene on top of that — they stop the engine
|
|
15
|
+
* from silently spinning on swallowed write losses, surface the deposition to the
|
|
16
|
+
* operator, and release resources. They are not what makes the system safe.
|
|
17
|
+
*
|
|
18
|
+
* This module is allow-listed for import only from `src/core/engine/**`.
|
|
19
|
+
*/
|
|
20
|
+
import type { BatchOperation, ConditionalBatchCondition } from '../../storage/interface.ts';
|
|
21
|
+
import type { EngineInternals } from './internals.ts';
|
|
22
|
+
/**
|
|
23
|
+
* Reject an engine-owned work entry point (start, startOrSignal, fork, resume)
|
|
24
|
+
* when `ownership: 'lease'` is configured but the engine does not currently hold
|
|
25
|
+
* the lease. The lease is acquired at the two boot gates ({@link Engine.create}
|
|
26
|
+
* and {@link Engine.recoverAll}); a directly constructed engine that does engine
|
|
27
|
+
* work before `recoverAll()` would otherwise durably write workflow state without
|
|
28
|
+
* single-writer ownership and without having recovered existing runs. Placed at
|
|
29
|
+
* each public awaited entry so the caller gets a clean {@link EngineLeaseNotHeldError}
|
|
30
|
+
* — without this, fork/resume would reach `resolveFenceEpochOrHalt` with no held
|
|
31
|
+
* epoch and be misreported as a deposition (warn + teardown) rather than the true
|
|
32
|
+
* "lease not held yet" condition. A no-op under `ownership: 'none'`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function assertLeaseHeldForEngineWork(internals: EngineInternals): void;
|
|
35
|
+
/**
|
|
36
|
+
* Commit an engine-generator-owned durable write, fenced on the held lease epoch
|
|
37
|
+
* under `ownership: 'lease'` (a byte-for-byte no-op under `ownership: 'none'`). A
|
|
38
|
+
* lost CAS race throws the caller-supplied `onLostRace` error so existing retry
|
|
39
|
+
* semantics apply; a deposition halts the engine and throws
|
|
40
|
+
* {@link EngineDeposedError}. The helper owns the batch-vs-conditionalBatch
|
|
41
|
+
* decision — pass plain operations plus whatever base conditions you already need.
|
|
42
|
+
*
|
|
43
|
+
* @param internals - the engine internals (ownership mode, lease manager, deposed flag)
|
|
44
|
+
* @param operations - the durable operations to commit atomically
|
|
45
|
+
* @param baseConditions - CAS conditions the caller already requires (may be empty)
|
|
46
|
+
* @param onLostRace - builds the error thrown on a same-epoch lost CAS race
|
|
47
|
+
*/
|
|
48
|
+
export declare function commitFencedEngineWrite(internals: EngineInternals, operations: BatchOperation[], baseConditions: ConditionalBatchCondition[], onLostRace: () => Error): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Like {@link commitFencedEngineWrite}, but the caller treats a base-precondition
|
|
51
|
+
* failure as a legitimate outcome rather than an error — used by the idempotent
|
|
52
|
+
* start path, where a `false` means a concurrent same-key caller already wrote the
|
|
53
|
+
* record (resolve to the existing run) rather than "retry". Returns `true` when the
|
|
54
|
+
* batch committed and `false` when a base condition failed. Deposition is still a
|
|
55
|
+
* hard halt: if the epoch condition is the one that failed, this drives
|
|
56
|
+
* {@link handleDeposition} and throws {@link EngineDeposedError} — a deposed engine
|
|
57
|
+
* must never report a precondition-failure the caller would read as "already exists"
|
|
58
|
+
* and silently move on.
|
|
59
|
+
*
|
|
60
|
+
* @param internals - the engine internals
|
|
61
|
+
* @param operations - the durable operations to commit atomically
|
|
62
|
+
* @param baseConditions - the caller's required CAS conditions (non-empty in
|
|
63
|
+
* practice — this path is for conditional starts, which always carry one)
|
|
64
|
+
*/
|
|
65
|
+
export declare function commitFencedEngineWriteAllowingPreconditionFailure(internals: EngineInternals, operations: BatchOperation[], baseConditions: ConditionalBatchCondition[]): Promise<boolean>;
|