@lostgradient/weft 0.3.0 → 0.5.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 +79 -24
- package/dist/cli/conformance.js +7 -1
- package/dist/cli/generated/operation-client.generated.d.ts +28 -13
- package/dist/cli/generated/operation-client.generated.js +1 -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 +79 -78
- package/dist/client/handle-delegation.d.ts +3 -2
- package/dist/client/handle-delegation.js +3 -1
- package/dist/client/http-client-requests.d.ts +2 -1
- package/dist/client/http-client-requests.js +7 -0
- package/dist/client/http-client.d.ts +9 -6
- package/dist/client/http-client.js +10 -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 +61 -5
- package/dist/client/local-handles.d.ts +22 -0
- package/dist/client/local-handles.js +23 -0
- package/dist/client/local.d.ts +6 -3
- package/dist/client/local.js +12 -26
- package/dist/client/start-body.d.ts +4 -3
- 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 +100 -6
- 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 +9 -5
- package/dist/core/context/index.js +17 -12
- package/dist/core/context/internals.d.ts +20 -0
- package/dist/core/context/internals.js +3 -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 +6 -1
- package/dist/core/context/run-operation.js +41 -87
- 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 +46 -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 -0
- package/dist/core/engine/construction.js +21 -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 +13 -0
- package/dist/core/engine/engine-create-types.d.ts +14 -4
- package/dist/core/engine/engine-internal-types.d.ts +26 -3
- package/dist/core/engine/errors.d.ts +47 -0
- package/dist/core/engine/errors.js +20 -0
- 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/handles.d.ts +8 -0
- package/dist/core/engine/index.d.ts +34 -16
- package/dist/core/engine/index.js +136 -9
- package/dist/core/engine/inline-parking.js +3 -2
- package/dist/core/engine/internals.d.ts +107 -3
- 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/persist.js +10 -32
- 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 +16 -9
- 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 +9 -0
- package/dist/core/engine/lifecycle/start-commit.js +50 -8
- 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.d.ts +3 -2
- package/dist/core/engine/lifecycle/start-or-signal.js +11 -81
- 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 +4 -4
- package/dist/core/engine/lifecycle/start.js +17 -9
- package/dist/core/engine/lifecycle/transition.js +17 -5
- package/dist/core/engine/lifecycle.d.ts +1 -1
- package/dist/core/engine/list-candidate-resolution.js +2 -2
- package/dist/core/engine/listing.js +9 -5
- package/dist/core/engine/operations-activity.d.ts +6 -13
- package/dist/core/engine/operations-activity.js +26 -53
- package/dist/core/engine/operations-coordination.d.ts +10 -0
- package/dist/core/engine/operations-coordination.js +44 -9
- 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/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-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 +7 -4
- package/dist/core/engine/schedules.js +37 -16
- 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/signals.d.ts +18 -2
- package/dist/core/engine/signals.js +42 -21
- 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 +25 -6
- package/dist/core/engine/termination/cleanup.d.ts +3 -1
- package/dist/core/engine/termination/cleanup.js +25 -1
- package/dist/core/engine/termination/complete.js +44 -6
- 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 +3 -1
- package/dist/core/engine/termination.d.ts +1 -0
- package/dist/core/engine/termination.js +4 -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 +32 -5
- 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 +4 -5
- 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 +18 -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 +88 -23
- package/dist/core/events/workflow-events.js +26 -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/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 +34 -0
- package/dist/core/start-workflow-validation.js +19 -0
- 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 +80 -61
- package/dist/core/types/bulk.d.ts +50 -9
- package/dist/core/types/checkpoint.d.ts +44 -8
- package/dist/core/types/list-options.d.ts +146 -0
- package/dist/core/types/list-options.js +0 -0
- package/dist/core/types/options.d.ts +121 -165
- package/dist/core/types/schedules.d.ts +39 -3
- package/dist/core/types/services-resolution.d.ts +2 -2
- 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 +42 -11
- 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 +84 -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.d.ts +4 -0
- package/dist/core/types.js +4 -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 +16 -0
- 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/format.js +1 -6
- package/dist/diagnostics/types.d.ts +4 -5
- package/dist/diagnostics/validate.d.ts +0 -1
- package/dist/diagnostics/version-check.d.ts +1 -1
- package/dist/diagnostics/version-check.js +4 -9
- package/dist/index.d.ts +12 -10
- package/dist/index.js +29 -3
- package/dist/json-schema.js +3 -3
- package/dist/mcp/cli.js +19 -19
- package/dist/mcp/dispatcher.js +1 -1
- package/dist/mcp/http.js +16 -6
- 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 +59 -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 +23 -23
- package/dist/server/index.d.ts +32 -2
- package/dist/server/index.js +32 -32
- 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/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 +6 -1
- package/dist/server/operations/start-or-signal-workflow.js +14 -24
- package/dist/server/operations/start-workflow-options.d.ts +6 -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 +8 -23
- 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/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 +3 -1
- package/dist/server/rest-bindings.js +12 -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-polling.js +61 -20
- 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 +38 -30
- package/dist/server/serve-internals.d.ts +3 -1
- package/dist/server/serve-internals.js +18 -2
- package/dist/server/task-state.d.ts +30 -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 +30 -30
- package/dist/storage/auto.js +1 -1
- package/dist/storage/bun-sql.js +24 -0
- 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 +76 -4
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/interface.d.ts +163 -0
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +10 -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 +30 -3
- package/dist/storage/neon-value-mapping.js +12 -0
- package/dist/storage/neon.d.ts +16 -0
- package/dist/storage/neon.js +9 -4
- package/dist/storage/node-sqlite.js +23 -0
- package/dist/storage/postgres-key-value-queries.d.ts +69 -44
- package/dist/storage/postgres-key-value-queries.js +62 -24
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/testing.d.ts +168 -0
- package/dist/storage/testing.js +2 -0
- 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 +20 -20
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/protocol.js +1 -1
- 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 +5 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { KEYS } from "../../../storage/interface.js";
|
|
2
|
+
import { decode } from "../../codec.js";
|
|
3
|
+
import { WorkflowTeardownEvent } from "../../events.js";
|
|
4
|
+
import { isTeardownClaim, parseTeardownTimerId } from "../state-utilities.js";
|
|
5
|
+
import { runFinalizerActivity } from "./finalizer-activity.js";
|
|
6
|
+
import {
|
|
7
|
+
claimTeardownMarker,
|
|
8
|
+
clearTeardownMarker,
|
|
9
|
+
deadLetterTeardown,
|
|
10
|
+
encodeOwedClaim,
|
|
11
|
+
MAX_TEARDOWN_ATTEMPTS,
|
|
12
|
+
rearmTeardownTimer,
|
|
13
|
+
runningClaimIsStale,
|
|
14
|
+
settleOnRunningClaim,
|
|
15
|
+
TEARDOWN_SELF_HEAL_DELAY_MS,
|
|
16
|
+
teardownBackoffMs,
|
|
17
|
+
teardownStaleThresholdMs,
|
|
18
|
+
teardownTimerOperations
|
|
19
|
+
} from "./finalizer-claim.js";
|
|
20
|
+
export { teardownStaleThresholdMs } from "./finalizer-claim.js";
|
|
21
|
+
const TERMINAL_STATUSES_OWED_TEARDOWN = new Set([
|
|
22
|
+
"cancelled",
|
|
23
|
+
"timed-out"
|
|
24
|
+
]);
|
|
25
|
+
function errorMessage(error) {
|
|
26
|
+
return error instanceof Error ? error.message : String(error);
|
|
27
|
+
}
|
|
28
|
+
async function rearmOnLostSettle(internals, workflowId, token) {
|
|
29
|
+
await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
|
|
30
|
+
}
|
|
31
|
+
async function clearOrRearm(internals, workflowId, token, markerBytes) {
|
|
32
|
+
return await clearTeardownMarker(internals, workflowId, markerBytes) ? { kind: "cleared" } : { kind: "rearm", token };
|
|
33
|
+
}
|
|
34
|
+
async function readDriveableClaim(internals, workflowId, token, markerBytes) {
|
|
35
|
+
let decoded;
|
|
36
|
+
try {
|
|
37
|
+
decoded = decode(markerBytes);
|
|
38
|
+
} catch {
|
|
39
|
+
return clearOrRearm(internals, workflowId, token, markerBytes);
|
|
40
|
+
}
|
|
41
|
+
if (!isTeardownClaim(decoded))
|
|
42
|
+
return clearOrRearm(internals, workflowId, token, markerBytes);
|
|
43
|
+
return { kind: "claim", claim: decoded };
|
|
44
|
+
}
|
|
45
|
+
async function resolveTeardownDrive(internals, workflowId, token, callbacks) {
|
|
46
|
+
const markerBytes = await internals.storage.get(KEYS.teardownOwed(workflowId));
|
|
47
|
+
if (markerBytes === null)
|
|
48
|
+
return { kind: "cleared" };
|
|
49
|
+
const resolution = await readDriveableClaim(internals, workflowId, token, markerBytes);
|
|
50
|
+
if (resolution.kind !== "claim")
|
|
51
|
+
return resolution;
|
|
52
|
+
const claim = resolution.claim;
|
|
53
|
+
if (claim.token !== token)
|
|
54
|
+
return { kind: "cleared" };
|
|
55
|
+
const state = await callbacks.loadWorkflowState(workflowId);
|
|
56
|
+
if (state === null || !TERMINAL_STATUSES_OWED_TEARDOWN.has(state.status))
|
|
57
|
+
return clearOrRearm(internals, workflowId, token, markerBytes);
|
|
58
|
+
const registeredFinalizer = internals.registrations.get(state.type)?.finalizer;
|
|
59
|
+
if (registeredFinalizer === void 0)
|
|
60
|
+
return { kind: "rearm", token };
|
|
61
|
+
const finalizer = registeredFinalizer;
|
|
62
|
+
if (!runningClaimIsStale(internals, claim, finalizer))
|
|
63
|
+
return { kind: "rearm", token };
|
|
64
|
+
const finalizerStateBytes = await internals.storage.get(KEYS.finalizerState(workflowId));
|
|
65
|
+
if (finalizerStateBytes === null) {
|
|
66
|
+
await deadLetterMissingState(internals, workflowId, state.type, claim.attempts, markerBytes, callbacks);
|
|
67
|
+
return { kind: "cleared" };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
kind: "run",
|
|
71
|
+
drive: { state, claim, markerBytes, finalizer, finalizerInput: decode(finalizerStateBytes) }
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function deadLetterMissingState(internals, workflowId, workflowType, attempts, expectedBytes, callbacks) {
|
|
75
|
+
const lastError = "finalizer state missing \u2014 recorded resource cannot be torn down";
|
|
76
|
+
if (await deadLetterTeardown(internals, workflowId, workflowType, attempts, expectedBytes, {
|
|
77
|
+
lastError,
|
|
78
|
+
finalizerInput: void 0
|
|
79
|
+
}))
|
|
80
|
+
callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, workflowType, "dead-lettered", attempts, lastError));
|
|
81
|
+
}
|
|
82
|
+
export async function runWorkflowFinalizer(internals, workflowId, timerId, callbacks) {
|
|
83
|
+
const token = parseTeardownTimerId(timerId);
|
|
84
|
+
if (token === null)
|
|
85
|
+
return;
|
|
86
|
+
try {
|
|
87
|
+
const resolution = await resolveTeardownDrive(internals, workflowId, token, callbacks);
|
|
88
|
+
if (resolution.kind === "cleared")
|
|
89
|
+
return;
|
|
90
|
+
if (resolution.kind === "rearm") {
|
|
91
|
+
await rearmTeardownTimer(internals, workflowId, resolution.token, TEARDOWN_SELF_HEAL_DELAY_MS);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
await driveResolvedTeardown(internals, workflowId, token, resolution.drive, callbacks);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
|
|
97
|
+
callbacks.handleCleanupError("runWorkflowFinalizer", error, workflowId);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function driveResolvedTeardown(internals, workflowId, token, drive, callbacks) {
|
|
101
|
+
const { state, claim, markerBytes, finalizer, finalizerInput } = drive, attempt = claim.attempts + 1, runningBytes = await claimTeardownMarker(internals, workflowId, markerBytes, claim.attempts, token);
|
|
102
|
+
if (runningBytes === null) {
|
|
103
|
+
await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const result = await runFinalizerActivity(finalizer, finalizerInput, attempt, internals.abortController.signal);
|
|
107
|
+
if (result.ok) {
|
|
108
|
+
await settleTeardownSuccess(internals, workflowId, state.type, token, attempt, runningBytes, callbacks);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (result.abortedByShutdown) {
|
|
112
|
+
const fireAt = internals.options.getNow() + TEARDOWN_SELF_HEAL_DELAY_MS;
|
|
113
|
+
if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
|
|
114
|
+
{
|
|
115
|
+
type: "put",
|
|
116
|
+
key: KEYS.teardownOwed(workflowId),
|
|
117
|
+
value: encodeOwedClaim(claim.attempts, token)
|
|
118
|
+
},
|
|
119
|
+
...teardownTimerOperations(token, workflowId, fireAt)
|
|
120
|
+
]))
|
|
121
|
+
await rearmOnLostSettle(internals, workflowId, token);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
await settleTeardownFailure(internals, workflowId, state, attempt, token, runningBytes, result.error, callbacks);
|
|
125
|
+
}
|
|
126
|
+
async function settleTeardownSuccess(internals, workflowId, workflowType, token, attempt, runningBytes, callbacks) {
|
|
127
|
+
if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
|
|
128
|
+
{ type: "delete", key: KEYS.teardownOwed(workflowId) },
|
|
129
|
+
{ type: "delete", key: KEYS.finalizerState(workflowId) }
|
|
130
|
+
])) {
|
|
131
|
+
await rearmOnLostSettle(internals, workflowId, token);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, workflowType, "completed", attempt));
|
|
135
|
+
}
|
|
136
|
+
async function settleTeardownFailure(internals, workflowId, state, attempt, token, runningBytes, error, callbacks) {
|
|
137
|
+
const message = errorMessage(error);
|
|
138
|
+
if (attempt >= MAX_TEARDOWN_ATTEMPTS) {
|
|
139
|
+
const finalizerStateBytes = await internals.storage.get(KEYS.finalizerState(workflowId));
|
|
140
|
+
if (!await deadLetterTeardown(internals, workflowId, state.type, attempt, runningBytes, {
|
|
141
|
+
lastError: message,
|
|
142
|
+
finalizerInput: finalizerStateBytes === null ? void 0 : decode(finalizerStateBytes)
|
|
143
|
+
})) {
|
|
144
|
+
await rearmOnLostSettle(internals, workflowId, token);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, state.type, "dead-lettered", attempt, message));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const fireAt = internals.options.getNow() + teardownBackoffMs(attempt);
|
|
151
|
+
if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
|
|
152
|
+
{ type: "put", key: KEYS.teardownOwed(workflowId), value: encodeOwedClaim(attempt, token) },
|
|
153
|
+
...teardownTimerOperations(token, workflowId, fireAt)
|
|
154
|
+
])) {
|
|
155
|
+
await rearmOnLostSettle(internals, workflowId, token);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, state.type, "failed", attempt, message));
|
|
159
|
+
}
|
|
@@ -13,7 +13,9 @@ import { type TerminationCallbacks } from './cleanup.ts';
|
|
|
13
13
|
* cancellation, so user code observing `ctx.signal.aborted` or registered
|
|
14
14
|
* abort listeners must not fire. The live inline run is *parked*
|
|
15
15
|
* (`parkWorkflow`: evict execution state without aborting), the same primitive
|
|
16
|
-
* the engine uses for signal-parking,
|
|
16
|
+
* the engine uses for signal-parking — but with the default eviction, not the
|
|
17
|
+
* `retainContext` form signal-parking uses, so suspend leaves no queryable
|
|
18
|
+
* Context behind,
|
|
17
19
|
* - does NOT run cancel handlers,
|
|
18
20
|
* - does NOT settle the result promise (`handle.result()` stays pending until a
|
|
19
21
|
* later `resume()` drives the run to completion, or a `cancel()` terminates it),
|
|
@@ -6,4 +6,5 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { TERMINAL_WORKFLOW_STATUSES, cleanupTerminalWorkflowDurableState, cleanupTerminalWorkflowImmediately, cleanupTerminalWorkflowMemory, cleanupTerminalWorkflowSynchronously, cleanupWaiters, cleanupWorkflowStorage, evictSuspendedWorkflowWaiters, finalizeScheduledWorkflowTerminal, handleCleanupError, runDeferredTerminalCleanup, type TerminationCallbacks, } from './termination/cleanup.ts';
|
|
8
8
|
export { buildPendingTimelineOperation, buildTerminalCleanupTimerOperations, cancelWorkflow, completeWorkflow, ensureTerminalCleanupTracked, failWorkflow, finalizePendingTimelineEntry, terminateWorkflow, timeoutWorkflow, } from './termination/complete.ts';
|
|
9
|
+
export { runWorkflowFinalizer, teardownStaleThresholdMs, type FinalizerDriveCallbacks, type TeardownDeadLetterRecord, } from './termination/finalizer.ts';
|
|
9
10
|
export { suspendWorkflow } from './termination/suspend.ts';
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { UpdateCompletedEvent, UpdateReceivedEvent } from "../events.js";
|
|
2
2
|
import { isGeneratorResult } from "../step-context.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
UpdateValidationError
|
|
6
|
-
} from "../updates.js";
|
|
3
|
+
import { UpdateValidationError } from "../updates.js";
|
|
4
|
+
import { notifyConditionWaiters } from "./condition-waiters.js";
|
|
7
5
|
import { trackWaiterKey, untrackWaiterKey } from "./signals.js";
|
|
6
|
+
import { waitForUpdateResponse } from "./waiting-update-response.js";
|
|
8
7
|
export async function update(internals, workflowId, name, payload, options, callbacks) {
|
|
9
8
|
const timeout = options?.timeout ?? 30000;
|
|
10
9
|
await runUpdateValidator(internals, workflowId, name, payload);
|
|
@@ -27,11 +26,13 @@ async function tryInlineUpdateHandler(internals, workflowId, name, payload, call
|
|
|
27
26
|
const result = await invokeUpdateHandler(internals, name, handler, payload);
|
|
28
27
|
callbacks.dispatchEvent(new UpdateCompletedEvent(updateId, workflowId, name, result));
|
|
29
28
|
callbacks.broadcast({ type: "update:completed", workflowId, updateId });
|
|
29
|
+
notifyConditionWaiters(internals, workflowId);
|
|
30
30
|
return { handled: !0, value: result };
|
|
31
31
|
} catch (error) {
|
|
32
32
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
33
33
|
callbacks.dispatchEvent(new UpdateCompletedEvent(updateId, workflowId, name, void 0, errorMessage));
|
|
34
34
|
callbacks.broadcast({ type: "update:completed", workflowId, updateId });
|
|
35
|
+
notifyConditionWaiters(internals, workflowId);
|
|
35
36
|
throw error;
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -51,27 +52,6 @@ async function tryWaitingUpdateHandler(internals, workflowId, name, payload, tim
|
|
|
51
52
|
callbacks.broadcast({ type: "update:completed", workflowId, updateId });
|
|
52
53
|
return { handled: !0, value: result };
|
|
53
54
|
}
|
|
54
|
-
async function waitForUpdateResponse(updateId, payload, timeout, updateWaiter) {
|
|
55
|
-
const { promise: respondPromise, resolve: resolveRespond } = Promise.withResolvers();
|
|
56
|
-
let responded = !1;
|
|
57
|
-
updateWaiter({ payload, respond: (value) => {
|
|
58
|
-
if (responded)
|
|
59
|
-
return;
|
|
60
|
-
responded = !0;
|
|
61
|
-
resolveRespond(value);
|
|
62
|
-
} });
|
|
63
|
-
let timeoutId;
|
|
64
|
-
try {
|
|
65
|
-
return await Promise.race([
|
|
66
|
-
respondPromise,
|
|
67
|
-
new Promise((_resolve, reject) => {
|
|
68
|
-
timeoutId = setTimeout(() => reject(new UpdateTimeoutError(updateId, timeout)), timeout);
|
|
69
|
-
})
|
|
70
|
-
]);
|
|
71
|
-
} finally {
|
|
72
|
-
clearTimeout(timeoutId);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
55
|
async function runCoordinatedUpdate(internals, workflowId, name, payload, timeout, callbacks) {
|
|
76
56
|
const updateId = await internals.updateCoordinator.createRequest(workflowId, name, payload);
|
|
77
57
|
callbacks.schedulePendingInlineUpdateDrain(workflowId);
|
|
@@ -8,6 +8,7 @@ export declare function isValidScheduleIdentifier(value: unknown): value is stri
|
|
|
8
8
|
export declare function coerceScheduleId(scheduleId: string, fieldName: string): string;
|
|
9
9
|
export declare function normalizeScheduleOptions(options: ScheduleOptions | undefined): Required<Pick<ScheduleOptions, 'overlap' | 'backfill'>> & {
|
|
10
10
|
id?: string;
|
|
11
|
+
jitterMs?: number;
|
|
11
12
|
};
|
|
12
13
|
/**
|
|
13
14
|
* A recurrence specification normalized into the discriminated cadence the
|
|
@@ -32,7 +33,7 @@ export declare function decodeScheduleIdentityFields(decoded: Record<string, unk
|
|
|
32
33
|
cronExpression?: string;
|
|
33
34
|
intervalMs?: number;
|
|
34
35
|
}) | null;
|
|
35
|
-
type ScheduleRuntimeFields = Pick<ScheduleState, 'backfill' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'queuedRuns'>;
|
|
36
|
+
type ScheduleRuntimeFields = Pick<ScheduleState, 'backfill' | 'jitterMs' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'lastMissedFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'missedFireCount' | 'queuedRuns'>;
|
|
36
37
|
export declare function decodeScheduleRuntimeFields(decoded: Record<string, unknown>, scheduleId: string): ScheduleRuntimeFields | null;
|
|
37
38
|
export declare function decodeScheduleState(bytes: Uint8Array): ScheduleState | null;
|
|
38
39
|
export {};
|
|
@@ -36,7 +36,7 @@ export function normalizeScheduleOptions(options) {
|
|
|
36
36
|
return { overlap: "skip", backfill: !1 };
|
|
37
37
|
if (typeof options !== "object" || options === null)
|
|
38
38
|
throw Error("options must be an object when provided");
|
|
39
|
-
const { id, overlap, backfill } = options, normalizedOptions = {
|
|
39
|
+
const { id, overlap, backfill, jitter } = options, normalizedOptions = {
|
|
40
40
|
overlap: "skip",
|
|
41
41
|
backfill: !1
|
|
42
42
|
};
|
|
@@ -52,8 +52,25 @@ export function normalizeScheduleOptions(options) {
|
|
|
52
52
|
throw Error("options.backfill must be a boolean when provided");
|
|
53
53
|
normalizedOptions.backfill = backfill;
|
|
54
54
|
}
|
|
55
|
+
if (jitter !== void 0)
|
|
56
|
+
normalizedOptions.jitterMs = normalizeScheduleJitter(jitter, "options.jitter");
|
|
55
57
|
return normalizedOptions;
|
|
56
58
|
}
|
|
59
|
+
function normalizeScheduleJitter(value, fieldName) {
|
|
60
|
+
if (typeof value !== "string" && typeof value !== "number")
|
|
61
|
+
throw Error(`${fieldName} must be a duration string or a number of milliseconds`);
|
|
62
|
+
let milliseconds;
|
|
63
|
+
try {
|
|
64
|
+
milliseconds = parseDuration(value);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
throw Error(`Invalid ${fieldName}: ${message}`, { cause: error });
|
|
68
|
+
}
|
|
69
|
+
const jitterMs = Math.ceil(milliseconds);
|
|
70
|
+
if (!Number.isSafeInteger(jitterMs) || jitterMs <= 0)
|
|
71
|
+
throw Error(`${fieldName} must resolve to a positive number of milliseconds`);
|
|
72
|
+
return jitterMs;
|
|
73
|
+
}
|
|
57
74
|
function normalizeIntervalEvery(every) {
|
|
58
75
|
if (typeof every !== "string" && typeof every !== "number")
|
|
59
76
|
throw Error('Schedule interval "every" must be a duration string or a number of milliseconds');
|
|
@@ -171,6 +188,16 @@ function decodeScheduleBackfill(decoded, scheduleId) {
|
|
|
171
188
|
}
|
|
172
189
|
return backfill;
|
|
173
190
|
}
|
|
191
|
+
function decodeScheduleJitterMs(decoded, scheduleId) {
|
|
192
|
+
const jitterMs = decoded.jitterMs;
|
|
193
|
+
if (jitterMs === void 0)
|
|
194
|
+
return;
|
|
195
|
+
if (typeof jitterMs !== "number" || !Number.isSafeInteger(jitterMs) || jitterMs <= 0) {
|
|
196
|
+
rejectInvalidScheduleRecord(scheduleId, "with invalid jitterMs");
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
return jitterMs;
|
|
200
|
+
}
|
|
174
201
|
function decodeScheduleTimestamps(decoded, scheduleId) {
|
|
175
202
|
const { createdAt, updatedAt } = decoded;
|
|
176
203
|
if (!isValidScheduleTimestamp(createdAt) || !isValidScheduleTimestamp(updatedAt))
|
|
@@ -178,10 +205,14 @@ function decodeScheduleTimestamps(decoded, scheduleId) {
|
|
|
178
205
|
const lastFireAt = decoded.lastFireAt;
|
|
179
206
|
if (lastFireAt !== void 0 && !isValidScheduleTimestamp(lastFireAt))
|
|
180
207
|
return rejectInvalidScheduleRecord(scheduleId, "with invalid lastFireAt");
|
|
208
|
+
const lastMissedFireAt = decoded.lastMissedFireAt;
|
|
209
|
+
if (lastMissedFireAt !== void 0 && !isValidScheduleTimestamp(lastMissedFireAt))
|
|
210
|
+
return rejectInvalidScheduleRecord(scheduleId, "with invalid lastMissedFireAt");
|
|
181
211
|
return {
|
|
182
212
|
createdAt,
|
|
183
213
|
updatedAt,
|
|
184
|
-
...lastFireAt !== void 0 && { lastFireAt }
|
|
214
|
+
...lastFireAt !== void 0 && { lastFireAt },
|
|
215
|
+
...lastMissedFireAt !== void 0 && { lastMissedFireAt }
|
|
185
216
|
};
|
|
186
217
|
}
|
|
187
218
|
function decodeScheduleNextFireAt(decoded, scheduleId) {
|
|
@@ -214,10 +245,23 @@ function decodeScheduleQueuedRuns(decoded, scheduleId) {
|
|
|
214
245
|
}
|
|
215
246
|
return queuedRuns;
|
|
216
247
|
}
|
|
248
|
+
function decodeScheduleMissedFireCount(decoded, scheduleId) {
|
|
249
|
+
const missedFireCount = decoded.missedFireCount;
|
|
250
|
+
if (missedFireCount === void 0)
|
|
251
|
+
return 0;
|
|
252
|
+
if (typeof missedFireCount !== "number" || !Number.isSafeInteger(missedFireCount) || missedFireCount < 0) {
|
|
253
|
+
rejectInvalidScheduleRecord(scheduleId, "with invalid missedFireCount");
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return missedFireCount;
|
|
257
|
+
}
|
|
217
258
|
export function decodeScheduleRuntimeFields(decoded, scheduleId) {
|
|
218
259
|
const backfill = decodeScheduleBackfill(decoded, scheduleId);
|
|
219
260
|
if (backfill === null)
|
|
220
261
|
return null;
|
|
262
|
+
const jitterMs = decodeScheduleJitterMs(decoded, scheduleId);
|
|
263
|
+
if (jitterMs === null)
|
|
264
|
+
return null;
|
|
221
265
|
const timestamps = decodeScheduleTimestamps(decoded, scheduleId);
|
|
222
266
|
if (timestamps === null)
|
|
223
267
|
return null;
|
|
@@ -230,11 +274,16 @@ export function decodeScheduleRuntimeFields(decoded, scheduleId) {
|
|
|
230
274
|
const queuedRuns = decodeScheduleQueuedRuns(decoded, scheduleId);
|
|
231
275
|
if (queuedRuns === null)
|
|
232
276
|
return null;
|
|
277
|
+
const missedFireCount = decodeScheduleMissedFireCount(decoded, scheduleId);
|
|
278
|
+
if (missedFireCount === null)
|
|
279
|
+
return null;
|
|
233
280
|
return {
|
|
234
281
|
backfill,
|
|
282
|
+
...jitterMs !== void 0 && { jitterMs },
|
|
235
283
|
...timestamps,
|
|
236
284
|
nextFireAt: nextFireAt.value,
|
|
237
285
|
...currentWorkflow.value !== void 0 && { currentWorkflowId: currentWorkflow.value },
|
|
286
|
+
missedFireCount,
|
|
238
287
|
queuedRuns
|
|
239
288
|
};
|
|
240
289
|
}
|
|
@@ -11,6 +11,29 @@ const WORKFLOW_TIMELINE_STATUSES = new Set([
|
|
|
11
11
|
"cancelled",
|
|
12
12
|
"timed-out"
|
|
13
13
|
]);
|
|
14
|
+
function defineCompleteWorkflowStateFieldNames(fieldNames) {
|
|
15
|
+
return fieldNames;
|
|
16
|
+
}
|
|
17
|
+
const WORKFLOW_STATE_FIELD_NAMES = new Set(defineCompleteWorkflowStateFieldNames([
|
|
18
|
+
"id",
|
|
19
|
+
"type",
|
|
20
|
+
"status",
|
|
21
|
+
"tags",
|
|
22
|
+
"input",
|
|
23
|
+
"result",
|
|
24
|
+
"error",
|
|
25
|
+
"errorStack",
|
|
26
|
+
"failureCategory",
|
|
27
|
+
"terminationReason",
|
|
28
|
+
"versionTuple",
|
|
29
|
+
"executionStateOwnerId",
|
|
30
|
+
"createdAt",
|
|
31
|
+
"startedAt",
|
|
32
|
+
"updatedAt",
|
|
33
|
+
"terminalCleanupToken",
|
|
34
|
+
"executionDeadline",
|
|
35
|
+
"forkedFrom"
|
|
36
|
+
]));
|
|
14
37
|
export function isSanitizedSearchAttributeValue(value) {
|
|
15
38
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
16
39
|
return !0;
|
|
@@ -56,12 +79,10 @@ export function isValidDecodedTags(value) {
|
|
|
56
79
|
return value === void 0 || isWorkflowTagArray(value);
|
|
57
80
|
}
|
|
58
81
|
export function decodeWorkflowState(bytes) {
|
|
59
|
-
const decoded = decode(bytes);
|
|
60
|
-
if (
|
|
61
|
-
liftFlatVersionTuple(
|
|
82
|
+
const decoded = decode(bytes), decodedRecord = isRecord(decoded) ? decoded : void 0;
|
|
83
|
+
if (decodedRecord !== void 0)
|
|
84
|
+
liftFlatVersionTuple(decodedRecord);
|
|
62
85
|
const state = decoded;
|
|
63
|
-
if ("tenant" in state)
|
|
64
|
-
delete state.tenant;
|
|
65
86
|
if (!isValidDecodedTags(state.tags)) {
|
|
66
87
|
console.warn(`[weft] Decoded workflow state for "${String(state.id)}" has invalid tags; dropping the malformed tag list from the decoded state.`);
|
|
67
88
|
delete state.tags;
|
|
@@ -80,6 +101,12 @@ export function decodeWorkflowState(bytes) {
|
|
|
80
101
|
console.warn(`[weft] Decoded workflow state for "${String(state.id)}" has an invalid executionStateOwnerId field; falling back to the workflow id as the execution owner. This usually indicates corruption or tampering of the storage record.`);
|
|
81
102
|
delete state.executionStateOwnerId;
|
|
82
103
|
}
|
|
104
|
+
return decodedRecord === void 0 ? state : stripUnknownWorkflowStateFields(state, decodedRecord);
|
|
105
|
+
}
|
|
106
|
+
function stripUnknownWorkflowStateFields(state, stateFields) {
|
|
107
|
+
for (const fieldName of Object.keys(stateFields))
|
|
108
|
+
if (!WORKFLOW_STATE_FIELD_NAMES.has(fieldName))
|
|
109
|
+
delete stateFields[fieldName];
|
|
83
110
|
return state;
|
|
84
111
|
}
|
|
85
112
|
function liftFlatVersionTuple(record) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Park until a waiting `ctx.waitForUpdate` handler responds (via the resolver it
|
|
3
|
+
* registered in `updateWaiters`) or the update times out. Resolves with the
|
|
4
|
+
* handler's response value; rejects with {@link UpdateTimeoutError} when the
|
|
5
|
+
* timeout elapses first. The `respond` callback is single-shot — a late second
|
|
6
|
+
* response is ignored.
|
|
7
|
+
*/
|
|
8
|
+
export declare function waitForUpdateResponse(updateId: string, payload: unknown, timeout: number, updateWaiter: (request: unknown) => void): Promise<unknown>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UpdateTimeoutError } from "../updates.js";
|
|
2
|
+
export async function waitForUpdateResponse(updateId, payload, timeout, updateWaiter) {
|
|
3
|
+
const { promise: respondPromise, resolve: resolveRespond } = Promise.withResolvers();
|
|
4
|
+
let responded = !1;
|
|
5
|
+
updateWaiter({ payload, respond: (value) => {
|
|
6
|
+
if (responded)
|
|
7
|
+
return;
|
|
8
|
+
responded = !0;
|
|
9
|
+
resolveRespond(value);
|
|
10
|
+
} });
|
|
11
|
+
let timeoutId;
|
|
12
|
+
try {
|
|
13
|
+
return await Promise.race([
|
|
14
|
+
respondPromise,
|
|
15
|
+
new Promise((_resolve, reject) => {
|
|
16
|
+
timeoutId = setTimeout(() => reject(new UpdateTimeoutError(updateId, timeout)), timeout);
|
|
17
|
+
})
|
|
18
|
+
]);
|
|
19
|
+
} finally {
|
|
20
|
+
clearTimeout(timeoutId);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BatchOperation, ConditionalBatchCondition } from '../../storage/interface.ts';
|
|
2
|
+
import type { WorkflowConcurrencyOptions } from '../types.ts';
|
|
3
|
+
import type { EngineInternals } from './internals.ts';
|
|
4
|
+
export type WorkflowConcurrencyStartOperations = {
|
|
5
|
+
stateKey: string;
|
|
6
|
+
operations: BatchOperation[];
|
|
7
|
+
conditions: ConditionalBatchCondition[];
|
|
8
|
+
};
|
|
9
|
+
export declare function buildWorkflowConcurrencyStartOperations(internals: EngineInternals, workflowType: string, workflowId: string, input: unknown, concurrency: WorkflowConcurrencyOptions): Promise<WorkflowConcurrencyStartOperations>;
|
|
10
|
+
export declare function releaseWorkflowConcurrencySlot(internals: EngineInternals, workflowId: string): Promise<void>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { KEYS } from "../../storage/interface.js";
|
|
2
|
+
import { AtomicState, atomicStateVersionKey, readAtomicStateSnapshot } from "../atomic-state.js";
|
|
3
|
+
import { decode, encode } from "../codec.js";
|
|
4
|
+
import {
|
|
5
|
+
initialLockRecord,
|
|
6
|
+
reduceRelease
|
|
7
|
+
} from "../concurrency.js";
|
|
8
|
+
import { WorkflowConcurrencyLimitExceededError } from "./errors.js";
|
|
9
|
+
const WORKFLOW_CONCURRENCY_HOLDER_VERSION = 1, NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE = Number.MAX_SAFE_INTEGER;
|
|
10
|
+
function encodeVersionCondition(dataKey, version) {
|
|
11
|
+
return {
|
|
12
|
+
key: atomicStateVersionKey(dataKey),
|
|
13
|
+
expectedValue: version === 0 ? null : encode(version)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function normalizeLockRecord(record) {
|
|
17
|
+
if (record === void 0)
|
|
18
|
+
return initialLockRecord();
|
|
19
|
+
return {
|
|
20
|
+
holders: Array.isArray(record.holders) ? record.holders : [],
|
|
21
|
+
waiters: Array.isArray(record.waiters) ? record.waiters : []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function liveWorkflowConcurrencyHolders(holders, now) {
|
|
25
|
+
return holders.filter((holder) => holder.leaseExpiresAt > now);
|
|
26
|
+
}
|
|
27
|
+
function acquireWorkflowConcurrencySlot(current, options) {
|
|
28
|
+
const record = normalizeLockRecord(current), holders = liveWorkflowConcurrencyHolders(record.holders, options.now);
|
|
29
|
+
if (holders.some((holder) => holder.holderId === options.workflowId))
|
|
30
|
+
return {
|
|
31
|
+
acquired: !0,
|
|
32
|
+
record: {
|
|
33
|
+
holders: holders.map((holder) => holder.holderId === options.workflowId ? {
|
|
34
|
+
holderId: options.workflowId,
|
|
35
|
+
leaseExpiresAt: NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE
|
|
36
|
+
} : holder),
|
|
37
|
+
waiters: []
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
if (holders.length >= options.limit)
|
|
41
|
+
return { acquired: !1, record: { holders, waiters: [] } };
|
|
42
|
+
return {
|
|
43
|
+
acquired: !0,
|
|
44
|
+
record: {
|
|
45
|
+
holders: [
|
|
46
|
+
...holders,
|
|
47
|
+
{
|
|
48
|
+
holderId: options.workflowId,
|
|
49
|
+
leaseExpiresAt: NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
waiters: []
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function resolveWorkflowConcurrencyPartitionKey(workflowType, input, concurrency) {
|
|
57
|
+
if (concurrency.key === void 0)
|
|
58
|
+
return workflowType;
|
|
59
|
+
let partitionKey;
|
|
60
|
+
try {
|
|
61
|
+
partitionKey = concurrency.key(input);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
throw Error(`workflow("${workflowType}").concurrency.key threw while resolving the partition key: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
64
|
+
}
|
|
65
|
+
if (typeof partitionKey !== "string")
|
|
66
|
+
throw TypeError(`workflow("${workflowType}").concurrency.key must return a string partition key`);
|
|
67
|
+
return partitionKey;
|
|
68
|
+
}
|
|
69
|
+
function encodeHolderRecord(workflowType, partitionKey) {
|
|
70
|
+
return {
|
|
71
|
+
version: WORKFLOW_CONCURRENCY_HOLDER_VERSION,
|
|
72
|
+
workflowType,
|
|
73
|
+
partitionKey
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function decodeHolderRecord(bytes) {
|
|
77
|
+
const decoded = decode(bytes);
|
|
78
|
+
if (typeof decoded !== "object" || decoded === null)
|
|
79
|
+
return null;
|
|
80
|
+
const record = decoded;
|
|
81
|
+
if (record.version !== WORKFLOW_CONCURRENCY_HOLDER_VERSION || typeof record.workflowType !== "string" || typeof record.partitionKey !== "string")
|
|
82
|
+
return null;
|
|
83
|
+
return {
|
|
84
|
+
version: WORKFLOW_CONCURRENCY_HOLDER_VERSION,
|
|
85
|
+
workflowType: record.workflowType,
|
|
86
|
+
partitionKey: record.partitionKey
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export async function buildWorkflowConcurrencyStartOperations(internals, workflowType, workflowId, input, concurrency) {
|
|
90
|
+
const partitionKey = resolveWorkflowConcurrencyPartitionKey(workflowType, input, concurrency), stateKey = KEYS.workflowConcurrency(workflowType, partitionKey), snapshot = await readAtomicStateSnapshot(internals.storage, stateKey, {
|
|
91
|
+
initial: initialLockRecord()
|
|
92
|
+
}), acquired = acquireWorkflowConcurrencySlot(snapshot.value, {
|
|
93
|
+
workflowId,
|
|
94
|
+
now: internals.options.getNow(),
|
|
95
|
+
limit: concurrency.max
|
|
96
|
+
});
|
|
97
|
+
if (!acquired.acquired)
|
|
98
|
+
throw new WorkflowConcurrencyLimitExceededError({
|
|
99
|
+
workflowType,
|
|
100
|
+
limit: concurrency.max,
|
|
101
|
+
partitionKey
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
stateKey,
|
|
105
|
+
conditions: [encodeVersionCondition(stateKey, snapshot.version)],
|
|
106
|
+
operations: [
|
|
107
|
+
{ type: "put", key: stateKey, value: encode(acquired.record) },
|
|
108
|
+
{ type: "put", key: atomicStateVersionKey(stateKey), value: encode(snapshot.version + 1) },
|
|
109
|
+
{
|
|
110
|
+
type: "put",
|
|
111
|
+
key: KEYS.workflowConcurrencyHolder(workflowId),
|
|
112
|
+
value: encode(encodeHolderRecord(workflowType, partitionKey))
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: "put",
|
|
116
|
+
key: KEYS.terminalCleanupNeeded(workflowId),
|
|
117
|
+
value: new Uint8Array(0)
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export async function releaseWorkflowConcurrencySlot(internals, workflowId) {
|
|
123
|
+
const holderKey = KEYS.workflowConcurrencyHolder(workflowId), markerBytes = await internals.storage.get(holderKey);
|
|
124
|
+
if (markerBytes === null)
|
|
125
|
+
return;
|
|
126
|
+
const marker = decodeHolderRecord(markerBytes);
|
|
127
|
+
if (marker === null) {
|
|
128
|
+
await internals.storage.delete(holderKey);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const stateKey = KEYS.workflowConcurrency(marker.workflowType, marker.partitionKey);
|
|
132
|
+
await new AtomicState(internals.storage, stateKey, {
|
|
133
|
+
initial: initialLockRecord()
|
|
134
|
+
}).update((current) => reduceRelease(current, { holderId: workflowId, now: internals.options.getNow() }));
|
|
135
|
+
await internals.storage.delete(holderKey);
|
|
136
|
+
}
|
|
@@ -26,11 +26,10 @@ export declare const STREAM_CHUNK_KIND = "stream:chunk";
|
|
|
26
26
|
export declare const COMPACTION_BOUNDARY_KIND = "workflow:compaction-boundary";
|
|
27
27
|
/**
|
|
28
28
|
* A committed workflow-feed record surfaced to subscribers of
|
|
29
|
-
* `subscribeWorkflowFeedCommits()`. Fires after
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* before interpreting `payload`.
|
|
29
|
+
* `subscribeWorkflowFeedCommits()`. Fires after the storage commit resolves, so
|
|
30
|
+
* replay and live delivery share the same committed sequence authority. The
|
|
31
|
+
* same shape covers both selectors — consumers filter on `selector` before
|
|
32
|
+
* interpreting `payload`.
|
|
34
33
|
*
|
|
35
34
|
* - `events` selector: `kind` is the durable log entry type
|
|
36
35
|
* (e.g. `'workflow:checkpoint'`). `sequence` / `timestamp` come
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventLog } from "../event-log.js";
|
|
2
2
|
import { readEventLogWatermark } from "./event-log-compaction.js";
|
|
3
3
|
import { workflowFeedListenerKey } from "./state-utilities.js";
|
|
4
|
-
import { loadStoredStreamChunks } from "./stream-chunk-loading.js";
|
|
4
|
+
import { loadStoredStreamChunks, loadStoredStreamTailSequence } from "./stream-chunk-loading.js";
|
|
5
5
|
export const TOKENS_STREAM_KEY = "tokens", STREAM_CHUNK_KIND = "stream:chunk", COMPACTION_BOUNDARY_KIND = "workflow:compaction-boundary";
|
|
6
6
|
export async function* replayWorkflowFeed(internals, workflowId, selector, afterSequence) {
|
|
7
7
|
if (selector === "events") {
|
|
@@ -17,6 +17,9 @@ export async function snapshotWorkflowFeedTail(internals, workflowId, selector)
|
|
|
17
17
|
return head.sequence;
|
|
18
18
|
return (await new EventLog(internals.storage, workflowId).loadHead()).sequence;
|
|
19
19
|
}
|
|
20
|
+
const tail = await loadStoredStreamTailSequence(internals.storage, workflowId, TOKENS_STREAM_KEY);
|
|
21
|
+
if (tail !== null)
|
|
22
|
+
return tail;
|
|
20
23
|
const chunks = await loadStoredStreamChunks(internals.storage, workflowId, TOKENS_STREAM_KEY);
|
|
21
24
|
if (chunks.length === 0)
|
|
22
25
|
return -1;
|