@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,189 @@
|
|
|
1
|
+
import { isRecord } from "../../worker/manifest/is-record.js";
|
|
2
|
+
import { utf8ByteLength } from "../../worker/manifest/utf8.js";
|
|
3
|
+
import {
|
|
4
|
+
workflowRevisionManifestFailure
|
|
5
|
+
} from "./failure.js";
|
|
6
|
+
import { contractHash } from "./hash.js";
|
|
7
|
+
import {
|
|
8
|
+
MAX_CONTRACT_IDENTIFIER_BYTES,
|
|
9
|
+
MAX_CONTRACT_MESSAGE_COUNT,
|
|
10
|
+
MAX_NORMALIZED_CONTRACT_BYTES
|
|
11
|
+
} from "./limits.js";
|
|
12
|
+
import { checkContractKey, parseContractRecord, parseSchemaPair } from "./manifest-parse-schema.js";
|
|
13
|
+
import { canonicalWorkflowContractJson, normalizeWorkflowContract } from "./normalize.js";
|
|
14
|
+
import { WORKFLOW_REVISION_MANIFEST_VERSION } from "./types.js";
|
|
15
|
+
function parseIdentifier(value, path) {
|
|
16
|
+
if (typeof value !== "string" || value.length === 0)
|
|
17
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a non-empty string", path);
|
|
18
|
+
const bytes = utf8ByteLength(value);
|
|
19
|
+
if (bytes > MAX_CONTRACT_IDENTIFIER_BYTES)
|
|
20
|
+
return workflowRevisionManifestFailure("identifier-too-long", `is ${bytes} bytes, exceeding the maximum identifier size of ${MAX_CONTRACT_IDENTIFIER_BYTES}`, path);
|
|
21
|
+
return { ok: !0, value };
|
|
22
|
+
}
|
|
23
|
+
function parseDescription(value, path) {
|
|
24
|
+
if (typeof value !== "string")
|
|
25
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a string", path);
|
|
26
|
+
return { ok: !0, value };
|
|
27
|
+
}
|
|
28
|
+
function parseTag(value, path) {
|
|
29
|
+
if (typeof value !== "string")
|
|
30
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a string", path);
|
|
31
|
+
return { ok: !0, value };
|
|
32
|
+
}
|
|
33
|
+
function parseTags(value, path) {
|
|
34
|
+
if (value === void 0)
|
|
35
|
+
return { ok: !0, value: void 0 };
|
|
36
|
+
if (!Array.isArray(value))
|
|
37
|
+
return workflowRevisionManifestFailure("invalid-field", "must be an array of strings", path);
|
|
38
|
+
if (value.length > MAX_CONTRACT_MESSAGE_COUNT)
|
|
39
|
+
return workflowRevisionManifestFailure("too-many-entries", `declares ${value.length} entries, exceeding the maximum of ${MAX_CONTRACT_MESSAGE_COUNT}`, path);
|
|
40
|
+
const tags = [];
|
|
41
|
+
let accumulatedBytes = 0;
|
|
42
|
+
for (const [index, entry] of value.entries()) {
|
|
43
|
+
const tag = parseTag(entry, `${path}[${index}]`);
|
|
44
|
+
if (!tag.ok)
|
|
45
|
+
return tag;
|
|
46
|
+
accumulatedBytes += utf8ByteLength(tag.value);
|
|
47
|
+
if (accumulatedBytes > MAX_NORMALIZED_CONTRACT_BYTES)
|
|
48
|
+
return workflowRevisionManifestFailure("manifest-too-large", `accumulated tag bytes exceed the maximum of ${MAX_NORMALIZED_CONTRACT_BYTES}`, path);
|
|
49
|
+
tags.push(tag.value);
|
|
50
|
+
}
|
|
51
|
+
return { ok: !0, value: tags.length === 0 ? void 0 : tags };
|
|
52
|
+
}
|
|
53
|
+
function parseContractIdentity(value, path) {
|
|
54
|
+
const name = parseIdentifier(value.name, `${path}.name`);
|
|
55
|
+
if (!name.ok)
|
|
56
|
+
return name;
|
|
57
|
+
const nameKeyFailure = checkContractKey(name.value, "workflow", `${path}.name`);
|
|
58
|
+
if (nameKeyFailure !== void 0)
|
|
59
|
+
return nameKeyFailure;
|
|
60
|
+
const workflowVersion = parseIdentifier(value.workflowVersion, `${path}.workflowVersion`);
|
|
61
|
+
if (!workflowVersion.ok)
|
|
62
|
+
return workflowVersion;
|
|
63
|
+
const identity = {
|
|
64
|
+
name: name.value,
|
|
65
|
+
workflowVersion: workflowVersion.value
|
|
66
|
+
};
|
|
67
|
+
if (value.description !== void 0) {
|
|
68
|
+
const description = parseDescription(value.description, `${path}.description`);
|
|
69
|
+
if (!description.ok)
|
|
70
|
+
return description;
|
|
71
|
+
identity.description = description.value;
|
|
72
|
+
}
|
|
73
|
+
const tags = parseTags(value.tags, `${path}.tags`);
|
|
74
|
+
if (!tags.ok)
|
|
75
|
+
return tags;
|
|
76
|
+
if (tags.value !== void 0)
|
|
77
|
+
identity.tags = tags.value;
|
|
78
|
+
return { ok: !0, value: identity };
|
|
79
|
+
}
|
|
80
|
+
const NAMED_RECORD_FIELDS = [
|
|
81
|
+
["signals", void 0],
|
|
82
|
+
["updates", void 0],
|
|
83
|
+
["queries", void 0],
|
|
84
|
+
["activities", "activity"]
|
|
85
|
+
];
|
|
86
|
+
function parseNamedRecordFields(value, path, collections) {
|
|
87
|
+
for (const [field, keyKind] of NAMED_RECORD_FIELDS) {
|
|
88
|
+
if (value[field] === void 0)
|
|
89
|
+
continue;
|
|
90
|
+
const parsed = parseContractRecord(value[field], `${path}.${field}`, keyKind);
|
|
91
|
+
if (!parsed.ok)
|
|
92
|
+
return parsed;
|
|
93
|
+
collections[field] = parsed.value;
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
function parseContractCollections(value, path) {
|
|
98
|
+
const collections = {};
|
|
99
|
+
if (value.inputSchema !== void 0 || value.outputSchema !== void 0) {
|
|
100
|
+
const pair = parseSchemaPair({ inputSchema: value.inputSchema, outputSchema: value.outputSchema }, path);
|
|
101
|
+
if (!pair.ok)
|
|
102
|
+
return pair;
|
|
103
|
+
if (pair.value.inputSchema !== void 0)
|
|
104
|
+
collections.inputSchema = pair.value.inputSchema;
|
|
105
|
+
if (pair.value.outputSchema !== void 0)
|
|
106
|
+
collections.outputSchema = pair.value.outputSchema;
|
|
107
|
+
}
|
|
108
|
+
const recordFailure = parseNamedRecordFields(value, path, collections);
|
|
109
|
+
if (recordFailure !== void 0)
|
|
110
|
+
return recordFailure;
|
|
111
|
+
if (value.finalizer !== void 0) {
|
|
112
|
+
const finalizer = parseSchemaPair(value.finalizer, `${path}.finalizer`);
|
|
113
|
+
if (!finalizer.ok)
|
|
114
|
+
return finalizer;
|
|
115
|
+
collections.finalizer = finalizer.value;
|
|
116
|
+
}
|
|
117
|
+
return { ok: !0, value: collections };
|
|
118
|
+
}
|
|
119
|
+
function parseContract(value, path) {
|
|
120
|
+
if (!isRecord(value))
|
|
121
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a JSON object", path);
|
|
122
|
+
const identity = parseContractIdentity(value, path);
|
|
123
|
+
if (!identity.ok)
|
|
124
|
+
return identity;
|
|
125
|
+
const collections = parseContractCollections(value, path);
|
|
126
|
+
if (!collections.ok)
|
|
127
|
+
return collections;
|
|
128
|
+
return { ok: !0, value: { ...identity.value, ...collections.value } };
|
|
129
|
+
}
|
|
130
|
+
const TOP_LEVEL_IDENTIFIER_FIELDS = [
|
|
131
|
+
["name", "manifest.name"],
|
|
132
|
+
["workflowVersion", "manifest.workflowVersion"],
|
|
133
|
+
["revision", "manifest.revision"],
|
|
134
|
+
["contractHash", "manifest.contractHash"]
|
|
135
|
+
];
|
|
136
|
+
function parseTopLevelIdentifiers(value) {
|
|
137
|
+
const parsed = {};
|
|
138
|
+
for (const [field, path] of TOP_LEVEL_IDENTIFIER_FIELDS) {
|
|
139
|
+
const result = parseIdentifier(value[field], path);
|
|
140
|
+
if (!result.ok)
|
|
141
|
+
return result;
|
|
142
|
+
parsed[field] = result.value;
|
|
143
|
+
}
|
|
144
|
+
return { ok: !0, value: parsed };
|
|
145
|
+
}
|
|
146
|
+
function checkIdentityAgreement(identifiers, contract) {
|
|
147
|
+
if (identifiers.name !== contract.name)
|
|
148
|
+
return workflowRevisionManifestFailure("invalid-field", "must equal manifest.contract.name", "manifest.name");
|
|
149
|
+
if (identifiers.workflowVersion !== contract.workflowVersion)
|
|
150
|
+
return workflowRevisionManifestFailure("invalid-field", "must equal manifest.contract.workflowVersion", "manifest.workflowVersion");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
async function finalizeManifest(identifiers, normalized) {
|
|
154
|
+
const canonicalJson = canonicalWorkflowContractJson(normalized), canonicalBytes = utf8ByteLength(canonicalJson);
|
|
155
|
+
if (canonicalBytes > MAX_NORMALIZED_CONTRACT_BYTES)
|
|
156
|
+
return workflowRevisionManifestFailure("manifest-too-large", `contract normalizes to ${canonicalBytes} bytes, exceeding the maximum of ${MAX_NORMALIZED_CONTRACT_BYTES}`, "manifest.contract");
|
|
157
|
+
const recomputedHash = await contractHash(normalized);
|
|
158
|
+
if (recomputedHash !== identifiers.contractHash)
|
|
159
|
+
return workflowRevisionManifestFailure("contract-hash-mismatch", `recomputed contractHash ${recomputedHash} does not match the supplied value`, "manifest.contractHash");
|
|
160
|
+
return {
|
|
161
|
+
ok: !0,
|
|
162
|
+
manifest: {
|
|
163
|
+
manifestVersion: WORKFLOW_REVISION_MANIFEST_VERSION,
|
|
164
|
+
name: identifiers.name,
|
|
165
|
+
workflowVersion: identifiers.workflowVersion,
|
|
166
|
+
revision: identifiers.revision,
|
|
167
|
+
contractHash: recomputedHash,
|
|
168
|
+
contract: normalized
|
|
169
|
+
},
|
|
170
|
+
canonicalJson
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export async function parseWorkflowRevisionManifest(value) {
|
|
174
|
+
if (!isRecord(value))
|
|
175
|
+
return workflowRevisionManifestFailure("not-an-object", "manifest must be a JSON object");
|
|
176
|
+
if (value.manifestVersion !== WORKFLOW_REVISION_MANIFEST_VERSION)
|
|
177
|
+
return workflowRevisionManifestFailure("manifest-version-unsupported", `manifest.manifestVersion must be ${String(WORKFLOW_REVISION_MANIFEST_VERSION)}`);
|
|
178
|
+
const identifiers = parseTopLevelIdentifiers(value);
|
|
179
|
+
if (!identifiers.ok)
|
|
180
|
+
return identifiers;
|
|
181
|
+
const contract = parseContract(value.contract, "manifest.contract");
|
|
182
|
+
if (!contract.ok)
|
|
183
|
+
return contract;
|
|
184
|
+
const agreementFailure = checkIdentityAgreement(identifiers.value, contract.value);
|
|
185
|
+
if (agreementFailure !== void 0)
|
|
186
|
+
return agreementFailure;
|
|
187
|
+
const normalized = normalizeWorkflowContract(contract.value);
|
|
188
|
+
return finalizeManifest(identifiers.value, normalized);
|
|
189
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a {@link WorkflowRevisionManifest} from a normalized contract.
|
|
3
|
+
*
|
|
4
|
+
* @module core/contract/manifest
|
|
5
|
+
*/
|
|
6
|
+
import type { WorkflowContract, WorkflowRevisionManifest } from './types.ts';
|
|
7
|
+
/**
|
|
8
|
+
* Options accepted by {@link buildWorkflowRevisionManifest}.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import type { BuildWorkflowRevisionManifestOptions } from '@lostgradient/weft';
|
|
13
|
+
*
|
|
14
|
+
* const options: BuildWorkflowRevisionManifestOptions = { revision: 'deploy-2026.09.01' };
|
|
15
|
+
* console.log(options.revision);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export interface BuildWorkflowRevisionManifestOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Explicit opaque revision identity. When omitted, `revision` is derived
|
|
21
|
+
* from the full contract via {@link deriveWorkflowRevision}. An empty
|
|
22
|
+
* string, or a string exceeding `MAX_CONTRACT_IDENTIFIER_BYTES`, is
|
|
23
|
+
* rejected rather than silently falling back to derivation.
|
|
24
|
+
*/
|
|
25
|
+
revision?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a {@link WorkflowRevisionManifest} for a workflow contract.
|
|
29
|
+
*
|
|
30
|
+
* Normalizes the contract, computes `contractHash`, and either derives
|
|
31
|
+
* `revision` (the default) or validates and preserves an explicitly
|
|
32
|
+
* supplied one.
|
|
33
|
+
*
|
|
34
|
+
* Throws a plain `Error` when `options.revision` is present but empty, or
|
|
35
|
+
* exceeds `MAX_CONTRACT_IDENTIFIER_BYTES` — a caller-supplied identity is
|
|
36
|
+
* validated the same way any other contract identifier is, since it becomes
|
|
37
|
+
* part of the manifest a consumer will trust.
|
|
38
|
+
*
|
|
39
|
+
* **Round-trips through {@link parseWorkflowRevisionManifest} before
|
|
40
|
+
* returning.** A manifest this function builds but its own parser would
|
|
41
|
+
* reject (`identifier-too-long`, `too-many-entries`, `manifest-too-large`)
|
|
42
|
+
* is a build-time bug, not a runtime condition to defer to whoever later
|
|
43
|
+
* reads the manifest back — see WFT-5 PR #943 review thread
|
|
44
|
+
* PRRT_kwDORwthfM6eWFwv. Throws a plain `Error` describing the rejection
|
|
45
|
+
* reason when that happens.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { buildWorkflowContract, buildWorkflowRevisionManifest } from '@lostgradient/weft';
|
|
50
|
+
*
|
|
51
|
+
* const contract = buildWorkflowContract({ name: 'checkout', version: '2.1.0' });
|
|
52
|
+
* const manifest = await buildWorkflowRevisionManifest(contract);
|
|
53
|
+
* console.log(manifest.name, manifest.contractHash.startsWith('sha256:'));
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildWorkflowRevisionManifest(contract: WorkflowContract, options?: BuildWorkflowRevisionManifestOptions): Promise<WorkflowRevisionManifest>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { utf8ByteLength } from "../../worker/manifest/utf8.js";
|
|
2
|
+
import { contractHash } from "./hash.js";
|
|
3
|
+
import { MAX_CONTRACT_IDENTIFIER_BYTES } from "./limits.js";
|
|
4
|
+
import { parseWorkflowRevisionManifest } from "./manifest-parse.js";
|
|
5
|
+
import { normalizeWorkflowContract } from "./normalize.js";
|
|
6
|
+
import { deriveWorkflowRevision } from "./revision.js";
|
|
7
|
+
import { WORKFLOW_REVISION_MANIFEST_VERSION } from "./types.js";
|
|
8
|
+
export async function buildWorkflowRevisionManifest(contract, options) {
|
|
9
|
+
const normalized = normalizeWorkflowContract(contract), hash = await contractHash(normalized);
|
|
10
|
+
let revision;
|
|
11
|
+
if (options?.revision !== void 0) {
|
|
12
|
+
if (options.revision.length === 0)
|
|
13
|
+
throw Error("buildWorkflowRevisionManifest: options.revision must not be an empty string");
|
|
14
|
+
const bytes = utf8ByteLength(options.revision);
|
|
15
|
+
if (bytes > MAX_CONTRACT_IDENTIFIER_BYTES)
|
|
16
|
+
throw Error(`buildWorkflowRevisionManifest: options.revision is ${bytes} bytes, exceeding the maximum identifier size of ${MAX_CONTRACT_IDENTIFIER_BYTES}`);
|
|
17
|
+
revision = options.revision;
|
|
18
|
+
} else
|
|
19
|
+
revision = await deriveWorkflowRevision(normalized);
|
|
20
|
+
const manifest = {
|
|
21
|
+
manifestVersion: WORKFLOW_REVISION_MANIFEST_VERSION,
|
|
22
|
+
name: normalized.name,
|
|
23
|
+
workflowVersion: normalized.workflowVersion,
|
|
24
|
+
revision,
|
|
25
|
+
contractHash: hash,
|
|
26
|
+
contract: normalized
|
|
27
|
+
}, parsed = await parseWorkflowRevisionManifest(manifest);
|
|
28
|
+
if (!parsed.ok)
|
|
29
|
+
throw Error(`buildWorkflowRevisionManifest: built manifest fails parseWorkflowRevisionManifest validation (${parsed.reason}${parsed.path === void 0 ? "" : ` at ${parsed.path}`}): ` + parsed.message);
|
|
30
|
+
return parsed.manifest;
|
|
31
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic normalization and canonical serialization for workflow
|
|
3
|
+
* contracts.
|
|
4
|
+
*
|
|
5
|
+
* Two contracts that describe the same workflow must produce byte-identical
|
|
6
|
+
* canonical output regardless of how their object keys were ordered in the
|
|
7
|
+
* source, so `contractHash()` and `deriveWorkflowRevision()` identify the
|
|
8
|
+
* *content* rather than an accident of construction. Serialization walks the
|
|
9
|
+
* declared contract shape explicitly instead of generically stringifying the
|
|
10
|
+
* input, which means an unknown extra property can never leak into the
|
|
11
|
+
* canonical bytes and change a hash.
|
|
12
|
+
*
|
|
13
|
+
* @module core/contract/normalize
|
|
14
|
+
*/
|
|
15
|
+
import type { WorkflowContract, WorkflowMessageContract } from './types.ts';
|
|
16
|
+
/**
|
|
17
|
+
* Normalize a workflow contract into its canonical in-memory form.
|
|
18
|
+
*
|
|
19
|
+
* Field order follows the declared shape, every open-ended record is
|
|
20
|
+
* rebuilt with its keys sorted (and omitted entirely when empty), and every
|
|
21
|
+
* schema fragment is deep-cloned onto a null-prototype object. The result is
|
|
22
|
+
* a fresh value; the input is not mutated.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { normalizeWorkflowContract } from '@lostgradient/weft';
|
|
27
|
+
*
|
|
28
|
+
* const normalized = normalizeWorkflowContract({
|
|
29
|
+
* name: 'checkout',
|
|
30
|
+
* workflowVersion: '2.1.0',
|
|
31
|
+
* signals: {
|
|
32
|
+
* zeta: {},
|
|
33
|
+
* alpha: {},
|
|
34
|
+
* },
|
|
35
|
+
* });
|
|
36
|
+
* console.log(Object.keys(normalized.signals ?? {})); // ['alpha', 'zeta']
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function normalizeWorkflowContract(contract: WorkflowContract): WorkflowContract;
|
|
40
|
+
/**
|
|
41
|
+
* Serialize one signal/update/query/activity contract's schema pair.
|
|
42
|
+
* Shared between {@link canonicalWorkflowContractJson} (the full-identity
|
|
43
|
+
* form) and `hash.ts`'s payload-only serialization, since both walk the same
|
|
44
|
+
* `{ inputSchema?, outputSchema? }` shape — the only difference between the
|
|
45
|
+
* two identities is which *top-level* fields are included, not how a single
|
|
46
|
+
* message/activity entry serializes.
|
|
47
|
+
*
|
|
48
|
+
* @internal Exported for reuse within `core/contract/*`; not part of the
|
|
49
|
+
* package's public API.
|
|
50
|
+
*/
|
|
51
|
+
export declare function canonicalMessageContractJson(entry: WorkflowMessageContract): string;
|
|
52
|
+
/**
|
|
53
|
+
* @internal Exported for reuse within `core/contract/*`; not part of the
|
|
54
|
+
* package's public API.
|
|
55
|
+
*/
|
|
56
|
+
export declare function canonicalContractRecordJson(record: Readonly<Record<string, WorkflowMessageContract>>): string;
|
|
57
|
+
/**
|
|
58
|
+
* @internal Exported for reuse within `core/contract/*` (`hash.ts`'s
|
|
59
|
+
* payload-only serialization shares this field-appending logic); not part of
|
|
60
|
+
* the package's public API.
|
|
61
|
+
*/
|
|
62
|
+
export declare function appendContractRecordField(fields: string[], label: 'signals' | 'updates' | 'queries' | 'activities', record: Readonly<Record<string, WorkflowMessageContract>> | undefined): void;
|
|
63
|
+
/**
|
|
64
|
+
* @internal Exported for reuse within `core/contract/*`; not part of the
|
|
65
|
+
* package's public API.
|
|
66
|
+
*/
|
|
67
|
+
export declare function appendSchemaField(fields: string[], label: 'inputSchema' | 'outputSchema', schema: Record<string, unknown> | undefined): void;
|
|
68
|
+
/**
|
|
69
|
+
* Serialize a workflow contract to its canonical, full-identity JSON string
|
|
70
|
+
* — the digest input {@link deriveWorkflowRevision} uses, and the value
|
|
71
|
+
* returned as `WorkflowRevisionManifestParseSuccess.canonicalJson`.
|
|
72
|
+
*
|
|
73
|
+
* This is a *different* identity from {@link contractHash}'s payload-only
|
|
74
|
+
* serialization: it includes `name`, `workflowVersion`, `description`, and
|
|
75
|
+
* `tags`, so a documentation edit changes this output (and therefore
|
|
76
|
+
* `revision`) without changing `contractHash`. The output is byte-identical
|
|
77
|
+
* for equivalent contracts regardless of source key order, and every field
|
|
78
|
+
* this project cares about changes it.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* import { canonicalWorkflowContractJson } from '@lostgradient/weft';
|
|
83
|
+
*
|
|
84
|
+
* const left = canonicalWorkflowContractJson({
|
|
85
|
+
* name: 'checkout',
|
|
86
|
+
* workflowVersion: '2.1.0',
|
|
87
|
+
* signals: { alpha: {}, zeta: {} },
|
|
88
|
+
* });
|
|
89
|
+
* const right = canonicalWorkflowContractJson({
|
|
90
|
+
* name: 'checkout',
|
|
91
|
+
* workflowVersion: '2.1.0',
|
|
92
|
+
* signals: { zeta: {}, alpha: {} },
|
|
93
|
+
* });
|
|
94
|
+
* console.log(left === right); // true
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare function canonicalWorkflowContractJson(contract: WorkflowContract): string;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { canonicalJsonStringify } from "../../worker/manifest/canonical-json.js";
|
|
2
|
+
import { WORKFLOW_CONTRACT_VERSION } from "./types.js";
|
|
3
|
+
function sortedKeys(record) {
|
|
4
|
+
return Object.keys(record).toSorted();
|
|
5
|
+
}
|
|
6
|
+
function cloneSchemaFragment(value) {
|
|
7
|
+
if (value === null || typeof value !== "object")
|
|
8
|
+
return value;
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.map((entry) => cloneSchemaFragment(entry));
|
|
11
|
+
const record = value, cloned = Object.create(null);
|
|
12
|
+
for (const key of Object.keys(record))
|
|
13
|
+
cloned[key] = cloneSchemaFragment(record[key]);
|
|
14
|
+
return cloned;
|
|
15
|
+
}
|
|
16
|
+
function cloneSchemaRecord(value) {
|
|
17
|
+
return value === void 0 ? void 0 : cloneSchemaFragment(value);
|
|
18
|
+
}
|
|
19
|
+
function normalizeMessageContract(entry) {
|
|
20
|
+
const normalized = {}, inputSchema = cloneSchemaRecord(entry.inputSchema);
|
|
21
|
+
if (inputSchema !== void 0)
|
|
22
|
+
normalized.inputSchema = inputSchema;
|
|
23
|
+
const outputSchema = cloneSchemaRecord(entry.outputSchema);
|
|
24
|
+
if (outputSchema !== void 0)
|
|
25
|
+
normalized.outputSchema = outputSchema;
|
|
26
|
+
return normalized;
|
|
27
|
+
}
|
|
28
|
+
function normalizeActivityContract(entry) {
|
|
29
|
+
return normalizeMessageContract(entry);
|
|
30
|
+
}
|
|
31
|
+
function sortedContractRecord(record, normalizeValue) {
|
|
32
|
+
if (record === void 0)
|
|
33
|
+
return;
|
|
34
|
+
const keys = sortedKeys(record);
|
|
35
|
+
if (keys.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
const normalized = Object.create(null);
|
|
38
|
+
for (const key of keys)
|
|
39
|
+
normalized[key] = normalizeValue(record[key]);
|
|
40
|
+
return normalized;
|
|
41
|
+
}
|
|
42
|
+
function applyDescriptionAndTags(draft, contract) {
|
|
43
|
+
if (contract.description !== void 0)
|
|
44
|
+
draft.description = contract.description;
|
|
45
|
+
if (contract.tags !== void 0 && contract.tags.length > 0)
|
|
46
|
+
draft.tags = [...contract.tags].toSorted();
|
|
47
|
+
}
|
|
48
|
+
function applySchemas(draft, contract) {
|
|
49
|
+
const inputSchema = cloneSchemaRecord(contract.inputSchema);
|
|
50
|
+
if (inputSchema !== void 0)
|
|
51
|
+
draft.inputSchema = inputSchema;
|
|
52
|
+
const outputSchema = cloneSchemaRecord(contract.outputSchema);
|
|
53
|
+
if (outputSchema !== void 0)
|
|
54
|
+
draft.outputSchema = outputSchema;
|
|
55
|
+
}
|
|
56
|
+
function applyMessageRecords(draft, contract) {
|
|
57
|
+
const signals = sortedContractRecord(contract.signals, normalizeMessageContract);
|
|
58
|
+
if (signals !== void 0)
|
|
59
|
+
draft.signals = signals;
|
|
60
|
+
const updates = sortedContractRecord(contract.updates, normalizeMessageContract);
|
|
61
|
+
if (updates !== void 0)
|
|
62
|
+
draft.updates = updates;
|
|
63
|
+
const queries = sortedContractRecord(contract.queries, normalizeMessageContract);
|
|
64
|
+
if (queries !== void 0)
|
|
65
|
+
draft.queries = queries;
|
|
66
|
+
}
|
|
67
|
+
export function normalizeWorkflowContract(contract) {
|
|
68
|
+
const draft = {
|
|
69
|
+
name: contract.name,
|
|
70
|
+
workflowVersion: contract.workflowVersion
|
|
71
|
+
};
|
|
72
|
+
applyDescriptionAndTags(draft, contract);
|
|
73
|
+
applySchemas(draft, contract);
|
|
74
|
+
applyMessageRecords(draft, contract);
|
|
75
|
+
const activities = sortedContractRecord(contract.activities, normalizeActivityContract);
|
|
76
|
+
if (activities !== void 0)
|
|
77
|
+
draft.activities = activities;
|
|
78
|
+
if (contract.finalizer !== void 0)
|
|
79
|
+
draft.finalizer = normalizeActivityContract(contract.finalizer);
|
|
80
|
+
return draft;
|
|
81
|
+
}
|
|
82
|
+
export function canonicalMessageContractJson(entry) {
|
|
83
|
+
const fields = [];
|
|
84
|
+
if (entry.inputSchema !== void 0)
|
|
85
|
+
fields.push(`"inputSchema":${canonicalJsonStringify(entry.inputSchema)}`);
|
|
86
|
+
if (entry.outputSchema !== void 0)
|
|
87
|
+
fields.push(`"outputSchema":${canonicalJsonStringify(entry.outputSchema)}`);
|
|
88
|
+
return `{${fields.join(",")}}`;
|
|
89
|
+
}
|
|
90
|
+
export function canonicalContractRecordJson(record) {
|
|
91
|
+
return `{${sortedKeys(record).map((key) => `${JSON.stringify(key)}:${canonicalMessageContractJson(record[key])}`).join(",")}}`;
|
|
92
|
+
}
|
|
93
|
+
export function appendContractRecordField(fields, label, record) {
|
|
94
|
+
if (record === void 0 || Object.keys(record).length === 0)
|
|
95
|
+
return;
|
|
96
|
+
fields.push(`"${label}":${canonicalContractRecordJson(record)}`);
|
|
97
|
+
}
|
|
98
|
+
export function appendSchemaField(fields, label, schema) {
|
|
99
|
+
if (schema === void 0)
|
|
100
|
+
return;
|
|
101
|
+
fields.push(`"${label}":${canonicalJsonStringify(schema)}`);
|
|
102
|
+
}
|
|
103
|
+
function appendTagsField(fields, tags) {
|
|
104
|
+
if (tags === void 0 || tags.length === 0)
|
|
105
|
+
return;
|
|
106
|
+
const sortedTags = [...tags].toSorted().map((tag) => JSON.stringify(tag));
|
|
107
|
+
fields.push(`"tags":[${sortedTags.join(",")}]`);
|
|
108
|
+
}
|
|
109
|
+
export function canonicalWorkflowContractJson(contract) {
|
|
110
|
+
const fields = [
|
|
111
|
+
`"contractVersion":${JSON.stringify(WORKFLOW_CONTRACT_VERSION)}`,
|
|
112
|
+
`"name":${JSON.stringify(contract.name)}`,
|
|
113
|
+
`"workflowVersion":${JSON.stringify(contract.workflowVersion)}`
|
|
114
|
+
];
|
|
115
|
+
if (contract.description !== void 0)
|
|
116
|
+
fields.push(`"description":${JSON.stringify(contract.description)}`);
|
|
117
|
+
appendTagsField(fields, contract.tags);
|
|
118
|
+
appendSchemaField(fields, "inputSchema", contract.inputSchema);
|
|
119
|
+
appendSchemaField(fields, "outputSchema", contract.outputSchema);
|
|
120
|
+
appendContractRecordField(fields, "signals", contract.signals);
|
|
121
|
+
appendContractRecordField(fields, "updates", contract.updates);
|
|
122
|
+
appendContractRecordField(fields, "queries", contract.queries);
|
|
123
|
+
appendContractRecordField(fields, "activities", contract.activities);
|
|
124
|
+
if (contract.finalizer !== void 0)
|
|
125
|
+
fields.push(`"finalizer":${canonicalMessageContractJson(contract.finalizer)}`);
|
|
126
|
+
return `{${fields.join(",")}}`;
|
|
127
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-derived workflow revision identity.
|
|
3
|
+
*
|
|
4
|
+
* `revision` is the broader identity companion to `contractHash`: it hashes
|
|
5
|
+
* the *entire* normalized contract — `name`, `workflowVersion`,
|
|
6
|
+
* `description`, and `tags` included — so it changes whenever anything
|
|
7
|
+
* about the definition changes, including documentation. This is the same
|
|
8
|
+
* formula the (now-refactored) `buildWorkerManifestFromRegistry()` used for
|
|
9
|
+
* its `workflowRevision` field before this module existed.
|
|
10
|
+
*
|
|
11
|
+
* @module core/contract/revision
|
|
12
|
+
*/
|
|
13
|
+
import type { WorkflowContract } from './types.ts';
|
|
14
|
+
/**
|
|
15
|
+
* Derive a content-addressed revision identity for a workflow contract.
|
|
16
|
+
*
|
|
17
|
+
* Two calls on an equivalent contract (regardless of source key order)
|
|
18
|
+
* produce the same revision, and any field the full canonical serialization
|
|
19
|
+
* carries — including `description` and `tags` — changes it.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { deriveWorkflowRevision } from '@lostgradient/weft';
|
|
24
|
+
*
|
|
25
|
+
* const revision = await deriveWorkflowRevision({ name: 'checkout', workflowVersion: '2.1.0' });
|
|
26
|
+
* console.log(revision.startsWith('sha256:')); // true
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function deriveWorkflowRevision(contract: WorkflowContract): Promise<string>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { digestCanonicalWorkflowContract } from "./hash.js";
|
|
2
|
+
import { canonicalWorkflowContractJson } from "./normalize.js";
|
|
3
|
+
export async function deriveWorkflowRevision(contract) {
|
|
4
|
+
return digestCanonicalWorkflowContract(canonicalWorkflowContractJson(contract));
|
|
5
|
+
}
|