@lostgradient/weft 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +46 -5
- package/dist/client/local.d.ts +4 -1
- package/dist/client/local.js +12 -4
- 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 +41 -0
- package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +12 -1
- package/dist/core/engine/activity-resolution.d.ts +23 -0
- package/dist/core/engine/activity-resolution.js +37 -0
- package/dist/core/engine/aggregate.js +66 -30
- package/dist/core/engine/async-activity-completion.d.ts +23 -6
- package/dist/core/engine/async-activity-completion.js +53 -12
- package/dist/core/engine/attributes-tags.js +9 -4
- package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
- package/dist/core/engine/bulk-operations-purge.js +38 -3
- package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
- package/dist/core/engine/bulk-operations-shared.js +8 -2
- package/dist/core/engine/bulk-operations.d.ts +4 -1
- package/dist/core/engine/bulk-operations.js +235 -24
- package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
- package/dist/core/engine/callback-creators-bundles.js +30 -2
- package/dist/core/engine/callback-creators-core.js +6 -4
- package/dist/core/engine/callback-creators-router.js +10 -0
- package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
- package/dist/core/engine/callback-creators-schedule.js +12 -8
- package/dist/core/engine/candidate-read-batching.d.ts +6 -0
- package/dist/core/engine/candidate-read-batching.js +1 -0
- package/dist/core/engine/checkpoint-io.js +61 -25
- package/dist/core/engine/checkpoint-reads.js +3 -2
- package/dist/core/engine/checkpoint-replay.d.ts +20 -0
- package/dist/core/engine/checkpoint-replay.js +242 -0
- package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
- package/dist/core/engine/checkpoint-side-effects.js +35 -0
- package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
- package/dist/core/engine/child-workflow-cancellation.js +40 -0
- package/dist/core/engine/child-workflow.js +27 -4
- package/dist/core/engine/condition-waiters.d.ts +14 -0
- package/dist/core/engine/condition-waiters.js +5 -0
- package/dist/core/engine/construction.d.ts +3 -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 +133 -8
- 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 +4 -11
- package/dist/core/engine/operations-activity.js +22 -49
- package/dist/core/engine/operations-coordination.d.ts +10 -0
- package/dist/core/engine/operations-coordination.js +43 -8
- package/dist/core/engine/operations-router.d.ts +6 -0
- package/dist/core/engine/operations-router.js +2 -0
- package/dist/core/engine/operations-speculate.js +6 -2
- package/dist/core/engine/operations-stream.js +12 -2
- package/dist/core/engine/operations-time.d.ts +4 -2
- package/dist/core/engine/operations-time.js +14 -2
- package/dist/core/engine/operations-wait-condition.d.ts +23 -0
- package/dist/core/engine/operations-wait-condition.js +62 -0
- package/dist/core/engine/ownership-options.d.ts +23 -0
- package/dist/core/engine/ownership-options.js +26 -0
- package/dist/core/engine/payload-size-policy.d.ts +3 -0
- package/dist/core/engine/payload-size-policy.js +4 -0
- package/dist/core/engine/pending-updates.d.ts +17 -0
- package/dist/core/engine/pending-updates.js +33 -11
- package/dist/core/engine/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 +22 -3
- 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 +27 -27
- 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 +26 -26
- 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 +28 -28
- 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
|
@@ -5,8 +5,50 @@ import {
|
|
|
5
5
|
decodeCodecDate,
|
|
6
6
|
encodeCodecDate
|
|
7
7
|
} from "../codec-helpers.js";
|
|
8
|
+
import { WeftError } from "../weft-error.js";
|
|
8
9
|
import { bindSerializerRegistryToCodec, hasRegisteredSerializer } from "./serializer-registry.js";
|
|
9
|
-
const EXTENSION_TYPE_DATE = 1, EXTENSION_TYPE_REGEXP = 2, EXTENSION_TYPE_MAP = 3, EXTENSION_TYPE_SET = 4, EXTENSION_TYPE_UNDEFINED = 5, EXTENSION_TYPE_ERROR = 6;
|
|
10
|
+
const EXTENSION_TYPE_DATE = 1, EXTENSION_TYPE_REGEXP = 2, EXTENSION_TYPE_MAP = 3, EXTENSION_TYPE_SET = 4, EXTENSION_TYPE_UNDEFINED = 5, EXTENSION_TYPE_ERROR = 6, REGEXP_SOURCE_MAX_BYTES = 65535, regexpSourceTextEncoder = new TextEncoder;
|
|
11
|
+
|
|
12
|
+
export class RegExpExtensionDecodeError extends WeftError {
|
|
13
|
+
extensionType;
|
|
14
|
+
source;
|
|
15
|
+
flags;
|
|
16
|
+
sourceByteLength;
|
|
17
|
+
constructor(parameters) {
|
|
18
|
+
super("RegExpExtensionDecodeError", `RegExp extension type ${EXTENSION_TYPE_REGEXP} could not be decoded: source=${formatRegExpSourceForMessage(parameters.source, parameters.sourceByteLength)} flags=${JSON.stringify(parameters.flags)} ${parameters.reason}`, parameters.cause === void 0 ? void 0 : { cause: parameters.cause });
|
|
19
|
+
this.extensionType = EXTENSION_TYPE_REGEXP;
|
|
20
|
+
this.source = parameters.source;
|
|
21
|
+
this.flags = parameters.flags;
|
|
22
|
+
this.sourceByteLength = parameters.sourceByteLength;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function formatRegExpSourceForMessage(source, sourceByteLength) {
|
|
26
|
+
if (sourceByteLength <= 200)
|
|
27
|
+
return JSON.stringify(source);
|
|
28
|
+
return `${sourceByteLength}-byte string starting ${JSON.stringify(source.slice(0, 120))}`;
|
|
29
|
+
}
|
|
30
|
+
function decodeRegExpExtension(source, flags) {
|
|
31
|
+
const sourceByteLength = regexpSourceTextEncoder.encode(source).byteLength;
|
|
32
|
+
if (sourceByteLength > REGEXP_SOURCE_MAX_BYTES)
|
|
33
|
+
throw new RegExpExtensionDecodeError({
|
|
34
|
+
source,
|
|
35
|
+
flags,
|
|
36
|
+
sourceByteLength,
|
|
37
|
+
reason: `because source exceeds the ${REGEXP_SOURCE_MAX_BYTES}-byte limit.`
|
|
38
|
+
});
|
|
39
|
+
try {
|
|
40
|
+
return new RegExp(source, flags);
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
43
|
+
throw new RegExpExtensionDecodeError({
|
|
44
|
+
source,
|
|
45
|
+
flags,
|
|
46
|
+
sourceByteLength,
|
|
47
|
+
reason: `because ${reason}`,
|
|
48
|
+
cause
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
10
52
|
export const extensionCodec = new ExtensionCodec;
|
|
11
53
|
bindSerializerRegistryToCodec(extensionCodec, replaceUndefined);
|
|
12
54
|
extensionCodec.register({
|
|
@@ -23,7 +65,7 @@ extensionCodec.register({
|
|
|
23
65
|
},
|
|
24
66
|
decode(data) {
|
|
25
67
|
const decoded = coerceCodecRecord(msgpackDecode(data)), source = typeof decoded.source === "string" ? decoded.source : "", flags = typeof decoded.flags === "string" ? decoded.flags : "";
|
|
26
|
-
return
|
|
68
|
+
return decodeRegExpExtension(source, flags);
|
|
27
69
|
}
|
|
28
70
|
});
|
|
29
71
|
extensionCodec.register({
|
|
@@ -94,6 +136,11 @@ extensionCodec.register({
|
|
|
94
136
|
}
|
|
95
137
|
});
|
|
96
138
|
export function replaceUndefined(value, visited) {
|
|
139
|
+
if (!containsUndefined(value, visited))
|
|
140
|
+
return value;
|
|
141
|
+
return replaceUndefinedDeep(value, new Set);
|
|
142
|
+
}
|
|
143
|
+
function replaceUndefinedDeep(value, visited) {
|
|
97
144
|
if (value === void 0)
|
|
98
145
|
return undefinedSentinel;
|
|
99
146
|
if (value === null || typeof value !== "object")
|
|
@@ -121,19 +168,19 @@ function replaceObjectUndefined(value, visited) {
|
|
|
121
168
|
function replaceArrayUndefined(value, visited) {
|
|
122
169
|
const result = Array.from({ length: value.length });
|
|
123
170
|
for (let index = 0;index < value.length; index++)
|
|
124
|
-
result[index] =
|
|
171
|
+
result[index] = replaceUndefinedDeep(value[index], visited);
|
|
125
172
|
return result;
|
|
126
173
|
}
|
|
127
174
|
function replaceMapUndefined(value, visited) {
|
|
128
175
|
const result = new Map;
|
|
129
176
|
for (const [key, mapValue] of value)
|
|
130
|
-
result.set(
|
|
177
|
+
result.set(replaceUndefinedDeep(key, visited), replaceUndefinedDeep(mapValue, visited));
|
|
131
178
|
return result;
|
|
132
179
|
}
|
|
133
180
|
function replaceSetUndefined(value, visited) {
|
|
134
181
|
const result = new Set;
|
|
135
182
|
for (const setValue of value)
|
|
136
|
-
result.add(
|
|
183
|
+
result.add(replaceUndefinedDeep(setValue, visited));
|
|
137
184
|
return result;
|
|
138
185
|
}
|
|
139
186
|
function isNestedValueFree(value) {
|
|
@@ -142,6 +189,53 @@ function isNestedValueFree(value) {
|
|
|
142
189
|
function replaceRecordUndefined(value, visited) {
|
|
143
190
|
const record = value, result = {};
|
|
144
191
|
for (const key of Object.keys(record))
|
|
145
|
-
result[key] =
|
|
192
|
+
result[key] = replaceUndefinedDeep(record[key], visited);
|
|
146
193
|
return result;
|
|
147
194
|
}
|
|
195
|
+
function containsUndefined(value, visited) {
|
|
196
|
+
if (value === void 0)
|
|
197
|
+
return !0;
|
|
198
|
+
if (value === null || typeof value !== "object")
|
|
199
|
+
return !1;
|
|
200
|
+
if (visited.has(value))
|
|
201
|
+
return !1;
|
|
202
|
+
if (isNestedValueFree(value))
|
|
203
|
+
return !1;
|
|
204
|
+
visited.add(value);
|
|
205
|
+
try {
|
|
206
|
+
if (Array.isArray(value))
|
|
207
|
+
return arrayContainsUndefined(value, visited);
|
|
208
|
+
if (value instanceof Map)
|
|
209
|
+
return mapContainsUndefined(value, visited);
|
|
210
|
+
if (value instanceof Set)
|
|
211
|
+
return setContainsUndefined(value, visited);
|
|
212
|
+
return recordContainsUndefined(value, visited);
|
|
213
|
+
} finally {
|
|
214
|
+
visited.delete(value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function arrayContainsUndefined(value, visited) {
|
|
218
|
+
for (let index = 0;index < value.length; index++)
|
|
219
|
+
if (containsUndefined(value[index], visited))
|
|
220
|
+
return !0;
|
|
221
|
+
return !1;
|
|
222
|
+
}
|
|
223
|
+
function mapContainsUndefined(value, visited) {
|
|
224
|
+
for (const [key, mapValue] of value)
|
|
225
|
+
if (containsUndefined(key, visited) || containsUndefined(mapValue, visited))
|
|
226
|
+
return !0;
|
|
227
|
+
return !1;
|
|
228
|
+
}
|
|
229
|
+
function setContainsUndefined(value, visited) {
|
|
230
|
+
for (const setValue of value)
|
|
231
|
+
if (containsUndefined(setValue, visited))
|
|
232
|
+
return !0;
|
|
233
|
+
return !1;
|
|
234
|
+
}
|
|
235
|
+
function recordContainsUndefined(value, visited) {
|
|
236
|
+
const record = value;
|
|
237
|
+
for (const key of Object.keys(record))
|
|
238
|
+
if (containsUndefined(record[key], visited))
|
|
239
|
+
return !0;
|
|
240
|
+
return !1;
|
|
241
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ContextInternals } from './internals.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Durable per-step retry bookkeeping for `ctx.run`, stored in the workflow's
|
|
4
|
+
* `checkpointLocals` so it survives crash/replay. One slot holds, per step: the
|
|
5
|
+
* current attempt number, how many backoff sleeps already completed, and the
|
|
6
|
+
* first-dispatch timestamp anchoring `scheduleToCloseTimeout`. Every mutator
|
|
7
|
+
* rebuilds the slot through {@link writeRetryStateSlot} so no sub-map is silently
|
|
8
|
+
* erased when another is updated.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState";
|
|
11
|
+
declare const ACTIVITY_RETRY_STATE_VERSION = 1;
|
|
12
|
+
export declare const MAX_CHECKPOINTED_RETRY_ATTEMPT = 10000;
|
|
13
|
+
export interface ActivityRetryState {
|
|
14
|
+
version: typeof ACTIVITY_RETRY_STATE_VERSION;
|
|
15
|
+
attempts: Record<string, number>;
|
|
16
|
+
completedRetrySleeps?: Record<string, number>;
|
|
17
|
+
/**
|
|
18
|
+
* First-dispatch engine-clock timestamp per step, the anchor for
|
|
19
|
+
* `scheduleToCloseTimeout`. Written ONCE on the first dispatch of a step and
|
|
20
|
+
* never overwritten, so the wall-clock budget is measured from the original
|
|
21
|
+
* dispatch even across crash/replay. Like `completedRetrySleeps`, it must be
|
|
22
|
+
* preserved whenever the retry-state slot is rebuilt.
|
|
23
|
+
*/
|
|
24
|
+
dispatchedAt?: Record<string, number>;
|
|
25
|
+
}
|
|
26
|
+
export declare function isActivityRetryState(value: unknown): value is ActivityRetryState;
|
|
27
|
+
export declare function readActivityRetryAttempt(internals: ContextInternals, step: number): number | undefined;
|
|
28
|
+
export declare function readCompletedRetrySleepCount(internals: ContextInternals, step: number): number;
|
|
29
|
+
export declare function writeActivityRetryAttempt(internals: ContextInternals, step: number, attempt: number): void;
|
|
30
|
+
export declare function completeActivityRetryAttempt(internals: ContextInternals, step: number, completedRetrySleepCount: number): void;
|
|
31
|
+
/**
|
|
32
|
+
* Read the first-dispatch anchor for a step's `scheduleToCloseTimeout`, writing
|
|
33
|
+
* `now` on the first dispatch. Read-first so a crash/replay never resets the
|
|
34
|
+
* window: the budget is measured from the original dispatch, and the anchor
|
|
35
|
+
* lands in the checkpoint committed at the dispatch `yield` that follows.
|
|
36
|
+
*/
|
|
37
|
+
export declare function readOrInitActivityDispatchedAt(internals: ContextInternals, step: number, now: number): number;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState";
|
|
2
|
+
const ACTIVITY_RETRY_STATE_VERSION = 1;
|
|
3
|
+
export const MAX_CHECKPOINTED_RETRY_ATTEMPT = 1e4;
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function isActivityRetryState(value) {
|
|
8
|
+
return isRecord(value) && value.version === ACTIVITY_RETRY_STATE_VERSION && isRecord(value.attempts) && (value.completedRetrySleeps === void 0 || isRecord(value.completedRetrySleeps)) && (value.dispatchedAt === void 0 || isRecord(value.dispatchedAt));
|
|
9
|
+
}
|
|
10
|
+
function assertValidRetryAttempt(attempt, step) {
|
|
11
|
+
if (!Number.isInteger(attempt) || attempt <= 1 || attempt > MAX_CHECKPOINTED_RETRY_ATTEMPT)
|
|
12
|
+
throw Error(`Invalid checkpointed activity retry attempt ${String(attempt)} for step ${String(step)}`);
|
|
13
|
+
}
|
|
14
|
+
export function readActivityRetryAttempt(internals, step) {
|
|
15
|
+
const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
|
|
16
|
+
if (!isActivityRetryState(state))
|
|
17
|
+
return;
|
|
18
|
+
const attempt = state.attempts[String(step)];
|
|
19
|
+
if (attempt === void 0)
|
|
20
|
+
return;
|
|
21
|
+
assertValidRetryAttempt(attempt, step);
|
|
22
|
+
return attempt;
|
|
23
|
+
}
|
|
24
|
+
export function readCompletedRetrySleepCount(internals, step) {
|
|
25
|
+
const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
|
|
26
|
+
if (!isActivityRetryState(state))
|
|
27
|
+
return 0;
|
|
28
|
+
const count = state.completedRetrySleeps?.[String(step)];
|
|
29
|
+
if (count === void 0)
|
|
30
|
+
return 0;
|
|
31
|
+
if (!Number.isInteger(count) || count < 0 || count > MAX_CHECKPOINTED_RETRY_ATTEMPT)
|
|
32
|
+
throw Error(`Invalid checkpointed activity retry sleep count ${String(count)} for step ${String(step)}`);
|
|
33
|
+
return count;
|
|
34
|
+
}
|
|
35
|
+
function currentRetryState(internals) {
|
|
36
|
+
const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
|
|
37
|
+
return isActivityRetryState(current) ? current : void 0;
|
|
38
|
+
}
|
|
39
|
+
function writeRetryStateSlot(internals, attempts, completedRetrySleeps, dispatchedAt) {
|
|
40
|
+
const { [ACTIVITY_RETRY_STATE_LOCAL_KEY]: _removed, ...remainingLocals } = internals.checkpointLocals, hasAttempts = Object.keys(attempts).length > 0, hasSleeps = completedRetrySleeps !== void 0 && Object.keys(completedRetrySleeps).length > 0, hasDispatched = dispatchedAt !== void 0 && Object.keys(dispatchedAt).length > 0;
|
|
41
|
+
if (!hasAttempts && !hasSleeps && !hasDispatched) {
|
|
42
|
+
internals.checkpointLocals = remainingLocals;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
internals.checkpointLocals = {
|
|
46
|
+
...remainingLocals,
|
|
47
|
+
[ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
|
|
48
|
+
version: ACTIVITY_RETRY_STATE_VERSION,
|
|
49
|
+
attempts,
|
|
50
|
+
...hasSleeps ? { completedRetrySleeps } : {},
|
|
51
|
+
...hasDispatched ? { dispatchedAt } : {}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function writeActivityRetryAttempt(internals, step, attempt) {
|
|
56
|
+
assertValidRetryAttempt(attempt, step);
|
|
57
|
+
const current = currentRetryState(internals), attempts = current ? { ...current.attempts } : {};
|
|
58
|
+
attempts[String(step)] = attempt;
|
|
59
|
+
writeRetryStateSlot(internals, attempts, current?.completedRetrySleeps, current?.dispatchedAt);
|
|
60
|
+
}
|
|
61
|
+
function clearActivityRetryAttempt(internals, step) {
|
|
62
|
+
const current = currentRetryState(internals);
|
|
63
|
+
if (!current)
|
|
64
|
+
return;
|
|
65
|
+
const attempts = { ...current.attempts };
|
|
66
|
+
delete attempts[String(step)];
|
|
67
|
+
writeRetryStateSlot(internals, attempts, current.completedRetrySleeps, current.dispatchedAt);
|
|
68
|
+
}
|
|
69
|
+
export function completeActivityRetryAttempt(internals, step, completedRetrySleepCount) {
|
|
70
|
+
if (!Number.isInteger(completedRetrySleepCount) || completedRetrySleepCount < 0 || completedRetrySleepCount > MAX_CHECKPOINTED_RETRY_ATTEMPT)
|
|
71
|
+
throw Error(`Invalid completed activity retry sleep count ${String(completedRetrySleepCount)} for step ${String(step)}`);
|
|
72
|
+
clearActivityRetryAttempt(internals, step);
|
|
73
|
+
if (completedRetrySleepCount === 0)
|
|
74
|
+
return;
|
|
75
|
+
const current = currentRetryState(internals), attempts = current ? { ...current.attempts } : {}, completedRetrySleeps = current ? { ...current.completedRetrySleeps } : {};
|
|
76
|
+
completedRetrySleeps[String(step)] = completedRetrySleepCount;
|
|
77
|
+
writeRetryStateSlot(internals, attempts, completedRetrySleeps, current?.dispatchedAt);
|
|
78
|
+
}
|
|
79
|
+
export function readOrInitActivityDispatchedAt(internals, step, now) {
|
|
80
|
+
const current = currentRetryState(internals), existing = current?.dispatchedAt?.[String(step)];
|
|
81
|
+
if (typeof existing === "number" && Number.isFinite(existing))
|
|
82
|
+
return existing;
|
|
83
|
+
if (existing !== void 0)
|
|
84
|
+
throw Error(`Invalid checkpointed activity dispatch anchor ${String(existing)} for step ${String(step)}`);
|
|
85
|
+
const attempts = current ? { ...current.attempts } : {}, dispatchedAt = current?.dispatchedAt ? { ...current.dispatchedAt } : {};
|
|
86
|
+
dispatchedAt[String(step)] = now;
|
|
87
|
+
writeRetryStateSlot(internals, attempts, current?.completedRetrySleeps, dispatchedAt);
|
|
88
|
+
return now;
|
|
89
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { ActivityCallOptions, Duration } from '../types.ts';
|
|
2
|
+
import { WeftError } from '../weft-error.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when an activity's {@link ActivityCallOptions.scheduleToCloseTimeout}
|
|
5
|
+
* is enforced at the retry boundary. This fires in two situations, both reported
|
|
6
|
+
* with the **actual** wall-clock {@link elapsed} at the moment of the throw:
|
|
7
|
+
*
|
|
8
|
+
* - The budget has genuinely elapsed (`elapsed >= budget`) — an attempt overran,
|
|
9
|
+
* or downtime during a backoff sleep pushed wall time past the deadline.
|
|
10
|
+
* - The budget has NOT yet elapsed, but the next retry's backoff would start it at
|
|
11
|
+
* or after the deadline — so Weft refuses to schedule a doomed sleep and fails at
|
|
12
|
+
* the retry decision point. In this case {@link projectedNextDispatchElapsed} is
|
|
13
|
+
* set to the elapsed milliseconds after first dispatch at which the skipped retry
|
|
14
|
+
* would have started.
|
|
15
|
+
*
|
|
16
|
+
* The name is registered as a `timeout` failure category, so it classifies and is
|
|
17
|
+
* searchable the same way the other timeout errors are.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { ActivityScheduleToCloseTimeoutError } from '@lostgradient/weft';
|
|
22
|
+
*
|
|
23
|
+
* function exceededRetryBudget(error: unknown): boolean {
|
|
24
|
+
* return error instanceof ActivityScheduleToCloseTimeoutError;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class ActivityScheduleToCloseTimeoutError extends WeftError<'ActivityScheduleToCloseTimeoutError'> {
|
|
29
|
+
readonly activityName: string;
|
|
30
|
+
/** Actual wall-clock milliseconds elapsed since first dispatch, at the throw. */
|
|
31
|
+
readonly elapsed: number;
|
|
32
|
+
readonly budget: number;
|
|
33
|
+
/**
|
|
34
|
+
* When the failure is the early retry-decision case (the budget has not yet
|
|
35
|
+
* elapsed but the next backoff would start the retry at or after the deadline),
|
|
36
|
+
* the elapsed milliseconds after first dispatch at which that skipped retry would
|
|
37
|
+
* have started. `undefined` when the budget had genuinely elapsed at the throw.
|
|
38
|
+
*/
|
|
39
|
+
readonly projectedNextDispatchElapsed?: number;
|
|
40
|
+
constructor(activityName: string, elapsed: number, budget: number, projectedNextDispatchElapsed?: number);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Thrown when an inline activity attempt overruns its per-attempt
|
|
44
|
+
* {@link ActivityCallOptions.timeout} wall-clock cap. The cap is measured fresh
|
|
45
|
+
* on every attempt (unlike {@link ActivityScheduleToCloseTimeoutError}, which is a
|
|
46
|
+
* single budget across all attempts), so the {@link attempt} number is reported.
|
|
47
|
+
*
|
|
48
|
+
* When this fires, the workflow stops awaiting the attempt and the activity's
|
|
49
|
+
* `AbortSignal` is aborted so a cooperating activity can stop promptly — but Weft
|
|
50
|
+
* cannot forcibly preempt a running activity function, so a non-cooperating
|
|
51
|
+
* activity keeps executing in the background until it returns. The timed-out
|
|
52
|
+
* attempt is retried (with a fresh cap) when a retry policy permits.
|
|
53
|
+
*
|
|
54
|
+
* The name is registered as a `timeout` failure category, so it classifies and is
|
|
55
|
+
* searchable the same way the other timeout errors are. `timeout` is enforced for
|
|
56
|
+
* **inline** execution only; worker-mode per-attempt bounds are governed by
|
|
57
|
+
* `visibilityTimeout`.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { ActivityPerAttemptTimeoutError } from '@lostgradient/weft';
|
|
62
|
+
*
|
|
63
|
+
* function overranAttempt(error: unknown): boolean {
|
|
64
|
+
* return error instanceof ActivityPerAttemptTimeoutError;
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare class ActivityPerAttemptTimeoutError extends WeftError<'ActivityPerAttemptTimeoutError'> {
|
|
69
|
+
readonly activityName: string;
|
|
70
|
+
/** The 1-based attempt number that overran its per-attempt cap. */
|
|
71
|
+
readonly attempt: number;
|
|
72
|
+
/** The per-attempt wall-clock cap, in milliseconds. */
|
|
73
|
+
readonly timeoutMs: number;
|
|
74
|
+
constructor(activityName: string, attempt: number, timeoutMs: number);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The largest delay a single `setTimeout` can represent without 32-bit overflow.
|
|
78
|
+
* A delay above this silently wraps and fires almost immediately, so a per-attempt
|
|
79
|
+
* `timeout` larger than this is rejected rather than misbehaving. (~24.8 days.)
|
|
80
|
+
*/
|
|
81
|
+
export declare const MAX_PER_ATTEMPT_TIMEOUT_MS = 2147483647;
|
|
82
|
+
/**
|
|
83
|
+
* Parse a per-attempt `timeout` duration to milliseconds, or `undefined` when
|
|
84
|
+
* unset. The value is read off the serialized activity operation, so it is typed
|
|
85
|
+
* `unknown` and validated here as hostile input: only a `number`/`string`
|
|
86
|
+
* {@link Duration} is accepted, and `parseDuration` enforces finite/non-negative
|
|
87
|
+
* so the cap can never silently become `NaN`/`Infinity`/negative. A `0`ms cap is
|
|
88
|
+
* rejected as meaningless (it would expire an attempt before it could run) —
|
|
89
|
+
* callers must omit `timeout` to disable the cap rather than passing `0` — and a
|
|
90
|
+
* value above {@link MAX_PER_ATTEMPT_TIMEOUT_MS} is rejected because it would
|
|
91
|
+
* overflow the underlying `setTimeout` and fire almost immediately.
|
|
92
|
+
*/
|
|
93
|
+
export declare function parsePerAttemptTimeoutMs(timeout: unknown): number | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* The first-dispatch anchor and parsed budget for a `ctx.run` call's
|
|
96
|
+
* `scheduleToCloseTimeout`, or `undefined` when no budget is configured.
|
|
97
|
+
*/
|
|
98
|
+
export type ScheduleToCloseBudget = {
|
|
99
|
+
budgetMs: number;
|
|
100
|
+
dispatchedAt: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Parse a `scheduleToCloseTimeout` duration to milliseconds, or `undefined` when
|
|
104
|
+
* unset. `parseDuration` validates the result is finite and non-negative on every
|
|
105
|
+
* input path (numeric and string, via `assertValidDurationMilliseconds`) and
|
|
106
|
+
* throws otherwise — so the budget can never silently become `NaN`/`Infinity`
|
|
107
|
+
* (which would make `elapsed >= budgetMs` always-false) or negative. `0` is valid
|
|
108
|
+
* (it permits exactly one attempt).
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseScheduleToCloseBudgetMs(scheduleToCloseTimeout: Duration | undefined): number | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Resolve the cross-attempt wall-clock budget for a `ctx.run` call: a per-call
|
|
113
|
+
* `scheduleToCloseTimeout` overrides the activity definition's default. String
|
|
114
|
+
* activities have no definition fields, so only the per-call option applies. The
|
|
115
|
+
* by-reference arm is `Function & { scheduleToCloseTimeout?: Duration }` to match
|
|
116
|
+
* the caller's `ActivityInput` (a callable carrying the activity definition); this
|
|
117
|
+
* resolver reads only the single `scheduleToCloseTimeout` field off it.
|
|
118
|
+
*/
|
|
119
|
+
export declare function resolveActivityScheduleToCloseTimeout(activity: string | (Function & {
|
|
120
|
+
scheduleToCloseTimeout?: Duration;
|
|
121
|
+
}), options: ActivityCallOptions | undefined): Duration | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve the per-attempt `timeout` for a `ctx.run` call: a per-call `timeout`
|
|
124
|
+
* overrides the activity definition's default. String activities have no
|
|
125
|
+
* definition fields, so only the per-call option applies. Mirrors
|
|
126
|
+
* {@link resolveActivityScheduleToCloseTimeout} so the per-attempt cap honors a
|
|
127
|
+
* `timeout` declared on the activity definition, not just at the call site.
|
|
128
|
+
*/
|
|
129
|
+
export declare function resolveActivityTimeout(activity: string | (Function & {
|
|
130
|
+
timeout?: Duration;
|
|
131
|
+
}), options: ActivityCallOptions | undefined): Duration | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Whether the schedule-to-close budget is exhausted at the given clock value.
|
|
134
|
+
* The comparison is `>=` so an exact-deadline or zero-budget retry is treated as
|
|
135
|
+
* exhausted — a `0`ms budget allows exactly one attempt, then throws.
|
|
136
|
+
*/
|
|
137
|
+
export declare function isScheduleToCloseBudgetExhausted(budget: ScheduleToCloseBudget, now: number): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Throw {@link ActivityScheduleToCloseTimeoutError} when the schedule-to-close
|
|
140
|
+
* budget bars the next attempt, otherwise return. Called two ways at the retry
|
|
141
|
+
* boundary, both routing through this single check; the thrown error always
|
|
142
|
+
* reports the ACTUAL elapsed time at `now`, never a projected one:
|
|
143
|
+
*
|
|
144
|
+
* - **Top of the retry loop** (`now = getNow()`, no `projectedNextDispatchClock`):
|
|
145
|
+
* the live clock has reached or passed the deadline — an attempt overran, or
|
|
146
|
+
* downtime during a backoff replay pushed wall time past it. Exhaustion is
|
|
147
|
+
* checked at `now`; the error reports `now - dispatchedAt` and no projection.
|
|
148
|
+
* - **Catch branch** (`now = getNow()`, `projectedNextDispatchClock = now +
|
|
149
|
+
* nextBackoff`, both from a single clock read): the budget may not have elapsed
|
|
150
|
+
* yet, but the next backoff would start the retry at or after the deadline, so we
|
|
151
|
+
* refuse to schedule that doomed sleep and fail at the retry decision point.
|
|
152
|
+
* Exhaustion is checked at the PROJECTED dispatch clock; the error still reports
|
|
153
|
+
* the actual `now - dispatchedAt` elapsed plus the projected next-dispatch
|
|
154
|
+
* (as elapsed-since-first-dispatch ms) as the deciding reason.
|
|
155
|
+
*
|
|
156
|
+
* `budget` is `undefined` when no `scheduleToCloseTimeout` is configured, in which
|
|
157
|
+
* case this is a no-op.
|
|
158
|
+
*/
|
|
159
|
+
export declare function assertScheduleToCloseBudgetNotExhausted(budget: ScheduleToCloseBudget | undefined, activityName: string, now: number, projectedNextDispatchClock?: number): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { parseDuration } from "../scheduler.js";
|
|
2
|
+
import { WeftError } from "../weft-error.js";
|
|
3
|
+
|
|
4
|
+
export class ActivityScheduleToCloseTimeoutError extends WeftError {
|
|
5
|
+
activityName;
|
|
6
|
+
elapsed;
|
|
7
|
+
budget;
|
|
8
|
+
projectedNextDispatchElapsed;
|
|
9
|
+
constructor(activityName, elapsed, budget, projectedNextDispatchElapsed) {
|
|
10
|
+
super("ActivityScheduleToCloseTimeoutError", projectedNextDispatchElapsed === void 0 ? `Activity "${activityName}" exceeded its scheduleToCloseTimeout budget of ${budget}ms (elapsed ${elapsed}ms across retries)` : `Activity "${activityName}" will not retry within its scheduleToCloseTimeout budget of ${budget}ms (elapsed ${elapsed}ms; next retry would start at ${projectedNextDispatchElapsed}ms after first dispatch, at or beyond the deadline)`);
|
|
11
|
+
this.activityName = activityName;
|
|
12
|
+
this.elapsed = elapsed;
|
|
13
|
+
this.budget = budget;
|
|
14
|
+
if (projectedNextDispatchElapsed !== void 0)
|
|
15
|
+
this.projectedNextDispatchElapsed = projectedNextDispatchElapsed;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class ActivityPerAttemptTimeoutError extends WeftError {
|
|
20
|
+
activityName;
|
|
21
|
+
attempt;
|
|
22
|
+
timeoutMs;
|
|
23
|
+
constructor(activityName, attempt, timeoutMs) {
|
|
24
|
+
super("ActivityPerAttemptTimeoutError", `Activity "${activityName}" attempt ${attempt} exceeded its per-attempt timeout of ${timeoutMs}ms`);
|
|
25
|
+
this.activityName = activityName;
|
|
26
|
+
this.attempt = attempt;
|
|
27
|
+
this.timeoutMs = timeoutMs;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const MAX_PER_ATTEMPT_TIMEOUT_MS = 2147483647;
|
|
31
|
+
export function parsePerAttemptTimeoutMs(timeout) {
|
|
32
|
+
if (timeout === void 0)
|
|
33
|
+
return;
|
|
34
|
+
if (typeof timeout !== "number" && typeof timeout !== "string")
|
|
35
|
+
throw Error(`Activity timeout must be a number or duration string when set (got ${typeof timeout}).`);
|
|
36
|
+
const ms = parseDuration(timeout);
|
|
37
|
+
if (ms <= 0)
|
|
38
|
+
throw Error(`Activity timeout must be greater than 0ms when set (got ${ms}ms); omit it to disable the per-attempt cap.`);
|
|
39
|
+
if (ms > MAX_PER_ATTEMPT_TIMEOUT_MS)
|
|
40
|
+
throw Error(`Activity timeout of ${ms}ms exceeds the maximum supported per-attempt cap of ${MAX_PER_ATTEMPT_TIMEOUT_MS}ms (~24.8 days).`);
|
|
41
|
+
return ms;
|
|
42
|
+
}
|
|
43
|
+
export function parseScheduleToCloseBudgetMs(scheduleToCloseTimeout) {
|
|
44
|
+
return scheduleToCloseTimeout === void 0 ? void 0 : parseDuration(scheduleToCloseTimeout);
|
|
45
|
+
}
|
|
46
|
+
export function resolveActivityScheduleToCloseTimeout(activity, options) {
|
|
47
|
+
if (options?.scheduleToCloseTimeout !== void 0)
|
|
48
|
+
return options.scheduleToCloseTimeout;
|
|
49
|
+
if (typeof activity === "string")
|
|
50
|
+
return;
|
|
51
|
+
return activity.scheduleToCloseTimeout;
|
|
52
|
+
}
|
|
53
|
+
export function resolveActivityTimeout(activity, options) {
|
|
54
|
+
if (options?.timeout !== void 0)
|
|
55
|
+
return options.timeout;
|
|
56
|
+
if (typeof activity === "string")
|
|
57
|
+
return;
|
|
58
|
+
return activity.timeout;
|
|
59
|
+
}
|
|
60
|
+
export function isScheduleToCloseBudgetExhausted(budget, now) {
|
|
61
|
+
return now - budget.dispatchedAt >= budget.budgetMs;
|
|
62
|
+
}
|
|
63
|
+
export function assertScheduleToCloseBudgetNotExhausted(budget, activityName, now, projectedNextDispatchClock) {
|
|
64
|
+
if (budget === void 0)
|
|
65
|
+
return;
|
|
66
|
+
if (!isScheduleToCloseBudgetExhausted(budget, projectedNextDispatchClock ?? now))
|
|
67
|
+
return;
|
|
68
|
+
throw new ActivityScheduleToCloseTimeoutError(activityName, now - budget.dispatchedAt, budget.budgetMs, projectedNextDispatchClock !== void 0 && now - budget.dispatchedAt < budget.budgetMs ? projectedNextDispatchClock - budget.dispatchedAt : void 0);
|
|
69
|
+
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type { ChildWorkflowOptions, ChildWorkflowTarget, WorkflowMapOptions, WorkflowPipeStage, WorkflowReduceInput, WorkflowReduceOptions } from '../types.ts';
|
|
1
|
+
import type { AwaitChildWorkflowOptions, ChildWorkflowHandle, ChildWorkflowOptions, ChildWorkflowTarget, WorkflowMapOptions, WorkflowPipeStage, WorkflowReduceInput, WorkflowReduceOptions } from '../types.ts';
|
|
2
2
|
import type { Context } from './index.ts';
|
|
3
3
|
import type { ContextInternals } from './internals.ts';
|
|
4
4
|
import type { ContextOperationRequest } from './operation-request.ts';
|
|
5
5
|
export declare function normalizePipeStage(internals: ContextInternals, stage: WorkflowPipeStage | ChildWorkflowTarget): {
|
|
6
6
|
workflowType: string;
|
|
7
|
-
options:
|
|
7
|
+
options: AwaitChildWorkflowOptions | undefined;
|
|
8
8
|
};
|
|
9
9
|
export declare function resolveChildWorkflowTarget<TInput = unknown, TOutput = unknown>(internals: ContextInternals, target: ChildWorkflowTarget<TInput, TOutput>): string;
|
|
10
10
|
export declare function resolveMapConcurrency(totalItems: number, requestedConcurrency: number | undefined): number;
|
|
11
11
|
export declare function createCompositionToken(internals: ContextInternals, kind: 'map' | 'pipe' | 'reduce'): string;
|
|
12
|
-
export declare function createCompositionChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options?:
|
|
13
|
-
export declare function createReduceChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options: WorkflowReduceOptions | undefined):
|
|
12
|
+
export declare function createCompositionChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options?: AwaitChildWorkflowOptions | undefined): AwaitChildWorkflowOptions;
|
|
13
|
+
export declare function createReduceChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options: WorkflowReduceOptions | undefined): AwaitChildWorkflowOptions;
|
|
14
14
|
export declare function primeParallelOperations(operations: Generator<ContextOperationRequest, unknown, unknown>[]): ContextOperationRequest[];
|
|
15
|
-
export declare function startChild<TResult = unknown>(context: Context, internals: ContextInternals, workflowType: string, input: unknown, options?: ChildWorkflowOptions): Generator<ContextOperationRequest, TResult
|
|
15
|
+
export declare function startChild<TResult = unknown>(context: Context, internals: ContextInternals, workflowType: string, input: unknown, options?: ChildWorkflowOptions): Generator<ContextOperationRequest, TResult | ChildWorkflowHandle<TResult>, unknown>;
|
|
16
16
|
export declare function pipe<TResult = unknown>(context: Context, internals: ContextInternals, stages: Array<WorkflowPipeStage | ChildWorkflowTarget>, input: unknown): Generator<ContextOperationRequest, TResult, unknown>;
|
|
17
17
|
export declare function map<TItem, TResult>(context: Context, internals: ContextInternals, items: readonly TItem[], workflowType: ChildWorkflowTarget<TItem, TResult>, options?: WorkflowMapOptions): Generator<ContextOperationRequest, TResult[], unknown>;
|
|
18
18
|
export declare function reduce<TItem, TAccumulator>(context: Context, internals: ContextInternals, items: readonly TItem[], workflowType: ChildWorkflowTarget<WorkflowReduceInput<TAccumulator, TItem>, TAccumulator>, initialValue: TAccumulator, options?: WorkflowReduceOptions): Generator<ContextOperationRequest, TAccumulator, unknown>;
|
|
@@ -28,6 +28,7 @@ export function createCompositionToken(internals, kind) {
|
|
|
28
28
|
return `${kind}:${internals.stepIndex}`;
|
|
29
29
|
}
|
|
30
30
|
export function createCompositionChildWorkflowOptions(internals, token, index, options = void 0) {
|
|
31
|
+
assertCompositionAwaitsChildWorkflow(options);
|
|
31
32
|
if (options?.id !== void 0)
|
|
32
33
|
return options;
|
|
33
34
|
return {
|
|
@@ -39,11 +40,20 @@ export function createReduceChildWorkflowOptions(internals, token, index, option
|
|
|
39
40
|
if (options === void 0)
|
|
40
41
|
return createCompositionChildWorkflowOptions(internals, token, index);
|
|
41
42
|
const { idPrefix, ...childWorkflowOptions } = options;
|
|
43
|
+
assertCompositionAwaitsChildWorkflow(childWorkflowOptions);
|
|
42
44
|
return createCompositionChildWorkflowOptions(internals, token, index, idPrefix !== void 0 ? {
|
|
43
45
|
...childWorkflowOptions,
|
|
44
46
|
id: `${idPrefix}:${index}`
|
|
45
47
|
} : childWorkflowOptions);
|
|
46
48
|
}
|
|
49
|
+
function assertCompositionAwaitsChildWorkflow(options) {
|
|
50
|
+
if (typeof options !== "object" || options === null || !("parentClosePolicy" in options))
|
|
51
|
+
return;
|
|
52
|
+
const parentClosePolicy = options.parentClosePolicy;
|
|
53
|
+
if (parentClosePolicy === void 0 || parentClosePolicy === "await")
|
|
54
|
+
return;
|
|
55
|
+
throw Error('ctx.pipe, ctx.map, and ctx.reduce always await child workflow results. Use ctx.startChild() directly for parentClosePolicy: "abandon" or "request-cancel".');
|
|
56
|
+
}
|
|
47
57
|
export function primeParallelOperations(operations) {
|
|
48
58
|
const subOperations = [];
|
|
49
59
|
for (const generator of operations) {
|
|
@@ -58,7 +68,7 @@ export function* startChild(context, internals, workflowType, input, options) {
|
|
|
58
68
|
if (internals.accumulatedResults?.has(step)) {
|
|
59
69
|
if (internals.explainMode)
|
|
60
70
|
console.log(`[weft] ctx.startChild("${workflowType}") \u2192 Returning cached result from step ${step}`);
|
|
61
|
-
return internals.accumulatedResults.get(step);
|
|
71
|
+
return resolveCachedStartChildResult(internals.accumulatedResults.get(step), options);
|
|
62
72
|
}
|
|
63
73
|
if (internals.explainMode) {
|
|
64
74
|
console.log(`[weft] ctx.startChild("${workflowType}", ${JSON.stringify(input)})`);
|
|
@@ -74,7 +84,10 @@ export function* startChild(context, internals, workflowType, input, options) {
|
|
|
74
84
|
...options !== void 0 ? { options } : {}
|
|
75
85
|
};
|
|
76
86
|
context.accumulatedResults.set(step, result);
|
|
77
|
-
return result;
|
|
87
|
+
return resolveCachedStartChildResult(result, options);
|
|
88
|
+
}
|
|
89
|
+
function resolveCachedStartChildResult(result, options) {
|
|
90
|
+
return (options?.parentClosePolicy ?? "await") === "await" ? result : result;
|
|
78
91
|
}
|
|
79
92
|
export function* pipe(context, internals, stages, input) {
|
|
80
93
|
const pipelineToken = createCompositionToken(internals, "pipe");
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Context } from './index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Presence checks over a {@link Context}'s lazily-allocated internal maps. Each
|
|
4
|
+
* returns `true` only when the backing structure exists *and* is non-empty, so
|
|
5
|
+
* the checkpoint-commit and inline-parking paths can decide whether a context
|
|
6
|
+
* carries pending attribute changes, registered update handlers, or exposed
|
|
7
|
+
* accessors without forcing allocation through the public getters.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from the `Context` class (which sits at the module line ceiling) as
|
|
10
|
+
* free functions; behavior is identical to the former `ctx.has*` getters.
|
|
11
|
+
*
|
|
12
|
+
* @module core/context/context-presence
|
|
13
|
+
*/
|
|
14
|
+
/** True when the context has at least one pending search-attribute change. */
|
|
15
|
+
export declare function hasPendingAttributeChanges(context: Context): boolean;
|
|
16
|
+
/** True when the context has at least one registered update handler. */
|
|
17
|
+
export declare function hasUpdateHandlers(context: Context): boolean;
|
|
18
|
+
/** True when the context has at least one exposed accessor. */
|
|
19
|
+
export declare function hasExposedAccessors(context: Context): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getInternals } from "./internals.js";
|
|
2
|
+
export function hasPendingAttributeChanges(context) {
|
|
3
|
+
const pendingAttributeChanges = getInternals(context).pendingAttributeChanges;
|
|
4
|
+
return pendingAttributeChanges !== void 0 && Object.keys(pendingAttributeChanges).length > 0;
|
|
5
|
+
}
|
|
6
|
+
export function hasUpdateHandlers(context) {
|
|
7
|
+
const updateHandlers = getInternals(context).updateHandlers;
|
|
8
|
+
return updateHandlers !== void 0 && updateHandlers.size > 0;
|
|
9
|
+
}
|
|
10
|
+
export function hasExposedAccessors(context) {
|
|
11
|
+
const exposedValues = getInternals(context).exposedValues;
|
|
12
|
+
return exposedValues !== void 0 && exposedValues.size > 0;
|
|
13
|
+
}
|
|
@@ -18,6 +18,31 @@ export declare function completePreparedSleepOperation(context: Context, prepare
|
|
|
18
18
|
}>): Generator<ContextOperationRequest, void, unknown>;
|
|
19
19
|
export declare function sleep(context: Context, internals: ContextInternals, duration: Duration): Generator<ContextOperationRequest, void, unknown>;
|
|
20
20
|
export declare function waitForSignal<T = unknown>(context: Context, internals: ContextInternals, name: string): Generator<ContextOperationRequest, T, unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Read the absolute deadline anchor for a `ctx.waitUntil` step, writing it on the
|
|
23
|
+
* first evaluation. Read-first so a crash/replay never resets the window: the
|
|
24
|
+
* timeout is measured from the original first yield, and the anchor lands in the
|
|
25
|
+
* checkpoint committed at that yield — the same atomicity the activity
|
|
26
|
+
* schedule-to-close anchor (`readOrInitActivityDispatchedAt`) relies on.
|
|
27
|
+
*
|
|
28
|
+
* Returns `undefined` when no timeout was supplied (wait forever).
|
|
29
|
+
*/
|
|
30
|
+
export declare function readOrInitConditionDeadline(internals: ContextInternals, step: number, timeout: Duration | undefined): number | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Wait until `predicate` returns `true`, re-evaluated by the engine each time the
|
|
33
|
+
* workflow is driven forward (an `onUpdate` handler mutating state, or the
|
|
34
|
+
* optional timeout). The predicate is a non-serializable closure held in-process,
|
|
35
|
+
* never checkpointed. Once the wait outcome has been checkpointed, replay returns
|
|
36
|
+
* the cached outcome and does not re-invoke the predicate. A predicate that
|
|
37
|
+
* throws fails the workflow at the `yield*` call site (like a throwing activity).
|
|
38
|
+
* Inline execution only.
|
|
39
|
+
*
|
|
40
|
+
* With no `timeout` the generator yields `void` (waits forever). With a `timeout`
|
|
41
|
+
* it yields `true` when the predicate was met or `false` when the deadline
|
|
42
|
+
* elapsed first.
|
|
43
|
+
*/
|
|
44
|
+
export declare function waitUntil(context: Context, internals: ContextInternals, predicate: () => boolean, timeout?: Duration): Generator<ContextOperationRequest, boolean | void, unknown>;
|
|
45
|
+
export declare function getVersion(_context: Context, internals: ContextInternals, changeId: string, minSupported: number, maxSupported: number): Generator<ContextOperationRequest, number, unknown>;
|
|
21
46
|
export declare function waitForUpdate<T = unknown>(context: Context, internals: ContextInternals, name: string): Generator<ContextOperationRequest, {
|
|
22
47
|
payload: T;
|
|
23
48
|
respond: (result: unknown) => void;
|