@lostgradient/weft 0.23.1 → 0.24.1
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 +72 -4
- package/dist/cli/codegen-emit-dedup.d.ts +81 -0
- package/dist/cli/codegen-emit-dedup.js +45 -0
- package/dist/cli/codegen-emit-registry.d.ts +90 -0
- package/dist/cli/codegen-emit-registry.js +50 -0
- package/dist/cli/codegen-emit.d.ts +26 -39
- package/dist/cli/codegen-emit.js +4 -27
- package/dist/cli/codegen-validate.d.ts +49 -0
- package/dist/cli/codegen-validate.js +186 -0
- package/dist/cli/codegen.js +6 -87
- package/dist/cli/conformance.js +5 -2
- package/dist/cli/generated/operation-catalog.snapshot.json +381 -3
- package/dist/cli/generated/operation-client.generated.d.ts +350 -10
- package/dist/cli/generated/operation-client.generated.js +14 -0
- package/dist/cli/output.js +1 -1
- package/dist/cli/parse-schedule-arguments.js +15 -3
- package/dist/cli/schedule.js +2 -1
- package/dist/cli/storage-factory.js +2 -0
- package/dist/cli/types.d.ts +2 -1
- package/dist/cli/workflow-commands.js +2 -0
- package/dist/cli-main.js +1 -1
- package/dist/client/http-client-requests.js +6 -9
- package/dist/client/start-body.js +1 -0
- package/dist/core/application-payload-digest.d.ts +42 -0
- package/dist/core/application-payload-digest.js +76 -0
- package/dist/core/application-primitive-abort.d.ts +50 -0
- package/dist/core/application-primitive-abort.js +40 -0
- package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
- package/dist/core/application-primitive-attempt-registry.js +73 -0
- package/dist/core/application-primitive-codec.d.ts +36 -0
- package/dist/core/application-primitive-codec.js +56 -0
- package/dist/core/application-primitive-commit.d.ts +67 -0
- package/dist/core/application-primitive-commit.js +66 -0
- package/dist/core/application-primitive-guards.d.ts +62 -0
- package/dist/core/application-primitive-guards.js +89 -0
- package/dist/core/application-primitive-payload.d.ts +29 -0
- package/dist/core/application-primitive-payload.js +65 -0
- package/dist/core/application-primitive-timing.d.ts +18 -0
- package/dist/core/application-primitive-timing.js +22 -0
- package/dist/core/atomic-state.js +2 -0
- package/dist/core/catalog/codec.d.ts +40 -0
- package/dist/core/catalog/codec.js +45 -0
- package/dist/core/catalog/errors.d.ts +104 -0
- package/dist/core/catalog/errors.js +41 -0
- package/dist/core/catalog/index.d.ts +25 -0
- package/dist/core/catalog/index.js +22 -0
- package/dist/core/catalog/reference-counts.d.ts +120 -0
- package/dist/core/catalog/reference-counts.js +28 -0
- package/dist/core/catalog/removal.d.ts +105 -0
- package/dist/core/catalog/removal.js +30 -0
- package/dist/core/catalog/storage-io.d.ts +101 -0
- package/dist/core/catalog/storage-io.js +106 -0
- package/dist/core/catalog/types.d.ts +108 -0
- package/dist/core/catalog/types.js +0 -0
- package/dist/core/catalog/workflow-catalog.d.ts +165 -0
- package/dist/core/catalog/workflow-catalog.js +198 -0
- package/dist/core/compare-codepoint.d.ts +13 -0
- package/dist/core/compare-codepoint.js +7 -0
- package/dist/core/compression.js +2 -0
- package/dist/core/context/attributes.d.ts +1 -1
- package/dist/core/context/durable-operations.d.ts +2 -2
- package/dist/core/context/index.js +5 -3
- package/dist/core/context/state-namespace.d.ts +1 -1
- package/dist/core/contract/build.d.ts +64 -0
- package/dist/core/contract/build.js +99 -0
- package/dist/core/contract/compatibility.d.ts +187 -0
- package/dist/core/contract/compatibility.js +37 -0
- package/dist/core/contract/failure.d.ts +64 -0
- package/dist/core/contract/failure.js +4 -0
- package/dist/core/contract/hash.d.ts +92 -0
- package/dist/core/contract/hash.js +34 -0
- package/dist/core/contract/index.d.ts +21 -0
- package/dist/core/contract/index.js +22 -0
- package/dist/core/contract/limits.d.ts +74 -0
- package/dist/core/contract/limits.js +1 -0
- package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
- package/dist/core/contract/manifest-parse-schema.js +106 -0
- package/dist/core/contract/manifest-parse.d.ts +76 -0
- package/dist/core/contract/manifest-parse.js +189 -0
- package/dist/core/contract/manifest.d.ts +56 -0
- package/dist/core/contract/manifest.js +31 -0
- package/dist/core/contract/normalize.d.ts +97 -0
- package/dist/core/contract/normalize.js +127 -0
- package/dist/core/contract/revision.d.ts +29 -0
- package/dist/core/contract/revision.js +5 -0
- package/dist/core/contract/types.d.ts +274 -0
- package/dist/core/contract/types.js +1 -0
- package/dist/core/engine/activity-resolution.js +17 -17
- package/dist/core/engine/bulk-operations-purge.js +14 -20
- package/dist/core/engine/bulk-operations-retry.d.ts +9 -0
- package/dist/core/engine/bulk-operations-retry.js +177 -0
- package/dist/core/engine/bulk-operations-shared.d.ts +18 -0
- package/dist/core/engine/bulk-operations-shared.js +14 -0
- package/dist/core/engine/bulk-operations.js +8 -167
- package/dist/core/engine/callback-creators-bundles.js +4 -2
- package/dist/core/engine/callback-creators-core.js +9 -1
- package/dist/core/engine/callback-creators-schedule.js +2 -2
- package/dist/core/engine/catalog-activation.d.ts +40 -0
- package/dist/core/engine/catalog-activation.js +17 -0
- package/dist/core/engine/catalog-events.d.ts +36 -0
- package/dist/core/engine/catalog-events.js +15 -0
- package/dist/core/engine/catalog-readiness.d.ts +49 -0
- package/dist/core/engine/catalog-readiness.js +61 -0
- package/dist/core/engine/catalog-removal.d.ts +236 -0
- package/dist/core/engine/catalog-removal.js +123 -0
- package/dist/core/engine/catalog-tombstone-recovery.d.ts +56 -0
- package/dist/core/engine/catalog-tombstone-recovery.js +39 -0
- package/dist/core/engine/constraints.js +5 -1
- package/dist/core/engine/construction.d.ts +2 -2
- package/dist/core/engine/construction.js +4 -2
- package/dist/core/engine/decode-revision.d.ts +32 -0
- package/dist/core/engine/decode-revision.js +9 -0
- package/dist/core/engine/disposal.d.ts +6 -2
- package/dist/core/engine/disposal.js +26 -3
- package/dist/core/engine/dynamic-source-errors.d.ts +81 -0
- package/dist/core/engine/dynamic-source-errors.js +25 -0
- package/dist/core/engine/dynamic-source-execution.d.ts +173 -0
- package/dist/core/engine/dynamic-source-execution.js +108 -0
- package/dist/core/engine/engine-internal-types.d.ts +16 -0
- package/dist/core/engine/engine-workflows-namespace.d.ts +140 -0
- package/dist/core/engine/engine-workflows-namespace.js +51 -0
- package/dist/core/engine/finalizer-metadata.d.ts +22 -0
- package/dist/core/engine/finalizer-metadata.js +12 -0
- package/dist/core/engine/handle-result.js +2 -0
- package/dist/core/engine/index.d.ts +91 -0
- package/dist/core/engine/index.js +78 -6
- package/dist/core/engine/inline-launch-queue.js +1 -1
- package/dist/core/engine/internals.d.ts +54 -15
- package/dist/core/engine/internals.js +6 -0
- package/dist/core/engine/lifecycle/checkpoint-launch.d.ts +29 -0
- package/dist/core/engine/lifecycle/checkpoint-launch.js +75 -0
- package/dist/core/engine/lifecycle/delayed-start-registration.d.ts +30 -0
- package/dist/core/engine/lifecycle/delayed-start-registration.js +11 -0
- package/dist/core/engine/lifecycle/fork-helpers.d.ts +33 -1
- package/dist/core/engine/lifecycle/fork-helpers.js +3 -1
- package/dist/core/engine/lifecycle/recovery-revision-groups.d.ts +75 -0
- package/dist/core/engine/lifecycle/recovery-revision-groups.js +64 -0
- package/dist/core/engine/lifecycle/resume-generation-guard.d.ts +58 -0
- package/dist/core/engine/lifecycle/resume-generation-guard.js +11 -0
- package/dist/core/engine/lifecycle/resume.js +18 -9
- package/dist/core/engine/lifecycle/shared.d.ts +43 -0
- package/dist/core/engine/lifecycle/standalone-claim-acquire.d.ts +12 -0
- package/dist/core/engine/lifecycle/standalone-claim-acquire.js +6 -0
- package/dist/core/engine/lifecycle/start-commit-errors.d.ts +12 -0
- package/dist/core/engine/lifecycle/start-commit-errors.js +6 -0
- package/dist/core/engine/lifecycle/start-commit.d.ts +22 -7
- package/dist/core/engine/lifecycle/start-commit.js +49 -15
- package/dist/core/engine/lifecycle/start-exec.d.ts +18 -2
- package/dist/core/engine/lifecycle/start-exec.js +7 -5
- package/dist/core/engine/lifecycle/start-or-signal-create.js +1 -3
- package/dist/core/engine/lifecycle/start-or-signal.js +1 -1
- package/dist/core/engine/lifecycle/start-precondition-attribution.d.ts +49 -0
- package/dist/core/engine/lifecycle/start-precondition-attribution.js +13 -0
- package/dist/core/engine/lifecycle/start-revision-resolution.d.ts +34 -0
- package/dist/core/engine/lifecycle/start-revision-resolution.js +11 -0
- package/dist/core/engine/lifecycle/start-state.d.ts +16 -0
- package/dist/core/engine/lifecycle/start-state.js +60 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +66 -3
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +13 -3
- package/dist/core/engine/lifecycle/start.d.ts +16 -6
- package/dist/core/engine/lifecycle/start.js +39 -66
- package/dist/core/engine/lifecycle/transition.d.ts +3 -4
- package/dist/core/engine/lifecycle/transition.js +30 -80
- package/dist/core/engine/lifecycle.d.ts +4 -2
- package/dist/core/engine/lifecycle.js +6 -6
- package/dist/core/engine/listing.js +15 -1
- package/dist/core/engine/memo-durable-activity.js +4 -1
- package/dist/core/engine/nonterminal-revision-count.d.ts +25 -0
- package/dist/core/engine/nonterminal-revision-count.js +16 -0
- package/dist/core/engine/operations-time.d.ts +5 -23
- package/dist/core/engine/operations-time.js +13 -11
- package/dist/core/engine/ownership-bootstrap.d.ts +1 -1
- package/dist/core/engine/pinned-schedule-revision-count.d.ts +26 -0
- package/dist/core/engine/pinned-schedule-revision-count.js +19 -0
- package/dist/core/engine/pinned-schedule-revision.d.ts +76 -0
- package/dist/core/engine/pinned-schedule-revision.js +53 -0
- package/dist/core/engine/registration.d.ts +106 -0
- package/dist/core/engine/registration.js +28 -7
- package/dist/core/engine/retention.js +9 -2
- package/dist/core/engine/revision-errors.d.ts +71 -0
- package/dist/core/engine/revision-errors.js +13 -0
- package/dist/core/engine/schedule-revision-fire.d.ts +17 -0
- package/dist/core/engine/schedule-revision-fire.js +3 -0
- package/dist/core/engine/schedule-run.js +2 -1
- package/dist/core/engine/schedules.d.ts +2 -1
- package/dist/core/engine/schedules.js +28 -9
- package/dist/core/engine/source-diagnostics.d.ts +76 -0
- package/dist/core/engine/source-diagnostics.js +105 -0
- package/dist/core/engine/source-registration.d.ts +42 -0
- package/dist/core/engine/source-registration.js +38 -0
- package/dist/core/engine/source-resolution.d.ts +101 -0
- package/dist/core/engine/source-resolution.js +154 -0
- package/dist/core/engine/source-runtime-state.d.ts +92 -0
- package/dist/core/engine/source-runtime-state.js +36 -0
- package/dist/core/engine/storage-io.d.ts +19 -2
- package/dist/core/engine/storage-io.js +21 -2
- package/dist/core/engine/termination/finalizer-registration.d.ts +18 -0
- package/dist/core/engine/termination/finalizer-registration.js +21 -0
- package/dist/core/engine/termination/finalizer.d.ts +16 -19
- package/dist/core/engine/termination/finalizer.js +3 -3
- package/dist/core/engine/time-operation-callbacks.d.ts +32 -0
- package/dist/core/engine/time-operation-callbacks.js +0 -0
- package/dist/core/engine/validation/schedule-cadence.d.ts +16 -0
- package/dist/core/engine/validation/schedule-cadence.js +20 -0
- package/dist/core/engine/validation/schedule-options.d.ts +4 -1
- package/dist/core/engine/validation/schedule-options.js +14 -0
- package/dist/core/engine/validation/schedule-revision.d.ts +24 -0
- package/dist/core/engine/validation/schedule-revision.js +21 -0
- package/dist/core/engine/validation/schedule-warnings.d.ts +11 -0
- package/dist/core/engine/validation/schedule-warnings.js +5 -0
- package/dist/core/engine/validation/schedule.d.ts +4 -3
- package/dist/core/engine/validation/schedule.js +15 -26
- package/dist/core/engine/validation.js +5 -2
- package/dist/core/engine/workflow-claim-reclaim-target.d.ts +1 -1
- package/dist/core/engine/workflow-claim-reclaim-target.js +16 -2
- package/dist/core/engine/workflow-retention-deadline.d.ts +16 -0
- package/dist/core/engine/workflow-retention-deadline.js +33 -0
- package/dist/core/events/catalog-events.d.ts +117 -0
- package/dist/core/events/catalog-events.js +62 -0
- package/dist/core/events/event-map.d.ts +11 -0
- package/dist/core/events/index.d.ts +2 -0
- package/dist/core/events/index.js +2 -0
- package/dist/core/events/workflow-source-events.d.ts +102 -0
- package/dist/core/events/workflow-source-events.js +57 -0
- package/dist/core/execution-strategy.d.ts +7 -0
- package/dist/core/inline-execution-strategy.context-options.d.ts +1 -1
- package/dist/core/inline-execution-strategy.js +1 -1
- package/dist/core/mailbox-admission.d.ts +26 -0
- package/dist/core/mailbox-admission.js +130 -0
- package/dist/core/mailbox-claims.d.ts +251 -0
- package/dist/core/mailbox-claims.js +0 -0
- package/dist/core/mailbox-codec.d.ts +32 -0
- package/dist/core/mailbox-codec.js +221 -0
- package/dist/core/mailbox-contract.d.ts +290 -0
- package/dist/core/mailbox-contract.js +0 -0
- package/dist/core/mailbox-delivery.d.ts +37 -0
- package/dist/core/mailbox-delivery.js +193 -0
- package/dist/core/mailbox-guards.d.ts +78 -0
- package/dist/core/mailbox-guards.js +58 -0
- package/dist/core/mailbox-index-codec.d.ts +41 -0
- package/dist/core/mailbox-index-codec.js +71 -0
- package/dist/core/mailbox-internals.d.ts +156 -0
- package/dist/core/mailbox-internals.js +154 -0
- package/dist/core/mailbox-maintenance.d.ts +29 -0
- package/dist/core/mailbox-maintenance.js +196 -0
- package/dist/core/mailbox-settlement.d.ts +69 -0
- package/dist/core/mailbox-settlement.js +206 -0
- package/dist/core/mailbox-storage.d.ts +117 -0
- package/dist/core/mailbox-storage.js +115 -0
- package/dist/core/mailbox-transition-helpers.d.ts +70 -0
- package/dist/core/mailbox-transition-helpers.js +43 -0
- package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
- package/dist/core/mailbox-transitions-recovery.js +64 -0
- package/dist/core/mailbox-transitions.d.ts +138 -0
- package/dist/core/mailbox-transitions.js +180 -0
- package/dist/core/mailbox-types.d.ts +406 -0
- package/dist/core/mailbox-types.js +16 -0
- package/dist/core/mailbox-validation.d.ts +65 -0
- package/dist/core/mailbox-validation.js +73 -0
- package/dist/core/mailbox-waits.d.ts +50 -0
- package/dist/core/mailbox-waits.js +97 -0
- package/dist/core/mailbox.d.ts +163 -0
- package/dist/core/mailbox.js +211 -0
- package/dist/core/outbox-claims.d.ts +307 -0
- package/dist/core/outbox-claims.js +0 -0
- package/dist/core/outbox-codec.d.ts +24 -0
- package/dist/core/outbox-codec.js +257 -0
- package/dist/core/outbox-contract.d.ts +346 -0
- package/dist/core/outbox-contract.js +0 -0
- package/dist/core/outbox-delivery.d.ts +34 -0
- package/dist/core/outbox-delivery.js +149 -0
- package/dist/core/outbox-drain.d.ts +29 -0
- package/dist/core/outbox-drain.js +158 -0
- package/dist/core/outbox-enqueue.d.ts +24 -0
- package/dist/core/outbox-enqueue.js +115 -0
- package/dist/core/outbox-guards.d.ts +76 -0
- package/dist/core/outbox-guards.js +60 -0
- package/dist/core/outbox-index-codec.d.ts +33 -0
- package/dist/core/outbox-index-codec.js +71 -0
- package/dist/core/outbox-internals.d.ts +99 -0
- package/dist/core/outbox-internals.js +159 -0
- package/dist/core/outbox-listing.d.ts +12 -0
- package/dist/core/outbox-listing.js +38 -0
- package/dist/core/outbox-maintenance.d.ts +28 -0
- package/dist/core/outbox-maintenance.js +191 -0
- package/dist/core/outbox-operations.d.ts +18 -0
- package/dist/core/outbox-operations.js +46 -0
- package/dist/core/outbox-runner.d.ts +30 -0
- package/dist/core/outbox-runner.js +217 -0
- package/dist/core/outbox-settlement.d.ts +57 -0
- package/dist/core/outbox-settlement.js +183 -0
- package/dist/core/outbox-storage.d.ts +107 -0
- package/dist/core/outbox-storage.js +127 -0
- package/dist/core/outbox-transition-helpers.d.ts +83 -0
- package/dist/core/outbox-transition-helpers.js +63 -0
- package/dist/core/outbox-transitions-recovery.d.ts +30 -0
- package/dist/core/outbox-transitions-recovery.js +42 -0
- package/dist/core/outbox-transitions.d.ts +145 -0
- package/dist/core/outbox-transitions.js +236 -0
- package/dist/core/outbox-types.d.ts +400 -0
- package/dist/core/outbox-types.js +20 -0
- package/dist/core/outbox-validation.d.ts +101 -0
- package/dist/core/outbox-validation.js +127 -0
- package/dist/core/outbox-waits.d.ts +39 -0
- package/dist/core/outbox-waits.js +88 -0
- package/dist/core/outbox.d.ts +156 -0
- package/dist/core/outbox.js +234 -0
- package/dist/core/registry-limits.d.ts +49 -0
- package/dist/core/registry-limits.js +10 -0
- package/dist/core/registry-schema-conversion.d.ts +20 -0
- package/dist/core/registry-schema-conversion.js +22 -0
- package/dist/core/registry-snapshot.d.ts +91 -42
- package/dist/core/registry-snapshot.js +39 -77
- package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
- package/dist/core/registry-workflow-contract-draft.js +28 -0
- package/dist/core/registry-workflow-manifest.d.ts +122 -0
- package/dist/core/registry-workflow-manifest.js +92 -0
- package/dist/core/source/errors.d.ts +55 -0
- package/dist/core/source/errors.js +13 -0
- package/dist/core/source/index.d.ts +19 -0
- package/dist/core/source/index.js +4 -0
- package/dist/core/source/resolvers.d.ts +45 -0
- package/dist/core/source/resolvers.js +9 -0
- package/dist/core/source/types.d.ts +211 -0
- package/dist/core/source/types.js +0 -0
- package/dist/core/source/validate.d.ts +91 -0
- package/dist/core/source/validate.js +62 -0
- package/dist/core/source/workflow-source.d.ts +43 -0
- package/dist/core/source/workflow-source.js +16 -0
- package/dist/core/types/checkpoint.d.ts +14 -0
- package/dist/core/types/schedules.d.ts +52 -1
- package/dist/core/types/state.d.ts +16 -0
- package/dist/core/types/workflow-registries.d.ts +7 -0
- package/dist/core/types/workflow-registry.d.ts +12 -0
- package/dist/core/versioning.js +2 -0
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +12 -1
- package/dist/core/worker-execution-strategy.d.ts +1 -0
- package/dist/core/worker-execution-strategy.js +13 -1
- package/dist/core/worker-fault-handling.d.ts +10 -0
- package/dist/core/worker-fault-handling.js +1 -0
- package/dist/core/worker-inbound-message.d.ts +1 -0
- package/dist/core/worker-inbound-message.js +1 -0
- package/dist/core/worker-protocol-guard.js +4 -0
- package/dist/core/worker-protocol.d.ts +7 -0
- package/dist/core/worker-protocol.js +2 -1
- package/dist/core/worker-turn-watchdog.d.ts +8 -1
- package/dist/core/worker-turn-watchdog.js +3 -2
- package/dist/diagnostics/format.js +5 -0
- package/dist/diagnostics/types.d.ts +24 -0
- package/dist/diagnostics/version-check.js +8 -2
- package/dist/http.js +2 -2
- package/dist/index.d.ts +25 -4
- package/dist/index.js +57 -0
- package/dist/indexeddb.js +1 -1
- package/dist/json-schema.js +3 -3
- package/dist/mcp/resources.js +2 -0
- package/dist/runtime/portable.d.ts +9 -1
- package/dist/server/fault-to-json-rpc.js +4 -1
- package/dist/server/handler/auth-context-principal.js +4 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/json-rpc-http.js +2 -0
- package/dist/server/json-rpc-websocket.js +6 -4
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
- package/dist/server/operation-catalog/types.d.ts +17 -0
- package/dist/server/operation-fault.d.ts +5 -0
- package/dist/server/operation-fault.js +4 -1
- package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
- package/dist/server/operations/activate-workflow-revision.js +69 -0
- package/dist/server/operations/create-schedule.d.ts +2 -0
- package/dist/server/operations/create-schedule.js +10 -6
- package/dist/server/operations/fleet-events-subscription.js +1 -1
- package/dist/server/operations/fork-workflow.js +1 -1
- package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
- package/dist/server/operations/get-active-workflow-revision.js +46 -0
- package/dist/server/operations/get-catalog-diagnostics.d.ts +113 -0
- package/dist/server/operations/get-catalog-diagnostics.js +65 -0
- package/dist/server/operations/get-registry.js +17 -4
- package/dist/server/operations/get-task-detail-schema.d.ts +8 -0
- package/dist/server/operations/get-task-detail-schema.js +1 -0
- package/dist/server/operations/get-task-detail.d.ts +8 -0
- package/dist/server/operations/get-task-detail.js +1 -0
- package/dist/server/operations/get-task-diagnostics.d.ts +4 -4
- package/dist/server/operations/get-workflow-revision.d.ts +25 -0
- package/dist/server/operations/get-workflow-revision.js +50 -0
- package/dist/server/operations/install-workflow-revision.d.ts +27 -0
- package/dist/server/operations/install-workflow-revision.js +46 -0
- package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
- package/dist/server/operations/list-workflow-revisions.js +40 -0
- package/dist/server/operations/preload-workflow-revision.d.ts +28 -0
- package/dist/server/operations/preload-workflow-revision.js +60 -0
- package/dist/server/operations/schedule-faults.d.ts +1 -0
- package/dist/server/operations/schedule-faults.js +32 -4
- package/dist/server/operations/schedule-rest-body.d.ts +1 -0
- package/dist/server/operations/schedule-rest-body.js +2 -1
- package/dist/server/operations/start-or-signal-workflow.js +1 -1
- package/dist/server/operations/start-workflow.js +1 -1
- package/dist/server/operations/static-registrations.js +42 -0
- package/dist/server/operations/storage.js +2 -2
- package/dist/server/operations/submit-review-decision.js +1 -1
- package/dist/server/operations/update-schedule.d.ts +2 -0
- package/dist/server/operations/update-schedule.js +4 -2
- package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
- package/dist/server/operations/workflow-catalog-operation-helpers.js +162 -0
- package/dist/server/runtime/task-dispatch-envelope.d.ts +14 -0
- package/dist/server/runtime/task-dispatch-envelope.js +32 -0
- package/dist/server/runtime/task-dispatch-revision.d.ts +29 -0
- package/dist/server/runtime/task-dispatch-revision.js +13 -0
- package/dist/server/runtime/task-dispatch.js +12 -37
- package/dist/server/runtime/task-ledger-recovery.js +1 -1
- package/dist/server/runtime/task-ledger-runtime.d.ts +14 -2
- package/dist/server/runtime/task-ledger-runtime.js +5 -3
- package/dist/server/runtime/task-polling.js +9 -3
- package/dist/server/runtime/task-reconciliation.js +2 -1
- package/dist/server/runtime/websocket-upgrade.js +2 -0
- package/dist/server/runtime/websocket-worker.js +9 -0
- package/dist/server/task-ledger-codec.d.ts +9 -0
- package/dist/server/task-ledger-codec.js +4 -1
- package/dist/server/task-ledger-transition-helpers.js +1 -0
- package/dist/server/task-ledger-types.d.ts +9 -0
- package/dist/server/task-ledger.d.ts +1 -1
- package/dist/server/task-ledger.js +2 -1
- package/dist/server/task-queue-types.d.ts +2 -0
- package/dist/storage/bun-sql.js +51 -6
- package/dist/storage/catalog-keys.d.ts +64 -0
- package/dist/storage/catalog-keys.js +8 -0
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/derived-operations.js +1 -1
- package/dist/storage/index.d.ts +28 -1
- package/dist/storage/interface.d.ts +28 -1
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-encoding.d.ts +15 -0
- package/dist/storage/key-encoding.js +3 -0
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +16 -0
- package/dist/storage/lmdb.d.ts +54 -1
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/mailbox-keys.d.ts +80 -0
- package/dist/storage/mailbox-keys.js +14 -0
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +2 -2
- package/dist/storage/node-sqlite-loader.d.ts +1 -1
- package/dist/storage/node-sqlite.js +51 -6
- package/dist/storage/outbox-keys.d.ts +77 -0
- package/dist/storage/outbox-keys.js +14 -0
- package/dist/storage/postgres.js +2 -2
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +6 -0
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
- package/dist/worker/manifest/registry-contract-builder.js +40 -31
- package/dist/worker/protocol-messages.d.ts +17 -0
- package/dist/worker/protocol-schemas.d.ts +32 -0
- package/dist/worker/protocol-schemas.js +7 -3
- package/dist/worker/protocol-task-result.js +35 -3
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/registry/types.d.ts +2 -0
- package/dist/worker/registry.d.ts +1 -1
- package/dist/worker/registry.js +3 -1
- package/dist/workers/workflow-runner.d.ts +9 -0
- package/dist/workers/workflow-runner.js +9 -2
- package/dist/workers/workflow-worker-entry.js +9 -4
- package/package.json +2 -2
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical, normalized workflow contract vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* A `WorkflowContract` is the single normalized representation that feeds
|
|
5
|
+
* both TypeScript code generation (`weft codegen`) and `contractHash()` — the
|
|
6
|
+
* same data, described once, rather than two independent derivations that
|
|
7
|
+
* could silently drift apart. `WorkflowRevisionManifest` pairs that contract
|
|
8
|
+
* with the two identity questions a consumer asks about a workflow revision:
|
|
9
|
+
*
|
|
10
|
+
* | Field | Question answered | Stability |
|
|
11
|
+
* | -------------- | ----------------------------------------------------- | ----------------------------- |
|
|
12
|
+
* | `contractHash` | Which public payload contract does this revision use? | Deterministic, payload-only |
|
|
13
|
+
* | `revision` | Which contract-metadata identity (name, version, docs) is this? | Deterministic or author-set |
|
|
14
|
+
*
|
|
15
|
+
* `contractHash` deliberately excludes `name`, `workflowVersion`,
|
|
16
|
+
* `description`, and `tags` — those identify *which* workflow and *how it is
|
|
17
|
+
* documented*, not *what callers may send and expect back*. `revision` is the
|
|
18
|
+
* broader identity: it changes on a documentation edit even when the payload
|
|
19
|
+
* contract does not, which is what lets a caller detect "the same contract,
|
|
20
|
+
* redeployed" versus "a genuinely different definition was loaded."
|
|
21
|
+
*
|
|
22
|
+
* @module core/contract/types
|
|
23
|
+
*/
|
|
24
|
+
import type { DefinitionSchema } from '../types/definition-schema.ts';
|
|
25
|
+
/**
|
|
26
|
+
* Domain separator folded into every `contractHash()`/`deriveWorkflowRevision()`
|
|
27
|
+
* digest. Bumping this constant is how a future normalization change is
|
|
28
|
+
* guaranteed to produce a different hash rather than silently colliding with
|
|
29
|
+
* one computed under the old rules.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { WORKFLOW_CONTRACT_VERSION } from '@lostgradient/weft';
|
|
34
|
+
*
|
|
35
|
+
* console.log(WORKFLOW_CONTRACT_VERSION); // 1
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare const WORKFLOW_CONTRACT_VERSION = 1;
|
|
39
|
+
/**
|
|
40
|
+
* Normalized JSON Schema pair carried by one workflow signal, update, or
|
|
41
|
+
* query.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* import type { WorkflowMessageContract } from '@lostgradient/weft';
|
|
46
|
+
*
|
|
47
|
+
* const approval: WorkflowMessageContract = {
|
|
48
|
+
* inputSchema: { type: 'object', properties: { approved: { type: 'boolean' } } },
|
|
49
|
+
* };
|
|
50
|
+
* console.log(approval.inputSchema?.['type']);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export type WorkflowMessageContract = Readonly<{
|
|
54
|
+
/** Normalized JSON Schema describing accepted input, when the message accepts one. */
|
|
55
|
+
inputSchema?: Record<string, unknown>;
|
|
56
|
+
/** Normalized JSON Schema describing the returned value, when the message returns one. */
|
|
57
|
+
outputSchema?: Record<string, unknown>;
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Normalized JSON Schema pair carried by one activity a workflow contract
|
|
61
|
+
* exposes.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import type { WorkflowActivityContract } from '@lostgradient/weft';
|
|
66
|
+
*
|
|
67
|
+
* const charge: WorkflowActivityContract = {
|
|
68
|
+
* inputSchema: { type: 'object', properties: { amount: { type: 'number' } } },
|
|
69
|
+
* outputSchema: { type: 'object', properties: { id: { type: 'string' } } },
|
|
70
|
+
* };
|
|
71
|
+
* console.log(charge.inputSchema?.['type']);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export type WorkflowActivityContract = Readonly<{
|
|
75
|
+
/** Normalized JSON Schema describing accepted input, when the activity accepts one. */
|
|
76
|
+
inputSchema?: Record<string, unknown>;
|
|
77
|
+
/** Normalized JSON Schema describing the returned value, when the activity returns one. */
|
|
78
|
+
outputSchema?: Record<string, unknown>;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Canonical, normalized representation of one workflow's public contract —
|
|
82
|
+
* everything callers may send it and expect back, plus enough identity
|
|
83
|
+
* metadata (`name`, `workflowVersion`, `description`, `tags`) to describe
|
|
84
|
+
* which workflow this is. This is the single input to both TypeScript
|
|
85
|
+
* emission and `contractHash()`.
|
|
86
|
+
*
|
|
87
|
+
* Every open-ended record (`signals`, `updates`, `queries`, `activities`) is
|
|
88
|
+
* omitted entirely rather than present-but-empty, matching the registry
|
|
89
|
+
* snapshot's "absent fields omitted, never `null` or `{}`" convention — see
|
|
90
|
+
* {@link normalizeWorkflowContract}.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* import type { WorkflowContract } from '@lostgradient/weft';
|
|
95
|
+
*
|
|
96
|
+
* const checkout: WorkflowContract = {
|
|
97
|
+
* name: 'checkout',
|
|
98
|
+
* workflowVersion: '2.1.0',
|
|
99
|
+
* inputSchema: { type: 'object', properties: { cartId: { type: 'string' } } },
|
|
100
|
+
* activities: {
|
|
101
|
+
* charge: { inputSchema: { type: 'object', properties: { amount: { type: 'number' } } } },
|
|
102
|
+
* },
|
|
103
|
+
* };
|
|
104
|
+
* console.log(checkout.name);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export type WorkflowContract = Readonly<{
|
|
108
|
+
/** Wire-safe workflow name. */
|
|
109
|
+
name: string;
|
|
110
|
+
/** Semantic replay-compatibility boundary declared by the workflow author. */
|
|
111
|
+
workflowVersion: string;
|
|
112
|
+
/** User-facing description. Excluded from `contractHash()`; included in `revision`. */
|
|
113
|
+
description?: string;
|
|
114
|
+
/** User-facing grouping tags. Excluded from `contractHash()`; included in `revision`. */
|
|
115
|
+
tags?: ReadonlyArray<string>;
|
|
116
|
+
/** Normalized JSON Schema describing accepted workflow input, when declared. */
|
|
117
|
+
inputSchema?: Record<string, unknown>;
|
|
118
|
+
/** Normalized JSON Schema describing the workflow result, when declared. */
|
|
119
|
+
outputSchema?: Record<string, unknown>;
|
|
120
|
+
/** Signal contracts keyed by canonical signal name. */
|
|
121
|
+
signals?: Readonly<Record<string, WorkflowMessageContract>>;
|
|
122
|
+
/** Update contracts keyed by canonical update name. */
|
|
123
|
+
updates?: Readonly<Record<string, WorkflowMessageContract>>;
|
|
124
|
+
/** Query contracts keyed by canonical query name. */
|
|
125
|
+
queries?: Readonly<Record<string, WorkflowMessageContract>>;
|
|
126
|
+
/** Activity contracts keyed by canonical activity name. */
|
|
127
|
+
activities?: Readonly<Record<string, WorkflowActivityContract>>;
|
|
128
|
+
/** Contract of the workflow's definition-level finalizer activity, when declared. */
|
|
129
|
+
finalizer?: WorkflowActivityContract;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Structural shape one signal, update, or query source must satisfy for
|
|
133
|
+
* {@link buildWorkflowContract} to convert it. Deliberately narrower than
|
|
134
|
+
* `SignalDefinition`/`UpdateDefinition`/`QueryDefinition` — only the schema
|
|
135
|
+
* metadata those conversions need — so any of the three handle types (and
|
|
136
|
+
* any structurally equivalent value) satisfies it without a cast.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* import { signal } from '@lostgradient/weft';
|
|
141
|
+
* import type { WorkflowContractMessageSource } from '@lostgradient/weft';
|
|
142
|
+
*
|
|
143
|
+
* const approval = signal('approval');
|
|
144
|
+
* const source: WorkflowContractMessageSource = approval;
|
|
145
|
+
* console.log(source.inputSchema === undefined);
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export interface WorkflowContractMessageSource {
|
|
149
|
+
/**
|
|
150
|
+
* The message's own wire name, as recorded by `signal()`/`update()`/`query()`
|
|
151
|
+
* and used by `normalizeMessageDefinitions()` (`core/engine/registration.ts`)
|
|
152
|
+
* to key the registered message — not necessarily the JS object key the
|
|
153
|
+
* caller used in `.signals({...})`/`.updates({...})`/`.queries({...})`,
|
|
154
|
+
* which may alias a different local name. {@link buildWorkflowContract}
|
|
155
|
+
* keys `WorkflowContract.signals`/`updates`/`queries` by this field so the
|
|
156
|
+
* built contract matches what the registry and codegen actually expose.
|
|
157
|
+
*/
|
|
158
|
+
readonly name: string;
|
|
159
|
+
readonly inputSchema?: DefinitionSchema;
|
|
160
|
+
readonly outputSchema?: DefinitionSchema;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Structural shape one activity or finalizer source must satisfy for
|
|
164
|
+
* {@link buildWorkflowContract} to convert it. Requires `name` — shared with
|
|
165
|
+
* every real activity source type — specifically so a `WorkflowDefinition`'s
|
|
166
|
+
* `finalizer` field (declared as the narrower `AnyActivityDefinition`, which
|
|
167
|
+
* does not itself declare `inputSchema`/`outputSchema`) remains structurally
|
|
168
|
+
* assignable here: TypeScript's weak-type check requires at least one
|
|
169
|
+
* property in common between source and target when every target property is
|
|
170
|
+
* optional, and `name` is that shared property.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { activity } from '@lostgradient/weft';
|
|
175
|
+
* import type { WorkflowContractActivitySource } from '@lostgradient/weft';
|
|
176
|
+
*
|
|
177
|
+
* const charge = activity({ name: 'charge', execute: async (input: number) => input });
|
|
178
|
+
* const source: WorkflowContractActivitySource = charge;
|
|
179
|
+
* console.log(source.name);
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export interface WorkflowContractActivitySource {
|
|
183
|
+
readonly name: string;
|
|
184
|
+
readonly inputSchema?: DefinitionSchema;
|
|
185
|
+
readonly outputSchema?: DefinitionSchema;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Authoring-time input accepted by {@link buildWorkflowContract} — the
|
|
189
|
+
* narrowest structural shape that both `WorkflowDefinition` and
|
|
190
|
+
* `BuiltWorkflowDefinition` already satisfy, so neither type is imported here
|
|
191
|
+
* and no coupling is introduced between this module and the workflow builder.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* import { workflow } from '@lostgradient/weft';
|
|
196
|
+
* import type { WorkflowContractSource } from '@lostgradient/weft';
|
|
197
|
+
*
|
|
198
|
+
* const greet = workflow({ name: 'greet', version: '1.0.0' }).execute(
|
|
199
|
+
* async function* (_ctx, input: string) {
|
|
200
|
+
* return `hello ${input}`;
|
|
201
|
+
* },
|
|
202
|
+
* );
|
|
203
|
+
* const source: WorkflowContractSource = greet;
|
|
204
|
+
* console.log(source.name);
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
export interface WorkflowContractSource {
|
|
208
|
+
readonly name: string;
|
|
209
|
+
readonly version?: string;
|
|
210
|
+
readonly description?: string;
|
|
211
|
+
readonly tags?: ReadonlyArray<string>;
|
|
212
|
+
readonly inputSchema?: DefinitionSchema;
|
|
213
|
+
readonly outputSchema?: DefinitionSchema;
|
|
214
|
+
readonly signals?: Readonly<Record<string, WorkflowContractMessageSource>>;
|
|
215
|
+
readonly updates?: Readonly<Record<string, WorkflowContractMessageSource>>;
|
|
216
|
+
readonly queries?: Readonly<Record<string, WorkflowContractMessageSource>>;
|
|
217
|
+
readonly activities?: Readonly<Record<string, WorkflowContractActivitySource>>;
|
|
218
|
+
readonly finalizer?: WorkflowContractActivitySource;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Current workflow revision manifest schema version. An unknown value is
|
|
222
|
+
* rejected by {@link parseWorkflowRevisionManifest} before any other field is
|
|
223
|
+
* read, the same "reject rather than best-effort parse" contract
|
|
224
|
+
* `WORKER_MANIFEST_VERSION` uses.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* import { WORKFLOW_REVISION_MANIFEST_VERSION } from '@lostgradient/weft';
|
|
229
|
+
*
|
|
230
|
+
* console.log(WORKFLOW_REVISION_MANIFEST_VERSION); // 1
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export declare const WORKFLOW_REVISION_MANIFEST_VERSION = 1;
|
|
234
|
+
/**
|
|
235
|
+
* A workflow contract paired with its two identity answers: the
|
|
236
|
+
* payload-only `contractHash` and the broader `revision`.
|
|
237
|
+
*
|
|
238
|
+
* `revision` is an opaque label: content-derived by {@link deriveWorkflowRevision}
|
|
239
|
+
* by default, or explicitly supplied. {@link parseWorkflowRevisionManifest}
|
|
240
|
+
* recomputes and checks `contractHash` on every parse, but never recomputes
|
|
241
|
+
* `revision` — an explicitly supplied revision is a caller assertion, not a
|
|
242
|
+
* value this module can verify.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* import { WORKFLOW_REVISION_MANIFEST_VERSION, buildWorkflowContract } from '@lostgradient/weft';
|
|
247
|
+
* import type { WorkflowRevisionManifest } from '@lostgradient/weft';
|
|
248
|
+
*
|
|
249
|
+
* const contract = buildWorkflowContract({ name: 'checkout', version: '2.1.0' });
|
|
250
|
+
* const manifest: WorkflowRevisionManifest = {
|
|
251
|
+
* manifestVersion: WORKFLOW_REVISION_MANIFEST_VERSION,
|
|
252
|
+
* name: contract.name,
|
|
253
|
+
* workflowVersion: contract.workflowVersion,
|
|
254
|
+
* revision: 'sha256:placeholder',
|
|
255
|
+
* contractHash: 'sha256:placeholder',
|
|
256
|
+
* contract,
|
|
257
|
+
* };
|
|
258
|
+
* console.log(manifest.name);
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export type WorkflowRevisionManifest = Readonly<{
|
|
262
|
+
/** Manifest schema version; unknown values are rejected, not tolerated. */
|
|
263
|
+
manifestVersion: typeof WORKFLOW_REVISION_MANIFEST_VERSION;
|
|
264
|
+
/** Wire-safe workflow name; must equal `contract.name`. */
|
|
265
|
+
name: string;
|
|
266
|
+
/** Semantic replay-compatibility boundary; must equal `contract.workflowVersion`. */
|
|
267
|
+
workflowVersion: string;
|
|
268
|
+
/** Content-derived or explicitly supplied opaque revision identity. */
|
|
269
|
+
revision: string;
|
|
270
|
+
/** Deterministic payload-only contract identity, verified on every parse. */
|
|
271
|
+
contractHash: string;
|
|
272
|
+
/** The normalized workflow contract this manifest describes. */
|
|
273
|
+
contract: WorkflowContract;
|
|
274
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const WORKFLOW_CONTRACT_VERSION = 1, WORKFLOW_REVISION_MANIFEST_VERSION = 1;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { ActivityResolutionError } from "./errors.js";
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
if (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
const globalFn = internals.activityRegistry.resolve(activityName);
|
|
12
|
-
if (globalFn)
|
|
13
|
-
return { fn: globalFn, workflowType };
|
|
14
|
-
return;
|
|
2
|
+
function resolveViaKnownIdentity(internals, identity, activityName) {
|
|
3
|
+
const eagerFn = internals.activityRegistriesByWorkflow.get(identity.type)?.resolve(activityName);
|
|
4
|
+
if (eagerFn)
|
|
5
|
+
return { fn: eagerFn, workflowType: identity.type };
|
|
6
|
+
if (identity.revision !== void 0) {
|
|
7
|
+
const revisionFn = internals.sources.resolved.get(identity.type)?.get(identity.revision)?.activityRegistry.resolve(activityName);
|
|
8
|
+
if (revisionFn)
|
|
9
|
+
return { fn: revisionFn, workflowType: identity.type };
|
|
15
10
|
}
|
|
16
11
|
const globalFn = internals.activityRegistry.resolve(activityName);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
return globalFn ? { fn: globalFn, workflowType: identity.type } : void 0;
|
|
13
|
+
}
|
|
14
|
+
function resolveActivityViaRegistries(internals, workflowId, activityName) {
|
|
15
|
+
const identity = internals.workflowTypeByWorkflowId.get(workflowId);
|
|
16
|
+
if (identity !== void 0)
|
|
17
|
+
return resolveViaKnownIdentity(internals, identity, activityName);
|
|
18
|
+
const globalFn = internals.activityRegistry.resolve(activityName);
|
|
19
|
+
return globalFn ? { fn: globalFn, workflowType: "<unknown>" } : void 0;
|
|
20
20
|
}
|
|
21
21
|
export function getActivityFunctionWithMetadata(internals, workflowId, operation) {
|
|
22
22
|
const resolved = resolveActivityViaRegistries(internals, workflowId, operation.activityName);
|
|
@@ -32,6 +32,6 @@ export function resolveActivityFunction(internals, workflowId, operation) {
|
|
|
32
32
|
return resolved.fn;
|
|
33
33
|
if (operation.fn)
|
|
34
34
|
return operation.fn;
|
|
35
|
-
const workflowType = internals.workflowTypeByWorkflowId.get(workflowId) ?? "<unknown>";
|
|
35
|
+
const workflowType = internals.workflowTypeByWorkflowId.get(workflowId)?.type ?? "<unknown>";
|
|
36
36
|
throw new ActivityResolutionError(workflowType, operation.activityName);
|
|
37
37
|
}
|
|
@@ -12,15 +12,16 @@ import { asyncActivityWorkflowPrefix } from "./async-activity-records.js";
|
|
|
12
12
|
import { forgetCommittedCheckpointBytes } from "./checkpoint-commit-snapshots.js";
|
|
13
13
|
import { commitFencedEngineWrite } from "./fenced-write.js";
|
|
14
14
|
import { streamWorkflowStates } from "./listing.js";
|
|
15
|
+
import {
|
|
16
|
+
forEachResolvedDynamicRetentionPolicy,
|
|
17
|
+
hasUnresolvedDynamicSourceCandidate
|
|
18
|
+
} from "./registration.js";
|
|
15
19
|
import { decodeScheduleRunMetadata } from "./schedule-run-metadata.js";
|
|
16
20
|
import { createTerminalCleanupTimerId } from "./state-utilities.js";
|
|
17
21
|
import { buildExternalTerminalRotationFragment } from "./storage-io.js";
|
|
18
|
-
import {
|
|
19
|
-
decodeWorkflowState,
|
|
20
|
-
isTerminalWorkflowStatus,
|
|
21
|
-
resolveRetentionForStatus
|
|
22
|
-
} from "./validation.js";
|
|
22
|
+
import { decodeWorkflowState, isTerminalWorkflowStatus } from "./validation.js";
|
|
23
23
|
import { buildWorkflowVisibilityIndexTransition } from "./workflow-indexes.js";
|
|
24
|
+
import { getWorkflowRetentionDeadline } from "./workflow-retention-deadline.js";
|
|
24
25
|
export const TERMINAL_CLEANUP_DELAY_MS = 60000;
|
|
25
26
|
export async function purgeInternal(internals, filter, parameters, cleanupWaiters) {
|
|
26
27
|
const { effectiveLimit, manualOffset } = resolvePurgeWindow(internals, filter, parameters.limit);
|
|
@@ -59,16 +60,17 @@ function getMinimumRetentionMs(internals) {
|
|
|
59
60
|
considerRetentionPolicy(internals.options.retention);
|
|
60
61
|
for (const registration of internals.registrations.values())
|
|
61
62
|
considerRetentionPolicy(registration.retention);
|
|
63
|
+
forEachResolvedDynamicRetentionPolicy(internals, considerRetentionPolicy);
|
|
62
64
|
return minimumRetentionMs;
|
|
63
65
|
}
|
|
64
66
|
async function* streamExpiredRetentionWorkflowStates(internals, now) {
|
|
65
|
-
const minimumRetentionMs = getMinimumRetentionMs(internals);
|
|
66
|
-
if (minimumRetentionMs === null)
|
|
67
|
+
const untrustworthyBound = hasUnresolvedDynamicSourceCandidate(internals), minimumRetentionMs = untrustworthyBound ? null : getMinimumRetentionMs(internals);
|
|
68
|
+
if (!untrustworthyBound && minimumRetentionMs === null)
|
|
67
69
|
return;
|
|
68
|
-
const terminalWorkflowPrefix = KEYS.terminalWorkflowPrefix(),
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
const terminalWorkflowPrefix = KEYS.terminalWorkflowPrefix(), scanOptions = minimumRetentionMs === null ? {} : {
|
|
71
|
+
lte: `${terminalWorkflowPrefix}${String(now - minimumRetentionMs).padStart(16, "0")}:\xFF`
|
|
72
|
+
};
|
|
73
|
+
for await (const [key] of internals.storage.scan(terminalWorkflowPrefix, scanOptions)) {
|
|
72
74
|
const encodedWorkflowId = key.slice(key.lastIndexOf(":") + 1), workflowId = tryDecodeStorageKeyComponent(encodedWorkflowId);
|
|
73
75
|
if (workflowId === null)
|
|
74
76
|
continue;
|
|
@@ -121,17 +123,9 @@ async function shouldPurgeWorkflowState(internals, state, expiredOnly, now) {
|
|
|
121
123
|
return !1;
|
|
122
124
|
if (!expiredOnly)
|
|
123
125
|
return !0;
|
|
124
|
-
const deadline = getWorkflowRetentionDeadline(internals, state);
|
|
126
|
+
const deadline = await getWorkflowRetentionDeadline(internals, state);
|
|
125
127
|
return deadline !== null && deadline <= now;
|
|
126
128
|
}
|
|
127
|
-
function getWorkflowRetentionDeadline(internals, state) {
|
|
128
|
-
if (!isTerminalWorkflowStatus(state.status))
|
|
129
|
-
return null;
|
|
130
|
-
const policy = internals.registrations.get(state.type)?.retention ?? internals.options.retention, retentionMs = resolveRetentionForStatus(policy, state.status);
|
|
131
|
-
if (retentionMs === void 0)
|
|
132
|
-
return null;
|
|
133
|
-
return state.updatedAt + retentionMs;
|
|
134
|
-
}
|
|
135
129
|
export async function purgeWorkflow(internals, state, cleanupWaiters) {
|
|
136
130
|
const deleteOperations = await collectWorkflowPurgeDeleteOperations(internals, state), rotation = await buildExternalTerminalRotationFragment(internals, state.id), operations = [...deleteOperations, ...rotation.operations];
|
|
137
131
|
await commitFencedEngineWrite(internals, null, operations, rotation.conditions, () => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BulkOperationDryRunResult, BulkOperationOptions, BulkRetryFailedResult, ListFilter } from '../types.ts';
|
|
2
|
+
import type { EngineInternals } from './internals.ts';
|
|
3
|
+
/**
|
|
4
|
+
* `bulkOperations.ts`'s `retryFailedAll()` implementation, split into its
|
|
5
|
+
* own module (with the rest of the retry-failed cluster below) to keep
|
|
6
|
+
* `bulk-operations.ts` under the 800-line implementation-file ceiling —
|
|
7
|
+
* the same reason `bulk-operations-purge.ts` was split out earlier.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runBulkFailedWorkflowRetry(internals: EngineInternals, filter: ListFilter, options?: BulkOperationOptions): Promise<BulkRetryFailedResult | BulkOperationDryRunResult>;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEYS,
|
|
3
|
+
requireStorageCapability
|
|
4
|
+
} from "../../storage/interface.js";
|
|
5
|
+
import { assertScopedBulkWorkflowFilter } from "../bulk-workflow-filter.js";
|
|
6
|
+
import { deserializeCheckpoint } from "../checkpoint.js";
|
|
7
|
+
import { decode, encode } from "../codec.js";
|
|
8
|
+
import { buildTimerBatchOperations } from "../scheduler.js";
|
|
9
|
+
import { buildIndexOperations } from "../search-attributes.js";
|
|
10
|
+
import { buildTerminalWorkflowIndexOperations } from "./attributes-tags.js";
|
|
11
|
+
import {
|
|
12
|
+
buildActionableBulkWorkflowFilter,
|
|
13
|
+
normalizeBulkOperationOptions,
|
|
14
|
+
prepareBulkOperation,
|
|
15
|
+
resolveBulkOperationConcurrency,
|
|
16
|
+
runBulkWorkflowPool,
|
|
17
|
+
shouldPersistBulkAudit,
|
|
18
|
+
toBulkOperationError,
|
|
19
|
+
validateBulkConfirmation,
|
|
20
|
+
withBulkAuditEvent
|
|
21
|
+
} from "./bulk-operations-shared.js";
|
|
22
|
+
import { resolveExecutableRegistrationForRetry } from "./dynamic-source-execution.js";
|
|
23
|
+
import { commitFencedEngineWriteAllowingPreconditionFailure } from "./fenced-write.js";
|
|
24
|
+
import { buildCatalogEntryRevisionCondition } from "./lifecycle/start-commit.js";
|
|
25
|
+
import { createTerminalCleanupTimerId } from "./state-utilities.js";
|
|
26
|
+
import { loadWorkflowState, runSerializedWorkflowStateWrite } from "./storage-io.js";
|
|
27
|
+
import { decodeWorkflowState } from "./validation.js";
|
|
28
|
+
import {
|
|
29
|
+
commitWithWorkflowClaimFold,
|
|
30
|
+
prepareWorkflowClaimFold,
|
|
31
|
+
throwWorkflowClaimUnavailable
|
|
32
|
+
} from "./workflow-claim-fold.js";
|
|
33
|
+
import { buildWorkflowConcurrencyStartOperations } from "./workflow-concurrency.js";
|
|
34
|
+
import { buildWorkflowVisibilityIndexTransition } from "./workflow-indexes.js";
|
|
35
|
+
const FAILED_WORKFLOW_STATUSES = ["failed"], CHECKPOINT_RETRY_CONCURRENCY_ADMISSION_MAX_ATTEMPTS = 5;
|
|
36
|
+
export async function runBulkFailedWorkflowRetry(internals, filter, options = {}) {
|
|
37
|
+
options = normalizeBulkOperationOptions(options);
|
|
38
|
+
assertScopedBulkWorkflowFilter(filter);
|
|
39
|
+
const actionableFilter = buildActionableBulkWorkflowFilter(internals, filter, FAILED_WORKFLOW_STATUSES), preparation = await prepareBulkOperation(internals, "retry-failed", actionableFilter, filter, {}, options);
|
|
40
|
+
if (options.dryRun === !0)
|
|
41
|
+
return preparation.preview;
|
|
42
|
+
validateBulkConfirmation(options, preparation);
|
|
43
|
+
const bulkConcurrency = resolveBulkOperationConcurrency(options);
|
|
44
|
+
let retried = 0;
|
|
45
|
+
const errors = [], retryResults = await runBulkWorkflowPool(preparation.workflowIds, bulkConcurrency, async (workflowId) => {
|
|
46
|
+
await retryFailedWorkflow(internals, workflowId);
|
|
47
|
+
return { status: "retried" };
|
|
48
|
+
});
|
|
49
|
+
for (const retryResult of retryResults) {
|
|
50
|
+
if (retryResult.status === "rejected") {
|
|
51
|
+
errors.push(toBulkOperationError(internals, retryResult.item, retryResult.reason));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
retried += 1;
|
|
55
|
+
}
|
|
56
|
+
const result = { retried, failed: errors.length, errors };
|
|
57
|
+
if (!shouldPersistBulkAudit(options))
|
|
58
|
+
return result;
|
|
59
|
+
return withBulkAuditEvent(internals, preparation, options, result, retried);
|
|
60
|
+
}
|
|
61
|
+
async function retryFailedWorkflow(internals, workflowId) {
|
|
62
|
+
const state = await loadWorkflowState(internals, workflowId);
|
|
63
|
+
if (state === null)
|
|
64
|
+
throw Error("Workflow no longer exists");
|
|
65
|
+
if (state.status !== "failed")
|
|
66
|
+
throw Error(`Workflow is ${state.status}, not failed`);
|
|
67
|
+
if (await internals.storage.get(KEYS.checkpoint(workflowId)) !== null) {
|
|
68
|
+
await reactivateFailedWorkflowFromCheckpoint(internals, state);
|
|
69
|
+
await internals.engine.resume(workflowId);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
await internals.engine.start(state.type, state.input, {
|
|
73
|
+
id: workflowId,
|
|
74
|
+
onTerminalConflict: "start-new",
|
|
75
|
+
...state.tags !== void 0 ? { tags: state.tags } : {}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function reactivateFailedWorkflowFromCheckpoint(internals, state) {
|
|
79
|
+
const reactivated = await runSerializedWorkflowStateWrite(internals, state.id, async () => reactivateFailedWorkflowFromCheckpointSerialized(internals, state.id));
|
|
80
|
+
if (reactivated.terminalCleanupTimerId !== void 0)
|
|
81
|
+
await internals.scheduler.cancel(reactivated.terminalCleanupTimerId, state.id);
|
|
82
|
+
}
|
|
83
|
+
async function reactivateFailedWorkflowFromCheckpointSerialized(internals, workflowId) {
|
|
84
|
+
let lastConcurrencyStateKey;
|
|
85
|
+
for (let attempt = 0;attempt < CHECKPOINT_RETRY_CONCURRENCY_ADMISSION_MAX_ATTEMPTS; attempt += 1) {
|
|
86
|
+
const { currentState, checkpoint } = await loadFailedWorkflowForReactivation(internals, workflowId), commit = await buildReactivationCommit(internals, workflowId, currentState, checkpoint);
|
|
87
|
+
lastConcurrencyStateKey = commit.concurrencyStateKey ?? lastConcurrencyStateKey;
|
|
88
|
+
if (await commitFailedWorkflowReactivation(internals, workflowId, commit.operations, commit.conditions))
|
|
89
|
+
return {
|
|
90
|
+
terminalCleanupTimerId: currentState.terminalCleanupToken === void 0 ? void 0 : createTerminalCleanupTimerId(!1, currentState.terminalCleanupToken)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
throw Error(`Workflow concurrency admission for "${lastConcurrencyStateKey ?? workflowId}" changed too many times while retrying failed workflow "${workflowId}"`);
|
|
94
|
+
}
|
|
95
|
+
async function loadFailedWorkflowForReactivation(internals, workflowId) {
|
|
96
|
+
const currentStateBytes = await internals.storage.get(KEYS.workflow(workflowId));
|
|
97
|
+
if (currentStateBytes === null)
|
|
98
|
+
throw Error("Workflow no longer exists");
|
|
99
|
+
const currentState = decodeWorkflowState(currentStateBytes);
|
|
100
|
+
if (currentState.status !== "failed")
|
|
101
|
+
throw Error(`Workflow is ${currentState.status}, not failed`);
|
|
102
|
+
const currentCheckpointBytes = await internals.storage.get(KEYS.checkpoint(workflowId));
|
|
103
|
+
if (currentCheckpointBytes === null)
|
|
104
|
+
throw Error("Checkpoint no longer exists");
|
|
105
|
+
return { currentState, checkpoint: deserializeCheckpoint(currentCheckpointBytes) };
|
|
106
|
+
}
|
|
107
|
+
async function buildReactivationCommit(internals, workflowId, currentState, checkpoint) {
|
|
108
|
+
const { entry: registration } = await resolveExecutableRegistrationForRetry(internals, currentState.type, currentState.revision, workflowId), catalogEntryCondition = currentState.revision === void 0 ? void 0 : await buildCatalogEntryRevisionCondition(internals, currentState.type, currentState.revision), concurrencyStartOperations = registration.concurrency === void 0 ? void 0 : await buildWorkflowConcurrencyStartOperations(internals, currentState.type, workflowId, currentState.input, registration.concurrency), reactivatedState = buildReactivatedWorkflowState(internals, currentState), currentAttributes = await loadSearchAttributes(internals, workflowId);
|
|
109
|
+
return {
|
|
110
|
+
operations: buildReactivationBatchOperations(workflowId, currentState, reactivatedState, checkpoint, currentAttributes, concurrencyStartOperations?.operations),
|
|
111
|
+
conditions: [
|
|
112
|
+
...concurrencyStartOperations?.conditions ?? [],
|
|
113
|
+
...catalogEntryCondition === void 0 ? [] : [catalogEntryCondition]
|
|
114
|
+
],
|
|
115
|
+
concurrencyStateKey: concurrencyStartOperations?.stateKey
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function buildReactivationBatchOperations(workflowId, currentState, reactivatedState, checkpoint, currentAttributes, concurrencyOperations) {
|
|
119
|
+
const deadlineOperations = reactivatedState.executionDeadline === void 0 ? [] : buildTimerBatchOperations({
|
|
120
|
+
id: `deadline:${workflowId}`,
|
|
121
|
+
workflowId,
|
|
122
|
+
fireAt: reactivatedState.executionDeadline,
|
|
123
|
+
kind: "execution-deadline"
|
|
124
|
+
});
|
|
125
|
+
return [
|
|
126
|
+
...buildTerminalWorkflowIndexOperations(currentState, reactivatedState),
|
|
127
|
+
{ type: "put", key: KEYS.workflow(workflowId), value: encode(reactivatedState) },
|
|
128
|
+
...buildWorkflowVisibilityIndexTransition(workflowId, currentState, reactivatedState).batchOps,
|
|
129
|
+
...buildRetrySearchAttributeOperations(workflowId, currentAttributes, checkpoint.searchAttributes),
|
|
130
|
+
...deadlineOperations,
|
|
131
|
+
...concurrencyOperations ?? []
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
async function commitFailedWorkflowReactivation(internals, workflowId, operations, conditions) {
|
|
135
|
+
const claimFold = await prepareWorkflowClaimFold(internals, workflowId);
|
|
136
|
+
if (claimFold === void 0) {
|
|
137
|
+
if (conditions.length > 0)
|
|
138
|
+
requireStorageCapability(internals.storage, "conditionalBatch", "retry failed workflow");
|
|
139
|
+
return commitFencedEngineWriteAllowingPreconditionFailure(internals, workflowId, operations, conditions);
|
|
140
|
+
}
|
|
141
|
+
const result = await commitWithWorkflowClaimFold(internals, claimFold, operations, conditions, "retry failed workflow claim acquisition");
|
|
142
|
+
if (result.status === "committed")
|
|
143
|
+
return !0;
|
|
144
|
+
return result.claimConflict ? throwWorkflowClaimUnavailable(internals, workflowId) : !1;
|
|
145
|
+
}
|
|
146
|
+
function buildReactivatedWorkflowState(internals, state) {
|
|
147
|
+
const reactivatedState = {
|
|
148
|
+
...state,
|
|
149
|
+
status: "running",
|
|
150
|
+
updatedAt: internals.options.getNow()
|
|
151
|
+
};
|
|
152
|
+
delete reactivatedState.error;
|
|
153
|
+
delete reactivatedState.errorStack;
|
|
154
|
+
delete reactivatedState.failureCategory;
|
|
155
|
+
delete reactivatedState.result;
|
|
156
|
+
delete reactivatedState.terminationReason;
|
|
157
|
+
delete reactivatedState.terminalCleanupToken;
|
|
158
|
+
return reactivatedState;
|
|
159
|
+
}
|
|
160
|
+
async function loadSearchAttributes(internals, workflowId) {
|
|
161
|
+
const attributeBytes = await internals.storage.get(KEYS.attribute(workflowId));
|
|
162
|
+
if (attributeBytes === null)
|
|
163
|
+
return {};
|
|
164
|
+
return decode(attributeBytes);
|
|
165
|
+
}
|
|
166
|
+
function buildRetrySearchAttributeOperations(workflowId, currentAttributes, checkpointAttributes) {
|
|
167
|
+
const operations = buildIndexOperations(workflowId, currentAttributes, checkpointAttributes);
|
|
168
|
+
if (Object.keys(checkpointAttributes).length === 0)
|
|
169
|
+
operations.push({ type: "delete", key: KEYS.attribute(workflowId) });
|
|
170
|
+
else
|
|
171
|
+
operations.push({
|
|
172
|
+
type: "put",
|
|
173
|
+
key: KEYS.attribute(workflowId),
|
|
174
|
+
value: encode(checkpointAttributes)
|
|
175
|
+
});
|
|
176
|
+
return operations;
|
|
177
|
+
}
|
|
@@ -2,6 +2,24 @@ import type { BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitO
|
|
|
2
2
|
import type { EngineInternals } from './internals.ts';
|
|
3
3
|
export declare const BULK_OPERATION_SAMPLE_LIMIT = 20;
|
|
4
4
|
export declare const DEFAULT_BULK_OPERATION_CONCURRENCY = 1;
|
|
5
|
+
export type BulkWorkflowPoolResult<TItem, TResult> = {
|
|
6
|
+
item: TItem;
|
|
7
|
+
status: 'fulfilled';
|
|
8
|
+
value: TResult;
|
|
9
|
+
} | {
|
|
10
|
+
item: TItem;
|
|
11
|
+
status: 'rejected';
|
|
12
|
+
reason: unknown;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Shared bounded-concurrency runner every bulk operation (cancel, retry,
|
|
16
|
+
* signal, delete) uses to drive its per-workflow work: runs `items` in
|
|
17
|
+
* fixed-size batches of `concurrencyLimit`, capturing each item's outcome
|
|
18
|
+
* rather than letting one rejection abort the batch (mirrors
|
|
19
|
+
* `Promise.allSettled`, but keyed back to the originating `item` so a
|
|
20
|
+
* caller can map a failure to the workflow it belongs to).
|
|
21
|
+
*/
|
|
22
|
+
export declare function runBulkWorkflowPool<TItem, TResult>(items: readonly TItem[], concurrencyLimit: number, operation: (item: TItem) => Promise<TResult>): Promise<BulkWorkflowPoolResult<TItem, TResult>[]>;
|
|
5
23
|
export type BulkWorkflowSnapshot = {
|
|
6
24
|
id: string;
|
|
7
25
|
type: string;
|
|
@@ -15,6 +15,20 @@ import { streamWorkflowStateBatches } from "./listing.js";
|
|
|
15
15
|
import { isTerminalWorkflowStatus } from "./validation.js";
|
|
16
16
|
export const BULK_OPERATION_SAMPLE_LIMIT = 20, DEFAULT_BULK_OPERATION_CONCURRENCY = 1;
|
|
17
17
|
const DEFAULT_BULK_OPERATION_PRINCIPAL = { method: "in-process" };
|
|
18
|
+
export async function runBulkWorkflowPool(items, concurrencyLimit, operation) {
|
|
19
|
+
const results = [];
|
|
20
|
+
for (let batchStart = 0;batchStart < items.length; batchStart += concurrencyLimit) {
|
|
21
|
+
const batchItems = items.slice(batchStart, batchStart + concurrencyLimit);
|
|
22
|
+
results.push(...await Promise.all(batchItems.map(async (item) => {
|
|
23
|
+
try {
|
|
24
|
+
return { item, status: "fulfilled", value: await operation(item) };
|
|
25
|
+
} catch (reason) {
|
|
26
|
+
return { item, status: "rejected", reason };
|
|
27
|
+
}
|
|
28
|
+
})));
|
|
29
|
+
}
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
18
32
|
export function buildActionableBulkWorkflowFilter(_internals, filter, actionableStatuses) {
|
|
19
33
|
const effectiveStatuses = (filter.status === void 0 ? actionableStatuses : Array.isArray(filter.status) ? filter.status : [filter.status]).filter((status) => actionableStatuses.includes(status));
|
|
20
34
|
if (effectiveStatuses.length === 0)
|