@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,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded failure vocabulary for workflow revision manifest validation.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `src/worker/manifest/failure.ts`: rejections are returned rather
|
|
5
|
+
* than thrown, `reason` is a closed union safe to use as a metric label, and
|
|
6
|
+
* `message`/`path` are diagnostics only.
|
|
7
|
+
*
|
|
8
|
+
* @module core/contract/failure
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Why an untrusted {@link WorkflowRevisionManifest} was rejected.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import type { WorkflowRevisionManifestRejectionReason } from '@lostgradient/weft';
|
|
16
|
+
*
|
|
17
|
+
* const counts = new Map<WorkflowRevisionManifestRejectionReason, number>();
|
|
18
|
+
* counts.set('contract-hash-mismatch', 1);
|
|
19
|
+
* console.log(counts.get('contract-hash-mismatch'));
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type WorkflowRevisionManifestRejectionReason = 'manifest-version-unsupported' | 'contract-hash-mismatch' | 'not-an-object' | 'invalid-field' | 'identifier-too-long' | 'too-many-entries' | 'manifest-too-large';
|
|
23
|
+
/**
|
|
24
|
+
* A rejected workflow revision manifest, with enough detail to fix the
|
|
25
|
+
* caller's input and not so much that it leaks contract content into logs.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { parseWorkflowRevisionManifest, type WorkflowRevisionManifestValidationFailure } from '@lostgradient/weft';
|
|
30
|
+
*
|
|
31
|
+
* const result = await parseWorkflowRevisionManifest({ manifestVersion: 99 });
|
|
32
|
+
* if (!result.ok) {
|
|
33
|
+
* const rejection: WorkflowRevisionManifestValidationFailure = result;
|
|
34
|
+
* console.log(rejection.reason); // 'manifest-version-unsupported'
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export type WorkflowRevisionManifestValidationFailure = Readonly<{
|
|
39
|
+
ok: false;
|
|
40
|
+
/** Bounded rejection reason, safe as a metric label. */
|
|
41
|
+
reason: WorkflowRevisionManifestRejectionReason;
|
|
42
|
+
/** Human-readable diagnostic. Never use as a metric label. */
|
|
43
|
+
message: string;
|
|
44
|
+
/** Dotted path to the offending field, when one applies. */
|
|
45
|
+
path?: string;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Build a validation failure whose message reads as one sentence about the
|
|
49
|
+
* offending path — `manifest.contract.workflowVersion must be a non-empty
|
|
50
|
+
* string`.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { workflowRevisionManifestFailure } from '@lostgradient/weft';
|
|
55
|
+
*
|
|
56
|
+
* const failure = workflowRevisionManifestFailure(
|
|
57
|
+
* 'invalid-field',
|
|
58
|
+
* 'must be a non-empty string',
|
|
59
|
+
* 'manifest.name',
|
|
60
|
+
* );
|
|
61
|
+
* console.log(failure.message);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function workflowRevisionManifestFailure(reason: WorkflowRevisionManifestRejectionReason, message: string, path?: string): WorkflowRevisionManifestValidationFailure;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-addressed digests of a workflow contract's public payload.
|
|
3
|
+
*
|
|
4
|
+
* `contractHash()` answers "which public payload contract does this
|
|
5
|
+
* revision implement" — it excludes `name`, `workflowVersion`,
|
|
6
|
+
* `description`, and `tags`, which identify the workflow and describe it in
|
|
7
|
+
* prose rather than describe what callers may send and get back. That
|
|
8
|
+
* exclusion is what lets a documentation edit change `deriveWorkflowRevision()`'s
|
|
9
|
+
* broader identity (see `revision.ts`) without changing `contractHash()`.
|
|
10
|
+
*
|
|
11
|
+
* `digestCanonicalWorkflowContract()` is a generic "digest this canonical
|
|
12
|
+
* JSON text" primitive shared by both identities: which identity a caller
|
|
13
|
+
* gets back depends entirely on which canonical serializer produced the
|
|
14
|
+
* text handed to it — `canonicalWorkflowContractJson()`'s full-identity
|
|
15
|
+
* output yields the same digest `deriveWorkflowRevision()` returns; this
|
|
16
|
+
* module's internal payload-only serializer is what `contractHash()` feeds
|
|
17
|
+
* it. Treat it as a shared digesting primitive, not as itself a payload-only
|
|
18
|
+
* function.
|
|
19
|
+
*
|
|
20
|
+
* SHA-256 rather than the repository's FNV-1a helpers, matching the worker
|
|
21
|
+
* manifest digest's choice: `contractHash` is compared for compatibility
|
|
22
|
+
* decisions, so a collision would let two different contracts pass for one
|
|
23
|
+
* another, ruling out a cache-key-quality hash.
|
|
24
|
+
*
|
|
25
|
+
* @module core/contract/hash
|
|
26
|
+
*/
|
|
27
|
+
import type { WorkflowActivityContract, WorkflowContract } from './types.ts';
|
|
28
|
+
/**
|
|
29
|
+
* Algorithm tag prefixed to every digest {@link contractHash} and
|
|
30
|
+
* {@link activityContractHash} produce.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { WORKFLOW_CONTRACT_DIGEST_ALGORITHM } from '@lostgradient/weft';
|
|
35
|
+
*
|
|
36
|
+
* const hash = 'sha256:2b1f0c9d';
|
|
37
|
+
* console.log(hash.startsWith(`${WORKFLOW_CONTRACT_DIGEST_ALGORITHM}:`)); // true
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare const WORKFLOW_CONTRACT_DIGEST_ALGORITHM = "sha256";
|
|
41
|
+
/**
|
|
42
|
+
* Digest canonical contract JSON text.
|
|
43
|
+
*
|
|
44
|
+
* Separate from {@link contractHash} and `deriveWorkflowRevision` so a
|
|
45
|
+
* caller that already holds a canonical serialization does not serialize
|
|
46
|
+
* the contract a second time. Which identity the result represents depends
|
|
47
|
+
* entirely on which canonical serializer produced `canonicalJson` — see this
|
|
48
|
+
* module's JSDoc.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { canonicalWorkflowContractJson, digestCanonicalWorkflowContract } from '@lostgradient/weft';
|
|
53
|
+
*
|
|
54
|
+
* const canonical = canonicalWorkflowContractJson({ name: 'checkout', workflowVersion: '2.1.0' });
|
|
55
|
+
* console.log((await digestCanonicalWorkflowContract(canonical)).startsWith('sha256:'));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function digestCanonicalWorkflowContract(canonicalJson: string): Promise<string>;
|
|
59
|
+
/**
|
|
60
|
+
* Compute a workflow contract's payload-only content identity.
|
|
61
|
+
*
|
|
62
|
+
* Determined entirely by the payload fields (schemas, signals, updates,
|
|
63
|
+
* queries, activities, finalizer) plus the `WORKFLOW_CONTRACT_VERSION`
|
|
64
|
+
* domain separator — two contracts that differ only in `name`,
|
|
65
|
+
* `workflowVersion`, `description`, or `tags` hash identically, and two
|
|
66
|
+
* contracts that differ only in key order also hash identically.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { contractHash } from '@lostgradient/weft';
|
|
71
|
+
*
|
|
72
|
+
* const left = await contractHash({ name: 'checkout', workflowVersion: '1.0.0' });
|
|
73
|
+
* const right = await contractHash({ name: 'checkout', workflowVersion: '2.0.0' });
|
|
74
|
+
* console.log(left === right); // true — name/workflowVersion are excluded
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function contractHash(contract: WorkflowContract): Promise<string>;
|
|
78
|
+
/**
|
|
79
|
+
* Compute one activity's payload-only content identity, independent of the
|
|
80
|
+
* workflow contract it is declared under.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { activityContractHash } from '@lostgradient/weft';
|
|
85
|
+
*
|
|
86
|
+
* const hash = await activityContractHash({
|
|
87
|
+
* inputSchema: { type: 'object', properties: { amount: { type: 'number' } } },
|
|
88
|
+
* });
|
|
89
|
+
* console.log(hash.startsWith('sha256:')); // true
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function activityContractHash(activity: WorkflowActivityContract): Promise<string>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { sha256Hex } from "../../worker/manifest/content-digest.js";
|
|
2
|
+
import {
|
|
3
|
+
appendContractRecordField,
|
|
4
|
+
appendSchemaField,
|
|
5
|
+
canonicalMessageContractJson
|
|
6
|
+
} from "./normalize.js";
|
|
7
|
+
import { WORKFLOW_CONTRACT_VERSION } from "./types.js";
|
|
8
|
+
export const WORKFLOW_CONTRACT_DIGEST_ALGORITHM = "sha256";
|
|
9
|
+
function canonicalWorkflowContractPayloadJson(contract) {
|
|
10
|
+
const fields = [`"contractVersion":${JSON.stringify(WORKFLOW_CONTRACT_VERSION)}`];
|
|
11
|
+
appendSchemaField(fields, "inputSchema", contract.inputSchema);
|
|
12
|
+
appendSchemaField(fields, "outputSchema", contract.outputSchema);
|
|
13
|
+
appendContractRecordField(fields, "signals", contract.signals);
|
|
14
|
+
appendContractRecordField(fields, "updates", contract.updates);
|
|
15
|
+
appendContractRecordField(fields, "queries", contract.queries);
|
|
16
|
+
appendContractRecordField(fields, "activities", contract.activities);
|
|
17
|
+
if (contract.finalizer !== void 0)
|
|
18
|
+
fields.push(`"finalizer":${canonicalMessageContractJson(contract.finalizer)}`);
|
|
19
|
+
return `{${fields.join(",")}}`;
|
|
20
|
+
}
|
|
21
|
+
export async function digestCanonicalWorkflowContract(canonicalJson) {
|
|
22
|
+
return sha256Hex(canonicalJson);
|
|
23
|
+
}
|
|
24
|
+
export async function contractHash(contract) {
|
|
25
|
+
return digestCanonicalWorkflowContract(canonicalWorkflowContractPayloadJson(contract));
|
|
26
|
+
}
|
|
27
|
+
export async function activityContractHash(activity) {
|
|
28
|
+
const versionField = `"contractVersion":${JSON.stringify(WORKFLOW_CONTRACT_VERSION)}`, schemaFields = canonicalActivityContractSchemaFields(activity);
|
|
29
|
+
return digestCanonicalWorkflowContract(`{${[versionField, ...schemaFields].join(",")}}`);
|
|
30
|
+
}
|
|
31
|
+
function canonicalActivityContractSchemaFields(entry) {
|
|
32
|
+
const stripped = canonicalMessageContractJson(entry).slice(1, -1);
|
|
33
|
+
return stripped.length === 0 ? [] : [stripped];
|
|
34
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical, normalized workflow contract vocabulary — the single input to
|
|
3
|
+
* both TypeScript code generation and `contractHash()`, plus the typed
|
|
4
|
+
* `WorkflowRevisionManifest` and its hostile-input parser.
|
|
5
|
+
*
|
|
6
|
+
* @module core/contract
|
|
7
|
+
*/
|
|
8
|
+
export { MAX_CONTRACT_IDENTIFIER_BYTES, MAX_CONTRACT_MESSAGE_COUNT, MAX_CONTRACT_SCHEMA_DEPTH, MAX_NORMALIZED_CONTRACT_BYTES, } from './limits.ts';
|
|
9
|
+
export { WORKFLOW_CONTRACT_VERSION, WORKFLOW_REVISION_MANIFEST_VERSION } from './types.ts';
|
|
10
|
+
export type { WorkflowActivityContract, WorkflowContract, WorkflowContractActivitySource, WorkflowContractMessageSource, WorkflowContractSource, WorkflowMessageContract, WorkflowRevisionManifest, } from './types.ts';
|
|
11
|
+
export { WorkflowContractConversionError, buildWorkflowContract } from './build.ts';
|
|
12
|
+
export { canonicalWorkflowContractJson, normalizeWorkflowContract } from './normalize.ts';
|
|
13
|
+
export { WORKFLOW_CONTRACT_DIGEST_ALGORITHM, activityContractHash, contractHash, digestCanonicalWorkflowContract, } from './hash.ts';
|
|
14
|
+
export { deriveWorkflowRevision } from './revision.ts';
|
|
15
|
+
export { buildWorkflowRevisionManifest } from './manifest.ts';
|
|
16
|
+
export type { BuildWorkflowRevisionManifestOptions } from './manifest.ts';
|
|
17
|
+
export type { WorkflowRevisionManifestRejectionReason, WorkflowRevisionManifestValidationFailure, } from './failure.ts';
|
|
18
|
+
export { parseWorkflowRevisionManifest } from './manifest-parse.ts';
|
|
19
|
+
export type { WorkflowRevisionManifestParseResult, WorkflowRevisionManifestParseSuccess, } from './manifest-parse.ts';
|
|
20
|
+
export { DEFAULT_WORKFLOW_COMPATIBILITY_POLICY, checkWorkflowCompatibility, } from './compatibility.ts';
|
|
21
|
+
export type { WorkflowCompatibilityPolicy, WorkflowCompatibilityReason, WorkflowCompatibilityVerdict, } from './compatibility.ts';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export {
|
|
2
|
+
MAX_CONTRACT_IDENTIFIER_BYTES,
|
|
3
|
+
MAX_CONTRACT_MESSAGE_COUNT,
|
|
4
|
+
MAX_CONTRACT_SCHEMA_DEPTH,
|
|
5
|
+
MAX_NORMALIZED_CONTRACT_BYTES
|
|
6
|
+
} from "./limits.js";
|
|
7
|
+
export { WORKFLOW_CONTRACT_VERSION, WORKFLOW_REVISION_MANIFEST_VERSION } from "./types.js";
|
|
8
|
+
export { WorkflowContractConversionError, buildWorkflowContract } from "./build.js";
|
|
9
|
+
export { canonicalWorkflowContractJson, normalizeWorkflowContract } from "./normalize.js";
|
|
10
|
+
export {
|
|
11
|
+
WORKFLOW_CONTRACT_DIGEST_ALGORITHM,
|
|
12
|
+
activityContractHash,
|
|
13
|
+
contractHash,
|
|
14
|
+
digestCanonicalWorkflowContract
|
|
15
|
+
} from "./hash.js";
|
|
16
|
+
export { deriveWorkflowRevision } from "./revision.js";
|
|
17
|
+
export { buildWorkflowRevisionManifest } from "./manifest.js";
|
|
18
|
+
export { parseWorkflowRevisionManifest } from "./manifest-parse.js";
|
|
19
|
+
export {
|
|
20
|
+
DEFAULT_WORKFLOW_COMPATIBILITY_POLICY,
|
|
21
|
+
checkWorkflowCompatibility
|
|
22
|
+
} from "./compatibility.js";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic bounds applied to a workflow contract before it is normalized,
|
|
3
|
+
* hashed, or admitted as a {@link WorkflowRevisionManifest}.
|
|
4
|
+
*
|
|
5
|
+
* Sized analogously to `src/worker/manifest/limits.ts` — the same
|
|
6
|
+
* placement rationale applies: the type declarations, the hostile-input
|
|
7
|
+
* manifest parser, and the canonical serializer can all depend on these
|
|
8
|
+
* limits without forming an import cycle.
|
|
9
|
+
*
|
|
10
|
+
* @module core/contract/limits
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Maximum UTF-8 byte length of any single identifier-shaped contract string —
|
|
14
|
+
* workflow/signal/update/query/activity name, `workflowVersion`, or an
|
|
15
|
+
* explicitly supplied `revision`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { MAX_CONTRACT_IDENTIFIER_BYTES } from '@lostgradient/weft';
|
|
20
|
+
*
|
|
21
|
+
* const name = 'checkout';
|
|
22
|
+
* const fits = new TextEncoder().encode(name).byteLength <= MAX_CONTRACT_IDENTIFIER_BYTES;
|
|
23
|
+
* console.log(fits); // true
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare const MAX_CONTRACT_IDENTIFIER_BYTES = 512;
|
|
27
|
+
/**
|
|
28
|
+
* Maximum number of entries in any one of a contract's `signals`, `updates`,
|
|
29
|
+
* `queries`, or `activities` records.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { MAX_CONTRACT_MESSAGE_COUNT } from '@lostgradient/weft';
|
|
34
|
+
*
|
|
35
|
+
* const signals = ['approved', 'rejected'];
|
|
36
|
+
* console.log(signals.length <= MAX_CONTRACT_MESSAGE_COUNT); // true
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const MAX_CONTRACT_MESSAGE_COUNT = 512;
|
|
40
|
+
/**
|
|
41
|
+
* Maximum nesting depth permitted inside one schema fragment
|
|
42
|
+
* (`inputSchema`/`outputSchema`).
|
|
43
|
+
*
|
|
44
|
+
* Mirrors `codegen-emit.ts`'s `MAX_RECURSION_DEPTH`. `isJSONValue()` and
|
|
45
|
+
* `canonicalJsonStringify()` are both unbounded recursion over their input,
|
|
46
|
+
* so {@link parseWorkflowRevisionManifest} enforces this bound itself,
|
|
47
|
+
* iteratively, before either ever walks an untrusted schema fragment.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { MAX_CONTRACT_SCHEMA_DEPTH } from '@lostgradient/weft';
|
|
52
|
+
*
|
|
53
|
+
* console.log(MAX_CONTRACT_SCHEMA_DEPTH >= 16); // true
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare const MAX_CONTRACT_SCHEMA_DEPTH = 64;
|
|
57
|
+
/**
|
|
58
|
+
* Maximum UTF-8 byte length of the canonical, normalized contract JSON.
|
|
59
|
+
*
|
|
60
|
+
* Checked against the canonical serialization — not the received bytes — so
|
|
61
|
+
* a compact payload cannot evade the bound and then expand under
|
|
62
|
+
* normalization.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { buildWorkflowContract, canonicalWorkflowContractJson, MAX_NORMALIZED_CONTRACT_BYTES } from '@lostgradient/weft';
|
|
67
|
+
*
|
|
68
|
+
* const canonical = canonicalWorkflowContractJson(
|
|
69
|
+
* buildWorkflowContract({ name: 'checkout', version: '2.1.0' }),
|
|
70
|
+
* );
|
|
71
|
+
* console.log(canonical.length <= MAX_NORMALIZED_CONTRACT_BYTES); // true
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const MAX_NORMALIZED_CONTRACT_BYTES = 262144;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MAX_CONTRACT_IDENTIFIER_BYTES = 512, MAX_CONTRACT_MESSAGE_COUNT = 512, MAX_CONTRACT_SCHEMA_DEPTH = 64, MAX_NORMALIZED_CONTRACT_BYTES = 262144;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hostile-input validation for the schema-fragment-shaped parts of an
|
|
3
|
+
* untrusted {@link WorkflowRevisionManifest}: `inputSchema`/`outputSchema`
|
|
4
|
+
* pairs, and the `signals`/`updates`/`queries`/`activities` records that
|
|
5
|
+
* carry them.
|
|
6
|
+
*
|
|
7
|
+
* Split out of `manifest-parse.ts` to keep each file under the repository's
|
|
8
|
+
* implementation-file-size ceiling and so the depth/JSON-safety walk that
|
|
9
|
+
* every schema fragment goes through has one place to audit.
|
|
10
|
+
*
|
|
11
|
+
* @module core/contract/manifest-parse-schema
|
|
12
|
+
*/
|
|
13
|
+
import { type NameKind } from '../types/name-grammar.ts';
|
|
14
|
+
import { type WorkflowRevisionManifestValidationFailure } from './failure.ts';
|
|
15
|
+
import type { WorkflowActivityContract, WorkflowMessageContract } from './types.ts';
|
|
16
|
+
type ParseSuccess<T> = {
|
|
17
|
+
ok: true;
|
|
18
|
+
value: T;
|
|
19
|
+
};
|
|
20
|
+
type ParseOutcome<T> = ParseSuccess<T> | WorkflowRevisionManifestValidationFailure;
|
|
21
|
+
/** Validate a `{ inputSchema?, outputSchema? }`-shaped entry from untrusted input. */
|
|
22
|
+
export declare function parseSchemaPair(value: unknown, path: string): ParseOutcome<WorkflowMessageContract | WorkflowActivityContract>;
|
|
23
|
+
/**
|
|
24
|
+
* Validate one record key: present, non-empty, within the identifier byte
|
|
25
|
+
* ceiling and, when `kind` is given, wire-safe per
|
|
26
|
+
* `validateWorkflowOrActivityName`. Signal/update/query names pass `kind:
|
|
27
|
+
* undefined` — those names are deliberately unconstrained, matching
|
|
28
|
+
* `SignalDefinition`/`UpdateDefinition`/`QueryDefinition` at the type level.
|
|
29
|
+
*/
|
|
30
|
+
export declare function checkContractKey(key: string, kind: NameKind | undefined, path: string): WorkflowRevisionManifestValidationFailure | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Validate a `signals`/`updates`/`queries`/`activities` record from
|
|
33
|
+
* untrusted input: bounded entry count, bounded/validated keys, and every
|
|
34
|
+
* entry parsed as a schema pair.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseContractRecord(value: unknown, path: string, keyKind: NameKind | undefined): ParseOutcome<Readonly<Record<string, WorkflowMessageContract | WorkflowActivityContract>>>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isRecord } from "../../worker/manifest/is-record.js";
|
|
2
|
+
import { utf8ByteLength } from "../../worker/manifest/utf8.js";
|
|
3
|
+
import { isJSONValue } from "../json.js";
|
|
4
|
+
import { validateWorkflowOrActivityName } from "../types/name-grammar.js";
|
|
5
|
+
import {
|
|
6
|
+
workflowRevisionManifestFailure
|
|
7
|
+
} from "./failure.js";
|
|
8
|
+
import {
|
|
9
|
+
MAX_CONTRACT_IDENTIFIER_BYTES,
|
|
10
|
+
MAX_CONTRACT_MESSAGE_COUNT,
|
|
11
|
+
MAX_CONTRACT_SCHEMA_DEPTH
|
|
12
|
+
} from "./limits.js";
|
|
13
|
+
function withinDepth(value, maxDepth) {
|
|
14
|
+
const stack = [{ value, depth: 1 }];
|
|
15
|
+
while (stack.length > 0) {
|
|
16
|
+
const frame = stack.pop();
|
|
17
|
+
if (frame === void 0)
|
|
18
|
+
break;
|
|
19
|
+
if (frame.depth > maxDepth)
|
|
20
|
+
return !1;
|
|
21
|
+
const current = frame.value;
|
|
22
|
+
if (current === null || typeof current !== "object")
|
|
23
|
+
continue;
|
|
24
|
+
const nextDepth = frame.depth + 1;
|
|
25
|
+
if (nextDepth > maxDepth)
|
|
26
|
+
return !1;
|
|
27
|
+
if (Array.isArray(current))
|
|
28
|
+
for (const item of current)
|
|
29
|
+
stack.push({ value: item, depth: nextDepth });
|
|
30
|
+
else
|
|
31
|
+
for (const item of Object.values(current))
|
|
32
|
+
stack.push({ value: item, depth: nextDepth });
|
|
33
|
+
}
|
|
34
|
+
return !0;
|
|
35
|
+
}
|
|
36
|
+
function cloneJsonSafe(value) {
|
|
37
|
+
if (value === null || typeof value !== "object")
|
|
38
|
+
return value;
|
|
39
|
+
if (Array.isArray(value))
|
|
40
|
+
return value.map((entry) => cloneJsonSafe(entry));
|
|
41
|
+
const record = value, cloned = Object.create(null);
|
|
42
|
+
for (const key of Object.keys(record))
|
|
43
|
+
cloned[key] = cloneJsonSafe(record[key]);
|
|
44
|
+
return cloned;
|
|
45
|
+
}
|
|
46
|
+
function parseSchemaFragment(value, path) {
|
|
47
|
+
if (!isRecord(value))
|
|
48
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a JSON object", path);
|
|
49
|
+
if (!withinDepth(value, MAX_CONTRACT_SCHEMA_DEPTH))
|
|
50
|
+
return workflowRevisionManifestFailure("invalid-field", `nests deeper than the maximum schema depth of ${MAX_CONTRACT_SCHEMA_DEPTH}`, path);
|
|
51
|
+
if (!isJSONValue(value))
|
|
52
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a JSON-safe object", path);
|
|
53
|
+
return { ok: !0, value: cloneJsonSafe(value) };
|
|
54
|
+
}
|
|
55
|
+
export function parseSchemaPair(value, path) {
|
|
56
|
+
if (!isRecord(value))
|
|
57
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a JSON object", path);
|
|
58
|
+
const entry = {};
|
|
59
|
+
if (value.inputSchema !== void 0) {
|
|
60
|
+
const inputSchema = parseSchemaFragment(value.inputSchema, `${path}.inputSchema`);
|
|
61
|
+
if (!inputSchema.ok)
|
|
62
|
+
return inputSchema;
|
|
63
|
+
entry.inputSchema = inputSchema.value;
|
|
64
|
+
}
|
|
65
|
+
if (value.outputSchema !== void 0) {
|
|
66
|
+
const outputSchema = parseSchemaFragment(value.outputSchema, `${path}.outputSchema`);
|
|
67
|
+
if (!outputSchema.ok)
|
|
68
|
+
return outputSchema;
|
|
69
|
+
entry.outputSchema = outputSchema.value;
|
|
70
|
+
}
|
|
71
|
+
return { ok: !0, value: entry };
|
|
72
|
+
}
|
|
73
|
+
export function checkContractKey(key, kind, path) {
|
|
74
|
+
if (kind !== void 0 && key.length === 0)
|
|
75
|
+
return workflowRevisionManifestFailure("invalid-field", "must not be an empty string", path);
|
|
76
|
+
if (kind !== void 0) {
|
|
77
|
+
const bytes = utf8ByteLength(key);
|
|
78
|
+
if (bytes > MAX_CONTRACT_IDENTIFIER_BYTES)
|
|
79
|
+
return workflowRevisionManifestFailure("identifier-too-long", `is ${bytes} bytes, exceeding the maximum identifier size of ${MAX_CONTRACT_IDENTIFIER_BYTES}`, path);
|
|
80
|
+
try {
|
|
81
|
+
validateWorkflowOrActivityName(key, kind);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
const message = (error instanceof Error ? error.message : "is not a wire-safe name").replaceAll(key, JSON.stringify(key));
|
|
84
|
+
return workflowRevisionManifestFailure("invalid-field", message, path);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
export function parseContractRecord(value, path, keyKind) {
|
|
90
|
+
if (!isRecord(value))
|
|
91
|
+
return workflowRevisionManifestFailure("invalid-field", "must be a JSON object", path);
|
|
92
|
+
const names = Object.keys(value);
|
|
93
|
+
if (names.length > MAX_CONTRACT_MESSAGE_COUNT)
|
|
94
|
+
return workflowRevisionManifestFailure("too-many-entries", `declares ${names.length} entries, exceeding the maximum of ${MAX_CONTRACT_MESSAGE_COUNT}`, path);
|
|
95
|
+
const built = Object.create(null);
|
|
96
|
+
for (const name of names) {
|
|
97
|
+
const keyFailure = checkContractKey(name, keyKind, `${path} key ${JSON.stringify(name)}`);
|
|
98
|
+
if (keyFailure !== void 0)
|
|
99
|
+
return keyFailure;
|
|
100
|
+
const entry = parseSchemaPair(value[name], `${path}.${name}`);
|
|
101
|
+
if (!entry.ok)
|
|
102
|
+
return entry;
|
|
103
|
+
built[name] = entry.value;
|
|
104
|
+
}
|
|
105
|
+
return { ok: !0, value: built };
|
|
106
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hostile-input parsing for workflow revision manifests.
|
|
3
|
+
*
|
|
4
|
+
* A manifest arrives from a source this module does not control — persisted
|
|
5
|
+
* storage read by an older or differently-configured build, a wire payload,
|
|
6
|
+
* an operator-supplied fixture. Every field is proven from `unknown` rather
|
|
7
|
+
* than asserted, every open-ended collection is bounded before it is walked,
|
|
8
|
+
* and `contractHash` is always recomputed and compared rather than trusted
|
|
9
|
+
* as supplied — a caller cannot assert a hash it did not earn.
|
|
10
|
+
*
|
|
11
|
+
* @module core/contract/manifest-parse
|
|
12
|
+
*/
|
|
13
|
+
import { type WorkflowRevisionManifestValidationFailure } from './failure.ts';
|
|
14
|
+
import type { WorkflowRevisionManifest } from './types.ts';
|
|
15
|
+
/**
|
|
16
|
+
* A successfully validated manifest, paired with the canonical serialization
|
|
17
|
+
* of its (normalized) contract, so a caller does not have to re-derive it.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import {
|
|
22
|
+
* buildWorkflowContract,
|
|
23
|
+
* buildWorkflowRevisionManifest,
|
|
24
|
+
* parseWorkflowRevisionManifest,
|
|
25
|
+
* type WorkflowRevisionManifestParseSuccess,
|
|
26
|
+
* } from '@lostgradient/weft';
|
|
27
|
+
*
|
|
28
|
+
* const manifest = await buildWorkflowRevisionManifest(buildWorkflowContract({ name: 'checkout' }));
|
|
29
|
+
* const result = await parseWorkflowRevisionManifest(manifest);
|
|
30
|
+
* if (result.ok) {
|
|
31
|
+
* const accepted: WorkflowRevisionManifestParseSuccess = result;
|
|
32
|
+
* console.log(accepted.canonicalJson.length > 0);
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export type WorkflowRevisionManifestParseSuccess = Readonly<{
|
|
37
|
+
ok: true;
|
|
38
|
+
/** The validated, normalized manifest. */
|
|
39
|
+
manifest: WorkflowRevisionManifest;
|
|
40
|
+
/** Canonical serialization of `manifest.contract` — `canonicalWorkflowContractJson(manifest.contract)`. */
|
|
41
|
+
canonicalJson: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Outcome of validating an untrusted workflow revision manifest.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { parseWorkflowRevisionManifest, type WorkflowRevisionManifestParseResult } from '@lostgradient/weft';
|
|
49
|
+
*
|
|
50
|
+
* const result: WorkflowRevisionManifestParseResult = await parseWorkflowRevisionManifest({});
|
|
51
|
+
* console.log(result.ok);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export type WorkflowRevisionManifestParseResult = WorkflowRevisionManifestParseSuccess | WorkflowRevisionManifestValidationFailure;
|
|
55
|
+
/**
|
|
56
|
+
* Validate an untrusted workflow revision manifest.
|
|
57
|
+
*
|
|
58
|
+
* The returned manifest is already normalized, `contractHash` is always
|
|
59
|
+
* recomputed from the (normalized) contract and compared against the
|
|
60
|
+
* supplied value — a mismatch is rejected with `'contract-hash-mismatch'`
|
|
61
|
+
* regardless of what the caller asserted — and `manifest.name`/
|
|
62
|
+
* `manifest.workflowVersion` must agree with `manifest.contract.name`/
|
|
63
|
+
* `manifest.contract.workflowVersion`. `revision` is validated (bounded,
|
|
64
|
+
* non-empty) but never recomputed: it is an opaque label the parser trusts
|
|
65
|
+
* once it is well-formed.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { buildWorkflowContract, buildWorkflowRevisionManifest, parseWorkflowRevisionManifest } from '@lostgradient/weft';
|
|
70
|
+
*
|
|
71
|
+
* const manifest = await buildWorkflowRevisionManifest(buildWorkflowContract({ name: 'checkout' }));
|
|
72
|
+
* const result = await parseWorkflowRevisionManifest(manifest);
|
|
73
|
+
* console.log(result.ok ? result.manifest.name : result.reason);
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseWorkflowRevisionManifest(value: unknown): Promise<WorkflowRevisionManifestParseResult>;
|