@lostgradient/weft 0.10.0 → 0.12.0
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 +10 -2
- package/dist/cli/generated/operation-catalog.snapshot.json +4671 -0
- package/dist/cli/generated/operation-client.generated.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli-main.js +227 -401
- package/dist/client/http-operations.js +7 -1
- package/dist/client/http-request.d.ts +23 -1
- package/dist/client/http-request.js +12 -3
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +7 -0
- package/dist/connection.d.ts +8 -0
- package/dist/connection.js +41 -17
- package/dist/core/checkpoint/serialization.js +2 -2
- package/dist/core/engine/callback-creators-core.js +2 -1
- package/dist/core/engine/disposal.js +4 -0
- package/dist/core/engine/engine-leak-warnings.d.ts +2 -0
- package/dist/core/engine/engine-leak-warnings.js +7 -1
- package/dist/core/engine/index.d.ts +49 -3
- package/dist/core/engine/index.js +19 -3
- package/dist/core/engine/inline-parking.js +14 -1
- package/dist/core/engine/internals.d.ts +21 -0
- package/dist/core/engine/lifecycle/shared.d.ts +25 -0
- package/dist/core/engine/lifecycle/transition.js +19 -9
- package/dist/core/engine/operations-time.js +8 -28
- package/dist/core/engine/sleep-timer-acknowledgements.d.ts +15 -0
- package/dist/core/engine/sleep-timer-acknowledgements.js +144 -0
- package/dist/core/engine/termination/cleanup.js +3 -0
- package/dist/core/types/definition-schema-to-json.d.ts +11 -0
- package/dist/core/types/definition-schema-to-json.js +11 -2
- package/dist/http.js +2 -0
- package/dist/indexeddb.js +1 -0
- package/dist/json-schema.js +3 -3
- package/dist/mcp/cli.js +63 -61
- package/dist/mcp/http.d.ts +7 -2
- package/dist/mcp/session.d.ts +3 -3
- package/dist/mcp/session.js +3 -2
- package/dist/mcp/stdio.d.ts +7 -2
- package/dist/observability/index.js +2 -2
- package/dist/runtime/portable.d.ts +33 -0
- package/dist/runtime/portable.js +17 -6
- package/dist/server/engine-event-feed-backend.d.ts +22 -3
- package/dist/server/fleet-event-feed.d.ts +65 -0
- package/dist/server/handler/index.d.ts +11 -2
- package/dist/server/handler/index.js +7 -0
- package/dist/server/handler.js +1 -56
- package/dist/server/index.d.ts +12 -1
- package/dist/server/index.js +87 -64
- package/dist/server/operations/submit-review-decision.d.ts +2 -0
- package/dist/server/operations/submit-review-decision.js +19 -2
- package/dist/server/replay-live-feed-internals.d.ts +19 -0
- package/dist/server/replay-live-feed-internals.js +76 -0
- package/dist/server/runtime/authentication-bridge.d.ts +2 -2
- package/dist/server/serve-internals.js +3 -3
- package/dist/server/workflow-event-feed.d.ts +100 -11
- package/dist/server/workflow-event-feed.js +1 -140
- package/dist/service-worker/index.d.ts +8 -2
- package/dist/service-worker/index.js +37 -56
- package/dist/service-worker/scheduler.js +1 -0
- package/dist/service-worker/setup.d.ts +6 -2
- package/dist/storage/auto.js +1 -1
- package/dist/storage/bun-sql.js +3 -3
- package/dist/storage/cloudflare-durable-object-sql.d.ts +75 -0
- package/dist/storage/cloudflare-durable-object-sql.js +0 -0
- package/dist/storage/cloudflare-value-codec.d.ts +65 -0
- package/dist/storage/cloudflare-value-codec.js +46 -0
- package/dist/storage/cloudflare.d.ts +140 -0
- package/dist/storage/cloudflare.js +127 -0
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/http.js +200 -2
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/indexeddb.js +311 -1
- package/dist/storage/interface.js +1 -1
- package/dist/storage/lazy-postgres-pool.d.ts +38 -0
- package/dist/storage/lazy-postgres-pool.js +38 -0
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon-batch.d.ts +8 -8
- package/dist/storage/neon.d.ts +26 -79
- package/dist/storage/neon.js +4 -4
- package/dist/storage/node-sqlite.js +3 -3
- package/dist/storage/postgres-key-value-queries.d.ts +7 -1
- package/dist/storage/postgres-key-value-queries.js +2 -3
- package/dist/storage/postgres-key-value-storage.d.ts +110 -0
- package/dist/storage/postgres-key-value-storage.js +204 -0
- package/dist/storage/postgres.d.ts +59 -0
- package/dist/storage/postgres.js +15 -0
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/sql-identifier.d.ts +35 -0
- package/dist/storage/sql-identifier.js +5 -0
- package/dist/storage/sqlite-key-value-queries.d.ts +11 -6
- package/dist/storage/sqlite-key-value-queries.js +3 -3
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/storage/typed-storage.js +138 -2
- package/dist/storage/web-extension.js +298 -1
- package/dist/testing/index.js +21 -60
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -0
- package/dist/worker/protocol.js +1 -1
- package/package.json +23 -5
package/dist/storage/http.js
CHANGED
|
@@ -1,2 +1,200 @@
|
|
|
1
|
-
var u=Object.defineProperty;var k=(F)=>F;function w(F,G){this[F]=k.bind(null,G)}var JF=(F,G)=>{for(var J in G)u(F,J,{get:G[J],enumerable:!0,configurable:!0,set:w.bind(G,J)})};function N(F){let G=[];for(let J=0;J<F.length;J+=512)G.push(String.fromCharCode(...F.subarray(J,J+512)));return btoa(G.join(""))}function R(F){let G=atob(F),J=new Uint8Array(G.length);for(let Y=0;Y<G.length;Y+=1)J[Y]=G.charCodeAt(Y);return J}function D(F){return typeof F==="object"&&F!==null&&!Array.isArray(F)}async function j(F,G){return await F.get(G)!==null}async function*X(F,G,J){for await(let[Y]of F.scan(G,J))yield Y}async function W(F,G){let J=0;for await(let Y of X(F,G))J++;return J}async function H(F,G){let J=[];for await(let Y of X(F,G))J.push({type:"delete",key:Y});if(J.length===0)return 0;return await F.batch(J),J.length}async function L(F,G,J){let Y=[];for await(let Z of X(F,G,J))Y.push({type:"delete",key:Z});if(Y.length===0)return 0;return await F.batch(Y),Y.length}function q(F,G,J){if(!F.capabilities()[G])throw Error(`Feature "${J}" requires storage capability "${G}", but this storage backend does not provide it.`)}var S="default";var T=1e4,jF=1e4;class K extends Error{code="StorageBatchOperationLimitExceededError";cap=T;count;target;constructor(F,G){super(`${F} count ${G} exceeds MAX_BATCH_OPERATIONS (${T}).`);this.name="StorageBatchOperationLimitExceededError",this.target=F,this.count=G}}function $(F,G){if(G>T)throw new K(F,G)}function O(F){return F.length>0?F.slice(0,-1)+String.fromCharCode(F.charCodeAt(F.length-1)+1):"ÿ"}function WF(F,G={}){if(G.gt!==void 0&&F<=G.gt)return!1;if(G.gte!==void 0&&F<G.gte)return!1;if(G.lt!==void 0&&F>=G.lt)return!1;if(G.lte!==void 0&&F>G.lte)return!1;return!0}function HF(F,G){if(F===null||G===null)return F===G;if(F.byteLength!==G.byteLength)return!1;for(let J=0;J<F.byteLength;J++)if(F[J]!==G[J])return!1;return!0}async function h(F,G){if(F.has)return F.has(G);return j(F,G)}function b(F,G,J){if(F.keys)return F.keys(G,J);return X(F,G,J)}async function v(F,G){if(F.count)return F.count(G);return W(F,G)}async function m(F,G){if(F.deletePrefix)return F.deletePrefix(G);return H(F,G)}async function LF(F,G){$("batch operations",G.length),await F.batch(G)}async function x(F,G,J){if($("conditionalBatch conditions",G.length),$("conditionalBatch operations",J.length),q(F,"conditionalBatch","storageConditionalBatch"),!F.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return F.conditionalBatch(G,J)}function Q(F){return encodeURIComponent(F)}function UF(F){return decodeURIComponent(F)}function NF(F){try{return decodeURIComponent(F)}catch{return null}}var _=(F)=>String(F).padStart(16,"0"),f="0",l="1",P=(F,G,J,Y)=>`sig:${Q(F)}:${Q(G)}:${Y}:${Q(J)}`,DF={workflow:(F)=>`wf:${Q(F)}`,checkpoint:(F)=>`wf:${Q(F)}:ckpt`,checkpointHistory:(F,G)=>`wf:${Q(F)}:ckpt:${String(G).padStart(10,"0")}`,timelinePrefix:(F)=>`wf:${Q(F)}:timeline:`,timeline:(F,G)=>`wf:${Q(F)}:timeline:${String(G).padStart(10,"0")}`,schedule:(F)=>`schedule:${Q(F)}`,scheduleTick:(F,G)=>`schedule-due:${String(F).padStart(16,"0")}:${Q(G)}`,scheduleRun:(F)=>`schedule-run:${Q(F)}`,operation:(F,G,J)=>`op:${F}:${_(G)}:${J}`,operationInflight:(F)=>`op:inflight:${F}`,operationQueued:(F)=>`op:queued:${F}`,operationResolved:(F)=>`op:resolved:${F}`,operationDeadLetterPrefix:()=>"op:dead-letter:",operationDeadLetter:(F)=>`op:dead-letter:${F}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(F,G,J)=>`audit:bulk:${_(F)}:${Q(G)}:${Q(J)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(F,G)=>`op:resolved-by-time:${_(F)}:${Q(G)}`,asyncActivity:(F,G)=>`async-act:v1:${Q(F)}:${Q(G)}`,asyncActivityResolution:(F,G)=>`async-act:v1:${Q(F)}:${Q(G)}:resolution`,activityReconciliationPrefix:(F)=>`actrec:v1:${Q(F)}:`,activityReconciliation:(F,G,J)=>`actrec:v1:${Q(F)}:${Q(G)}:${J}`,eventPrefix:(F)=>`ev:${Q(F)}:`,event:(F,G)=>`ev:${Q(F)}:${String(G).padStart(10,"0")}`,eventHead:(F)=>`ev:${Q(F)}:head`,eventWatermark:(F)=>`ev:${Q(F)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(F)=>`fleet-event:${String(F).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventByWorkflowPrefix:(F)=>`fleet-event-by-workflow:${Q(F)}:`,fleetEventByWorkflow:(F,G)=>`fleet-event-by-workflow:${Q(F)}:${String(G).padStart(10,"0")}`,signal:(F,G,J)=>P(F,G,J,l),startSignal:(F,G,J)=>P(F,G,J,f),signalSequence:(F)=>`sigseq:v1:${Q(F)}`,signalAcceptedResponsePrefix:(F)=>`sigres:v1:${Q(F)}:`,signalAcceptedResponse:(F,G,J)=>`sigres:v1:${Q(F)}:${Q(G)}:${Q(J)}`,deadline:(F,G)=>`wf-deadline:${_(F)}:${Q(G)}`,terminalCleanup:(F,G)=>`wf-cleanup:${_(F)}:${Q(G)}`,teardownTimer:(F,G)=>`wf-teardown:${_(F)}:${Q(G)}`,delayedStart:(F,G)=>`wf-delayed:${_(F)}:${Q(G)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(F,G)=>`wf-terminal:${_(F)}:${Q(G)}`,attribute:(F)=>`attr:${Q(F)}`,attributeIndex:(F,G,J)=>`idx:${F}:${G}:${Q(J)}`,tagIndex:(F,G)=>`tag:${Q(F)}:${Q(G)}`,updatePrefix:(F)=>`upd:${Q(F)}:`,update:(F,G)=>`upd:${Q(F)}:${G}`,updateResponse:(F)=>`upr:${F}`,updateIdempotency:(F,G)=>`upk:${Q(F)}:${G}`,startIdempotency:(F)=>`start-idem:${Q(F)}`,startIdempotencySignalId:(F)=>`start-idem:${F}`,livenessPrefix:()=>"liveness:",liveness:(F)=>`liveness:${Q(F)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder",budget:(F,G,J)=>`budget:${F}:${G}:${J}`,review:(F,G)=>`review:${Q(F)}:${G}`,workflowHeaders:(F)=>`wf-headers:${Q(F)}`,childCancellationPrefix:(F)=>`child-cancel:${Q(F)}:`,childCancellation:(F,G)=>`child-cancel:${Q(F)}:${Q(G)}`,terminalCleanupNeeded:(F)=>`wf-cleanup-needed:${Q(F)}`,workflowConcurrency:(F,G)=>`wf-concurrency:${Q(F)}:${Q(G)}`,workflowConcurrencyHolder:(F)=>`wf-concurrency-holder:${Q(F)}`,workflowHasServices:(F)=>`wf-has-services:${Q(F)}`,finalizerState:(F)=>`wf-finalizer-state:${Q(F)}`,teardownOwed:(F)=>`wf-teardown-needed:${Q(F)}`,teardownDeadLetter:(F)=>`wf-teardown-deadletter:${Q(F)}`,offload:(F,G)=>`offload:${Q(F)}:${G}`,archive:(F,G)=>`archive:${Q(F)}:${G}`,stateExecution:(F,G)=>`state:execution:${Q(F)}:${Q(G)}`,stateWorkflow:(F,G)=>`state:workflow-scope:${S}:${Q(F)}:${Q(G)}`,streamChunkPrefix:(F,G)=>`blob:${Q(F)}:${G}:chunk:`,streamChunk:(F,G,J)=>`blob:${Q(F)}:${G}:chunk:${String(J).padStart(10,"0")}`,streamTail:(F,G)=>`blob:${Q(F)}:${G}:tail`,streamMetadata:(F,G)=>`blob:${Q(F)}:${G}:meta`,budgetCharged:(F)=>`budget-charged:${F}`,toolEffect:(F,G,J)=>`tool-effect:${Q(F)}:${G}:${J}`,workflowVisibilityStatus:(F,G)=>`wf-idx-status:${Q(F)}:${Q(G)}`,workflowVisibilityType:(F,G)=>`wf-idx-type:${Q(F)}:${Q(G)}`,workflowVisibilityCreated:(F,G)=>`wf-idx-created:${_(F)}:${Q(G)}`,workflowVisibilityUpdated:(F,G)=>`wf-idx-updated:${_(F)}:${Q(G)}`,workflowVisibilityDeadline:(F,G)=>`wf-idx-deadline:${_(F)}:${Q(G)}`,workflowVisibilityManifest:(F)=>`wf-idx-manifest:${Q(F)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};function d(F){if(F===void 0)return;if(typeof F!=="number"||!Number.isInteger(F)||F<0)throw Error("deleteRange limit must be a finite non-negative integer");return F===0?0:F}function V(F){let G={},J=!1;for(let Z of["gt","gte","lt","lte"]){let M=F[Z];if(M===void 0)continue;if(typeof M!=="string")throw Error("deleteRange bounds must be strings");G[Z]=M,J=!0}if(!J)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let Y=d(F.limit);if(Y!==void 0)G.limit=Y;return G}async function c(F,G,J){let Y=V(J);if(F.deleteRange)return F.deleteRange(G,Y);return L(F,G,Y)}function p(F,G){let J={key:F,open:!1};if(G.gte!==void 0&&G.gte>J.key)J.key=G.gte,J.open=!1;if(G.gt!==void 0&&G.gt>=J.key)J.key=G.gt,J.open=!0;return J}function a(F,G){let J={key:O(F),open:!0};if(G.lt!==void 0&&G.lt<=J.key)J.key=G.lt,J.open=!0;if(G.lte!==void 0&&G.lte<J.key)J.key=G.lte,J.open=!1;return J}function BF(F,G){let J=p(F,G),Y=a(F,G);if(J.key>Y.key||J.key===Y.key&&(J.open||Y.open))return null;return{lower:J,upper:Y}}function A(F){return F.replaceAll(/:+$/g,"")}function s(F,G){let J=A(F),Y=A(G);if(J.length===0)return Y;if(Y.length===0)return J;return`${J}:${Y}`}class z{#G;#J;constructor(F,G){this.#G=F,this.#J=A(G)}#F(F){if(this.#J.length===0)return F;return F.length===0?`${this.#J}:`:`${this.#J}:${F}`}#Q(F){if(this.#J.length===0)return F;return F.slice(this.#J.length+1)}#Y(F={}){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.reverse!==void 0)G.reverse=F.reverse;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}#_(F){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}capabilities(){return this.#G.capabilities()}scoped(F){return new z(this.#G,s(this.#J,F))}async get(F){return this.#G.get(this.#F(F))}async put(F,G){await this.#G.put(this.#F(F),G)}async delete(F){await this.#G.delete(this.#F(F))}async*scan(F,G){for await(let[J,Y]of this.#G.scan(this.#F(F),this.#Y(G)))yield[this.#Q(J),Y]}async batch(F){$("batch operations",F.length),await this.#G.batch(F.map((G)=>{if(G.type==="put")return{type:"put",key:this.#F(G.key),value:G.value};return{type:"delete",key:this.#F(G.key)}}))}async conditionalBatch(F,G){return x(this.#G,F.map((J)=>({key:this.#F(J.key),expectedValue:J.expectedValue})),G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#F(J.key),value:J.value};return{type:"delete",key:this.#F(J.key)}}))}async has(F){return h(this.#G,this.#F(F))}async deletePrefix(F){return m(this.#G,this.#F(F))}async deleteRange(F,G){let J=this.#_(V(G));return c(this.#G,this.#F(F),J)}async*keys(F,G){for await(let J of b(this.#G,this.#F(F),this.#Y(G)))yield this.#Q(J)}async count(F){return v(this.#G,this.#F(F))}[Symbol.dispose](){this.#G[Symbol.dispose]()}}function g(F,G){return new z(F,G)}var n=67108864;function y(F){if(F.type==="put")return{type:"put",key:F.key,value:N(F.value)};return{type:"delete",key:F.key}}function r(F){return{key:F.key,expectedValue:F.expectedValue===null?null:N(F.expectedValue)}}function i(F){if(!D(F)||typeof F.key!=="string"||typeof F.value!=="string")throw Error("HTTPStorage scan response contained an invalid NDJSON entry.");return{key:F.key,value:F.value}}function t(F){if(!D(F)||typeof F.applied!=="boolean")throw Error('HTTPStorage conditional batch response must include a boolean "applied" field.');return F.applied}function E(F,G,J){if(J!==void 0)F.searchParams.set(G,String(J))}function o(F){if(F.trim().length===0)return null;let G=i(JSON.parse(F));return[G.key,R(G.value)]}function e(F){if(F>n)throw Error("HTTPStorage scan response exceeded the maximum allowed size.")}async function*FF(F){if(F.body===null)return;let G=F.body.getReader(),J=new TextDecoder,Y="",Z=0,M=!1;try{while(!0){let{done:U,value:B}=await G.read();if(U){M=!0;break}Z+=B.byteLength,e(Z),Y+=J.decode(B,{stream:!0});let C=Y.split(`
|
|
2
|
-
|
|
1
|
+
import { decodeBase64ToBytes, encodeBytesToBase64, isRecord } from "./byte-encoding.js";
|
|
2
|
+
import { normalizeDeleteRangeOptions } from "./delete-range.js";
|
|
3
|
+
import {
|
|
4
|
+
storageCountCore,
|
|
5
|
+
storageDeletePrefixCore,
|
|
6
|
+
storageDeleteRangeCore,
|
|
7
|
+
storageHasCore,
|
|
8
|
+
storageKeysCore
|
|
9
|
+
} from "./derived-operations.js";
|
|
10
|
+
import {
|
|
11
|
+
assertStorageBatchOperationCount
|
|
12
|
+
} from "./interface.js";
|
|
13
|
+
import { scopedStorage } from "./scoped-storage.js";
|
|
14
|
+
const MAX_SCAN_RESPONSE_BYTES = 67108864;
|
|
15
|
+
function encodeOperation(operation) {
|
|
16
|
+
if (operation.type === "put")
|
|
17
|
+
return {
|
|
18
|
+
type: "put",
|
|
19
|
+
key: operation.key,
|
|
20
|
+
value: encodeBytesToBase64(operation.value)
|
|
21
|
+
};
|
|
22
|
+
return { type: "delete", key: operation.key };
|
|
23
|
+
}
|
|
24
|
+
function encodeCondition(condition) {
|
|
25
|
+
return {
|
|
26
|
+
key: condition.key,
|
|
27
|
+
expectedValue: condition.expectedValue === null ? null : encodeBytesToBase64(condition.expectedValue)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function parseScanEntry(value) {
|
|
31
|
+
if (!isRecord(value) || typeof value.key !== "string" || typeof value.value !== "string")
|
|
32
|
+
throw Error("HTTPStorage scan response contained an invalid NDJSON entry.");
|
|
33
|
+
return { key: value.key, value: value.value };
|
|
34
|
+
}
|
|
35
|
+
function parseConditionalBatchResponse(value) {
|
|
36
|
+
if (!isRecord(value) || typeof value.applied !== "boolean")
|
|
37
|
+
throw Error('HTTPStorage conditional batch response must include a boolean "applied" field.');
|
|
38
|
+
return value.applied;
|
|
39
|
+
}
|
|
40
|
+
function appendOptionalSearchParameter(url, name, value) {
|
|
41
|
+
if (value !== void 0)
|
|
42
|
+
url.searchParams.set(name, String(value));
|
|
43
|
+
}
|
|
44
|
+
function parseScanLine(line) {
|
|
45
|
+
if (line.trim().length === 0)
|
|
46
|
+
return null;
|
|
47
|
+
const entry = parseScanEntry(JSON.parse(line));
|
|
48
|
+
return [entry.key, decodeBase64ToBytes(entry.value)];
|
|
49
|
+
}
|
|
50
|
+
function assertScanResponseSize(bytesRead) {
|
|
51
|
+
if (bytesRead > MAX_SCAN_RESPONSE_BYTES)
|
|
52
|
+
throw Error("HTTPStorage scan response exceeded the maximum allowed size.");
|
|
53
|
+
}
|
|
54
|
+
async function* readNdjsonLines(response) {
|
|
55
|
+
if (response.body === null)
|
|
56
|
+
return;
|
|
57
|
+
const reader = response.body.getReader(), decoder = new TextDecoder;
|
|
58
|
+
let bufferedText = "", bytesRead = 0, reachedEndOfStream = !1;
|
|
59
|
+
try {
|
|
60
|
+
while (!0) {
|
|
61
|
+
const { done, value } = await reader.read();
|
|
62
|
+
if (done) {
|
|
63
|
+
reachedEndOfStream = !0;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
bytesRead += value.byteLength;
|
|
67
|
+
assertScanResponseSize(bytesRead);
|
|
68
|
+
bufferedText += decoder.decode(value, { stream: !0 });
|
|
69
|
+
const lines = bufferedText.split(`
|
|
70
|
+
`);
|
|
71
|
+
bufferedText = lines.pop() ?? "";
|
|
72
|
+
for (const line of lines)
|
|
73
|
+
yield line;
|
|
74
|
+
}
|
|
75
|
+
bufferedText += decoder.decode();
|
|
76
|
+
if (bufferedText.length > 0)
|
|
77
|
+
yield bufferedText;
|
|
78
|
+
} finally {
|
|
79
|
+
try {
|
|
80
|
+
if (!reachedEndOfStream)
|
|
81
|
+
await reader.cancel();
|
|
82
|
+
} catch {}
|
|
83
|
+
reader.releaseLock();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export class HTTPStorage {
|
|
88
|
+
#baseUrl;
|
|
89
|
+
#headers;
|
|
90
|
+
#remoteConditionalBatch;
|
|
91
|
+
constructor(options) {
|
|
92
|
+
this.#baseUrl = options.baseUrl instanceof URL ? options.baseUrl : new URL(options.baseUrl);
|
|
93
|
+
this.#headers = { ...options.headers };
|
|
94
|
+
this.#remoteConditionalBatch = options.remoteConditionalBatch ?? !1;
|
|
95
|
+
}
|
|
96
|
+
capabilities() {
|
|
97
|
+
return {
|
|
98
|
+
persistence: "remote",
|
|
99
|
+
readAfterWrite: "eventual",
|
|
100
|
+
scanConsistency: "best-effort",
|
|
101
|
+
atomicBatch: !0,
|
|
102
|
+
conditionalBatch: this.#remoteConditionalBatch,
|
|
103
|
+
boundedRangeDelete: !1
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
#url(path) {
|
|
107
|
+
const base = this.#baseUrl.href.endsWith("/") ? this.#baseUrl.href : `${this.#baseUrl.href}/`;
|
|
108
|
+
return new URL(path.replace(/^\/+/, ""), base);
|
|
109
|
+
}
|
|
110
|
+
#storageKeyUrl(key) {
|
|
111
|
+
return this.#url(`/v1/storage/${encodeURIComponent(key)}`);
|
|
112
|
+
}
|
|
113
|
+
#scanUrl(prefix, options) {
|
|
114
|
+
const url = this.#url("/v1/storage");
|
|
115
|
+
url.searchParams.set("prefix", prefix);
|
|
116
|
+
appendOptionalSearchParameter(url, "limit", options.limit);
|
|
117
|
+
appendOptionalSearchParameter(url, "reverse", options.reverse);
|
|
118
|
+
appendOptionalSearchParameter(url, "gt", options.gt);
|
|
119
|
+
appendOptionalSearchParameter(url, "gte", options.gte);
|
|
120
|
+
appendOptionalSearchParameter(url, "lt", options.lt);
|
|
121
|
+
appendOptionalSearchParameter(url, "lte", options.lte);
|
|
122
|
+
return url;
|
|
123
|
+
}
|
|
124
|
+
async#request(url, init = {}, allowedStatuses = []) {
|
|
125
|
+
const headers = new Headers(this.#headers);
|
|
126
|
+
for (const [key, value] of new Headers(init.headers).entries())
|
|
127
|
+
headers.set(key, value);
|
|
128
|
+
const response = await fetch(url, { ...init, headers });
|
|
129
|
+
if (!response.ok && !allowedStatuses.includes(response.status))
|
|
130
|
+
throw Error(`HTTPStorage request failed: ${init.method ?? "GET"} ${url.pathname} returned ${String(response.status)}.`);
|
|
131
|
+
return response;
|
|
132
|
+
}
|
|
133
|
+
async get(key) {
|
|
134
|
+
const response = await this.#request(this.#storageKeyUrl(key), { method: "GET" }, [404]);
|
|
135
|
+
if (response.status === 404)
|
|
136
|
+
return null;
|
|
137
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
138
|
+
}
|
|
139
|
+
async put(key, value) {
|
|
140
|
+
await this.#request(this.#storageKeyUrl(key), {
|
|
141
|
+
method: "PUT",
|
|
142
|
+
headers: { "content-type": "application/octet-stream" },
|
|
143
|
+
body: new Blob([value])
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async delete(key) {
|
|
147
|
+
await this.#request(this.#storageKeyUrl(key), { method: "DELETE" });
|
|
148
|
+
}
|
|
149
|
+
async* scan(prefix, options = {}) {
|
|
150
|
+
const response = await this.#request(this.#scanUrl(prefix, options), {
|
|
151
|
+
method: "GET",
|
|
152
|
+
headers: { accept: "application/x-ndjson" }
|
|
153
|
+
});
|
|
154
|
+
for await (const line of readNdjsonLines(response)) {
|
|
155
|
+
const entry = parseScanLine(line);
|
|
156
|
+
if (entry !== null)
|
|
157
|
+
yield entry;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async batch(operations) {
|
|
161
|
+
assertStorageBatchOperationCount("batch operations", operations.length);
|
|
162
|
+
await this.#request(this.#url("/v1/storage/-/batch"), {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers: { "content-type": "application/json" },
|
|
165
|
+
body: JSON.stringify({ operations: operations.map(encodeOperation) })
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async conditionalBatch(conditions, operations) {
|
|
169
|
+
assertStorageBatchOperationCount("conditionalBatch conditions", conditions.length);
|
|
170
|
+
assertStorageBatchOperationCount("conditionalBatch operations", operations.length);
|
|
171
|
+
const response = await this.#request(this.#url("/v1/storage/-/conditional-batch"), {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: { "content-type": "application/json" },
|
|
174
|
+
body: JSON.stringify({
|
|
175
|
+
conditions: conditions.map(encodeCondition),
|
|
176
|
+
operations: operations.map(encodeOperation)
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
return parseConditionalBatchResponse(await response.json());
|
|
180
|
+
}
|
|
181
|
+
has(key) {
|
|
182
|
+
return storageHasCore(this, key);
|
|
183
|
+
}
|
|
184
|
+
async* keys(prefix, options) {
|
|
185
|
+
yield* storageKeysCore(this, prefix, options);
|
|
186
|
+
}
|
|
187
|
+
count(prefix) {
|
|
188
|
+
return storageCountCore(this, prefix);
|
|
189
|
+
}
|
|
190
|
+
deletePrefix(prefix) {
|
|
191
|
+
return storageDeletePrefixCore(this, prefix);
|
|
192
|
+
}
|
|
193
|
+
deleteRange(prefix, options) {
|
|
194
|
+
return storageDeleteRangeCore(this, prefix, normalizeDeleteRangeOptions(options));
|
|
195
|
+
}
|
|
196
|
+
scoped(prefix) {
|
|
197
|
+
return scopedStorage(this, prefix);
|
|
198
|
+
}
|
|
199
|
+
[Symbol.dispose]() {}
|
|
200
|
+
}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* import { LMDBStorage } from '@lostgradient/weft/storage/lmdb'; // peer: lmdb
|
|
15
15
|
* import { TursoStorage } from '@lostgradient/weft/storage/turso'; // peer: @libsql/client
|
|
16
16
|
* import { NeonStorage } from '@lostgradient/weft/storage/neon'; // peer: @neondatabase/serverless
|
|
17
|
+
* import { CloudflareDurableObjectSQLiteStorage } from '@lostgradient/weft/storage/cloudflare'; // caller-injected `sql` binding, zero runtime deps
|
|
17
18
|
* import { IndexedDBStorage } from '@lostgradient/weft/storage/indexeddb'; // browser-only
|
|
18
19
|
* import { WebExtensionStorage } from '@lostgradient/weft/storage/web-extension'; // extension-only
|
|
19
20
|
* import { HTTPStorage } from '@lostgradient/weft/storage/http'; // remote storage
|
|
@@ -1 +1,311 @@
|
|
|
1
|
-
var s=Object.defineProperty;var n=(U)=>U;function i(U,Y){this[U]=n.bind(null,Y)}var QU=(U,Y)=>{for(var G in Y)s(U,G,{get:Y[G],enumerable:!0,configurable:!0,set:i.bind(Y,G)})};async function E(U,Y){return await U.get(Y)!==null}async function*S(U,Y,G){for await(let[Q]of U.scan(Y,G))yield Q}async function R(U,Y){let G=0;for await(let Q of S(U,Y))G++;return G}async function v(U,Y){let G=[];for await(let Q of S(U,Y))G.push({type:"delete",key:Q});if(G.length===0)return 0;return await U.batch(G),G.length}async function b(U,Y,G){let Q=[];for await(let X of S(U,Y,G))Q.push({type:"delete",key:X});if(Q.length===0)return 0;return await U.batch(Q),Q.length}function A(U,Y,G){if(!U.capabilities()[Y])throw Error(`Feature "${G}" requires storage capability "${Y}", but this storage backend does not provide it.`)}var m="default";var P=1e4,BU=1e4;class y extends Error{code="StorageBatchOperationLimitExceededError";cap=P;count;target;constructor(U,Y){super(`${U} count ${Y} exceeds MAX_BATCH_OPERATIONS (${P}).`);this.name="StorageBatchOperationLimitExceededError",this.target=U,this.count=Y}}function T(U,Y){if(Y>P)throw new y(U,Y)}function K(U){return U.length>0?U.slice(0,-1)+String.fromCharCode(U.charCodeAt(U.length-1)+1):"ÿ"}function C(U,Y={}){if(Y.gt!==void 0&&U<=Y.gt)return!1;if(Y.gte!==void 0&&U<Y.gte)return!1;if(Y.lt!==void 0&&U>=Y.lt)return!1;if(Y.lte!==void 0&&U>Y.lte)return!1;return!0}function I(U,Y){if(U===null||Y===null)return U===Y;if(U.byteLength!==Y.byteLength)return!1;for(let G=0;G<U.byteLength;G++)if(U[G]!==Y[G])return!1;return!0}async function g(U,Y){if(U.has)return U.has(Y);return E(U,Y)}function k(U,Y,G){if(U.keys)return U.keys(Y,G);return S(U,Y,G)}async function c(U,Y){if(U.count)return U.count(Y);return R(U,Y)}async function w(U,Y){if(U.deletePrefix)return U.deletePrefix(Y);return v(U,Y)}async function DU(U,Y){T("batch operations",Y.length),await U.batch(Y)}async function u(U,Y,G){if(T("conditionalBatch conditions",Y.length),T("conditionalBatch operations",G.length),A(U,"conditionalBatch","storageConditionalBatch"),!U.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return U.conditionalBatch(Y,G)}function J(U){return encodeURIComponent(U)}function _U(U){return decodeURIComponent(U)}function zU(U){try{return decodeURIComponent(U)}catch{return null}}var z=(U)=>String(U).padStart(16,"0"),r="0",t="1",x=(U,Y,G,Q)=>`sig:${J(U)}:${J(Y)}:${Q}:${J(G)}`,MU={workflow:(U)=>`wf:${J(U)}`,checkpoint:(U)=>`wf:${J(U)}:ckpt`,checkpointHistory:(U,Y)=>`wf:${J(U)}:ckpt:${String(Y).padStart(10,"0")}`,timelinePrefix:(U)=>`wf:${J(U)}:timeline:`,timeline:(U,Y)=>`wf:${J(U)}:timeline:${String(Y).padStart(10,"0")}`,schedule:(U)=>`schedule:${J(U)}`,scheduleTick:(U,Y)=>`schedule-due:${String(U).padStart(16,"0")}:${J(Y)}`,scheduleRun:(U)=>`schedule-run:${J(U)}`,operation:(U,Y,G)=>`op:${U}:${z(Y)}:${G}`,operationInflight:(U)=>`op:inflight:${U}`,operationQueued:(U)=>`op:queued:${U}`,operationResolved:(U)=>`op:resolved:${U}`,operationDeadLetterPrefix:()=>"op:dead-letter:",operationDeadLetter:(U)=>`op:dead-letter:${U}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(U,Y,G)=>`audit:bulk:${z(U)}:${J(Y)}:${J(G)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(U,Y)=>`op:resolved-by-time:${z(U)}:${J(Y)}`,asyncActivity:(U,Y)=>`async-act:v1:${J(U)}:${J(Y)}`,asyncActivityResolution:(U,Y)=>`async-act:v1:${J(U)}:${J(Y)}:resolution`,activityReconciliationPrefix:(U)=>`actrec:v1:${J(U)}:`,activityReconciliation:(U,Y,G)=>`actrec:v1:${J(U)}:${J(Y)}:${G}`,eventPrefix:(U)=>`ev:${J(U)}:`,event:(U,Y)=>`ev:${J(U)}:${String(Y).padStart(10,"0")}`,eventHead:(U)=>`ev:${J(U)}:head`,eventWatermark:(U)=>`ev:${J(U)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(U)=>`fleet-event:${String(U).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventByWorkflowPrefix:(U)=>`fleet-event-by-workflow:${J(U)}:`,fleetEventByWorkflow:(U,Y)=>`fleet-event-by-workflow:${J(U)}:${String(Y).padStart(10,"0")}`,signal:(U,Y,G)=>x(U,Y,G,t),startSignal:(U,Y,G)=>x(U,Y,G,r),signalSequence:(U)=>`sigseq:v1:${J(U)}`,signalAcceptedResponsePrefix:(U)=>`sigres:v1:${J(U)}:`,signalAcceptedResponse:(U,Y,G)=>`sigres:v1:${J(U)}:${J(Y)}:${J(G)}`,deadline:(U,Y)=>`wf-deadline:${z(U)}:${J(Y)}`,terminalCleanup:(U,Y)=>`wf-cleanup:${z(U)}:${J(Y)}`,teardownTimer:(U,Y)=>`wf-teardown:${z(U)}:${J(Y)}`,delayedStart:(U,Y)=>`wf-delayed:${z(U)}:${J(Y)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(U,Y)=>`wf-terminal:${z(U)}:${J(Y)}`,attribute:(U)=>`attr:${J(U)}`,attributeIndex:(U,Y,G)=>`idx:${U}:${Y}:${J(G)}`,tagIndex:(U,Y)=>`tag:${J(U)}:${J(Y)}`,updatePrefix:(U)=>`upd:${J(U)}:`,update:(U,Y)=>`upd:${J(U)}:${Y}`,updateResponse:(U)=>`upr:${U}`,updateIdempotency:(U,Y)=>`upk:${J(U)}:${Y}`,startIdempotency:(U)=>`start-idem:${J(U)}`,startIdempotencySignalId:(U)=>`start-idem:${U}`,livenessPrefix:()=>"liveness:",liveness:(U)=>`liveness:${J(U)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder",budget:(U,Y,G)=>`budget:${U}:${Y}:${G}`,review:(U,Y)=>`review:${J(U)}:${Y}`,workflowHeaders:(U)=>`wf-headers:${J(U)}`,childCancellationPrefix:(U)=>`child-cancel:${J(U)}:`,childCancellation:(U,Y)=>`child-cancel:${J(U)}:${J(Y)}`,terminalCleanupNeeded:(U)=>`wf-cleanup-needed:${J(U)}`,workflowConcurrency:(U,Y)=>`wf-concurrency:${J(U)}:${J(Y)}`,workflowConcurrencyHolder:(U)=>`wf-concurrency-holder:${J(U)}`,workflowHasServices:(U)=>`wf-has-services:${J(U)}`,finalizerState:(U)=>`wf-finalizer-state:${J(U)}`,teardownOwed:(U)=>`wf-teardown-needed:${J(U)}`,teardownDeadLetter:(U)=>`wf-teardown-deadletter:${J(U)}`,offload:(U,Y)=>`offload:${J(U)}:${Y}`,archive:(U,Y)=>`archive:${J(U)}:${Y}`,stateExecution:(U,Y)=>`state:execution:${J(U)}:${J(Y)}`,stateWorkflow:(U,Y)=>`state:workflow-scope:${m}:${J(U)}:${J(Y)}`,streamChunkPrefix:(U,Y)=>`blob:${J(U)}:${Y}:chunk:`,streamChunk:(U,Y,G)=>`blob:${J(U)}:${Y}:chunk:${String(G).padStart(10,"0")}`,streamTail:(U,Y)=>`blob:${J(U)}:${Y}:tail`,streamMetadata:(U,Y)=>`blob:${J(U)}:${Y}:meta`,budgetCharged:(U)=>`budget-charged:${U}`,toolEffect:(U,Y,G)=>`tool-effect:${J(U)}:${Y}:${G}`,workflowVisibilityStatus:(U,Y)=>`wf-idx-status:${J(U)}:${J(Y)}`,workflowVisibilityType:(U,Y)=>`wf-idx-type:${J(U)}:${J(Y)}`,workflowVisibilityCreated:(U,Y)=>`wf-idx-created:${z(U)}:${J(Y)}`,workflowVisibilityUpdated:(U,Y)=>`wf-idx-updated:${z(U)}:${J(Y)}`,workflowVisibilityDeadline:(U,Y)=>`wf-idx-deadline:${z(U)}:${J(Y)}`,workflowVisibilityManifest:(U)=>`wf-idx-manifest:${J(U)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};function o(U){if(U===void 0)return;if(typeof U!=="number"||!Number.isInteger(U)||U<0)throw Error("deleteRange limit must be a finite non-negative integer");return U===0?0:U}function h(U){let Y={},G=!1;for(let X of["gt","gte","lt","lte"]){let $=U[X];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");Y[X]=$,G=!0}if(!G)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let Q=o(U.limit);if(Q!==void 0)Y.limit=Q;return Y}async function f(U,Y,G){let Q=h(G);if(U.deleteRange)return U.deleteRange(Y,Q);return b(U,Y,Q)}function e(U,Y){let G={key:U,open:!1};if(Y.gte!==void 0&&Y.gte>G.key)G.key=Y.gte,G.open=!1;if(Y.gt!==void 0&&Y.gt>=G.key)G.key=Y.gt,G.open=!0;return G}function UU(U,Y){let G={key:K(U),open:!0};if(Y.lt!==void 0&&Y.lt<=G.key)G.key=Y.lt,G.open=!0;if(Y.lte!==void 0&&Y.lte<G.key)G.key=Y.lte,G.open=!1;return G}function l(U,Y){let G=e(U,Y),Q=UU(U,Y);if(G.key>Q.key||G.key===Q.key&&(G.open||Q.open))return null;return{lower:G,upper:Q}}function q(U){return U.replaceAll(/:+$/g,"")}function YU(U,Y){let G=q(U),Q=q(Y);if(G.length===0)return Q;if(Q.length===0)return G;return`${G}:${Q}`}class O{#Y;#G;constructor(U,Y){this.#Y=U,this.#G=q(Y)}#U(U){if(this.#G.length===0)return U;return U.length===0?`${this.#G}:`:`${this.#G}:${U}`}#J(U){if(this.#G.length===0)return U;return U.slice(this.#G.length+1)}#Q(U={}){let Y={};if(U.limit!==void 0)Y.limit=U.limit;if(U.reverse!==void 0)Y.reverse=U.reverse;if(U.gt!==void 0)Y.gt=this.#U(U.gt);if(U.gte!==void 0)Y.gte=this.#U(U.gte);if(U.lt!==void 0)Y.lt=this.#U(U.lt);if(U.lte!==void 0)Y.lte=this.#U(U.lte);return Y}#X(U){let Y={};if(U.limit!==void 0)Y.limit=U.limit;if(U.gt!==void 0)Y.gt=this.#U(U.gt);if(U.gte!==void 0)Y.gte=this.#U(U.gte);if(U.lt!==void 0)Y.lt=this.#U(U.lt);if(U.lte!==void 0)Y.lte=this.#U(U.lte);return Y}capabilities(){return this.#Y.capabilities()}scoped(U){return new O(this.#Y,YU(this.#G,U))}async get(U){return this.#Y.get(this.#U(U))}async put(U,Y){await this.#Y.put(this.#U(U),Y)}async delete(U){await this.#Y.delete(this.#U(U))}async*scan(U,Y){for await(let[G,Q]of this.#Y.scan(this.#U(U),this.#Q(Y)))yield[this.#J(G),Q]}async batch(U){T("batch operations",U.length),await this.#Y.batch(U.map((Y)=>{if(Y.type==="put")return{type:"put",key:this.#U(Y.key),value:Y.value};return{type:"delete",key:this.#U(Y.key)}}))}async conditionalBatch(U,Y){return u(this.#Y,U.map((G)=>({key:this.#U(G.key),expectedValue:G.expectedValue})),Y.map((G)=>{if(G.type==="put")return{type:"put",key:this.#U(G.key),value:G.value};return{type:"delete",key:this.#U(G.key)}}))}async has(U){return g(this.#Y,this.#U(U))}async deletePrefix(U){return w(this.#Y,this.#U(U))}async deleteRange(U,Y){let G=this.#X(h(Y));return f(this.#Y,this.#U(U),G)}async*keys(U,Y){for await(let G of k(this.#Y,this.#U(U),this.#Q(Y)))yield this.#J(G)}async count(U){return c(this.#Y,this.#U(U))}[Symbol.dispose](){this.#Y[Symbol.dispose]()}}function d(U,Y){return new O(U,Y)}var F="kv";function GU(U=globalThis){let{indexedDB:Y,IDBKeyRange:G}=U;if(Y===void 0||G===void 0)throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");return{indexedDB:Y,IDBKeyRange:G}}function N(U){return new Promise((Y,G)=>{U.onsuccess=()=>Y(U.result),U.onerror=()=>G(U.error)})}function p(U,Y){let G=null,Q=null,X=null,$=(Z,L)=>{let H=Z??Error(L);if(Q){let B=Q;G=null,Q=null,B(H);return}X=H};return U.onsuccess=()=>{if(!G)return;let Z=G;G=null,Q=null,Z(U.result)},U.onerror=()=>{$(U.error,"IndexedDB cursor request failed.")},Y.onerror=()=>{$(Y.error,"IndexedDB transaction failed.")},Y.onabort=()=>{$(Y.error,"IndexedDB transaction aborted.")},()=>{return new Promise((Z,L)=>{if(X){let H=X;X=null,L(H);return}if(G=Z,Q=L,U.readyState==="done"){let H=G;G=null,Q=null,H?.(U.result)}})}}class JU{#Y;#G=null;#U;#J;constructor(U="weft",Y=GU()){this.#Y=U,this.#J=Y,this.#U=this.#Q()}capabilities(){return{persistence:"local",readAfterWrite:"linearizable",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}#Q(){let U=this.#J.indexedDB.open(this.#Y,1);return U.onupgradeneeded=()=>{let Y=U.result;if(!Y.objectStoreNames.contains(F))Y.createObjectStore(F)},N(U).then((Y)=>{return this.#G=Y,Y})}async get(U){let Q=(await this.#U).transaction(F,"readonly").objectStore(F),X=await N(Q.get(U));return X===void 0?null:new Uint8Array(X)}async put(U,Y){let X=(await this.#U).transaction(F,"readwrite").objectStore(F);await N(X.put(Y,U))}async delete(U){let Q=(await this.#U).transaction(F,"readwrite").objectStore(F);await N(Q.delete(U))}async has(U){let Q=(await this.#U).transaction(F,"readonly").objectStore(F);return await N(Q.count(U))>0}async deletePrefix(U){let Y=await this.#U,G=K(U),Q=this.#J.IDBKeyRange.bound(U,G,!1,!0);return new Promise((X,$)=>{let Z=Y.transaction(F,"readwrite"),L=Z.objectStore(F),H=0,B=L.count(Q);B.onsuccess=()=>{H=B.result,L.delete(Q)},Z.oncomplete=()=>X(H),Z.onerror=()=>$(Z.error)})}async deleteRange(U,Y){let G=h(Y),Q=l(U,G);if(Q===null)return 0;let X=this.#J.IDBKeyRange.bound(Q.lower.key,Q.upper.key,Q.lower.open,Q.upper.open),$=await this.#U,{limit:Z}=G;return new Promise((L,H)=>{let B=$.transaction(F,"readwrite"),M=B.objectStore(F),D=0;if(Z===void 0){let W=M.count(X);W.onsuccess=()=>{D=W.result,M.delete(X)}}else{let W=M.openCursor(X,"next");W.onsuccess=()=>{let _=W.result;if(_===null||D>=Z)return;if(_.delete(),D++,D<Z)_.continue()}}B.oncomplete=()=>L(D),B.onerror=()=>H(B.error)})}async*scan(U,Y={}){let{limit:G,reverse:Q}=Y,X=await this.#U,$=K(U),Z=this.#J.IDBKeyRange.bound(U,$,!1,!0),L=Q?"prev":"next",H=X.transaction(F,"readonly"),M=H.objectStore(F).openCursor(Z,L),D=0,W=p(M,H),_=!1;try{let V=await W();while(V){if(G!==void 0&&D>=G)break;let j=V.key;if(C(j,Y))yield[j,new Uint8Array(V.value)],D++;V.continue(),V=await W()}_=!0}finally{if(!_)try{H.abort()}catch{}}}async batch(U){if(T("batch operations",U.length),U.length===0)return;let Y=await this.#U;return new Promise((G,Q)=>{let X=Y.transaction(F,"readwrite"),$=X.objectStore(F);for(let Z of U)if(Z.type==="put")$.put(Z.value,Z.key);else $.delete(Z.key);X.oncomplete=()=>G(),X.onerror=()=>Q(X.error)})}async conditionalBatch(U,Y){T("conditionalBatch conditions",U.length),T("conditionalBatch operations",Y.length);let G=await this.#U;return new Promise((Q,X)=>{let $=G.transaction(F,"readwrite"),Z=$.objectStore(F),L=!1,H=!1,B=(W,_)=>{if(L)return;L=!0,X(W??Error(_))};$.oncomplete=()=>{if(L)return;L=!0,Q(!0)},$.onerror=()=>{B($.error,"IndexedDB conditionalBatch transaction failed.")},$.onabort=()=>{if(L)return;if(L=!0,H){Q(!1);return}X($.error??Error("IndexedDB conditionalBatch transaction aborted."))};let M=()=>{for(let W of Y)if(W.type==="put")Z.put(W.value,W.key);else Z.delete(W.key)},D=(W)=>{if(W>=U.length){M();return}let _=U[W],V=Z.get(_.key);V.onsuccess=()=>{let j=V.result,a=j===void 0?null:new Uint8Array(j);if(!I(a,_.expectedValue)){H=!0,$.abort();return}D(W+1)},V.onerror=()=>{B(V.error,"IndexedDB conditionalBatch condition check failed.")}};D(0)})}async*keys(U,Y={}){let{limit:G,reverse:Q}=Y,X=await this.#U,$=K(U),Z=this.#J.IDBKeyRange.bound(U,$,!1,!0),L=Q?"prev":"next",H=X.transaction(F,"readonly"),M=H.objectStore(F).openKeyCursor(Z,L),D=0,W=p(M,H),_=!1;try{let V=await W();while(V){if(G!==void 0&&D>=G)break;let j=V.key;if(C(j,Y))yield j,D++;V.continue(),V=await W()}_=!0}finally{if(!_)try{H.abort()}catch{}}}async count(U){let Y=await this.#U,G=K(U),X=Y.transaction(F,"readonly").objectStore(F);return N(X.count(this.#J.IDBKeyRange.bound(U,G,!1,!0)))}scoped(U){return d(this,U)}[Symbol.dispose](){if(this.#G)this.#G.close(),this.#G=null}}export{JU as IndexedDBStorage};
|
|
1
|
+
import {
|
|
2
|
+
normalizeDeleteRangeOptions,
|
|
3
|
+
resolveDeleteRangeBounds
|
|
4
|
+
} from "./delete-range.js";
|
|
5
|
+
import {
|
|
6
|
+
assertStorageBatchOperationCount,
|
|
7
|
+
matchesScanOptions,
|
|
8
|
+
resolvePrefixRangeEnd,
|
|
9
|
+
storageValuesEqual
|
|
10
|
+
} from "./interface.js";
|
|
11
|
+
import { scopedStorage } from "./scoped-storage.js";
|
|
12
|
+
const STORE_NAME = "kv";
|
|
13
|
+
function resolveIndexedDbRuntime(runtime = globalThis) {
|
|
14
|
+
const { indexedDB: indexedDbFactory, IDBKeyRange: keyRangeFactory } = runtime;
|
|
15
|
+
if (indexedDbFactory === void 0 || keyRangeFactory === void 0)
|
|
16
|
+
throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");
|
|
17
|
+
return {
|
|
18
|
+
indexedDB: indexedDbFactory,
|
|
19
|
+
IDBKeyRange: keyRangeFactory
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function promisify(request) {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
request.onsuccess = () => resolve(request.result);
|
|
25
|
+
request.onerror = () => reject(request.error);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function createCursorRequestAwaiter(request, transaction) {
|
|
29
|
+
let resolveCurrent = null, rejectCurrent = null, pendingError = null;
|
|
30
|
+
const rejectPendingCursor = (error, fallbackMessage) => {
|
|
31
|
+
const reason = error ?? Error(fallbackMessage);
|
|
32
|
+
if (rejectCurrent) {
|
|
33
|
+
const reject = rejectCurrent;
|
|
34
|
+
resolveCurrent = null;
|
|
35
|
+
rejectCurrent = null;
|
|
36
|
+
reject(reason);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
pendingError = reason;
|
|
40
|
+
};
|
|
41
|
+
request.onsuccess = () => {
|
|
42
|
+
if (!resolveCurrent)
|
|
43
|
+
return;
|
|
44
|
+
const resolve = resolveCurrent;
|
|
45
|
+
resolveCurrent = null;
|
|
46
|
+
rejectCurrent = null;
|
|
47
|
+
resolve(request.result);
|
|
48
|
+
};
|
|
49
|
+
request.onerror = () => {
|
|
50
|
+
rejectPendingCursor(request.error, "IndexedDB cursor request failed.");
|
|
51
|
+
};
|
|
52
|
+
transaction.onerror = () => {
|
|
53
|
+
rejectPendingCursor(transaction.error, "IndexedDB transaction failed.");
|
|
54
|
+
};
|
|
55
|
+
transaction.onabort = () => {
|
|
56
|
+
rejectPendingCursor(transaction.error, "IndexedDB transaction aborted.");
|
|
57
|
+
};
|
|
58
|
+
return () => {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
if (pendingError) {
|
|
61
|
+
const error = pendingError;
|
|
62
|
+
pendingError = null;
|
|
63
|
+
reject(error);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
resolveCurrent = resolve;
|
|
67
|
+
rejectCurrent = reject;
|
|
68
|
+
if (request.readyState === "done") {
|
|
69
|
+
const resolveReady = resolveCurrent;
|
|
70
|
+
resolveCurrent = null;
|
|
71
|
+
rejectCurrent = null;
|
|
72
|
+
resolveReady?.(request.result);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class IndexedDBStorage {
|
|
79
|
+
#databaseName;
|
|
80
|
+
#database = null;
|
|
81
|
+
#databasePromise;
|
|
82
|
+
#runtime;
|
|
83
|
+
constructor(databaseName = "weft", runtime = resolveIndexedDbRuntime()) {
|
|
84
|
+
this.#databaseName = databaseName;
|
|
85
|
+
this.#runtime = runtime;
|
|
86
|
+
this.#databasePromise = this.#open();
|
|
87
|
+
}
|
|
88
|
+
capabilities() {
|
|
89
|
+
return {
|
|
90
|
+
persistence: "local",
|
|
91
|
+
readAfterWrite: "linearizable",
|
|
92
|
+
scanConsistency: "best-effort",
|
|
93
|
+
atomicBatch: !0,
|
|
94
|
+
conditionalBatch: !0,
|
|
95
|
+
boundedRangeDelete: !0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
#open() {
|
|
99
|
+
const request = this.#runtime.indexedDB.open(this.#databaseName, 1);
|
|
100
|
+
request.onupgradeneeded = () => {
|
|
101
|
+
const database = request.result;
|
|
102
|
+
if (!database.objectStoreNames.contains(STORE_NAME))
|
|
103
|
+
database.createObjectStore(STORE_NAME);
|
|
104
|
+
};
|
|
105
|
+
return promisify(request).then((database) => {
|
|
106
|
+
this.#database = database;
|
|
107
|
+
return database;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async get(key) {
|
|
111
|
+
const store = (await this.#databasePromise).transaction(STORE_NAME, "readonly").objectStore(STORE_NAME), result = await promisify(store.get(key));
|
|
112
|
+
return result === void 0 ? null : new Uint8Array(result);
|
|
113
|
+
}
|
|
114
|
+
async put(key, value) {
|
|
115
|
+
const store = (await this.#databasePromise).transaction(STORE_NAME, "readwrite").objectStore(STORE_NAME);
|
|
116
|
+
await promisify(store.put(value, key));
|
|
117
|
+
}
|
|
118
|
+
async delete(key) {
|
|
119
|
+
const store = (await this.#databasePromise).transaction(STORE_NAME, "readwrite").objectStore(STORE_NAME);
|
|
120
|
+
await promisify(store.delete(key));
|
|
121
|
+
}
|
|
122
|
+
async has(key) {
|
|
123
|
+
const store = (await this.#databasePromise).transaction(STORE_NAME, "readonly").objectStore(STORE_NAME);
|
|
124
|
+
return await promisify(store.count(key)) > 0;
|
|
125
|
+
}
|
|
126
|
+
async deletePrefix(prefix) {
|
|
127
|
+
const database = await this.#databasePromise, prefixEnd = resolvePrefixRangeEnd(prefix), range = this.#runtime.IDBKeyRange.bound(prefix, prefixEnd, !1, !0);
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
const transaction = database.transaction(STORE_NAME, "readwrite"), store = transaction.objectStore(STORE_NAME);
|
|
130
|
+
let deletedCount = 0;
|
|
131
|
+
const countRequest = store.count(range);
|
|
132
|
+
countRequest.onsuccess = () => {
|
|
133
|
+
deletedCount = countRequest.result;
|
|
134
|
+
store.delete(range);
|
|
135
|
+
};
|
|
136
|
+
transaction.oncomplete = () => resolve(deletedCount);
|
|
137
|
+
transaction.onerror = () => reject(transaction.error);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async deleteRange(prefix, options) {
|
|
141
|
+
const normalized = normalizeDeleteRangeOptions(options), bounds = resolveDeleteRangeBounds(prefix, normalized);
|
|
142
|
+
if (bounds === null)
|
|
143
|
+
return 0;
|
|
144
|
+
const range = this.#runtime.IDBKeyRange.bound(bounds.lower.key, bounds.upper.key, bounds.lower.open, bounds.upper.open), database = await this.#databasePromise, { limit } = normalized;
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const transaction = database.transaction(STORE_NAME, "readwrite"), store = transaction.objectStore(STORE_NAME);
|
|
147
|
+
let deletedCount = 0;
|
|
148
|
+
if (limit === void 0) {
|
|
149
|
+
const countRequest = store.count(range);
|
|
150
|
+
countRequest.onsuccess = () => {
|
|
151
|
+
deletedCount = countRequest.result;
|
|
152
|
+
store.delete(range);
|
|
153
|
+
};
|
|
154
|
+
} else {
|
|
155
|
+
const cursorRequest = store.openCursor(range, "next");
|
|
156
|
+
cursorRequest.onsuccess = () => {
|
|
157
|
+
const cursor = cursorRequest.result;
|
|
158
|
+
if (cursor === null || deletedCount >= limit)
|
|
159
|
+
return;
|
|
160
|
+
cursor.delete();
|
|
161
|
+
deletedCount++;
|
|
162
|
+
if (deletedCount < limit)
|
|
163
|
+
cursor.continue();
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
transaction.oncomplete = () => resolve(deletedCount);
|
|
167
|
+
transaction.onerror = () => reject(transaction.error);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async* scan(prefix, options = {}) {
|
|
171
|
+
const { limit, reverse } = options, database = await this.#databasePromise, prefixEnd = resolvePrefixRangeEnd(prefix), range = this.#runtime.IDBKeyRange.bound(prefix, prefixEnd, !1, !0), direction = reverse ? "prev" : "next", transaction = database.transaction(STORE_NAME, "readonly"), request = transaction.objectStore(STORE_NAME).openCursor(range, direction);
|
|
172
|
+
let count = 0;
|
|
173
|
+
const nextCursor = createCursorRequestAwaiter(request, transaction);
|
|
174
|
+
let completed = !1;
|
|
175
|
+
try {
|
|
176
|
+
let cursor = await nextCursor();
|
|
177
|
+
while (cursor) {
|
|
178
|
+
if (limit !== void 0 && count >= limit)
|
|
179
|
+
break;
|
|
180
|
+
const key = cursor.key;
|
|
181
|
+
if (matchesScanOptions(key, options)) {
|
|
182
|
+
yield [key, new Uint8Array(cursor.value)];
|
|
183
|
+
count++;
|
|
184
|
+
}
|
|
185
|
+
cursor.continue();
|
|
186
|
+
cursor = await nextCursor();
|
|
187
|
+
}
|
|
188
|
+
completed = !0;
|
|
189
|
+
} finally {
|
|
190
|
+
if (!completed)
|
|
191
|
+
try {
|
|
192
|
+
transaction.abort();
|
|
193
|
+
} catch {}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async batch(operations) {
|
|
197
|
+
assertStorageBatchOperationCount("batch operations", operations.length);
|
|
198
|
+
if (operations.length === 0)
|
|
199
|
+
return;
|
|
200
|
+
const database = await this.#databasePromise;
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
const transaction = database.transaction(STORE_NAME, "readwrite"), store = transaction.objectStore(STORE_NAME);
|
|
203
|
+
for (const operation of operations)
|
|
204
|
+
if (operation.type === "put")
|
|
205
|
+
store.put(operation.value, operation.key);
|
|
206
|
+
else
|
|
207
|
+
store.delete(operation.key);
|
|
208
|
+
transaction.oncomplete = () => resolve();
|
|
209
|
+
transaction.onerror = () => reject(transaction.error);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
async conditionalBatch(conditions, operations) {
|
|
213
|
+
assertStorageBatchOperationCount("conditionalBatch conditions", conditions.length);
|
|
214
|
+
assertStorageBatchOperationCount("conditionalBatch operations", operations.length);
|
|
215
|
+
const database = await this.#databasePromise;
|
|
216
|
+
return new Promise((resolve, reject) => {
|
|
217
|
+
const transaction = database.transaction(STORE_NAME, "readwrite"), store = transaction.objectStore(STORE_NAME);
|
|
218
|
+
let settled = !1, abortedByCondition = !1;
|
|
219
|
+
const settleReject = (error, message) => {
|
|
220
|
+
if (settled)
|
|
221
|
+
return;
|
|
222
|
+
settled = !0;
|
|
223
|
+
reject(error ?? Error(message));
|
|
224
|
+
};
|
|
225
|
+
transaction.oncomplete = () => {
|
|
226
|
+
if (settled)
|
|
227
|
+
return;
|
|
228
|
+
settled = !0;
|
|
229
|
+
resolve(!0);
|
|
230
|
+
};
|
|
231
|
+
transaction.onerror = () => {
|
|
232
|
+
settleReject(transaction.error, "IndexedDB conditionalBatch transaction failed.");
|
|
233
|
+
};
|
|
234
|
+
transaction.onabort = () => {
|
|
235
|
+
if (settled)
|
|
236
|
+
return;
|
|
237
|
+
settled = !0;
|
|
238
|
+
if (abortedByCondition) {
|
|
239
|
+
resolve(!1);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
reject(transaction.error ?? Error("IndexedDB conditionalBatch transaction aborted."));
|
|
243
|
+
};
|
|
244
|
+
const applyOperations = () => {
|
|
245
|
+
for (const operation of operations)
|
|
246
|
+
if (operation.type === "put")
|
|
247
|
+
store.put(operation.value, operation.key);
|
|
248
|
+
else
|
|
249
|
+
store.delete(operation.key);
|
|
250
|
+
}, verifyCondition = (index) => {
|
|
251
|
+
if (index >= conditions.length) {
|
|
252
|
+
applyOperations();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const condition = conditions[index], request = store.get(condition.key);
|
|
256
|
+
request.onsuccess = () => {
|
|
257
|
+
const raw = request.result, currentValue = raw === void 0 ? null : new Uint8Array(raw);
|
|
258
|
+
if (!storageValuesEqual(currentValue, condition.expectedValue)) {
|
|
259
|
+
abortedByCondition = !0;
|
|
260
|
+
transaction.abort();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
verifyCondition(index + 1);
|
|
264
|
+
};
|
|
265
|
+
request.onerror = () => {
|
|
266
|
+
settleReject(request.error, "IndexedDB conditionalBatch condition check failed.");
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
verifyCondition(0);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
async* keys(prefix, options = {}) {
|
|
273
|
+
const { limit, reverse } = options, database = await this.#databasePromise, prefixEnd = resolvePrefixRangeEnd(prefix), range = this.#runtime.IDBKeyRange.bound(prefix, prefixEnd, !1, !0), direction = reverse ? "prev" : "next", transaction = database.transaction(STORE_NAME, "readonly"), request = transaction.objectStore(STORE_NAME).openKeyCursor(range, direction);
|
|
274
|
+
let count = 0;
|
|
275
|
+
const nextCursor = createCursorRequestAwaiter(request, transaction);
|
|
276
|
+
let completed = !1;
|
|
277
|
+
try {
|
|
278
|
+
let cursor = await nextCursor();
|
|
279
|
+
while (cursor) {
|
|
280
|
+
if (limit !== void 0 && count >= limit)
|
|
281
|
+
break;
|
|
282
|
+
const key = cursor.key;
|
|
283
|
+
if (matchesScanOptions(key, options)) {
|
|
284
|
+
yield key;
|
|
285
|
+
count++;
|
|
286
|
+
}
|
|
287
|
+
cursor.continue();
|
|
288
|
+
cursor = await nextCursor();
|
|
289
|
+
}
|
|
290
|
+
completed = !0;
|
|
291
|
+
} finally {
|
|
292
|
+
if (!completed)
|
|
293
|
+
try {
|
|
294
|
+
transaction.abort();
|
|
295
|
+
} catch {}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async count(prefix) {
|
|
299
|
+
const database = await this.#databasePromise, prefixEnd = resolvePrefixRangeEnd(prefix), store = database.transaction(STORE_NAME, "readonly").objectStore(STORE_NAME);
|
|
300
|
+
return promisify(store.count(this.#runtime.IDBKeyRange.bound(prefix, prefixEnd, !1, !0)));
|
|
301
|
+
}
|
|
302
|
+
scoped(prefix) {
|
|
303
|
+
return scopedStorage(this, prefix);
|
|
304
|
+
}
|
|
305
|
+
[Symbol.dispose]() {
|
|
306
|
+
if (this.#database) {
|
|
307
|
+
this.#database.close();
|
|
308
|
+
this.#database = null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
2
|
+
var T=import.meta.require,v=(E,_,F)=>{if(_!=null){if(typeof _!=="object"&&typeof _!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let P;if(F)P=_[Symbol.asyncDispose];if(P===void 0)P=_[Symbol.dispose];if(typeof P!=="function")throw TypeError("Object not disposable");E.push([F,P,_])}else if(F)E.push([F]);return _},H=(E,_,F)=>{let P=(W)=>_=F?new SuppressedError(W,_,"An error was suppressed during disposal"):(F=!0,W),Y=(W)=>{while(W=E.pop())try{var Z=W[1]&&W[1].call(W[2]);if(W[0])return Promise.resolve(Z).then(Y,(X)=>(P(X),Y()))}catch(X){P(X)}if(F)throw _};return Y()};function D(E,_,F){if(!E.capabilities()[_])throw Error(`Feature "${F}" requires storage capability "${_}", but this storage backend does not provide it.`)}function $(E){let _=E.capabilities(),F=[];if(_.persistence!=="local"&&_.persistence!=="remote")F.push(`persistence must be "local" or "remote" (got "${_.persistence}")`);if(_.readAfterWrite!=="linearizable")F.push(`readAfterWrite must be "linearizable" (got "${_.readAfterWrite}")`);if(_.scanConsistency!=="snapshot")F.push(`scanConsistency must be "snapshot" (got "${_.scanConsistency}")`);if(!_.atomicBatch)F.push("atomicBatch must be true");if(!_.conditionalBatch)F.push("conditionalBatch must be true");if(F.length>0)throw Error(`Storage is not durable enough for recovery: ${F.join("; ")}.`)}var L="default";async function J(E,_){return await E.get(_)!==null}async function*U(E,_,F){for await(let[P]of E.scan(_,F))yield P}async function K(E,_){let F=0;for await(let P of U(E,_))F++;return F}async function M(E,_){let F=[];for await(let P of U(E,_))F.push({type:"delete",key:P});if(F.length===0)return 0;return await E.batch(F),F.length}async function h(E,_,F){let P=[];for await(let Y of U(E,_,F))P.push({type:"delete",key:Y});if(P.length===0)return 0;return await E.batch(P),P.length}var j=["actrec:","archive:","async-act:","attr:","audit:bulk:","blob:","budget:","budget-charged:","ev:","fleet-event-by-workflow:","fleet-event:","fleet-event-tail","idx:","lease:","liveness:","offload:","op:","review:","schedule:","schedule-due:","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-teardown:","wf-teardown-deadletter:","wf-teardown-needed:","wf-terminal:"];var V=1e4,u=1e4;class Q extends Error{code="StorageBatchOperationLimitExceededError";cap=V;count;target;constructor(E,_){super(`${E} count ${_} exceeds MAX_BATCH_OPERATIONS (${V}).`);this.name="StorageBatchOperationLimitExceededError",this.target=E,this.count=_}}function G(E,_){if(_>V)throw new Q(E,_)}function y(E){return E.length>0?E.slice(0,-1)+String.fromCharCode(E.charCodeAt(E.length-1)+1):"\xFF"}function g(E,_={}){if(_.gt!==void 0&&E<=_.gt)return!1;if(_.gte!==void 0&&E<_.gte)return!1;if(_.lt!==void 0&&E>=_.lt)return!1;if(_.lte!==void 0&&E>_.lte)return!1;return!0}function n(E,_){if(E===null||_===null)return E===_;if(E.byteLength!==_.byteLength)return!1;for(let F=0;F<E.byteLength;F++)if(E[F]!==_[F])return!1;return!0}async function p(E,_){if(E.has)return E.has(_);return J(E,_)}function s(E,_,F){if(E.keys)return E.keys(_,F);return U(E,_,F)}async function f(E,_){if(E.count)return E.count(_);return K(E,_)}async function a(E,_){if(E.deletePrefix)return E.deletePrefix(_);return M(E,_)}async function I(E,_){G("batch operations",_.length),await E.batch(_)}async function l(E,_,F){if(G("conditionalBatch conditions",_.length),G("conditionalBatch operations",F.length),D(E,"conditionalBatch","storageConditionalBatch"),!E.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return E.conditionalBatch(_,F)}function S(E){return encodeURIComponent(E)}function k(E){return decodeURIComponent(E)}function t(E){try{return decodeURIComponent(E)}catch{return null}}var R=(E)=>String(E).padStart(16,"0"),z="0",B="1",O=(E,_,F,P)=>`sig:${S(E)}:${S(_)}:${P}:${S(F)}`,d={workflow:(E)=>`wf:${S(E)}`,checkpoint:(E)=>`wf:${S(E)}:ckpt`,checkpointHistory:(E,_)=>`wf:${S(E)}:ckpt:${String(_).padStart(10,"0")}`,timelinePrefix:(E)=>`wf:${S(E)}:timeline:`,timeline:(E,_)=>`wf:${S(E)}:timeline:${String(_).padStart(10,"0")}`,schedule:(E)=>`schedule:${S(E)}`,scheduleTick:(E,_)=>`schedule-due:${String(E).padStart(16,"0")}:${S(_)}`,scheduleRun:(E)=>`schedule-run:${S(E)}`,operation:(E,_,F)=>`op:${E}:${R(_)}:${F}`,operationInflight:(E)=>`op:inflight:${E}`,operationQueued:(E)=>`op:queued:${E}`,operationResolved:(E)=>`op:resolved:${E}`,operationDeadLetterPrefix:()=>"op:dead-letter:",operationDeadLetter:(E)=>`op:dead-letter:${E}`,bulkOperationAuditPrefix:()=>"audit:bulk:",bulkOperationAudit:(E,_,F)=>`audit:bulk:${R(E)}:${S(_)}:${S(F)}`,operationResolvedByTimePrefix:()=>"op:resolved-by-time:",operationResolvedByTime:(E,_)=>`op:resolved-by-time:${R(E)}:${S(_)}`,asyncActivity:(E,_)=>`async-act:v1:${S(E)}:${S(_)}`,asyncActivityResolution:(E,_)=>`async-act:v1:${S(E)}:${S(_)}:resolution`,activityReconciliationPrefix:(E)=>`actrec:v1:${S(E)}:`,activityReconciliation:(E,_,F)=>`actrec:v1:${S(E)}:${S(_)}:${F}`,eventPrefix:(E)=>`ev:${S(E)}:`,event:(E,_)=>`ev:${S(E)}:${String(_).padStart(10,"0")}`,eventHead:(E)=>`ev:${S(E)}:head`,eventWatermark:(E)=>`ev:${S(E)}:watermark`,fleetEventPrefix:()=>"fleet-event:",fleetEvent:(E)=>`fleet-event:${String(E).padStart(10,"0")}`,fleetEventTail:()=>"fleet-event-tail",fleetEventByWorkflowPrefix:(E)=>`fleet-event-by-workflow:${S(E)}:`,fleetEventByWorkflow:(E,_)=>`fleet-event-by-workflow:${S(E)}:${String(_).padStart(10,"0")}`,signal:(E,_,F)=>O(E,_,F,B),startSignal:(E,_,F)=>O(E,_,F,z),signalSequence:(E)=>`sigseq:v1:${S(E)}`,signalAcceptedResponsePrefix:(E)=>`sigres:v1:${S(E)}:`,signalAcceptedResponse:(E,_,F)=>`sigres:v1:${S(E)}:${S(_)}:${S(F)}`,deadline:(E,_)=>`wf-deadline:${R(E)}:${S(_)}`,terminalCleanup:(E,_)=>`wf-cleanup:${R(E)}:${S(_)}`,teardownTimer:(E,_)=>`wf-teardown:${R(E)}:${S(_)}`,delayedStart:(E,_)=>`wf-delayed:${R(E)}:${S(_)}`,terminalWorkflowPrefix:()=>"wf-terminal:",terminalWorkflow:(E,_)=>`wf-terminal:${R(E)}:${S(_)}`,attribute:(E)=>`attr:${S(E)}`,attributeIndex:(E,_,F)=>`idx:${E}:${_}:${S(F)}`,tagIndex:(E,_)=>`tag:${S(E)}:${S(_)}`,updatePrefix:(E)=>`upd:${S(E)}:`,update:(E,_)=>`upd:${S(E)}:${_}`,updateResponse:(E)=>`upr:${E}`,updateIdempotency:(E,_)=>`upk:${S(E)}:${_}`,startIdempotency:(E)=>`start-idem:${S(E)}`,startIdempotencySignalId:(E)=>`start-idem:${E}`,livenessPrefix:()=>"liveness:",liveness:(E)=>`liveness:${S(E)}`,leasePrefix:()=>"lease:",leaseEpoch:()=>"lease:epoch",leaseHolder:()=>"lease:holder",budget:(E,_,F)=>`budget:${E}:${_}:${F}`,review:(E,_)=>`review:${S(E)}:${_}`,workflowHeaders:(E)=>`wf-headers:${S(E)}`,childCancellationPrefix:(E)=>`child-cancel:${S(E)}:`,childCancellation:(E,_)=>`child-cancel:${S(E)}:${S(_)}`,terminalCleanupNeeded:(E)=>`wf-cleanup-needed:${S(E)}`,workflowConcurrency:(E,_)=>`wf-concurrency:${S(E)}:${S(_)}`,workflowConcurrencyHolder:(E)=>`wf-concurrency-holder:${S(E)}`,workflowHasServices:(E)=>`wf-has-services:${S(E)}`,finalizerState:(E)=>`wf-finalizer-state:${S(E)}`,teardownOwed:(E)=>`wf-teardown-needed:${S(E)}`,teardownDeadLetter:(E)=>`wf-teardown-deadletter:${S(E)}`,offload:(E,_)=>`offload:${S(E)}:${_}`,archive:(E,_)=>`archive:${S(E)}:${_}`,stateExecution:(E,_)=>`state:execution:${S(E)}:${S(_)}`,stateWorkflow:(E,_)=>`state:workflow-scope:${L}:${S(E)}:${S(_)}`,streamChunkPrefix:(E,_)=>`blob:${S(E)}:${_}:chunk:`,streamChunk:(E,_,F)=>`blob:${S(E)}:${_}:chunk:${String(F).padStart(10,"0")}`,streamTail:(E,_)=>`blob:${S(E)}:${_}:tail`,streamMetadata:(E,_)=>`blob:${S(E)}:${_}:meta`,budgetCharged:(E)=>`budget-charged:${E}`,toolEffect:(E,_,F)=>`tool-effect:${S(E)}:${_}:${F}`,workflowVisibilityStatus:(E,_)=>`wf-idx-status:${S(E)}:${S(_)}`,workflowVisibilityType:(E,_)=>`wf-idx-type:${S(E)}:${S(_)}`,workflowVisibilityCreated:(E,_)=>`wf-idx-created:${R(E)}:${S(_)}`,workflowVisibilityUpdated:(E,_)=>`wf-idx-updated:${R(E)}:${S(_)}`,workflowVisibilityDeadline:(E,_)=>`wf-idx-deadline:${R(E)}:${S(_)}`,workflowVisibilityManifest:(E)=>`wf-idx-manifest:${S(E)}`,workflowVisibilityMetaVersion:()=>"wf-idx-meta:version",workflowVisibilityMetaBuiltAt:()=>"wf-idx-meta:built-at",workflowVisibilityMetaCursor:()=>"wf-idx-meta:cursor"};export{t as tryDecodeStorageKeyComponent,n as storageValuesEqual,s as storageKeys,p as storageHas,a as storageDeletePrefix,f as storageCount,l as storageConditionalBatch,I as storageBatch,y as resolvePrefixRangeEnd,D as requireStorageCapability,g as matchesScanOptions,S as encodeStorageKeyComponent,k as decodeStorageKeyComponent,G as assertStorageBatchOperationCount,$ as assertDurableStorageForRecovery,j as WEFT_RESERVED_KEY_PREFIXES,Q as StorageBatchOperationLimitExceededError,u as MAX_SCAN_LIMIT,V as MAX_BATCH_OPERATIONS,d as KEYS,L as DEFAULT_SCOPE};
|