@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
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Weft
|
|
2
2
|
|
|
3
|
-
A Bun-native durable execution engine. Current release: `0.
|
|
3
|
+
A Bun-native durable execution engine. Current release: `0.24.1`.
|
|
4
4
|
|
|
5
5
|
Install the library from npm as `@lostgradient/weft`:
|
|
6
6
|
|
|
@@ -253,6 +253,74 @@ For stable-id re-sync flows, `engine.startOrSignal()` can replace a terminal pri
|
|
|
253
253
|
|
|
254
254
|
When a workflow drains signals with `ctx.race([ctx.waitForSignal(name), ctx.sleep(0)])` and then returns, use that stable `id`, a deterministic per-event `signalId`, and `onTerminalConflict: 'start-new'` for the corresponding `startOrSignal` calls. Delivery is serialized against terminal completion, so a signal arriving across the completion boundary is consumed by the current run or handed to its successor; a positive drain window is not needed for correctness.
|
|
255
255
|
|
|
256
|
+
### Durable Application Command Mailbox
|
|
257
|
+
|
|
258
|
+
Signals are workflow control. When the thing receiving a command is an application _resource_ rather than a workflow run — an agent taking steering input, a resource fielding requests from a peer service — `Mailbox` gives it a durable, strictly FIFO command queue with real receipts.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import { Mailbox, MemoryStorage } from '@lostgradient/weft';
|
|
262
|
+
|
|
263
|
+
await using storage = new MemoryStorage();
|
|
264
|
+
using mailbox = new Mailbox({ storage, namespace: 'bureau', resourceId: 'agent-7' });
|
|
265
|
+
|
|
266
|
+
const admission = await mailbox.admit({
|
|
267
|
+
caller: 'user:42',
|
|
268
|
+
target: 'agent:7',
|
|
269
|
+
kind: 'steer',
|
|
270
|
+
payload: { form: 'inline', value: { text: 'stop and summarize' } },
|
|
271
|
+
idempotencyKey: 'steer-1',
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const claimed = await mailbox.claim();
|
|
275
|
+
if (claimed.status === 'claimed' && admission.status === 'admitted') {
|
|
276
|
+
await mailbox.acknowledge({
|
|
277
|
+
commandId: claimed.claim.receipt.commandId,
|
|
278
|
+
attemptToken: claimed.claim.attemptToken,
|
|
279
|
+
outcome: { applied: true },
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Admission returns a receipt that, on a persistent backend such as `BunSQLiteStorage`, survives process restart; `MemoryStorage` above keeps the example self-contained and is gone with the process. Idempotency binds to `(caller, target, kind, payloadDigest)`, so an exact retry returns the original receipt and a conflicting reuse of the key returns a stable conflict without touching the original. Claims are attempt-fenced, so two consumers sharing one durable store can never both hold a valid claim _on the same command_ — delivery is strictly FIFO, but a later command may be claimed while an earlier one is still in flight, so completion order is up to the consumers. Cancellation is durable before it reaches anyone, and reports honestly whether cleanup is still outstanding rather than claiming an uncooperative handler stopped.
|
|
285
|
+
|
|
286
|
+
Delivery intent, ordering, ownership, and disposition are durable; external side effects are not made exactly-once. See [Application Mailbox](documentation/guides/mailbox.md).
|
|
287
|
+
|
|
288
|
+
### Durable Application Delivery Outbox
|
|
289
|
+
|
|
290
|
+
The mailbox is for commands coming _in_ to a resource. For work going _out_ — a webhook, a notification, a message to a peer service — `Outbox` is the matching primitive: a durable, at-least-once delivery queue whose enqueue, attempt leases, transport outcomes, retry schedule, cancellation, and dead-letter state are all durable and observable, without ever confusing a transport write with an acknowledgement.
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
import { Outbox, MemoryStorage } from '@lostgradient/weft';
|
|
294
|
+
|
|
295
|
+
await using storage = new MemoryStorage();
|
|
296
|
+
using outbox = new Outbox({
|
|
297
|
+
storage,
|
|
298
|
+
namespace: 'bureau',
|
|
299
|
+
ownerId: 'agent-7',
|
|
300
|
+
adapter: {
|
|
301
|
+
async send(request) {
|
|
302
|
+
// Put the request on the wire. Present request.delivery.externalIdempotencyKey
|
|
303
|
+
// as the remote idempotency key when the delivery carries one; the attempt
|
|
304
|
+
// token changes per attempt and is only a request id or fence.
|
|
305
|
+
void request;
|
|
306
|
+
return { status: 'acknowledged', evidence: { messageId: 'm-1' } };
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
await outbox.enqueue({
|
|
312
|
+
destinationRef: 'webhook:orders',
|
|
313
|
+
kind: 'order.shipped',
|
|
314
|
+
payload: { form: 'inline', value: { orderId: 42 } },
|
|
315
|
+
idempotencyKey: 'order-42-shipped',
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const delivered = await outbox.deliverNext();
|
|
319
|
+
if (delivered.status === 'settled') console.log(delivered.receipt.state); // 'acknowledged'
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Every attempt is durably marked `attempting` _before_ the adapter is called, so a crash before the send is a safe retry and a crash after it is an unknown outcome — which is parked or dead-lettered by explicit policy, and retried automatically only when the delivery carries stable external idempotency evidence. Returning from `send()` never settles anything by itself; the outbox commits the matching disposition, fenced on the attempt. See [Application Outbox](documentation/guides/outbox.md).
|
|
323
|
+
|
|
256
324
|
### Search Attributes
|
|
257
325
|
|
|
258
326
|
Attach indexed metadata to a workflow at runtime, then list and filter on it.
|
|
@@ -335,7 +403,7 @@ A small `Storage` interface over string keys and `Uint8Array` values: five requi
|
|
|
335
403
|
- **`SQLiteStorage`** (subpath `@lostgradient/weft/storage/sqlite`) for SQLite persistence; Bun resolves to `BunSQLiteStorage`, Node resolves to `NodeSQLiteStorage`
|
|
336
404
|
- **`BunSQLiteStorage`** (subpath `@lostgradient/weft/storage/sqlite/bun`) for an explicit Bun SQLite override
|
|
337
405
|
- **`NodeSQLiteStorage`** (subpath `@lostgradient/weft/storage/sqlite/node`) for an explicit Node.js SQLite override via `better-sqlite3`
|
|
338
|
-
- **`LMDBStorage`** (subpath `@lostgradient/weft/storage/lmdb`) for embedded high-throughput workloads
|
|
406
|
+
- **`LMDBStorage`** (subpath `@lostgradient/weft/storage/lmdb`) for embedded high-throughput workloads; accepts a `durability: 'relaxed'` option that skips `fsync` on every commit, trading crash durability for write latency—use it for test fixtures, not production storage. `capabilities().persistence` reports `'ephemeral'` for a relaxed-durability instance (instead of `'local'`), so `assertDurableStorageForRecovery()` correctly rejects it
|
|
339
407
|
- **`TursoStorage`** (subpath `@lostgradient/weft/storage/turso`) for distributed libSQL deployments
|
|
340
408
|
- **`NeonStorage`** (subpath `@lostgradient/weft/storage/neon`) for durable remote Neon/Postgres deployments
|
|
341
409
|
- **`IndexedDBStorage`** (subpath `@lostgradient/weft/storage/indexeddb`) for browser environments
|
|
@@ -367,7 +435,7 @@ await using server = serve({ engine, port: 7233 });
|
|
|
367
435
|
// server.url is e.g. "http://0.0.0.0:7233"
|
|
368
436
|
```
|
|
369
437
|
|
|
370
|
-
Endpoints under `/api/v1/` cover the full lifecycle: start workflows, list, signal, update, query, cancel, fork, and stream events. JSON-RPC over WebSocket also exposes workflow and fleet event subscriptions for operator UIs that need live state without polling. Content negotiation supports JSON and MessagePack. The server can also mount an externally supplied dashboard shell at known page routes; see the [server guide](documentation/guides/server.md#external-dashboard-mounting) for the hosting contract.
|
|
438
|
+
Endpoints under `/api/v1/` cover the full lifecycle: start workflows, list, signal, update, query, cancel, fork, and stream events. JSON-RPC over WebSocket also exposes workflow and fleet event subscriptions for operator UIs that need live state without polling. Content negotiation supports JSON and MessagePack. `engine.workflows` and the matching `/v1/registry/` operations expose the durable workflow catalog for admin tooling — install a revision's manifest and activate it as the advertised active revision — bookkeeping only, never workflow execution routing; see [`workflow-versioning.md`](documentation/guides/workflow-versioning.md#engineworkflows-public-catalog-control). `workflowSource()` pairs a typed, serializable source descriptor with a never-serialized loader capability, so one workflow can register lazily while another stays eagerly registered; `engine.registerSource()` records the candidate without importing it, and `engine.resolveWorkflowSource()` (or its `engine.workflows.preload()` alias) loads, validates, and installs it into the same catalog with single-flight deduplication per `(name, revision)`. Every execution entry point — `start()`, `startOrSignal()`, `schedule()`, `fork()`, `resume()`, and recovery — awaits resolution for a lazy type before running any handler code, with bounded diagnostics and process-local events for the load pipeline; see [Engine Integration](documentation/guides/workflow-versioning.md#engine-integration-wft-1516). The server can also mount an externally supplied dashboard shell at known page routes; see the [server guide](documentation/guides/server.md#external-dashboard-mounting) for the hosting contract.
|
|
371
439
|
|
|
372
440
|
### Remote Workers
|
|
373
441
|
|
|
@@ -565,7 +633,7 @@ Guides:
|
|
|
565
633
|
- [Durable Timers](documentation/guides/durable-timers.md), [Timeouts](documentation/guides/timeouts.md), [Parallel Execution](documentation/guides/parallel-execution.md)
|
|
566
634
|
- [Search Attributes](documentation/guides/search-attributes.md), [Workflow Visibility Backfill](documentation/guides/workflow-visibility-backfill.md), [State](documentation/guides/state.md), [Session State](documentation/guides/session-state.md), [Events](documentation/guides/events.md)
|
|
567
635
|
- [Interceptors](documentation/guides/interceptors.md), [Observability](documentation/guides/observability.md), [Testing](documentation/guides/testing.md)
|
|
568
|
-
- [Workflow Versioning](documentation/guides/workflow-versioning.md), [Remote Workers](documentation/guides/remote-workers.md), [Service Worker](documentation/guides/service-worker.md), [Resource Management](documentation/guides/resource-management.md), [Concurrency: Mutex and Semaphore](documentation/guides/concurrency.md)
|
|
636
|
+
- [Workflow Versioning](documentation/guides/workflow-versioning.md), [Remote Workers](documentation/guides/remote-workers.md), [Service Worker](documentation/guides/service-worker.md), [Resource Management](documentation/guides/resource-management.md), [Concurrency: Mutex and Semaphore](documentation/guides/concurrency.md), [Application Mailbox](documentation/guides/mailbox.md), [Application Outbox](documentation/guides/outbox.md)
|
|
569
637
|
|
|
570
638
|
Architecture and reference:
|
|
571
639
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-deduplication for `weft codegen`'s generated `.d.ts`.
|
|
3
|
+
*
|
|
4
|
+
* `codegen-emit-registry.ts` walks every active workflow's `inputSchema`/
|
|
5
|
+
* `outputSchema` in a fixed, deterministic order (workflows sorted by name,
|
|
6
|
+
* then input before output) and hands this module the resulting sequence of
|
|
7
|
+
* {@link SchemaFragmentOccurrence}s — each fragment's independently-emitted
|
|
8
|
+
* TypeScript text (`jsonSchemaToTypeScript`). {@link buildSchemaAliasTable}
|
|
9
|
+
* groups those by that emitted text and decides, for each group, whether the
|
|
10
|
+
* repeated type is worth hoisting into a single shared `type` alias
|
|
11
|
+
* referenced from every entry that uses it, rather than repeating the same
|
|
12
|
+
* TypeScript text inline at every call site.
|
|
13
|
+
*
|
|
14
|
+
* Grouping by the emitted TypeScript text itself — not by a normalization of
|
|
15
|
+
* the source JSON Schema — is deliberate: two JSON Schema fragments that
|
|
16
|
+
* differ only in an order-insensitive construct (`required: ['a', 'b']` vs
|
|
17
|
+
* `required: ['b', 'a']`; `properties` key order) render to byte-identical
|
|
18
|
+
* TypeScript through `jsonSchemaToTypeScript` (which sorts object keys), so
|
|
19
|
+
* grouping by a JSON-level canonical key would miss deduplicating them even
|
|
20
|
+
* though they are exactly the same type a consumer would want aliased
|
|
21
|
+
* together. Grouping by the rendered text instead means "these occurrences
|
|
22
|
+
* produce the same alias" and "these occurrences are the same TypeScript
|
|
23
|
+
* type" are the same question, answered once, so there is no JSON-vs-text
|
|
24
|
+
* disagreement to reconcile: any two occurrences landing in the same group
|
|
25
|
+
* are equal by construction (`Map` keys are compared by value), not merely
|
|
26
|
+
* expected to agree.
|
|
27
|
+
*
|
|
28
|
+
* A schema only qualifies for hoisting when it recurs (count >= 2) and the
|
|
29
|
+
* emitted type is not trivial — hoisting `unknown` or `string` behind an
|
|
30
|
+
* opaque alias name would only make the generated file harder to read for
|
|
31
|
+
* zero benefit, and would trivially "dedupe" every schema-less workflow
|
|
32
|
+
* (`inputSchema` undefined → emitted type `unknown`) into a shared alias the
|
|
33
|
+
* moment two workflows both lack an input schema, which is the common case,
|
|
34
|
+
* not an edge case.
|
|
35
|
+
*
|
|
36
|
+
* @module cli/codegen-emit-dedup
|
|
37
|
+
*/
|
|
38
|
+
export { CodegenEmitError } from './codegen-emit-keywords.ts';
|
|
39
|
+
/** One schema fragment's independently-emitted TypeScript text. */
|
|
40
|
+
export type SchemaFragmentOccurrence = {
|
|
41
|
+
tsType: string;
|
|
42
|
+
};
|
|
43
|
+
/** A hoisted schema's alias name and the TypeScript type it aliases. */
|
|
44
|
+
export type SchemaAliasEntry = {
|
|
45
|
+
alias: string;
|
|
46
|
+
tsType: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Emitted TypeScript type expressions that are never worth hoisting behind
|
|
50
|
+
* an alias, no matter how many times they recur: bare primitives and the
|
|
51
|
+
* handful of compound "no meaningful shape" forms `jsonSchemaToTypeScript`
|
|
52
|
+
* produces for an absent, empty, or fully-open/closed schema.
|
|
53
|
+
*/
|
|
54
|
+
export declare const TRIVIAL_TYPESCRIPT_TYPES: ReadonlySet<string>;
|
|
55
|
+
/** Options for {@link buildSchemaAliasTable}, injectable for deterministic testing. */
|
|
56
|
+
export type BuildSchemaAliasTableOptions = {
|
|
57
|
+
/** Alias-name hash function. Defaults to {@link hashString} (FNV-1a). */
|
|
58
|
+
hash?: (key: string) => string;
|
|
59
|
+
};
|
|
60
|
+
/** Prefix for every generated schema alias name — distinctive and double-underscored so it never collides with a real consumer type name. */
|
|
61
|
+
export declare const ALIAS_PREFIX = "__WeftSchema_";
|
|
62
|
+
/**
|
|
63
|
+
* Group a fixed, deterministically-ordered sequence of schema occurrences
|
|
64
|
+
* by their emitted TypeScript text and decide which recurring, non-trivial
|
|
65
|
+
* types should be hoisted into a shared `type` alias.
|
|
66
|
+
*
|
|
67
|
+
* Returns a map keyed by `tsType` (not by alias) so a caller emitting one
|
|
68
|
+
* workflow entry's `input`/`output` field can look up "does this schema's
|
|
69
|
+
* emitted type have a hoisted alias?" directly, without a second reverse
|
|
70
|
+
* index — the caller computes the same `jsonSchemaToTypeScript` text it
|
|
71
|
+
* would otherwise emit inline, and either finds an alias or emits that text.
|
|
72
|
+
*
|
|
73
|
+
* Alias names are deterministic: `ALIAS_PREFIX` plus a hash of the emitted
|
|
74
|
+
* type text (FNV-1a via {@link hashString} by default, injectable via
|
|
75
|
+
* `options.hash` for testing). A real hash collision between two different
|
|
76
|
+
* emitted types is astronomically unlikely but not impossible, so it is
|
|
77
|
+
* checked and throws {@link CodegenEmitError} rather than silently letting
|
|
78
|
+
* one type's alias declaration shadow another's — `codegen.ts` already
|
|
79
|
+
* converts that error to `exitCode: 1`.
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildSchemaAliasTable(occurrences: readonly SchemaFragmentOccurrence[], options?: BuildSchemaAliasTableOptions): ReadonlyMap<string, SchemaAliasEntry>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { hashString } from "../runtime/portable.js";
|
|
2
|
+
import { CodegenEmitError } from "./codegen-emit-keywords.js";
|
|
3
|
+
export { CodegenEmitError } from "./codegen-emit-keywords.js";
|
|
4
|
+
export const TRIVIAL_TYPESCRIPT_TYPES = new Set([
|
|
5
|
+
"string",
|
|
6
|
+
"number",
|
|
7
|
+
"boolean",
|
|
8
|
+
"null",
|
|
9
|
+
"unknown",
|
|
10
|
+
"never",
|
|
11
|
+
"Record<string, never>",
|
|
12
|
+
"Record<string, unknown>",
|
|
13
|
+
"Array<unknown>"
|
|
14
|
+
]);
|
|
15
|
+
const LITERAL_TOKEN_PATTERN = /^(-?[0-9]+(\.[0-9]+)?|true|false|null|"([^"\\]|\\.)*")$/;
|
|
16
|
+
function isTrivialTsType(tsType) {
|
|
17
|
+
return TRIVIAL_TYPESCRIPT_TYPES.has(tsType) || LITERAL_TOKEN_PATTERN.test(tsType);
|
|
18
|
+
}
|
|
19
|
+
export const ALIAS_PREFIX = "__WeftSchema_";
|
|
20
|
+
function groupOccurrences(occurrences) {
|
|
21
|
+
const groups = new Map;
|
|
22
|
+
occurrences.forEach((occurrence, index) => {
|
|
23
|
+
const existing = groups.get(occurrence.tsType);
|
|
24
|
+
if (existing === void 0)
|
|
25
|
+
groups.set(occurrence.tsType, { count: 1, firstIndex: index });
|
|
26
|
+
else
|
|
27
|
+
existing.count += 1;
|
|
28
|
+
});
|
|
29
|
+
return groups;
|
|
30
|
+
}
|
|
31
|
+
export function buildSchemaAliasTable(occurrences, options) {
|
|
32
|
+
const hash = options?.hash ?? hashString, groups = groupOccurrences(occurrences), orderedTypes = [...groups.keys()].toSorted((a, b) => groups.get(a).firstIndex - groups.get(b).firstIndex), aliasOwners = new Map, table = new Map;
|
|
33
|
+
for (const tsType of orderedTypes) {
|
|
34
|
+
if (groups.get(tsType).count < 2)
|
|
35
|
+
continue;
|
|
36
|
+
if (isTrivialTsType(tsType))
|
|
37
|
+
continue;
|
|
38
|
+
const alias = `${ALIAS_PREFIX}${hash(tsType)}`, owner = aliasOwners.get(alias);
|
|
39
|
+
if (owner !== void 0 && owner !== tsType)
|
|
40
|
+
throw new CodegenEmitError(`codegen: schema alias collision: emitted-type hashes ${JSON.stringify(hash(owner))} and ${JSON.stringify(hash(tsType))} both resolved to alias "${alias}"`);
|
|
41
|
+
aliasOwners.set(alias, tsType);
|
|
42
|
+
table.set(tsType, { alias, tsType });
|
|
43
|
+
}
|
|
44
|
+
return table;
|
|
45
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.d.ts` assembly for `weft codegen`'s active-workflow projection.
|
|
3
|
+
*
|
|
4
|
+
* Consumes the active workflow projection of a registry snapshot
|
|
5
|
+
* (`Record<name, CodegenWorkflowEntry>`, projected from its v2 manifest
|
|
6
|
+
* array by `codegen-validate.ts`'s `resolveActiveWorkflowEntries`) and
|
|
7
|
+
* produces a single `.d.ts` string that augments the public
|
|
8
|
+
* `'@lostgradient/weft'` module with typed `WorkflowRegistry` entries. The
|
|
9
|
+
* output is byte-stable across runs with the same input: keys are sorted
|
|
10
|
+
* with explicit codepoint comparators, property names and string-literal
|
|
11
|
+
* values are uniformly double-quoted via `emitStringLiteral`, and there are
|
|
12
|
+
* no timestamps or environment-dependent paths.
|
|
13
|
+
*
|
|
14
|
+
* The augmented `WorkflowRegistry` interface is the single source of truth
|
|
15
|
+
* for per-workflow input/output typing across the whole public surface:
|
|
16
|
+
* `engine.start`, `WorkflowHandle.result()`, AND the client
|
|
17
|
+
* (`WeftClient.start`/`schedule` and `ClientHandle.result()`). The client
|
|
18
|
+
* overloads key off this interface, so emitting one declaration narrows
|
|
19
|
+
* both engine and client call sites — there is no separate client-specific
|
|
20
|
+
* emission, and skipping codegen leaves both usable with plain string
|
|
21
|
+
* names. Every entry also carries `revision`/`workflowVersion` as
|
|
22
|
+
* string-literal fields for compile-time introspection; neither is
|
|
23
|
+
* required by `engine.start`/`WeftClient.start`/`.schedule()`, which read
|
|
24
|
+
* only `input`/`output` structurally (`WorkflowInput`/`WorkflowOutput` in
|
|
25
|
+
* `core/types/workflow-registries.ts`) — an ordinary start needs no
|
|
26
|
+
* caller-supplied revision.
|
|
27
|
+
*
|
|
28
|
+
* Activity names are no longer emitted as a global `ActivityTypes` module
|
|
29
|
+
* augmentation — that interface was removed when the chained workflow
|
|
30
|
+
* builder made activity names a per-workflow concern (typed at the
|
|
31
|
+
* builder's `.activities({...})` step). The snapshot still carries
|
|
32
|
+
* activity schemas because the same registry feeds discovery and MCP
|
|
33
|
+
* tooling, but the emitter intentionally drops them from the generated
|
|
34
|
+
* `.d.ts`.
|
|
35
|
+
*
|
|
36
|
+
* When two or more workflow entries' `inputSchema`/`outputSchema` render to
|
|
37
|
+
* the same non-trivial TypeScript text (see `codegen-emit-dedup.ts` — grouped
|
|
38
|
+
* by the emitted text itself, not by a JSON-level normalization of the
|
|
39
|
+
* source schema, so schemas differing only in an order-insensitive JSON
|
|
40
|
+
* construct like `required` array order still dedupe correctly), that text
|
|
41
|
+
* is hoisted into a single, unexported, file-top-level
|
|
42
|
+
* `type __WeftSchema_<hash> = <TS type>;` alias declared BEFORE
|
|
43
|
+
* `declare module '@lostgradient/weft' { ... }` — never inside it.
|
|
44
|
+
* Placing an alias inside the augmentation block would make it a
|
|
45
|
+
* pseudo-public exported type name of `@lostgradient/weft` (autocomplete
|
|
46
|
+
* pollution for every consumer), and because TypeScript `type` aliases
|
|
47
|
+
* don't structurally merge the way `interface` does, two independently
|
|
48
|
+
* generated `.d.ts` files declaring the same content-derived alias name
|
|
49
|
+
* inside the same augmented interface would collide with a real
|
|
50
|
+
* "Duplicate identifier" compile error the moment both landed in one
|
|
51
|
+
* TypeScript program. File-scoped placement avoids both problems.
|
|
52
|
+
*
|
|
53
|
+
* @module cli/codegen-emit-registry
|
|
54
|
+
*/
|
|
55
|
+
export { CodegenEmitError } from './codegen-emit-keywords.ts';
|
|
56
|
+
/**
|
|
57
|
+
* One active workflow's codegen-relevant metadata: its input/output
|
|
58
|
+
* schemas plus the `revision`/`workflowVersion` identity fields every
|
|
59
|
+
* generated entry now carries. Deliberately narrower than, and separate
|
|
60
|
+
* from, `core/registry-workflow-manifest.ts`'s `RegistryWorkflowEntry` —
|
|
61
|
+
* that type also describes the full registration-time shape fed into
|
|
62
|
+
* `buildWorkflowRevisionManifest` itself (which doesn't yet have a
|
|
63
|
+
* `revision` to attach — a manifest can't carry the revision of the
|
|
64
|
+
* manifest used to build it), so widening it here would be circular.
|
|
65
|
+
* `description`/`tags` are carried through for parity with the source
|
|
66
|
+
* manifest and future codegen features, but this batch does not emit them
|
|
67
|
+
* into the `.d.ts` (see the module's `openQuestions` in its planning
|
|
68
|
+
* record — emitting free-text description as a JSDoc comment reopens the
|
|
69
|
+
* same injection-safety surface WFT-5 closed for the contract module, and
|
|
70
|
+
* is out of scope here).
|
|
71
|
+
*/
|
|
72
|
+
export type CodegenWorkflowEntry = {
|
|
73
|
+
inputSchema?: Record<string, unknown>;
|
|
74
|
+
outputSchema?: Record<string, unknown>;
|
|
75
|
+
description?: string;
|
|
76
|
+
tags?: ReadonlyArray<string>;
|
|
77
|
+
revision: string;
|
|
78
|
+
workflowVersion: string;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Emit the full `.d.ts` declaration string for a registry's active workflow
|
|
82
|
+
* projection.
|
|
83
|
+
*
|
|
84
|
+
* The output is deterministic: keys are sorted by codepoint, property
|
|
85
|
+
* names and string-literal values go through {@link emitPropertyKey}/
|
|
86
|
+
* {@link emitStringLiteral}, unions/intersections are always parenthesized
|
|
87
|
+
* so they compose correctly when nested, and hoisted schema aliases are
|
|
88
|
+
* sorted by alias name.
|
|
89
|
+
*/
|
|
90
|
+
export declare function emitRegistryDeclaration(activeWorkflows: Record<string, CodegenWorkflowEntry>): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { compareCodepoint } from "../core/compare-codepoint.js";
|
|
2
|
+
import {
|
|
3
|
+
buildSchemaAliasTable
|
|
4
|
+
} from "./codegen-emit-dedup.js";
|
|
5
|
+
import { emitPropertyKey, emitStringLiteral, jsonSchemaToTypeScript } from "./codegen-emit.js";
|
|
6
|
+
export { CodegenEmitError } from "./codegen-emit-keywords.js";
|
|
7
|
+
const WEFT_PACKAGE_NAME = "@lostgradient/weft";
|
|
8
|
+
function sortedWorkflowEntries(workflows) {
|
|
9
|
+
return Object.entries(workflows).toSorted(([a], [b]) => compareCodepoint(a, b));
|
|
10
|
+
}
|
|
11
|
+
function collectSchemaOccurrences(workflows) {
|
|
12
|
+
const occurrences = [], workflowsWithTypes = [];
|
|
13
|
+
for (const [name, entry] of workflows) {
|
|
14
|
+
const inputType = jsonSchemaToTypeScript(entry.inputSchema), outputType = jsonSchemaToTypeScript(entry.outputSchema);
|
|
15
|
+
occurrences.push({ tsType: inputType }, { tsType: outputType });
|
|
16
|
+
workflowsWithTypes.push({ name, entry, inputType, outputType });
|
|
17
|
+
}
|
|
18
|
+
return { occurrences, workflowsWithTypes };
|
|
19
|
+
}
|
|
20
|
+
function schemaTypeReference(tsType, aliasTable) {
|
|
21
|
+
const aliasEntry = aliasTable.get(tsType);
|
|
22
|
+
return aliasEntry !== void 0 ? aliasEntry.alias : tsType;
|
|
23
|
+
}
|
|
24
|
+
function emitWorkflowEntry(workflow, aliasTable) {
|
|
25
|
+
const { name, entry, inputType, outputType } = workflow, input = schemaTypeReference(inputType, aliasTable), output = schemaTypeReference(outputType, aliasTable), revision = emitStringLiteral(entry.revision), workflowVersion = emitStringLiteral(entry.workflowVersion);
|
|
26
|
+
return ` ${emitPropertyKey(name)}: { input: ${input}; output: ${output}; revision: ${revision}; workflowVersion: ${workflowVersion} };`;
|
|
27
|
+
}
|
|
28
|
+
function emitAliasDeclarations(aliasTable) {
|
|
29
|
+
return [...aliasTable.values()].toSorted((a, b) => compareCodepoint(a.alias, b.alias)).map((entry) => `type ${entry.alias} = ${entry.tsType};`);
|
|
30
|
+
}
|
|
31
|
+
export function emitRegistryDeclaration(activeWorkflows) {
|
|
32
|
+
const workflows = sortedWorkflowEntries(activeWorkflows), { occurrences, workflowsWithTypes } = collectSchemaOccurrences(workflows), aliasTable = buildSchemaAliasTable(occurrences), aliasLines = emitAliasDeclarations(aliasTable), workflowLines = workflowsWithTypes.map((workflow) => emitWorkflowEntry(workflow, aliasTable)), workflowBlock = workflowLines.length === 0 ? " interface WorkflowRegistry {}" : [" interface WorkflowRegistry {", ...workflowLines, " }"].join(`
|
|
33
|
+
`);
|
|
34
|
+
return [
|
|
35
|
+
"// Generated by `weft codegen`. Do not edit by hand.",
|
|
36
|
+
"// Augments `WorkflowRegistry` to type engine and client call sites",
|
|
37
|
+
"// (start/schedule input and handle.result() output) per workflow.",
|
|
38
|
+
"/* eslint-disable */",
|
|
39
|
+
"",
|
|
40
|
+
...aliasLines,
|
|
41
|
+
...aliasLines.length > 0 ? [""] : [],
|
|
42
|
+
`declare module '${WEFT_PACKAGE_NAME}' {`,
|
|
43
|
+
workflowBlock,
|
|
44
|
+
"}",
|
|
45
|
+
"",
|
|
46
|
+
"export {};",
|
|
47
|
+
""
|
|
48
|
+
].join(`
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
@@ -1,50 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Deterministic JSON-Schema → TypeScript
|
|
2
|
+
* Deterministic JSON-Schema → TypeScript expression converter for
|
|
3
|
+
* `weft codegen`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Converts a single JSON Schema fragment ({@link jsonSchemaToTypeScript})
|
|
6
|
+
* into a TypeScript type expression, and emits a safely-quoted TypeScript
|
|
7
|
+
* string literal or property key ({@link emitStringLiteral},
|
|
8
|
+
* {@link emitPropertyKey}). The JSON Schema subset supported here covers
|
|
9
|
+
* what `definitionSchemaToJsonSchema` actually produces today (Zod via
|
|
10
|
+
* `z.toJSONSchema` and Valibot via `@valibot/to-json-schema`). Anything
|
|
11
|
+
* outside that subset degrades to `unknown` so the converter never claims
|
|
12
|
+
* a type it cannot justify.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* client-specific emission, and skipping codegen leaves both usable with
|
|
19
|
-
* plain string names.
|
|
20
|
-
*
|
|
21
|
-
* Activity names are no longer emitted as a global `ActivityTypes`
|
|
22
|
-
* module augmentation — that interface was removed when the chained
|
|
23
|
-
* workflow builder made activity names a per-workflow concern (typed at
|
|
24
|
-
* the builder's `.activities({...})` step). The snapshot still carries
|
|
25
|
-
* activity schemas because the same registry feeds discovery and MCP tooling,
|
|
26
|
-
* but the emitter intentionally drops them from the
|
|
27
|
-
* generated `.d.ts`.
|
|
28
|
-
*
|
|
29
|
-
* The JSON Schema subset supported here covers what
|
|
30
|
-
* `definitionSchemaToJsonSchema` actually produces today (Zod via
|
|
31
|
-
* `z.toJSONSchema` and Valibot via `@valibot/to-json-schema`).
|
|
32
|
-
* Anything outside that subset degrades to `unknown` so the emitter
|
|
33
|
-
* never claims a type it cannot justify.
|
|
14
|
+
* `codegen-emit-registry.ts` is the module that actually assembles a full
|
|
15
|
+
* `.d.ts` file (the `WorkflowRegistry` module augmentation, revision/
|
|
16
|
+
* workflowVersion literals, and schema-alias hoisting) from these
|
|
17
|
+
* primitives — this module has no knowledge of the registry snapshot shape
|
|
18
|
+
* or the augmented module's structure, only of JSON Schema → TypeScript
|
|
19
|
+
* conversion.
|
|
34
20
|
*
|
|
35
21
|
* @module cli/codegen-emit
|
|
36
22
|
*/
|
|
37
|
-
import type { RegistrySnapshot } from '../core/registry-snapshot.ts';
|
|
38
23
|
export { CodegenEmitError } from './codegen-emit-keywords.ts';
|
|
24
|
+
/**
|
|
25
|
+
* Emit a TypeScript string literal type for an arbitrary string value.
|
|
26
|
+
* Shared by {@link emitPropertyKey} (a literal used as a property key) and
|
|
27
|
+
* `codegen-emit-registry.ts`'s `revision`/`workflowVersion` emission (a
|
|
28
|
+
* literal used as a value type) — both need the same `JSON.stringify`
|
|
29
|
+
* safety property: quotes, backslashes, control characters, and any other
|
|
30
|
+
* hostile content are always safely embedded inside the double-quoted
|
|
31
|
+
* string, so neither call site can inject generated TypeScript.
|
|
32
|
+
*/
|
|
33
|
+
export declare function emitStringLiteral(value: string): string;
|
|
39
34
|
/** Emit a TypeScript property key as a double-quoted string literal. */
|
|
40
35
|
export declare function emitPropertyKey(name: string): string;
|
|
41
36
|
/** Convert a single JSON Schema fragment to a TypeScript type expression. */
|
|
42
37
|
export declare function jsonSchemaToTypeScript(schema: unknown): string;
|
|
43
|
-
/**
|
|
44
|
-
* Emit the full `.d.ts` declaration string for a registry snapshot.
|
|
45
|
-
*
|
|
46
|
-
* The output is deterministic: keys are sorted by codepoint, property
|
|
47
|
-
* names go through {@link emitPropertyKey}, and unions/intersections
|
|
48
|
-
* are always parenthesized so they compose correctly when nested.
|
|
49
|
-
*/
|
|
50
|
-
export declare function emitRegistryDeclaration(snapshot: RegistrySnapshot): string;
|
package/dist/cli/codegen-emit.js
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
PRIMITIVE_SUPPORTED_KEYS
|
|
7
7
|
} from "./codegen-emit-keywords.js";
|
|
8
8
|
export { CodegenEmitError } from "./codegen-emit-keywords.js";
|
|
9
|
-
const WEFT_PACKAGE_NAME = "@lostgradient/weft";
|
|
10
9
|
function codepointCompare(a, b) {
|
|
11
10
|
if (a < b)
|
|
12
11
|
return -1;
|
|
@@ -14,8 +13,11 @@ function codepointCompare(a, b) {
|
|
|
14
13
|
return 1;
|
|
15
14
|
return 0;
|
|
16
15
|
}
|
|
16
|
+
export function emitStringLiteral(value) {
|
|
17
|
+
return JSON.stringify(value);
|
|
18
|
+
}
|
|
17
19
|
export function emitPropertyKey(name) {
|
|
18
|
-
return
|
|
20
|
+
return emitStringLiteral(name);
|
|
19
21
|
}
|
|
20
22
|
function primitiveTypeFor(typeKeyword) {
|
|
21
23
|
switch (typeKeyword) {
|
|
@@ -253,28 +255,3 @@ function indexSignatureForObject(additionalRaw, namedValueTypes, hasOptionalName
|
|
|
253
255
|
}
|
|
254
256
|
return "unknown";
|
|
255
257
|
}
|
|
256
|
-
function sortedWorkflowEntries(workflows) {
|
|
257
|
-
return Object.entries(workflows).toSorted(([a], [b]) => codepointCompare(a, b));
|
|
258
|
-
}
|
|
259
|
-
function emitWorkflowEntry(name, entry) {
|
|
260
|
-
const input = jsonSchemaToTypeScript(entry.inputSchema), output = jsonSchemaToTypeScript(entry.outputSchema);
|
|
261
|
-
return ` ${emitPropertyKey(name)}: { input: ${input}; output: ${output} };`;
|
|
262
|
-
}
|
|
263
|
-
export function emitRegistryDeclaration(snapshot) {
|
|
264
|
-
const workflowLines = sortedWorkflowEntries(snapshot.workflows).map(([name, entry]) => emitWorkflowEntry(name, entry)), workflowBlock = workflowLines.length === 0 ? " interface WorkflowRegistry {}" : [" interface WorkflowRegistry {", ...workflowLines, " }"].join(`
|
|
265
|
-
`);
|
|
266
|
-
return [
|
|
267
|
-
"// Generated by `weft codegen`. Do not edit by hand.",
|
|
268
|
-
"// Augments `WorkflowRegistry` to type engine and client call sites",
|
|
269
|
-
"// (start/schedule input and handle.result() output) per workflow.",
|
|
270
|
-
"/* eslint-disable */",
|
|
271
|
-
"",
|
|
272
|
-
`declare module '${WEFT_PACKAGE_NAME}' {`,
|
|
273
|
-
workflowBlock,
|
|
274
|
-
"}",
|
|
275
|
-
"",
|
|
276
|
-
"export {};",
|
|
277
|
-
""
|
|
278
|
-
].join(`
|
|
279
|
-
`);
|
|
280
|
-
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Envelope and per-manifest validation for a `weft codegen` registry
|
|
3
|
+
* snapshot source (fetched from a live server or vendored as `--from`
|
|
4
|
+
* JSON).
|
|
5
|
+
*
|
|
6
|
+
* Split out of `codegen.ts` specifically to stay under the repository's
|
|
7
|
+
* implementation-file-size ceiling once WFT-6's manifest validation
|
|
8
|
+
* (reusing `core/contract`'s hostile-input `parseWorkflowRevisionManifest`)
|
|
9
|
+
* was added — `codegen.ts` was already 460 of 500 lines before this module
|
|
10
|
+
* existed.
|
|
11
|
+
*
|
|
12
|
+
* @module cli/codegen-validate
|
|
13
|
+
*/
|
|
14
|
+
import { type RegistryActivityEntry } from '../core/registry-snapshot.ts';
|
|
15
|
+
import type { CodegenWorkflowEntry } from './codegen-emit-registry.ts';
|
|
16
|
+
/**
|
|
17
|
+
* Ceiling on the raw `workflows` array's length, checked before a single
|
|
18
|
+
* element is parsed or cryptographically hashed, and on the number of
|
|
19
|
+
* entries in `activeRevisions`, checked before a single key/value pair is
|
|
20
|
+
* read (`activeRevisions` can never usefully point at more names than
|
|
21
|
+
* `workflows` could ever declare, so the same ceiling applies to both).
|
|
22
|
+
* Shared with `core/registry-snapshot.ts`'s producer-side enforcement via
|
|
23
|
+
* {@link MAX_REGISTRY_WORKFLOW_COUNT} rather than each defining its own
|
|
24
|
+
* number: a consumer ceiling looser than the producer's would be dead code,
|
|
25
|
+
* and one tighter would make `weft codegen --server` reject a
|
|
26
|
+
* legitimately-generated snapshot from a same-release server.
|
|
27
|
+
*/
|
|
28
|
+
export type ValidateSnapshotResult<T> = {
|
|
29
|
+
ok: true;
|
|
30
|
+
value: T;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
error: string;
|
|
34
|
+
};
|
|
35
|
+
/** The active workflow projection `weft codegen` emits from, plus the activity count for the CLI's summary line. */
|
|
36
|
+
export interface ActiveRegistryProjection {
|
|
37
|
+
workflows: Record<string, CodegenWorkflowEntry>;
|
|
38
|
+
activities: Record<string, RegistryActivityEntry>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate an untrusted registry snapshot end-to-end: the version/envelope
|
|
42
|
+
* shape, every `workflows` manifest, and the `activeRevisions` pointer map,
|
|
43
|
+
* projecting the result down to what `weft codegen` actually emits from.
|
|
44
|
+
*
|
|
45
|
+
* Surfaces a clear version-mismatch diagnostic before delegating to the
|
|
46
|
+
* full envelope schema, since the version check is the most likely failure
|
|
47
|
+
* when consumers vendor a snapshot from an older or newer server.
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateRegistrySnapshot(value: unknown): Promise<ValidateSnapshotResult<ActiveRegistryProjection>>;
|