@lostgradient/weft 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -43
- package/dist/cli/conformance.js +7 -1
- package/dist/cli/generated/operation-client.generated.d.ts +55 -13
- package/dist/cli/generated/operation-client.generated.js +3 -0
- package/dist/cli/help-text.d.ts +1 -1
- package/dist/cli/help-text.js +1 -0
- package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
- package/dist/cli/operation-catalog-snapshot.js +11 -0
- package/dist/cli/parse-schedule-arguments.js +3 -1
- package/dist/cli/schedule.js +2 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli-main.js +80 -79
- package/dist/client/handle-delegation.d.ts +7 -2
- package/dist/client/handle-delegation.js +9 -1
- package/dist/client/http-client-requests.d.ts +4 -1
- package/dist/client/http-client-requests.js +10 -0
- package/dist/client/http-client.d.ts +10 -4
- package/dist/client/http-client.js +18 -1
- package/dist/client/http-request.d.ts +11 -1
- package/dist/client/http-request.js +17 -7
- package/dist/client/index.d.ts +1 -1
- package/dist/client/interface.d.ts +100 -4
- package/dist/client/local.d.ts +7 -1
- package/dist/client/local.js +17 -2
- package/dist/client/start-body.d.ts +9 -2
- package/dist/client/start-body.js +13 -4
- package/dist/core/byte-arrays.d.ts +5 -0
- package/dist/core/byte-arrays.js +5 -0
- package/dist/core/checkpoint/lifecycle.d.ts +3 -0
- package/dist/core/checkpoint/lifecycle.js +9 -4
- package/dist/core/checkpoint/serialization.js +12 -5
- package/dist/core/codec/extension-codec.d.ts +16 -0
- package/dist/core/codec/extension-codec.js +104 -8
- package/dist/core/codec/index.d.ts +1 -0
- package/dist/core/codec/index.js +1 -0
- package/dist/core/codec/serializer-registry.d.ts +122 -0
- package/dist/core/codec/serializer-registry.js +51 -0
- package/dist/core/context/activity-retry-state.d.ts +38 -0
- package/dist/core/context/activity-retry-state.js +89 -0
- package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
- package/dist/core/context/activity-schedule-to-close.js +69 -0
- package/dist/core/context/child-workflow-pipe.d.ts +5 -5
- package/dist/core/context/child-workflow-pipe.js +15 -2
- package/dist/core/context/context-presence.d.ts +19 -0
- package/dist/core/context/context-presence.js +13 -0
- package/dist/core/context/durable-operations.d.ts +25 -0
- package/dist/core/context/durable-operations.js +64 -0
- package/dist/core/context/index.d.ts +18 -5
- package/dist/core/context/index.js +17 -12
- package/dist/core/context/internals.d.ts +29 -0
- package/dist/core/context/internals.js +6 -1
- package/dist/core/context/operation-request.d.ts +35 -0
- package/dist/core/context/parallel-cache-entry.d.ts +14 -5
- package/dist/core/context/run-operation.d.ts +21 -3
- package/dist/core/context/run-operation.js +56 -93
- package/dist/core/context/session-state.js +7 -8
- package/dist/core/context/speculative-child.js +2 -0
- package/dist/core/context/types.d.ts +15 -0
- package/dist/core/context/version-patching.d.ts +8 -0
- package/dist/core/context/version-patching.js +40 -0
- package/dist/core/context/workflow-logger.d.ts +98 -0
- package/dist/core/context/workflow-logger.js +68 -0
- package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
- package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
- package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
- package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +12 -1
- package/dist/core/engine/activity-resolution.d.ts +23 -0
- package/dist/core/engine/activity-resolution.js +37 -0
- package/dist/core/engine/aggregate.js +66 -30
- package/dist/core/engine/async-activity-completion.d.ts +23 -6
- package/dist/core/engine/async-activity-completion.js +53 -12
- package/dist/core/engine/attributes-tags.js +9 -4
- package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
- package/dist/core/engine/bulk-operations-purge.js +38 -3
- package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
- package/dist/core/engine/bulk-operations-shared.js +8 -2
- package/dist/core/engine/bulk-operations.d.ts +4 -1
- package/dist/core/engine/bulk-operations.js +235 -24
- package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
- package/dist/core/engine/callback-creators-bundles.js +30 -2
- package/dist/core/engine/callback-creators-core.js +6 -4
- package/dist/core/engine/callback-creators-router.js +10 -0
- package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
- package/dist/core/engine/callback-creators-schedule.js +12 -8
- package/dist/core/engine/candidate-read-batching.d.ts +6 -0
- package/dist/core/engine/candidate-read-batching.js +1 -0
- package/dist/core/engine/checkpoint-io.js +61 -25
- package/dist/core/engine/checkpoint-reads.js +3 -2
- package/dist/core/engine/checkpoint-replay.d.ts +20 -0
- package/dist/core/engine/checkpoint-replay.js +242 -0
- package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
- package/dist/core/engine/checkpoint-side-effects.js +35 -0
- package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
- package/dist/core/engine/child-workflow-cancellation.js +40 -0
- package/dist/core/engine/child-workflow.js +27 -4
- package/dist/core/engine/condition-waiters.d.ts +14 -0
- package/dist/core/engine/condition-waiters.js +5 -0
- package/dist/core/engine/construction.d.ts +3 -1
- package/dist/core/engine/construction.js +30 -8
- package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
- package/dist/core/engine/coordination-branch-executors.js +107 -0
- package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
- package/dist/core/engine/deferred-consume-envelope.js +14 -0
- package/dist/core/engine/disposal.js +25 -0
- package/dist/core/engine/engine-create-types.d.ts +14 -18
- package/dist/core/engine/engine-internal-types.d.ts +38 -3
- package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
- package/dist/core/engine/engine-leak-warnings.js +4 -0
- package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
- package/dist/core/engine/engine-runtime-helpers.js +26 -5
- package/dist/core/engine/errors.d.ts +121 -0
- package/dist/core/engine/errors.js +45 -1
- package/dist/core/engine/event-log-compaction.d.ts +8 -0
- package/dist/core/engine/event-log-compaction.js +20 -2
- package/dist/core/engine/fenced-write.d.ts +65 -0
- package/dist/core/engine/fenced-write.js +71 -0
- package/dist/core/engine/finalizer-state.d.ts +28 -0
- package/dist/core/engine/finalizer-state.js +16 -0
- package/dist/core/engine/handle-result.js +1 -1
- package/dist/core/engine/handles.d.ts +97 -40
- package/dist/core/engine/handles.js +25 -27
- package/dist/core/engine/index.d.ts +125 -15
- package/dist/core/engine/index.js +207 -11
- package/dist/core/engine/inline-launch-queue.d.ts +14 -0
- package/dist/core/engine/inline-launch-queue.js +32 -7
- package/dist/core/engine/inline-parking.js +3 -2
- package/dist/core/engine/internals.d.ts +125 -13
- package/dist/core/engine/lease-codec.d.ts +35 -0
- package/dist/core/engine/lease-codec.js +32 -0
- package/dist/core/engine/lease-deposition.d.ts +66 -0
- package/dist/core/engine/lease-deposition.js +10 -0
- package/dist/core/engine/lease-errors.d.ts +99 -0
- package/dist/core/engine/lease-errors.js +30 -0
- package/dist/core/engine/lease-manager.d.ts +114 -0
- package/dist/core/engine/lease-manager.js +135 -0
- package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
- package/dist/core/engine/lifecycle/persist.js +15 -52
- package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
- package/dist/core/engine/lifecycle/recovered-services.js +18 -3
- package/dist/core/engine/lifecycle/resume.js +39 -11
- package/dist/core/engine/lifecycle/shared.d.ts +8 -1
- package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
- package/dist/core/engine/lifecycle/start-batch.js +2 -1
- package/dist/core/engine/lifecycle/start-commit.d.ts +56 -0
- package/dist/core/engine/lifecycle/start-commit.js +69 -0
- package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
- package/dist/core/engine/lifecycle/start-exec.js +38 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
- package/dist/core/engine/lifecycle/start-or-signal.d.ts +46 -0
- package/dist/core/engine/lifecycle/start-or-signal.js +71 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
- package/dist/core/engine/lifecycle/start.d.ts +6 -6
- package/dist/core/engine/lifecycle/start.js +47 -45
- package/dist/core/engine/lifecycle/transition.js +17 -5
- package/dist/core/engine/lifecycle.d.ts +3 -2
- package/dist/core/engine/lifecycle.js +9 -2
- package/dist/core/engine/list-candidate-resolution.js +2 -2
- package/dist/core/engine/listing.js +10 -6
- package/dist/core/engine/operations-activity.d.ts +4 -11
- package/dist/core/engine/operations-activity.js +22 -49
- package/dist/core/engine/operations-coordination.d.ts +10 -0
- package/dist/core/engine/operations-coordination.js +43 -8
- package/dist/core/engine/operations-router.d.ts +6 -0
- package/dist/core/engine/operations-router.js +2 -0
- package/dist/core/engine/operations-speculate.js +6 -2
- package/dist/core/engine/operations-stream.js +12 -2
- package/dist/core/engine/operations-time.d.ts +4 -2
- package/dist/core/engine/operations-time.js +14 -2
- package/dist/core/engine/operations-wait-condition.d.ts +23 -0
- package/dist/core/engine/operations-wait-condition.js +62 -0
- package/dist/core/engine/ownership-options.d.ts +23 -0
- package/dist/core/engine/ownership-options.js +26 -0
- package/dist/core/engine/payload-size-policy.d.ts +3 -0
- package/dist/core/engine/payload-size-policy.js +4 -0
- package/dist/core/engine/pending-updates.d.ts +17 -0
- package/dist/core/engine/pending-updates.js +33 -11
- package/dist/core/engine/persisted-data-version.d.ts +5 -9
- package/dist/core/engine/persisted-data-version.js +4 -5
- package/dist/core/engine/queries.js +1 -1
- package/dist/core/engine/registration.d.ts +1 -0
- package/dist/core/engine/registration.js +18 -3
- package/dist/core/engine/schedule-handle.d.ts +45 -0
- package/dist/core/engine/schedule-handle.js +26 -0
- package/dist/core/engine/schedule-jitter.d.ts +5 -0
- package/dist/core/engine/schedule-jitter.js +10 -0
- package/dist/core/engine/schedule-run.d.ts +17 -0
- package/dist/core/engine/schedule-run.js +38 -0
- package/dist/core/engine/schedule-timer.js +81 -17
- package/dist/core/engine/schedules.d.ts +8 -5
- package/dist/core/engine/schedules.js +44 -19
- package/dist/core/engine/search-attribute-records.d.ts +4 -0
- package/dist/core/engine/search-attribute-records.js +17 -0
- package/dist/core/engine/second-instance-detector.d.ts +96 -0
- package/dist/core/engine/second-instance-detector.js +108 -0
- package/dist/core/engine/signals.d.ts +38 -0
- package/dist/core/engine/signals.js +55 -19
- package/dist/core/engine/state-utilities.d.ts +49 -2
- package/dist/core/engine/state-utilities.js +114 -3
- package/dist/core/engine/storage-io.d.ts +16 -2
- package/dist/core/engine/storage-io.js +26 -5
- package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
- package/dist/core/engine/stream-chunk-loading.js +24 -1
- package/dist/core/engine/sub-operation.js +22 -3
- package/dist/core/engine/termination/cleanup.d.ts +28 -1
- package/dist/core/engine/termination/cleanup.js +44 -2
- package/dist/core/engine/termination/complete.js +48 -9
- package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
- package/dist/core/engine/termination/finalizer-activity.js +30 -0
- package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
- package/dist/core/engine/termination/finalizer-claim.js +80 -0
- package/dist/core/engine/termination/finalizer.d.ts +48 -0
- package/dist/core/engine/termination/finalizer.js +159 -0
- package/dist/core/engine/termination/suspend.d.ts +70 -0
- package/dist/core/engine/termination/suspend.js +41 -0
- package/dist/core/engine/termination.d.ts +5 -2
- package/dist/core/engine/termination.js +6 -0
- package/dist/core/engine/updates.js +5 -25
- package/dist/core/engine/validation/schedule.d.ts +2 -1
- package/dist/core/engine/validation/schedule.js +51 -2
- package/dist/core/engine/validation.js +54 -3
- package/dist/core/engine/waiting-update-response.d.ts +8 -0
- package/dist/core/engine/waiting-update-response.js +22 -0
- package/dist/core/engine/workflow-concurrency.d.ts +10 -0
- package/dist/core/engine/workflow-concurrency.js +136 -0
- package/dist/core/engine/workflow-feed.d.ts +9 -8
- package/dist/core/engine/workflow-feed.js +4 -1
- package/dist/core/engine/workflow-indexes.d.ts +9 -0
- package/dist/core/engine/workflow-indexes.js +10 -0
- package/dist/core/engine/workflow-state-stream.js +33 -13
- package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
- package/dist/core/engine-helpers.js +1 -0
- package/dist/core/events/activity-events.d.ts +43 -12
- package/dist/core/events/activity-events.js +28 -0
- package/dist/core/events/attribute-events.d.ts +2 -3
- package/dist/core/events/event-map.d.ts +19 -12
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -0
- package/dist/core/events/schedule-events.d.ts +71 -0
- package/dist/core/events/schedule-events.js +29 -0
- package/dist/core/events/signal-events.d.ts +4 -6
- package/dist/core/events/system-events.d.ts +29 -19
- package/dist/core/events/system-events.js +26 -0
- package/dist/core/events/update-events.d.ts +6 -8
- package/dist/core/events/workflow-events.d.ts +108 -20
- package/dist/core/events/workflow-events.js +35 -0
- package/dist/core/failure-categories.js +5 -17
- package/dist/core/fault-code.d.ts +9 -3
- package/dist/core/fault-code.js +1 -0
- package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
- package/dist/core/inline-execution-strategy.context-options.js +56 -0
- package/dist/core/inline-execution-strategy.d.ts +31 -36
- package/dist/core/inline-execution-strategy.js +16 -27
- package/dist/core/list-filter-validation.d.ts +1 -1
- package/dist/core/list-filter-validation.js +2 -1
- package/dist/core/payload-size.d.ts +1 -1
- package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
- package/dist/core/review/events.d.ts +6 -8
- package/dist/core/scheduler/scheduler-class.d.ts +10 -1
- package/dist/core/scheduler/scheduler-class.js +38 -11
- package/dist/core/scheduler/timer-batch.js +9 -1
- package/dist/core/scheduler/timer-sources.d.ts +1 -0
- package/dist/core/scheduler/timer-sources.js +11 -5
- package/dist/core/session-state.d.ts +0 -1
- package/dist/core/session-state.js +2 -2
- package/dist/core/start-workflow-validation.d.ts +56 -0
- package/dist/core/start-workflow-validation.js +30 -1
- package/dist/core/step-context.d.ts +10 -6
- package/dist/core/step-context.js +7 -15
- package/dist/core/types/activity-verification.d.ts +67 -0
- package/dist/core/types/activity-verification.js +0 -0
- package/dist/core/types/activity.d.ts +86 -64
- package/dist/core/types/bulk.d.ts +50 -9
- package/dist/core/types/checkpoint.d.ts +44 -8
- package/dist/core/types/identity.d.ts +8 -1
- package/dist/core/types/launch-metadata.d.ts +33 -0
- package/dist/core/types/launch-metadata.js +0 -0
- package/dist/core/types/list-options.d.ts +146 -0
- package/dist/core/types/list-options.js +0 -0
- package/dist/core/types/message-handles.d.ts +25 -0
- package/dist/core/types/options.d.ts +165 -215
- package/dist/core/types/reviews.d.ts +2 -1
- package/dist/core/types/schedules.d.ts +39 -3
- package/dist/core/types/services-resolution.d.ts +47 -0
- package/dist/core/types/services-resolution.js +0 -0
- package/dist/core/types/state.d.ts +11 -11
- package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
- package/dist/core/types/workflow-builder-runtime.js +11 -2
- package/dist/core/types/workflow-builder.d.ts +47 -15
- package/dist/core/types/workflow-concurrency.d.ts +39 -0
- package/dist/core/types/workflow-concurrency.js +0 -0
- package/dist/core/types/workflow-context.d.ts +157 -14
- package/dist/core/types/workflow-definition.d.ts +53 -10
- package/dist/core/types/workflow-function.d.ts +101 -9
- package/dist/core/types/workflow-log.d.ts +98 -0
- package/dist/core/types/workflow-log.js +0 -0
- package/dist/core/types/workflow-registries.d.ts +14 -3
- package/dist/core/types/workflow-registry.d.ts +3 -0
- package/dist/core/types/workflow-snapshot.d.ts +29 -0
- package/dist/core/types/workflow-snapshot.js +0 -0
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.js +7 -0
- package/dist/core/versioning.d.ts +9 -39
- package/dist/core/versioning.js +2 -12
- package/dist/core/weft-error.d.ts +44 -1
- package/dist/core/weft-error.js +19 -1
- package/dist/core/worker-execution-strategy-options.d.ts +26 -0
- package/dist/core/worker-execution-strategy.js +40 -36
- package/dist/core/worker-inbound-message.d.ts +38 -0
- package/dist/core/worker-inbound-message.js +37 -0
- package/dist/core/worker-log-abuse-counter.d.ts +175 -0
- package/dist/core/worker-log-abuse-counter.js +107 -0
- package/dist/core/worker-message-helpers.d.ts +47 -0
- package/dist/core/worker-message-helpers.js +26 -0
- package/dist/core/worker-protocol-guard.js +1 -1
- package/dist/core/worker-protocol-log.d.ts +56 -0
- package/dist/core/worker-protocol-log.js +18 -0
- package/dist/core/worker-protocol.d.ts +23 -0
- package/dist/core/worker-protocol.js +12 -2
- package/dist/core/workflow-version-tuple.d.ts +3 -9
- package/dist/core/workflow-version-tuple.js +2 -3
- package/dist/diagnostics/doctor.js +6 -3
- package/dist/diagnostics/format.js +3 -8
- package/dist/diagnostics/types.d.ts +5 -5
- package/dist/diagnostics/validate.d.ts +0 -1
- package/dist/diagnostics/version-check.d.ts +1 -1
- package/dist/diagnostics/version-check.js +10 -13
- package/dist/index.d.ts +13 -11
- package/dist/index.js +39 -4
- package/dist/json-schema.js +3 -3
- package/dist/mcp/cli.js +35 -35
- package/dist/mcp/dispatcher.js +1 -1
- package/dist/mcp/http.js +16 -6
- package/dist/mcp/list-filter.js +2 -1
- package/dist/mcp/protocol.d.ts +2 -0
- package/dist/mcp/protocol.js +1 -1
- package/dist/mcp/session.d.ts +16 -0
- package/dist/mcp/session.js +60 -6
- package/dist/mcp/tools.js +73 -6
- package/dist/observability/index.js +2 -2
- package/dist/server/asyncapi-channels.js +5 -2
- package/dist/server/attribute-filters.d.ts +8 -3
- package/dist/server/attribute-filters.js +6 -1
- package/dist/server/authentication/api-key.d.ts +2 -1
- package/dist/server/authentication/api-key.js +5 -2
- package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
- package/dist/server/authentication/constant-time-api-key.js +24 -0
- package/dist/server/authentication/index.d.ts +1 -1
- package/dist/server/authentication/index.js +7 -4
- package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
- package/dist/server/authentication/rotating-api-key-store.js +19 -11
- package/dist/server/engine-event-feed-backend.d.ts +4 -5
- package/dist/server/fault-to-http.js +8 -1
- package/dist/server/fault-to-json-rpc.js +1 -0
- package/dist/server/fleet-event-feed.d.ts +31 -0
- package/dist/server/fleet-event-feed.js +157 -0
- package/dist/server/handler/index.js +1 -1
- package/dist/server/handler/response-helpers.js +2 -1
- package/dist/server/handler/route-dispatch.d.ts +6 -3
- package/dist/server/handler/route-dispatch.js +2 -2
- package/dist/server/handler.js +31 -31
- package/dist/server/index.d.ts +32 -2
- package/dist/server/index.js +35 -35
- package/dist/server/interactive-operations.js +1 -0
- package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
- package/dist/server/json-rpc-transport-helpers.js +2 -1
- package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
- package/dist/server/json-rpc-websocket-runtime.js +1 -0
- package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
- package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
- package/dist/server/json-rpc-websocket-types.d.ts +22 -0
- package/dist/server/json-rpc-websocket-types.js +0 -0
- package/dist/server/json-rpc-websocket-validation.js +20 -4
- package/dist/server/json-rpc-websocket.d.ts +2 -43
- package/dist/server/json-rpc-websocket.js +57 -74
- package/dist/server/openapi.d.ts +2 -1
- package/dist/server/openapi.js +1 -3
- package/dist/server/openrpc-document-schema.d.ts +78 -0
- package/dist/server/openrpc-document-schema.js +27 -1
- package/dist/server/openrpc-errors.d.ts +3 -0
- package/dist/server/openrpc-errors.js +2 -1
- package/dist/server/openrpc.js +32 -0
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
- package/dist/server/operation-catalog/pipeline-stages.js +26 -12
- package/dist/server/operation-catalog/pipeline.js +8 -1
- package/dist/server/operation-catalog/registry.js +13 -0
- package/dist/server/operation-catalog/types.d.ts +20 -9
- package/dist/server/operation-fault.d.ts +10 -0
- package/dist/server/operation-fault.js +2 -0
- package/dist/server/operation-registry.d.ts +12 -11
- package/dist/server/operation-registry.js +12 -3
- package/dist/server/operations/aggregate-workflows.d.ts +15 -15
- package/dist/server/operations/async-activity.d.ts +2 -2
- package/dist/server/operations/async-activity.js +12 -7
- package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-cancel-workflows.js +2 -2
- package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-delete-workflows.js +2 -2
- package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
- package/dist/server/operations/bulk-filter-helpers.js +54 -24
- package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
- package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
- package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
- package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
- package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
- package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
- package/dist/server/operations/bulk-signal-workflows.js +2 -2
- package/dist/server/operations/cancel-schedule.d.ts +1 -1
- package/dist/server/operations/create-schedule.d.ts +3 -1
- package/dist/server/operations/create-schedule.js +29 -11
- package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
- package/dist/server/operations/fleet-events-subscription.js +99 -0
- package/dist/server/operations/fork-workflow.d.ts +1 -1
- package/dist/server/operations/fork-workflow.js +3 -2
- package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
- package/dist/server/operations/get-registry.d.ts +1 -1
- package/dist/server/operations/get-retention-overview.d.ts +1 -1
- package/dist/server/operations/get-review.d.ts +1 -1
- package/dist/server/operations/get-schedule.d.ts +1 -1
- package/dist/server/operations/get-stream-chunks.d.ts +1 -1
- package/dist/server/operations/get-system-metrics.d.ts +2 -2
- package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
- package/dist/server/operations/get-task-diagnostics.js +101 -7
- package/dist/server/operations/get-update-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/get-workflow-events.d.ts +1 -1
- package/dist/server/operations/get-workflow-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
- package/dist/server/operations/get-workflow.d.ts +1 -1
- package/dist/server/operations/list-checkpoints.d.ts +1 -1
- package/dist/server/operations/list-reviews.d.ts +1 -1
- package/dist/server/operations/list-schedules.d.ts +1 -1
- package/dist/server/operations/list-task-queues.d.ts +2 -2
- package/dist/server/operations/list-workers.d.ts +2 -2
- package/dist/server/operations/list-workflows.d.ts +1 -1
- package/dist/server/operations/operation-helpers.d.ts +16 -1
- package/dist/server/operations/operation-helpers.js +15 -3
- package/dist/server/operations/pause-schedule.d.ts +1 -1
- package/dist/server/operations/purge-workflows.d.ts +5 -5
- package/dist/server/operations/purge-workflows.js +2 -2
- package/dist/server/operations/query-workflow.d.ts +1 -1
- package/dist/server/operations/query-workflow.js +3 -2
- package/dist/server/operations/recover-all.d.ts +1 -1
- package/dist/server/operations/replay-workflow.d.ts +1 -1
- package/dist/server/operations/resume-schedule.d.ts +1 -1
- package/dist/server/operations/resume-workflow.js +2 -2
- package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/set-workflow-attributes.js +6 -3
- package/dist/server/operations/signal-workflow.js +8 -3
- package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
- package/dist/server/operations/start-or-signal-workflow.d.ts +44 -0
- package/dist/server/operations/start-or-signal-workflow.js +130 -0
- package/dist/server/operations/start-workflow-options.d.ts +38 -0
- package/dist/server/operations/start-workflow-options.js +63 -0
- package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
- package/dist/server/operations/start-workflow-rest-input.js +31 -0
- package/dist/server/operations/start-workflow.d.ts +1 -1
- package/dist/server/operations/start-workflow.js +15 -92
- package/dist/server/operations/storage.d.ts +6 -6
- package/dist/server/operations/storage.js +24 -14
- package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.js +6 -3
- package/dist/server/operations/suspend-workflow.d.ts +13 -0
- package/dist/server/operations/suspend-workflow.js +36 -0
- package/dist/server/operations/update-schedule.d.ts +1 -1
- package/dist/server/operations/update-schedule.js +7 -4
- package/dist/server/operations/update-workflow.d.ts +1 -1
- package/dist/server/operations/update-workflow.js +7 -3
- package/dist/server/operations/worker-drain.d.ts +8 -8
- package/dist/server/operations/worker-drain.js +11 -8
- package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
- package/dist/server/operations/workflow-events-subscription.js +43 -8
- package/dist/server/rest-binding.d.ts +21 -8
- package/dist/server/rest-bindings.js +24 -0
- package/dist/server/rest-body.d.ts +10 -0
- package/dist/server/rest-body.js +80 -0
- package/dist/server/runtime/authentication-bridge.d.ts +1 -0
- package/dist/server/runtime/authentication-bridge.js +33 -6
- package/dist/server/runtime/client-visible-events.d.ts +3 -0
- package/dist/server/runtime/client-visible-events.js +65 -0
- package/dist/server/runtime/context.d.ts +7 -0
- package/dist/server/runtime/event-broadcasting.d.ts +6 -0
- package/dist/server/runtime/event-broadcasting.js +72 -38
- package/dist/server/runtime/retry.d.ts +1 -0
- package/dist/server/runtime/retry.js +14 -0
- package/dist/server/runtime/shutdown.d.ts +7 -6
- package/dist/server/runtime/shutdown.js +6 -1
- package/dist/server/runtime/task-dispatch.js +5 -3
- package/dist/server/runtime/task-polling.d.ts +16 -2
- package/dist/server/runtime/task-polling.js +80 -24
- package/dist/server/runtime/task-reconciliation.js +9 -1
- package/dist/server/runtime/task-result-resolution.d.ts +15 -0
- package/dist/server/runtime/task-result-resolution.js +81 -0
- package/dist/server/runtime/websocket-stream.d.ts +20 -1
- package/dist/server/runtime/websocket-stream.js +173 -7
- package/dist/server/runtime/websocket-upgrade.js +22 -3
- package/dist/server/runtime/websocket-worker.d.ts +1 -1
- package/dist/server/runtime/websocket-worker.js +46 -30
- package/dist/server/serve-internals.d.ts +11 -1
- package/dist/server/serve-internals.js +20 -2
- package/dist/server/task-state.d.ts +38 -0
- package/dist/server/task-state.js +28 -0
- package/dist/server/workflow-event-feed.d.ts +36 -115
- package/dist/server/workflow-event-feed.js +92 -27
- package/dist/service-worker/index.js +31 -31
- package/dist/storage/auto.js +1 -1
- package/dist/storage/bun-sql.js +24 -0
- package/dist/storage/capabilities.d.ts +10 -2
- package/dist/storage/capabilities.js +2 -2
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/default-scope.d.ts +7 -4
- package/dist/storage/http.js +2 -2
- package/dist/storage/index.d.ts +81 -4
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/interface.d.ts +189 -0
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +12 -0
- package/dist/storage/lmdb.d.ts +4 -3
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon-batch.d.ts +30 -0
- package/dist/storage/neon-batch.js +30 -0
- package/dist/storage/neon-value-mapping.d.ts +74 -0
- package/dist/storage/neon-value-mapping.js +23 -0
- package/dist/storage/neon.d.ts +124 -0
- package/dist/storage/neon.js +15 -0
- package/dist/storage/node-sqlite-loader.d.ts +71 -0
- package/dist/storage/node-sqlite-loader.js +41 -0
- package/dist/storage/node-sqlite.d.ts +1 -19
- package/dist/storage/node-sqlite.js +61 -32
- package/dist/storage/postgres-key-value-queries.d.ts +104 -0
- package/dist/storage/postgres-key-value-queries.js +101 -0
- package/dist/storage/resolve.d.ts +2 -165
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +209 -0
- package/dist/storage/storage-configuration.js +0 -0
- package/dist/storage/testing.d.ts +168 -0
- package/dist/storage/testing.js +2 -0
- package/dist/storage/text-value-store.d.ts +9 -9
- package/dist/storage/turso.d.ts +8 -0
- package/dist/storage/turso.js +2 -2
- package/dist/storage/typed-storage.js +1 -1
- package/dist/storage/web-extension.js +1 -1
- package/dist/testing/index.js +35 -35
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/index.js +9 -5
- package/dist/worker/long-poll.js +4 -0
- package/dist/worker/protocol-messages.d.ts +20 -0
- package/dist/worker/protocol-schemas.d.ts +32 -0
- package/dist/worker/protocol-schemas.js +8 -4
- package/dist/worker/protocol-task-result.d.ts +28 -0
- package/dist/worker/protocol-task-result.js +76 -0
- package/dist/worker/protocol.d.ts +4 -15
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/registry/fair-share.d.ts +29 -0
- package/dist/worker/registry/fair-share.js +30 -0
- package/dist/worker/registry/routing.d.ts +18 -0
- package/dist/worker/registry/routing.js +14 -0
- package/dist/worker/registry/types.d.ts +7 -0
- package/dist/worker/registry.d.ts +16 -1
- package/dist/worker/registry.js +24 -36
- package/dist/workers/worker-replay-state.d.ts +32 -0
- package/dist/workers/worker-replay-state.js +35 -0
- package/dist/workers/worker-state-namespace.d.ts +21 -0
- package/dist/workers/worker-state-namespace.js +13 -0
- package/dist/workers/workflow-runner.d.ts +19 -15
- package/dist/workers/workflow-runner.js +72 -60
- package/dist/workers/workflow-worker-entry.js +5 -2
- package/package.json +21 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Weft
|
|
2
2
|
|
|
3
|
-
A Bun-native durable execution engine. Current
|
|
3
|
+
A Bun-native durable execution engine. Current release: `0.4.0`.
|
|
4
4
|
|
|
5
5
|
Install the library from npm as `@lostgradient/weft`:
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ The CLI binaries remain unscoped: package installs place `weft` and `weft-mcp` o
|
|
|
16
16
|
|
|
17
17
|
Imagine you're building an e-commerce checkout: charge the customer's credit card, reserve inventory, send a confirmation email, schedule shipping. What happens if your server crashes between step one and step two? The customer has been charged, but the inventory was never reserved. You can't just re-run the whole flow—you'd double-charge them.
|
|
18
18
|
|
|
19
|
-
**Durable execution** solves this. You write a normal-looking function
|
|
19
|
+
**Durable execution** solves this. You write a normal-looking function around durable boundaries; with durable storage, Weft checkpoints those boundaries and automatically resumes persisted work after a process restart. The exact guarantee, including the current activity crash-window limit, is spelled out in [Durability Guarantee](documentation/architecture/durability-guarantee.md).
|
|
20
20
|
|
|
21
21
|
Temporal is the most prominent durable execution engine, built in 2019 with Go, gRPC, and Cassandra. It works. But we can do better with modern tools.
|
|
22
22
|
|
|
@@ -43,12 +43,12 @@ Weft is a ground-up rethink: what would durable execution look like if you desig
|
|
|
43
43
|
|
|
44
44
|
## Stability Tiers
|
|
45
45
|
|
|
46
|
-
Weft is
|
|
46
|
+
Weft is still pre-1.0. The table below is the current adoption guidance, not a permanent compatibility guarantee. Surfaces marked **candidate-stable** are expected to carry the 1.0 support promise if the [Tier-0 Behavioral Contract](documentation/architecture/tier-0-behavioral-contract.md) does not force a public-shape change. Tier-0 work may still add error codes, duplicate-response shapes, or storage-capability failures before those surfaces graduate.
|
|
47
47
|
|
|
48
|
-
| Tier | Surfaces
|
|
49
|
-
| ----------------------------- |
|
|
50
|
-
| Candidate-stable, provisional | Engine core, [`TestEngine`](documentation/guides/testing.md), Bun SQLite, Node SQLite, LMDB, [`RemoteWorker`](documentation/guides/remote-workers.md), [`serve()`](documentation/guides/server.md) and `/v1` REST, exported public error codes
|
|
51
|
-
| Experimental | [Browser runtime](documentation/guides/service-worker.md), [MCP](documentation/reference/api-server.md#mcp-server), IndexedDB, WebExtension, HTTP and compressed storage, Turso pending conformance proof, CLI commands beyond `serve` and `
|
|
48
|
+
| Tier | Surfaces | What to expect |
|
|
49
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| Candidate-stable, provisional | Engine core, [`TestEngine`](documentation/guides/testing.md), Bun SQLite, Node SQLite, LMDB, [`RemoteWorker`](documentation/guides/remote-workers.md), [`serve()`](documentation/guides/server.md) and `/v1` REST, source/binary CLI commands `serve`, `doctor`, `version`, `--version`, and `-v`, exported public error codes | Suitable for serious trials. Pin the package version and read release notes before upgrading until the 1.0 contract lands. |
|
|
51
|
+
| Experimental | [Browser runtime](documentation/guides/service-worker.md), [MCP](documentation/reference/api-server.md#mcp-server), IndexedDB, WebExtension, HTTP and compressed storage, Turso pending conformance proof, CLI commands beyond `serve`, `doctor`, `version`, `--version`, and `-v` when running Weft from source or a standalone binary, [OpenTelemetry](documentation/guides/observability.md) metric names, externally supplied dashboard mounting, [`ctx.step()`](documentation/guides/workflows.md#getting-started-without-generators) sugar | API shape, storage guarantees, diagnostics, or compatibility behavior may change without a deprecation window before 1.0. |
|
|
52
52
|
|
|
53
53
|
If a surface is not named here, treat it as experimental. Stability is about compatibility and operational guarantees; it is not a statement that every candidate-stable surface is appropriate for every deployment.
|
|
54
54
|
|
|
@@ -56,6 +56,17 @@ The public path to 1.0 is tracked in the [roadmap to 1.0](documentation/roadmap-
|
|
|
56
56
|
|
|
57
57
|
The browser surfaces graduate on a specific, mechanical criterion: the IndexedDB and WebExtension adapters and the Service Worker runtime stay experimental until their real-browser smoke tests are green in a **required** CI gate. The [browser-surface promotion gate](documentation/roadmap-to-1.0.md#browser-surface-promotion-gate) documents how the `browser-smoke` CI job flips from non-blocking to required, and why real-browser coverage — not fake-IndexedDB or stubbed-`chrome.storage` unit tests — is the evidence that moves them to stable.
|
|
58
58
|
|
|
59
|
+
## Durability Guarantee
|
|
60
|
+
|
|
61
|
+
Weft's durability promise is checkpoint-level and explicit:
|
|
62
|
+
|
|
63
|
+
- Every `yield*` boundary is persisted before the workflow advances to the next durable step.
|
|
64
|
+
- `Engine.create()` recovers by default after registering workflow definitions, so fresh processes resume persisted running workflows without a separate boot hook.
|
|
65
|
+
- Recovery resumes from the last checkpoint position instead of replaying the workflow from the beginning.
|
|
66
|
+
- External activity side effects still need idempotency keys, provider lookup, or verifier logic. Without that, a crash after the external side effect but before Weft commits the activity result can dispatch the activity again.
|
|
67
|
+
|
|
68
|
+
The full [Durability Guarantee](documentation/architecture/durability-guarantee.md) separates what is guaranteed today from the Tier-0 activity-reconciliation work that narrows the remaining crash window.
|
|
69
|
+
|
|
59
70
|
## Hello, World
|
|
60
71
|
|
|
61
72
|
The smallest useful Weft program has four moving pieces: a storage backend, a named activity, a named workflow, and a handle that waits for the result.
|
|
@@ -92,8 +103,18 @@ That's the core loop: `workflow({ name })` is a **chained builder** that co-loca
|
|
|
92
103
|
|
|
93
104
|
`Engine.create()` does the registration dance for you: it constructs the engine and registers each workflow in the `workflows` map, pulling in all the activities each workflow declares. It then **recovers by default** — `engine.recoverAll()` runs after registration, so any workflows still running from a previous process pick up where they left off. That's the point of durable storage, so you don't have to ask for it. Pass `recover: false` to opt out (handy for tests, for `ScopedStorage`-isolated engines, or when you want to inspect a store before migrating it). Durability is separate: each step is persisted before it commits no matter what `recover` is set to — `recover` only decides whether _this_ engine resumes that persisted work on boot. Run a single engine per durable store; pointing two at the same store is not yet coordinated and can double-resume a workflow.
|
|
94
105
|
|
|
106
|
+
Passing an explicitly empty workflow map is the same default-registry boot shape as omitting `workflows`: `Engine.create({ workflows: {} })` recovers after registration and returns an engine whose TypeScript type is compatible with default-registry consumers such as `serve({ engine })`. Use a non-empty `workflows` map when you want TypeScript to narrow `engine.start(...)` to the registered names.
|
|
107
|
+
|
|
95
108
|
If you'd rather wire things up by hand — useful for tests, isolating engines onto separate storage scopes via `ScopedStorage`, or adding new workflows after the engine starts up — `new Engine({ storage })`, `engine.register(workflow)` or `engine.registerWorkflows({ ... })`, and `await engine.recoverAll()` are the underlying primitives. Each `engine.register(workflow)` call returns the engine with that workflow's name and types baked in, so `engine.start('welcome', ...)` autocompletes immediately.
|
|
96
109
|
|
|
110
|
+
When a workflow needs a live host capability that cannot be checkpointed, pass it as per-run `services`:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const handle = await engine.start('welcome', { name: 'Steve' }, { services: { crmClient } });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Inside inline workflows, read that value from `ctx.services` and narrow it to your application type. Weft never writes the service object into checkpoints; it persists only a presence marker so `Engine.create({ resolveWorkflowServices })` can rebuild the service value during fresh-process recovery before the generator advances. Do not use `services` for durable data, and do not pass it in Worker execution mode — non-serializable values cannot cross to a Worker.
|
|
117
|
+
|
|
97
118
|
> [!NOTE]
|
|
98
119
|
> The chained builder also accepts `.signals({...})`, `.updates({...})`, `.queries({...})`, and `.searchAttributes({...})`. Each can be called at most once before `.execute(fn)`; the type system flips a phantom flag so a duplicate call fails to typecheck, and the runtime mirrors the same invariant. These maps don't introduce new runtime gating — they're type hints that thread into `ctx.run()`, `ctx.waitForSignal()`, `ctx.waitForUpdate()`, and friends so your editor autocompletes and your code typechecks. The underlying dispatch paths are unchanged.
|
|
99
120
|
|
|
@@ -115,17 +136,20 @@ Because recovery never re-executes the workflow from the beginning, your workflo
|
|
|
115
136
|
| **Checkpoint** | A serialized snapshot of a workflow's position and local variables, written at every yield. |
|
|
116
137
|
| **Signal** | A fire-and-forget message sent _into_ a running workflow. Workflows pause at `ctx.waitForSignal()` until one arrives. |
|
|
117
138
|
| **Update** | A request-response message sent into a running workflow. The caller blocks until the workflow returns a result. |
|
|
118
|
-
| **Query** | A read-only
|
|
139
|
+
| **Query** | A read-only request sent with `engine.query()` or `handle.query()` to inspect workflow state without mutating it. |
|
|
119
140
|
| **Search attribute** | Indexed metadata on a workflow (customer ID, region, status) set via `ctx.setAttribute()` and queryable through the list API. |
|
|
120
141
|
| **Worker** | A process or thread that executes activities. Inline by default; can run remote over WebSocket. |
|
|
121
142
|
| **Interceptor** | A composable hook that wraps context operations for tracing, validation, encryption, or any cross-cutting concern. |
|
|
122
143
|
| **Shared state** | A compare-and-swap (CAS) durable mutable primitive for safe concurrent reads and writes across workflows. |
|
|
144
|
+
| **Idempotent start** | A stable `idempotencyKey` that makes retried starts return the existing run instead of creating duplicates. |
|
|
123
145
|
|
|
124
146
|
## Features
|
|
125
147
|
|
|
126
148
|
### Durable Workflows
|
|
127
149
|
|
|
128
|
-
Generator functions with automatic checkpointing at every `yield*` boundary. Activities, sleeps, signals, queries, updates, parallel execution via `ctx.all()`, race semantics via `ctx.race()`, memoization via `ctx.memo()`, sagas via `ctx.saga()`, child workflows, and forks.
|
|
150
|
+
Generator functions with automatic checkpointing at every `yield*` boundary. Activities, sleeps, signals, condition gates with `ctx.waitUntil()`, queries, updates, structured logs with `ctx.log`, parallel execution via `ctx.all()`, race semantics via `ctx.race()`, memoization via `ctx.memo()`, sagas via `ctx.saga()`, child workflows, and forks. `ctx.all()` and `ctx.race()` can branch over activities, sleeps, and signal waits; use `ctx.race([ctx.waitForSignal(name), ctx.sleep(timeout)])` for signal timeouts instead of placing an unbounded signal wait directly in `ctx.all()`.
|
|
151
|
+
|
|
152
|
+
Every workflow context exposes `ctx.workflowId` and `ctx.workflowType`. `workflowType` is the registered name from `workflow({ name })`, so shared workflow code can log, tag, or branch on the current workflow type without closing over definition-site state.
|
|
129
153
|
|
|
130
154
|
```typescript
|
|
131
155
|
const checkout = workflow({ name: 'checkout' })
|
|
@@ -171,9 +195,28 @@ const handle = await engine.start('approval', { orderId: 'order-123' });
|
|
|
171
195
|
await engine.signal(handle.id, approvalSignal, { approved: true });
|
|
172
196
|
```
|
|
173
197
|
|
|
198
|
+
For state that changes through synchronous updates, use `ctx.waitUntil(predicate, timeout?)` as a durable condition gate. It re-checks a pure predicate when `ctx.onUpdate()` handlers mutate workflow-local state, or when the optional timeout fires. It is inline-only because the predicate closure stays in the engine process; signals do not re-drive it because signals are pull-based messages consumed by `ctx.waitForSignal()`.
|
|
199
|
+
|
|
200
|
+
```typescript partial
|
|
201
|
+
const quorum = workflow({ name: 'quorum' })
|
|
202
|
+
.updates({
|
|
203
|
+
vote: update<void, number>('vote'),
|
|
204
|
+
})
|
|
205
|
+
.execute(async function* (ctx) {
|
|
206
|
+
let votes = 0;
|
|
207
|
+
ctx.onUpdate('vote', () => {
|
|
208
|
+
votes += 1;
|
|
209
|
+
return votes;
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const reached = yield* ctx.waitUntil(() => votes >= 3, '1h');
|
|
213
|
+
return reached ? 'accepted' : 'expired';
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
174
217
|
### Live Workflow Events
|
|
175
218
|
|
|
176
|
-
Workflow handles expose lifecycle events through `addEventListener`, and client handles can open a live tail for progress UIs or operators. `LocalClient` reads from the in-process engine stream; `HttpClient` uses the per-workflow `/v1/workflows/:id/watch` WebSocket channel with history catch-up on connect and reconnect, so `addEventListener`, `client.tail(id)`, and `handle.tail()` are push-based rather than a polling loop.
|
|
219
|
+
Workflow handles expose lifecycle events through `addEventListener`, and client handles can open a live tail for progress UIs or operators. `LocalClient` reads from the in-process engine stream; `HttpClient` uses the per-workflow `/v1/workflows/:id/watch` WebSocket channel with history catch-up on connect and reconnect, so `addEventListener`, `client.tail(id)`, and `handle.tail()` are push-based rather than a polling loop. JSON-RPC clients can subscribe over WebSocket with `weft.workflows.subscribe` for one workflow or `weft.events.subscribe` for the fleet-wide event feed. Client code that receives a workflow id from another process can call `client.getHandle(id)` to re-attach a `ClientHandle` or get `null` when the run does not exist.
|
|
177
220
|
|
|
178
221
|
```typescript
|
|
179
222
|
const handle = await client.start('checkout', order);
|
|
@@ -188,6 +231,23 @@ for await (const event of tail) {
|
|
|
188
231
|
|
|
189
232
|
The tail is single-consumer and stops on terminal workflow events or `tail.close()`. In runtimes without a built-in WebSocket, or where authenticated WebSockets need headers the platform constructor cannot send, provide `HttpClientOptions.webSocketFactory`.
|
|
190
233
|
|
|
234
|
+
### Idempotent Starts and Signal-With-Start
|
|
235
|
+
|
|
236
|
+
Retried webhooks and queue deliveries should not double-start workflows. Pass a stable `idempotencyKey` to `engine.start()` to make every retry return a handle for the same run. Use `engine.startOrSignal()` when the first event should create the workflow and later events should signal the existing non-terminal run. The call returns `{ handle, outcome }`, where `outcome` is `'started'` for the caller that created the run and `'signalled'` for callers that delivered to, or converged onto, an existing run.
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const { handle, outcome } = await engine.startOrSignal(
|
|
240
|
+
'approval',
|
|
241
|
+
{ orderId: 'order-123' },
|
|
242
|
+
{ name: 'payment', payload: { status: 'succeeded' } },
|
|
243
|
+
{ idempotencyKey: 'payment-webhook-order-123' },
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
console.log(handle.id, outcome); // outcome is 'started' or 'signalled'
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The idempotency mapping intentionally outlives terminal cleanup. If retention removes the workflow record, the key is spent and future calls return a conflict instead of starting a replacement.
|
|
250
|
+
|
|
191
251
|
### Search Attributes
|
|
192
252
|
|
|
193
253
|
Attach indexed metadata to a workflow at runtime, then list and filter on it.
|
|
@@ -215,10 +275,14 @@ const orders = await engine.list({
|
|
|
215
275
|
|
|
216
276
|
Workflow visibility extends the same list surface with operator filters for `idPrefix`, failure categories, created/updated/deadline ranges, and status arrays. Use `engine.aggregate()` or `GET /api/v1/workflows/aggregate` for grouped counts by status, type, failure category, or a search attribute. Existing Bun SQLite deployments should run the [workflow visibility backfill](documentation/guides/workflow-visibility-backfill.md) before relying on the indexed fast path for older workflows.
|
|
217
277
|
|
|
278
|
+
Failure-category filters use the current execution taxonomy only: `application`, `timeout`, `cancellation`, `resource`, and `system`. Older category names from pre-1.0 experiments are dropped during decode and are not expanded in list or aggregate filters.
|
|
279
|
+
|
|
218
280
|
### Human-in-the-Loop Review
|
|
219
281
|
|
|
220
282
|
Weft can pause a workflow at any checkpoint and surface a decision payload to a human reviewer. The workflow resumes with the reviewer's decision—no polling, no special infrastructure.
|
|
221
283
|
|
|
284
|
+
As of June 12, 2026, [Temporal's public human-approval example](https://docs.temporal.io/ai-cookbook/human-in-the-loop-python) models approval with Signals, and [Inngest's TypeScript docs](https://www.inngest.com/docs/reference/typescript/v4/functions/step-wait-for-event) model approval waits with `step.waitForEvent()`. Weft makes the review itself a durable workflow operation: [`ctx.review()`](src/core/context/durable-operations.ts) creates a stored review request, exposes review list/get/decision APIs, emits review events, and resumes the workflow with the submitted decision.
|
|
285
|
+
|
|
222
286
|
```typescript
|
|
223
287
|
import { Engine, workflow } from '@lostgradient/weft';
|
|
224
288
|
import { SQLiteStorage } from '@lostgradient/weft/storage/sqlite';
|
|
@@ -256,7 +320,7 @@ const paymentWorkflow = workflow({ name: 'payment' })
|
|
|
256
320
|
});
|
|
257
321
|
```
|
|
258
322
|
|
|
259
|
-
If the process crashes
|
|
323
|
+
If the process crashes after the approval decision is checkpointed, the reviewer is not asked again. The `chargeCard` activity is still an at-least-once side effect: if the payment provider accepts the charge and the process crashes before Weft commits the activity result, recovery can run `chargeCard` again. Pass an idempotency key, provider transaction lookup, or equivalent verifier to the payment provider; the [activities guide](documentation/guides/activities.md#per-call-options) explains that boundary in more detail.
|
|
260
324
|
|
|
261
325
|
### Pluggable Storage
|
|
262
326
|
|
|
@@ -268,6 +332,7 @@ A small `Storage` interface over string keys and `Uint8Array` values: five requi
|
|
|
268
332
|
- **`NodeSQLiteStorage`** (subpath `@lostgradient/weft/storage/sqlite/node`) for an explicit Node.js SQLite override via `better-sqlite3`
|
|
269
333
|
- **`LMDBStorage`** (subpath `@lostgradient/weft/storage/lmdb`) for embedded high-throughput workloads
|
|
270
334
|
- **`TursoStorage`** (subpath `@lostgradient/weft/storage/turso`) for distributed libSQL deployments
|
|
335
|
+
- **`NeonStorage`** (subpath `@lostgradient/weft/storage/neon`) for durable remote Neon/Postgres deployments
|
|
271
336
|
- **`IndexedDBStorage`** (subpath `@lostgradient/weft/storage/indexeddb`) for browser environments
|
|
272
337
|
- **`WebExtensionStorage`** (subpath `@lostgradient/weft/storage/web-extension`) for extension contexts using `browser.storage` or `chrome.storage`
|
|
273
338
|
- **`HTTPStorage`** (subpath `@lostgradient/weft/storage/http`) for remote storage over Weft's HTTP storage routes
|
|
@@ -275,6 +340,8 @@ A small `Storage` interface over string keys and `Uint8Array` values: five requi
|
|
|
275
340
|
|
|
276
341
|
Bring your own backend by implementing the interface—five methods is enough.
|
|
277
342
|
|
|
343
|
+
Production recovery needs one engine process per durable store. Use a local durable adapter (`SQLiteStorage` or `LMDBStorage`) when the service owns its disk, or `NeonStorage` when the deployment wants managed Postgres durability and point-in-time restore. In either case, validate the store at boot with `assertDurableStorageForRecovery()` and enforce the singleton topology in infrastructure; the [singleton service deployment guide](documentation/guides/singleton-service-deployment.md) covers the checklist and the optional warn-only second-instance detector.
|
|
344
|
+
|
|
278
345
|
For long-running workflows, `history.retentionWindow` can compact old event-log records behind the latest checkpoint while preserving verification through a durable watermark. `history.maxEvents` remains a lifetime circuit breaker even after compaction. Use `payloadSize.maxBytes` when operators need an admission-time cap on workflow inputs, signal payloads, and activity results before those values reach storage.
|
|
279
346
|
|
|
280
347
|
### Server Mode
|
|
@@ -293,7 +360,7 @@ await using server = serve({ engine, port: 7233 });
|
|
|
293
360
|
// server.url is e.g. "http://0.0.0.0:7233"
|
|
294
361
|
```
|
|
295
362
|
|
|
296
|
-
Endpoints under `/api/v1/` cover the full lifecycle: start workflows, list, signal, update, query, cancel, fork, and stream events. Content negotiation supports JSON and MessagePack. The server can also mount an externally supplied dashboard shell at known page routes; see the [server guide](documentation/guides/server.md#external-dashboard-mounting) for the hosting contract.
|
|
363
|
+
Endpoints under `/api/v1/` cover the full lifecycle: start workflows, list, signal, update, query, cancel, fork, and stream events. JSON-RPC over WebSocket also exposes workflow and fleet event subscriptions for operator UIs that need live state without polling. Content negotiation supports JSON and MessagePack. The server can also mount an externally supplied dashboard shell at known page routes; see the [server guide](documentation/guides/server.md#external-dashboard-mounting) for the hosting contract.
|
|
297
364
|
|
|
298
365
|
### Remote Workers
|
|
299
366
|
|
|
@@ -323,6 +390,8 @@ The core engine runs inside a Web Worker, with a Service Worker acting as the du
|
|
|
323
390
|
|
|
324
391
|
Built-in event system (`EventTarget`-based, so it composes with everything), W3C `traceparent` propagation, and OpenTelemetry-compatible metrics. Composable interceptors layer cross-cutting concerns—tracing, validation, encryption—without any of them knowing about each other.
|
|
325
392
|
|
|
393
|
+
Schedules also emit `schedule:fired` on the live engine each time a schedule actually launches a workflow run. The event carries `scheduleId`, `workflowId`, `firedAt`, and the scheduled `occurrence` when one is retained, so in-process dispatchers can react to cadence without polling schedule state.
|
|
394
|
+
|
|
326
395
|
```typescript
|
|
327
396
|
import { createObservabilityInterceptors, createOpenTelemetryMetrics } from '@lostgradient/weft';
|
|
328
397
|
|
|
@@ -337,6 +406,8 @@ const engine = new Engine({
|
|
|
337
406
|
});
|
|
338
407
|
```
|
|
339
408
|
|
|
409
|
+
Inside workflow code, `ctx.log` emits structured console records with `workflowId`, `workflowType`, `level`, and `timestamp` attached. Caller attributes are nested under `attributes`, so they cannot overwrite the envelope. Logs at already-restored checkpoint positions are suppressed on recovery; logs at the live frontier still emit, and in worker mode the destination is the worker process console.
|
|
410
|
+
|
|
340
411
|
### Testing
|
|
341
412
|
|
|
342
413
|
`TestEngine` swaps the production engine in tests and gives you a virtual clock. `engine.advanceTime('1 hour')` jumps timers forward without waiting; `engine.mock(activity, fake)` swaps in fake activity implementations with type-checked signatures, call recording, and per-call overrides.
|
|
@@ -372,39 +443,46 @@ For chaos testing, `withChaos()` wraps activities with configurable transient fa
|
|
|
372
443
|
Every error Weft throws extends `WeftError`, so a single `instanceof` check catches them all, and each carries a stable string `code` equal to its class name:
|
|
373
444
|
|
|
374
445
|
```typescript
|
|
375
|
-
import { isWeftError
|
|
446
|
+
import { isWeftError } from '@lostgradient/weft';
|
|
376
447
|
|
|
377
448
|
try {
|
|
378
449
|
await engine.start('checkout', { orderId: 'order-1' }, { id: 'order-1' });
|
|
379
450
|
} catch (error) {
|
|
380
451
|
if (!isWeftError(error)) throw error; // not ours — rethrow
|
|
381
452
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
console.error(`[${error.code}] ${error.message}`);
|
|
391
|
-
}
|
|
453
|
+
switch (error.code) {
|
|
454
|
+
case 'WorkflowAlreadyExistsError':
|
|
455
|
+
// idempotent retry — already running
|
|
456
|
+
break;
|
|
457
|
+
case 'WorkflowNotRegisteredError':
|
|
458
|
+
throw error; // a programming error, not a runtime condition
|
|
459
|
+
default:
|
|
460
|
+
console.error(`[${error.code}] ${error.message}`);
|
|
392
461
|
}
|
|
393
462
|
}
|
|
394
463
|
```
|
|
395
464
|
|
|
396
|
-
`isWeftError` is an `instanceof` check — the right tool in the common case where the error came from the same module instance. If an error can reach you across a realm or a duplicate module load (multiple copies of `@lostgradient/weft` in one process), `instanceof` is unreliable;
|
|
465
|
+
`isWeftError` is an `instanceof` check — the right tool in the common case where the error came from the same module instance. If an error can reach you across a realm or a duplicate module load (multiple copies of `@lostgradient/weft` in one process), `instanceof` is unreliable; use `isWeftErrorLike` to narrow the caught value structurally:
|
|
397
466
|
|
|
398
467
|
```typescript
|
|
399
|
-
import {
|
|
468
|
+
import { isWeftErrorLike } from '@lostgradient/weft';
|
|
400
469
|
|
|
401
470
|
function isAlreadyRunning(error: unknown): boolean {
|
|
402
|
-
|
|
403
|
-
|
|
471
|
+
return isWeftErrorLike(error) && error.code === 'WorkflowAlreadyExistsError';
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
When the same producer might run through either `LocalClient` or `HttpClient`, use `isWeftFault(error, code)` for a specific branch. It matches same-process `WeftError` instances and HTTP-wrapped errors whose REST response carried the originating public `weftCode`.
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
import { isWeftFault } from '@lostgradient/weft';
|
|
479
|
+
|
|
480
|
+
function isMissingWorkflow(error: unknown): boolean {
|
|
481
|
+
return isWeftFault(error, 'WorkflowNotFoundError');
|
|
404
482
|
}
|
|
405
483
|
```
|
|
406
484
|
|
|
407
|
-
The exported `WeftErrorCode` union lists every code that belongs to a public, exported error class; those codes are stable contract and safe to `switch` on exhaustively. Errors that are internal to Weft also extend `WeftError` but carry codes intentionally left out of `WeftErrorCode` — `isWeftErrorCode`
|
|
485
|
+
The exported `WeftErrorCode` union lists every code that belongs to a public, exported error class; those codes are stable contract and safe to `switch` on exhaustively. Errors that are internal to Weft also extend `WeftError` but carry codes intentionally left out of `WeftErrorCode` — `isWeftErrorCode` and `isWeftErrorLike` return `false` for them — so internal codes may change between releases without breaking your types.
|
|
408
486
|
|
|
409
487
|
## Installation
|
|
410
488
|
|
|
@@ -418,6 +496,7 @@ Storage backends and adapters are exported under subpaths so they only load when
|
|
|
418
496
|
import { SQLiteStorage } from '@lostgradient/weft/storage/sqlite';
|
|
419
497
|
import { LMDBStorage } from '@lostgradient/weft/storage/lmdb';
|
|
420
498
|
import { TursoStorage } from '@lostgradient/weft/storage/turso';
|
|
499
|
+
import { NeonStorage } from '@lostgradient/weft/storage/neon';
|
|
421
500
|
import { IndexedDBStorage } from '@lostgradient/weft/storage/indexeddb';
|
|
422
501
|
import { WebExtensionStorage } from '@lostgradient/weft/storage/web-extension';
|
|
423
502
|
import { HTTPStorage } from '@lostgradient/weft/storage/http';
|
|
@@ -441,21 +520,22 @@ const welcome = workflow({ name: 'welcome' }).execute(
|
|
|
441
520
|
engine.register(welcome);
|
|
442
521
|
```
|
|
443
522
|
|
|
444
|
-
Each `ctx.step()` is a checkpoint boundary.
|
|
523
|
+
Each `ctx.step()` is a checkpoint boundary. Completed steps replay from storage after crash recovery instead of re-running, and `compileStepWorkflow(...)` compiles the step-style function into the generator form the engine runs internally. Await each step before starting the next. When you need durable timers, signals, parallel execution, or worker-mode isolation, switch to the generator API.
|
|
445
524
|
|
|
446
525
|
## Weft vs. Temporal
|
|
447
526
|
|
|
448
|
-
| Concept | Temporal
|
|
449
|
-
| ---------------------- |
|
|
450
|
-
| Core mental model | Replay determinism
|
|
451
|
-
| Workflow language | Go, Java, TypeScript, Python, .NET, Ruby, PHP
|
|
452
|
-
| Activity invocation | `proxyActivities()` + type import
|
|
453
|
-
| Timer | Deterministic `workflow.sleep()`
|
|
454
|
-
| Signal | `setHandler` + `condition`
|
|
455
|
-
|
|
|
456
|
-
|
|
|
457
|
-
|
|
|
458
|
-
|
|
|
527
|
+
| Concept | Temporal | Weft |
|
|
528
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
|
|
529
|
+
| Core mental model | Replay determinism | Generators pause and resume |
|
|
530
|
+
| Workflow language | Go, Java, TypeScript, Python, .NET, Ruby, PHP | TypeScript only (activities can be any language via `RemoteWorker`) |
|
|
531
|
+
| Activity invocation | `proxyActivities()` + type import | `yield* ctx.run('activityName', input)` (declared in `.activities({...})`) |
|
|
532
|
+
| Timer | Deterministic `workflow.sleep()` | `yield* ctx.sleep("1 hour")` |
|
|
533
|
+
| Signal | `setHandler` + `condition` | `yield* ctx.waitForSignal(name)` |
|
|
534
|
+
| Human review | Signals/queries/updates as [message-passing primitives](https://docs.temporal.io/develop/typescript/workflows/message-passing) | `yield* ctx.review(...)` with [durable review request](src/core/review/index.ts) and decision APIs |
|
|
535
|
+
| Versioning | `patched()` / `deprecatePatch()` | Stored and registered versions are strict recovery guards |
|
|
536
|
+
| Long-running workflows | `continueAsNew()` | None needed (checkpoint size is bounded by live state, not history length) |
|
|
537
|
+
| Dev environment | Docker Compose + Temporal server | `bun add @lostgradient/weft` |
|
|
538
|
+
| Bundling | Webpack for workflow sandbox | None |
|
|
459
539
|
|
|
460
540
|
> Weft is for teams whose primary backend language is TypeScript. If you need workflows in multiple languages, [Temporal](https://temporal.io) is the right answer. For the design rationale, see [ADR 0001 — Workflows Are TypeScript-Only by Design](documentation/contributing/architecture-decisions/0001-workflows-typescript-only.md).
|
|
461
541
|
>
|
|
@@ -480,9 +560,9 @@ Guides:
|
|
|
480
560
|
|
|
481
561
|
Architecture and reference:
|
|
482
562
|
|
|
483
|
-
- [Design Philosophy](documentation/architecture/design-philosophy.md), [Checkpoint vs. Replay](documentation/architecture/checkpoint-versus-replay.md), [Web Standards](documentation/architecture/web-standards.md)
|
|
484
|
-
- [Browser Runtime](documentation/architecture/browser-runtime.md), [Web Workers](documentation/architecture/web-workers.md), [Single Binary](documentation/architecture/single-binary.md)
|
|
485
|
-
- [API Reference](documentation/reference/) (Engine, Context, Storage, Server, Workers, Testing, Events, Interceptors, Observability, CLI, Configuration, Types)
|
|
563
|
+
- [Design Philosophy](documentation/architecture/design-philosophy.md), [Durability Guarantee](documentation/architecture/durability-guarantee.md), [Checkpoint vs. Replay](documentation/architecture/checkpoint-versus-replay.md), [Web Standards](documentation/architecture/web-standards.md)
|
|
564
|
+
- [Temporal Comparison](documentation/architecture/temporal-comparison.md), [Inngest Comparison](documentation/architecture/inngest-comparison.md), [Browser Runtime](documentation/architecture/browser-runtime.md), [Web Workers](documentation/architecture/web-workers.md), [Single Binary](documentation/architecture/single-binary.md)
|
|
565
|
+
- [API Reference](documentation/reference/) (Engine, Context, Storage, Server, Workers, Testing, Events, Errors, Interceptors, Observability, CLI, Configuration, Types)
|
|
486
566
|
|
|
487
567
|
Contributing:
|
|
488
568
|
|
package/dist/cli/conformance.js
CHANGED
|
@@ -139,7 +139,13 @@ async function dispatchAndWait(server, storage, operationId, activityName, input
|
|
|
139
139
|
await waitForResolvedStatus(storage, operationId, expectedStatus, timeoutMs);
|
|
140
140
|
}
|
|
141
141
|
async function runConformanceChecks(command, timeoutMs) {
|
|
142
|
-
const storage = new MemoryStorage, engine = new Engine({ storage }), server = serve({
|
|
142
|
+
const storage = new MemoryStorage, engine = new Engine({ storage }), server = serve({
|
|
143
|
+
engine,
|
|
144
|
+
port: 0,
|
|
145
|
+
hostname: "127.0.0.1",
|
|
146
|
+
workerReconnectGracePeriodMs: 100,
|
|
147
|
+
workerShutdownTimeoutMs: timeoutMs
|
|
148
|
+
}), checks = [];
|
|
143
149
|
let worker;
|
|
144
150
|
try {
|
|
145
151
|
worker = startWorker(command, server);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type CatalogWeftClient, type WeftClientConnection } from '../operation-client-runtime.ts';
|
|
2
|
-
export declare const CATALOG_OPERATION_NAMES: readonly ["weft.activities.complete", "weft.activities.fail", "weft.recover.all", "weft.retention.get", "weft.reviews.decision.submit", "weft.reviews.get", "weft.reviews.list", "weft.schedules.cancel", "weft.schedules.create", "weft.schedules.get", "weft.schedules.list", "weft.schedules.pause", "weft.schedules.resume", "weft.schedules.update", "weft.system.metrics", "weft.system.registry", "weft.task.queues.list", "weft.tasks.diagnostics", "weft.updates.result.get", "weft.worker.deployments.drain", "weft.worker.deployments.resume", "weft.workers.drain", "weft.workers.list", "weft.workers.resume", "weft.workflows.aggregate", "weft.workflows.attributes.get", "weft.workflows.attributes.set", "weft.workflows.bulk.cancel", "weft.workflows.bulk.delete", "weft.workflows.bulk.signal", "weft.workflows.bulk.tags", "weft.workflows.cancel", "weft.workflows.checkpoints.get", "weft.workflows.checkpoints.list", "weft.workflows.events.list", "weft.workflows.fork", "weft.workflows.get", "weft.workflows.list", "weft.workflows.purge", "weft.workflows.query", "weft.workflows.replay", "weft.workflows.result.get", "weft.workflows.resume", "weft.workflows.signal", "weft.workflows.start", "weft.workflows.streams.chunks", "weft.workflows.tags.add", "weft.workflows.tags.remove", "weft.workflows.timeline.get", "weft.workflows.timeout", "weft.workflows.update"];
|
|
2
|
+
export declare const CATALOG_OPERATION_NAMES: readonly ["weft.activities.complete", "weft.activities.fail", "weft.recover.all", "weft.retention.get", "weft.reviews.decision.submit", "weft.reviews.get", "weft.reviews.list", "weft.schedules.cancel", "weft.schedules.create", "weft.schedules.get", "weft.schedules.list", "weft.schedules.pause", "weft.schedules.resume", "weft.schedules.update", "weft.system.metrics", "weft.system.registry", "weft.task.queues.list", "weft.tasks.diagnostics", "weft.updates.result.get", "weft.worker.deployments.drain", "weft.worker.deployments.resume", "weft.workers.drain", "weft.workers.list", "weft.workers.resume", "weft.workflows.aggregate", "weft.workflows.attributes.get", "weft.workflows.attributes.set", "weft.workflows.bulk.cancel", "weft.workflows.bulk.delete", "weft.workflows.bulk.retryfailed", "weft.workflows.bulk.signal", "weft.workflows.bulk.tags", "weft.workflows.cancel", "weft.workflows.checkpoints.get", "weft.workflows.checkpoints.list", "weft.workflows.events.list", "weft.workflows.fork", "weft.workflows.get", "weft.workflows.list", "weft.workflows.purge", "weft.workflows.query", "weft.workflows.replay", "weft.workflows.result.get", "weft.workflows.resume", "weft.workflows.signal", "weft.workflows.start", "weft.workflows.startorsignal", "weft.workflows.streams.chunks", "weft.workflows.suspend", "weft.workflows.tags.add", "weft.workflows.tags.remove", "weft.workflows.timeline.get", "weft.workflows.timeout", "weft.workflows.update"];
|
|
3
3
|
export type CatalogOperationName = (typeof CATALOG_OPERATION_NAMES)[number];
|
|
4
|
-
type
|
|
4
|
+
type SharedAttributesBulkConcurrenc_73ecbca6 = {
|
|
5
5
|
readonly attributes?: ReadonlyArray<SharedGtGteKey_896a0c41>;
|
|
6
|
+
readonly bulkConcurrency?: number;
|
|
6
7
|
readonly confirmationToken?: string;
|
|
7
8
|
readonly createdAt?: SharedGtGteLt_d9a61361;
|
|
8
9
|
readonly dryRun?: boolean;
|
|
@@ -104,7 +105,7 @@ export type CatalogOperationTypes = {
|
|
|
104
105
|
'weft.reviews.list': {
|
|
105
106
|
readonly input: {
|
|
106
107
|
readonly reviewType?: string;
|
|
107
|
-
readonly status?:
|
|
108
|
+
readonly status?: 'pending' | 'completed';
|
|
108
109
|
readonly workflowId?: string;
|
|
109
110
|
};
|
|
110
111
|
readonly output: {
|
|
@@ -126,6 +127,7 @@ export type CatalogOperationTypes = {
|
|
|
126
127
|
readonly every?: unknown;
|
|
127
128
|
readonly id?: unknown;
|
|
128
129
|
readonly input?: unknown;
|
|
130
|
+
readonly jitter?: unknown;
|
|
129
131
|
readonly overlap?: unknown;
|
|
130
132
|
readonly type: unknown;
|
|
131
133
|
};
|
|
@@ -198,7 +200,7 @@ export type CatalogOperationTypes = {
|
|
|
198
200
|
readonly oldestEnqueuedAt: unknown;
|
|
199
201
|
readonly oldestQueuedAgeMs: unknown;
|
|
200
202
|
readonly queue: string;
|
|
201
|
-
readonly schedulingPolicy:
|
|
203
|
+
readonly schedulingPolicy: 'priority' | 'fifo' | 'lifo';
|
|
202
204
|
readonly waitingPollers: number;
|
|
203
205
|
}>;
|
|
204
206
|
};
|
|
@@ -217,24 +219,29 @@ export type CatalogOperationTypes = {
|
|
|
217
219
|
readonly output: {
|
|
218
220
|
readonly items: ReadonlyArray<{
|
|
219
221
|
readonly activityName?: string;
|
|
222
|
+
readonly deadLetterReason?: string;
|
|
223
|
+
readonly deadLetteredAt?: number;
|
|
220
224
|
readonly evidence: ReadonlyArray<string>;
|
|
221
225
|
readonly executionLatencyMs?: number;
|
|
222
226
|
readonly heartbeatAgeMs?: number;
|
|
223
|
-
readonly kind:
|
|
224
|
-
readonly lastRequeueReason?:
|
|
227
|
+
readonly kind: 'stuck-queued' | 'stale-inflight' | 'retry-storm' | 'all-workers-at-capacity' | 'dead-lettered';
|
|
228
|
+
readonly lastRequeueReason?: 'visibility-timeout' | 'worker-disconnect';
|
|
225
229
|
readonly operationId?: string;
|
|
226
230
|
readonly queue?: string;
|
|
227
231
|
readonly queueLatencyMs?: number;
|
|
228
232
|
readonly requeueCount: number;
|
|
229
233
|
readonly resolutionReason?: string;
|
|
234
|
+
readonly retryAttempts?: number;
|
|
230
235
|
readonly retryCount: number;
|
|
231
|
-
readonly state:
|
|
236
|
+
readonly state: 'queued' | 'inflight' | 'resolved' | 'capacity' | 'dead-lettered';
|
|
237
|
+
readonly storageError?: string;
|
|
232
238
|
readonly workerId?: string;
|
|
233
239
|
readonly workflowId?: string;
|
|
234
240
|
}>;
|
|
235
241
|
readonly limit: number;
|
|
236
242
|
readonly summary: {
|
|
237
243
|
readonly allWorkersAtCapacity: number;
|
|
244
|
+
readonly deadLettered: number;
|
|
238
245
|
readonly retryStorms: number;
|
|
239
246
|
readonly staleInflight: number;
|
|
240
247
|
readonly stuckQueued: number;
|
|
@@ -282,7 +289,7 @@ export type CatalogOperationTypes = {
|
|
|
282
289
|
readonly drainedWorkers: number;
|
|
283
290
|
readonly drainingWorkers: number;
|
|
284
291
|
readonly gitSha: unknown;
|
|
285
|
-
readonly health:
|
|
292
|
+
readonly health: 'active' | 'draining' | 'drained';
|
|
286
293
|
readonly inFlight: number;
|
|
287
294
|
readonly oldestStartedAt: unknown;
|
|
288
295
|
readonly runtimeVersion: unknown;
|
|
@@ -297,7 +304,7 @@ export type CatalogOperationTypes = {
|
|
|
297
304
|
readonly connectedAt: number;
|
|
298
305
|
readonly deploymentName?: string;
|
|
299
306
|
readonly gitSha?: string;
|
|
300
|
-
readonly health:
|
|
307
|
+
readonly health: 'active' | 'draining' | 'drained';
|
|
301
308
|
readonly heartbeatAgeMs: number;
|
|
302
309
|
readonly id: string;
|
|
303
310
|
readonly inFlight: number;
|
|
@@ -306,7 +313,7 @@ export type CatalogOperationTypes = {
|
|
|
306
313
|
readonly runtimeVersion?: string;
|
|
307
314
|
readonly startedAt: number;
|
|
308
315
|
}>;
|
|
309
|
-
readonly routingPolicy:
|
|
316
|
+
readonly routingPolicy: 'least-loaded' | 'round-robin' | 'fair-share';
|
|
310
317
|
};
|
|
311
318
|
readonly faults: never;
|
|
312
319
|
};
|
|
@@ -366,18 +373,24 @@ export type CatalogOperationTypes = {
|
|
|
366
373
|
readonly faults: never;
|
|
367
374
|
};
|
|
368
375
|
'weft.workflows.bulk.cancel': {
|
|
369
|
-
readonly input:
|
|
376
|
+
readonly input: SharedAttributesBulkConcurrenc_73ecbca6;
|
|
370
377
|
readonly output: unknown;
|
|
371
378
|
readonly faults: never;
|
|
372
379
|
};
|
|
373
380
|
'weft.workflows.bulk.delete': {
|
|
374
|
-
readonly input:
|
|
381
|
+
readonly input: SharedAttributesBulkConcurrenc_73ecbca6;
|
|
375
382
|
readonly output: unknown;
|
|
376
383
|
readonly faults: 'Unprocessable';
|
|
377
384
|
};
|
|
385
|
+
'weft.workflows.bulk.retryfailed': {
|
|
386
|
+
readonly input: SharedAttributesBulkConcurrenc_73ecbca6;
|
|
387
|
+
readonly output: unknown;
|
|
388
|
+
readonly faults: never;
|
|
389
|
+
};
|
|
378
390
|
'weft.workflows.bulk.signal': {
|
|
379
391
|
readonly input: {
|
|
380
392
|
readonly attributes?: ReadonlyArray<SharedGtGteKey_896a0c41>;
|
|
393
|
+
readonly bulkConcurrency?: number;
|
|
381
394
|
readonly confirmationToken?: string;
|
|
382
395
|
readonly createdAt?: SharedGtGteLt_d9a61361;
|
|
383
396
|
readonly dryRun?: boolean;
|
|
@@ -399,10 +412,11 @@ export type CatalogOperationTypes = {
|
|
|
399
412
|
};
|
|
400
413
|
'weft.workflows.bulk.tags': {
|
|
401
414
|
readonly input: {
|
|
415
|
+
readonly bulkConcurrency?: number;
|
|
402
416
|
readonly confirmationToken?: string;
|
|
403
417
|
readonly dryRun?: boolean;
|
|
404
418
|
readonly filter?: SharedAttributesCreatedAtExecu_c9ba5dc6;
|
|
405
|
-
readonly operation:
|
|
419
|
+
readonly operation: 'add' | 'remove';
|
|
406
420
|
readonly requestId?: string;
|
|
407
421
|
readonly tags: ReadonlyArray<string>;
|
|
408
422
|
};
|
|
@@ -540,6 +554,27 @@ export type CatalogOperationTypes = {
|
|
|
540
554
|
};
|
|
541
555
|
readonly faults: 'Conflict';
|
|
542
556
|
};
|
|
557
|
+
'weft.workflows.startorsignal': {
|
|
558
|
+
readonly input: {
|
|
559
|
+
readonly executionTimeout?: unknown;
|
|
560
|
+
readonly id?: unknown;
|
|
561
|
+
readonly idempotencyKey?: unknown;
|
|
562
|
+
readonly input?: unknown;
|
|
563
|
+
readonly searchAttributes?: unknown;
|
|
564
|
+
readonly signalId?: string;
|
|
565
|
+
readonly signalName: string;
|
|
566
|
+
readonly signalPayload?: unknown;
|
|
567
|
+
readonly startAfter?: unknown;
|
|
568
|
+
readonly startAt?: unknown;
|
|
569
|
+
readonly tags?: unknown;
|
|
570
|
+
readonly type: unknown;
|
|
571
|
+
};
|
|
572
|
+
readonly output: {
|
|
573
|
+
readonly id: string;
|
|
574
|
+
readonly outcome: 'started' | 'signalled';
|
|
575
|
+
};
|
|
576
|
+
readonly faults: 'Conflict';
|
|
577
|
+
};
|
|
543
578
|
'weft.workflows.streams.chunks': {
|
|
544
579
|
readonly input: {
|
|
545
580
|
readonly after?: unknown;
|
|
@@ -551,6 +586,13 @@ export type CatalogOperationTypes = {
|
|
|
551
586
|
};
|
|
552
587
|
readonly faults: never;
|
|
553
588
|
};
|
|
589
|
+
'weft.workflows.suspend': {
|
|
590
|
+
readonly input: {
|
|
591
|
+
readonly workflowId: string;
|
|
592
|
+
};
|
|
593
|
+
readonly output: unknown;
|
|
594
|
+
readonly faults: 'Unprocessable';
|
|
595
|
+
};
|
|
554
596
|
'weft.workflows.tags.add': {
|
|
555
597
|
readonly input: {
|
|
556
598
|
readonly tags?: unknown;
|
|
@@ -32,6 +32,7 @@ export const CATALOG_OPERATION_NAMES = [
|
|
|
32
32
|
"weft.workflows.attributes.set",
|
|
33
33
|
"weft.workflows.bulk.cancel",
|
|
34
34
|
"weft.workflows.bulk.delete",
|
|
35
|
+
"weft.workflows.bulk.retryfailed",
|
|
35
36
|
"weft.workflows.bulk.signal",
|
|
36
37
|
"weft.workflows.bulk.tags",
|
|
37
38
|
"weft.workflows.cancel",
|
|
@@ -48,7 +49,9 @@ export const CATALOG_OPERATION_NAMES = [
|
|
|
48
49
|
"weft.workflows.resume",
|
|
49
50
|
"weft.workflows.signal",
|
|
50
51
|
"weft.workflows.start",
|
|
52
|
+
"weft.workflows.startorsignal",
|
|
51
53
|
"weft.workflows.streams.chunks",
|
|
54
|
+
"weft.workflows.suspend",
|
|
52
55
|
"weft.workflows.tags.add",
|
|
53
56
|
"weft.workflows.tags.remove",
|
|
54
57
|
"weft.workflows.timeline.get",
|
package/dist/cli/help-text.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const CONFORMANCE_HELP_TEXT = "\nweft conformance - Run RemoteWor
|
|
|
4
4
|
export declare const DOCTOR_HELP_TEXT = "\nweft doctor - Run diagnostics on the Weft database\n\nUsage: weft doctor [options]\n\nOptions:\n -d, --database <path> Database file path (default: ./weft.db)\n -j, --json Output results as JSON\n -h, --help Show this help message\n";
|
|
5
5
|
export declare const VERSION_CHECK_HELP_TEXT = "\nweft version:check - Check workflow version compatibility\n\nUsage: weft version:check [options]\n\nOptions:\n -d, --database <path> Database file path (default: ./weft.db)\n -w, --workflows <path> Path to workflows module\n -j, --json Output results as JSON\n -h, --help Show this help message\n";
|
|
6
6
|
export declare const TIMELINE_HELP_TEXT = "\nweft timeline - Inspect workflow timeline and replay history\n\nUsage:\n weft timeline <workflowId> [options]\n weft timeline <workflowId> --diff <fromStep> <toStep> [options]\n\nOptions:\n -d, --database <path> Database file path (default: ./weft.db)\n --step <step> Show replay details for one checkpoint step\n --diff Diff two checkpoint steps (requires two positional step numbers)\n -h, --help Show this help message\n";
|
|
7
|
-
export declare const SCHEDULE_HELP_TEXT = "\nweft schedule - Manage recurring schedules\n\nUsage:\n weft schedule list [options]\n weft schedule create <workflowType> <cronExpression> [options]\n weft schedule create <workflowType> --every <duration> [options]\n weft schedule pause <scheduleId> [options]\n weft schedule resume <scheduleId> [options]\n weft schedule cancel <scheduleId> [options]\n\nProvide a cron expression positional OR an --every interval (e.g. \"30s\", \"1h\"),\nbut not both. Interval schedules fire one period after creation, then every\nperiod after that.\n\nOptions:\n -d, --database <path> Database file path (default: ./weft.db)\n -s, --storage <backend> Storage backend: sqlite, lmdb (default: sqlite)\n -w, --workflows <path> Path to workflow registrations module (required for create)\n --every <duration> Interval cadence for create (e.g. 30s, 5m, 1h); mutually exclusive with the cron positional\n --input <json> JSON input payload for create (default: null)\n --id <id> Custom schedule id for create\n --overlap <policy> Overlap policy: skip, queue, cancel-running, allow\n --backfill Run missed ticks on recovery\n -j, --json Output results as JSON\n -h, --help Show this help message\n";
|
|
7
|
+
export declare const SCHEDULE_HELP_TEXT = "\nweft schedule - Manage recurring schedules\n\nUsage:\n weft schedule list [options]\n weft schedule create <workflowType> <cronExpression> [options]\n weft schedule create <workflowType> --every <duration> [options]\n weft schedule pause <scheduleId> [options]\n weft schedule resume <scheduleId> [options]\n weft schedule cancel <scheduleId> [options]\n\nProvide a cron expression positional OR an --every interval (e.g. \"30s\", \"1h\"),\nbut not both. Interval schedules fire one period after creation, then every\nperiod after that.\n\nOptions:\n -d, --database <path> Database file path (default: ./weft.db)\n -s, --storage <backend> Storage backend: sqlite, lmdb (default: sqlite)\n -w, --workflows <path> Path to workflow registrations module (required for create)\n --every <duration> Interval cadence for create (e.g. 30s, 5m, 1h); mutually exclusive with the cron positional\n --input <json> JSON input payload for create (default: null)\n --id <id> Custom schedule id for create\n --overlap <policy> Overlap policy: skip, queue, cancel-running, allow\n --backfill Run missed ticks on recovery\n --jitter <duration> Deterministic dispatch jitter for create (e.g. 30s, 5m)\n -j, --json Output results as JSON\n -h, --help Show this help message\n";
|
|
8
8
|
export declare const VALIDATE_HELP_TEXT = "\nweft validate - Lint workflow registrations for design-time anti-patterns\n\nUsage: weft validate <entry.ts>... [options]\n\nArguments:\n <entry.ts>... One or more TypeScript modules or glob patterns that\n resolve to workflow registrations and/or activity\n definitions.\n\nOptions:\n -j, --json Output results as JSON\n -h, --help Show this help message\n\nExit codes:\n 0 No errors (warnings may be present)\n 1 One or more errors detected\n 2 Entry file could not be loaded (takes precedence over validation errors)\n\nJSON output:\n { entries, valid, hasLoadErrors, hasValidationErrors }\n\nChecks performed:\n unbounded-retry Activity retry.maxAttempts is Infinity\n stateful-without-compensator Non-idempotent activity has no compensate fn\n";
|
|
9
9
|
export declare const SERVER_HELP_TEXT = "\nweft server - Inspect a running server's health and operation surface\n\nUsage:\n weft server health [options]\n weft server info [options]\n\nOptions:\n --server <url> Server URL (default: WEFT_ADDR, profile, run lockfile, or localhost)\n --token <token> Bearer token (default: WEFT_TOKEN)\n --profile <name> Profile from ~/.weft/config\n --wait (health) Poll until the server is reachable\n --wait-timeout <ms> (health) Maximum time to wait, in milliseconds (default: 30000)\n -j, --json Emit machine-readable JSON output\n -q, --quiet Suppress success/error text (use the exit code)\n -h, --help Show this help message\n\nExit codes:\n 0 Healthy\n 1 Unreachable / unhealthy\n 2 Connection error\n";
|
|
10
10
|
export declare const WORKFLOW_HELP_TEXT = "\nweft workflow - List, inspect, start, signal, and cancel workflows on a server\n\nUsage:\n weft workflow ls [--type <type>] [--status <status>] [--limit <n>] [options]\n weft workflow get <workflow-id> [options]\n weft workflow events <workflow-id> [options]\n weft workflow start <workflow-type> [--input <json> | --input-file <path|->] [--id <id>] [options]\n weft workflow cancel <workflow-id> [--yes] [--dry-run] [options]\n weft workflow signal <workflow-id> <signal-name> [--input <json> | --input-file <path|->] [options]\n\nOptions:\n --server <url> Server URL (default: WEFT_ADDR, profile, run lockfile, or localhost)\n --token <token> Bearer token (default: WEFT_TOKEN)\n --profile <name> Profile from ~/.weft/config\n --type <type> (ls) Filter by workflow type\n --status <status> (ls) Filter by workflow status\n --limit <n> (ls) Maximum number of rows\n --input <json> (start/signal) JSON input payload\n --input-file <path> (start/signal) Read JSON input from a file, or '-' for stdin\n --id <id> (start) Explicit workflow id\n -y, --yes (cancel) Confirm without prompting\n --dry-run (cancel) Print affected count without cancelling\n -j, --json Emit machine-readable output (NDJSON for lists)\n -q, --quiet Print ids only / suppress success text\n -h, --help Show this help message\n\nExit codes:\n 0 Success\n 1 Operation failed or destructive operation was not confirmed\n 2 Connection error\n 3 Usage or input error\n 4 Operation unavailable on this server (version skew)\n";
|
package/dist/cli/help-text.js
CHANGED
|
@@ -123,6 +123,7 @@ Options:
|
|
|
123
123
|
--id <id> Custom schedule id for create
|
|
124
124
|
--overlap <policy> Overlap policy: skip, queue, cancel-running, allow
|
|
125
125
|
--backfill Run missed ticks on recovery
|
|
126
|
+
--jitter <duration> Deterministic dispatch jitter for create (e.g. 30s, 5m)
|
|
126
127
|
-j, --json Output results as JSON
|
|
127
128
|
-h, --help Show this help message
|
|
128
129
|
`, VALIDATE_HELP_TEXT = `
|