@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
|
@@ -35,6 +35,8 @@ function operationProcessors(callbacks) {
|
|
|
35
35
|
sleep: callbacks.processSleepOperation,
|
|
36
36
|
"wait-signal": callbacks.processWaitSignalOperation,
|
|
37
37
|
"wait-update": callbacks.processWaitUpdateOperation,
|
|
38
|
+
"wait-condition": callbacks.processWaitConditionOperation,
|
|
39
|
+
"get-version": callbacks.processGetVersionOperation,
|
|
38
40
|
parallel: callbacks.processParallelOperation,
|
|
39
41
|
race: callbacks.processRaceOperation,
|
|
40
42
|
memo: callbacks.processMemoOperation,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { finalizeAndUnwrap } from "./deferred-consume-envelope.js";
|
|
2
|
+
import { assertSupportedSignalBranches } from "./operations-coordination.js";
|
|
1
3
|
import { SpeculativeExecutionState } from "./speculative-execution-state.js";
|
|
2
4
|
export async function processSpeculateOperation(internals, workflowId, operation, callbacks) {
|
|
3
5
|
return callbacks.runOperationWithResult(workflowId, operation, () => executeSpeculativeBranch(internals, workflowId, operation, callbacks));
|
|
@@ -30,8 +32,10 @@ export async function driveSpeculativeGenerator(workflowId, generator, speculati
|
|
|
30
32
|
return iterationResult.value;
|
|
31
33
|
const nextOperation = iterationResult.value;
|
|
32
34
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
if (nextOperation.type === "race" || nextOperation.type === "parallel")
|
|
36
|
+
assertSupportedSignalBranches(nextOperation.operations);
|
|
37
|
+
const nextResult = await callbacks.executeSubOperation(workflowId, nextOperation, void 0, speculativeState), finalizedResult = await finalizeAndUnwrap(nextResult);
|
|
38
|
+
return advance(finalizedResult, void 0);
|
|
35
39
|
} catch (error) {
|
|
36
40
|
return advance(lastResult, error instanceof Error ? error : Error(String(error)));
|
|
37
41
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KEYS } from "../../storage/interface.js";
|
|
2
2
|
import { encode } from "../codec.js";
|
|
3
3
|
import { cleanupPartialStreamChunks, createCleanupErrorReporter } from "../engine-helpers.js";
|
|
4
|
-
import { loadStoredStreamChunks } from "./stream-chunk-loading.js";
|
|
4
|
+
import { encodeStoredStreamTailSequence, loadStoredStreamChunks } from "./stream-chunk-loading.js";
|
|
5
5
|
import { STREAM_CHUNK_KIND, TOKENS_STREAM_KEY, notifyWorkflowFeedCommit } from "./workflow-feed.js";
|
|
6
6
|
export async function getStreamChunksFromInternals(internals, workflowId, key, options) {
|
|
7
7
|
return loadStoredStreamChunks(internals.storage, workflowId, key, options);
|
|
@@ -33,7 +33,17 @@ export async function writeStreamChunksFromInternals(internals, workflowId, oper
|
|
|
33
33
|
let chunkCount = 0, totalSizeBytes = 0;
|
|
34
34
|
for await (const chunk of asyncGenerator) {
|
|
35
35
|
const encoded = encode(chunk), sequence = chunkCount, chunkKey = KEYS.streamChunk(workflowId, operation.key, sequence);
|
|
36
|
-
|
|
36
|
+
if (operation.key === TOKENS_STREAM_KEY)
|
|
37
|
+
await internals.storage.batch([
|
|
38
|
+
{ type: "put", key: chunkKey, value: encoded },
|
|
39
|
+
{
|
|
40
|
+
type: "put",
|
|
41
|
+
key: KEYS.streamTail(workflowId, operation.key),
|
|
42
|
+
value: encodeStoredStreamTailSequence(sequence)
|
|
43
|
+
}
|
|
44
|
+
]);
|
|
45
|
+
else
|
|
46
|
+
await internals.storage.put(chunkKey, encoded);
|
|
37
47
|
writtenKeys.push(chunkKey);
|
|
38
48
|
totalSizeBytes += encoded.byteLength;
|
|
39
49
|
chunkCount++;
|
|
@@ -8,6 +8,7 @@ type SleepOperation = Extract<ContextOperationRequest, {
|
|
|
8
8
|
}>;
|
|
9
9
|
export type TimeOperationCallbacks = {
|
|
10
10
|
completeOperation: (workflowId: string, value: unknown) => void;
|
|
11
|
+
dispatchEvent: (event: Event) => void;
|
|
11
12
|
loadWorkflowState: (workflowId: string) => Promise<WorkflowState | null>;
|
|
12
13
|
failWorkflow: (workflowId: string, error: Error) => Promise<void>;
|
|
13
14
|
runSerializedWorkflowStateWrite: <Result>(workflowId: string, writeOperation: () => Promise<Result>) => Promise<Result>;
|
|
@@ -17,6 +18,7 @@ export type TimeOperationCallbacks = {
|
|
|
17
18
|
loadWorkflowStartHeaders: (workflowId: string) => Promise<Map<string, string> | undefined>;
|
|
18
19
|
parseStartOptionDuration: (value: Duration, fieldName: 'options.executionTimeout' | 'options.startAfter') => number;
|
|
19
20
|
runDeferredTerminalCleanup: (workflowId: string, timerId: string) => Promise<void>;
|
|
21
|
+
runWorkflowFinalizer: (workflowId: string, timerId: string) => Promise<void>;
|
|
20
22
|
handleScheduleTimer: (entry: TimerEntry) => Promise<void>;
|
|
21
23
|
timeout: (workflowId: string) => Promise<void>;
|
|
22
24
|
handleCleanupError: (source: string, error: unknown, workflowId: string) => void;
|
|
@@ -24,6 +26,6 @@ export type TimeOperationCallbacks = {
|
|
|
24
26
|
export declare function createDelayedStartTimerEntry(_internals: EngineInternals, workflowId: string, scheduledStartAt: number, options: StartOptions | undefined, callbacks: Pick<TimeOperationCallbacks, 'parseStartOptionDuration'>): TimerEntry;
|
|
25
27
|
export declare function processSleepOperation(internals: EngineInternals, workflowId: string, operation: SleepOperation, callbacks: Pick<TimeOperationCallbacks, 'completeOperation' | 'loadWorkflowState'>): Promise<void>;
|
|
26
28
|
export declare function registerSleepResolver(internals: EngineInternals, workflowId: string, operationId: string, resolve: () => void): void;
|
|
27
|
-
export declare function startDelayedWorkflow(internals: EngineInternals, entry: TimerEntry, callbacks: Pick<TimeOperationCallbacks, 'beginWorkflowExecution' | 'failWorkflow' | 'handleCleanupError' | 'loadWorkflowStartHeaders' | 'loadWorkflowState' | 'runSerializedWorkflowStateWrite' | 'setWorkflowStartHeaders' | 'workflowVersionTupleFromState'>): Promise<void>;
|
|
28
|
-
export declare function handleTimerFired(internals: EngineInternals, entry: TimerEntry, callbacks: Pick<TimeOperationCallbacks, 'failWorkflow' | 'handleCleanupError' | 'loadWorkflowStartHeaders' | 'loadWorkflowState' | 'runDeferredTerminalCleanup' | 'runSerializedWorkflowStateWrite' | 'handleScheduleTimer' | 'setWorkflowStartHeaders' | 'timeout' | 'beginWorkflowExecution' | 'workflowVersionTupleFromState'>): Promise<void>;
|
|
29
|
+
export declare function startDelayedWorkflow(internals: EngineInternals, entry: TimerEntry, callbacks: Pick<TimeOperationCallbacks, 'beginWorkflowExecution' | 'dispatchEvent' | 'failWorkflow' | 'handleCleanupError' | 'loadWorkflowStartHeaders' | 'loadWorkflowState' | 'runSerializedWorkflowStateWrite' | 'setWorkflowStartHeaders' | 'workflowVersionTupleFromState'>): Promise<void>;
|
|
30
|
+
export declare function handleTimerFired(internals: EngineInternals, entry: TimerEntry, callbacks: Pick<TimeOperationCallbacks, 'failWorkflow' | 'handleCleanupError' | 'loadWorkflowStartHeaders' | 'loadWorkflowState' | 'runDeferredTerminalCleanup' | 'runWorkflowFinalizer' | 'runSerializedWorkflowStateWrite' | 'handleScheduleTimer' | 'setWorkflowStartHeaders' | 'timeout' | 'beginWorkflowExecution' | 'dispatchEvent' | 'workflowVersionTupleFromState'>): Promise<void>;
|
|
29
31
|
export {};
|
|
@@ -2,6 +2,7 @@ import { KEYS, storageHas } from "../../storage/interface.js";
|
|
|
2
2
|
import { deserializeCheckpoint } from "../checkpoint.js";
|
|
3
3
|
import { encode } from "../codec.js";
|
|
4
4
|
import { buildTimerBatchOperations, normalizeStorageTimestamp } from "../scheduler.js";
|
|
5
|
+
import { commitFencedEngineWrite } from "./fenced-write.js";
|
|
5
6
|
import { reprovideRecoveredServices } from "./lifecycle/recovered-services.js";
|
|
6
7
|
import { buildWorkflowVisibilityIndexTransition } from "./workflow-indexes.js";
|
|
7
8
|
export function createDelayedStartTimerEntry(_internals, workflowId, scheduledStartAt, options, callbacks) {
|
|
@@ -81,12 +82,12 @@ export async function startDelayedWorkflow(internals, entry, callbacks) {
|
|
|
81
82
|
fireAt: executionDeadline,
|
|
82
83
|
kind: "execution-deadline"
|
|
83
84
|
}));
|
|
84
|
-
await internals
|
|
85
|
+
await commitFencedEngineWrite(internals, operations, [], () => Error(`Delayed-start transition for workflow "${entry.workflowId}" lost its CAS race.`));
|
|
85
86
|
return nextRunningState;
|
|
86
87
|
});
|
|
87
88
|
if (!runningState)
|
|
88
89
|
return;
|
|
89
|
-
if (await reprovideRecoveredServices(internals, runningState, (workflowId, error) => callbacks.failWorkflow(workflowId, error), callbacks.handleCleanupError))
|
|
90
|
+
if (await reprovideRecoveredServices(internals, runningState, (workflowId, error) => callbacks.failWorkflow(workflowId, error), callbacks.handleCleanupError, callbacks.dispatchEvent))
|
|
90
91
|
return;
|
|
91
92
|
if (await storageHas(internals.storage, KEYS.terminalCleanupNeeded(entry.workflowId)))
|
|
92
93
|
internals.workflowsNeedingTerminalCleanup.add(entry.workflowId);
|
|
@@ -133,15 +134,26 @@ export async function handleTimerFired(internals, entry, callbacks) {
|
|
|
133
134
|
await callbacks.runDeferredTerminalCleanup(entry.workflowId, entry.id);
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
137
|
+
if (entry.kind === "teardown") {
|
|
138
|
+
await callbacks.runWorkflowFinalizer(entry.workflowId, entry.id);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
136
141
|
if (entry.kind === "schedule") {
|
|
137
142
|
await callbacks.handleScheduleTimer(entry);
|
|
138
143
|
return;
|
|
139
144
|
}
|
|
140
145
|
if (entry.kind === "sleep")
|
|
141
146
|
resolveSleepTimer(internals, entry);
|
|
147
|
+
else if (entry.kind === "wait-condition")
|
|
148
|
+
resolveConditionTimer(internals, entry);
|
|
142
149
|
else if (entry.kind === "execution-deadline")
|
|
143
150
|
await callbacks.timeout(entry.workflowId);
|
|
144
151
|
}
|
|
152
|
+
function resolveConditionTimer(internals, entry) {
|
|
153
|
+
const resolver = internals.conditionWaiters.get(entry.workflowId);
|
|
154
|
+
if (resolver)
|
|
155
|
+
resolver();
|
|
156
|
+
}
|
|
145
157
|
async function handleReviewTimer(internals, entry, callbacks) {
|
|
146
158
|
const reviewId = entry.id.split(":")[1];
|
|
147
159
|
if (!reviewId)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ContextOperationRequest } from '../context.ts';
|
|
2
|
+
import type { EngineInternals } from './internals.ts';
|
|
3
|
+
import type { CoordinationOperationCallbacks } from './operations-coordination.ts';
|
|
4
|
+
type WaitConditionOperation = Extract<ContextOperationRequest, {
|
|
5
|
+
type: 'wait-condition';
|
|
6
|
+
}>;
|
|
7
|
+
export type ConditionOperationCallbacks = Pick<CoordinationOperationCallbacks, 'completeOperation'> & {
|
|
8
|
+
/**
|
|
9
|
+
* Fail the pending operation, feeding the error to the generator so it
|
|
10
|
+
* re-throws at the `yield* ctx.waitUntil` site. Used when the user predicate
|
|
11
|
+
* throws — a throwing predicate must surface as a catchable workflow failure,
|
|
12
|
+
* not park the run forever.
|
|
13
|
+
*/
|
|
14
|
+
failOperation: (workflowId: string, operation: WaitConditionOperation, error: unknown) => void;
|
|
15
|
+
/** Whether the workflow is still running — gates completion after a wake. */
|
|
16
|
+
isWorkflowRunning: (workflowId: string) => Promise<boolean>;
|
|
17
|
+
/** Schedule the deterministic deadline timer (`cond:${workflowId}:${step}`). */
|
|
18
|
+
scheduleConditionDeadline: (workflowId: string, step: number, fireAt: number) => Promise<void>;
|
|
19
|
+
/** Cancel the deadline timer in storage on teardown. */
|
|
20
|
+
cancelConditionDeadline: (workflowId: string, step: number) => Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
export declare function processWaitConditionOperation(internals: EngineInternals, workflowId: string, operation: WaitConditionOperation, callbacks: ConditionOperationCallbacks): Promise<void>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function evaluateConditionOutcome(internals, predicate, deadline) {
|
|
2
|
+
if (predicate())
|
|
3
|
+
return { done: !0, value: deadline === void 0 ? void 0 : !0 };
|
|
4
|
+
if (deadline !== void 0 && internals.options.getNow() >= deadline)
|
|
5
|
+
return { done: !0, value: !1 };
|
|
6
|
+
return { done: !1 };
|
|
7
|
+
}
|
|
8
|
+
export async function processWaitConditionOperation(internals, workflowId, operation, callbacks) {
|
|
9
|
+
const abortSignal = internals.abortController.signal, { predicate, deadline } = operation;
|
|
10
|
+
let settled = !1;
|
|
11
|
+
const complete = (value) => {
|
|
12
|
+
if (settled)
|
|
13
|
+
return;
|
|
14
|
+
settled = !0;
|
|
15
|
+
callbacks.completeOperation(workflowId, value);
|
|
16
|
+
};
|
|
17
|
+
if (abortSignal.aborted)
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
const initial = evaluateConditionOutcome(internals, predicate, deadline);
|
|
21
|
+
if (initial.done) {
|
|
22
|
+
complete(initial.value);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (deadline !== void 0)
|
|
26
|
+
await callbacks.scheduleConditionDeadline(workflowId, operation.step, deadline);
|
|
27
|
+
try {
|
|
28
|
+
let step = await runConditionWaitStep(internals, workflowId, predicate, deadline, callbacks);
|
|
29
|
+
while (step.status === "continue")
|
|
30
|
+
step = await runConditionWaitStep(internals, workflowId, predicate, deadline, callbacks);
|
|
31
|
+
if (step.status === "complete")
|
|
32
|
+
complete(step.value);
|
|
33
|
+
} finally {
|
|
34
|
+
releaseConditionWaiter(internals, workflowId);
|
|
35
|
+
if (deadline !== void 0)
|
|
36
|
+
await callbacks.cancelConditionDeadline(workflowId, operation.step);
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
callbacks.failOperation(workflowId, operation, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function runConditionWaitStep(internals, workflowId, predicate, deadline, callbacks) {
|
|
43
|
+
const abortSignal = internals.abortController.signal;
|
|
44
|
+
if (abortSignal.aborted)
|
|
45
|
+
return { status: "stop" };
|
|
46
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
47
|
+
internals.conditionWaiters.set(workflowId, resolve);
|
|
48
|
+
const outcome = abortSignal.aborted ? { done: !0, value: void 0, aborted: !0 } : { ...evaluateConditionOutcome(internals, predicate, deadline), aborted: !1 };
|
|
49
|
+
if (outcome.done) {
|
|
50
|
+
releaseConditionWaiter(internals, workflowId);
|
|
51
|
+
return outcome.aborted ? { status: "stop" } : { status: "complete", value: outcome.value };
|
|
52
|
+
}
|
|
53
|
+
await promise;
|
|
54
|
+
if (abortSignal.aborted)
|
|
55
|
+
return { status: "stop" };
|
|
56
|
+
if (!await callbacks.isWorkflowRunning(workflowId))
|
|
57
|
+
return { status: "stop" };
|
|
58
|
+
return { status: "continue" };
|
|
59
|
+
}
|
|
60
|
+
function releaseConditionWaiter(internals, workflowId) {
|
|
61
|
+
internals.conditionWaiters.delete(workflowId);
|
|
62
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolution of the `ownership` posture options (`Engine.create({ ownership })`)
|
|
3
|
+
* into {@link ResolvedOptions}. Extracted from `construction.ts` to keep that
|
|
4
|
+
* file under the `max-lines` ceiling; mirrors the second-instance resolver's
|
|
5
|
+
* "only validate when the feature is enabled" discipline.
|
|
6
|
+
*
|
|
7
|
+
* @module core/engine/ownership-options
|
|
8
|
+
*/
|
|
9
|
+
import type { EngineConstructorOptions, ResolvedOptions } from './engine-internal-types.ts';
|
|
10
|
+
/** Default lease time-to-live for `ownership: 'lease'`. */
|
|
11
|
+
export declare const DEFAULT_LEASE_TTL_MS = 30000;
|
|
12
|
+
/** Default lease renewal interval for `ownership: 'lease'`. */
|
|
13
|
+
export declare const DEFAULT_LEASE_RENEW_INTERVAL_MS = 5000;
|
|
14
|
+
/** Default boot-time lease acquisition wait window for `ownership: 'lease'`. */
|
|
15
|
+
export declare const DEFAULT_LEASE_WAIT_TIMEOUT_MS = 60000;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the ownership posture and lease tuning into their `ResolvedOptions`
|
|
18
|
+
* fields. Defaults to `'none'`. The lease durations are documented as "ignored
|
|
19
|
+
* when ownership is not 'lease'", so they are only normalized (and thus only
|
|
20
|
+
* able to throw on an invalid value) when lease ownership is actually enabled —
|
|
21
|
+
* an invalid duration must not make an off-by-default config fatal at boot.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveOwnershipFields(options: EngineConstructorOptions | undefined): Pick<ResolvedOptions, 'ownershipMode' | 'leaseTtlMs' | 'leaseRenewIntervalMs' | 'leaseWaitTimeoutMs'>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { normalizeRetentionDuration } from "./validation.js";
|
|
2
|
+
export const DEFAULT_LEASE_TTL_MS = 30000, DEFAULT_LEASE_RENEW_INTERVAL_MS = 5000, DEFAULT_LEASE_WAIT_TIMEOUT_MS = 60000;
|
|
3
|
+
export function resolveOwnershipFields(options) {
|
|
4
|
+
const ownershipMode = assertKnownOwnershipMode(options?.ownership ?? "none");
|
|
5
|
+
if (ownershipMode !== "lease")
|
|
6
|
+
return {
|
|
7
|
+
ownershipMode,
|
|
8
|
+
leaseTtlMs: DEFAULT_LEASE_TTL_MS,
|
|
9
|
+
leaseRenewIntervalMs: DEFAULT_LEASE_RENEW_INTERVAL_MS,
|
|
10
|
+
leaseWaitTimeoutMs: DEFAULT_LEASE_WAIT_TIMEOUT_MS
|
|
11
|
+
};
|
|
12
|
+
const leaseTtlMs = normalizeRetentionDuration(options?.leaseTtl, "options.leaseTtl") ?? DEFAULT_LEASE_TTL_MS, leaseRenewIntervalMs = normalizeRetentionDuration(options?.leaseRenewInterval, "options.leaseRenewInterval") ?? DEFAULT_LEASE_RENEW_INTERVAL_MS, leaseWaitTimeoutMs = normalizeRetentionDuration(options?.leaseWaitTimeout, "options.leaseWaitTimeout") ?? DEFAULT_LEASE_WAIT_TIMEOUT_MS;
|
|
13
|
+
assertLeaseTimingCoherent(leaseTtlMs, leaseRenewIntervalMs, leaseWaitTimeoutMs);
|
|
14
|
+
return { ownershipMode, leaseTtlMs, leaseRenewIntervalMs, leaseWaitTimeoutMs };
|
|
15
|
+
}
|
|
16
|
+
function assertKnownOwnershipMode(mode) {
|
|
17
|
+
if (mode !== "none" && mode !== "lease")
|
|
18
|
+
throw Error(`Unknown ownership posture "${String(mode)}". Expected 'none' or 'lease'.`);
|
|
19
|
+
return mode;
|
|
20
|
+
}
|
|
21
|
+
function assertLeaseTimingCoherent(leaseTtlMs, leaseRenewIntervalMs, leaseWaitTimeoutMs) {
|
|
22
|
+
if (leaseTtlMs <= 0 || leaseRenewIntervalMs <= 0 || leaseWaitTimeoutMs <= 0)
|
|
23
|
+
throw Error(`ownership: 'lease' requires positive leaseTtl, leaseRenewInterval, and leaseWaitTimeout (got leaseTtl=${leaseTtlMs}ms, leaseRenewInterval=${leaseRenewIntervalMs}ms, leaseWaitTimeout=${leaseWaitTimeoutMs}ms).`);
|
|
24
|
+
if (leaseRenewIntervalMs >= leaseTtlMs)
|
|
25
|
+
throw Error(`ownership: 'lease' requires leaseRenewInterval (${leaseRenewIntervalMs}ms) to be strictly less than leaseTtl (${leaseTtlMs}ms), so a renewal fires before the lease can lapse.`);
|
|
26
|
+
}
|
|
@@ -14,5 +14,22 @@ export declare function invokeUpdateHandler(internals: EngineInternals, name: st
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function processPendingUpdatesAfterInlineAdvance(internals: EngineInternals, workflowId: string, callbacks: PendingUpdateCallbacks): Promise<void>;
|
|
16
16
|
export declare function schedulePendingInlineUpdateDrain(internals: EngineInternals, workflowId: string, callbacks: PendingUpdateCallbacks): void;
|
|
17
|
+
/**
|
|
18
|
+
* Drain a workflow's buffered coordinated updates and deliver each to its
|
|
19
|
+
* handler exactly once, even when several drains race.
|
|
20
|
+
*
|
|
21
|
+
* Several triggers can fire near-simultaneously: each `engine.update()` schedules
|
|
22
|
+
* a `setTimeout(0)` drain, and the post-advance path drains too. Their consume-
|
|
23
|
+
* deletes are durable (`storage.batch`) and lag the in-memory `getPendingUpdates`
|
|
24
|
+
* scan, so two overlapping drains both see the same pending set. Each update id
|
|
25
|
+
* is therefore CLAIMED synchronously in `deliveredPendingUpdateIds` before
|
|
26
|
+
* delivery (no `await` between the membership check and the add, so a concurrent
|
|
27
|
+
* drain cannot interleave): a racing drain that re-reads the same id skips it.
|
|
28
|
+
*
|
|
29
|
+
* After the drain, re-drive a parked `ctx.waitUntil` once. A coordinated update
|
|
30
|
+
* buffered before `ctx.onUpdate` was registered drains here (not on the inline
|
|
31
|
+
* `tryInlineUpdateHandler` path), and a handler may have mutated the workflow-
|
|
32
|
+
* local state a predicate reads, so the wait must be poked to re-evaluate.
|
|
33
|
+
*/
|
|
17
34
|
export declare function processPendingUpdatesForHandlers(internals: EngineInternals, workflowId: string, callbacks: PendingUpdateCallbacks): Promise<void>;
|
|
18
35
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { UpdateCompletedEvent, UpdateReceivedEvent } from "../events.js";
|
|
2
2
|
import { UpdateValidationError } from "../updates.js";
|
|
3
|
+
import { notifyConditionWaiters } from "./condition-waiters.js";
|
|
4
|
+
import { commitFencedEngineWrite } from "./fenced-write.js";
|
|
3
5
|
import {
|
|
4
6
|
extractStandardSchemaIssues,
|
|
5
7
|
invokeUpdateHandler as invokeUpdateHandlerFromInternals
|
|
@@ -71,17 +73,37 @@ export async function processPendingUpdatesForHandlers(internals, workflowId, ca
|
|
|
71
73
|
const pendingUpdates = await internals.updateCoordinator.getPendingUpdates(workflowId);
|
|
72
74
|
if (pendingUpdates.length === 0)
|
|
73
75
|
return;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
let handlerRan = !1;
|
|
77
|
+
try {
|
|
78
|
+
for (const update of pendingUpdates) {
|
|
79
|
+
const handler = handlers.get(update.name);
|
|
80
|
+
if (!handler)
|
|
81
|
+
continue;
|
|
82
|
+
if (!claimPendingUpdateForDelivery(internals, workflowId, update.updateId))
|
|
83
|
+
continue;
|
|
84
|
+
const validatorRejectionError = await runValidatorIfPresent(context, update);
|
|
85
|
+
if (validatorRejectionError !== null) {
|
|
86
|
+
await rejectPendingUpdate(internals, workflowId, update, validatorRejectionError, callbacks);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
handlerRan = !0;
|
|
90
|
+
await deliverPendingUpdate(internals, workflowId, update, handler, callbacks);
|
|
82
91
|
}
|
|
83
|
-
|
|
92
|
+
} finally {
|
|
93
|
+
if (handlerRan)
|
|
94
|
+
notifyConditionWaiters(internals, workflowId);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function claimPendingUpdateForDelivery(internals, workflowId, updateId) {
|
|
98
|
+
let claimed = internals.deliveredPendingUpdateIds.get(workflowId);
|
|
99
|
+
if (claimed === void 0) {
|
|
100
|
+
claimed = new Set;
|
|
101
|
+
internals.deliveredPendingUpdateIds.set(workflowId, claimed);
|
|
84
102
|
}
|
|
103
|
+
if (claimed.has(updateId))
|
|
104
|
+
return !1;
|
|
105
|
+
claimed.add(updateId);
|
|
106
|
+
return !0;
|
|
85
107
|
}
|
|
86
108
|
async function runValidatorIfPresent(context, update) {
|
|
87
109
|
const validator = context.updateValidators?.get(update.name);
|
|
@@ -91,7 +113,7 @@ async function runValidatorIfPresent(context, update) {
|
|
|
91
113
|
}
|
|
92
114
|
async function rejectPendingUpdate(internals, workflowId, update, errorMessage, callbacks) {
|
|
93
115
|
const responseOperations = internals.updateCoordinator.buildResponseOperations(update.updateId, workflowId, void 0, errorMessage, update.idempotencyKey);
|
|
94
|
-
await internals
|
|
116
|
+
await commitFencedEngineWrite(internals, responseOperations, [], () => Error(`Update rejection for workflow "${workflowId}" lost its CAS race.`));
|
|
95
117
|
callbacks.broadcast({ type: "update:completed", workflowId, updateId: update.updateId });
|
|
96
118
|
}
|
|
97
119
|
async function deliverPendingUpdate(internals, workflowId, update, handler, callbacks) {
|
|
@@ -103,7 +125,7 @@ async function deliverPendingUpdate(internals, workflowId, update, handler, call
|
|
|
103
125
|
error = handlerError instanceof Error ? handlerError.message : String(handlerError);
|
|
104
126
|
}
|
|
105
127
|
const responseOperations = internals.updateCoordinator.buildResponseOperations(update.updateId, workflowId, result, error, update.idempotencyKey);
|
|
106
|
-
await internals
|
|
128
|
+
await commitFencedEngineWrite(internals, responseOperations, [], () => Error(`Update response for workflow "${workflowId}" lost its CAS race.`));
|
|
107
129
|
callbacks.dispatchEvent(new UpdateCompletedEvent(update.updateId, workflowId, update.name, result, error));
|
|
108
130
|
callbacks.broadcast({ type: "update:completed", workflowId, updateId: update.updateId });
|
|
109
131
|
}
|
|
@@ -12,13 +12,9 @@ import type { Storage as WeftStorage } from '../../storage/interface.ts';
|
|
|
12
12
|
* 3. Sentinel is absent. Only stamp the storage when it carries no user
|
|
13
13
|
* workflow data. Stamping a database that already holds workflow records,
|
|
14
14
|
* schedules, checkpoints, or any other `wf:` / `op:` / `schedule:` / `ev:`
|
|
15
|
-
* prefixed key would silently classify
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* sentinel, fail with `PersistedDataIncompatibleError(null, …)` so the
|
|
20
|
-
* operator can choose explicitly whether to wipe and start fresh.
|
|
15
|
+
* prefixed key would silently classify unversioned data as schema-current
|
|
16
|
+
* and risk replaying incompatible records. When user data is already present
|
|
17
|
+
* without a sentinel, fail with `PersistedDataIncompatibleError(null, …)` so
|
|
18
|
+
* the operator can choose explicitly whether to wipe and start fresh.
|
|
21
19
|
*/
|
|
22
|
-
export declare function assertCompatiblePersistedDataVersion(storage: WeftStorage
|
|
23
|
-
allowLegacyData?: boolean;
|
|
24
|
-
}): Promise<void>;
|
|
20
|
+
export declare function assertCompatiblePersistedDataVersion(storage: WeftStorage): Promise<void>;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
PersistedDataIncompatibleError
|
|
5
5
|
} from "../persisted-data-incompatible-error.js";
|
|
6
6
|
const SCHEMA_VERSION_PATTERN = /^(?:0|[1-9]\d*)$/, USER_DATA_PREFIXES = ["wf:", "op:", "schedule:", "ev:", "sig:", "upd:", "idx:"];
|
|
7
|
-
export async function assertCompatiblePersistedDataVersion(storage
|
|
7
|
+
export async function assertCompatiblePersistedDataVersion(storage) {
|
|
8
8
|
const raw = await storage.get(PERSISTED_DATA_SCHEMA_VERSION_KEY);
|
|
9
9
|
if (raw !== null) {
|
|
10
10
|
const text = new TextDecoder().decode(raw);
|
|
@@ -17,9 +17,8 @@ export async function assertCompatiblePersistedDataVersion(storage, options = {}
|
|
|
17
17
|
throw new PersistedDataIncompatibleError(parsed, CURRENT_PERSISTED_DATA_SCHEMA_VERSION);
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
for (const
|
|
22
|
-
|
|
23
|
-
throw new PersistedDataIncompatibleError(null, CURRENT_PERSISTED_DATA_SCHEMA_VERSION);
|
|
20
|
+
for (const prefix of USER_DATA_PREFIXES)
|
|
21
|
+
for await (const _entry of storage.scan(prefix, { limit: 1 }))
|
|
22
|
+
throw new PersistedDataIncompatibleError(null, CURRENT_PERSISTED_DATA_SCHEMA_VERSION);
|
|
24
23
|
await storage.put(PERSISTED_DATA_SCHEMA_VERSION_KEY, new TextEncoder().encode(String(CURRENT_PERSISTED_DATA_SCHEMA_VERSION)));
|
|
25
24
|
}
|
|
@@ -4,7 +4,7 @@ export async function query(internals, workflowId, name, input) {
|
|
|
4
4
|
const inlineStrategy = internals.inlineStrategy;
|
|
5
5
|
if (!inlineStrategy)
|
|
6
6
|
throw Error("Workflow queries are not supported when using the worker execution strategy.");
|
|
7
|
-
const context = inlineStrategy.getContext(workflowId);
|
|
7
|
+
const context = inlineStrategy.getContext(workflowId) ?? inlineStrategy.getParkedContext(workflowId);
|
|
8
8
|
if (!context)
|
|
9
9
|
return;
|
|
10
10
|
const queryHandler = context.queryHandlers.get(name);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EngineInternals } from './internals.ts';
|
|
2
2
|
export type RegistrationCallbacks = {
|
|
3
3
|
ensureRetentionSweepInterval: () => void;
|
|
4
|
+
dispatchEvent: (event: Event) => void;
|
|
4
5
|
};
|
|
5
6
|
export declare function register(internals: EngineInternals, definition: unknown, callbacks: RegistrationCallbacks): void;
|
|
6
7
|
export declare function resolveWorkflowTypeTarget(internals: EngineInternals, target: string | Function, _callbacks: RegistrationCallbacks): string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ActivityRegistry } from "../activity-registry.js";
|
|
2
|
+
import { WorkflowDefinitionRegisteredEvent } from "../events.js";
|
|
2
3
|
import {
|
|
3
4
|
activity,
|
|
4
5
|
validateDefinitionSchemaMetadata
|
|
@@ -31,16 +32,29 @@ function buildBaseRegistrationEntry(name, registration) {
|
|
|
31
32
|
...registration.outputSchema === void 0 ? {} : {
|
|
32
33
|
outputSchema: validateDefinitionSchemaMetadata(registration.outputSchema, `registration("${name}").outputSchema`)
|
|
33
34
|
},
|
|
34
|
-
...normalizedRetention !== null && { retention: normalizedRetention }
|
|
35
|
+
...normalizedRetention !== null && { retention: normalizedRetention },
|
|
36
|
+
...registration.concurrency !== void 0 ? {
|
|
37
|
+
concurrency: normalizeWorkflowConcurrencyOptions(registration.concurrency, `registration("${name}").concurrency`)
|
|
38
|
+
} : {}
|
|
35
39
|
};
|
|
36
40
|
}
|
|
41
|
+
function normalizeWorkflowConcurrencyOptions(concurrency, fieldName) {
|
|
42
|
+
if (!Number.isInteger(concurrency.max) || concurrency.max < 1)
|
|
43
|
+
throw RangeError(`${fieldName}.max must be a positive integer`);
|
|
44
|
+
if (concurrency.key !== void 0 && typeof concurrency.key !== "function")
|
|
45
|
+
throw TypeError(`${fieldName}.key must be a function when provided`);
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
max: concurrency.max,
|
|
48
|
+
...concurrency.key === void 0 ? {} : { key: concurrency.key }
|
|
49
|
+
});
|
|
50
|
+
}
|
|
37
51
|
function applyOptionalRegistrationFields(entry, registration) {
|
|
38
|
-
if (registration.migrate)
|
|
39
|
-
entry.migrate = registration.migrate;
|
|
40
52
|
if (registration.searchAttributes && Object.keys(registration.searchAttributes).length > 0)
|
|
41
53
|
entry.searchAttributes = registration.searchAttributes;
|
|
42
54
|
if (registration.constraints && registration.constraints.length > 0)
|
|
43
55
|
entry.constraints = registration.constraints;
|
|
56
|
+
if (registration.finalizer !== void 0)
|
|
57
|
+
entry.finalizer = registration.finalizer;
|
|
44
58
|
}
|
|
45
59
|
function buildRegistrationEntry(name, registration) {
|
|
46
60
|
const entry = buildBaseRegistrationEntry(name, registration);
|
|
@@ -55,6 +69,7 @@ function commitWorkflowDefinition(internals, definition, callbacks) {
|
|
|
55
69
|
internals.registrations.set(name, entry);
|
|
56
70
|
callbacks.ensureRetentionSweepInterval();
|
|
57
71
|
internals.workflowTypesByHandler.set(definition.handler, name);
|
|
72
|
+
callbacks.dispatchEvent(new WorkflowDefinitionRegisteredEvent(name));
|
|
58
73
|
}
|
|
59
74
|
function hasNonNullObjectField(value, key) {
|
|
60
75
|
if (!(key in value))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ScheduleSpec, ScheduleSummary } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Narrow engine view a {@link ScheduleHandle} delegates to. The full
|
|
4
|
+
* {@link Engine} implements it; the handle only depends on these schedule
|
|
5
|
+
* lifecycle operations.
|
|
6
|
+
*/
|
|
7
|
+
export interface ScheduleHandleEngine {
|
|
8
|
+
pauseSchedule(scheduleId: string): Promise<void>;
|
|
9
|
+
resumeSchedule(scheduleId: string): Promise<void>;
|
|
10
|
+
cancelSchedule(scheduleId: string): Promise<void>;
|
|
11
|
+
updateSchedule(scheduleId: string, newSpec: string | ScheduleSpec): Promise<void>;
|
|
12
|
+
getSchedule(scheduleId: string): Promise<ScheduleSummary | null>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Handle to a recurring schedule created by {@link Engine.schedule}. Use
|
|
16
|
+
* `handle.pause()`, `handle.resume()`, `handle.cancel()`, or
|
|
17
|
+
* `handle.update(cronExpression)` to manage the schedule lifecycle.
|
|
18
|
+
* `handle.describe()` returns the current {@link ScheduleSummary}.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { workflow, Engine, ScheduleHandle } from '@lostgradient/weft';
|
|
23
|
+
*
|
|
24
|
+
* const engine = new Engine();
|
|
25
|
+
* engine.register(workflow({ name: 'daily-report' }).execute(async function* () { return 'ok'; }));
|
|
26
|
+
*
|
|
27
|
+
* const handle = await engine.schedule('daily-report', null, '0 9 * * *');
|
|
28
|
+
* const typedHandle: ScheduleHandle = handle;
|
|
29
|
+
* await handle.pause();
|
|
30
|
+
* const summary = await handle.describe();
|
|
31
|
+
* void typedHandle;
|
|
32
|
+
* console.log(summary.status); // 'paused'
|
|
33
|
+
* await handle.cancel();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class ScheduleHandle {
|
|
37
|
+
#private;
|
|
38
|
+
readonly id: string;
|
|
39
|
+
constructor(id: string, engine: ScheduleHandleEngine);
|
|
40
|
+
pause(): Promise<void>;
|
|
41
|
+
resume(): Promise<void>;
|
|
42
|
+
cancel(): Promise<void>;
|
|
43
|
+
update(newSpec: string | ScheduleSpec): Promise<void>;
|
|
44
|
+
describe(): Promise<ScheduleSummary>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class ScheduleHandle {
|
|
2
|
+
id;
|
|
3
|
+
#engine;
|
|
4
|
+
constructor(id, engine) {
|
|
5
|
+
this.id = id;
|
|
6
|
+
this.#engine = engine;
|
|
7
|
+
}
|
|
8
|
+
async pause() {
|
|
9
|
+
await this.#engine.pauseSchedule(this.id);
|
|
10
|
+
}
|
|
11
|
+
async resume() {
|
|
12
|
+
await this.#engine.resumeSchedule(this.id);
|
|
13
|
+
}
|
|
14
|
+
async cancel() {
|
|
15
|
+
await this.#engine.cancelSchedule(this.id);
|
|
16
|
+
}
|
|
17
|
+
async update(newSpec) {
|
|
18
|
+
await this.#engine.updateSchedule(this.id, newSpec);
|
|
19
|
+
}
|
|
20
|
+
async describe() {
|
|
21
|
+
const schedule = await this.#engine.getSchedule(this.id);
|
|
22
|
+
if (!schedule)
|
|
23
|
+
throw Error(`Schedule "${this.id}" not found`);
|
|
24
|
+
return schedule;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ScheduleState } from '../types.ts';
|
|
2
|
+
type JitteredSchedule = Pick<ScheduleState, 'id' | 'jitterMs'>;
|
|
3
|
+
export declare function computeScheduleJitterOffset(scheduleId: string, nominalFireAt: number, jitterMs: number | undefined): number;
|
|
4
|
+
export declare function resolveEffectiveScheduleFireAt(schedule: JitteredSchedule, nominalFireAt: number): number;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { hashString } from "../../runtime/portable.js";
|
|
2
|
+
export function computeScheduleJitterOffset(scheduleId, nominalFireAt, jitterMs) {
|
|
3
|
+
if (jitterMs === void 0 || jitterMs <= 0)
|
|
4
|
+
return 0;
|
|
5
|
+
const hash = BigInt(`0x${hashString(`${scheduleId}\x00${nominalFireAt}`)}`);
|
|
6
|
+
return Number(hash % BigInt(jitterMs));
|
|
7
|
+
}
|
|
8
|
+
export function resolveEffectiveScheduleFireAt(schedule, nominalFireAt) {
|
|
9
|
+
return nominalFireAt + computeScheduleJitterOffset(schedule.id, nominalFireAt, schedule.jitterMs);
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ScheduleState } from '../types.ts';
|
|
2
|
+
import type { EngineInternals } from './internals.ts';
|
|
3
|
+
import type { ScheduleCallbacks } from './schedules.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Launch one scheduled occurrence's workflow run and emit `schedule:fired`.
|
|
6
|
+
*
|
|
7
|
+
* This is the single chokepoint every occurrence launch flows through — initial
|
|
8
|
+
* cadence ticks, `cancel-running` replacements, and `queue`-drained runs — so it
|
|
9
|
+
* is the one place that reliably holds the launched `workflowId` across all
|
|
10
|
+
* overlap policies. The blocked policies (`skip`, and `queue` while a run is
|
|
11
|
+
* active) never reach here, so they correctly do not fire.
|
|
12
|
+
*
|
|
13
|
+
* `occurrence` is the scheduled grid timestamp the run was due, threaded from the
|
|
14
|
+
* timer loop. It is `undefined` for a `queue`-drained run, whose grid slot was
|
|
15
|
+
* tracked only as a count and whose original timestamp is therefore gone.
|
|
16
|
+
*/
|
|
17
|
+
export declare function startScheduledRun(internals: EngineInternals, state: ScheduleState, callbacks: Pick<ScheduleCallbacks, 'startWorkflow' | 'failWorkflow' | 'handleCleanupError'>, occurrence?: number): Promise<string>;
|