@lostgradient/weft 0.24.0 → 0.24.2
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 +2 -2
- package/dist/cli/conformance.js +5 -2
- package/dist/cli/generated/operation-catalog.snapshot.json +95 -1
- package/dist/cli/generated/operation-client.generated.d.ts +28 -2
- package/dist/cli/generated/operation-client.generated.js +2 -0
- package/dist/cli/parse-schedule-arguments.js +15 -3
- package/dist/cli/schedule.js +2 -1
- package/dist/cli/types.d.ts +2 -1
- package/dist/client/http-client-requests.js +6 -9
- package/dist/client/start-body.js +1 -0
- package/dist/core/catalog/index.d.ts +2 -2
- package/dist/core/catalog/index.js +9 -2
- package/dist/core/catalog/reference-counts.d.ts +29 -14
- package/dist/core/catalog/removal.d.ts +63 -10
- package/dist/core/catalog/removal.js +18 -2
- package/dist/core/catalog/storage-io.d.ts +23 -0
- package/dist/core/catalog/storage-io.js +1 -1
- package/dist/core/engine/activity-resolution.js +17 -17
- package/dist/core/engine/bulk-operations-purge.d.ts +1 -1
- package/dist/core/engine/bulk-operations-purge.js +17 -22
- package/dist/core/engine/bulk-operations-retry.d.ts +24 -0
- package/dist/core/engine/bulk-operations-retry.js +190 -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.d.ts +3 -2
- package/dist/core/engine/bulk-operations.js +10 -169
- package/dist/core/engine/callback-creators-bundles.js +5 -3
- 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-readiness.js +2 -0
- package/dist/core/engine/catalog-removal.d.ts +107 -3
- package/dist/core/engine/catalog-removal.js +66 -13
- 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/child-workflow.d.ts +13 -1
- package/dist/core/engine/child-workflow.js +22 -4
- package/dist/core/engine/constraints.js +5 -1
- package/dist/core/engine/construction.d.ts +1 -1
- 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 +24 -10
- 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 +10 -0
- package/dist/core/engine/engine-workflows-namespace.js +3 -1
- package/dist/core/engine/generation-codec.d.ts +22 -0
- package/dist/core/engine/generation-codec.js +2 -0
- package/dist/core/engine/index.d.ts +18 -10
- package/dist/core/engine/index.js +22 -11
- package/dist/core/engine/inline-launch-queue.js +1 -1
- package/dist/core/engine/internals.d.ts +26 -30
- 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-isolation.d.ts +20 -0
- package/dist/core/engine/lifecycle/recovery-isolation.js +26 -0
- 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-body.d.ts +44 -0
- package/dist/core/engine/lifecycle/resume-body.js +211 -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.d.ts +46 -3
- package/dist/core/engine/lifecycle/resume.js +21 -201
- package/dist/core/engine/lifecycle/shared.d.ts +43 -0
- package/dist/core/engine/lifecycle/standalone-claim-acquire.d.ts +80 -2
- package/dist/core/engine/lifecycle/standalone-claim-acquire.js +20 -4
- 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 +24 -7
- package/dist/core/engine/lifecycle/start-commit.js +57 -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-resolution.d.ts +8 -2
- package/dist/core/engine/lifecycle/start-or-signal-resolution.js +11 -3
- package/dist/core/engine/lifecycle/start-or-signal.js +1 -1
- package/dist/core/engine/lifecycle/start-precondition-attribution.d.ts +55 -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-schedule-timing.d.ts +11 -0
- package/dist/core/engine/lifecycle/start-schedule-timing.js +21 -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 +146 -4
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +33 -4
- package/dist/core/engine/lifecycle/start.d.ts +54 -7
- package/dist/core/engine/lifecycle/start.js +53 -90
- package/dist/core/engine/lifecycle/transition.d.ts +12 -4
- package/dist/core/engine/lifecycle/transition.js +40 -95
- package/dist/core/engine/lifecycle.d.ts +5 -2
- package/dist/core/engine/lifecycle.js +7 -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 +30 -0
- package/dist/core/engine/registration.js +17 -2
- 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-overlap.js +2 -1
- 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.d.ts +10 -0
- package/dist/core/engine/schedule-run.js +2 -1
- package/dist/core/engine/schedules.d.ts +11 -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.js +4 -2
- package/dist/core/engine/source-resolution.d.ts +25 -9
- package/dist/core/engine/source-resolution.js +49 -14
- 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/complete.js +1 -1
- 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/termination/suspend.js +3 -0
- 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 +29 -4
- package/dist/core/engine/validation/schedule.js +19 -36
- package/dist/core/engine/validation.js +13 -17
- package/dist/core/engine/workflow-claim-reclaim-target.d.ts +1 -1
- package/dist/core/engine/workflow-claim-reclaim-target.js +22 -8
- package/dist/core/engine/workflow-claim-registry.d.ts +79 -75
- package/dist/core/engine/workflow-claim-registry.js +15 -2
- package/dist/core/engine/workflow-generation-fence.d.ts +74 -0
- package/dist/core/engine/workflow-generation-fence.js +19 -0
- 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/event-map.d.ts +5 -0
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -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/start-workflow-validation.d.ts +15 -0
- package/dist/core/start-workflow-validation.js +11 -1
- 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/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +4 -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/core/workflow-identifiers.d.ts +37 -0
- package/dist/core/workflow-identifiers.js +19 -1
- 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 +3 -3
- package/dist/index.js +7 -0
- package/dist/indexeddb.js +1 -1
- package/dist/json-schema.js +3 -3
- package/dist/server/fault-to-json-rpc.js +2 -1
- package/dist/server/fleet-event-feed.js +6 -6
- package/dist/server/index.d.ts +11 -0
- package/dist/server/operation-fault.d.ts +2 -0
- package/dist/server/operation-fault.js +2 -1
- package/dist/server/operations/create-schedule.d.ts +2 -0
- package/dist/server/operations/create-schedule.js +10 -6
- package/dist/server/operations/get-catalog-diagnostics.d.ts +28 -0
- package/dist/server/operations/get-catalog-diagnostics.js +10 -2
- 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/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/static-registrations.js +6 -0
- 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.js +27 -0
- package/dist/server/rest-binding.d.ts +11 -0
- package/dist/server/runtime/task-dispatch-envelope.d.ts +41 -0
- package/dist/server/runtime/task-dispatch-envelope.js +54 -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.d.ts +3 -1
- package/dist/server/runtime/task-dispatch.js +20 -44
- 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-worker.js +9 -0
- package/dist/server/task-ledger-codec.d.ts +28 -0
- package/dist/server/task-ledger-codec.js +7 -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 +3 -1
- package/dist/server/task-queue-types.d.ts +2 -0
- package/dist/storage/bun-sql.js +135 -100
- package/dist/storage/catalog-keys.d.ts +19 -0
- package/dist/storage/catalog-keys.js +3 -1
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/generation-keys.d.ts +52 -0
- package/dist/storage/generation-keys.js +4 -0
- package/dist/storage/index.d.ts +76 -63
- package/dist/storage/interface.d.ts +24 -230
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +2 -0
- package/dist/storage/lease-keys.d.ts +48 -0
- package/dist/storage/lease-keys.js +8 -0
- package/dist/storage/lmdb.d.ts +30 -2
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +3 -3
- package/dist/storage/node-sqlite.js +135 -100
- package/dist/storage/postgres.js +3 -3
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/signal-keys.d.ts +23 -0
- package/dist/storage/signal-keys.js +9 -0
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/storage/workflow-lifecycle-keys.d.ts +128 -0
- package/dist/storage/workflow-lifecycle-keys.js +46 -0
- package/dist/storage/workflow-record-keys.d.ts +98 -0
- package/dist/storage/workflow-record-keys.js +47 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- 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,9 @@
|
|
|
1
|
+
import { encodeStorageKeyComponent } from "./key-encoding.js";
|
|
2
|
+
const SIGNAL_SORT_CLASS_START = "0", SIGNAL_SORT_CLASS_NORMAL = "1", signalStorageKey = (workflowId, name, id, sortClass) => `sig:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(name)}:${sortClass}:${encodeStorageKeyComponent(id)}`;
|
|
3
|
+
export const SIGNAL_KEYS = {
|
|
4
|
+
signal: (workflowId, name, id) => signalStorageKey(workflowId, name, id, SIGNAL_SORT_CLASS_NORMAL),
|
|
5
|
+
startSignal: (workflowId, name, id) => signalStorageKey(workflowId, name, id, SIGNAL_SORT_CLASS_START),
|
|
6
|
+
signalSequence: (workflowId) => `sigseq:v1:${encodeStorageKeyComponent(workflowId)}`,
|
|
7
|
+
signalAcceptedResponsePrefix: (workflowId) => `sigres:v1:${encodeStorageKeyComponent(workflowId)}:`,
|
|
8
|
+
signalAcceptedResponse: (workflowId, name, signalId) => `sigres:v1:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(name)}:${encodeStorageKeyComponent(signalId)}`
|
|
9
|
+
};
|
package/dist/storage/testing.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var V=import.meta.require;function v(t,e,n){if(!t.capabilities()[e])throw Error(`Feature "${n}" requires storage capability "${e}", but this storage backend does not provide it.`)}function L(t){let e=t.capabilities(),n=[];if(e.persistence!=="local"&&e.persistence!=="remote")n.push(`persistence must be "local" or "remote" (got "${e.persistence}")`);if(e.readAfterWrite!=="linearizable")n.push(`readAfterWrite must be "linearizable" (got "${e.readAfterWrite}")`);if(e.scanConsistency!=="snapshot")n.push(`scanConsistency must be "snapshot" (got "${e.scanConsistency}")`);if(!e.atomicBatch)n.push("atomicBatch must be true");if(!e.conditionalBatch)n.push("conditionalBatch must be true");if(n.length>0)throw Error(`Storage is not durable enough for recovery: ${n.join("; ")}.`)}function a(t){return encodeURIComponent(t)}function I(t){return decodeURIComponent(t)}function K(t){try{return decodeURIComponent(t)}catch{return null}}function l(t){return String(t).padStart(16,"0")}var B={catalogEntry:(t,e)=>`catalog-entry:${a(t)}:${a(e)}`,catalogEntryPrefix:(t)=>`catalog-entry:${a(t)}:`,catalogActive:(t)=>`catalog-active:${a(t)}`};var x="default";async function E(t,e){return await t.get(e)!==null}async function*y(t,e,n){for await(let[r]of t.scan(e,n))yield r}async function P(t,e){let n=0;for await(let r of y(t,e))n++;return n}async function O(t,e){let n=[];for await(let r of y(t,e))n.push({type:"delete",key:r});if(n.length===0)return 0;return await t.batch(n),n.length}async function Q(t,e,n){let r=[];for await(let o of y(t,e,n))r.push({type:"delete",key:o});if(r.length===0)return 0;return await t.batch(r),r.length}var A={applicationMailbox:(t,e)=>`appmbx:v1:${a(t)}:${a(e)}`,applicationMailboxSinkProbe:(t,e,n)=>`appprobe:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandPrefix:(t,e)=>`appcmd:v1:${a(t)}:${a(e)}:`,applicationCommand:(t,e,n)=>`appcmd:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandReadyPrefix:(t,e)=>`appready:v1:${a(t)}:${a(e)}:`,applicationCommandReady:(t,e,n)=>`appready:v1:${a(t)}:${a(e)}:${l(n)}`,applicationCommandIdempotency:(t,e,n)=>`appidem:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandBySequencePrefix:(t,e)=>`appseq:v1:${a(t)}:${a(e)}:`,applicationCommandBySequence:(t,e,n)=>`appseq:v1:${a(t)}:${a(e)}:${l(n)}`,applicationCommandTerminalPrefix:(t,e)=>`appterm:v1:${a(t)}:${a(e)}:`,applicationCommandTerminal:(t,e,n,r)=>`appterm:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`};var T={applicationOutbox:(t,e)=>`appobx:v1:${a(t)}:${a(e)}`,applicationOutboxSinkProbe:(t,e,n)=>`appprobe:v1:outbox:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryPrefix:(t,e)=>`appdlv:v1:${a(t)}:${a(e)}:`,applicationDelivery:(t,e,n)=>`appdlv:v1:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryDuePrefix:(t,e)=>`appdue:v1:${a(t)}:${a(e)}:`,applicationDeliveryDue:(t,e,n,r)=>`appdue:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`,applicationDeliveryIdempotency:(t,e,n)=>`appdidem:v1:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryBySequencePrefix:(t,e)=>`appdseq:v1:${a(t)}:${a(e)}:`,applicationDeliveryBySequence:(t,e,n)=>`appdseq:v1:${a(t)}:${a(e)}:${l(n)}`,applicationDeliveryTerminalPrefix:(t,e)=>`appdterm:v1:${a(t)}:${a(e)}:`,applicationDeliveryTerminal:(t,e,n,r)=>`appdterm:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`};var R={workflowOwnerEpoch:(t)=>`wf-owner-epoch:${a(t)}`,workflowOwnerHolder:(t)=>`wf-owner-holder:${a(t)}`,ownershipModeMarker:()=>"ownership-mode-marker"};var W=["actrec:","appcmd:","appdidem:","appdlv:","appdseq:","appdterm:","appdue:","appidem:","appmbx:","appobx:","appprobe:","appready:","appseq:","appterm:","archive:","async-act:","attr:","audit:bulk:","blob:","budget:","budget-charged:","catalog-active:","catalog-entry:","child-by-parent:","ev:","fleet-event-by-workflow:","fleet-event:","fleet-event-tail","fleet-event-watermark","idx:","lease:","liveness:","offload:","ownership-mode-marker","op:","review:","schedule:","schedule-due:","schedule-run-by-schedule:","schedule-run-link:","schedule-run:","sig:","sigres:","sigseq:","start-idem:","state:","tag:","tool-effect:","upd:","upk:","upr:","wf:","wf-cleanup:","wf-cleanup-needed:","wf-concurrency:","wf-concurrency-holder:","wf-deadline:","wf-delayed:","wf-finalizer-state:","wf-has-services:","wf-headers:","wf-idx-","wf-owner-epoch:","wf-owner-holder:","wf-teardown:","wf-teardown-deadletter:","wf-teardown-needed:","wf-teardown-succeeded:","wf-terminal:"];var C=1e4,ft=1e4;class _ extends Error{code="StorageBatchOperationLimitExceededError";cap=C;count;target;constructor(t,e){super(`${t} count ${e} exceeds MAX_BATCH_OPERATIONS (${C}).`);this.name="StorageBatchOperationLimitExceededError",this.target=t,this.count=e}}function k(t,e){if(e>C)throw new _(t,e)}function mt(t){return t.length>0?t.slice(0,-1)+String.fromCharCode(t.charCodeAt(t.length-1)+1):"\xFF"}function yt(t,e={}){if(e.gt!==void 0&&t<=e.gt)return!1;if(e.gte!==void 0&&t<e.gte)return!1;if(e.lt!==void 0&&t>=e.lt)return!1;if(e.lte!==void 0&&t>e.lte)return!1;return!0}function wt(t,e){if(t===null||e===null)return t===e;if(t.byteLength!==e.byteLength)return!1;for(let n=0;n<t.byteLength;n++)if(t[n]!==e[n])return!1;return!0}async function bt(t,e){if(t.has)return t.has(e);return E(t,e)}function $t(t,e,n){if(t.keys)return t.keys(e,n);return y(t,e,n)}async function ht(t,e){if(t.count)return t.count(e);return P(t,e)}async function St(t,e){if(t.deletePrefix)return t.deletePrefix(e);return O(t,e)}async function vt(t,e){k("batch operations",e.length),await t.batch(e)}async function b(t,e,n){if(k("conditionalBatch conditions",e.length),k("conditionalBatch operations",n.length),v(t,"conditionalBatch","storageConditionalBatch"),!t.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return t.conditionalBatch(e,n)}var g=l,M="0",U="1",q=(t,e,n,r)=>`sig:${a(t)}:${a(e)}:${r}:${a(n)}`,xt={workflow:(t)=>`wf:${a(t)}`,checkpoint:(t)=>`wf:${a(t)}:ckpt`,checkpointHistory:(t,e)=>`wf:${a(t)}:ckpt:${String(e).padStart(10,"0")}`,timelinePrefix:(t)=>`wf:${a(t)}:timeline:`,timeline:(t,e)=>`wf:${a(t)}:timeline:${String(e).padStart(10,"0")}`,schedule:(t)=>`schedule:${a(t)}`,scheduleTick:(t,e)=>`schedule-due:${String(t).padStart(16,"0")}:${a(e)}`,scheduleRun:(t)=>`schedule-run:${a(t)}`,scheduleRunLink:(t)=>`schedule-run-link:${a(t)}`,scheduleRunBySchedulePrefix:(t)=>`schedule-run-by-schedule:${a(t)}:`,scheduleRunBySchedule:(t,e)=>`schedule-run-by-schedule:${a(t)}:${a(e)}`,operation:(t,e,n)=>`op:${t}:${g(e)}:${n}`,operationInflight:(t)=>`op:inflight:${t}`,operationQueued:(t)=>`op:queued:${t}`,operationResolved:(t)=>`op:resolved:${t}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(t,e,n)=>`audit:bulk:${g(t)}:${a(e)}:${a(n)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(t,e)=>`op:resolved-by-time:${g(t)}:${a(e)}`,asyncActivity:(t,e)=>`async-act:v1:${a(t)}:${a(e)}`,asyncActivityResolution:(t,e)=>`async-act:v1:${a(t)}:${a(e)}:resolution`,activityReconciliationPrefix:(t)=>`actrec:v1:${a(t)}:`,activityReconciliation:(t,e,n)=>`actrec:v1:${a(t)}:${a(e)}:${n}`,eventPrefix:(t)=>`ev:${a(t)}:`,event:(t,e)=>`ev:${a(t)}:${String(e).padStart(10,"0")}`,eventHead:(t)=>`ev:${a(t)}:head`,eventWatermark:(t)=>`ev:${a(t)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(t)=>`fleet-event:${String(t).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventWatermark:()=>"fleet-event-watermark",fleetEventByWorkflowPrefix:(t)=>`fleet-event-by-workflow:${a(t)}:`,fleetEventByWorkflow:(t,e)=>`fleet-event-by-workflow:${a(t)}:${String(e).padStart(10,"0")}`,signal:(t,e,n)=>q(t,e,n,U),startSignal:(t,e,n)=>q(t,e,n,M),signalSequence:(t)=>`sigseq:v1:${a(t)}`,signalAcceptedResponsePrefix:(t)=>`sigres:v1:${a(t)}:`,signalAcceptedResponse:(t,e,n)=>`sigres:v1:${a(t)}:${a(e)}:${a(n)}`,deadline:(t,e)=>`wf-deadline:${g(t)}:${a(e)}`,terminalCleanup:(t,e)=>`wf-cleanup:${g(t)}:${a(e)}`,teardownTimer:(t,e)=>`wf-teardown:${g(t)}:${a(e)}`,delayedStart:(t,e)=>`wf-delayed:${g(t)}:${a(e)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(t,e)=>`wf-terminal:${g(t)}:${a(e)}`,attribute:(t)=>`attr:${a(t)}`,attributeIndex:(t,e,n)=>`idx:${t}:${e}:${a(n)}`,tagIndex:(t,e)=>`tag:${a(t)}:${a(e)}`,updatePrefix:(t)=>`upd:${a(t)}:`,update:(t,e)=>`upd:${a(t)}:${e}`,updateResponse:(t)=>`upr:${t}`,updateIdempotency:(t,e)=>`upk:${a(t)}:${e}`,startIdempotency:(t)=>`start-idem:${a(t)}`,startIdempotencySignalId:(t)=>`start-idem:${t}`,livenessPrefix:()=>"liveness:",liveness:(t)=>`liveness:${a(t)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder",...A,...T,...R,...B,budget:(t,e,n)=>`budget:${t}:${e}:${n}`,review:(t,e)=>`review:${a(t)}:${e}`,workflowHeaders:(t)=>`wf-headers:${a(t)}`,childCancellationPrefix:(t)=>`child-cancel:${a(t)}:`,childCancellation:(t,e)=>`child-cancel:${a(t)}:${a(e)}`,childWorkflowByParentPrefix:(t,e)=>`child-by-parent:${a(t)}:${e===void 0?"":`${a(e)}:`}`,childWorkflowByParent:(t,e,n)=>`child-by-parent:${a(t)}:${e===void 0?"":`${a(e)}:`}${a(n)}`,terminalCleanupNeeded:(t)=>`wf-cleanup-needed:${a(t)}`,workflowConcurrency:(t,e)=>`wf-concurrency:${a(t)}:${a(e)}`,workflowConcurrencyHolder:(t)=>`wf-concurrency-holder:${a(t)}`,workflowHasServices:(t)=>`wf-has-services:${a(t)}`,finalizerState:(t)=>`wf-finalizer-state:${a(t)}`,teardownOwed:(t)=>`wf-teardown-needed:${a(t)}`,teardownSucceeded:(t)=>`wf-teardown-succeeded:${a(t)}`,teardownDeadLetter:(t)=>`wf-teardown-deadletter:${a(t)}`,offload:(t,e)=>`offload:${a(t)}:${e}`,archive:(t,e)=>`archive:${a(t)}:${e}`,stateExecution:(t,e)=>`state:execution:${a(t)}:${a(e)}`,stateWorkflow:(t,e)=>`state:workflow-scope:${x}:${a(t)}:${a(e)}`,streamChunkPrefix:(t,e)=>`blob:${a(t)}:${e}:chunk:`,streamChunk:(t,e,n)=>`blob:${a(t)}:${e}:chunk:${String(n).padStart(10,"0")}`,streamTail:(t,e)=>`blob:${a(t)}:${e}:tail`,streamMetadata:(t,e)=>`blob:${a(t)}:${e}:meta`,budgetCharged:(t)=>`budget-charged:${t}`,toolEffect:(t,e,n)=>`tool-effect:${a(t)}:${e}:${n}`,workflowVisibilityStatus:(t,e)=>`wf-idx-status:${a(t)}:${a(e)}`,workflowVisibilityType:(t,e)=>`wf-idx-type:${a(t)}:${a(e)}`,workflowVisibilityCreated:(t,e)=>`wf-idx-created:${g(t)}:${a(e)}`,workflowVisibilityUpdated:(t,e)=>`wf-idx-updated:${g(t)}:${a(e)}`,workflowVisibilityDeadline:(t,e)=>`wf-idx-deadline:${g(t)}:${a(e)}`,workflowVisibilityManifest:(t)=>`wf-idx-manifest:${a(t)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};import{describe as h,expect as s,it as p}from"bun:test";import{expect as m}from"bun:test";var H=new TextEncoder,N=new TextDecoder;function i(t){return H.encode(t)}function w(t){return N.decode(t)}async function u(t){let e=[];for await(let n of t)e.push(n);return e}function D(t){let e=t.capabilities();m(["ephemeral","local","remote"]).toContain(e.persistence??""),m(["linearizable","session","eventual"]).toContain(e.readAfterWrite),m(["snapshot","best-effort"]).toContain(e.scanConsistency),m(typeof e.atomicBatch).toBe("boolean"),m(typeof e.conditionalBatch).toBe("boolean"),m(typeof e.boundedRangeDelete).toBe("boolean")}function _t(t,e){h(`${t} binary and large-scan conformance`,()=>{p("round-trips binary values correctly",async()=>{let n=await e.create();try{let r=new Uint8Array([0,1,127,128,255,42,0,13,10]);await n.put("binary",r);let o=await n.get("binary");s(o).toEqual(r)}finally{n[Symbol.dispose]()}}),p("returns 1000 scanned keys in sorted order",async()=>{let n=await e.create();try{let r=Array.from({length:1000},(c,d)=>({type:"put",key:`item:${String(d).padStart(4,"0")}`,value:i(String(d))}));await n.batch(r);let o=await u(n.scan("item:"));s(o).toHaveLength(1000);for(let c=0;c<o.length;c+=1)s(o[c][0]).toBe(`item:${String(c).padStart(4,"0")}`)}finally{n[Symbol.dispose]()}},e.largeScanTimeoutMs)})}function Dt(t,e){let{create:n,expected:r}=e;h(`${t} capabilities() conformance`,()=>{if(p("reports a well-formed capability shape",async()=>{using o=await n();D(o)}),p("reports the expected capability row",async()=>{using o=await n();s(o.capabilities()).toEqual(r)}),p("satisfies its declared read-after-write level",async()=>{using o=await n();await o.put("raw:key",i("written"));let c=await o.get("raw:key");if(r.readAfterWrite!=="eventual")s(c).not.toBeNull(),s(w(c)).toBe("written")}),r.scanConsistency==="snapshot")p("does not observe a key inserted after the scan began (snapshot)",async()=>{using o=await n();await o.put("scan:a",i("1")),await o.put("scan:b",i("2"));let c=o.scan("scan:")[Symbol.asyncIterator](),d=await c.next();s(d.done).toBe(!1),await o.put("scan:c",i("3"));let f=[];if(!d.done)f.push(d.value[0]);for(let S=await c.next();!S.done;S=await c.next())f.push(S.value[0]);s(f).not.toContain("scan:c"),s(f).toContain("scan:a"),s(f).toContain("scan:b")});if(r.conditionalBatch)p("applies nothing when a conditionalBatch precondition mismatches",async()=>{using o=await n();await o.put("cas:key",i("initial"));let c=await b(o,[{key:"cas:key",expectedValue:i("wrong")}],[{type:"put",key:"cas:key",value:i("changed")}]);s(c).toBe(!1),s(w(await o.get("cas:key"))).toBe("initial")}),p("reports conditionalBatch before running compare-and-swap assertions",async()=>{using o=await n();s(o.capabilities().conditionalBatch).toBe(!0)})})}function Lt(t,e){let{create:n}=e;h(`${t} concurrent conditionalBatch conformance`,()=>{p("lets exactly one of two contending conditionalBatch calls win",async()=>{using r=await n();s(r.capabilities().conditionalBatch).toBe(!0),await r.put("cas:counter",i("start"));let o=[{key:"cas:counter",expectedValue:i("start")}],[c,d]=await Promise.all([b(r,o,[{type:"put",key:"cas:counter",value:i("first")}]),b(r,o,[{type:"put",key:"cas:counter",value:i("second")}])]);s([c,d].filter(Boolean)).toHaveLength(1);let f=w(await r.get("cas:counter"));s(f).toBe(c?"first":"second")})})}function It(t,e){let{create:n}=e;h(`${t} basic storage contract`,()=>{p("get on empty storage returns null",async()=>{using r=await n();let o=await r.get("nonexistent");s(o).toBeNull()}),p("put then get returns same bytes",async()=>{using r=await n();let o=i("hello");await r.put("key",o);let c=await r.get("key");s(c).toEqual(o)}),p("put with same key overwrites previous value",async()=>{using r=await n();await r.put("key",i("first")),await r.put("key",i("second"));let o=await r.get("key");s(w(o)).toBe("second")}),p("delete removes key, subsequent get returns null",async()=>{using r=await n();await r.put("key",i("value")),await r.delete("key");let o=await r.get("key");s(o).toBeNull()}),p("delete on a missing key is a no-op",async()=>{using r=await n();await r.delete("nonexistent"),s(await r.get("nonexistent")).toBeNull()}),p("scan with prefix returns only matching keys, sorted lexicographically",async()=>{using r=await n();await r.put("wf:b",i("b")),await r.put("wf:a",i("a")),await r.put("wf:c",i("c")),await r.put("other:x",i("x"));let o=await u(r.scan("wf:"));s(o.map(([c])=>c)).toEqual(["wf:a","wf:b","wf:c"])}),p("scan with limit returns at most N entries",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c"));let o=await u(r.scan("p:",{limit:2}));s(o).toHaveLength(2),s(o.map(([c])=>c)).toEqual(["p:a","p:b"])}),p("scan with reverse returns in reverse order",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c"));let o=await u(r.scan("p:",{reverse:!0}));s(o.map(([c])=>c)).toEqual(["p:c","p:b","p:a"])}),p("scan with gt/lt bounds",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c")),await r.put("p:d",i("d"));let o=await u(r.scan("p:",{gt:"p:a",lt:"p:d"}));s(o.map(([c])=>c)).toEqual(["p:b","p:c"])}),p("scan with inclusive gte/lte bounds",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c")),await r.put("p:d",i("d"));let o=await u(r.scan("p:",{gte:"p:b",lte:"p:c"}));s(o.map(([c])=>c)).toEqual(["p:b","p:c"])}),p("scan with no matching keys returns no entries",async()=>{using r=await n();await r.put("other:a",i("a")),s(await u(r.scan("wf:"))).toHaveLength(0)}),p("batch with multiple puts stores every value",async()=>{using r=await n();await r.batch([{type:"put",key:"a",value:i("1")},{type:"put",key:"b",value:i("2")},{type:"put",key:"c",value:i("3")}]),s(await r.get("a")).toEqual(i("1")),s(await r.get("b")).toEqual(i("2")),s(await r.get("c")).toEqual(i("3"))}),p("batch with mixed puts and deletes leaves the expected state",async()=>{using r=await n();await r.put("keep",i("keep")),await r.put("remove",i("remove")),await r.batch([{type:"put",key:"new",value:i("new")},{type:"delete",key:"remove"}]),s(await r.get("keep")).toEqual(i("keep")),s(await r.get("remove")).toBeNull(),s(await r.get("new")).toEqual(i("new"))}),p("batch with no operations is a no-op",async()=>{using r=await n();await r.put("key",i("value")),await r.batch([]),s(await r.get("key")).toEqual(i("value"))}),p("scan with empty prefix returns all keys",async()=>{using r=await n();await r.put("alpha",i("a")),await r.put("beta",i("b")),await r.put("gamma",i("c"));let o=await u(r.scan(""));s(o.map(([c])=>c)).toEqual(["alpha","beta","gamma"])}),p("scan with empty prefix on empty storage returns no entries",async()=>{using r=await n();s(await u(r.scan(""))).toEqual([])})})}export{It as runBasicStorageContract,_t as runBinaryAndLargeScanStorageConformance,Lt as runConcurrentConditionalBatchConformance,Dt as runStorageCapabilityConformance};
|
|
2
|
+
var J=import.meta.require;function v(t,e,n){if(!t.capabilities()[e])throw Error(`Feature "${n}" requires storage capability "${e}", but this storage backend does not provide it.`)}function U(t){let e=t.capabilities(),n=[];if(e.persistence!=="local"&&e.persistence!=="remote")n.push(`persistence must be "local" or "remote" (got "${e.persistence}")`);if(e.readAfterWrite!=="linearizable")n.push(`readAfterWrite must be "linearizable" (got "${e.readAfterWrite}")`);if(e.scanConsistency!=="snapshot")n.push(`scanConsistency must be "snapshot" (got "${e.scanConsistency}")`);if(!e.atomicBatch)n.push("atomicBatch must be true");if(!e.conditionalBatch)n.push("conditionalBatch must be true");if(n.length>0)throw Error(`Storage is not durable enough for recovery: ${n.join("; ")}.`)}function a(t){return encodeURIComponent(t)}function H(t){return decodeURIComponent(t)}function X(t){try{return decodeURIComponent(t)}catch{return null}}function l(t){return String(t).padStart(16,"0")}var k={catalogEntry:(t,e)=>`catalog-entry:${a(t)}:${a(e)}`,catalogEntryPrefix:(t)=>`catalog-entry:${a(t)}:`,catalogActive:(t)=>`catalog-active:${a(t)}`,catalogTombstone:(t,e)=>`catalog-tombstone:${a(t)}:${a(e)}`,catalogTombstonePrefix:()=>"catalog-tombstone:"};async function B(t,e){return await t.get(e)!==null}async function*y(t,e,n){for await(let[r]of t.scan(e,n))yield r}async function _(t,e){let n=0;for await(let r of y(t,e))n++;return n}async function R(t,e){let n=[];for await(let r of y(t,e))n.push({type:"delete",key:r});if(n.length===0)return 0;return await t.batch(n),n.length}async function rt(t,e,n){let r=[];for await(let o of y(t,e,n))r.push({type:"delete",key:o});if(r.length===0)return 0;return await t.batch(r),r.length}var K={workflowGeneration:(t)=>`wf-gen:${a(t)}`};var A={livenessPrefix:()=>"liveness:",liveness:(t)=>`liveness:${a(t)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder"};var P={applicationMailbox:(t,e)=>`appmbx:v1:${a(t)}:${a(e)}`,applicationMailboxSinkProbe:(t,e,n)=>`appprobe:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandPrefix:(t,e)=>`appcmd:v1:${a(t)}:${a(e)}:`,applicationCommand:(t,e,n)=>`appcmd:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandReadyPrefix:(t,e)=>`appready:v1:${a(t)}:${a(e)}:`,applicationCommandReady:(t,e,n)=>`appready:v1:${a(t)}:${a(e)}:${l(n)}`,applicationCommandIdempotency:(t,e,n)=>`appidem:v1:${a(t)}:${a(e)}:${a(n)}`,applicationCommandBySequencePrefix:(t,e)=>`appseq:v1:${a(t)}:${a(e)}:`,applicationCommandBySequence:(t,e,n)=>`appseq:v1:${a(t)}:${a(e)}:${l(n)}`,applicationCommandTerminalPrefix:(t,e)=>`appterm:v1:${a(t)}:${a(e)}:`,applicationCommandTerminal:(t,e,n,r)=>`appterm:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`};var L={applicationOutbox:(t,e)=>`appobx:v1:${a(t)}:${a(e)}`,applicationOutboxSinkProbe:(t,e,n)=>`appprobe:v1:outbox:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryPrefix:(t,e)=>`appdlv:v1:${a(t)}:${a(e)}:`,applicationDelivery:(t,e,n)=>`appdlv:v1:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryDuePrefix:(t,e)=>`appdue:v1:${a(t)}:${a(e)}:`,applicationDeliveryDue:(t,e,n,r)=>`appdue:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`,applicationDeliveryIdempotency:(t,e,n)=>`appdidem:v1:${a(t)}:${a(e)}:${a(n)}`,applicationDeliveryBySequencePrefix:(t,e)=>`appdseq:v1:${a(t)}:${a(e)}:`,applicationDeliveryBySequence:(t,e,n)=>`appdseq:v1:${a(t)}:${a(e)}:${l(n)}`,applicationDeliveryTerminalPrefix:(t,e)=>`appdterm:v1:${a(t)}:${a(e)}:`,applicationDeliveryTerminal:(t,e,n,r)=>`appdterm:v1:${a(t)}:${a(e)}:${l(n)}:${a(r)}`};var T={workflowOwnerEpoch:(t)=>`wf-owner-epoch:${a(t)}`,workflowOwnerHolder:(t)=>`wf-owner-holder:${a(t)}`,ownershipModeMarker:()=>"ownership-mode-marker"};var V="0",G="1",D=(t,e,n,r)=>`sig:${a(t)}:${a(e)}:${r}:${a(n)}`,W={signal:(t,e,n)=>D(t,e,n,G),startSignal:(t,e,n)=>D(t,e,n,V),signalSequence:(t)=>`sigseq:v1:${a(t)}`,signalAcceptedResponsePrefix:(t)=>`sigres:v1:${a(t)}:`,signalAcceptedResponse:(t,e,n)=>`sigres:v1:${a(t)}:${a(e)}:${a(n)}`};var x="default";var d=l,I={deadline:(t,e)=>`wf-deadline:${d(t)}:${a(e)}`,terminalCleanup:(t,e)=>`wf-cleanup:${d(t)}:${a(e)}`,teardownTimer:(t,e)=>`wf-teardown:${d(t)}:${a(e)}`,delayedStart:(t,e)=>`wf-delayed:${d(t)}:${a(e)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(t,e)=>`wf-terminal:${d(t)}:${a(e)}`},Y={budget:(t,e,n)=>`budget:${t}:${e}:${n}`,review:(t,e)=>`review:${a(t)}:${e}`,workflowHeaders:(t)=>`wf-headers:${a(t)}`,childCancellationPrefix:(t)=>`child-cancel:${a(t)}:`,childCancellation:(t,e)=>`child-cancel:${a(t)}:${a(e)}`,childWorkflowByParentPrefix:(t,e)=>`child-by-parent:${a(t)}:${e===void 0?"":`${a(e)}:`}`,childWorkflowByParent:(t,e,n)=>`child-by-parent:${a(t)}:${e===void 0?"":`${a(e)}:`}${a(n)}`,terminalCleanupNeeded:(t)=>`wf-cleanup-needed:${a(t)}`,workflowConcurrency:(t,e)=>`wf-concurrency:${a(t)}:${a(e)}`,workflowConcurrencyHolder:(t)=>`wf-concurrency-holder:${a(t)}`,workflowHasServices:(t)=>`wf-has-services:${a(t)}`,finalizerState:(t)=>`wf-finalizer-state:${a(t)}`,teardownOwed:(t)=>`wf-teardown-needed:${a(t)}`,teardownSucceeded:(t)=>`wf-teardown-succeeded:${a(t)}`,teardownDeadLetter:(t)=>`wf-teardown-deadletter:${a(t)}`,offload:(t,e)=>`offload:${a(t)}:${e}`,archive:(t,e)=>`archive:${a(t)}:${e}`,stateExecution:(t,e)=>`state:execution:${a(t)}:${a(e)}`,stateWorkflow:(t,e)=>`state:workflow-scope:${x}:${a(t)}:${a(e)}`,streamChunkPrefix:(t,e)=>`blob:${a(t)}:${e}:chunk:`,streamChunk:(t,e,n)=>`blob:${a(t)}:${e}:chunk:${String(n).padStart(10,"0")}`,streamTail:(t,e)=>`blob:${a(t)}:${e}:tail`,streamMetadata:(t,e)=>`blob:${a(t)}:${e}:meta`,budgetCharged:(t)=>`budget-charged:${t}`,toolEffect:(t,e,n)=>`tool-effect:${a(t)}:${e}:${n}`,workflowVisibilityStatus:(t,e)=>`wf-idx-status:${a(t)}:${a(e)}`,workflowVisibilityType:(t,e)=>`wf-idx-type:${a(t)}:${a(e)}`,workflowVisibilityCreated:(t,e)=>`wf-idx-created:${d(t)}:${a(e)}`,workflowVisibilityUpdated:(t,e)=>`wf-idx-updated:${d(t)}:${a(e)}`,workflowVisibilityDeadline:(t,e)=>`wf-idx-deadline:${d(t)}:${a(e)}`,workflowVisibilityManifest:(t)=>`wf-idx-manifest:${a(t)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};var E=l,q={workflow:(t)=>`wf:${a(t)}`,checkpoint:(t)=>`wf:${a(t)}:ckpt`,checkpointHistory:(t,e)=>`wf:${a(t)}:ckpt:${String(e).padStart(10,"0")}`,timelinePrefix:(t)=>`wf:${a(t)}:timeline:`,timeline:(t,e)=>`wf:${a(t)}:timeline:${String(e).padStart(10,"0")}`,schedule:(t)=>`schedule:${a(t)}`,scheduleTick:(t,e)=>`schedule-due:${String(t).padStart(16,"0")}:${a(e)}`,scheduleRun:(t)=>`schedule-run:${a(t)}`,scheduleRunLink:(t)=>`schedule-run-link:${a(t)}`,scheduleRunBySchedulePrefix:(t)=>`schedule-run-by-schedule:${a(t)}:`,scheduleRunBySchedule:(t,e)=>`schedule-run-by-schedule:${a(t)}:${a(e)}`,operation:(t,e,n)=>`op:${t}:${E(e)}:${n}`,operationInflight:(t)=>`op:inflight:${t}`,operationQueued:(t)=>`op:queued:${t}`,operationResolved:(t)=>`op:resolved:${t}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(t,e,n)=>`audit:bulk:${E(t)}:${a(e)}:${a(n)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(t,e)=>`op:resolved-by-time:${E(t)}:${a(e)}`,asyncActivity:(t,e)=>`async-act:v1:${a(t)}:${a(e)}`,asyncActivityResolution:(t,e)=>`async-act:v1:${a(t)}:${a(e)}:resolution`,activityReconciliationPrefix:(t)=>`actrec:v1:${a(t)}:`,activityReconciliation:(t,e,n)=>`actrec:v1:${a(t)}:${a(e)}:${n}`,eventPrefix:(t)=>`ev:${a(t)}:`,event:(t,e)=>`ev:${a(t)}:${String(e).padStart(10,"0")}`,eventHead:(t)=>`ev:${a(t)}:head`,eventWatermark:(t)=>`ev:${a(t)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(t)=>`fleet-event:${String(t).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventWatermark:()=>"fleet-event-watermark",fleetEventByWorkflowPrefix:(t)=>`fleet-event-by-workflow:${a(t)}:`,fleetEventByWorkflow:(t,e)=>`fleet-event-by-workflow:${a(t)}:${String(e).padStart(10,"0")}`},N={attribute:(t)=>`attr:${a(t)}`,attributeIndex:(t,e,n)=>`idx:${t}:${e}:${a(n)}`,tagIndex:(t,e)=>`tag:${a(t)}:${a(e)}`,updatePrefix:(t)=>`upd:${a(t)}:`,update:(t,e)=>`upd:${a(t)}:${e}`,updateResponse:(t)=>`upr:${t}`,updateIdempotency:(t,e)=>`upk:${a(t)}:${e}`,startIdempotency:(t)=>`start-idem:${a(t)}`,startIdempotencySignalId:(t)=>`start-idem:${t}`};var z=["actrec:","appcmd:","appdidem:","appdlv:","appdseq:","appdterm:","appdue:","appidem:","appmbx:","appobx:","appprobe:","appready:","appseq:","appterm:","archive:","async-act:","attr:","audit:bulk:","blob:","budget:","budget-charged:","catalog-active:","catalog-entry:","catalog-tombstone:","child-by-parent:","ev:","fleet-event-by-workflow:","fleet-event:","fleet-event-tail","fleet-event-watermark","idx:","lease:","liveness:","offload:","ownership-mode-marker","op:","review:","schedule:","schedule-due:","schedule-run-by-schedule:","schedule-run-link:","schedule-run:","sig:","sigres:","sigseq:","start-idem:","state:","tag:","tool-effect:","upd:","upk:","upr:","wf:","wf-cleanup:","wf-cleanup-needed:","wf-concurrency:","wf-concurrency-holder:","wf-deadline:","wf-delayed:","wf-finalizer-state:","wf-gen:","wf-has-services:","wf-headers:","wf-idx-","wf-owner-epoch:","wf-owner-holder:","wf-teardown:","wf-teardown-deadletter:","wf-teardown-needed:","wf-teardown-succeeded:","wf-terminal:"];var C=1e4,Dt=1e4;class F extends Error{code="StorageBatchOperationLimitExceededError";cap=C;count;target;constructor(t,e){super(`${t} count ${e} exceeds MAX_BATCH_OPERATIONS (${C}).`);this.name="StorageBatchOperationLimitExceededError",this.target=t,this.count=e}}function O(t,e){if(e>C)throw new F(t,e)}function Wt(t){return t.length>0?t.slice(0,-1)+String.fromCharCode(t.charCodeAt(t.length-1)+1):"\xFF"}function It(t,e={}){if(e.gt!==void 0&&t<=e.gt)return!1;if(e.gte!==void 0&&t<e.gte)return!1;if(e.lt!==void 0&&t>=e.lt)return!1;if(e.lte!==void 0&&t>e.lte)return!1;return!0}function Yt(t,e){if(t===null||e===null)return t===e;if(t.byteLength!==e.byteLength)return!1;for(let n=0;n<t.byteLength;n++)if(t[n]!==e[n])return!1;return!0}async function qt(t,e){if(t.has)return t.has(e);return B(t,e)}function Nt(t,e,n){if(t.keys)return t.keys(e,n);return y(t,e,n)}async function Ft(t,e){if(t.count)return t.count(e);return _(t,e)}async function Mt(t,e){if(t.deletePrefix)return t.deletePrefix(e);return R(t,e)}async function Ut(t,e){O("batch operations",e.length),await t.batch(e)}async function b(t,e,n){if(O("conditionalBatch conditions",e.length),O("conditionalBatch operations",n.length),v(t,"conditionalBatch","storageConditionalBatch"),!t.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return t.conditionalBatch(e,n)}var Ht={...q,...W,...I,...N,...A,...P,...L,...T,...k,...K,...Y};import{describe as h,expect as s,it as p}from"bun:test";import{expect as m}from"bun:test";var j=new TextEncoder,Q=new TextDecoder;function i(t){return j.encode(t)}function w(t){return Q.decode(t)}async function g(t){let e=[];for await(let n of t)e.push(n);return e}function M(t){let e=t.capabilities();m(["ephemeral","local","remote"]).toContain(e.persistence??""),m(["linearizable","session","eventual"]).toContain(e.readAfterWrite),m(["snapshot","best-effort"]).toContain(e.scanConsistency),m(typeof e.atomicBatch).toBe("boolean"),m(typeof e.conditionalBatch).toBe("boolean"),m(typeof e.boundedRangeDelete).toBe("boolean")}function ae(t,e){h(`${t} binary and large-scan conformance`,()=>{p("round-trips binary values correctly",async()=>{let n=await e.create();try{let r=new Uint8Array([0,1,127,128,255,42,0,13,10]);await n.put("binary",r);let o=await n.get("binary");s(o).toEqual(r)}finally{n[Symbol.dispose]()}}),p("returns 1000 scanned keys in sorted order",async()=>{let n=await e.create();try{let r=Array.from({length:1000},(c,u)=>({type:"put",key:`item:${String(u).padStart(4,"0")}`,value:i(String(u))}));await n.batch(r);let o=await g(n.scan("item:"));s(o).toHaveLength(1000);for(let c=0;c<o.length;c+=1)s(o[c][0]).toBe(`item:${String(c).padStart(4,"0")}`)}finally{n[Symbol.dispose]()}},e.largeScanTimeoutMs)})}function ne(t,e){let{create:n,expected:r}=e;h(`${t} capabilities() conformance`,()=>{if(p("reports a well-formed capability shape",async()=>{using o=await n();M(o)}),p("reports the expected capability row",async()=>{using o=await n();s(o.capabilities()).toEqual(r)}),p("satisfies its declared read-after-write level",async()=>{using o=await n();await o.put("raw:key",i("written"));let c=await o.get("raw:key");if(r.readAfterWrite!=="eventual")s(c).not.toBeNull(),s(w(c)).toBe("written")}),r.scanConsistency==="snapshot")p("does not observe a key inserted after the scan began (snapshot)",async()=>{using o=await n();await o.put("scan:a",i("1")),await o.put("scan:b",i("2"));let c=o.scan("scan:")[Symbol.asyncIterator](),u=await c.next();s(u.done).toBe(!1),await o.put("scan:c",i("3"));let f=[];if(!u.done)f.push(u.value[0]);for(let S=await c.next();!S.done;S=await c.next())f.push(S.value[0]);s(f).not.toContain("scan:c"),s(f).toContain("scan:a"),s(f).toContain("scan:b")});if(r.conditionalBatch)p("applies nothing when a conditionalBatch precondition mismatches",async()=>{using o=await n();await o.put("cas:key",i("initial"));let c=await b(o,[{key:"cas:key",expectedValue:i("wrong")}],[{type:"put",key:"cas:key",value:i("changed")}]);s(c).toBe(!1),s(w(await o.get("cas:key"))).toBe("initial")}),p("reports conditionalBatch before running compare-and-swap assertions",async()=>{using o=await n();s(o.capabilities().conditionalBatch).toBe(!0)})})}function re(t,e){let{create:n}=e;h(`${t} concurrent conditionalBatch conformance`,()=>{p("lets exactly one of two contending conditionalBatch calls win",async()=>{using r=await n();s(r.capabilities().conditionalBatch).toBe(!0),await r.put("cas:counter",i("start"));let o=[{key:"cas:counter",expectedValue:i("start")}],[c,u]=await Promise.all([b(r,o,[{type:"put",key:"cas:counter",value:i("first")}]),b(r,o,[{type:"put",key:"cas:counter",value:i("second")}])]);s([c,u].filter(Boolean)).toHaveLength(1);let f=w(await r.get("cas:counter"));s(f).toBe(c?"first":"second")})})}function ie(t,e){let{create:n}=e;h(`${t} basic storage contract`,()=>{p("get on empty storage returns null",async()=>{using r=await n();let o=await r.get("nonexistent");s(o).toBeNull()}),p("put then get returns same bytes",async()=>{using r=await n();let o=i("hello");await r.put("key",o);let c=await r.get("key");s(c).toEqual(o)}),p("put with same key overwrites previous value",async()=>{using r=await n();await r.put("key",i("first")),await r.put("key",i("second"));let o=await r.get("key");s(w(o)).toBe("second")}),p("delete removes key, subsequent get returns null",async()=>{using r=await n();await r.put("key",i("value")),await r.delete("key");let o=await r.get("key");s(o).toBeNull()}),p("delete on a missing key is a no-op",async()=>{using r=await n();await r.delete("nonexistent"),s(await r.get("nonexistent")).toBeNull()}),p("scan with prefix returns only matching keys, sorted lexicographically",async()=>{using r=await n();await r.put("wf:b",i("b")),await r.put("wf:a",i("a")),await r.put("wf:c",i("c")),await r.put("other:x",i("x"));let o=await g(r.scan("wf:"));s(o.map(([c])=>c)).toEqual(["wf:a","wf:b","wf:c"])}),p("scan with limit returns at most N entries",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c"));let o=await g(r.scan("p:",{limit:2}));s(o).toHaveLength(2),s(o.map(([c])=>c)).toEqual(["p:a","p:b"])}),p("scan with reverse returns in reverse order",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c"));let o=await g(r.scan("p:",{reverse:!0}));s(o.map(([c])=>c)).toEqual(["p:c","p:b","p:a"])}),p("scan with gt/lt bounds",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c")),await r.put("p:d",i("d"));let o=await g(r.scan("p:",{gt:"p:a",lt:"p:d"}));s(o.map(([c])=>c)).toEqual(["p:b","p:c"])}),p("scan with inclusive gte/lte bounds",async()=>{using r=await n();await r.put("p:a",i("a")),await r.put("p:b",i("b")),await r.put("p:c",i("c")),await r.put("p:d",i("d"));let o=await g(r.scan("p:",{gte:"p:b",lte:"p:c"}));s(o.map(([c])=>c)).toEqual(["p:b","p:c"])}),p("scan with no matching keys returns no entries",async()=>{using r=await n();await r.put("other:a",i("a")),s(await g(r.scan("wf:"))).toHaveLength(0)}),p("batch with multiple puts stores every value",async()=>{using r=await n();await r.batch([{type:"put",key:"a",value:i("1")},{type:"put",key:"b",value:i("2")},{type:"put",key:"c",value:i("3")}]),s(await r.get("a")).toEqual(i("1")),s(await r.get("b")).toEqual(i("2")),s(await r.get("c")).toEqual(i("3"))}),p("batch with mixed puts and deletes leaves the expected state",async()=>{using r=await n();await r.put("keep",i("keep")),await r.put("remove",i("remove")),await r.batch([{type:"put",key:"new",value:i("new")},{type:"delete",key:"remove"}]),s(await r.get("keep")).toEqual(i("keep")),s(await r.get("remove")).toBeNull(),s(await r.get("new")).toEqual(i("new"))}),p("batch with no operations is a no-op",async()=>{using r=await n();await r.put("key",i("value")),await r.batch([]),s(await r.get("key")).toEqual(i("value"))}),p("scan with empty prefix returns all keys",async()=>{using r=await n();await r.put("alpha",i("a")),await r.put("beta",i("b")),await r.put("gamma",i("c"));let o=await g(r.scan(""));s(o.map(([c])=>c)).toEqual(["alpha","beta","gamma"])}),p("scan with empty prefix on empty storage returns no entries",async()=>{using r=await n();s(await g(r.scan(""))).toEqual([])})})}export{ie as runBasicStorageContract,ae as runBinaryAndLargeScanStorageConformance,re as runConcurrentConditionalBatchConformance,ne as runStorageCapabilityConformance};
|
package/dist/storage/turso.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var Oe=import.meta.require;function S(e,t,r){if(!e.capabilities()[t])throw Error(`Feature "${r}" requires storage capability "${t}", but this storage backend does not provide it.`)}function ie(e){let t=e.capabilities(),r=[];if(t.persistence!=="local"&&t.persistence!=="remote")r.push(`persistence must be "local" or "remote" (got "${t.persistence}")`);if(t.readAfterWrite!=="linearizable")r.push(`readAfterWrite must be "linearizable" (got "${t.readAfterWrite}")`);if(t.scanConsistency!=="snapshot")r.push(`scanConsistency must be "snapshot" (got "${t.scanConsistency}")`);if(!t.atomicBatch)r.push("atomicBatch must be true");if(!t.conditionalBatch)r.push("conditionalBatch must be true");if(r.length>0)throw Error(`Storage is not durable enough for recovery: ${r.join("; ")}.`)}function n(e){return encodeURIComponent(e)}function ae(e){return decodeURIComponent(e)}function oe(e){try{return decodeURIComponent(e)}catch{return null}}function s(e){return String(e).padStart(16,"0")}var v={catalogEntry:(e,t)=>`catalog-entry:${n(e)}:${n(t)}`,catalogEntryPrefix:(e)=>`catalog-entry:${n(e)}:`,catalogActive:(e)=>`catalog-active:${n(e)}`};var w="default";async function O(e,t){return await e.get(t)!==null}async function*p(e,t,r){for await(let[i]of e.scan(t,r))yield i}async function C(e,t){let r=0;for await(let i of p(e,t))r++;return r}async function k(e,t){let r=[];for await(let i of p(e,t))r.push({type:"delete",key:i});if(r.length===0)return 0;return await e.batch(r),r.length}async function T(e,t,r){let i=[];for await(let a of p(e,t,r))i.push({type:"delete",key:a});if(i.length===0)return 0;return await e.batch(i),i.length}var P={applicationMailbox:(e,t)=>`appmbx:v1:${n(e)}:${n(t)}`,applicationMailboxSinkProbe:(e,t,r)=>`appprobe:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandPrefix:(e,t)=>`appcmd:v1:${n(e)}:${n(t)}:`,applicationCommand:(e,t,r)=>`appcmd:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandReadyPrefix:(e,t)=>`appready:v1:${n(e)}:${n(t)}:`,applicationCommandReady:(e,t,r)=>`appready:v1:${n(e)}:${n(t)}:${s(r)}`,applicationCommandIdempotency:(e,t,r)=>`appidem:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandBySequencePrefix:(e,t)=>`appseq:v1:${n(e)}:${n(t)}:`,applicationCommandBySequence:(e,t,r)=>`appseq:v1:${n(e)}:${n(t)}:${s(r)}`,applicationCommandTerminalPrefix:(e,t)=>`appterm:v1:${n(e)}:${n(t)}:`,applicationCommandTerminal:(e,t,r,i)=>`appterm:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`};var B={applicationOutbox:(e,t)=>`appobx:v1:${n(e)}:${n(t)}`,applicationOutboxSinkProbe:(e,t,r)=>`appprobe:v1:outbox:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryPrefix:(e,t)=>`appdlv:v1:${n(e)}:${n(t)}:`,applicationDelivery:(e,t,r)=>`appdlv:v1:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryDuePrefix:(e,t)=>`appdue:v1:${n(e)}:${n(t)}:`,applicationDeliveryDue:(e,t,r,i)=>`appdue:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`,applicationDeliveryIdempotency:(e,t,r)=>`appdidem:v1:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryBySequencePrefix:(e,t)=>`appdseq:v1:${n(e)}:${n(t)}:`,applicationDeliveryBySequence:(e,t,r)=>`appdseq:v1:${n(e)}:${n(t)}:${s(r)}`,applicationDeliveryTerminalPrefix:(e,t)=>`appdterm:v1:${n(e)}:${n(t)}:`,applicationDeliveryTerminal:(e,t,r,i)=>`appdterm:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`};var A={workflowOwnerEpoch:(e)=>`wf-owner-epoch:${n(e)}`,workflowOwnerHolder:(e)=>`wf-owner-holder:${n(e)}`,ownershipModeMarker:()=>"ownership-mode-marker"};var se=["actrec:","appcmd:","appdidem:","appdlv:","appdseq:","appdterm:","appdue:","appidem:","appmbx:","appobx:","appprobe:","appready:","appseq:","appterm:","archive:","async-act:","attr:","audit:bulk:","blob:","budget:","budget-charged:","catalog-active:","catalog-entry:","child-by-parent:","ev:","fleet-event-by-workflow:","fleet-event:","fleet-event-tail","fleet-event-watermark","idx:","lease:","liveness:","offload:","ownership-mode-marker","op:","review:","schedule:","schedule-due:","schedule-run-by-schedule:","schedule-run-link:","schedule-run:","sig:","sigres:","sigseq:","start-idem:","state:","tag:","tool-effect:","upd:","upk:","upr:","wf:","wf-cleanup:","wf-cleanup-needed:","wf-concurrency:","wf-concurrency-holder:","wf-deadline:","wf-delayed:","wf-finalizer-state:","wf-has-services:","wf-headers:","wf-idx-","wf-owner-epoch:","wf-owner-holder:","wf-teardown:","wf-teardown-deadletter:","wf-teardown-needed:","wf-teardown-succeeded:","wf-terminal:"];var b=1e4,Xe=1e4;class D extends Error{code="StorageBatchOperationLimitExceededError";cap=b;count;target;constructor(e,t){super(`${e} count ${t} exceeds MAX_BATCH_OPERATIONS (${b}).`);this.name="StorageBatchOperationLimitExceededError",this.target=e,this.count=t}}function u(e,t){if(t>b)throw new D(e,t)}function L(e){return e.length>0?e.slice(0,-1)+String.fromCharCode(e.charCodeAt(e.length-1)+1):"\xFF"}function Ge(e,t={}){if(t.gt!==void 0&&e<=t.gt)return!1;if(t.gte!==void 0&&e<t.gte)return!1;if(t.lt!==void 0&&e>=t.lt)return!1;if(t.lte!==void 0&&e>t.lte)return!1;return!0}function I(e,t){if(e===null||t===null)return e===t;if(e.byteLength!==t.byteLength)return!1;for(let r=0;r<e.byteLength;r++)if(e[r]!==t[r])return!1;return!0}async function q(e,t){if(e.has)return e.has(t);return O(e,t)}function K(e,t,r){if(e.keys)return e.keys(t,r);return p(e,t,r)}async function N(e,t){if(e.count)return e.count(t);return C(e,t)}async function U(e,t){if(e.deletePrefix)return e.deletePrefix(t);return k(e,t)}async function je(e,t){u("batch operations",t.length),await e.batch(t)}async function M(e,t,r){if(u("conditionalBatch conditions",t.length),u("conditionalBatch operations",r.length),S(e,"conditionalBatch","storageConditionalBatch"),!e.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return e.conditionalBatch(t,r)}var l=s,le="0",ce="1",_=(e,t,r,i)=>`sig:${n(e)}:${n(t)}:${i}:${n(r)}`,Ze={workflow:(e)=>`wf:${n(e)}`,checkpoint:(e)=>`wf:${n(e)}:ckpt`,checkpointHistory:(e,t)=>`wf:${n(e)}:ckpt:${String(t).padStart(10,"0")}`,timelinePrefix:(e)=>`wf:${n(e)}:timeline:`,timeline:(e,t)=>`wf:${n(e)}:timeline:${String(t).padStart(10,"0")}`,schedule:(e)=>`schedule:${n(e)}`,scheduleTick:(e,t)=>`schedule-due:${String(e).padStart(16,"0")}:${n(t)}`,scheduleRun:(e)=>`schedule-run:${n(e)}`,scheduleRunLink:(e)=>`schedule-run-link:${n(e)}`,scheduleRunBySchedulePrefix:(e)=>`schedule-run-by-schedule:${n(e)}:`,scheduleRunBySchedule:(e,t)=>`schedule-run-by-schedule:${n(e)}:${n(t)}`,operation:(e,t,r)=>`op:${e}:${l(t)}:${r}`,operationInflight:(e)=>`op:inflight:${e}`,operationQueued:(e)=>`op:queued:${e}`,operationResolved:(e)=>`op:resolved:${e}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(e,t,r)=>`audit:bulk:${l(e)}:${n(t)}:${n(r)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(e,t)=>`op:resolved-by-time:${l(e)}:${n(t)}`,asyncActivity:(e,t)=>`async-act:v1:${n(e)}:${n(t)}`,asyncActivityResolution:(e,t)=>`async-act:v1:${n(e)}:${n(t)}:resolution`,activityReconciliationPrefix:(e)=>`actrec:v1:${n(e)}:`,activityReconciliation:(e,t,r)=>`actrec:v1:${n(e)}:${n(t)}:${r}`,eventPrefix:(e)=>`ev:${n(e)}:`,event:(e,t)=>`ev:${n(e)}:${String(t).padStart(10,"0")}`,eventHead:(e)=>`ev:${n(e)}:head`,eventWatermark:(e)=>`ev:${n(e)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(e)=>`fleet-event:${String(e).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventWatermark:()=>"fleet-event-watermark",fleetEventByWorkflowPrefix:(e)=>`fleet-event-by-workflow:${n(e)}:`,fleetEventByWorkflow:(e,t)=>`fleet-event-by-workflow:${n(e)}:${String(t).padStart(10,"0")}`,signal:(e,t,r)=>_(e,t,r,ce),startSignal:(e,t,r)=>_(e,t,r,le),signalSequence:(e)=>`sigseq:v1:${n(e)}`,signalAcceptedResponsePrefix:(e)=>`sigres:v1:${n(e)}:`,signalAcceptedResponse:(e,t,r)=>`sigres:v1:${n(e)}:${n(t)}:${n(r)}`,deadline:(e,t)=>`wf-deadline:${l(e)}:${n(t)}`,terminalCleanup:(e,t)=>`wf-cleanup:${l(e)}:${n(t)}`,teardownTimer:(e,t)=>`wf-teardown:${l(e)}:${n(t)}`,delayedStart:(e,t)=>`wf-delayed:${l(e)}:${n(t)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(e,t)=>`wf-terminal:${l(e)}:${n(t)}`,attribute:(e)=>`attr:${n(e)}`,attributeIndex:(e,t,r)=>`idx:${e}:${t}:${n(r)}`,tagIndex:(e,t)=>`tag:${n(e)}:${n(t)}`,updatePrefix:(e)=>`upd:${n(e)}:`,update:(e,t)=>`upd:${n(e)}:${t}`,updateResponse:(e)=>`upr:${e}`,updateIdempotency:(e,t)=>`upk:${n(e)}:${t}`,startIdempotency:(e)=>`start-idem:${n(e)}`,startIdempotencySignalId:(e)=>`start-idem:${e}`,livenessPrefix:()=>"liveness:",liveness:(e)=>`liveness:${n(e)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder",...P,...B,...A,...v,budget:(e,t,r)=>`budget:${e}:${t}:${r}`,review:(e,t)=>`review:${n(e)}:${t}`,workflowHeaders:(e)=>`wf-headers:${n(e)}`,childCancellationPrefix:(e)=>`child-cancel:${n(e)}:`,childCancellation:(e,t)=>`child-cancel:${n(e)}:${n(t)}`,childWorkflowByParentPrefix:(e,t)=>`child-by-parent:${n(e)}:${t===void 0?"":`${n(t)}:`}`,childWorkflowByParent:(e,t,r)=>`child-by-parent:${n(e)}:${t===void 0?"":`${n(t)}:`}${n(r)}`,terminalCleanupNeeded:(e)=>`wf-cleanup-needed:${n(e)}`,workflowConcurrency:(e,t)=>`wf-concurrency:${n(e)}:${n(t)}`,workflowConcurrencyHolder:(e)=>`wf-concurrency-holder:${n(e)}`,workflowHasServices:(e)=>`wf-has-services:${n(e)}`,finalizerState:(e)=>`wf-finalizer-state:${n(e)}`,teardownOwed:(e)=>`wf-teardown-needed:${n(e)}`,teardownSucceeded:(e)=>`wf-teardown-succeeded:${n(e)}`,teardownDeadLetter:(e)=>`wf-teardown-deadletter:${n(e)}`,offload:(e,t)=>`offload:${n(e)}:${t}`,archive:(e,t)=>`archive:${n(e)}:${t}`,stateExecution:(e,t)=>`state:execution:${n(e)}:${n(t)}`,stateWorkflow:(e,t)=>`state:workflow-scope:${w}:${n(e)}:${n(t)}`,streamChunkPrefix:(e,t)=>`blob:${n(e)}:${t}:chunk:`,streamChunk:(e,t,r)=>`blob:${n(e)}:${t}:chunk:${String(r).padStart(10,"0")}`,streamTail:(e,t)=>`blob:${n(e)}:${t}:tail`,streamMetadata:(e,t)=>`blob:${n(e)}:${t}:meta`,budgetCharged:(e)=>`budget-charged:${e}`,toolEffect:(e,t,r)=>`tool-effect:${n(e)}:${t}:${r}`,workflowVisibilityStatus:(e,t)=>`wf-idx-status:${n(e)}:${n(t)}`,workflowVisibilityType:(e,t)=>`wf-idx-type:${n(e)}:${n(t)}`,workflowVisibilityCreated:(e,t)=>`wf-idx-created:${l(e)}:${n(t)}`,workflowVisibilityUpdated:(e,t)=>`wf-idx-updated:${l(e)}:${n(t)}`,workflowVisibilityDeadline:(e,t)=>`wf-idx-deadline:${l(e)}:${n(t)}`,workflowVisibilityManifest:(e)=>`wf-idx-manifest:${n(e)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};function ge(e){if(e===void 0)return;if(typeof e!=="number"||!Number.isInteger(e)||e<0)throw Error("deleteRange limit must be a finite non-negative integer");return e===0?0:e}function d(e){let t={},r=!1;for(let a of["gt","gte","lt","lte"]){let o=e[a];if(o===void 0)continue;if(typeof o!=="string")throw Error("deleteRange bounds must be strings");t[a]=o,r=!0}if(!r)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let i=ge(e.limit);if(i!==void 0)t.limit=i;return t}async function Y(e,t,r){let i=d(r);if(e.deleteRange)return e.deleteRange(t,i);return T(e,t,i)}function E(e){return e.replaceAll(/:+$/g,"")}function ue(e,t){let r=E(e),i=E(t);if(r.length===0)return i;if(i.length===0)return r;return`${r}:${i}`}class x{#e;#r;constructor(e,t){this.#e=e,this.#r=E(t)}#t(e){if(this.#r.length===0)return e;return e.length===0?`${this.#r}:`:`${this.#r}:${e}`}#n(e){return e.map((t)=>{if(t.type==="put")return{type:"put",key:this.#t(t.key),value:t.value};return{type:"delete",key:this.#t(t.key)}})}#i(e){if(this.#r.length===0)return e;return e.slice(this.#r.length+1)}#a(e){let t={};if(e.limit!==void 0)t.limit=e.limit;if(e.gt!==void 0)t.gt=this.#t(e.gt);if(e.gte!==void 0)t.gte=this.#t(e.gte);if(e.lt!==void 0)t.lt=this.#t(e.lt);if(e.lte!==void 0)t.lte=this.#t(e.lte);return t}#o(e={}){let t=this.#a(e);if(e.reverse!==void 0)t.reverse=e.reverse;return t}#s(e){return this.#a(e)}capabilities(){return this.#e.capabilities()}scoped(e){return new x(this.#e,ue(this.#r,e))}async get(e){return this.#e.get(this.#t(e))}async put(e,t){await this.#e.put(this.#t(e),t)}async delete(e){await this.#e.delete(this.#t(e))}async*scan(e,t){for await(let[r,i]of this.#e.scan(this.#t(e),this.#o(t)))yield[this.#i(r),i]}async batch(e){u("batch operations",e.length),await this.#e.batch(this.#n(e))}async conditionalBatch(e,t){return M(this.#e,e.map((r)=>({key:this.#t(r.key),expectedValue:r.expectedValue})),this.#n(t))}async has(e){return q(this.#e,this.#t(e))}async deletePrefix(e){return U(this.#e,this.#t(e))}async deleteRange(e,t){let r=this.#s(d(t));return Y(this.#e,this.#t(e),r)}async*keys(e,t){for await(let r of K(this.#e,this.#t(e),this.#o(t)))yield this.#i(r)}async count(e){return N(this.#e,this.#t(e))}[Symbol.dispose](){this.#e[Symbol.dispose]()}}function W(e,t){return new x(e,t)}import{createClient as he}from"@libsql/client";var pe=/^PRAGMA\b/iu,de=/^PRAGMA\s+(?:[A-Z_][A-Z0-9_]*\.)?[A-Z_][A-Z0-9_]*\s*$/iu,fe=/^SELECT\b/iu;function me(e){return e.trim().replace(/;+\s*$/u,"").trim()}function ye(e){return de.test(e)}function V(e){let t=me(e);if(t.length===0)throw Error("Storage query must not be empty.");if(t.includes(";"))throw Error("Storage query must contain exactly one read-only statement.");if(fe.test(t))return;if(pe.test(t)&&ye(t))return;throw Error("Storage query only supports read-only SELECT and PRAGMA statements.")}var Q=`CREATE TABLE IF NOT EXISTS kv (
|
|
2
|
+
var Ae=import.meta.require;function h(e,t,r){if(!e.capabilities()[t])throw Error(`Feature "${r}" requires storage capability "${t}", but this storage backend does not provide it.`)}function pe(e){let t=e.capabilities(),r=[];if(t.persistence!=="local"&&t.persistence!=="remote")r.push(`persistence must be "local" or "remote" (got "${t.persistence}")`);if(t.readAfterWrite!=="linearizable")r.push(`readAfterWrite must be "linearizable" (got "${t.readAfterWrite}")`);if(t.scanConsistency!=="snapshot")r.push(`scanConsistency must be "snapshot" (got "${t.scanConsistency}")`);if(!t.atomicBatch)r.push("atomicBatch must be true");if(!t.conditionalBatch)r.push("conditionalBatch must be true");if(r.length>0)throw Error(`Storage is not durable enough for recovery: ${r.join("; ")}.`)}function n(e){return encodeURIComponent(e)}function de(e){return decodeURIComponent(e)}function fe(e){try{return decodeURIComponent(e)}catch{return null}}function s(e){return String(e).padStart(16,"0")}var C={catalogEntry:(e,t)=>`catalog-entry:${n(e)}:${n(t)}`,catalogEntryPrefix:(e)=>`catalog-entry:${n(e)}:`,catalogActive:(e)=>`catalog-active:${n(e)}`,catalogTombstone:(e,t)=>`catalog-tombstone:${n(e)}:${n(t)}`,catalogTombstonePrefix:()=>"catalog-tombstone:"};async function v(e,t){return await e.get(t)!==null}async function*p(e,t,r){for await(let[i]of e.scan(t,r))yield i}async function T(e,t){let r=0;for await(let i of p(e,t))r++;return r}async function _(e,t){let r=[];for await(let i of p(e,t))r.push({type:"delete",key:i});if(r.length===0)return 0;return await e.batch(r),r.length}async function k(e,t,r){let i=[];for await(let a of p(e,t,r))i.push({type:"delete",key:a});if(i.length===0)return 0;return await e.batch(i),i.length}var P={workflowGeneration:(e)=>`wf-gen:${n(e)}`};var B={livenessPrefix:()=>"liveness:",liveness:(e)=>`liveness:${n(e)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder"};var L={applicationMailbox:(e,t)=>`appmbx:v1:${n(e)}:${n(t)}`,applicationMailboxSinkProbe:(e,t,r)=>`appprobe:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandPrefix:(e,t)=>`appcmd:v1:${n(e)}:${n(t)}:`,applicationCommand:(e,t,r)=>`appcmd:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandReadyPrefix:(e,t)=>`appready:v1:${n(e)}:${n(t)}:`,applicationCommandReady:(e,t,r)=>`appready:v1:${n(e)}:${n(t)}:${s(r)}`,applicationCommandIdempotency:(e,t,r)=>`appidem:v1:${n(e)}:${n(t)}:${n(r)}`,applicationCommandBySequencePrefix:(e,t)=>`appseq:v1:${n(e)}:${n(t)}:`,applicationCommandBySequence:(e,t,r)=>`appseq:v1:${n(e)}:${n(t)}:${s(r)}`,applicationCommandTerminalPrefix:(e,t)=>`appterm:v1:${n(e)}:${n(t)}:`,applicationCommandTerminal:(e,t,r,i)=>`appterm:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`};var A={applicationOutbox:(e,t)=>`appobx:v1:${n(e)}:${n(t)}`,applicationOutboxSinkProbe:(e,t,r)=>`appprobe:v1:outbox:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryPrefix:(e,t)=>`appdlv:v1:${n(e)}:${n(t)}:`,applicationDelivery:(e,t,r)=>`appdlv:v1:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryDuePrefix:(e,t)=>`appdue:v1:${n(e)}:${n(t)}:`,applicationDeliveryDue:(e,t,r,i)=>`appdue:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`,applicationDeliveryIdempotency:(e,t,r)=>`appdidem:v1:${n(e)}:${n(t)}:${n(r)}`,applicationDeliveryBySequencePrefix:(e,t)=>`appdseq:v1:${n(e)}:${n(t)}:`,applicationDeliveryBySequence:(e,t,r)=>`appdseq:v1:${n(e)}:${n(t)}:${s(r)}`,applicationDeliveryTerminalPrefix:(e,t)=>`appdterm:v1:${n(e)}:${n(t)}:`,applicationDeliveryTerminal:(e,t,r,i)=>`appdterm:v1:${n(e)}:${n(t)}:${s(r)}:${n(i)}`};var D={workflowOwnerEpoch:(e)=>`wf-owner-epoch:${n(e)}`,workflowOwnerHolder:(e)=>`wf-owner-holder:${n(e)}`,ownershipModeMarker:()=>"ownership-mode-marker"};var me="0",ye="1",K=(e,t,r,i)=>`sig:${n(e)}:${n(t)}:${i}:${n(r)}`,I={signal:(e,t,r)=>K(e,t,r,ye),startSignal:(e,t,r)=>K(e,t,r,me),signalSequence:(e)=>`sigseq:v1:${n(e)}`,signalAcceptedResponsePrefix:(e)=>`sigres:v1:${n(e)}:`,signalAcceptedResponse:(e,t,r)=>`sigres:v1:${n(e)}:${n(t)}:${n(r)}`};var E="default";var u=s,q={deadline:(e,t)=>`wf-deadline:${u(e)}:${n(t)}`,terminalCleanup:(e,t)=>`wf-cleanup:${u(e)}:${n(t)}`,teardownTimer:(e,t)=>`wf-teardown:${u(e)}:${n(t)}`,delayedStart:(e,t)=>`wf-delayed:${u(e)}:${n(t)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(e,t)=>`wf-terminal:${u(e)}:${n(t)}`},Y={budget:(e,t,r)=>`budget:${e}:${t}:${r}`,review:(e,t)=>`review:${n(e)}:${t}`,workflowHeaders:(e)=>`wf-headers:${n(e)}`,childCancellationPrefix:(e)=>`child-cancel:${n(e)}:`,childCancellation:(e,t)=>`child-cancel:${n(e)}:${n(t)}`,childWorkflowByParentPrefix:(e,t)=>`child-by-parent:${n(e)}:${t===void 0?"":`${n(t)}:`}`,childWorkflowByParent:(e,t,r)=>`child-by-parent:${n(e)}:${t===void 0?"":`${n(t)}:`}${n(r)}`,terminalCleanupNeeded:(e)=>`wf-cleanup-needed:${n(e)}`,workflowConcurrency:(e,t)=>`wf-concurrency:${n(e)}:${n(t)}`,workflowConcurrencyHolder:(e)=>`wf-concurrency-holder:${n(e)}`,workflowHasServices:(e)=>`wf-has-services:${n(e)}`,finalizerState:(e)=>`wf-finalizer-state:${n(e)}`,teardownOwed:(e)=>`wf-teardown-needed:${n(e)}`,teardownSucceeded:(e)=>`wf-teardown-succeeded:${n(e)}`,teardownDeadLetter:(e)=>`wf-teardown-deadletter:${n(e)}`,offload:(e,t)=>`offload:${n(e)}:${t}`,archive:(e,t)=>`archive:${n(e)}:${t}`,stateExecution:(e,t)=>`state:execution:${n(e)}:${n(t)}`,stateWorkflow:(e,t)=>`state:workflow-scope:${E}:${n(e)}:${n(t)}`,streamChunkPrefix:(e,t)=>`blob:${n(e)}:${t}:chunk:`,streamChunk:(e,t,r)=>`blob:${n(e)}:${t}:chunk:${String(r).padStart(10,"0")}`,streamTail:(e,t)=>`blob:${n(e)}:${t}:tail`,streamMetadata:(e,t)=>`blob:${n(e)}:${t}:meta`,budgetCharged:(e)=>`budget-charged:${e}`,toolEffect:(e,t,r)=>`tool-effect:${n(e)}:${t}:${r}`,workflowVisibilityStatus:(e,t)=>`wf-idx-status:${n(e)}:${n(t)}`,workflowVisibilityType:(e,t)=>`wf-idx-type:${n(e)}:${n(t)}`,workflowVisibilityCreated:(e,t)=>`wf-idx-created:${u(e)}:${n(t)}`,workflowVisibilityUpdated:(e,t)=>`wf-idx-updated:${u(e)}:${n(t)}`,workflowVisibilityDeadline:(e,t)=>`wf-idx-deadline:${u(e)}:${n(t)}`,workflowVisibilityManifest:(e)=>`wf-idx-manifest:${n(e)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};var w=s,W={workflow:(e)=>`wf:${n(e)}`,checkpoint:(e)=>`wf:${n(e)}:ckpt`,checkpointHistory:(e,t)=>`wf:${n(e)}:ckpt:${String(t).padStart(10,"0")}`,timelinePrefix:(e)=>`wf:${n(e)}:timeline:`,timeline:(e,t)=>`wf:${n(e)}:timeline:${String(t).padStart(10,"0")}`,schedule:(e)=>`schedule:${n(e)}`,scheduleTick:(e,t)=>`schedule-due:${String(e).padStart(16,"0")}:${n(t)}`,scheduleRun:(e)=>`schedule-run:${n(e)}`,scheduleRunLink:(e)=>`schedule-run-link:${n(e)}`,scheduleRunBySchedulePrefix:(e)=>`schedule-run-by-schedule:${n(e)}:`,scheduleRunBySchedule:(e,t)=>`schedule-run-by-schedule:${n(e)}:${n(t)}`,operation:(e,t,r)=>`op:${e}:${w(t)}:${r}`,operationInflight:(e)=>`op:inflight:${e}`,operationQueued:(e)=>`op:queued:${e}`,operationResolved:(e)=>`op:resolved:${e}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(e,t,r)=>`audit:bulk:${w(e)}:${n(t)}:${n(r)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(e,t)=>`op:resolved-by-time:${w(e)}:${n(t)}`,asyncActivity:(e,t)=>`async-act:v1:${n(e)}:${n(t)}`,asyncActivityResolution:(e,t)=>`async-act:v1:${n(e)}:${n(t)}:resolution`,activityReconciliationPrefix:(e)=>`actrec:v1:${n(e)}:`,activityReconciliation:(e,t,r)=>`actrec:v1:${n(e)}:${n(t)}:${r}`,eventPrefix:(e)=>`ev:${n(e)}:`,event:(e,t)=>`ev:${n(e)}:${String(t).padStart(10,"0")}`,eventHead:(e)=>`ev:${n(e)}:head`,eventWatermark:(e)=>`ev:${n(e)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(e)=>`fleet-event:${String(e).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventWatermark:()=>"fleet-event-watermark",fleetEventByWorkflowPrefix:(e)=>`fleet-event-by-workflow:${n(e)}:`,fleetEventByWorkflow:(e,t)=>`fleet-event-by-workflow:${n(e)}:${String(t).padStart(10,"0")}`},N={attribute:(e)=>`attr:${n(e)}`,attributeIndex:(e,t,r)=>`idx:${e}:${t}:${n(r)}`,tagIndex:(e,t)=>`tag:${n(e)}:${n(t)}`,updatePrefix:(e)=>`upd:${n(e)}:`,update:(e,t)=>`upd:${n(e)}:${t}`,updateResponse:(e)=>`upr:${e}`,updateIdempotency:(e,t)=>`upk:${n(e)}:${t}`,startIdempotency:(e)=>`start-idem:${n(e)}`,startIdempotencySignalId:(e)=>`start-idem:${e}`};var Se=["actrec:","appcmd:","appdidem:","appdlv:","appdseq:","appdterm:","appdue:","appidem:","appmbx:","appobx:","appprobe:","appready:","appseq:","appterm:","archive:","async-act:","attr:","audit:bulk:","blob:","budget:","budget-charged:","catalog-active:","catalog-entry:","catalog-tombstone:","child-by-parent:","ev:","fleet-event-by-workflow:","fleet-event:","fleet-event-tail","fleet-event-watermark","idx:","lease:","liveness:","offload:","ownership-mode-marker","op:","review:","schedule:","schedule-due:","schedule-run-by-schedule:","schedule-run-link:","schedule-run:","sig:","sigres:","sigseq:","start-idem:","state:","tag:","tool-effect:","upd:","upk:","upr:","wf:","wf-cleanup:","wf-cleanup-needed:","wf-concurrency:","wf-concurrency-holder:","wf-deadline:","wf-delayed:","wf-finalizer-state:","wf-gen:","wf-has-services:","wf-headers:","wf-idx-","wf-owner-epoch:","wf-owner-holder:","wf-teardown:","wf-teardown-deadletter:","wf-teardown-needed:","wf-teardown-succeeded:","wf-terminal:"];var b=1e4,St=1e4;class F extends Error{code="StorageBatchOperationLimitExceededError";cap=b;count;target;constructor(e,t){super(`${e} count ${t} exceeds MAX_BATCH_OPERATIONS (${b}).`);this.name="StorageBatchOperationLimitExceededError",this.target=e,this.count=t}}function g(e,t){if(t>b)throw new F(e,t)}function U(e){return e.length>0?e.slice(0,-1)+String.fromCharCode(e.charCodeAt(e.length-1)+1):"\xFF"}function ht(e,t={}){if(t.gt!==void 0&&e<=t.gt)return!1;if(t.gte!==void 0&&e<t.gte)return!1;if(t.lt!==void 0&&e>=t.lt)return!1;if(t.lte!==void 0&&e>t.lte)return!1;return!0}function M(e,t){if(e===null||t===null)return e===t;if(e.byteLength!==t.byteLength)return!1;for(let r=0;r<e.byteLength;r++)if(e[r]!==t[r])return!1;return!0}async function V(e,t){if(e.has)return e.has(t);return v(e,t)}function Q(e,t,r){if(e.keys)return e.keys(t,r);return p(e,t,r)}async function z(e,t){if(e.count)return e.count(t);return T(e,t)}async function H(e,t){if(e.deletePrefix)return e.deletePrefix(t);return _(e,t)}async function Et(e,t){g("batch operations",t.length),await e.batch(t)}async function X(e,t,r){if(g("conditionalBatch conditions",t.length),g("conditionalBatch operations",r.length),h(e,"conditionalBatch","storageConditionalBatch"),!e.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return e.conditionalBatch(t,r)}var wt={...W,...I,...q,...N,...B,...L,...A,...D,...C,...P,...Y};function he(e){if(e===void 0)return;if(typeof e!=="number"||!Number.isInteger(e)||e<0)throw Error("deleteRange limit must be a finite non-negative integer");return e===0?0:e}function d(e){let t={},r=!1;for(let a of["gt","gte","lt","lte"]){let o=e[a];if(o===void 0)continue;if(typeof o!=="string")throw Error("deleteRange bounds must be strings");t[a]=o,r=!0}if(!r)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let i=he(e.limit);if(i!==void 0)t.limit=i;return t}async function G(e,t,r){let i=d(r);if(e.deleteRange)return e.deleteRange(t,i);return k(e,t,i)}function R(e){return e.replaceAll(/:+$/g,"")}function Ee(e,t){let r=R(e),i=R(t);if(r.length===0)return i;if(i.length===0)return r;return`${r}:${i}`}class O{#e;#r;constructor(e,t){this.#e=e,this.#r=R(t)}#t(e){if(this.#r.length===0)return e;return e.length===0?`${this.#r}:`:`${this.#r}:${e}`}#n(e){return e.map((t)=>{if(t.type==="put")return{type:"put",key:this.#t(t.key),value:t.value};return{type:"delete",key:this.#t(t.key)}})}#i(e){if(this.#r.length===0)return e;return e.slice(this.#r.length+1)}#a(e){let t={};if(e.limit!==void 0)t.limit=e.limit;if(e.gt!==void 0)t.gt=this.#t(e.gt);if(e.gte!==void 0)t.gte=this.#t(e.gte);if(e.lt!==void 0)t.lt=this.#t(e.lt);if(e.lte!==void 0)t.lte=this.#t(e.lte);return t}#o(e={}){let t=this.#a(e);if(e.reverse!==void 0)t.reverse=e.reverse;return t}#s(e){return this.#a(e)}capabilities(){return this.#e.capabilities()}scoped(e){return new O(this.#e,Ee(this.#r,e))}async get(e){return this.#e.get(this.#t(e))}async put(e,t){await this.#e.put(this.#t(e),t)}async delete(e){await this.#e.delete(this.#t(e))}async*scan(e,t){for await(let[r,i]of this.#e.scan(this.#t(e),this.#o(t)))yield[this.#i(r),i]}async batch(e){g("batch operations",e.length),await this.#e.batch(this.#n(e))}async conditionalBatch(e,t){return X(this.#e,e.map((r)=>({key:this.#t(r.key),expectedValue:r.expectedValue})),this.#n(t))}async has(e){return V(this.#e,this.#t(e))}async deletePrefix(e){return H(this.#e,this.#t(e))}async deleteRange(e,t){let r=this.#s(d(t));return G(this.#e,this.#t(e),r)}async*keys(e,t){for await(let r of Q(this.#e,this.#t(e),this.#o(t)))yield this.#i(r)}async count(e){return z(this.#e,this.#t(e))}[Symbol.dispose](){this.#e[Symbol.dispose]()}}function j(e,t){return new O(e,t)}import{createClient as xe}from"@libsql/client";var we=/^PRAGMA\b/iu,be=/^PRAGMA\s+(?:[A-Z_][A-Z0-9_]*\.)?[A-Z_][A-Z0-9_]*\s*$/iu,$e=/^SELECT\b/iu;function Re(e){return e.trim().replace(/;+\s*$/u,"").trim()}function Oe(e){return be.test(e)}function Z(e){let t=Re(e);if(t.length===0)throw Error("Storage query must not be empty.");if(t.includes(";"))throw Error("Storage query must contain exactly one read-only statement.");if($e.test(t))return;if(we.test(t)&&Oe(t))return;throw Error("Storage query only supports read-only SELECT and PRAGMA statements.")}var J=`CREATE TABLE IF NOT EXISTS kv (
|
|
3
3
|
key TEXT PRIMARY KEY,
|
|
4
4
|
value BLOB NOT NULL
|
|
5
|
-
) WITHOUT ROWID`,
|
|
5
|
+
) WITHOUT ROWID`,x="SELECT value FROM kv WHERE key = ?",m="INSERT INTO kv (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",y="DELETE FROM kv WHERE key = ?",ee="SELECT 1 AS present FROM kv WHERE key = ? LIMIT 1",te="SELECT COUNT(*) AS count FROM kv WHERE key >= ? AND key < ?",ne="DELETE FROM kv WHERE key >= ? AND key < ?";function S(e){return[e,U(e)]}function re(e,t){let{gt:r,gte:i,lt:a,lte:o}=t,l=["key >= ? AND key < ?"],c=S(e);if(r!==void 0)l.push("key > ?"),c.push(r);if(i!==void 0)l.push("key >= ?"),c.push(i);if(a!==void 0)l.push("key < ?"),c.push(a);if(o!==void 0)l.push("key <= ?"),c.push(o);return{conditions:l,parameters:c}}function ie(e,t={}){let{limit:r,reverse:i}=t,{conditions:a,parameters:o}=re(e,t),l=i?"DESC":"ASC",c=r!==void 0?" LIMIT ?":"";if(r!==void 0)o.push(r);return{parameters:o,sqlSuffix:`WHERE ${a.join(" AND ")} ORDER BY key ${l}${c}`}}function ae(e,t,r="kv"){let{conditions:i,parameters:a}=re(e,t),o=i.join(" AND ");if(t.limit===void 0)return{parameters:a,sql:`DELETE FROM ${r} WHERE ${o}`};return a.push(t.limit),{parameters:a,sql:`DELETE FROM ${r} WHERE key IN (SELECT key FROM ${r} WHERE ${o} ORDER BY key ASC LIMIT ?)`}}function oe(e,t={}){let{parameters:r,sqlSuffix:i}=ie(e,t);return{parameters:r,sql:`SELECT key, value FROM kv ${i}`}}function se(e,t={}){let{parameters:r,sqlSuffix:i}=ie(e,t);return{parameters:r,sql:`SELECT key FROM kv ${i}`}}var le=`${J};`,f=10,Ce=new Set(["SQLITE_BUSY","SQLITE_LOCKED"]);function ce(e){return typeof e==="object"&&e!==null&&"code"in e&&typeof e.code==="string"&&Ce.has(e.code)}async function ve(e){return e.transaction("write")}async function Te(e){try{await e.rollback()}catch{}}async function ge(e){await new Promise((t)=>{setTimeout(t,Math.min(e*5,50))})}async function _e(e,t){for(let r=1;r<=f;r++)try{await e.batch(t,"write");return}catch(i){if(!ce(i)||r===f)throw i;await ge(r)}}async function ke(e,t){for(let r of t){let a=(await e.execute({sql:x,args:[r.key]})).rows[0]?.value,o=a===null||a===void 0?null:new Uint8Array(a);if(!M(o,r.expectedValue))return!1}return!0}async function Pe(e,t){for(let r of t)if(r.type==="put")await e.execute({sql:m,args:[r.key,r.value]});else await e.execute({sql:y,args:[r.key]})}function Be(e){if(e==="file::memory:"||e===":memory:")return"ephemeral";if(e.startsWith("file:"))return"local";return"remote"}class Le{#e;#r;#t=!1;constructor(e){this.#r=Be(e.url),this.#e=xe(e.authToken?{url:e.url,authToken:e.authToken}:{url:e.url})}capabilities(){return{persistence:this.#r,readAfterWrite:"session",scanConsistency:"snapshot",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}async#n(){if(this.#t)return;await this.#e.executeMultiple(le),this.#t=!0}async get(e){await this.#n();let t=await this.#e.execute({sql:x,args:[e]});if(t.rows.length===0)return null;let r=t.rows[0].value;if(r===null||r===void 0)return null;return new Uint8Array(r)}async put(e,t){await this.#n(),await this.#e.execute({sql:m,args:[e,t]})}async delete(e){await this.#n(),await this.#e.execute({sql:y,args:[e]})}async has(e){return await this.#n(),(await this.#e.execute({sql:ee,args:[e]})).rows.length>0}async deletePrefix(e){await this.#n();let[t,r]=S(e);return(await this.#e.execute({sql:ne,args:[t,r]})).rowsAffected}async deleteRange(e,t){await this.#n();let r=d(t),{parameters:i,sql:a}=ae(e,r);return(await this.#e.execute({sql:a,args:i})).rowsAffected}async*scan(e,t={}){await this.#n();let{parameters:r,sql:i}=oe(e,t),a=await this.#e.execute({sql:i,args:r});for(let o of a.rows){let{key:l,value:c}=o,ue=new Uint8Array(c);yield[l,ue]}}async*keys(e,t={}){await this.#n();let{parameters:r,sql:i}=se(e,t),a=await this.#e.execute({sql:i,args:r});for(let o of a.rows)yield o.key}async count(e){await this.#n();let[t,r]=S(e),i=await this.#e.execute({sql:te,args:[t,r]});return Number(i.rows[0]?.count??0)}scoped(e){return j(this,e)}async batch(e){if(g("batch operations",e.length),e.length===0)return;await this.#n();let t=e.map((r)=>{if(r.type==="put")return{sql:m,args:[r.key,r.value]};return{sql:y,args:[r.key]}});await _e(this.#e,t)}async conditionalBatch(e,t){g("conditionalBatch conditions",e.length),g("conditionalBatch operations",t.length),await this.#n();let r;for(let i=1;i<=f;i++){let a;try{if(a=await ve(this.#e),await a.executeMultiple(le),!await ke(a,e))return await a.rollback(),!1;return await Pe(a,t),await a.commit(),!0}catch(o){if(a!==void 0)await Te(a);if(!ce(o))throw o;if(r=o,i<f)await ge(i)}}throw Error(`conditionalBatch exhausted ${f} attempts after SQLite contention failures`,{cause:r})}async query(e,t){return await this.#n(),Z(e),(await this.#e.execute({sql:e,args:t??[]})).rows}[Symbol.dispose](){this.#e.close()}}export{Le as TursoStorage};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage key builders for post-execution workflow lifecycle concerns:
|
|
3
|
+
* deadlines and terminal timers, finalizer/teardown tracking, concurrency
|
|
4
|
+
* limits, child-workflow bookkeeping, durable state/stream storage, and the
|
|
5
|
+
* workflow visibility index.
|
|
6
|
+
*
|
|
7
|
+
* These are spread into `KEYS` in `interface.ts` rather than declared there, so
|
|
8
|
+
* the lifecycle keyspace can carry its full rationale without pushing that
|
|
9
|
+
* file's documented line ceiling. Callers still reach them through `KEYS`,
|
|
10
|
+
* which keeps one import contract for storage keys.
|
|
11
|
+
*
|
|
12
|
+
* @module storage/workflow-lifecycle-keys
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Deadline and terminal timer keys.
|
|
16
|
+
*
|
|
17
|
+
* Spread into `KEYS` after `SIGNAL_KEYS` and ahead of
|
|
18
|
+
* `WORKFLOW_RECORD_KEYS_EXTENDED` to preserve the pre-split
|
|
19
|
+
* `Object.keys(KEYS)` insertion order; not intended to be imported directly
|
|
20
|
+
* by engine code.
|
|
21
|
+
*/
|
|
22
|
+
export declare const WORKFLOW_LIFECYCLE_KEYS_CORE: {
|
|
23
|
+
readonly deadline: (deadline: number, workflowId: string) => string;
|
|
24
|
+
readonly terminalCleanup: (fireAt: number, timerId: string) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Durable timer that drives a workflow's finalizer after a `cancelled`/`timed-out`
|
|
27
|
+
* terminal (issue #446 Phase 2). Sortable by `fireAt` and scanned by its own
|
|
28
|
+
* source (`wf-teardown:`) so it dispatches as the `teardown` timer kind rather
|
|
29
|
+
* than `terminal-cleanup`. Re-armed with exponential backoff on a failed finalizer
|
|
30
|
+
* attempt; the scheduler deletes the fired entry after the drive returns without
|
|
31
|
+
* throwing, so a backoff reschedule is a write of a new entry at the later `fireAt`.
|
|
32
|
+
*/
|
|
33
|
+
readonly teardownTimer: (fireAt: number, timerId: string) => string;
|
|
34
|
+
readonly delayedStart: (startAt: number, workflowId: string) => string;
|
|
35
|
+
readonly terminalWorkflowPrefix: () => string;
|
|
36
|
+
readonly terminalWorkflow: (updatedAt: number, workflowId: string) => string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Finalizer/teardown tracking, concurrency limits, child-workflow
|
|
40
|
+
* bookkeeping, durable state/stream storage, and workflow visibility index
|
|
41
|
+
* keys.
|
|
42
|
+
*
|
|
43
|
+
* Spread into `KEYS` after `MAILBOX_KEYS`, `OUTBOX_KEYS`,
|
|
44
|
+
* `OWNERSHIP_CLAIM_KEYS`, and `WORKFLOW_CATALOG_KEYS` to preserve the
|
|
45
|
+
* pre-split `Object.keys(KEYS)` insertion order; not intended to be imported
|
|
46
|
+
* directly by engine code.
|
|
47
|
+
*/
|
|
48
|
+
export declare const WORKFLOW_LIFECYCLE_KEYS_EXTENDED: {
|
|
49
|
+
readonly budget: (namespace: string, period: string, date: string) => string;
|
|
50
|
+
readonly review: (workflowId: string, reviewId: string) => string;
|
|
51
|
+
readonly workflowHeaders: (workflowId: string) => string;
|
|
52
|
+
readonly childCancellationPrefix: (workflowId: string) => string;
|
|
53
|
+
readonly childCancellation: (workflowId: string, childWorkflowId: string) => string;
|
|
54
|
+
readonly childWorkflowByParentPrefix: (parentWorkflowId: string, parentWorkflowExecutionToken?: string) => string;
|
|
55
|
+
readonly childWorkflowByParent: (parentWorkflowId: string, parentWorkflowExecutionToken: string | undefined, childWorkflowId: string) => string;
|
|
56
|
+
readonly terminalCleanupNeeded: (workflowId: string) => string;
|
|
57
|
+
readonly workflowConcurrency: (workflowType: string, partitionKey: string) => string;
|
|
58
|
+
readonly workflowConcurrencyHolder: (workflowId: string) => string;
|
|
59
|
+
/**
|
|
60
|
+
* Presence-only marker written at start only when a run is launched with a
|
|
61
|
+
* non-serialized `services` value (see `start-batch.ts`). It lets a
|
|
62
|
+
* fresh-process recovery tell a run whose services were lost on crash apart
|
|
63
|
+
* from one that never had any — the services value itself is never persisted,
|
|
64
|
+
* so this bit is the only durable trace. Cleared on terminal cleanup.
|
|
65
|
+
*/
|
|
66
|
+
readonly workflowHasServices: (workflowId: string) => string;
|
|
67
|
+
/**
|
|
68
|
+
* Last-write-wins payload that `ctx.setFinalizerState(value)` records for a
|
|
69
|
+
* workflow's definition-level `finalizer` activity (issue #446). Staged as a
|
|
70
|
+
* pending atomic side-effect so it commits with the next checkpoint or the
|
|
71
|
+
* terminal batch, and swept on terminal cleanup.
|
|
72
|
+
*
|
|
73
|
+
* **Current behavior (this release): recorded only.** Nothing reads this value
|
|
74
|
+
* yet. **Planned behavior (future release):** the engine will pass the decoded
|
|
75
|
+
* value as the finalizer's input when driving teardown after a
|
|
76
|
+
* `cancelled`/`timed-out` terminal, where presence means "a resource was
|
|
77
|
+
* recorded" and absence means the finalizer is skipped.
|
|
78
|
+
*/
|
|
79
|
+
readonly finalizerState: (workflowId: string) => string;
|
|
80
|
+
/**
|
|
81
|
+
* Durable execution-claim + attempt marker for a workflow that owes a finalizer
|
|
82
|
+
* run after a `cancelled`/`timed-out` terminal (issue #446 Phase 2). Mirrors the
|
|
83
|
+
* `wf-cleanup-needed:` lifecycle. The value is the encoded claim record
|
|
84
|
+
* `{ status: 'owed' | 'running'; attempts: number; token: string; claimedAt?: number }`:
|
|
85
|
+
* the engine fenced-CAS's `owed → running` (stamping `claimedAt`) before invoking the
|
|
86
|
+
* finalizer, and settle-CAS's the exact `running` bytes it wrote when clearing or
|
|
87
|
+
* rescheduling. Liveness is decided purely by TIME: a `running` claim is reclaimable
|
|
88
|
+
* once `claimedAt` is older than the finalizer's per-attempt timeout plus a margin
|
|
89
|
+
* (see `teardownStaleThresholdMs`), so crash recovery is an ordinary stale-claim retry
|
|
90
|
+
* driven by the timer that survived the terminal batch — there is no in-memory liveness
|
|
91
|
+
* set and no epoch in the record. The cost is that a finalizer running past the stale
|
|
92
|
+
* threshold may be re-driven concurrently, which is why workflow finalizers must be
|
|
93
|
+
* idempotent. Present while teardown is outstanding; deleted by the finalizer on
|
|
94
|
+
* success or when it dead-letters, which is what unblocks purge.
|
|
95
|
+
*/
|
|
96
|
+
readonly teardownOwed: (workflowId: string) => string;
|
|
97
|
+
/** Durable successful finalizer outcome, retained until workflow purge or retention. */
|
|
98
|
+
readonly teardownSucceeded: (workflowId: string) => string;
|
|
99
|
+
/**
|
|
100
|
+
* Durable audit record written when a workflow's finalizer permanently fails — the
|
|
101
|
+
* retry horizon is reached, or the recorded resource state vanished so the finalizer
|
|
102
|
+
* can never run (issue #446 Phase 2). Holds the `TeardownDeadLetterRecord` shape
|
|
103
|
+
* `{ type, lastError, attempts, deadLetteredAt, workflowExecutionToken?, finalizerInput? }`.
|
|
104
|
+
* **Excluded from the workflow purge delete-set** so it survives as the operator's
|
|
105
|
+
* evidence of a leaked external resource and remains queryable through the durable
|
|
106
|
+
* finalizer-status API after purge.
|
|
107
|
+
*/
|
|
108
|
+
readonly teardownDeadLetter: (workflowId: string) => string;
|
|
109
|
+
readonly offload: (workflowId: string, key: string) => string;
|
|
110
|
+
readonly archive: (workflowId: string, key: string) => string;
|
|
111
|
+
readonly stateExecution: (ownerWorkflowId: string, key: string) => string;
|
|
112
|
+
readonly stateWorkflow: (workflowType: string, key: string) => string;
|
|
113
|
+
readonly streamChunkPrefix: (workflowId: string, key: string) => string;
|
|
114
|
+
readonly streamChunk: (workflowId: string, key: string, chunkIndex: number) => string;
|
|
115
|
+
readonly streamTail: (workflowId: string, key: string) => string;
|
|
116
|
+
readonly streamMetadata: (workflowId: string, key: string) => string;
|
|
117
|
+
readonly budgetCharged: (operationId: string) => string;
|
|
118
|
+
readonly toolEffect: (workflowId: string, agentId: string, semanticHash: string) => string;
|
|
119
|
+
readonly workflowVisibilityStatus: (status: string, workflowId: string) => string;
|
|
120
|
+
readonly workflowVisibilityType: (type: string, workflowId: string) => string;
|
|
121
|
+
readonly workflowVisibilityCreated: (createdAt: number, workflowId: string) => string;
|
|
122
|
+
readonly workflowVisibilityUpdated: (updatedAt: number, workflowId: string) => string;
|
|
123
|
+
readonly workflowVisibilityDeadline: (deadline: number, workflowId: string) => string;
|
|
124
|
+
readonly workflowVisibilityManifest: (workflowId: string) => string;
|
|
125
|
+
readonly workflowVisibilityMetaVersion: () => string;
|
|
126
|
+
readonly workflowVisibilityMetaBuiltAt: () => string;
|
|
127
|
+
readonly workflowVisibilityMetaCursor: () => string;
|
|
128
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DEFAULT_SCOPE } from "./default-scope.js";
|
|
2
|
+
import { encodeStorageKeyComponent, formatSortableStorageTimestamp } from "./key-encoding.js";
|
|
3
|
+
const formatSortableTimestamp = formatSortableStorageTimestamp;
|
|
4
|
+
export const WORKFLOW_LIFECYCLE_KEYS_CORE = {
|
|
5
|
+
deadline: (deadline, workflowId) => `wf-deadline:${formatSortableTimestamp(deadline)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
6
|
+
terminalCleanup: (fireAt, timerId) => `wf-cleanup:${formatSortableTimestamp(fireAt)}:${encodeStorageKeyComponent(timerId)}`,
|
|
7
|
+
teardownTimer: (fireAt, timerId) => `wf-teardown:${formatSortableTimestamp(fireAt)}:${encodeStorageKeyComponent(timerId)}`,
|
|
8
|
+
delayedStart: (startAt, workflowId) => `wf-delayed:${formatSortableTimestamp(startAt)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
9
|
+
terminalWorkflowPrefix: () => "wf-terminal:",
|
|
10
|
+
terminalWorkflow: (updatedAt, workflowId) => `wf-terminal:${formatSortableTimestamp(updatedAt)}:${encodeStorageKeyComponent(workflowId)}`
|
|
11
|
+
}, WORKFLOW_LIFECYCLE_KEYS_EXTENDED = {
|
|
12
|
+
budget: (namespace, period, date) => `budget:${namespace}:${period}:${date}`,
|
|
13
|
+
review: (workflowId, reviewId) => `review:${encodeStorageKeyComponent(workflowId)}:${reviewId}`,
|
|
14
|
+
workflowHeaders: (workflowId) => `wf-headers:${encodeStorageKeyComponent(workflowId)}`,
|
|
15
|
+
childCancellationPrefix: (workflowId) => `child-cancel:${encodeStorageKeyComponent(workflowId)}:`,
|
|
16
|
+
childCancellation: (workflowId, childWorkflowId) => `child-cancel:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(childWorkflowId)}`,
|
|
17
|
+
childWorkflowByParentPrefix: (parentWorkflowId, parentWorkflowExecutionToken) => `child-by-parent:${encodeStorageKeyComponent(parentWorkflowId)}:${parentWorkflowExecutionToken === void 0 ? "" : `${encodeStorageKeyComponent(parentWorkflowExecutionToken)}:`}`,
|
|
18
|
+
childWorkflowByParent: (parentWorkflowId, parentWorkflowExecutionToken, childWorkflowId) => `child-by-parent:${encodeStorageKeyComponent(parentWorkflowId)}:${parentWorkflowExecutionToken === void 0 ? "" : `${encodeStorageKeyComponent(parentWorkflowExecutionToken)}:`}${encodeStorageKeyComponent(childWorkflowId)}`,
|
|
19
|
+
terminalCleanupNeeded: (workflowId) => `wf-cleanup-needed:${encodeStorageKeyComponent(workflowId)}`,
|
|
20
|
+
workflowConcurrency: (workflowType, partitionKey) => `wf-concurrency:${encodeStorageKeyComponent(workflowType)}:${encodeStorageKeyComponent(partitionKey)}`,
|
|
21
|
+
workflowConcurrencyHolder: (workflowId) => `wf-concurrency-holder:${encodeStorageKeyComponent(workflowId)}`,
|
|
22
|
+
workflowHasServices: (workflowId) => `wf-has-services:${encodeStorageKeyComponent(workflowId)}`,
|
|
23
|
+
finalizerState: (workflowId) => `wf-finalizer-state:${encodeStorageKeyComponent(workflowId)}`,
|
|
24
|
+
teardownOwed: (workflowId) => `wf-teardown-needed:${encodeStorageKeyComponent(workflowId)}`,
|
|
25
|
+
teardownSucceeded: (workflowId) => `wf-teardown-succeeded:${encodeStorageKeyComponent(workflowId)}`,
|
|
26
|
+
teardownDeadLetter: (workflowId) => `wf-teardown-deadletter:${encodeStorageKeyComponent(workflowId)}`,
|
|
27
|
+
offload: (workflowId, key) => `offload:${encodeStorageKeyComponent(workflowId)}:${key}`,
|
|
28
|
+
archive: (workflowId, key) => `archive:${encodeStorageKeyComponent(workflowId)}:${key}`,
|
|
29
|
+
stateExecution: (ownerWorkflowId, key) => `state:execution:${encodeStorageKeyComponent(ownerWorkflowId)}:${encodeStorageKeyComponent(key)}`,
|
|
30
|
+
stateWorkflow: (workflowType, key) => `state:workflow-scope:${DEFAULT_SCOPE}:${encodeStorageKeyComponent(workflowType)}:${encodeStorageKeyComponent(key)}`,
|
|
31
|
+
streamChunkPrefix: (workflowId, key) => `blob:${encodeStorageKeyComponent(workflowId)}:${key}:chunk:`,
|
|
32
|
+
streamChunk: (workflowId, key, chunkIndex) => `blob:${encodeStorageKeyComponent(workflowId)}:${key}:chunk:${String(chunkIndex).padStart(10, "0")}`,
|
|
33
|
+
streamTail: (workflowId, key) => `blob:${encodeStorageKeyComponent(workflowId)}:${key}:tail`,
|
|
34
|
+
streamMetadata: (workflowId, key) => `blob:${encodeStorageKeyComponent(workflowId)}:${key}:meta`,
|
|
35
|
+
budgetCharged: (operationId) => `budget-charged:${operationId}`,
|
|
36
|
+
toolEffect: (workflowId, agentId, semanticHash) => `tool-effect:${encodeStorageKeyComponent(workflowId)}:${agentId}:${semanticHash}`,
|
|
37
|
+
workflowVisibilityStatus: (status, workflowId) => `wf-idx-status:${encodeStorageKeyComponent(status)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
38
|
+
workflowVisibilityType: (type, workflowId) => `wf-idx-type:${encodeStorageKeyComponent(type)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
39
|
+
workflowVisibilityCreated: (createdAt, workflowId) => `wf-idx-created:${formatSortableTimestamp(createdAt)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
40
|
+
workflowVisibilityUpdated: (updatedAt, workflowId) => `wf-idx-updated:${formatSortableTimestamp(updatedAt)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
41
|
+
workflowVisibilityDeadline: (deadline, workflowId) => `wf-idx-deadline:${formatSortableTimestamp(deadline)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
42
|
+
workflowVisibilityManifest: (workflowId) => `wf-idx-manifest:${encodeStorageKeyComponent(workflowId)}`,
|
|
43
|
+
workflowVisibilityMetaVersion: () => "wf-idx-meta:version",
|
|
44
|
+
workflowVisibilityMetaBuiltAt: () => "wf-idx-meta:built-at",
|
|
45
|
+
workflowVisibilityMetaCursor: () => "wf-idx-meta:cursor"
|
|
46
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage key builders for the durable per-run execution record: workflow
|
|
3
|
+
* state, checkpoints, timelines, schedules, queued operations, events, async
|
|
4
|
+
* activity resolution, and workflow updates.
|
|
5
|
+
*
|
|
6
|
+
* These are spread into `KEYS` in `interface.ts` rather than declared there, so
|
|
7
|
+
* the workflow-record keyspace can carry its full rationale without pushing
|
|
8
|
+
* that file's documented line ceiling. Callers still reach them through `KEYS`,
|
|
9
|
+
* which keeps one import contract for storage keys.
|
|
10
|
+
*
|
|
11
|
+
* @module storage/workflow-record-keys
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Workflow state, checkpoint, timeline, schedule, queued-operation, and event
|
|
15
|
+
* keys.
|
|
16
|
+
*
|
|
17
|
+
* Spread into `KEYS` ahead of `SIGNAL_KEYS` and `WORKFLOW_LIFECYCLE_KEYS_CORE`
|
|
18
|
+
* to preserve the pre-split `Object.keys(KEYS)` insertion order; not intended
|
|
19
|
+
* to be imported directly by engine code.
|
|
20
|
+
*/
|
|
21
|
+
export declare const WORKFLOW_RECORD_KEYS_CORE: {
|
|
22
|
+
readonly workflow: (id: string) => string;
|
|
23
|
+
readonly checkpoint: (id: string) => string;
|
|
24
|
+
readonly checkpointHistory: (id: string, step: number) => string;
|
|
25
|
+
readonly timelinePrefix: (id: string) => string;
|
|
26
|
+
readonly timeline: (id: string, step: number) => string;
|
|
27
|
+
readonly schedule: (id: string) => string;
|
|
28
|
+
readonly scheduleTick: (fireAt: number, id: string) => string;
|
|
29
|
+
readonly scheduleRun: (workflowId: string) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Durable per-workflow manifest for the schedule that launched a run. Unlike
|
|
32
|
+
* `scheduleRun`, this link survives terminal cleanup so schedule history can
|
|
33
|
+
* be queried until the workflow itself is purged.
|
|
34
|
+
*/
|
|
35
|
+
readonly scheduleRunLink: (workflowId: string) => string;
|
|
36
|
+
readonly scheduleRunBySchedulePrefix: (scheduleId: string) => string;
|
|
37
|
+
readonly scheduleRunBySchedule: (scheduleId: string, workflowId: string) => string;
|
|
38
|
+
readonly operation: (queue: string, scheduledAt: number, id: string) => string;
|
|
39
|
+
readonly operationInflight: (id: string) => string;
|
|
40
|
+
readonly operationQueued: (id: string) => string;
|
|
41
|
+
readonly operationResolved: (id: string) => string;
|
|
42
|
+
readonly bulkOperationAuditPrefix: () => string;
|
|
43
|
+
readonly bulkOperationAudit: (timestamp: number, requestId: string, confirmationToken: string) => string;
|
|
44
|
+
readonly operationResolvedByTimePrefix: () => string;
|
|
45
|
+
readonly operationResolvedByTime: (resolvedAt: number, id: string) => string;
|
|
46
|
+
readonly asyncActivity: (workflowId: string, token: string) => string;
|
|
47
|
+
readonly asyncActivityResolution: (workflowId: string, token: string) => string;
|
|
48
|
+
readonly activityReconciliationPrefix: (workflowId: string) => string;
|
|
49
|
+
readonly activityReconciliation: (workflowId: string, activityName: string, idempotencyKeyDigest: string) => string;
|
|
50
|
+
readonly eventPrefix: (workflowId: string) => string;
|
|
51
|
+
readonly event: (workflowId: string, sequence: number) => string;
|
|
52
|
+
readonly eventHead: (workflowId: string) => string;
|
|
53
|
+
readonly eventWatermark: (workflowId: string) => string;
|
|
54
|
+
readonly fleetEventPrefix: () => string;
|
|
55
|
+
readonly fleetEvent: (sequence: number) => string;
|
|
56
|
+
readonly fleetEventTail: () => string;
|
|
57
|
+
readonly fleetEventWatermark: () => string;
|
|
58
|
+
readonly fleetEventByWorkflowPrefix: (workflowId: string) => string;
|
|
59
|
+
readonly fleetEventByWorkflow: (workflowId: string, sequence: number) => string;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Workflow attribute/tag index and update keys.
|
|
63
|
+
*
|
|
64
|
+
* Spread into `KEYS` after `WORKFLOW_LIFECYCLE_KEYS_CORE` to preserve the
|
|
65
|
+
* pre-split `Object.keys(KEYS)` insertion order; not intended to be imported
|
|
66
|
+
* directly by engine code.
|
|
67
|
+
*/
|
|
68
|
+
export declare const WORKFLOW_RECORD_KEYS_EXTENDED: {
|
|
69
|
+
readonly attribute: (workflowId: string) => string;
|
|
70
|
+
readonly attributeIndex: (attributeName: string, encodedValue: string, workflowId: string) => string;
|
|
71
|
+
readonly tagIndex: (tag: string, workflowId: string) => string;
|
|
72
|
+
readonly updatePrefix: (workflowId: string) => string;
|
|
73
|
+
readonly update: (workflowId: string, updateId: string) => string;
|
|
74
|
+
readonly updateResponse: (updateId: string) => string;
|
|
75
|
+
readonly updateIdempotency: (workflowId: string, key: string) => string;
|
|
76
|
+
/**
|
|
77
|
+
* Maps a start `idempotencyKey` to the workflow id created for it. Written
|
|
78
|
+
* atomically with the workflow record under a `conditionalBatch` gated on this
|
|
79
|
+
* key being absent, so concurrent same-key starts converge on one workflow.
|
|
80
|
+
* Unlike `updateIdempotency`, it is keyed by the idempotency key alone (no
|
|
81
|
+
* workflow id) because the workflow id is the value it resolves to. It is
|
|
82
|
+
* intentionally NOT swept on terminal cleanup: it must outlive the run so a
|
|
83
|
+
* post-completion `startOrSignal` sees a terminal workflow (and conflicts)
|
|
84
|
+
* rather than missing the mapping and creating a fresh run.
|
|
85
|
+
*/
|
|
86
|
+
readonly startIdempotency: (key: string) => string;
|
|
87
|
+
/**
|
|
88
|
+
* The convergence signal id that `startOrSignal` derives from an idempotency
|
|
89
|
+
* key so independent same-key callers deliver ONE signal. Deliberately uses the
|
|
90
|
+
* RAW key (not `encodeStorageKeyComponent`): unlike `startIdempotency` this is a
|
|
91
|
+
* signal id, not a storage key, and `validateSignalId` is character-agnostic, so
|
|
92
|
+
* the raw key is always a valid id as long as it fits the byte cap (enforced as
|
|
93
|
+
* ≤117 bytes so `"start-idem:"` + key stays within the 128-byte signal-id
|
|
94
|
+
* ceiling). The two derivations are independent namespaces; both are individually
|
|
95
|
+
* correct, so the raw-vs-encoded difference is harmless.
|
|
96
|
+
*/
|
|
97
|
+
readonly startIdempotencySignalId: (key: string) => string;
|
|
98
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { encodeStorageKeyComponent, formatSortableStorageTimestamp } from "./key-encoding.js";
|
|
2
|
+
const formatSortableTimestamp = formatSortableStorageTimestamp;
|
|
3
|
+
export const WORKFLOW_RECORD_KEYS_CORE = {
|
|
4
|
+
workflow: (id) => `wf:${encodeStorageKeyComponent(id)}`,
|
|
5
|
+
checkpoint: (id) => `wf:${encodeStorageKeyComponent(id)}:ckpt`,
|
|
6
|
+
checkpointHistory: (id, step) => `wf:${encodeStorageKeyComponent(id)}:ckpt:${String(step).padStart(10, "0")}`,
|
|
7
|
+
timelinePrefix: (id) => `wf:${encodeStorageKeyComponent(id)}:timeline:`,
|
|
8
|
+
timeline: (id, step) => `wf:${encodeStorageKeyComponent(id)}:timeline:${String(step).padStart(10, "0")}`,
|
|
9
|
+
schedule: (id) => `schedule:${encodeStorageKeyComponent(id)}`,
|
|
10
|
+
scheduleTick: (fireAt, id) => `schedule-due:${String(fireAt).padStart(16, "0")}:${encodeStorageKeyComponent(id)}`,
|
|
11
|
+
scheduleRun: (workflowId) => `schedule-run:${encodeStorageKeyComponent(workflowId)}`,
|
|
12
|
+
scheduleRunLink: (workflowId) => `schedule-run-link:${encodeStorageKeyComponent(workflowId)}`,
|
|
13
|
+
scheduleRunBySchedulePrefix: (scheduleId) => `schedule-run-by-schedule:${encodeStorageKeyComponent(scheduleId)}:`,
|
|
14
|
+
scheduleRunBySchedule: (scheduleId, workflowId) => `schedule-run-by-schedule:${encodeStorageKeyComponent(scheduleId)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
15
|
+
operation: (queue, scheduledAt, id) => `op:${queue}:${formatSortableTimestamp(scheduledAt)}:${id}`,
|
|
16
|
+
operationInflight: (id) => `op:inflight:${id}`,
|
|
17
|
+
operationQueued: (id) => `op:queued:${id}`,
|
|
18
|
+
operationResolved: (id) => `op:resolved:${id}`,
|
|
19
|
+
bulkOperationAuditPrefix: () => "audit:bulk:",
|
|
20
|
+
bulkOperationAudit: (timestamp, requestId, confirmationToken) => `audit:bulk:${formatSortableTimestamp(timestamp)}:${encodeStorageKeyComponent(requestId)}:${encodeStorageKeyComponent(confirmationToken)}`,
|
|
21
|
+
operationResolvedByTimePrefix: () => "op:resolved-by-time:",
|
|
22
|
+
operationResolvedByTime: (resolvedAt, id) => `op:resolved-by-time:${formatSortableTimestamp(resolvedAt)}:${encodeStorageKeyComponent(id)}`,
|
|
23
|
+
asyncActivity: (workflowId, token) => `async-act:v1:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(token)}`,
|
|
24
|
+
asyncActivityResolution: (workflowId, token) => `async-act:v1:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(token)}:resolution`,
|
|
25
|
+
activityReconciliationPrefix: (workflowId) => `actrec:v1:${encodeStorageKeyComponent(workflowId)}:`,
|
|
26
|
+
activityReconciliation: (workflowId, activityName, idempotencyKeyDigest) => `actrec:v1:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(activityName)}:${idempotencyKeyDigest}`,
|
|
27
|
+
eventPrefix: (workflowId) => `ev:${encodeStorageKeyComponent(workflowId)}:`,
|
|
28
|
+
event: (workflowId, sequence) => `ev:${encodeStorageKeyComponent(workflowId)}:${String(sequence).padStart(10, "0")}`,
|
|
29
|
+
eventHead: (workflowId) => `ev:${encodeStorageKeyComponent(workflowId)}:head`,
|
|
30
|
+
eventWatermark: (workflowId) => `ev:${encodeStorageKeyComponent(workflowId)}:watermark`,
|
|
31
|
+
fleetEventPrefix: () => "fleet-event:",
|
|
32
|
+
fleetEvent: (sequence) => `fleet-event:${String(sequence).padStart(10, "0")}`,
|
|
33
|
+
fleetEventTail: () => "fleet-event-tail",
|
|
34
|
+
fleetEventWatermark: () => "fleet-event-watermark",
|
|
35
|
+
fleetEventByWorkflowPrefix: (workflowId) => `fleet-event-by-workflow:${encodeStorageKeyComponent(workflowId)}:`,
|
|
36
|
+
fleetEventByWorkflow: (workflowId, sequence) => `fleet-event-by-workflow:${encodeStorageKeyComponent(workflowId)}:${String(sequence).padStart(10, "0")}`
|
|
37
|
+
}, WORKFLOW_RECORD_KEYS_EXTENDED = {
|
|
38
|
+
attribute: (workflowId) => `attr:${encodeStorageKeyComponent(workflowId)}`,
|
|
39
|
+
attributeIndex: (attributeName, encodedValue, workflowId) => `idx:${attributeName}:${encodedValue}:${encodeStorageKeyComponent(workflowId)}`,
|
|
40
|
+
tagIndex: (tag, workflowId) => `tag:${encodeStorageKeyComponent(tag)}:${encodeStorageKeyComponent(workflowId)}`,
|
|
41
|
+
updatePrefix: (workflowId) => `upd:${encodeStorageKeyComponent(workflowId)}:`,
|
|
42
|
+
update: (workflowId, updateId) => `upd:${encodeStorageKeyComponent(workflowId)}:${updateId}`,
|
|
43
|
+
updateResponse: (updateId) => `upr:${updateId}`,
|
|
44
|
+
updateIdempotency: (workflowId, key) => `upk:${encodeStorageKeyComponent(workflowId)}:${key}`,
|
|
45
|
+
startIdempotency: (key) => `start-idem:${encodeStorageKeyComponent(key)}`,
|
|
46
|
+
startIdempotencySignalId: (key) => `start-idem:${key}`
|
|
47
|
+
};
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.24.
|
|
1
|
+
export const VERSION = "0.24.2";
|