@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
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { KEYS } from "../../../storage/interface.js";
|
|
2
2
|
import { deserializeCheckpoint, serializeCheckpoint } from "../../checkpoint.js";
|
|
3
|
+
import { RegExpExtensionDecodeError } from "../../codec/extension-codec.js";
|
|
3
4
|
import { Context, setContextWorkflowInterceptor } from "../../context.js";
|
|
4
5
|
import { EMPTY_EVENT_HEAD } from "../../event-log.js";
|
|
5
6
|
import { WorkflowRecoverySkippedEvent, WorkflowStartedEvent } from "../../events.js";
|
|
6
7
|
import { createCancelHandlerRegistration, resetCancelHandlers } from "../cancel-handlers.js";
|
|
7
8
|
import { forgetCommittedCheckpointBytes } from "../checkpoint-commit-snapshots.js";
|
|
9
|
+
import { hydrateCheckpointReplayState } from "../checkpoint-replay.js";
|
|
8
10
|
import { WorkflowTypeNotRegisteredForRecoveryError } from "../errors.js";
|
|
11
|
+
import { commitFencedEngineWrite } from "../fenced-write.js";
|
|
9
12
|
import { getWorkflowExecutionStartedAt } from "../handles.js";
|
|
10
13
|
import { normalizeForkStep, selectPersistedWorkflowStartHeaders } from "../state-utilities.js";
|
|
11
14
|
import { loadWorkflowState } from "../storage-io.js";
|
|
@@ -73,7 +76,15 @@ export async function recoverAll(internals, callbacks, options) {
|
|
|
73
76
|
callbacks.dispatchEvent(new WorkflowRecoverySkippedEvent(entry.workflow.workflowId, entry.workflow.type, "type-not-registered"));
|
|
74
77
|
continue;
|
|
75
78
|
}
|
|
76
|
-
|
|
79
|
+
try {
|
|
80
|
+
handles.push(await resume(internals, entry.workflowId, callbacks));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error instanceof RegExpExtensionDecodeError) {
|
|
83
|
+
await callbacks.failWorkflowForCheckpointDecodeError(entry.workflowId, error);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
77
88
|
}
|
|
78
89
|
return handles;
|
|
79
90
|
}
|
|
@@ -100,8 +111,8 @@ export async function fork(internals, sourceWorkflowId, options, callbacks) {
|
|
|
100
111
|
throw Error(`Checkpoint not found at step ${String(fromStep)} for workflow "${sourceWorkflowId}"`);
|
|
101
112
|
throw Error(`Checkpoint not found for workflow "${sourceWorkflowId}"`);
|
|
102
113
|
}
|
|
103
|
-
const
|
|
104
|
-
...
|
|
114
|
+
const storedSourceCheckpoint = deserializeCheckpoint(checkpointBytes), sourceCheckpoint = await hydrateCheckpointReplayState(internals.storage, sourceWorkflowId, storedSourceCheckpoint), preparedExecutionState = derivePreparedExecutionState(internals, sourceWorkflowId, sourceState, sourceCheckpoint, registration, callbacks), sourceWorkflowHeaders = internals.workflowHeaders.get(sourceWorkflowId) ?? await loadWorkflowStartHeaders(internals, sourceWorkflowId, callbacks), persistedWorkflowStartHeaders = selectPersistedWorkflowStartHeaders(sourceWorkflowHeaders), workflowId = crypto.randomUUID(), forkedAt = internals.options.getNow(), lineage = createForkLineage(internals, sourceWorkflowId, sourceCheckpoint, callbacks), { accumulatedResultReplayWatermark: _sourceReplayWatermark, ...sourceCheckpointForFork } = preparedExecutionState.checkpoint, forkCheckpoint = {
|
|
115
|
+
...sourceCheckpointForFork,
|
|
105
116
|
createdAt: forkedAt,
|
|
106
117
|
workflowId,
|
|
107
118
|
searchAttributes: buildForkSearchAttributes(internals, preparedExecutionState.checkpoint, lineage, callbacks)
|
|
@@ -109,7 +120,7 @@ export async function fork(internals, sourceWorkflowId, options, callbacks) {
|
|
|
109
120
|
let forkStarted = !1;
|
|
110
121
|
try {
|
|
111
122
|
const forkCheckpointBytes = serializeCheckpoint(forkCheckpoint);
|
|
112
|
-
await internals
|
|
123
|
+
await commitFencedEngineWrite(internals, buildForkBatchOperations(internals, workflowId, forkState, forkCheckpoint, forkCheckpointBytes, persistedWorkflowStartHeaders, callbacks), [], () => Error(`Fork of workflow "${workflowId}" lost its CAS race.`));
|
|
113
124
|
internals.eventLogHeads.set(workflowId, EMPTY_EVENT_HEAD);
|
|
114
125
|
setWorkflowStartHeaders(internals, workflowId, persistedWorkflowStartHeaders, callbacks);
|
|
115
126
|
const handle = launchWorkflowFromCheckpoint(internals, workflowId, forkState, forkCheckpoint, registration, callbacks);
|
|
@@ -146,7 +157,8 @@ function launchInlineWorkflowFromCheckpoint(internals, workflowId, state, checkp
|
|
|
146
157
|
searchAttributeSchema: registration.searchAttributes
|
|
147
158
|
},
|
|
148
159
|
sleepReferenceTime: checkpoint.createdAt,
|
|
149
|
-
...state.executionDeadline !== void 0 && { deadline: state.executionDeadline }
|
|
160
|
+
...state.executionDeadline !== void 0 && { deadline: state.executionDeadline },
|
|
161
|
+
...internals.options.onLog != null && { logSink: internals.options.onLog }
|
|
150
162
|
});
|
|
151
163
|
setContextWorkflowInterceptor(context, getComposedWorkflowInterceptor(internals));
|
|
152
164
|
if (internals.options.development)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { EMPTY_STORAGE_VALUE, createWorkflowHandle, loadTerminalCleanupTrackedState, loadWorkflowStartHeaders, normalizeStartWorkflowTags, processPendingUpdatesAfterReplay, setWorkflowStartHeaders, type LifecycleCallbacks, type RecoverAllOptions, } from './lifecycle/shared.ts';
|
|
2
2
|
export { createWorkflowVersionTuple, derivePreparedExecutionState, prepareResumeState, throwVersionMismatch, workflowStateWithVersionTuple, workflowVersionTupleFromState, } from './lifecycle/persist.ts';
|
|
3
3
|
export { createInitialCheckpoint, createInitialWorkflowState, parseStartOptionDuration, resolveScheduledStartAt, start, startWorkflow, } from './lifecycle/start.ts';
|
|
4
|
-
export { startOrSignal, startWithIdempotency, type StartOrSignalCallbacks, } from './lifecycle/start-or-signal.ts';
|
|
4
|
+
export { startOrSignal, startWithIdempotency, type StartOrSignalCallbacks, type StartOrSignalResult, } from './lifecycle/start-or-signal.ts';
|
|
5
5
|
export { buildInitialSearchAttributeOperations, buildStartBatchOperations, validateSearchAttributes, } from './lifecycle/start-batch.ts';
|
|
6
6
|
export { beginWorkflowExecution, runWorkflowStartInterceptor, startWorkflowExecution, } from './lifecycle/start-exec.ts';
|
|
7
7
|
export { buildForkBatchOperations, buildForkSearchAttributes, createForkLineage, createForkedWorkflowState, } from './lifecycle/fork-helpers.ts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { intersectIdentifierSets } from "./state-utilities.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getCachedWorkflowVisibilityWatermark } from "./workflow-indexes.js";
|
|
3
3
|
import { queryAttributeIndex, resolveConstrainedIds } from "./workflow-state-stream.js";
|
|
4
4
|
import {
|
|
5
5
|
queryWorkflowIdPrefixCandidates,
|
|
@@ -50,7 +50,7 @@ export async function resolveListCandidateIds(internals, filter, normalizedTagFi
|
|
|
50
50
|
resolveConstrainedIds(internals, filter, normalizedTagFilters),
|
|
51
51
|
resolveFailureCategoryCandidateIds(internals, filter?.failureCategory)
|
|
52
52
|
]);
|
|
53
|
-
if (await
|
|
53
|
+
if (await getCachedWorkflowVisibilityWatermark(internals) === "stale") {
|
|
54
54
|
const queries = filter === void 0 ? [] : collectVisibilityQueries(internals, filter, ["idPrefix"]), visibilitySets = await Promise.all(queries);
|
|
55
55
|
return combineCandidateSets([
|
|
56
56
|
baseConstrainedIds,
|
|
@@ -5,7 +5,12 @@ import { isFailureCategory, normalizeListFilter } from "../list-filter-validatio
|
|
|
5
5
|
import { buildIndexOperations, validateAttributeType } from "../search-attributes.js";
|
|
6
6
|
import { normalizeWorkflowTags } from "../workflow-tags.js";
|
|
7
7
|
import { mutateWorkflowTags, validateAttributeValueSizes } from "./attributes-tags.js";
|
|
8
|
+
import { CONSTRAINED_ID_CHUNK_SIZE } from "./candidate-read-batching.js";
|
|
8
9
|
import { resolveListCandidateIds } from "./list-candidate-resolution.js";
|
|
10
|
+
import {
|
|
11
|
+
readSearchAttributesForFilter,
|
|
12
|
+
readSearchAttributesForStates
|
|
13
|
+
} from "./search-attribute-records.js";
|
|
9
14
|
import { matchesListFilter, paginateWorkflowSummaries } from "./state-utilities.js";
|
|
10
15
|
import { decodeWorkflowState, normalizeBulkFilterNumber } from "./validation.js";
|
|
11
16
|
import { MAX_LIST_SCAN_ROWS, WorkflowListScanCapExceededError } from "./workflow-indexes.js";
|
|
@@ -18,19 +23,18 @@ export async function list(internals, filter, options) {
|
|
|
18
23
|
const normalizedFilter = filter === void 0 ? void 0 : normalizeListFilter(filter), normalizedTagFilters = normalizeWorkflowTags(normalizedFilter?.tags), constrainedIds = await resolveListCandidateIds(internals, normalizedFilter, normalizedTagFilters), items = constrainedIds !== null ? await collectSummariesFromConstrainedIds(internals, constrainedIds, normalizedFilter, normalizedTagFilters, options) : await collectSummariesFromFullScan(internals, normalizedFilter, normalizedTagFilters, options);
|
|
19
24
|
return paginateWorkflowSummaries(sortSummariesByCreatedAtDescending(items), normalizedFilter);
|
|
20
25
|
}
|
|
21
|
-
const CONSTRAINED_ID_CHUNK_SIZE = 64;
|
|
22
26
|
async function collectSummariesFromConstrainedIds(internals, constrainedIds, normalizedFilter, normalizedTagFilters, options) {
|
|
23
27
|
const orderedIds = [...constrainedIds];
|
|
24
28
|
if (orderedIds.length > MAX_LIST_SCAN_ROWS)
|
|
25
29
|
throw new WorkflowListScanCapExceededError(MAX_LIST_SCAN_ROWS);
|
|
26
30
|
const items = [];
|
|
27
31
|
for (let start = 0;start < orderedIds.length; start += CONSTRAINED_ID_CHUNK_SIZE) {
|
|
28
|
-
const chunkIds = orderedIds.slice(start, start + CONSTRAINED_ID_CHUNK_SIZE), chunkBytes = await Promise.all(chunkIds.map((workflowId) => internals.storage.get(KEYS.workflow(workflowId)))), matchingStates = [];
|
|
32
|
+
const chunkIds = orderedIds.slice(start, start + CONSTRAINED_ID_CHUNK_SIZE), chunkBytes = await Promise.all(chunkIds.map((workflowId) => internals.storage.get(KEYS.workflow(workflowId)))), searchAttributesByWorkflowId = await readSearchAttributesForStates(internals, chunkBytes, normalizedFilter), matchingStates = [];
|
|
29
33
|
for (const stateBytes of chunkBytes) {
|
|
30
34
|
if (!stateBytes)
|
|
31
35
|
continue;
|
|
32
36
|
const state = decodeWorkflowState(stateBytes);
|
|
33
|
-
if (!matchesListFilter(state, normalizedFilter, constrainedIds, normalizedTagFilters))
|
|
37
|
+
if (!matchesListFilter(state, normalizedFilter, constrainedIds, normalizedTagFilters, searchAttributesByWorkflowId.get(state.id) ?? null))
|
|
34
38
|
continue;
|
|
35
39
|
matchingStates.push(state);
|
|
36
40
|
}
|
|
@@ -47,8 +51,8 @@ async function collectSummariesFromFullScan(internals, normalizedFilter, normali
|
|
|
47
51
|
scanned += 1;
|
|
48
52
|
if (scanned > MAX_LIST_SCAN_ROWS)
|
|
49
53
|
throw new WorkflowListScanCapExceededError(MAX_LIST_SCAN_ROWS);
|
|
50
|
-
const state = decodeWorkflowState(value);
|
|
51
|
-
if (!matchesListFilter(state, normalizedFilter, null, normalizedTagFilters))
|
|
54
|
+
const state = decodeWorkflowState(value), searchAttributes = await readSearchAttributesForFilter(internals, state.id, normalizedFilter);
|
|
55
|
+
if (!matchesListFilter(state, normalizedFilter, null, normalizedTagFilters, searchAttributes))
|
|
52
56
|
continue;
|
|
53
57
|
const attributeBytes = shouldReadFailureCategoryAttribute(state, options) ? await internals.storage.get(KEYS.attribute(state.id)) : null;
|
|
54
58
|
items.push(summaryFromState(state, failureCategoryFromAttributeBytes(attributeBytes)));
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ContextOperationRequest } from '../context.ts';
|
|
2
2
|
import type { ComposedActivityInterceptor, ComposedWorkflowInterceptor } from '../interceptor.ts';
|
|
3
|
-
import type { ActivityContext, ActivityVerificationResult } from '../types.ts';
|
|
3
|
+
import type { ActivityContext, ActivityVerificationResult, OperationOutcome } from '../types.ts';
|
|
4
4
|
import { buildActivityVerificationContext, type ActivityReconciliationMetadata } from './activity-reconciliation.ts';
|
|
5
5
|
import type { EngineInternals } from './internals.ts';
|
|
6
6
|
import type { SpeculativeExecutionState } from './speculative-execution-state.ts';
|
|
7
|
+
import type { CapturedRejectionReason } from './strategy-helpers.ts';
|
|
7
8
|
export type ActivityFunctionWithMetadata = ((...arguments_: unknown[]) => unknown) & ActivityReconciliationMetadata & {
|
|
8
9
|
verify?: (result: unknown, context?: ReturnType<typeof buildActivityVerificationContext>) => Promise<ActivityVerificationResult> | ActivityVerificationResult;
|
|
9
10
|
compensate?: (input: unknown, output: unknown) => Promise<void> | void;
|
|
@@ -13,19 +14,11 @@ type ActivityOperation = Extract<ContextOperationRequest, {
|
|
|
13
14
|
}>;
|
|
14
15
|
export type ActivityOperationCallbacks = {
|
|
15
16
|
runOperationWithResult: (workflowId: string, operation: ActivityOperation, execute: () => Promise<unknown>) => Promise<void>;
|
|
17
|
+
finalizePendingTimelineEntry: (workflowId: string, status: 'completed' | 'failed', value: unknown) => void;
|
|
18
|
+
feedOperationResult: (workflowId: string, outcome: OperationOutcome, originalReason?: CapturedRejectionReason) => void;
|
|
16
19
|
getComposedActivityInterceptor: () => ComposedActivityInterceptor | null;
|
|
17
20
|
getComposedWorkflowInterceptor: () => ComposedWorkflowInterceptor | null;
|
|
18
21
|
};
|
|
19
|
-
export declare function getActivityFunctionWithMetadata(internals: EngineInternals, workflowId: string, operation: ActivityOperation): ActivityFunctionWithMetadata | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* Resolve the activity function for a given operation. Uses the same
|
|
22
|
-
* per-workflow-first-then-global ordering as `getActivityFunctionWithMetadata`.
|
|
23
|
-
* For inline-mode callers that pass an `operation.fn` directly, the registries
|
|
24
|
-
* are still consulted first so a workflow's locally-scoped activity wins over
|
|
25
|
-
* the bare callable. Throws `ActivityResolutionError` when neither path
|
|
26
|
-
* resolves.
|
|
27
|
-
*/
|
|
28
|
-
export declare function resolveActivityFunction(internals: EngineInternals, workflowId: string, operation: ActivityOperation): (...arguments_: unknown[]) => unknown;
|
|
29
22
|
export declare function buildActivityVerification(_internals: EngineInternals, activityName: string, verify: ActivityFunctionWithMetadata['verify'], context: ReturnType<typeof buildActivityVerificationContext>, result: unknown): Promise<void>;
|
|
30
23
|
export declare function buildActivityCompensation(internals: EngineInternals, workflowId: string, operation: ActivityOperation, result: unknown): (() => Promise<void>) | undefined;
|
|
31
24
|
export declare function invokeWorkerActivity(internals: EngineInternals, operationId: string, activityName: string, input: unknown, attempt: number): Promise<unknown>;
|
|
@@ -34,7 +27,7 @@ export declare function invokeInlineActivity(internals: EngineInternals, workflo
|
|
|
34
27
|
* Execute an activity function, dispatching to a Web Worker pool when
|
|
35
28
|
* `activityExecution` is configured, or running inline on the main thread.
|
|
36
29
|
*/
|
|
37
|
-
export declare function executeActivity(internals: EngineInternals, workflowId: string, operation: ActivityOperation, callbacks: ActivityOperationCallbacks, attempt?: number): Promise<unknown>;
|
|
38
|
-
export declare function executeActivityOperationResult(internals: EngineInternals, workflowId: string, operation: ActivityOperation, callbacks: ActivityOperationCallbacks, speculativeState?: SpeculativeExecutionState): Promise<unknown>;
|
|
30
|
+
export declare function executeActivity(internals: EngineInternals, workflowId: string, operation: ActivityOperation, callbacks: ActivityOperationCallbacks, attempt?: number, coordinatorSignal?: AbortSignal): Promise<unknown>;
|
|
31
|
+
export declare function executeActivityOperationResult(internals: EngineInternals, workflowId: string, operation: ActivityOperation, callbacks: ActivityOperationCallbacks, coordinatorSignal?: AbortSignal, speculativeState?: SpeculativeExecutionState): Promise<unknown>;
|
|
39
32
|
export declare function processActivityOperation(internals: EngineInternals, workflowId: string, operation: ActivityOperation, callbacks: ActivityOperationCallbacks): Promise<void>;
|
|
40
33
|
export {};
|
|
@@ -1,57 +1,27 @@
|
|
|
1
1
|
import { assertPayloadWithinLimit } from "../payload-size.js";
|
|
2
|
+
import {
|
|
3
|
+
buildActivityContext,
|
|
4
|
+
clearLastHeartbeatForStep,
|
|
5
|
+
warnIfRetryMissingHeartbeat
|
|
6
|
+
} from "./activity-heartbeat-tracking.js";
|
|
7
|
+
import { resolvePerAttemptTimeout, withPerAttemptTimeout } from "./activity-per-attempt-timeout.js";
|
|
2
8
|
import {
|
|
3
9
|
buildActivityReconciliationReference,
|
|
4
10
|
buildActivityVerificationContext,
|
|
5
11
|
createCompletedActivityReconciliationRecord,
|
|
6
12
|
resolveActivityIdempotencyKey,
|
|
7
13
|
resolveStartedActivityReconciliationRecord,
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
stageActivityReconciliationTransitionWithAtomicWorkflowCommit,
|
|
15
|
+
validateActivityResultForReconciliation
|
|
10
16
|
} from "./activity-reconciliation.js";
|
|
17
|
+
import { getActivityFunctionWithMetadata, resolveActivityFunction } from "./activity-resolution.js";
|
|
11
18
|
import {
|
|
12
19
|
AsyncActivityDeferral,
|
|
13
20
|
deriveAsyncActivityToken,
|
|
14
21
|
driveWorkflowInterceptorGenerator,
|
|
15
22
|
parkDeferredAsyncActivity
|
|
16
23
|
} from "./async-activity-completion.js";
|
|
17
|
-
import { ActivityResolutionError } from "./errors.js";
|
|
18
24
|
import { callActivityFunction } from "./state-utilities.js";
|
|
19
|
-
function resolveActivityViaRegistries(internals, workflowId, activityName) {
|
|
20
|
-
const workflowType = internals.workflowTypeByWorkflowId.get(workflowId);
|
|
21
|
-
if (workflowType !== void 0) {
|
|
22
|
-
const perWorkflow = internals.activityRegistriesByWorkflow.get(workflowType);
|
|
23
|
-
if (perWorkflow !== void 0) {
|
|
24
|
-
const perWorkflowFn = perWorkflow.resolve(activityName);
|
|
25
|
-
if (perWorkflowFn)
|
|
26
|
-
return { fn: perWorkflowFn, workflowType };
|
|
27
|
-
}
|
|
28
|
-
const globalFn = internals.activityRegistry.resolve(activityName);
|
|
29
|
-
if (globalFn)
|
|
30
|
-
return { fn: globalFn, workflowType };
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const globalFn = internals.activityRegistry.resolve(activityName);
|
|
34
|
-
if (globalFn)
|
|
35
|
-
return { fn: globalFn, workflowType: "<unknown>" };
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
export function getActivityFunctionWithMetadata(internals, workflowId, operation) {
|
|
39
|
-
const resolved = resolveActivityViaRegistries(internals, workflowId, operation.activityName);
|
|
40
|
-
if (resolved)
|
|
41
|
-
return resolved.fn;
|
|
42
|
-
if (typeof operation.fn === "function")
|
|
43
|
-
return operation.fn;
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
export function resolveActivityFunction(internals, workflowId, operation) {
|
|
47
|
-
const resolved = resolveActivityViaRegistries(internals, workflowId, operation.activityName);
|
|
48
|
-
if (resolved)
|
|
49
|
-
return resolved.fn;
|
|
50
|
-
if (operation.fn)
|
|
51
|
-
return operation.fn;
|
|
52
|
-
const workflowType = internals.workflowTypeByWorkflowId.get(workflowId) ?? "<unknown>";
|
|
53
|
-
throw new ActivityResolutionError(workflowType, operation.activityName);
|
|
54
|
-
}
|
|
55
25
|
export function buildActivityVerification(_internals, activityName, verify, context, result) {
|
|
56
26
|
return (async () => {
|
|
57
27
|
const verified = await verify?.(result, context);
|
|
@@ -99,16 +69,12 @@ function getActivityAttempt(operation) {
|
|
|
99
69
|
const attempt = operation.attempt;
|
|
100
70
|
return typeof attempt === "number" && Number.isInteger(attempt) && attempt > 0 ? attempt : 1;
|
|
101
71
|
}
|
|
102
|
-
export async function executeActivity(internals, workflowId, operation, callbacks, attempt = getActivityAttempt(operation)) {
|
|
103
|
-
const activityInput = operation.input,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
completeAsync: () => {
|
|
109
|
-
throw new AsyncActivityDeferral(asyncToken);
|
|
110
|
-
}
|
|
111
|
-
}, invokeActivity = internals.activityWorkerDispatcher ? (activityName, input) => invokeWorkerActivity(internals, operation.operationId, activityName, input, attempt) : (activityName, input) => invokeInlineActivity(internals, workflowId, operation, activityContext, activityName, input), composedActivity = callbacks.getComposedActivityInterceptor(), executeWithActivityInterceptors = async (activityName, input, headers) => {
|
|
72
|
+
export async function executeActivity(internals, workflowId, operation, callbacks, attempt = getActivityAttempt(operation), coordinatorSignal) {
|
|
73
|
+
const activityInput = operation.input, step = operation.step ?? 0;
|
|
74
|
+
warnIfRetryMissingHeartbeat(internals, workflowId, step, attempt);
|
|
75
|
+
const asyncToken = deriveAsyncActivityToken(workflowId, step, attempt), { perAttemptTimeoutMs, attemptAbortController, activitySignal } = resolvePerAttemptTimeout(internals, workflowId, operation, coordinatorSignal), activityContext = buildActivityContext(internals, workflowId, step, activitySignal, () => {
|
|
76
|
+
throw new AsyncActivityDeferral(asyncToken);
|
|
77
|
+
}), invokeActivity = internals.activityWorkerDispatcher ? (activityName, input) => invokeWorkerActivity(internals, operation.operationId, activityName, input, attempt) : (activityName, input) => withPerAttemptTimeout(invokeInlineActivity(internals, workflowId, operation, activityContext, activityName, input), perAttemptTimeoutMs, activityName, attempt, attemptAbortController), composedActivity = callbacks.getComposedActivityInterceptor(), executeWithActivityInterceptors = async (activityName, input, headers) => {
|
|
112
78
|
if (!composedActivity)
|
|
113
79
|
return invokeActivity(activityName, input);
|
|
114
80
|
const activityInterception = {
|
|
@@ -141,7 +107,7 @@ export async function executeActivity(internals, workflowId, operation, callback
|
|
|
141
107
|
copyActivityHeadersToOperation(operation, headers);
|
|
142
108
|
return result;
|
|
143
109
|
}
|
|
144
|
-
export async function executeActivityOperationResult(internals, workflowId, operation, callbacks, speculativeState) {
|
|
110
|
+
export async function executeActivityOperationResult(internals, workflowId, operation, callbacks, coordinatorSignal, speculativeState) {
|
|
145
111
|
const activity = getActivityFunctionWithMetadata(internals, workflowId, operation), idempotencyKey = resolveActivityIdempotencyKey(activity, operation), operationAttempt = getActivityAttempt(operation);
|
|
146
112
|
if (idempotencyKey !== void 0) {
|
|
147
113
|
const reference = await buildActivityReconciliationReference(workflowId, operation.activityName, idempotencyKey), started = await resolveStartedActivityReconciliationRecord(internals, workflowId, operation, reference, activity, idempotencyKey, operationAttempt);
|
|
@@ -149,16 +115,20 @@ export async function executeActivityOperationResult(internals, workflowId, oper
|
|
|
149
115
|
validateActivityResultForReconciliation(started.completedResult, internals.options.payloadSizePolicy.maxBytes);
|
|
150
116
|
return started.completedResult;
|
|
151
117
|
}
|
|
152
|
-
const result = await executeActivity(internals, workflowId, operation, callbacks, started.attempt);
|
|
118
|
+
const result = await executeActivity(internals, workflowId, operation, callbacks, started.attempt, coordinatorSignal);
|
|
153
119
|
validateActivityResultForReconciliation(result, internals.options.payloadSizePolicy.maxBytes);
|
|
154
120
|
await finalizeActivityResult(internals, workflowId, operation, result, activity, idempotencyKey, started.attempt, speculativeState, !0);
|
|
155
121
|
const completedRecord = createCompletedActivityReconciliationRecord(started, result, internals.options.getNow());
|
|
156
|
-
|
|
122
|
+
stageActivityReconciliationTransitionWithAtomicWorkflowCommit(internals, workflowId, reference, started, completedRecord);
|
|
123
|
+
if (!speculativeState)
|
|
124
|
+
clearLastHeartbeatForStep(internals, workflowId, operation.step ?? 0);
|
|
157
125
|
return result;
|
|
158
126
|
}
|
|
159
|
-
const result = await executeActivity(internals, workflowId, operation, callbacks, operationAttempt);
|
|
127
|
+
const result = await executeActivity(internals, workflowId, operation, callbacks, operationAttempt, coordinatorSignal);
|
|
160
128
|
assertPayloadWithinLimit(result, internals.options.payloadSizePolicy.maxBytes, "activity result");
|
|
161
129
|
await finalizeActivityResult(internals, workflowId, operation, result, activity, idempotencyKey, operationAttempt, speculativeState);
|
|
130
|
+
if (!speculativeState)
|
|
131
|
+
clearLastHeartbeatForStep(internals, workflowId, operation.step ?? 0);
|
|
162
132
|
return result;
|
|
163
133
|
}
|
|
164
134
|
async function finalizeActivityResult(internals, workflowId, operation, result, activity, idempotencyKey, attempt, speculativeState, awaitSpeculativeVerification = !1) {
|
|
@@ -187,6 +157,9 @@ export async function processActivityOperation(internals, workflowId, operation,
|
|
|
187
157
|
operationId: operation.operationId,
|
|
188
158
|
step: operation.step ?? 0,
|
|
189
159
|
attempt: getActivityAttempt(operation)
|
|
160
|
+
}, {
|
|
161
|
+
feedOperationResult: callbacks.feedOperationResult,
|
|
162
|
+
finalizeTimeline: callbacks.finalizePendingTimelineEntry
|
|
190
163
|
});
|
|
191
164
|
throw error;
|
|
192
165
|
}
|
|
@@ -15,6 +15,16 @@ type RaceOperation = Extract<ContextOperationRequest, {
|
|
|
15
15
|
type RunAllOperation = Extract<ContextOperationRequest, {
|
|
16
16
|
type: 'run-all';
|
|
17
17
|
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Reject a `ctx.race` / `ctx.all` whose branches wait on the SAME signal name,
|
|
20
|
+
* recursively through nested `race` / `parallel` branches. Sibling wait-signal
|
|
21
|
+
* branches share the `${workflowId}:${signalName}` waiter key, so two anywhere in
|
|
22
|
+
* the coordination tree would clobber each other at registration, leaving one
|
|
23
|
+
* branch permanently unreachable (the run would hang). Reject the meaningless
|
|
24
|
+
* shape deterministically rather than silently dropping a branch. Distinct names
|
|
25
|
+
* (the event-or-close idiom) are unaffected.
|
|
26
|
+
*/
|
|
27
|
+
export declare function assertSupportedSignalBranches(operations: readonly ContextOperationRequest[]): void;
|
|
18
28
|
export type CoordinationOperationCallbacks = {
|
|
19
29
|
completeOperation: (workflowId: string, value: unknown) => void;
|
|
20
30
|
runOperationWithResult: (workflowId: string, operation: OperationWithCallerStack, execute: () => Promise<unknown>) => Promise<void>;
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
executeRunAllBranches,
|
|
6
6
|
executeRunAllBranchesSettled
|
|
7
7
|
} from "../engine-helpers.js";
|
|
8
|
+
import { finalizeAndUnwrap } from "./deferred-consume-envelope.js";
|
|
8
9
|
import {
|
|
9
10
|
executeActivityOperationResult as executeActivityOperationResultFromInternals
|
|
10
11
|
} from "./operations-activity.js";
|
|
@@ -13,14 +14,30 @@ import {
|
|
|
13
14
|
dispatchBranchesAllSettled,
|
|
14
15
|
valuesFromSlots
|
|
15
16
|
} from "./parallel-dispatch.js";
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
consumeSignalWithAtomicWorkflowCommit,
|
|
19
|
+
trackWaiterKey,
|
|
20
|
+
untrackWaiterKey
|
|
21
|
+
} from "./signals.js";
|
|
17
22
|
import { callActivityFunction } from "./state-utilities.js";
|
|
23
|
+
export function assertSupportedSignalBranches(operations) {
|
|
24
|
+
const seen = new Set, walk = (subOperations) => {
|
|
25
|
+
for (const subOperation of subOperations)
|
|
26
|
+
if (subOperation.type === "wait-signal") {
|
|
27
|
+
if (seen.has(subOperation.signalName))
|
|
28
|
+
throw Error(`ctx.race / ctx.all cannot have two branches waiting on the same signal "${subOperation.signalName}": sibling wait-signal branches share one waiter and would clobber each other. Wait on the signal once, or use distinct signal names.`);
|
|
29
|
+
seen.add(subOperation.signalName);
|
|
30
|
+
} else if (subOperation.type === "race" || subOperation.type === "parallel")
|
|
31
|
+
walk(subOperation.operations);
|
|
32
|
+
};
|
|
33
|
+
walk(operations);
|
|
34
|
+
}
|
|
18
35
|
export async function processWaitSignalOperation(internals, workflowId, operation, callbacks) {
|
|
19
36
|
const abortSignal = internals.abortController.signal, waiterKey = `${workflowId}:${operation.signalName}`;
|
|
20
37
|
while (!0) {
|
|
21
38
|
if (abortSignal.aborted)
|
|
22
39
|
return;
|
|
23
|
-
const existingPayload = await
|
|
40
|
+
const existingPayload = await consumeSignalWithAtomicWorkflowCommit(internals, workflowId, operation.signalName);
|
|
24
41
|
if (existingPayload.found) {
|
|
25
42
|
callbacks.completeOperation(workflowId, existingPayload.payload);
|
|
26
43
|
return;
|
|
@@ -33,7 +50,7 @@ export async function processWaitSignalOperation(internals, workflowId, operatio
|
|
|
33
50
|
untrackWaiterKey(internals.signalWaitersByWorkflow, workflowId, waiterKey);
|
|
34
51
|
return;
|
|
35
52
|
}
|
|
36
|
-
const bufferedPayload = await
|
|
53
|
+
const bufferedPayload = await consumeSignalWithAtomicWorkflowCommit(internals, workflowId, operation.signalName);
|
|
37
54
|
if (bufferedPayload.found) {
|
|
38
55
|
if (internals.signalWaiters.get(waiterKey) === resolve) {
|
|
39
56
|
internals.signalWaiters.delete(waiterKey);
|
|
@@ -49,19 +66,34 @@ export async function processWaitSignalOperation(internals, workflowId, operatio
|
|
|
49
66
|
}
|
|
50
67
|
export async function processParallelOperation(internals, workflowId, operation, callbacks) {
|
|
51
68
|
return callbacks.runOperationWithResult(workflowId, operation, async () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
69
|
+
assertSupportedSignalBranches(operation.operations);
|
|
70
|
+
const resumedSlots = extractResumedSlots(operation.resumedCacheEntry), operationIds = operation.operations.map((sub, i) => typeof sub.operationId === "string" ? sub.operationId : `parallel:${operation.step}:${i}`), { slots, hasFirstError, firstError } = await dispatchBranchesAllSettled(operationIds, resumedSlots, (index) => callbacks.executeSubOperation(workflowId, operation.operations[index]));
|
|
71
|
+
if (hasFirstError)
|
|
72
|
+
assertPartialFailurePersistenceSupported(canPersistPartialEntry(internals, workflowId), slots, "ctx.all", "worker execution mode");
|
|
73
|
+
await finalizeFulfilledSlots(slots);
|
|
74
|
+
const entry = buildEntryFromSlots("all", slots);
|
|
75
|
+
writePartialEntry(internals, workflowId, operation.step, entry);
|
|
76
|
+
if (hasFirstError)
|
|
55
77
|
throw firstError;
|
|
56
|
-
}
|
|
57
78
|
return valuesFromSlots(slots);
|
|
58
79
|
});
|
|
59
80
|
}
|
|
81
|
+
async function finalizeFulfilledSlots(slots) {
|
|
82
|
+
const failure = (await Promise.allSettled(slots.map(async (slot) => {
|
|
83
|
+
if (slot.status === "fulfilled")
|
|
84
|
+
slot.value = await finalizeAndUnwrap(slot.value);
|
|
85
|
+
}))).find((outcome) => outcome.status === "rejected");
|
|
86
|
+
if (failure)
|
|
87
|
+
throw failure.reason;
|
|
88
|
+
}
|
|
60
89
|
function extractResumedSlots(resumedCacheEntry) {
|
|
61
90
|
if (!isParallelOperationCacheEntry(resumedCacheEntry))
|
|
62
91
|
return;
|
|
63
92
|
return resumedCacheEntry.branches;
|
|
64
93
|
}
|
|
94
|
+
function canPersistPartialEntry(internals, workflowId) {
|
|
95
|
+
return internals.inlineStrategy?.getContext(workflowId) !== void 0;
|
|
96
|
+
}
|
|
65
97
|
function writePartialEntry(internals, workflowId, step, entry) {
|
|
66
98
|
const context = internals.inlineStrategy?.getContext(workflowId);
|
|
67
99
|
if (context === void 0)
|
|
@@ -76,13 +108,16 @@ function assertPartialFailurePersistenceSupported(partialEntryWritten, slots, op
|
|
|
76
108
|
}
|
|
77
109
|
export async function processRaceOperation(_internals, workflowId, operation, callbacks) {
|
|
78
110
|
return callbacks.runOperationWithResult(workflowId, operation, async () => {
|
|
111
|
+
assertSupportedSignalBranches(operation.operations);
|
|
79
112
|
const controller = new AbortController, subOperations = operation.operations.map((subOperation) => callbacks.executeSubOperation(workflowId, subOperation, controller.signal));
|
|
80
113
|
Promise.allSettled(subOperations);
|
|
114
|
+
let winner;
|
|
81
115
|
try {
|
|
82
|
-
|
|
116
|
+
winner = await Promise.race(subOperations);
|
|
83
117
|
} finally {
|
|
84
118
|
controller.abort();
|
|
85
119
|
}
|
|
120
|
+
return finalizeAndUnwrap(winner);
|
|
86
121
|
});
|
|
87
122
|
}
|
|
88
123
|
export async function processRunAllOperation(internals, workflowId, operation, callbacks) {
|
|
@@ -157,6 +192,6 @@ export async function executeRunAllOperationResult(internals, workflowId, operat
|
|
|
157
192
|
activityName: fn.name,
|
|
158
193
|
fn,
|
|
159
194
|
input
|
|
160
|
-
}, callbacks.getActivityOperationCallbacks(), speculativeState);
|
|
195
|
+
}, callbacks.getActivityOperationCallbacks(), void 0, speculativeState);
|
|
161
196
|
});
|
|
162
197
|
}
|
|
@@ -18,6 +18,12 @@ export type OperationRouterCallbacks = {
|
|
|
18
18
|
processWaitUpdateOperation: (workflowId: string, operation: Extract<ContextOperationRequest, {
|
|
19
19
|
type: 'wait-update';
|
|
20
20
|
}>) => Promise<void>;
|
|
21
|
+
processWaitConditionOperation: (workflowId: string, operation: Extract<ContextOperationRequest, {
|
|
22
|
+
type: 'wait-condition';
|
|
23
|
+
}>) => Promise<void>;
|
|
24
|
+
processGetVersionOperation: (workflowId: string, operation: Extract<ContextOperationRequest, {
|
|
25
|
+
type: 'get-version';
|
|
26
|
+
}>) => Promise<void>;
|
|
21
27
|
processParallelOperation: (workflowId: string, operation: Extract<ContextOperationRequest, {
|
|
22
28
|
type: 'parallel';
|
|
23
29
|
}>) => Promise<void>;
|
|
@@ -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 {};
|