@nestm/storage 0.1.0-alpha.18 → 0.1.0-alpha.19
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/CHANGELOG.md +6 -0
- package/README.md +12 -0
- package/dist/workspace/storage-catalog-checkout.d.ts +1 -1
- package/dist/workspace/storage-catalog-checkout.d.ts.map +1 -1
- package/dist/workspace/storage-catalog-checkout.js +3 -50
- package/dist/workspace/storage-catalog-checkout.js.map +1 -1
- package/dist/workspace/storage-file-catalog.types.d.ts +8 -0
- package/dist/workspace/storage-file-catalog.types.d.ts.map +1 -1
- package/dist/workspace/storage-file-catalog.types.js.map +1 -1
- package/dist/workspace/storage-file-workflow.d.ts.map +1 -1
- package/dist/workspace/storage-file-workflow.js +17 -1
- package/dist/workspace/storage-file-workflow.js.map +1 -1
- package/dist/workspace/storage-file-workflow.protection.d.ts.map +1 -1
- package/dist/workspace/storage-file-workflow.protection.js +35 -0
- package/dist/workspace/storage-file-workflow.protection.js.map +1 -1
- package/dist/workspace/storage-file-workflow.types.d.ts +9 -1
- package/dist/workspace/storage-file-workflow.types.d.ts.map +1 -1
- package/dist/workspace/storage-file-workflow.types.js.map +1 -1
- package/dist/workspace/storage-working-files.d.ts.map +1 -1
- package/dist/workspace/storage-working-files.js +41 -6
- package/dist/workspace/storage-working-files.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @nestm/storage
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.19
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6402887: Add protected revision-pinned host streams for file catalogs and checkpoints. Apply saved-file edits directly from one stream into an atomic candidate, avoiding intermediate checkouts and repeated small range reads.
|
|
8
|
+
|
|
3
9
|
## 0.1.0-alpha.18
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1352,3 +1352,15 @@ MIT
|
|
|
1352
1352
|
The host authorizes reads, serializes metadata, enforces key policy and atomically proves reference eligibility before `metadata.discard` removes anything. A missing upload receipt means completion is uncertain: keep prepared cleanup inventory for a later sweep. A rejected prepare does not authorize cleanup of another writer's reservation. Engine shutdown stays with its owner. See [the standalone archive consumer](scripts/fixtures/encrypted-content-consumer.ts).
|
|
1353
1353
|
|
|
1354
1354
|
`StorageStagedContentStore.writeReserved(scope, payloadId, stream, options)` accepts a fresh UUID from a trusted caller. It retains create-only semantics and returns that exact identity in the receipt; it never overwrites an existing payload. Ordinary writers continue to use `write`.
|
|
1355
|
+
|
|
1356
|
+
### Revision-pinned host streams
|
|
1357
|
+
|
|
1358
|
+
Catalog `readStream({ path, expectedEtag, start?, end?, signal? })` and workflow
|
|
1359
|
+
`readStream({ draftId, expectedSize, start?, end?, signal? })` return metadata and
|
|
1360
|
+
a byte stream. Ranges use an inclusive start and exclusive end. These host-only
|
|
1361
|
+
operations retain read authorization and linked cancellation; they are never
|
|
1362
|
+
projected as unbounded model tools. Catalog hosts must pin immutable content to
|
|
1363
|
+
the requested revision and reject stale heads. Saved-file working edits consume
|
|
1364
|
+
one stream directly into an atomic candidate without creating a checkout first.
|
|
1365
|
+
`stageStream.body` may asynchronously open its source after authorization and
|
|
1366
|
+
replay validation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StorageFileCatalogCapability, StorageCatalogCommand } from './storage-file-catalog.types.js';
|
|
2
2
|
import type { StorageFileWorkflowCapability } from './storage-file-workflow.types.js';
|
|
3
|
-
/**
|
|
3
|
+
/** Copy an exact host stream into a sealed checkpoint without small-window rereads. */
|
|
4
4
|
export declare function checkoutStorageCatalogText<Receipt>(catalog: StorageFileCatalogCapability<Receipt>, workflow: StorageFileWorkflowCapability<Receipt>, input: StorageCatalogCommand & {
|
|
5
5
|
readonly expectedEtag: string;
|
|
6
6
|
}): Promise<import("./storage-file-workflow.types.js").StorageFileDraft<Receipt>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-catalog-checkout.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-catalog-checkout.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAEtF,uFAAuF;AACvF,wBAAsB,0BAA0B,CAAC,OAAO,EACtD,OAAO,EAAE,4BAA4B,CAAC,OAAO,CAAC,EAC9C,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC,EAChD,KAAK,EAAE,qBAAqB,GAAG;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,iFAWjE"}
|
|
@@ -1,60 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
/** Stream exact catalog windows into a sealed checkpoint without buffering the file. */
|
|
1
|
+
/** Copy an exact host stream into a sealed checkpoint without small-window rereads. */
|
|
3
2
|
export async function checkoutStorageCatalogText(catalog, workflow, input) {
|
|
4
|
-
const file = await catalog.stat(input);
|
|
5
|
-
if (file.etag !== input.expectedEtag)
|
|
6
|
-
throw new StorageError('The catalog revision changed.', {
|
|
7
|
-
code: 'CONFLICT',
|
|
8
|
-
});
|
|
9
3
|
return workflow.stageStream({
|
|
10
4
|
path: input.path,
|
|
11
5
|
expectedEtag: input.expectedEtag,
|
|
12
6
|
text: true,
|
|
13
7
|
signal: input.signal,
|
|
14
8
|
idempotencyKey: input.commandId,
|
|
15
|
-
contentIdentity: JSON.stringify([
|
|
16
|
-
body: () =>
|
|
17
|
-
let offset = 0;
|
|
18
|
-
return new ReadableStream({
|
|
19
|
-
async pull(controller) {
|
|
20
|
-
try {
|
|
21
|
-
const page = await catalog.readWindow({ ...input, offset });
|
|
22
|
-
if (page.etag !== input.expectedEtag ||
|
|
23
|
-
page.totalBytes !== file.size ||
|
|
24
|
-
page.offset !== offset)
|
|
25
|
-
throw new StorageError('The catalog revision changed.', {
|
|
26
|
-
code: 'CONFLICT',
|
|
27
|
-
});
|
|
28
|
-
if (page.content === null)
|
|
29
|
-
throw new StorageError('Checkout requires a text file.', {
|
|
30
|
-
code: 'INVALID_ARGUMENT',
|
|
31
|
-
});
|
|
32
|
-
const next = offset + new TextEncoder().encode(page.content).byteLength;
|
|
33
|
-
if (next > file.size ||
|
|
34
|
-
(page.nextOffset === null
|
|
35
|
-
? next !== file.size
|
|
36
|
-
: page.nextOffset !== next || next <= offset))
|
|
37
|
-
throw new StorageError('Invalid catalog text window.', {
|
|
38
|
-
code: 'PROVIDER',
|
|
39
|
-
});
|
|
40
|
-
controller.enqueue(new TextEncoder().encode(page.content));
|
|
41
|
-
offset = next;
|
|
42
|
-
if (page.nextOffset === null) {
|
|
43
|
-
const current = await catalog.stat(input);
|
|
44
|
-
if (current.etag !== input.expectedEtag ||
|
|
45
|
-
current.size !== file.size)
|
|
46
|
-
throw new StorageError('The catalog revision changed.', {
|
|
47
|
-
code: 'CONFLICT',
|
|
48
|
-
});
|
|
49
|
-
controller.close();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
controller.error(error);
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
}, { highWaterMark: 0 });
|
|
57
|
-
},
|
|
9
|
+
contentIdentity: JSON.stringify([input.path, input.expectedEtag]),
|
|
10
|
+
body: async () => (await catalog.readStream(input)).body,
|
|
58
11
|
});
|
|
59
12
|
}
|
|
60
13
|
//# sourceMappingURL=storage-catalog-checkout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-catalog-checkout.js","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-catalog-checkout.js","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"AAMA,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAA8C,EAC9C,QAAgD,EAChD,KAAgE;IAEhE,OAAO,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,cAAc,EAAE,KAAK,CAAC,SAAS;QAC/B,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;KACzD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n StorageFileCatalogCapability,\n StorageCatalogCommand,\n} from './storage-file-catalog.types.js';\nimport type { StorageFileWorkflowCapability } from './storage-file-workflow.types.js';\n\n/** Copy an exact host stream into a sealed checkpoint without small-window rereads. */\nexport async function checkoutStorageCatalogText<Receipt>(\n catalog: StorageFileCatalogCapability<Receipt>,\n workflow: StorageFileWorkflowCapability<Receipt>,\n input: StorageCatalogCommand & { readonly expectedEtag: string },\n) {\n return workflow.stageStream({\n path: input.path,\n expectedEtag: input.expectedEtag,\n text: true,\n signal: input.signal,\n idempotencyKey: input.commandId,\n contentIdentity: JSON.stringify([input.path, input.expectedEtag]),\n body: async () => (await catalog.readStream(input)).body,\n });\n}\n"]}
|
|
@@ -47,6 +47,14 @@ export interface StorageFileCatalogCapability<Receipt = unknown> {
|
|
|
47
47
|
readonly size: number;
|
|
48
48
|
readonly totalBytes: number;
|
|
49
49
|
}>;
|
|
50
|
+
/** Host-only bytes pinned to expectedEtag; end is exclusive. Never project as a model tool. */
|
|
51
|
+
readStream(input: StorageCatalogPath & {
|
|
52
|
+
readonly expectedEtag: string;
|
|
53
|
+
readonly start?: number | undefined;
|
|
54
|
+
readonly end?: number | undefined;
|
|
55
|
+
}): Promise<StorageCatalogFile & {
|
|
56
|
+
readonly body: ReadableStream<Uint8Array>;
|
|
57
|
+
}>;
|
|
50
58
|
searchContent(input: StorageCatalogPath & StorageCatalogPage & {
|
|
51
59
|
readonly expectedEtag: string;
|
|
52
60
|
readonly query: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-catalog.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"storage-file-catalog.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-catalog.types.js","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n StorageTextEdit,\n StorageTextSearchResult,\n} from '../core/storage-text.js';\nimport type { StorageTextWindow } from '../core/storage-streams.js';\nimport type {\n StorageFileWorkflowOperation,\n StorageFileWorkflowPage,\n} from './storage-file-workflow.types.js';\n\nexport interface StorageCatalogFile {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly contentType: string;\n}\nexport interface StorageFileCatalogLimits {\n readonly maxReadBytes: number;\n readonly maxWriteBytes: number;\n readonly maxPageSize: number;\n readonly maxSearchScanBytes: number;\n readonly maxSearchMatches: number;\n readonly maxPathBytes: number;\n}\nexport interface StorageCatalogPath extends StorageFileWorkflowOperation {\n readonly path: string;\n readonly expectedEtag?: string | undefined;\n}\nexport interface StorageCatalogPage extends StorageFileWorkflowOperation {\n readonly offset?: number | undefined;\n}\nexport interface StorageCatalogCommand extends StorageCatalogPath {\n /** Opaque host-scoped command identity, stable across response-loss retries. */\n readonly commandId: string;\n}\n/** Host catalog port. Implementations own persistence, conditional heads and replay. */\nexport interface StorageFileCatalogCapability<Receipt = unknown> {\n readonly kind: 'storage-file-catalog';\n readonly version: 1;\n readonly limits: StorageFileCatalogLimits;\n allows(permission: 'read' | 'write'): boolean;\n list(\n input: StorageCatalogPage & { readonly directory?: string | undefined },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n stat(input: StorageCatalogPath): Promise<StorageCatalogFile>;\n search(\n input: StorageCatalogPage & { readonly query: string },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n readWindow(input: StorageCatalogPath & StorageCatalogPage): Promise<\n StorageTextWindow & {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly totalBytes: number;\n }\n >;\n searchContent(\n input: StorageCatalogPath &\n StorageCatalogPage & {\n readonly expectedEtag: string;\n readonly query: string;\n },\n ): Promise<\n StorageTextSearchResult & { readonly path: string; readonly etag: string }\n >;\n write(\n input: StorageCatalogCommand & { readonly content: string },\n ): Promise<Receipt>;\n edit(\n input: StorageCatalogCommand & {\n readonly expectedEtag: string;\n readonly change: StorageTextEdit;\n },\n ): Promise<Receipt>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage-file-catalog.types.js","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n StorageTextEdit,\n StorageTextSearchResult,\n} from '../core/storage-text.js';\nimport type { StorageTextWindow } from '../core/storage-streams.js';\nimport type {\n StorageFileWorkflowOperation,\n StorageFileWorkflowPage,\n} from './storage-file-workflow.types.js';\n\nexport interface StorageCatalogFile {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly contentType: string;\n}\nexport interface StorageFileCatalogLimits {\n readonly maxReadBytes: number;\n readonly maxWriteBytes: number;\n readonly maxPageSize: number;\n readonly maxSearchScanBytes: number;\n readonly maxSearchMatches: number;\n readonly maxPathBytes: number;\n}\nexport interface StorageCatalogPath extends StorageFileWorkflowOperation {\n readonly path: string;\n readonly expectedEtag?: string | undefined;\n}\nexport interface StorageCatalogPage extends StorageFileWorkflowOperation {\n readonly offset?: number | undefined;\n}\nexport interface StorageCatalogCommand extends StorageCatalogPath {\n /** Opaque host-scoped command identity, stable across response-loss retries. */\n readonly commandId: string;\n}\n/** Host catalog port. Implementations own persistence, conditional heads and replay. */\nexport interface StorageFileCatalogCapability<Receipt = unknown> {\n readonly kind: 'storage-file-catalog';\n readonly version: 1;\n readonly limits: StorageFileCatalogLimits;\n allows(permission: 'read' | 'write'): boolean;\n list(\n input: StorageCatalogPage & { readonly directory?: string | undefined },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n stat(input: StorageCatalogPath): Promise<StorageCatalogFile>;\n search(\n input: StorageCatalogPage & { readonly query: string },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n readWindow(input: StorageCatalogPath & StorageCatalogPage): Promise<\n StorageTextWindow & {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly totalBytes: number;\n }\n >;\n /** Host-only bytes pinned to expectedEtag; end is exclusive. Never project as a model tool. */\n readStream(\n input: StorageCatalogPath & {\n readonly expectedEtag: string;\n readonly start?: number | undefined;\n readonly end?: number | undefined;\n },\n ): Promise<\n StorageCatalogFile & { readonly body: ReadableStream<Uint8Array> }\n >;\n searchContent(\n input: StorageCatalogPath &\n StorageCatalogPage & {\n readonly expectedEtag: string;\n readonly query: string;\n },\n ): Promise<\n StorageTextSearchResult & { readonly path: string; readonly etag: string }\n >;\n write(\n input: StorageCatalogCommand & { readonly content: string },\n ): Promise<Receipt>;\n edit(\n input: StorageCatalogCommand & {\n readonly expectedEtag: string;\n readonly change: StorageTextEdit;\n },\n ): Promise<Receipt>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,+BAA+B,EAGpC,KAAK,6BAA6B,EAGlC,KAAK,0BAA0B,EAIhC,MAAM,kCAAkC,CAAC;AAE1C,qBAAa,mBAAmB,CAAC,KAAK,EAAE,OAAO;;IAE7C,YAAY,OAAO,EAAE,0BAA0B,CAAC,KAAK,EAAE,OAAO,CAAC,EAE9D;IAED,KAAK,CACH,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,+BAAoC,GAC5C,6BAA6B,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,+BAA+B,EAGpC,KAAK,6BAA6B,EAGlC,KAAK,0BAA0B,EAIhC,MAAM,kCAAkC,CAAC;AAE1C,qBAAa,mBAAmB,CAAC,KAAK,EAAE,OAAO;;IAE7C,YAAY,OAAO,EAAE,0BAA0B,CAAC,KAAK,EAAE,OAAO,CAAC,EAE9D;IAED,KAAK,CACH,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,+BAAoC,GAC5C,6BAA6B,CAAC,OAAO,CAAC,CAmqBxC;CA6FF"}
|
|
@@ -197,7 +197,7 @@ export class StorageFileWorkflow {
|
|
|
197
197
|
expectedEtag: input.expectedEtag ?? null,
|
|
198
198
|
source,
|
|
199
199
|
text: input.text,
|
|
200
|
-
content: input.body(),
|
|
200
|
+
content: await input.body(),
|
|
201
201
|
};
|
|
202
202
|
},
|
|
203
203
|
}));
|
|
@@ -270,6 +270,22 @@ export class StorageFileWorkflow {
|
|
|
270
270
|
};
|
|
271
271
|
});
|
|
272
272
|
},
|
|
273
|
+
readStream: async (input) => {
|
|
274
|
+
const signal = operation('read', input);
|
|
275
|
+
const draft = await transaction(signal, (tx) => requireDraft(tx, input.draftId));
|
|
276
|
+
if (draft.status === 'cancelled' || draft.size !== input.expectedSize)
|
|
277
|
+
conflict('The source checkpoint changed.');
|
|
278
|
+
const start = input.start ?? 0;
|
|
279
|
+
const end = input.end ?? draft.size;
|
|
280
|
+
storageInteger(start, 'start');
|
|
281
|
+
storageInteger(end, 'end');
|
|
282
|
+
if (start > end || end > draft.size)
|
|
283
|
+
invalid('Invalid stream range.');
|
|
284
|
+
return {
|
|
285
|
+
...summary(draft),
|
|
286
|
+
body: this.#stream(scope, draft, limits, signal, start, end),
|
|
287
|
+
};
|
|
288
|
+
},
|
|
273
289
|
read: async (input) => {
|
|
274
290
|
const signal = operation('read', input);
|
|
275
291
|
const draft = await transaction(signal, (tx) => requireDraft(tx, input.draftId));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"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","sourcesContent":["import { searchStorageText } from '../core/storage-text.js';\nimport { editStorageTextStream } from '../core/storage-text-stream-edit.js';\nimport { stageStorageTextDraft } from './storage-text-draft.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { StorageError } from '../storage.error.js';\nimport { assertWorkspacePath } from './storage-workspace.path.js';\nimport type { StorageStagedBody } from '../core/storage-staged-content.js';\nimport {\n collectStorageBytes,\n readStorageTextWindow,\n storageBytesStream,\n storageInteger,\n} from '../core/storage-streams.js';\nimport {\n DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS,\n type MountStorageFileWorkflowOptions,\n type StorageFileDraft,\n type StorageFileDraftRecord,\n type StorageFileWorkflowCapability,\n type StorageFileWorkflowLimits,\n type StorageFileWorkflowOperation,\n type StorageFileWorkflowOptions,\n type StorageFileWorkflowPermission,\n type StorageFileWorkflowMutation,\n type StorageFileWorkflowTransaction,\n} from './storage-file-workflow.types.js';\n\nexport class StorageFileWorkflow<Scope, Receipt> {\n readonly #options: StorageFileWorkflowOptions<Scope, Receipt>;\n constructor(options: StorageFileWorkflowOptions<Scope, Receipt>) {\n this.#options = options;\n }\n\n mount(\n scope: Scope,\n options: MountStorageFileWorkflowOptions = {},\n ): StorageFileWorkflowCapability<Receipt> {\n const limits = Object.freeze({\n ...DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS,\n ...options.limits,\n });\n for (const [name, value] of Object.entries(limits))\n storageInteger(value, name, name === 'maxReadBytes' ? 4 : 1);\n const permissions = new Set(\n options.permissions ?? ['read', 'write', 'commit'],\n );\n const mutations = new Set<StorageFileWorkflowMutation>(\n options.mutations ?? ['create', 'replace'],\n );\n const boundSignal = options.signal;\n const requireMutation = (expectedEtag: string | null | undefined) => {\n if (!mutations.has(expectedEtag == null ? 'create' : 'replace'))\n throw new StorageError(\n 'Draft mutation is not permitted by this capability.',\n { code: 'UNAUTHORIZED' },\n );\n };\n const operationPermissions = new WeakMap<\n AbortSignal,\n StorageFileWorkflowPermission\n >();\n const allows = (permission: StorageFileWorkflowPermission) =>\n permissions.has(permission) &&\n (permission === 'read' || mutations.size > 0);\n const operation = (\n permission: StorageFileWorkflowPermission,\n input: StorageFileWorkflowOperation,\n ) => {\n if (!allows(permission))\n throw new StorageError('File workflow operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n const signals = [boundSignal, input.signal].filter(\n (signal): signal is AbortSignal => signal !== undefined,\n );\n const signal = AbortSignal.any(signals);\n signal.throwIfAborted();\n operationPermissions.set(signal, permission);\n return signal;\n };\n const transaction = <T>(\n signal: AbortSignal,\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<T>,\n ) =>\n this.#transaction(scope, signal, operationPermissions.get(signal)!, work);\n const content = this.#options.content;\n const workflow: StorageFileWorkflowCapability<Receipt> = {\n kind: 'storage-file-workflow',\n version: 1,\n limits,\n allows,\n restrict: (restriction) => {\n const narrowed = { ...limits };\n for (const name of Object.keys(\n limits,\n ) as (keyof StorageFileWorkflowLimits)[]) {\n const requested = restriction.limits?.[name] ?? limits[name];\n storageInteger(requested, name, name === 'maxReadBytes' ? 4 : 1);\n narrowed[name] = Math.min(limits[name], requested);\n }\n return this.mount(scope, {\n limits: narrowed,\n permissions: [...(restriction.permissions ?? permissions)].filter(\n (permission) => permissions.has(permission),\n ),\n mutations: [...(restriction.mutations ?? mutations)].filter(\n (mutation) => mutations.has(mutation),\n ),\n signal: AbortSignal.any(\n [boundSignal, restriction.signal].filter(\n (signal): signal is AbortSignal => signal !== undefined,\n ),\n ),\n });\n },\n lookup: async (input) => {\n const signal = operation('read', input);\n validateIdentity(input.idempotencyKey);\n return transaction(signal, async (tx) => {\n const draft = await tx.findDraftByKey(input.idempotencyKey);\n return draft === null ? null : summary(draft);\n });\n },\n begin: async (input) => {\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n validateIdentity(input.idempotencyKey);\n if (\n typeof input.text !== 'boolean' ||\n (input.expectedEtag !== undefined &&\n (typeof input.expectedEtag !== 'string' ||\n input.expectedEtag.length === 0 ||\n input.expectedEtag.length > 1024))\n )\n invalid('Invalid draft input.');\n const fingerprint = digest(\n new TextEncoder().encode(\n JSON.stringify([\n input.path,\n input.expectedEtag ?? null,\n input.text,\n ]),\n ),\n );\n return transaction(signal, async (tx) => {\n const prior = await tx.findDraftByKey(input.idempotencyKey);\n if (prior !== null) {\n if (prior.requestFingerprint !== fingerprint)\n conflict('Draft key was already used for different input.');\n return summary(prior);\n }\n const record: StorageFileDraftRecord<Receipt> = {\n id: randomUUID(),\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n sourceDraftId: null,\n text: input.text,\n status: 'open',\n size: 0,\n result: null,\n createdAt: new Date().toISOString(),\n idempotencyKey: input.idempotencyKey,\n requestFingerprint: fingerprint,\n body: null,\n };\n await tx.saveDraft(record);\n return summary(record);\n });\n },\n stageText: async (request) => {\n const input = { ...request };\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n validateIdentity(input.idempotencyKey);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n if (\n input.expectedEtag !== undefined &&\n (input.expectedEtag.length < 1 || input.expectedEtag.length > 1024)\n )\n invalid('Invalid ETag.');\n if (\n new TextEncoder().encode(input.content).byteLength >\n limits.maxTextBytes\n )\n throw new StorageError(\n 'Text checkpoint exceeds the buffered text limit.',\n { code: 'LIMIT_EXCEEDED' },\n );\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'stage-text',\n input.path,\n input.expectedEtag ?? null,\n input.content,\n ]),\n ),\n ),\n load: async () => ({\n content: input.content,\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n source: null,\n }),\n }),\n );\n },\n stageStream: async (request) => {\n const input = { ...request };\n if (input.sourceDraftId !== undefined) operation('read', input);\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n validateIdentity(input.idempotencyKey);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n if (\n typeof input.text !== 'boolean' ||\n typeof input.contentIdentity !== 'string' ||\n !input.contentIdentity.length ||\n input.contentIdentity.length > 1024\n )\n invalid('Invalid streaming draft identity.');\n if (\n input.expectedEtag !== undefined &&\n (!input.expectedEtag.length || input.expectedEtag.length > 1024)\n )\n invalid('Invalid ETag.');\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'stage-stream',\n input.path,\n input.expectedEtag ?? null,\n input.text,\n input.contentIdentity,\n input.sourceDraftId ?? null,\n input.expectedSize ?? null,\n ]),\n ),\n ),\n load: async () => {\n const source =\n input.sourceDraftId === undefined\n ? null\n : await transaction(signal, (tx) =>\n requireDraft(tx, input.sourceDraftId!),\n );\n if (\n source !== null &&\n (source.path !== input.path ||\n source.expectedEtag !== (input.expectedEtag ?? null) ||\n source.size !== input.expectedSize ||\n !['open', 'sealed'].includes(source.status))\n )\n conflict('The source checkpoint changed.');\n return {\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n source,\n text: input.text,\n content: input.body(),\n };\n },\n }),\n );\n },\n reviseText: async (request) => {\n const input = {\n ...request,\n changes: request.changes.map((change) => ({ ...change })),\n };\n operation('read', input);\n const signal = operation('write', input);\n validateIdentity(input.idempotencyKey);\n validateIdentity(input.draftId);\n if (\n input.requestIdentity !== undefined &&\n input.requestIdentity.length > 4096\n )\n invalid('Invalid edit request identity.');\n storageInteger(input.expectedSize, 'expectedSize');\n if (input.changes.length < 1 || input.changes.length > limits.maxEdits)\n throw new StorageError(\n 'Text editing exceeds the configured limits.',\n { code: 'LIMIT_EXCEEDED' },\n );\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'revise-text',\n input.draftId,\n input.expectedSize,\n input.changes,\n ...(input.requestIdentity === undefined\n ? []\n : [input.requestIdentity]),\n ]),\n ),\n ),\n load: async () => {\n const source = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n requireMutation(source.expectedEtag);\n if (\n !source.text ||\n !['open', 'sealed'].includes(source.status) ||\n source.size !== input.expectedSize\n )\n conflict(\n 'The source must be an unfinished text draft at the expected size.',\n );\n return {\n source,\n path: source.path,\n expectedEtag: source.expectedEtag,\n content: editStorageTextStream(\n this.#stream(scope, source, limits, signal),\n input.changes,\n {\n maxEditBytes: limits.maxTextBytes,\n maxEdits: limits.maxEdits,\n signal,\n },\n ),\n };\n },\n }),\n );\n },\n list: async (input = {}) => {\n const signal = operation('read', input);\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n return transaction(signal, async (tx) => {\n const records = await tx.listDrafts(offset, limits.maxPageSize + 1);\n if (records.length > limits.maxPageSize + 1)\n provider('Persistence returned an oversized page.');\n return {\n items: records.slice(0, limits.maxPageSize).map(summary),\n nextOffset:\n records.length > limits.maxPageSize\n ? offset + limits.maxPageSize\n : null,\n };\n });\n },\n read: async (input) => {\n const signal = operation('read', input);\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (draft.status === 'cancelled') conflict('Draft is cancelled.');\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n if (offset > draft.size) invalid('Offset exceeds draft size.');\n const window = draft.text\n ? await readStorageTextWindow(\n async (range) =>\n this.#stream(\n scope,\n draft,\n limits,\n signal,\n range.start,\n range.end + 1,\n ),\n {\n size: draft.size,\n offset,\n maxBytes: limits.maxReadBytes,\n signal,\n },\n )\n : { content: null, offset, nextOffset: null };\n return { ...summary(draft), ...window };\n },\n searchText: async (input) => {\n const signal = operation('read', input);\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n !draft.text ||\n draft.status === 'cancelled' ||\n draft.size !== input.expectedSize\n )\n conflict('The source checkpoint changed.');\n const result = await searchStorageText(\n async (range) =>\n this.#stream(\n scope,\n draft,\n limits,\n signal,\n range.start,\n range.end + 1,\n ),\n {\n size: draft.size,\n query: input.query,\n offset: input.offset,\n maxScanBytes: 262144,\n maxMatches: 12,\n maxSnippetCharacters: 320,\n maxReadBytes: limits.maxReadBytes,\n signal,\n },\n );\n return { ...result, path: draft.path, etag: draft.id };\n },\n readText: async (request) => {\n const input = { ...request };\n const signal = operation('read', input);\n storageInteger(input.expectedSize, 'expectedSize');\n if (input.expectedSize > limits.maxTextBytes)\n throw new StorageError('Text read exceeds the buffered text limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n !draft.text ||\n draft.status === 'cancelled' ||\n draft.size !== input.expectedSize\n )\n conflict(\n 'The source must be an available text draft at the expected size.',\n );\n const bytes = await collectStorageBytes(\n this.#stream(scope, draft, limits, signal),\n limits.maxTextBytes,\n signal,\n );\n const current = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n current.status === 'cancelled' ||\n current.size !== input.expectedSize\n )\n conflict('The source draft changed while reading.');\n return {\n ...summary(current),\n content: new TextDecoder('utf-8', {\n fatal: true,\n ignoreBOM: true,\n }).decode(bytes),\n };\n },\n append: async (input) => {\n const signal = operation('write', input);\n storageInteger(input.offset, 'offset');\n if (\n !(input.bytes instanceof Uint8Array) ||\n input.bytes.byteLength < 1 ||\n input.bytes.byteLength > limits.maxChunkBytes\n )\n throw new StorageError('Append exceeds chunk limits.', {\n code: 'LIMIT_EXCEEDED',\n });\n // Snapshot before any await: callers may reuse or mutate their upload buffer.\n const bytes = input.bytes.slice();\n const sha256 = digest(bytes);\n const prior = await transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n requireMutation(draft.expectedEtag);\n return appendState(tx, draft, input.offset, bytes.byteLength, sha256);\n });\n if (prior.replay) return summary(prior.draft);\n if (prior.draft.text) {\n try {\n new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n invalid('Text chunks must contain complete UTF-8 characters.');\n }\n }\n const body = await content.write(scope, storageBytesStream(bytes), {\n maxBytes: limits.maxChunkBytes,\n signal,\n });\n if (body.size !== bytes.byteLength || body.sha256 !== sha256)\n provider('Staged chunk receipt does not match input.');\n return transaction(signal, async (tx) => {\n const current = await appendState(\n tx,\n await requireDraft(tx, input.draftId),\n input.offset,\n bytes.byteLength,\n sha256,\n );\n requireMutation(current.draft.expectedEtag);\n if (current.replay) return summary(current.draft);\n const size = current.draft.size + bytes.byteLength;\n storageInteger(size, 'size');\n await tx.putPart(input.draftId, {\n offset: input.offset,\n size: body.size,\n sha256,\n body,\n });\n const draft = { ...current.draft, size };\n await tx.saveDraft(draft);\n return summary(draft);\n });\n },\n parts: async (input) => {\n const signal = operation('read', input);\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n return transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n if (draft.status === 'cancelled') conflict('Draft is cancelled.');\n if (offset > draft.size) invalid('Offset exceeds draft size.');\n const parts = await tx.listParts(\n draft.id,\n offset,\n limits.maxPageSize,\n );\n if (parts.length > limits.maxPageSize)\n provider('Persistence returned an oversized page.');\n const items = parts\n .filter((part) => part.offset + part.size > offset)\n .map(({ offset, size, sha256 }) => ({ offset, size, sha256 }));\n const last = items.at(-1);\n const next =\n last === undefined ? draft.size : last.offset + last.size;\n if (offset < draft.size && (last === undefined || next <= offset))\n provider('Draft contains missing chunks.');\n return { items, nextOffset: next < draft.size ? next : null };\n });\n },\n cancel: async (input) => {\n const signal = operation('write', input);\n return transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n requireMutation(draft.expectedEtag);\n if (draft.status === 'committed')\n conflict('Committed draft cannot be cancelled.');\n const cancelled = { ...draft, status: 'cancelled' as const };\n await tx.saveDraft(cancelled);\n return summary(cancelled);\n });\n },\n commit: async (input) => {\n const signal = operation('commit', input);\n if (\n input.drafts.length < 1 ||\n input.drafts.length > limits.maxCommitFiles ||\n new Set(input.drafts.map((draft) => draft.draftId)).size !==\n input.drafts.length\n )\n invalid('Commit requires distinct draft IDs within the batch limit.');\n const requests = input.drafts.map((draft) => ({ ...draft }));\n for (const request of requests) {\n storageInteger(request.size, 'size');\n if (\n request.sha256 !== undefined &&\n !/^[0-9a-f]{64}$/u.test(request.sha256)\n )\n invalid('Invalid SHA-256.');\n }\n const sealed = await transaction(signal, async (tx) => {\n const drafts: StorageFileDraftRecord<Receipt>[] = [];\n for (const request of requests) {\n const draft = await requireDraft(tx, request.draftId);\n requireMutation(draft.expectedEtag);\n if (draft.size !== request.size || draft.status === 'cancelled')\n conflict('Draft is cancelled or has a different byte count.');\n if (\n draft.status === 'committed' &&\n (draft.result === null ||\n draft.body === null ||\n (request.sha256 !== undefined &&\n request.sha256 !== draft.body.sha256))\n )\n conflict('Committed draft does not match the requested digest.');\n drafts.push(draft);\n }\n if (new Set(drafts.map((draft) => draft.path)).size !== drafts.length)\n conflict('A path may appear only once per commit.');\n if (drafts.every((draft) => draft.status === 'committed'))\n return drafts;\n if (drafts.some((draft) => draft.status === 'committed'))\n conflict('Cannot mix committed and uncommitted drafts.');\n const result = drafts.map((draft) => ({\n ...draft,\n status: 'sealed' as const,\n }));\n for (const draft of result) await tx.saveDraft(draft);\n return result;\n });\n if (sealed.every((draft) => draft.status === 'committed'))\n return sealed.map((draft) => draft.result!);\n const prepared = new Map<string, StorageStagedBody>();\n for (const [index, draft] of sealed.entries()) {\n const body = await content.write(\n scope,\n this.#stream(scope, draft, limits, signal, 0, draft.size, 'commit'),\n { maxBytes: draft.size, signal },\n );\n if (\n body.size !== draft.size ||\n (requests[index]!.sha256 !== undefined &&\n requests[index]!.sha256 !== body.sha256)\n )\n conflict(\n 'Completed body does not match the expected byte count or SHA-256.',\n );\n prepared.set(draft.id, body);\n }\n return transaction(signal, async (tx) => {\n const drafts: StorageFileDraftRecord<Receipt>[] = [];\n for (const request of requests) {\n const draft = await requireDraft(tx, request.draftId);\n requireMutation(draft.expectedEtag);\n drafts.push(draft);\n }\n // A competing identical commit may have completed while bodies streamed.\n if (drafts.every((draft) => draft.status === 'committed')) {\n for (const [index, draft] of drafts.entries())\n if (\n draft.result === null ||\n draft.body?.sha256 !== prepared.get(draft.id)?.sha256 ||\n draft.size !== requests[index]!.size\n )\n conflict('Concurrent commit differs from the prepared body.');\n return drafts.map((draft) => draft.result!);\n }\n if (drafts.some((draft) => draft.status !== 'sealed'))\n conflict('Every draft must remain sealed until commit.');\n const ordered = [...drafts].sort((a, b) =>\n a.path < b.path ? -1 : a.path > b.path ? 1 : 0,\n );\n const results = await tx.commitHeads(\n ordered.map((draft) => ({ draft, body: prepared.get(draft.id)! })),\n );\n if (\n results.length !== ordered.length ||\n results.some((receipt) => receipt === null || receipt === undefined)\n )\n provider('Host must return one non-null receipt per head.');\n const byId = new Map<string, Receipt>();\n for (const [index, draft] of ordered.entries()) {\n const result = results[index]!;\n byId.set(draft.id, result);\n await tx.saveDraft({\n ...draft,\n status: 'committed',\n result,\n body: prepared.get(draft.id)!,\n });\n }\n return requests.map((request) => byId.get(request.draftId)!);\n });\n },\n };\n return Object.freeze(workflow);\n }\n\n #transaction<Result>(\n scope: Scope,\n signal: AbortSignal,\n permission: StorageFileWorkflowPermission,\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<Result>,\n ): Promise<Result> {\n signal.throwIfAborted();\n return this.#options.persistence.transaction(\n scope,\n { signal, permission },\n async (tx) => {\n signal.throwIfAborted();\n const result = await work(tx);\n signal.throwIfAborted();\n return result;\n },\n );\n }\n #stream(\n scope: Scope,\n draft: StorageFileDraftRecord<Receipt>,\n limits: StorageFileWorkflowLimits,\n parentSignal: AbortSignal,\n start = 0,\n end = draft.size,\n permission: StorageFileWorkflowPermission = 'read',\n ): ReadableStream<Uint8Array> {\n const controller = new AbortController();\n const signal = AbortSignal.any([parentSignal, controller.signal]);\n const content = this.#options.content;\n const transaction = <T>(\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<T>,\n ) => this.#transaction(scope, signal, permission, work);\n const iterator = (async function* () {\n let cursor = start;\n while (cursor < end) {\n const parts = await transaction(async (tx) => {\n const current = await requireDraft(tx, draft.id);\n if (current.status === 'cancelled') conflict('Draft was cancelled.');\n return tx.listParts(draft.id, cursor, limits.maxPageSize);\n });\n if (parts.length > limits.maxPageSize)\n provider('Persistence returned an oversized page.');\n let advanced = false;\n for (const part of parts) {\n if (cursor >= end) break;\n storageInteger(part.offset, 'part.offset');\n storageInteger(part.size, 'part.size', 1);\n if (\n part.size > limits.maxChunkBytes ||\n part.size !== part.body.size ||\n part.sha256 !== part.body.sha256\n )\n provider('Invalid chunk receipt.');\n if (part.offset + part.size <= cursor) continue;\n if (part.offset > cursor) provider('Draft contains a missing chunk.');\n const bytes = await collectStorageBytes(\n await content.read(scope, part.body, { signal }),\n part.size,\n signal,\n );\n if (bytes.byteLength !== part.size || digest(bytes) !== part.sha256)\n conflict('Draft chunk failed integrity verification.');\n const next = Math.min(end, part.offset + part.size);\n yield bytes.subarray(cursor - part.offset, next - part.offset);\n cursor = next;\n advanced = true;\n }\n if (!advanced) provider('Draft is incomplete.');\n }\n })();\n return new ReadableStream(\n {\n async pull(output) {\n try {\n const next = await iterator.next();\n if (next.done) output.close();\n else output.enqueue(next.value);\n } catch (error) {\n output.error(error);\n await iterator.return(undefined);\n }\n },\n async cancel(reason) {\n controller.abort(reason);\n await iterator.return(undefined);\n },\n },\n { highWaterMark: 0 },\n );\n }\n}\n\nasync function requireDraft<R>(\n tx: StorageFileWorkflowTransaction<R>,\n id: string,\n): Promise<StorageFileDraftRecord<R>> {\n validateIdentity(id);\n const draft = await tx.getDraft(id);\n if (draft === null)\n throw new StorageError('Draft is unavailable.', { code: 'NOT_FOUND' });\n return draft;\n}\nasync function appendState<R>(\n tx: StorageFileWorkflowTransaction<R>,\n draft: StorageFileDraftRecord<R>,\n offset: number,\n size: number,\n sha256: string,\n) {\n if (draft.status !== 'open') conflict('Draft is closed for writes.');\n if (offset < draft.size) {\n const previous = (await tx.listParts(draft.id, offset, 1))[0];\n if (\n previous?.offset === offset &&\n previous.size === size &&\n previous.sha256 === sha256\n )\n return { draft, replay: true };\n conflict('Different bytes were already appended at this offset.');\n }\n if (offset !== draft.size)\n conflict('Draft offset changed. Read the current size before appending.');\n return { draft, replay: false };\n}\nfunction summary<R>(draft: StorageFileDraftRecord<R>): StorageFileDraft<R> {\n const {\n id,\n path,\n expectedEtag,\n sourceDraftId,\n text,\n status,\n size,\n result,\n createdAt,\n } = draft;\n return Object.freeze({\n id,\n path,\n expectedEtag,\n sourceDraftId,\n text,\n status,\n size,\n result,\n createdAt,\n });\n}\nfunction validateIdentity(value: string) {\n if (typeof value !== 'string' || value.length < 1 || value.length > 256)\n invalid('Invalid workflow identity.');\n}\nfunction digest(bytes: Uint8Array) {\n return createHash('sha256').update(bytes).digest('hex');\n}\nfunction invalid(message: string): never {\n throw new StorageError(message, { code: 'INVALID_ARGUMENT' });\n}\nfunction conflict(message: string): never {\n throw new StorageError(message, { code: 'CONFLICT' });\n}\nfunction provider(message: string): never {\n throw new StorageError(message, { code: 'PROVIDER' });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"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","sourcesContent":["import { searchStorageText } from '../core/storage-text.js';\nimport { editStorageTextStream } from '../core/storage-text-stream-edit.js';\nimport { stageStorageTextDraft } from './storage-text-draft.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { StorageError } from '../storage.error.js';\nimport { assertWorkspacePath } from './storage-workspace.path.js';\nimport type { StorageStagedBody } from '../core/storage-staged-content.js';\nimport {\n collectStorageBytes,\n readStorageTextWindow,\n storageBytesStream,\n storageInteger,\n} from '../core/storage-streams.js';\nimport {\n DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS,\n type MountStorageFileWorkflowOptions,\n type StorageFileDraft,\n type StorageFileDraftRecord,\n type StorageFileWorkflowCapability,\n type StorageFileWorkflowLimits,\n type StorageFileWorkflowOperation,\n type StorageFileWorkflowOptions,\n type StorageFileWorkflowPermission,\n type StorageFileWorkflowMutation,\n type StorageFileWorkflowTransaction,\n} from './storage-file-workflow.types.js';\n\nexport class StorageFileWorkflow<Scope, Receipt> {\n readonly #options: StorageFileWorkflowOptions<Scope, Receipt>;\n constructor(options: StorageFileWorkflowOptions<Scope, Receipt>) {\n this.#options = options;\n }\n\n mount(\n scope: Scope,\n options: MountStorageFileWorkflowOptions = {},\n ): StorageFileWorkflowCapability<Receipt> {\n const limits = Object.freeze({\n ...DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS,\n ...options.limits,\n });\n for (const [name, value] of Object.entries(limits))\n storageInteger(value, name, name === 'maxReadBytes' ? 4 : 1);\n const permissions = new Set(\n options.permissions ?? ['read', 'write', 'commit'],\n );\n const mutations = new Set<StorageFileWorkflowMutation>(\n options.mutations ?? ['create', 'replace'],\n );\n const boundSignal = options.signal;\n const requireMutation = (expectedEtag: string | null | undefined) => {\n if (!mutations.has(expectedEtag == null ? 'create' : 'replace'))\n throw new StorageError(\n 'Draft mutation is not permitted by this capability.',\n { code: 'UNAUTHORIZED' },\n );\n };\n const operationPermissions = new WeakMap<\n AbortSignal,\n StorageFileWorkflowPermission\n >();\n const allows = (permission: StorageFileWorkflowPermission) =>\n permissions.has(permission) &&\n (permission === 'read' || mutations.size > 0);\n const operation = (\n permission: StorageFileWorkflowPermission,\n input: StorageFileWorkflowOperation,\n ) => {\n if (!allows(permission))\n throw new StorageError('File workflow operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n const signals = [boundSignal, input.signal].filter(\n (signal): signal is AbortSignal => signal !== undefined,\n );\n const signal = AbortSignal.any(signals);\n signal.throwIfAborted();\n operationPermissions.set(signal, permission);\n return signal;\n };\n const transaction = <T>(\n signal: AbortSignal,\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<T>,\n ) =>\n this.#transaction(scope, signal, operationPermissions.get(signal)!, work);\n const content = this.#options.content;\n const workflow: StorageFileWorkflowCapability<Receipt> = {\n kind: 'storage-file-workflow',\n version: 1,\n limits,\n allows,\n restrict: (restriction) => {\n const narrowed = { ...limits };\n for (const name of Object.keys(\n limits,\n ) as (keyof StorageFileWorkflowLimits)[]) {\n const requested = restriction.limits?.[name] ?? limits[name];\n storageInteger(requested, name, name === 'maxReadBytes' ? 4 : 1);\n narrowed[name] = Math.min(limits[name], requested);\n }\n return this.mount(scope, {\n limits: narrowed,\n permissions: [...(restriction.permissions ?? permissions)].filter(\n (permission) => permissions.has(permission),\n ),\n mutations: [...(restriction.mutations ?? mutations)].filter(\n (mutation) => mutations.has(mutation),\n ),\n signal: AbortSignal.any(\n [boundSignal, restriction.signal].filter(\n (signal): signal is AbortSignal => signal !== undefined,\n ),\n ),\n });\n },\n lookup: async (input) => {\n const signal = operation('read', input);\n validateIdentity(input.idempotencyKey);\n return transaction(signal, async (tx) => {\n const draft = await tx.findDraftByKey(input.idempotencyKey);\n return draft === null ? null : summary(draft);\n });\n },\n begin: async (input) => {\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n validateIdentity(input.idempotencyKey);\n if (\n typeof input.text !== 'boolean' ||\n (input.expectedEtag !== undefined &&\n (typeof input.expectedEtag !== 'string' ||\n input.expectedEtag.length === 0 ||\n input.expectedEtag.length > 1024))\n )\n invalid('Invalid draft input.');\n const fingerprint = digest(\n new TextEncoder().encode(\n JSON.stringify([\n input.path,\n input.expectedEtag ?? null,\n input.text,\n ]),\n ),\n );\n return transaction(signal, async (tx) => {\n const prior = await tx.findDraftByKey(input.idempotencyKey);\n if (prior !== null) {\n if (prior.requestFingerprint !== fingerprint)\n conflict('Draft key was already used for different input.');\n return summary(prior);\n }\n const record: StorageFileDraftRecord<Receipt> = {\n id: randomUUID(),\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n sourceDraftId: null,\n text: input.text,\n status: 'open',\n size: 0,\n result: null,\n createdAt: new Date().toISOString(),\n idempotencyKey: input.idempotencyKey,\n requestFingerprint: fingerprint,\n body: null,\n };\n await tx.saveDraft(record);\n return summary(record);\n });\n },\n stageText: async (request) => {\n const input = { ...request };\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n validateIdentity(input.idempotencyKey);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n if (\n input.expectedEtag !== undefined &&\n (input.expectedEtag.length < 1 || input.expectedEtag.length > 1024)\n )\n invalid('Invalid ETag.');\n if (\n new TextEncoder().encode(input.content).byteLength >\n limits.maxTextBytes\n )\n throw new StorageError(\n 'Text checkpoint exceeds the buffered text limit.',\n { code: 'LIMIT_EXCEEDED' },\n );\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'stage-text',\n input.path,\n input.expectedEtag ?? null,\n input.content,\n ]),\n ),\n ),\n load: async () => ({\n content: input.content,\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n source: null,\n }),\n }),\n );\n },\n stageStream: async (request) => {\n const input = { ...request };\n if (input.sourceDraftId !== undefined) operation('read', input);\n const signal = operation('write', input);\n requireMutation(input.expectedEtag);\n validateIdentity(input.idempotencyKey);\n assertWorkspacePath(input.path, limits.maxPathBytes, {\n allowRoot: false,\n });\n if (\n typeof input.text !== 'boolean' ||\n typeof input.contentIdentity !== 'string' ||\n !input.contentIdentity.length ||\n input.contentIdentity.length > 1024\n )\n invalid('Invalid streaming draft identity.');\n if (\n input.expectedEtag !== undefined &&\n (!input.expectedEtag.length || input.expectedEtag.length > 1024)\n )\n invalid('Invalid ETag.');\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'stage-stream',\n input.path,\n input.expectedEtag ?? null,\n input.text,\n input.contentIdentity,\n input.sourceDraftId ?? null,\n input.expectedSize ?? null,\n ]),\n ),\n ),\n load: async () => {\n const source =\n input.sourceDraftId === undefined\n ? null\n : await transaction(signal, (tx) =>\n requireDraft(tx, input.sourceDraftId!),\n );\n if (\n source !== null &&\n (source.path !== input.path ||\n source.expectedEtag !== (input.expectedEtag ?? null) ||\n source.size !== input.expectedSize ||\n !['open', 'sealed'].includes(source.status))\n )\n conflict('The source checkpoint changed.');\n return {\n path: input.path,\n expectedEtag: input.expectedEtag ?? null,\n source,\n text: input.text,\n content: await input.body(),\n };\n },\n }),\n );\n },\n reviseText: async (request) => {\n const input = {\n ...request,\n changes: request.changes.map((change) => ({ ...change })),\n };\n operation('read', input);\n const signal = operation('write', input);\n validateIdentity(input.idempotencyKey);\n validateIdentity(input.draftId);\n if (\n input.requestIdentity !== undefined &&\n input.requestIdentity.length > 4096\n )\n invalid('Invalid edit request identity.');\n storageInteger(input.expectedSize, 'expectedSize');\n if (input.changes.length < 1 || input.changes.length > limits.maxEdits)\n throw new StorageError(\n 'Text editing exceeds the configured limits.',\n { code: 'LIMIT_EXCEEDED' },\n );\n return summary(\n await stageStorageTextDraft({\n scope,\n signal,\n limits,\n content,\n requireMutation,\n transaction: (work) => transaction(signal, work),\n idempotencyKey: input.idempotencyKey,\n fingerprint: digest(\n new TextEncoder().encode(\n JSON.stringify([\n 'revise-text',\n input.draftId,\n input.expectedSize,\n input.changes,\n ...(input.requestIdentity === undefined\n ? []\n : [input.requestIdentity]),\n ]),\n ),\n ),\n load: async () => {\n const source = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n requireMutation(source.expectedEtag);\n if (\n !source.text ||\n !['open', 'sealed'].includes(source.status) ||\n source.size !== input.expectedSize\n )\n conflict(\n 'The source must be an unfinished text draft at the expected size.',\n );\n return {\n source,\n path: source.path,\n expectedEtag: source.expectedEtag,\n content: editStorageTextStream(\n this.#stream(scope, source, limits, signal),\n input.changes,\n {\n maxEditBytes: limits.maxTextBytes,\n maxEdits: limits.maxEdits,\n signal,\n },\n ),\n };\n },\n }),\n );\n },\n list: async (input = {}) => {\n const signal = operation('read', input);\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n return transaction(signal, async (tx) => {\n const records = await tx.listDrafts(offset, limits.maxPageSize + 1);\n if (records.length > limits.maxPageSize + 1)\n provider('Persistence returned an oversized page.');\n return {\n items: records.slice(0, limits.maxPageSize).map(summary),\n nextOffset:\n records.length > limits.maxPageSize\n ? offset + limits.maxPageSize\n : null,\n };\n });\n },\n readStream: async (input) => {\n const signal = operation('read', input);\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (draft.status === 'cancelled' || draft.size !== input.expectedSize)\n conflict('The source checkpoint changed.');\n const start = input.start ?? 0;\n const end = input.end ?? draft.size;\n storageInteger(start, 'start');\n storageInteger(end, 'end');\n if (start > end || end > draft.size) invalid('Invalid stream range.');\n return {\n ...summary(draft),\n body: this.#stream(scope, draft, limits, signal, start, end),\n };\n },\n read: async (input) => {\n const signal = operation('read', input);\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (draft.status === 'cancelled') conflict('Draft is cancelled.');\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n if (offset > draft.size) invalid('Offset exceeds draft size.');\n const window = draft.text\n ? await readStorageTextWindow(\n async (range) =>\n this.#stream(\n scope,\n draft,\n limits,\n signal,\n range.start,\n range.end + 1,\n ),\n {\n size: draft.size,\n offset,\n maxBytes: limits.maxReadBytes,\n signal,\n },\n )\n : { content: null, offset, nextOffset: null };\n return { ...summary(draft), ...window };\n },\n searchText: async (input) => {\n const signal = operation('read', input);\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n !draft.text ||\n draft.status === 'cancelled' ||\n draft.size !== input.expectedSize\n )\n conflict('The source checkpoint changed.');\n const result = await searchStorageText(\n async (range) =>\n this.#stream(\n scope,\n draft,\n limits,\n signal,\n range.start,\n range.end + 1,\n ),\n {\n size: draft.size,\n query: input.query,\n offset: input.offset,\n maxScanBytes: 262144,\n maxMatches: 12,\n maxSnippetCharacters: 320,\n maxReadBytes: limits.maxReadBytes,\n signal,\n },\n );\n return { ...result, path: draft.path, etag: draft.id };\n },\n readText: async (request) => {\n const input = { ...request };\n const signal = operation('read', input);\n storageInteger(input.expectedSize, 'expectedSize');\n if (input.expectedSize > limits.maxTextBytes)\n throw new StorageError('Text read exceeds the buffered text limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n const draft = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n !draft.text ||\n draft.status === 'cancelled' ||\n draft.size !== input.expectedSize\n )\n conflict(\n 'The source must be an available text draft at the expected size.',\n );\n const bytes = await collectStorageBytes(\n this.#stream(scope, draft, limits, signal),\n limits.maxTextBytes,\n signal,\n );\n const current = await transaction(signal, (tx) =>\n requireDraft(tx, input.draftId),\n );\n if (\n current.status === 'cancelled' ||\n current.size !== input.expectedSize\n )\n conflict('The source draft changed while reading.');\n return {\n ...summary(current),\n content: new TextDecoder('utf-8', {\n fatal: true,\n ignoreBOM: true,\n }).decode(bytes),\n };\n },\n append: async (input) => {\n const signal = operation('write', input);\n storageInteger(input.offset, 'offset');\n if (\n !(input.bytes instanceof Uint8Array) ||\n input.bytes.byteLength < 1 ||\n input.bytes.byteLength > limits.maxChunkBytes\n )\n throw new StorageError('Append exceeds chunk limits.', {\n code: 'LIMIT_EXCEEDED',\n });\n // Snapshot before any await: callers may reuse or mutate their upload buffer.\n const bytes = input.bytes.slice();\n const sha256 = digest(bytes);\n const prior = await transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n requireMutation(draft.expectedEtag);\n return appendState(tx, draft, input.offset, bytes.byteLength, sha256);\n });\n if (prior.replay) return summary(prior.draft);\n if (prior.draft.text) {\n try {\n new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n invalid('Text chunks must contain complete UTF-8 characters.');\n }\n }\n const body = await content.write(scope, storageBytesStream(bytes), {\n maxBytes: limits.maxChunkBytes,\n signal,\n });\n if (body.size !== bytes.byteLength || body.sha256 !== sha256)\n provider('Staged chunk receipt does not match input.');\n return transaction(signal, async (tx) => {\n const current = await appendState(\n tx,\n await requireDraft(tx, input.draftId),\n input.offset,\n bytes.byteLength,\n sha256,\n );\n requireMutation(current.draft.expectedEtag);\n if (current.replay) return summary(current.draft);\n const size = current.draft.size + bytes.byteLength;\n storageInteger(size, 'size');\n await tx.putPart(input.draftId, {\n offset: input.offset,\n size: body.size,\n sha256,\n body,\n });\n const draft = { ...current.draft, size };\n await tx.saveDraft(draft);\n return summary(draft);\n });\n },\n parts: async (input) => {\n const signal = operation('read', input);\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset');\n return transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n if (draft.status === 'cancelled') conflict('Draft is cancelled.');\n if (offset > draft.size) invalid('Offset exceeds draft size.');\n const parts = await tx.listParts(\n draft.id,\n offset,\n limits.maxPageSize,\n );\n if (parts.length > limits.maxPageSize)\n provider('Persistence returned an oversized page.');\n const items = parts\n .filter((part) => part.offset + part.size > offset)\n .map(({ offset, size, sha256 }) => ({ offset, size, sha256 }));\n const last = items.at(-1);\n const next =\n last === undefined ? draft.size : last.offset + last.size;\n if (offset < draft.size && (last === undefined || next <= offset))\n provider('Draft contains missing chunks.');\n return { items, nextOffset: next < draft.size ? next : null };\n });\n },\n cancel: async (input) => {\n const signal = operation('write', input);\n return transaction(signal, async (tx) => {\n const draft = await requireDraft(tx, input.draftId);\n requireMutation(draft.expectedEtag);\n if (draft.status === 'committed')\n conflict('Committed draft cannot be cancelled.');\n const cancelled = { ...draft, status: 'cancelled' as const };\n await tx.saveDraft(cancelled);\n return summary(cancelled);\n });\n },\n commit: async (input) => {\n const signal = operation('commit', input);\n if (\n input.drafts.length < 1 ||\n input.drafts.length > limits.maxCommitFiles ||\n new Set(input.drafts.map((draft) => draft.draftId)).size !==\n input.drafts.length\n )\n invalid('Commit requires distinct draft IDs within the batch limit.');\n const requests = input.drafts.map((draft) => ({ ...draft }));\n for (const request of requests) {\n storageInteger(request.size, 'size');\n if (\n request.sha256 !== undefined &&\n !/^[0-9a-f]{64}$/u.test(request.sha256)\n )\n invalid('Invalid SHA-256.');\n }\n const sealed = await transaction(signal, async (tx) => {\n const drafts: StorageFileDraftRecord<Receipt>[] = [];\n for (const request of requests) {\n const draft = await requireDraft(tx, request.draftId);\n requireMutation(draft.expectedEtag);\n if (draft.size !== request.size || draft.status === 'cancelled')\n conflict('Draft is cancelled or has a different byte count.');\n if (\n draft.status === 'committed' &&\n (draft.result === null ||\n draft.body === null ||\n (request.sha256 !== undefined &&\n request.sha256 !== draft.body.sha256))\n )\n conflict('Committed draft does not match the requested digest.');\n drafts.push(draft);\n }\n if (new Set(drafts.map((draft) => draft.path)).size !== drafts.length)\n conflict('A path may appear only once per commit.');\n if (drafts.every((draft) => draft.status === 'committed'))\n return drafts;\n if (drafts.some((draft) => draft.status === 'committed'))\n conflict('Cannot mix committed and uncommitted drafts.');\n const result = drafts.map((draft) => ({\n ...draft,\n status: 'sealed' as const,\n }));\n for (const draft of result) await tx.saveDraft(draft);\n return result;\n });\n if (sealed.every((draft) => draft.status === 'committed'))\n return sealed.map((draft) => draft.result!);\n const prepared = new Map<string, StorageStagedBody>();\n for (const [index, draft] of sealed.entries()) {\n const body = await content.write(\n scope,\n this.#stream(scope, draft, limits, signal, 0, draft.size, 'commit'),\n { maxBytes: draft.size, signal },\n );\n if (\n body.size !== draft.size ||\n (requests[index]!.sha256 !== undefined &&\n requests[index]!.sha256 !== body.sha256)\n )\n conflict(\n 'Completed body does not match the expected byte count or SHA-256.',\n );\n prepared.set(draft.id, body);\n }\n return transaction(signal, async (tx) => {\n const drafts: StorageFileDraftRecord<Receipt>[] = [];\n for (const request of requests) {\n const draft = await requireDraft(tx, request.draftId);\n requireMutation(draft.expectedEtag);\n drafts.push(draft);\n }\n // A competing identical commit may have completed while bodies streamed.\n if (drafts.every((draft) => draft.status === 'committed')) {\n for (const [index, draft] of drafts.entries())\n if (\n draft.result === null ||\n draft.body?.sha256 !== prepared.get(draft.id)?.sha256 ||\n draft.size !== requests[index]!.size\n )\n conflict('Concurrent commit differs from the prepared body.');\n return drafts.map((draft) => draft.result!);\n }\n if (drafts.some((draft) => draft.status !== 'sealed'))\n conflict('Every draft must remain sealed until commit.');\n const ordered = [...drafts].sort((a, b) =>\n a.path < b.path ? -1 : a.path > b.path ? 1 : 0,\n );\n const results = await tx.commitHeads(\n ordered.map((draft) => ({ draft, body: prepared.get(draft.id)! })),\n );\n if (\n results.length !== ordered.length ||\n results.some((receipt) => receipt === null || receipt === undefined)\n )\n provider('Host must return one non-null receipt per head.');\n const byId = new Map<string, Receipt>();\n for (const [index, draft] of ordered.entries()) {\n const result = results[index]!;\n byId.set(draft.id, result);\n await tx.saveDraft({\n ...draft,\n status: 'committed',\n result,\n body: prepared.get(draft.id)!,\n });\n }\n return requests.map((request) => byId.get(request.draftId)!);\n });\n },\n };\n return Object.freeze(workflow);\n }\n\n #transaction<Result>(\n scope: Scope,\n signal: AbortSignal,\n permission: StorageFileWorkflowPermission,\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<Result>,\n ): Promise<Result> {\n signal.throwIfAborted();\n return this.#options.persistence.transaction(\n scope,\n { signal, permission },\n async (tx) => {\n signal.throwIfAborted();\n const result = await work(tx);\n signal.throwIfAborted();\n return result;\n },\n );\n }\n #stream(\n scope: Scope,\n draft: StorageFileDraftRecord<Receipt>,\n limits: StorageFileWorkflowLimits,\n parentSignal: AbortSignal,\n start = 0,\n end = draft.size,\n permission: StorageFileWorkflowPermission = 'read',\n ): ReadableStream<Uint8Array> {\n const controller = new AbortController();\n const signal = AbortSignal.any([parentSignal, controller.signal]);\n const content = this.#options.content;\n const transaction = <T>(\n work: (tx: StorageFileWorkflowTransaction<Receipt>) => Promise<T>,\n ) => this.#transaction(scope, signal, permission, work);\n const iterator = (async function* () {\n let cursor = start;\n while (cursor < end) {\n const parts = await transaction(async (tx) => {\n const current = await requireDraft(tx, draft.id);\n if (current.status === 'cancelled') conflict('Draft was cancelled.');\n return tx.listParts(draft.id, cursor, limits.maxPageSize);\n });\n if (parts.length > limits.maxPageSize)\n provider('Persistence returned an oversized page.');\n let advanced = false;\n for (const part of parts) {\n if (cursor >= end) break;\n storageInteger(part.offset, 'part.offset');\n storageInteger(part.size, 'part.size', 1);\n if (\n part.size > limits.maxChunkBytes ||\n part.size !== part.body.size ||\n part.sha256 !== part.body.sha256\n )\n provider('Invalid chunk receipt.');\n if (part.offset + part.size <= cursor) continue;\n if (part.offset > cursor) provider('Draft contains a missing chunk.');\n const bytes = await collectStorageBytes(\n await content.read(scope, part.body, { signal }),\n part.size,\n signal,\n );\n if (bytes.byteLength !== part.size || digest(bytes) !== part.sha256)\n conflict('Draft chunk failed integrity verification.');\n const next = Math.min(end, part.offset + part.size);\n yield bytes.subarray(cursor - part.offset, next - part.offset);\n cursor = next;\n advanced = true;\n }\n if (!advanced) provider('Draft is incomplete.');\n }\n })();\n return new ReadableStream(\n {\n async pull(output) {\n try {\n const next = await iterator.next();\n if (next.done) output.close();\n else output.enqueue(next.value);\n } catch (error) {\n output.error(error);\n await iterator.return(undefined);\n }\n },\n async cancel(reason) {\n controller.abort(reason);\n await iterator.return(undefined);\n },\n },\n { highWaterMark: 0 },\n );\n }\n}\n\nasync function requireDraft<R>(\n tx: StorageFileWorkflowTransaction<R>,\n id: string,\n): Promise<StorageFileDraftRecord<R>> {\n validateIdentity(id);\n const draft = await tx.getDraft(id);\n if (draft === null)\n throw new StorageError('Draft is unavailable.', { code: 'NOT_FOUND' });\n return draft;\n}\nasync function appendState<R>(\n tx: StorageFileWorkflowTransaction<R>,\n draft: StorageFileDraftRecord<R>,\n offset: number,\n size: number,\n sha256: string,\n) {\n if (draft.status !== 'open') conflict('Draft is closed for writes.');\n if (offset < draft.size) {\n const previous = (await tx.listParts(draft.id, offset, 1))[0];\n if (\n previous?.offset === offset &&\n previous.size === size &&\n previous.sha256 === sha256\n )\n return { draft, replay: true };\n conflict('Different bytes were already appended at this offset.');\n }\n if (offset !== draft.size)\n conflict('Draft offset changed. Read the current size before appending.');\n return { draft, replay: false };\n}\nfunction summary<R>(draft: StorageFileDraftRecord<R>): StorageFileDraft<R> {\n const {\n id,\n path,\n expectedEtag,\n sourceDraftId,\n text,\n status,\n size,\n result,\n createdAt,\n } = draft;\n return Object.freeze({\n id,\n path,\n expectedEtag,\n sourceDraftId,\n text,\n status,\n size,\n result,\n createdAt,\n });\n}\nfunction validateIdentity(value: string) {\n if (typeof value !== 'string' || value.length < 1 || value.length > 256)\n invalid('Invalid workflow identity.');\n}\nfunction digest(bytes: Uint8Array) {\n return createHash('sha256').update(bytes).digest('hex');\n}\nfunction invalid(message: string): never {\n throw new StorageError(message, { code: 'INVALID_ARGUMENT' });\n}\nfunction conflict(message: string): never {\n throw new StorageError(message, { code: 'CONFLICT' });\n}\nfunction provider(message: string): never {\n throw new StorageError(message, { code: 'PROVIDER' });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.protection.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.protection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,6BAA6B,EAE7B,6BAA6B,EAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAEpF,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE;QAC9B,QAAQ,CAAC,UAAU,EAAE,6BAA6B,CAAC;QACnD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;KAC9B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AACD,MAAM,WAAW,4BAA4B,CAC3C,OAAO,GAAG,OAAO,CACjB,SAAQ,gBAAgB;IACxB,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;CAC1D;AACD,MAAM,WAAW,0CAA0C,CACzD,OAAO,CACP,SAAQ,6BAA6B;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;CAC1D;AAED,8EAA8E;AAC9E,wBAAsB,mCAAmC,CAAC,MAAM,EAC9D,UAAU,EAAE,6BAA6B,GAAG;IAC1C,QAAQ,CAAC,UAAU,EAAE,6BAA6B,CAAC;IACnD,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACpD,EACD,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,GAC7C,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EACzD,OAAO,EAAE,0CAA0C,CAAC,OAAO,CAAC,GAC3D,4BAA4B,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.protection.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.protection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,6BAA6B,EAE7B,6BAA6B,EAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAEpF,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE;QAC9B,QAAQ,CAAC,UAAU,EAAE,6BAA6B,CAAC;QACnD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;KAC9B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AACD,MAAM,WAAW,4BAA4B,CAC3C,OAAO,GAAG,OAAO,CACjB,SAAQ,gBAAgB;IACxB,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;CAC1D;AACD,MAAM,WAAW,0CAA0C,CACzD,OAAO,CACP,SAAQ,6BAA6B;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;CAC1D;AAED,8EAA8E;AAC9E,wBAAsB,mCAAmC,CAAC,MAAM,EAC9D,UAAU,EAAE,6BAA6B,GAAG;IAC1C,QAAQ,CAAC,UAAU,EAAE,6BAA6B,CAAC;IACnD,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACpD,EACD,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,GAC7C,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EACzD,OAAO,EAAE,0CAA0C,CAAC,OAAO,CAAC,GAC3D,4BAA4B,CAAC,OAAO,CAAC,CAqTvC;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,OAAO,GAAG,OAAO,EACtD,SAAS,EAAE,gBAAgB,GAC1B,6BAA6B,CAAC,OAAO,CAAC,CA0BxC;AACD,wBAAgB,qBAAqB,CAAC,OAAO,GAAG,OAAO,EACrD,SAAS,EAAE,gBAAgB,GAC1B,4BAA4B,CAAC,OAAO,CAAC,CAsBvC"}
|
|
@@ -80,6 +80,7 @@ export function protectStorageFileWorkflowWorkspace(options) {
|
|
|
80
80
|
list: (input = {}) => workflowRead(input, (signal) => workflows.list({ ...input, signal })),
|
|
81
81
|
read: (input) => workflowRead(input, (signal) => workflows.read({ ...input, signal })),
|
|
82
82
|
searchText: (input) => workflowRead(input, (signal) => workflows.searchText({ ...input, signal })),
|
|
83
|
+
readStream: (input) => workflowRead(input, (signal) => workflows.readStream({ ...input, signal })),
|
|
83
84
|
readText: (input) => workflowRead(input, (signal) => workflows.readText({ ...input, signal })),
|
|
84
85
|
parts: (input) => workflowRead(input, (signal) => workflows.parts({ ...input, signal })),
|
|
85
86
|
append: (input) => {
|
|
@@ -154,6 +155,40 @@ export function protectStorageFileWorkflowWorkspace(options) {
|
|
|
154
155
|
checkPage(new TextEncoder().encode(page.content ?? '').byteLength, limits.maxReadBytes);
|
|
155
156
|
return page;
|
|
156
157
|
}),
|
|
158
|
+
readStream: (input) => catalogRun('read', input, async (signal) => {
|
|
159
|
+
const result = await catalog.readStream({ ...input, signal });
|
|
160
|
+
const reader = result.body.getReader();
|
|
161
|
+
return {
|
|
162
|
+
...result,
|
|
163
|
+
body: new ReadableStream({
|
|
164
|
+
async pull(controller) {
|
|
165
|
+
try {
|
|
166
|
+
const part = await catalogRun('read', { signal }, async (current) => {
|
|
167
|
+
current.throwIfAborted();
|
|
168
|
+
const part = await reader.read();
|
|
169
|
+
current.throwIfAborted();
|
|
170
|
+
return part;
|
|
171
|
+
});
|
|
172
|
+
if (part.done) {
|
|
173
|
+
reader.releaseLock();
|
|
174
|
+
controller.close();
|
|
175
|
+
}
|
|
176
|
+
else
|
|
177
|
+
controller.enqueue(part.value);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
await reader.cancel(error).catch(() => { });
|
|
181
|
+
reader.releaseLock();
|
|
182
|
+
controller.error(error);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
async cancel(reason) {
|
|
186
|
+
await reader.cancel(reason);
|
|
187
|
+
reader.releaseLock();
|
|
188
|
+
},
|
|
189
|
+
}, { highWaterMark: 0 }),
|
|
190
|
+
};
|
|
191
|
+
}),
|
|
157
192
|
searchContent: (input) => {
|
|
158
193
|
requireBase('search');
|
|
159
194
|
return catalogRun('read', input, async (signal) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.protection.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.protection.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageError } from '../storage.error.js';\nimport { storageInteger } from '../core/storage-streams.js';\nimport type { StorageOperationOptions } from '../storage.types.js';\nimport type {\n StorageWorkspace,\n StorageWorkspacePermission,\n} from './storage-workspace.types.js';\nimport type {\n StorageFileWorkflowCapability,\n StorageFileWorkflowOperation,\n StorageFileWorkflowPermission,\n} from './storage-file-workflow.types.js';\nimport type { StorageFileCatalogCapability } from './storage-file-catalog.types.js';\n\nexport interface StorageFileWorkflowProtection {\n readonly signal: AbortSignal;\n /** Fresh host authority check. Transaction ports must independently recheck. */\n readonly authorize: (operation: {\n readonly permission: StorageFileWorkflowPermission;\n readonly signal: AbortSignal;\n }) => void | Promise<void>;\n}\nexport interface StorageFileWorkflowWorkspace<\n Receipt = unknown,\n> extends StorageWorkspace {\n readonly workflows: StorageFileWorkflowCapability<Receipt>;\n readonly catalog?: StorageFileCatalogCapability<Receipt>;\n}\nexport interface ProtectStorageFileWorkflowWorkspaceOptions<\n Receipt,\n> extends StorageFileWorkflowProtection {\n /** Host catalog delegate, already restricted to the same trusted scope. */\n readonly workspace: StorageWorkspace;\n readonly workflows: StorageFileWorkflowCapability<Receipt>;\n readonly catalog?: StorageFileCatalogCapability<Receipt>;\n}\n\n/** For host-owned feature closures captured during capability acquisition. */\nexport async function protectStorageFileWorkflowOperation<Result>(\n protection: StorageFileWorkflowProtection & {\n readonly permission: StorageFileWorkflowPermission;\n readonly operationSignal?: AbortSignal | undefined;\n },\n work: (signal: AbortSignal) => Promise<Result>,\n): Promise<Result> {\n const signal =\n protection.operationSignal === undefined\n ? protection.signal\n : AbortSignal.any([protection.signal, protection.operationSignal]);\n signal.throwIfAborted();\n await protection.authorize({ permission: protection.permission, signal });\n signal.throwIfAborted();\n // A completed mutation must return its receipt even if abort races its response.\n return work(signal);\n}\n\nexport function protectStorageFileWorkflowWorkspace<Receipt>(\n options: ProtectStorageFileWorkflowWorkspaceOptions<Receipt>,\n): StorageFileWorkflowWorkspace<Receipt> {\n const { workspace, catalog } = options;\n const workflows = options.workflows.restrict({\n mutations: [\n ...(workspace.allows('create') ? ['create' as const] : []),\n ...(workspace.allows('replace') ? ['replace' as const] : []),\n ],\n signal: options.signal,\n });\n const run = <T>(\n permission: StorageFileWorkflowPermission,\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) =>\n protectStorageFileWorkflowOperation(\n { ...options, permission, operationSignal: input.signal },\n work,\n );\n const requireBase = (permission: StorageWorkspacePermission) => {\n if (!workspace.allows(permission)) denied();\n };\n const requireMutation = (expectedEtag: string | null | undefined) =>\n requireBase(expectedEtag == null ? 'create' : 'replace');\n const workflowRead = <T>(\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n requireBase('read');\n if (!workflows.allows('read')) denied();\n return run('read', input, work);\n };\n const workflowWrite = <T>(\n permission: 'write' | 'commit',\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (\n (!workspace.allows('create') && !workspace.allows('replace')) ||\n !workflows.allows(permission)\n )\n denied();\n return run(permission, input, work);\n };\n const protectedWorkflows = Object.freeze<\n StorageFileWorkflowCapability<Receipt>\n >({\n kind: 'storage-file-workflow',\n version: 1,\n limits: Object.freeze({ ...workflows.limits }),\n restrict: (restriction) =>\n protectStorageFileWorkflowWorkspace({\n ...options,\n workflows: workflows.restrict(restriction),\n }).workflows,\n allows: (permission) =>\n workflows.allows(permission) &&\n (permission === 'read'\n ? workspace.allows('read')\n : workspace.allows('create') || workspace.allows('replace')),\n lookup: (input) =>\n workflowRead(input, (signal) => workflows.lookup({ ...input, signal })),\n begin: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n return workflowWrite('write', snapshot, (signal) =>\n workflows.begin({ ...snapshot, signal }),\n );\n },\n stageText: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n return workflowWrite('write', snapshot, (signal) =>\n workflows.stageText({ ...snapshot, signal }),\n );\n },\n stageStream: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n const write = () =>\n workflowWrite('write', snapshot, (signal) =>\n workflows.stageStream({ ...snapshot, signal }),\n );\n return snapshot.sourceDraftId === undefined\n ? write()\n : workflowRead(snapshot, write);\n },\n reviseText: (input) => {\n requireBase('read');\n const snapshot = {\n ...input,\n changes: input.changes.map((change) => ({ ...change })),\n };\n return workflowRead(snapshot, () =>\n workflowWrite('write', snapshot, (signal) =>\n workflows.reviseText({ ...snapshot, signal }),\n ),\n );\n },\n list: (input = {}) =>\n workflowRead(input, (signal) => workflows.list({ ...input, signal })),\n read: (input) =>\n workflowRead(input, (signal) => workflows.read({ ...input, signal })),\n searchText: (input) =>\n workflowRead(input, (signal) =>\n workflows.searchText({ ...input, signal }),\n ),\n readText: (input) =>\n workflowRead(input, (signal) => workflows.readText({ ...input, signal })),\n parts: (input) =>\n workflowRead(input, (signal) => workflows.parts({ ...input, signal })),\n append: (input) => {\n const snapshot = { ...input, bytes: input.bytes.slice() };\n return workflowWrite('write', snapshot, (signal) =>\n workflows.append({ ...snapshot, signal }),\n );\n },\n cancel: (input) =>\n workflowWrite('write', input, (signal) =>\n workflows.cancel({ ...input, signal }),\n ),\n commit: (input) => {\n const snapshot = {\n ...input,\n drafts: input.drafts.map((draft) => ({ ...draft })),\n };\n return workflowWrite('commit', snapshot, (signal) =>\n workflows.commit({ ...snapshot, signal }),\n );\n },\n });\n const base = protectBase(workspace, options);\n if (catalog === undefined)\n return Object.freeze({ ...base, workflows: protectedWorkflows });\n const limits = Object.freeze({\n ...catalog.limits,\n maxReadBytes: Math.min(\n catalog.limits.maxReadBytes,\n workspace.limits.maxReadBytes,\n ),\n maxWriteBytes: Math.min(\n catalog.limits.maxWriteBytes,\n workspace.limits.maxWriteBytes,\n ),\n maxPageSize: Math.min(\n catalog.limits.maxPageSize,\n workspace.limits.maxPageSize,\n ),\n maxPathBytes: Math.min(\n catalog.limits.maxPathBytes,\n workspace.limits.maxPathBytes,\n ),\n });\n for (const [name, value] of Object.entries(limits))\n storageInteger(value, name, 1);\n const catalogRun = <T>(\n permission: 'read' | 'write',\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (!catalog.allows(permission)) denied();\n if (permission === 'read') requireBase('read');\n return run(permission, input, work);\n };\n const textLimit = (text: string) => {\n if (/[\\uD800-\\uDFFF]/u.test(text))\n throw new StorageError('Text must be well-formed UTF-8.', {\n code: 'INVALID_ARGUMENT',\n });\n if (new TextEncoder().encode(text).byteLength > limits.maxWriteBytes)\n throw new StorageError('Catalog write exceeds its byte budget.', {\n code: 'LIMIT_EXCEEDED',\n });\n };\n const protectedCatalog = Object.freeze<StorageFileCatalogCapability<Receipt>>(\n {\n kind: 'storage-file-catalog',\n version: 1,\n limits,\n allows: (permission) =>\n catalog.allows(permission) &&\n (permission === 'read'\n ? workspace.allows('read')\n : workspace.allows('create') || workspace.allows('replace')),\n list: (input) => {\n requireBase('list');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.list({ ...input, signal });\n checkPage(page.items.length, limits.maxPageSize);\n return page;\n });\n },\n stat: (input) =>\n catalogRun('read', input, (signal) =>\n catalog.stat({ ...input, signal }),\n ),\n search: (input) => {\n requireBase('search');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.search({ ...input, signal });\n checkPage(page.items.length, limits.maxPageSize);\n return page;\n });\n },\n readWindow: (input) =>\n catalogRun('read', input, async (signal) => {\n const page = await catalog.readWindow({ ...input, signal });\n checkPage(\n new TextEncoder().encode(page.content ?? '').byteLength,\n limits.maxReadBytes,\n );\n return page;\n }),\n searchContent: (input) => {\n requireBase('search');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.searchContent({ ...input, signal });\n checkPage(page.matches.length, limits.maxSearchMatches);\n return page;\n });\n },\n write: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n textLimit(snapshot.content);\n return catalogRun('write', snapshot, (signal) =>\n catalog.write({ ...snapshot, signal }),\n );\n },\n edit: (input) => {\n const change =\n input.change.kind === 'batch'\n ? {\n ...input.change,\n changes: input.change.changes.map((entry) => ({ ...entry })),\n }\n : { ...input.change };\n const snapshot = { ...input, change };\n requireBase('replace');\n if (change.kind === 'batch') {\n if (change.changes.length < 1 || change.changes.length > 64)\n throw new StorageError('Edit batch exceeds the operation limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n let total = '';\n for (const entry of change.changes)\n total +=\n entry.kind === 'append'\n ? entry.text\n : entry.oldText + entry.newText;\n textLimit(total);\n } else if (change.kind === 'append') textLimit(change.text);\n else {\n textLimit(change.oldText);\n textLimit(change.newText);\n }\n return catalogRun('write', snapshot, (signal) =>\n catalog.edit({ ...snapshot, signal }),\n );\n },\n },\n );\n return Object.freeze({\n ...base,\n workflows: protectedWorkflows,\n catalog: protectedCatalog,\n });\n}\n\n/** Structural extension lookup survives host-owned feature properties on the handle. */\nexport function getStorageFileWorkflow<Receipt = unknown>(\n workspace: StorageWorkspace,\n): StorageFileWorkflowCapability<Receipt> {\n const capability = (\n workspace as Partial<StorageFileWorkflowWorkspace<Receipt>>\n ).workflows;\n if (\n capability?.kind !== 'storage-file-workflow' ||\n capability.version !== 1 ||\n [\n 'allows',\n 'restrict',\n 'begin',\n 'stageText',\n 'reviseText',\n 'list',\n 'read',\n 'readText',\n 'parts',\n 'append',\n 'cancel',\n 'commit',\n ].some((method) => typeof Reflect.get(capability, method) !== 'function')\n )\n throw new StorageError('Protected file workflow is unavailable.', {\n code: 'NOT_SUPPORTED',\n });\n return capability;\n}\nexport function getStorageFileCatalog<Receipt = unknown>(\n workspace: StorageWorkspace,\n): StorageFileCatalogCapability<Receipt> {\n const capability = (\n workspace as Partial<StorageFileWorkflowWorkspace<Receipt>>\n ).catalog;\n if (\n capability?.kind !== 'storage-file-catalog' ||\n capability.version !== 1 ||\n [\n 'allows',\n 'list',\n 'stat',\n 'search',\n 'readWindow',\n 'searchContent',\n 'write',\n 'edit',\n ].some((method) => typeof Reflect.get(capability, method) !== 'function')\n )\n throw new StorageError('Protected file catalog is unavailable.', {\n code: 'NOT_SUPPORTED',\n });\n return capability;\n}\n\nfunction protectBase(\n workspace: StorageWorkspace,\n protection: StorageFileWorkflowProtection,\n): StorageWorkspace {\n const run = <T>(\n permission: StorageWorkspacePermission,\n input: StorageOperationOptions | undefined,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (!workspace.allows(permission)) denied();\n return protectStorageFileWorkflowOperation(\n {\n ...protection,\n permission: ['read', 'list', 'search'].includes(permission)\n ? 'read'\n : 'write',\n operationSignal: input?.signal,\n },\n work,\n );\n };\n return Object.freeze({\n get permissions() {\n return new Set(workspace.permissions);\n },\n limits: Object.freeze({ ...workspace.limits }),\n allows: (permission) => workspace.allows(permission),\n stat: (path, input) =>\n run('read', input, (signal) =>\n workspace.stat(path, { ...input, signal }),\n ),\n readText: (path, input) =>\n run('read', input, (signal) =>\n workspace.readText(path, { ...input, signal }),\n ),\n readBytes: (path, input) =>\n run('read', input, (signal) =>\n workspace.readBytes(path, { ...input, signal }),\n ),\n list: (input) =>\n run('list', input, (signal) => workspace.list({ ...input, signal })),\n search: (query, input) =>\n run('search', input, (signal) =>\n workspace.search(query, { ...input, signal }),\n ),\n writeFile: (path, body, input) => {\n const snapshot = typeof body === 'string' ? body : body.slice();\n const request = { ...input };\n return run(\n request.mode === 'overwrite'\n ? 'write'\n : request.mode === 'create'\n ? 'create'\n : 'replace',\n request,\n (signal) => workspace.writeFile(path, snapshot, { ...request, signal }),\n );\n },\n copyFile: (source, destination, input) =>\n run('copy', input, (signal) =>\n workspace.copyFile(source, destination, { ...input, signal }),\n ),\n moveFile: (source, destination, input) =>\n run('move', input, (signal) =>\n workspace.moveFile(source, destination, { ...input, signal }),\n ),\n deleteFile: (path, input) =>\n run('delete', input, (signal) =>\n workspace.deleteFile(path, { ...input, signal }),\n ),\n // A child mount must never inherit its parent's broader catalog/workflow.\n mount: (directory, input) => {\n protection.signal.throwIfAborted();\n return protectBase(workspace.mount(directory, input), protection);\n },\n } satisfies StorageWorkspace);\n}\nfunction checkPage(size: number, maximum: number) {\n if (size > maximum)\n throw new StorageError('Catalog result exceeds its configured limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n}\nfunction denied(): never {\n throw new StorageError('File operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.protection.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.protection.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageError } from '../storage.error.js';\nimport { storageInteger } from '../core/storage-streams.js';\nimport type { StorageOperationOptions } from '../storage.types.js';\nimport type {\n StorageWorkspace,\n StorageWorkspacePermission,\n} from './storage-workspace.types.js';\nimport type {\n StorageFileWorkflowCapability,\n StorageFileWorkflowOperation,\n StorageFileWorkflowPermission,\n} from './storage-file-workflow.types.js';\nimport type { StorageFileCatalogCapability } from './storage-file-catalog.types.js';\n\nexport interface StorageFileWorkflowProtection {\n readonly signal: AbortSignal;\n /** Fresh host authority check. Transaction ports must independently recheck. */\n readonly authorize: (operation: {\n readonly permission: StorageFileWorkflowPermission;\n readonly signal: AbortSignal;\n }) => void | Promise<void>;\n}\nexport interface StorageFileWorkflowWorkspace<\n Receipt = unknown,\n> extends StorageWorkspace {\n readonly workflows: StorageFileWorkflowCapability<Receipt>;\n readonly catalog?: StorageFileCatalogCapability<Receipt>;\n}\nexport interface ProtectStorageFileWorkflowWorkspaceOptions<\n Receipt,\n> extends StorageFileWorkflowProtection {\n /** Host catalog delegate, already restricted to the same trusted scope. */\n readonly workspace: StorageWorkspace;\n readonly workflows: StorageFileWorkflowCapability<Receipt>;\n readonly catalog?: StorageFileCatalogCapability<Receipt>;\n}\n\n/** For host-owned feature closures captured during capability acquisition. */\nexport async function protectStorageFileWorkflowOperation<Result>(\n protection: StorageFileWorkflowProtection & {\n readonly permission: StorageFileWorkflowPermission;\n readonly operationSignal?: AbortSignal | undefined;\n },\n work: (signal: AbortSignal) => Promise<Result>,\n): Promise<Result> {\n const signal =\n protection.operationSignal === undefined\n ? protection.signal\n : AbortSignal.any([protection.signal, protection.operationSignal]);\n signal.throwIfAborted();\n await protection.authorize({ permission: protection.permission, signal });\n signal.throwIfAborted();\n // A completed mutation must return its receipt even if abort races its response.\n return work(signal);\n}\n\nexport function protectStorageFileWorkflowWorkspace<Receipt>(\n options: ProtectStorageFileWorkflowWorkspaceOptions<Receipt>,\n): StorageFileWorkflowWorkspace<Receipt> {\n const { workspace, catalog } = options;\n const workflows = options.workflows.restrict({\n mutations: [\n ...(workspace.allows('create') ? ['create' as const] : []),\n ...(workspace.allows('replace') ? ['replace' as const] : []),\n ],\n signal: options.signal,\n });\n const run = <T>(\n permission: StorageFileWorkflowPermission,\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) =>\n protectStorageFileWorkflowOperation(\n { ...options, permission, operationSignal: input.signal },\n work,\n );\n const requireBase = (permission: StorageWorkspacePermission) => {\n if (!workspace.allows(permission)) denied();\n };\n const requireMutation = (expectedEtag: string | null | undefined) =>\n requireBase(expectedEtag == null ? 'create' : 'replace');\n const workflowRead = <T>(\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n requireBase('read');\n if (!workflows.allows('read')) denied();\n return run('read', input, work);\n };\n const workflowWrite = <T>(\n permission: 'write' | 'commit',\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (\n (!workspace.allows('create') && !workspace.allows('replace')) ||\n !workflows.allows(permission)\n )\n denied();\n return run(permission, input, work);\n };\n const protectedWorkflows = Object.freeze<\n StorageFileWorkflowCapability<Receipt>\n >({\n kind: 'storage-file-workflow',\n version: 1,\n limits: Object.freeze({ ...workflows.limits }),\n restrict: (restriction) =>\n protectStorageFileWorkflowWorkspace({\n ...options,\n workflows: workflows.restrict(restriction),\n }).workflows,\n allows: (permission) =>\n workflows.allows(permission) &&\n (permission === 'read'\n ? workspace.allows('read')\n : workspace.allows('create') || workspace.allows('replace')),\n lookup: (input) =>\n workflowRead(input, (signal) => workflows.lookup({ ...input, signal })),\n begin: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n return workflowWrite('write', snapshot, (signal) =>\n workflows.begin({ ...snapshot, signal }),\n );\n },\n stageText: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n return workflowWrite('write', snapshot, (signal) =>\n workflows.stageText({ ...snapshot, signal }),\n );\n },\n stageStream: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n const write = () =>\n workflowWrite('write', snapshot, (signal) =>\n workflows.stageStream({ ...snapshot, signal }),\n );\n return snapshot.sourceDraftId === undefined\n ? write()\n : workflowRead(snapshot, write);\n },\n reviseText: (input) => {\n requireBase('read');\n const snapshot = {\n ...input,\n changes: input.changes.map((change) => ({ ...change })),\n };\n return workflowRead(snapshot, () =>\n workflowWrite('write', snapshot, (signal) =>\n workflows.reviseText({ ...snapshot, signal }),\n ),\n );\n },\n list: (input = {}) =>\n workflowRead(input, (signal) => workflows.list({ ...input, signal })),\n read: (input) =>\n workflowRead(input, (signal) => workflows.read({ ...input, signal })),\n searchText: (input) =>\n workflowRead(input, (signal) =>\n workflows.searchText({ ...input, signal }),\n ),\n readStream: (input) =>\n workflowRead(input, (signal) =>\n workflows.readStream({ ...input, signal }),\n ),\n readText: (input) =>\n workflowRead(input, (signal) => workflows.readText({ ...input, signal })),\n parts: (input) =>\n workflowRead(input, (signal) => workflows.parts({ ...input, signal })),\n append: (input) => {\n const snapshot = { ...input, bytes: input.bytes.slice() };\n return workflowWrite('write', snapshot, (signal) =>\n workflows.append({ ...snapshot, signal }),\n );\n },\n cancel: (input) =>\n workflowWrite('write', input, (signal) =>\n workflows.cancel({ ...input, signal }),\n ),\n commit: (input) => {\n const snapshot = {\n ...input,\n drafts: input.drafts.map((draft) => ({ ...draft })),\n };\n return workflowWrite('commit', snapshot, (signal) =>\n workflows.commit({ ...snapshot, signal }),\n );\n },\n });\n const base = protectBase(workspace, options);\n if (catalog === undefined)\n return Object.freeze({ ...base, workflows: protectedWorkflows });\n const limits = Object.freeze({\n ...catalog.limits,\n maxReadBytes: Math.min(\n catalog.limits.maxReadBytes,\n workspace.limits.maxReadBytes,\n ),\n maxWriteBytes: Math.min(\n catalog.limits.maxWriteBytes,\n workspace.limits.maxWriteBytes,\n ),\n maxPageSize: Math.min(\n catalog.limits.maxPageSize,\n workspace.limits.maxPageSize,\n ),\n maxPathBytes: Math.min(\n catalog.limits.maxPathBytes,\n workspace.limits.maxPathBytes,\n ),\n });\n for (const [name, value] of Object.entries(limits))\n storageInteger(value, name, 1);\n const catalogRun = <T>(\n permission: 'read' | 'write',\n input: StorageFileWorkflowOperation,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (!catalog.allows(permission)) denied();\n if (permission === 'read') requireBase('read');\n return run(permission, input, work);\n };\n const textLimit = (text: string) => {\n if (/[\\uD800-\\uDFFF]/u.test(text))\n throw new StorageError('Text must be well-formed UTF-8.', {\n code: 'INVALID_ARGUMENT',\n });\n if (new TextEncoder().encode(text).byteLength > limits.maxWriteBytes)\n throw new StorageError('Catalog write exceeds its byte budget.', {\n code: 'LIMIT_EXCEEDED',\n });\n };\n const protectedCatalog = Object.freeze<StorageFileCatalogCapability<Receipt>>(\n {\n kind: 'storage-file-catalog',\n version: 1,\n limits,\n allows: (permission) =>\n catalog.allows(permission) &&\n (permission === 'read'\n ? workspace.allows('read')\n : workspace.allows('create') || workspace.allows('replace')),\n list: (input) => {\n requireBase('list');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.list({ ...input, signal });\n checkPage(page.items.length, limits.maxPageSize);\n return page;\n });\n },\n stat: (input) =>\n catalogRun('read', input, (signal) =>\n catalog.stat({ ...input, signal }),\n ),\n search: (input) => {\n requireBase('search');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.search({ ...input, signal });\n checkPage(page.items.length, limits.maxPageSize);\n return page;\n });\n },\n readWindow: (input) =>\n catalogRun('read', input, async (signal) => {\n const page = await catalog.readWindow({ ...input, signal });\n checkPage(\n new TextEncoder().encode(page.content ?? '').byteLength,\n limits.maxReadBytes,\n );\n return page;\n }),\n readStream: (input) =>\n catalogRun('read', input, async (signal) => {\n const result = await catalog.readStream({ ...input, signal });\n const reader = result.body.getReader();\n return {\n ...result,\n body: new ReadableStream<Uint8Array>(\n {\n async pull(controller) {\n try {\n const part = await catalogRun(\n 'read',\n { signal },\n async (current) => {\n current.throwIfAborted();\n const part = await reader.read();\n current.throwIfAborted();\n return part;\n },\n );\n if (part.done) {\n reader.releaseLock();\n controller.close();\n } else controller.enqueue(part.value);\n } catch (error) {\n await reader.cancel(error).catch(() => {});\n reader.releaseLock();\n controller.error(error);\n }\n },\n async cancel(reason) {\n await reader.cancel(reason);\n reader.releaseLock();\n },\n },\n { highWaterMark: 0 },\n ),\n };\n }),\n searchContent: (input) => {\n requireBase('search');\n return catalogRun('read', input, async (signal) => {\n const page = await catalog.searchContent({ ...input, signal });\n checkPage(page.matches.length, limits.maxSearchMatches);\n return page;\n });\n },\n write: (input) => {\n const snapshot = { ...input };\n requireMutation(snapshot.expectedEtag);\n textLimit(snapshot.content);\n return catalogRun('write', snapshot, (signal) =>\n catalog.write({ ...snapshot, signal }),\n );\n },\n edit: (input) => {\n const change =\n input.change.kind === 'batch'\n ? {\n ...input.change,\n changes: input.change.changes.map((entry) => ({ ...entry })),\n }\n : { ...input.change };\n const snapshot = { ...input, change };\n requireBase('replace');\n if (change.kind === 'batch') {\n if (change.changes.length < 1 || change.changes.length > 64)\n throw new StorageError('Edit batch exceeds the operation limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n let total = '';\n for (const entry of change.changes)\n total +=\n entry.kind === 'append'\n ? entry.text\n : entry.oldText + entry.newText;\n textLimit(total);\n } else if (change.kind === 'append') textLimit(change.text);\n else {\n textLimit(change.oldText);\n textLimit(change.newText);\n }\n return catalogRun('write', snapshot, (signal) =>\n catalog.edit({ ...snapshot, signal }),\n );\n },\n },\n );\n return Object.freeze({\n ...base,\n workflows: protectedWorkflows,\n catalog: protectedCatalog,\n });\n}\n\n/** Structural extension lookup survives host-owned feature properties on the handle. */\nexport function getStorageFileWorkflow<Receipt = unknown>(\n workspace: StorageWorkspace,\n): StorageFileWorkflowCapability<Receipt> {\n const capability = (\n workspace as Partial<StorageFileWorkflowWorkspace<Receipt>>\n ).workflows;\n if (\n capability?.kind !== 'storage-file-workflow' ||\n capability.version !== 1 ||\n [\n 'allows',\n 'restrict',\n 'begin',\n 'stageText',\n 'reviseText',\n 'list',\n 'read',\n 'readText',\n 'parts',\n 'append',\n 'cancel',\n 'commit',\n ].some((method) => typeof Reflect.get(capability, method) !== 'function')\n )\n throw new StorageError('Protected file workflow is unavailable.', {\n code: 'NOT_SUPPORTED',\n });\n return capability;\n}\nexport function getStorageFileCatalog<Receipt = unknown>(\n workspace: StorageWorkspace,\n): StorageFileCatalogCapability<Receipt> {\n const capability = (\n workspace as Partial<StorageFileWorkflowWorkspace<Receipt>>\n ).catalog;\n if (\n capability?.kind !== 'storage-file-catalog' ||\n capability.version !== 1 ||\n [\n 'allows',\n 'list',\n 'stat',\n 'search',\n 'readWindow',\n 'searchContent',\n 'write',\n 'edit',\n ].some((method) => typeof Reflect.get(capability, method) !== 'function')\n )\n throw new StorageError('Protected file catalog is unavailable.', {\n code: 'NOT_SUPPORTED',\n });\n return capability;\n}\n\nfunction protectBase(\n workspace: StorageWorkspace,\n protection: StorageFileWorkflowProtection,\n): StorageWorkspace {\n const run = <T>(\n permission: StorageWorkspacePermission,\n input: StorageOperationOptions | undefined,\n work: (signal: AbortSignal) => Promise<T>,\n ) => {\n if (!workspace.allows(permission)) denied();\n return protectStorageFileWorkflowOperation(\n {\n ...protection,\n permission: ['read', 'list', 'search'].includes(permission)\n ? 'read'\n : 'write',\n operationSignal: input?.signal,\n },\n work,\n );\n };\n return Object.freeze({\n get permissions() {\n return new Set(workspace.permissions);\n },\n limits: Object.freeze({ ...workspace.limits }),\n allows: (permission) => workspace.allows(permission),\n stat: (path, input) =>\n run('read', input, (signal) =>\n workspace.stat(path, { ...input, signal }),\n ),\n readText: (path, input) =>\n run('read', input, (signal) =>\n workspace.readText(path, { ...input, signal }),\n ),\n readBytes: (path, input) =>\n run('read', input, (signal) =>\n workspace.readBytes(path, { ...input, signal }),\n ),\n list: (input) =>\n run('list', input, (signal) => workspace.list({ ...input, signal })),\n search: (query, input) =>\n run('search', input, (signal) =>\n workspace.search(query, { ...input, signal }),\n ),\n writeFile: (path, body, input) => {\n const snapshot = typeof body === 'string' ? body : body.slice();\n const request = { ...input };\n return run(\n request.mode === 'overwrite'\n ? 'write'\n : request.mode === 'create'\n ? 'create'\n : 'replace',\n request,\n (signal) => workspace.writeFile(path, snapshot, { ...request, signal }),\n );\n },\n copyFile: (source, destination, input) =>\n run('copy', input, (signal) =>\n workspace.copyFile(source, destination, { ...input, signal }),\n ),\n moveFile: (source, destination, input) =>\n run('move', input, (signal) =>\n workspace.moveFile(source, destination, { ...input, signal }),\n ),\n deleteFile: (path, input) =>\n run('delete', input, (signal) =>\n workspace.deleteFile(path, { ...input, signal }),\n ),\n // A child mount must never inherit its parent's broader catalog/workflow.\n mount: (directory, input) => {\n protection.signal.throwIfAborted();\n return protectBase(workspace.mount(directory, input), protection);\n },\n } satisfies StorageWorkspace);\n}\nfunction checkPage(size: number, maximum: number) {\n if (size > maximum)\n throw new StorageError('Catalog result exceeds its configured limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n}\nfunction denied(): never {\n throw new StorageError('File operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n}\n"]}
|
|
@@ -31,7 +31,7 @@ export interface StorageFileDraftStageStream extends StorageFileDraftBegin {
|
|
|
31
31
|
/** Stable trusted source identity used to detect conflicting command replay. */
|
|
32
32
|
readonly contentIdentity: string;
|
|
33
33
|
/** Open only after authorization and replay lookup; bytes are never exposed to the model. */
|
|
34
|
-
readonly body: () => ReadableStream<Uint8Array
|
|
34
|
+
readonly body: () => ReadableStream<Uint8Array> | Promise<ReadableStream<Uint8Array>>;
|
|
35
35
|
readonly sourceDraftId?: string | undefined;
|
|
36
36
|
readonly expectedSize?: number | undefined;
|
|
37
37
|
}
|
|
@@ -155,6 +155,14 @@ export interface StorageFileWorkflowCapability<Receipt = unknown> {
|
|
|
155
155
|
begin(input: StorageFileDraftBegin): Promise<StorageFileDraft<Receipt>>;
|
|
156
156
|
list(input?: StorageFileDraftPageRequest): Promise<StorageFileWorkflowPage<StorageFileDraft<Receipt>>>;
|
|
157
157
|
read(input: StorageFileDraftRequest & StorageFileDraftPageRequest): Promise<StorageFileDraft<Receipt> & StorageTextWindow>;
|
|
158
|
+
/** Host-only stream of an exact checkpoint; end is exclusive. */
|
|
159
|
+
readStream(input: StorageFileDraftRequest & {
|
|
160
|
+
readonly expectedSize: number;
|
|
161
|
+
readonly start?: number | undefined;
|
|
162
|
+
readonly end?: number | undefined;
|
|
163
|
+
}): Promise<StorageFileDraft<Receipt> & {
|
|
164
|
+
readonly body: ReadableStream<Uint8Array>;
|
|
165
|
+
}>;
|
|
158
166
|
searchText(input: StorageFileDraftRequest & StorageFileDraftPageRequest & {
|
|
159
167
|
readonly expectedSize: number;
|
|
160
168
|
readonly query: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,MAAM,6BAA6B,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AACxE,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC/D,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,eAAO,MAAM,oCAAoC,EAAE,QAAQ,CAAC,yBAAyB,CASjF,CAAC;AACL,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C;AACD,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AACD,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CACrD,qBAAqB,EACrB,MAAM,CACP;IACC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE,gFAAgF;IAChF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.types.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.types.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,oCAAoC,GAC/C,MAAM,CAAC,MAAM,CAAC;IACZ,aAAa,EAAE,OAAO;IACtB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,EAAE;IACf,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IAC9B,QAAQ,EAAE,EAAE;CACb,CAAC,CAAC","sourcesContent":["import type {\n StorageStagedBody,\n StorageStagedContent,\n} from '../core/storage-staged-content.js';\nimport type { StorageTextChange } from '../core/storage-text-edit.js';\nimport type { StorageTextSearchResult } from '../core/storage-text.js';\nimport type { StorageTextWindow } from '../core/storage-streams.js';\n\nexport type StorageFileWorkflowPermission = 'read' | 'write' | 'commit';\nexport type StorageFileWorkflowMutation = 'create' | 'replace';\nexport interface StorageFileWorkflowLimits {\n maxChunkBytes: number;\n maxReadBytes: number;\n maxPageSize: number;\n maxCommitFiles: number;\n maxPathBytes: number;\n /** Buffered input and host read ceiling; streamed file edits are not limited by total file size. */\n maxTextBytes: number;\n maxEdits: number;\n}\nexport const DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS: Readonly<StorageFileWorkflowLimits> =\n Object.freeze({\n maxChunkBytes: 262_144,\n maxReadBytes: 4096,\n maxPageSize: 64,\n maxCommitFiles: 20,\n maxPathBytes: 1024,\n maxTextBytes: 16 * 1024 * 1024,\n maxEdits: 64,\n });\nexport interface StorageFileWorkflowOperation {\n readonly signal?: AbortSignal | undefined;\n}\nexport interface StorageFileDraftBegin extends StorageFileWorkflowOperation {\n readonly path: string;\n readonly idempotencyKey: string;\n readonly text: boolean;\n readonly expectedEtag?: string | undefined;\n}\nexport interface StorageFileDraftStageText extends Omit<\n StorageFileDraftBegin,\n 'text'\n> {\n readonly content: string;\n}\nexport interface StorageFileDraftStageStream extends StorageFileDraftBegin {\n /** Stable trusted source identity used to detect conflicting command replay. */\n readonly contentIdentity: string;\n /** Open only after authorization and replay lookup; bytes are never exposed to the model. */\n readonly body: () => ReadableStream<Uint8Array>;\n readonly sourceDraftId?: string | undefined;\n readonly expectedSize?: number | undefined;\n}\nexport interface StorageFileDraftReviseText extends StorageFileDraftRequest {\n /** Optional host request identity, included in replay validation. */\n readonly requestIdentity?: string | undefined;\n readonly expectedSize: number;\n readonly idempotencyKey: string;\n readonly changes: readonly StorageTextChange[];\n}\nexport interface StorageFileDraftRequest extends StorageFileWorkflowOperation {\n readonly draftId: string;\n}\nexport interface StorageFileDraftPageRequest extends StorageFileWorkflowOperation {\n readonly offset?: number | undefined;\n}\nexport interface StorageFileDraftAppend extends StorageFileDraftRequest {\n readonly offset: number;\n readonly bytes: Uint8Array;\n}\nexport interface StorageFileDraftCommit {\n readonly draftId: string;\n readonly size: number;\n readonly sha256?: string | undefined;\n}\nexport interface StorageFileWorkflowCommit extends StorageFileWorkflowOperation {\n readonly drafts: readonly StorageFileDraftCommit[];\n}\nexport interface StorageFileDraft<Receipt> {\n readonly id: string;\n readonly path: string;\n readonly expectedEtag: string | null;\n /** Predecessor checkpoint; null for a new draft or catalog checkout. */\n readonly sourceDraftId: string | null;\n readonly text: boolean;\n readonly status: 'open' | 'sealed' | 'committed' | 'cancelled';\n readonly size: number;\n readonly result: Receipt | null;\n readonly createdAt: string;\n}\nexport interface StorageFileDraftRecord<\n Receipt,\n> extends StorageFileDraft<Receipt> {\n readonly idempotencyKey: string;\n readonly requestFingerprint: string;\n /** Whole-file verified body; persisted only with successful head commit. */\n readonly body: StorageStagedBody | null;\n}\nexport interface StorageFilePartReceipt {\n readonly offset: number;\n readonly size: number;\n readonly sha256: string;\n}\nexport interface StorageFilePartRecord extends StorageFilePartReceipt {\n readonly body: StorageStagedBody;\n}\nexport interface StorageFileWorkflowPage<Item> {\n readonly items: readonly Item[];\n readonly nextOffset: number | null;\n}\nexport interface StorageFileHeadChange<Receipt> {\n readonly draft: StorageFileDraftRecord<Receipt>;\n readonly body: StorageStagedBody;\n}\n\n/** All methods execute in the SAME host transaction. Records are detached values. */\nexport interface StorageFileWorkflowTransaction<Receipt> {\n findDraftByKey(key: string): Promise<StorageFileDraftRecord<Receipt> | null>;\n getDraft(id: string): Promise<StorageFileDraftRecord<Receipt> | null>;\n saveDraft(draft: StorageFileDraftRecord<Receipt>): Promise<void>;\n /** Stable order, at most limit entries; scoped to the authorized principal. */\n listDrafts(\n offset: number,\n limit: number,\n ): Promise<readonly StorageFileDraftRecord<Receipt>[]>;\n /** Ordered by offset; include the part containing offset, then later parts. */\n listParts(\n draftId: string,\n offset: number,\n limit: number,\n ): Promise<readonly StorageFilePartRecord[]>;\n putPart(draftId: string, part: StorageFilePartRecord): Promise<void>;\n /**\n * Compare every expected head/create predicate and update all heads atomically.\n * Return one receipt per change, in the supplied order. Must join this transaction;\n * never implement this as serial provider writes or independent transactions.\n * Paths arrive sorted to permit consistent lock ordering.\n */\n commitHeads(\n changes: readonly StorageFileHeadChange<Receipt>[],\n ): Promise<readonly Receipt[]>;\n}\nexport interface StorageFileWorkflowPersistence<Scope, Receipt> {\n /**\n * Reauthorize scope on EVERY call; lock/serialize its draft/idempotency state\n * before work begins, including across replicas. Roll back ALL callback effects\n * on rejection. Resolve only after durable commit. Do not retry the callback.\n * Check signal before committing; once committed, return its result even if\n * signal subsequently aborts. Lost responses are reconciled by replay.\n */\n transaction<Result>(\n scope: Scope,\n options: StorageFileWorkflowOperation & {\n readonly permission: StorageFileWorkflowPermission;\n },\n work: (\n transaction: StorageFileWorkflowTransaction<Receipt>,\n ) => Promise<Result>,\n ): Promise<Result>;\n}\nexport interface StorageFileWorkflowOptions<Scope, Receipt> {\n readonly persistence: StorageFileWorkflowPersistence<Scope, Receipt>;\n readonly content: StorageStagedContent<Scope>;\n}\nexport interface MountStorageFileWorkflowOptions extends StorageFileWorkflowOperation {\n readonly permissions?: Iterable<StorageFileWorkflowPermission>;\n /** Checked against each persisted draft on append/cancel/commit, including replay. */\n readonly mutations?: Iterable<StorageFileWorkflowMutation>;\n readonly limits?: Partial<StorageFileWorkflowLimits>;\n}\n/** A host-scope-bound capability. Scope, provider keys and staged bodies stay private. */\nexport interface StorageFileWorkflowCapability<Receipt = unknown> {\n readonly kind: 'storage-file-workflow';\n readonly version: 1;\n readonly limits: Readonly<StorageFileWorkflowLimits>;\n allows(permission: StorageFileWorkflowPermission): boolean;\n /** Narrow only; cannot change scope, widen grants/limits, or detach parent abort. */\n restrict(\n options: MountStorageFileWorkflowOptions,\n ): StorageFileWorkflowCapability<Receipt>;\n /** Atomically save a bounded text buffer as a sealed, resumable checkpoint. */\n stageText(\n input: StorageFileDraftStageText,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Stage arbitrary-size text or binary source in bounded, integrity-checked chunks. */\n stageStream(\n input: StorageFileDraftStageStream,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Save a new sealed checkpoint; preserve the source and original head precondition. */\n reviseText(\n input: StorageFileDraftReviseText,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Recover a host command receipt without reopening its source. */\n lookup(\n input: StorageFileWorkflowOperation & { readonly idempotencyKey: string },\n ): Promise<StorageFileDraft<Receipt> | null>;\n begin(input: StorageFileDraftBegin): Promise<StorageFileDraft<Receipt>>;\n list(\n input?: StorageFileDraftPageRequest,\n ): Promise<StorageFileWorkflowPage<StorageFileDraft<Receipt>>>;\n read(\n input: StorageFileDraftRequest & StorageFileDraftPageRequest,\n ): Promise<StorageFileDraft<Receipt> & StorageTextWindow>;\n searchText(\n input: StorageFileDraftRequest &\n StorageFileDraftPageRequest & {\n readonly expectedSize: number;\n readonly query: string;\n },\n ): Promise<\n StorageTextSearchResult & { readonly path: string; readonly etag: string }\n >;\n /** Buffer one exact text revision within maxTextBytes for host validation. */\n readText(\n input: StorageFileDraftRequest & { readonly expectedSize: number },\n ): Promise<StorageFileDraft<Receipt> & { readonly content: string }>;\n append(input: StorageFileDraftAppend): Promise<StorageFileDraft<Receipt>>;\n parts(\n input: StorageFileDraftRequest & StorageFileDraftPageRequest,\n ): Promise<StorageFileWorkflowPage<StorageFilePartReceipt>>;\n cancel(input: StorageFileDraftRequest): Promise<StorageFileDraft<Receipt>>;\n commit(input: StorageFileWorkflowCommit): Promise<readonly Receipt[]>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.types.js","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.types.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,oCAAoC,GAC/C,MAAM,CAAC,MAAM,CAAC;IACZ,aAAa,EAAE,OAAO;IACtB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,EAAE;IACf,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IAC9B,QAAQ,EAAE,EAAE;CACb,CAAC,CAAC","sourcesContent":["import type {\n StorageStagedBody,\n StorageStagedContent,\n} from '../core/storage-staged-content.js';\nimport type { StorageTextChange } from '../core/storage-text-edit.js';\nimport type { StorageTextSearchResult } from '../core/storage-text.js';\nimport type { StorageTextWindow } from '../core/storage-streams.js';\n\nexport type StorageFileWorkflowPermission = 'read' | 'write' | 'commit';\nexport type StorageFileWorkflowMutation = 'create' | 'replace';\nexport interface StorageFileWorkflowLimits {\n maxChunkBytes: number;\n maxReadBytes: number;\n maxPageSize: number;\n maxCommitFiles: number;\n maxPathBytes: number;\n /** Buffered input and host read ceiling; streamed file edits are not limited by total file size. */\n maxTextBytes: number;\n maxEdits: number;\n}\nexport const DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS: Readonly<StorageFileWorkflowLimits> =\n Object.freeze({\n maxChunkBytes: 262_144,\n maxReadBytes: 4096,\n maxPageSize: 64,\n maxCommitFiles: 20,\n maxPathBytes: 1024,\n maxTextBytes: 16 * 1024 * 1024,\n maxEdits: 64,\n });\nexport interface StorageFileWorkflowOperation {\n readonly signal?: AbortSignal | undefined;\n}\nexport interface StorageFileDraftBegin extends StorageFileWorkflowOperation {\n readonly path: string;\n readonly idempotencyKey: string;\n readonly text: boolean;\n readonly expectedEtag?: string | undefined;\n}\nexport interface StorageFileDraftStageText extends Omit<\n StorageFileDraftBegin,\n 'text'\n> {\n readonly content: string;\n}\nexport interface StorageFileDraftStageStream extends StorageFileDraftBegin {\n /** Stable trusted source identity used to detect conflicting command replay. */\n readonly contentIdentity: string;\n /** Open only after authorization and replay lookup; bytes are never exposed to the model. */\n readonly body: () =>\n ReadableStream<Uint8Array> | Promise<ReadableStream<Uint8Array>>;\n readonly sourceDraftId?: string | undefined;\n readonly expectedSize?: number | undefined;\n}\nexport interface StorageFileDraftReviseText extends StorageFileDraftRequest {\n /** Optional host request identity, included in replay validation. */\n readonly requestIdentity?: string | undefined;\n readonly expectedSize: number;\n readonly idempotencyKey: string;\n readonly changes: readonly StorageTextChange[];\n}\nexport interface StorageFileDraftRequest extends StorageFileWorkflowOperation {\n readonly draftId: string;\n}\nexport interface StorageFileDraftPageRequest extends StorageFileWorkflowOperation {\n readonly offset?: number | undefined;\n}\nexport interface StorageFileDraftAppend extends StorageFileDraftRequest {\n readonly offset: number;\n readonly bytes: Uint8Array;\n}\nexport interface StorageFileDraftCommit {\n readonly draftId: string;\n readonly size: number;\n readonly sha256?: string | undefined;\n}\nexport interface StorageFileWorkflowCommit extends StorageFileWorkflowOperation {\n readonly drafts: readonly StorageFileDraftCommit[];\n}\nexport interface StorageFileDraft<Receipt> {\n readonly id: string;\n readonly path: string;\n readonly expectedEtag: string | null;\n /** Predecessor checkpoint; null for a new draft or catalog checkout. */\n readonly sourceDraftId: string | null;\n readonly text: boolean;\n readonly status: 'open' | 'sealed' | 'committed' | 'cancelled';\n readonly size: number;\n readonly result: Receipt | null;\n readonly createdAt: string;\n}\nexport interface StorageFileDraftRecord<\n Receipt,\n> extends StorageFileDraft<Receipt> {\n readonly idempotencyKey: string;\n readonly requestFingerprint: string;\n /** Whole-file verified body; persisted only with successful head commit. */\n readonly body: StorageStagedBody | null;\n}\nexport interface StorageFilePartReceipt {\n readonly offset: number;\n readonly size: number;\n readonly sha256: string;\n}\nexport interface StorageFilePartRecord extends StorageFilePartReceipt {\n readonly body: StorageStagedBody;\n}\nexport interface StorageFileWorkflowPage<Item> {\n readonly items: readonly Item[];\n readonly nextOffset: number | null;\n}\nexport interface StorageFileHeadChange<Receipt> {\n readonly draft: StorageFileDraftRecord<Receipt>;\n readonly body: StorageStagedBody;\n}\n\n/** All methods execute in the SAME host transaction. Records are detached values. */\nexport interface StorageFileWorkflowTransaction<Receipt> {\n findDraftByKey(key: string): Promise<StorageFileDraftRecord<Receipt> | null>;\n getDraft(id: string): Promise<StorageFileDraftRecord<Receipt> | null>;\n saveDraft(draft: StorageFileDraftRecord<Receipt>): Promise<void>;\n /** Stable order, at most limit entries; scoped to the authorized principal. */\n listDrafts(\n offset: number,\n limit: number,\n ): Promise<readonly StorageFileDraftRecord<Receipt>[]>;\n /** Ordered by offset; include the part containing offset, then later parts. */\n listParts(\n draftId: string,\n offset: number,\n limit: number,\n ): Promise<readonly StorageFilePartRecord[]>;\n putPart(draftId: string, part: StorageFilePartRecord): Promise<void>;\n /**\n * Compare every expected head/create predicate and update all heads atomically.\n * Return one receipt per change, in the supplied order. Must join this transaction;\n * never implement this as serial provider writes or independent transactions.\n * Paths arrive sorted to permit consistent lock ordering.\n */\n commitHeads(\n changes: readonly StorageFileHeadChange<Receipt>[],\n ): Promise<readonly Receipt[]>;\n}\nexport interface StorageFileWorkflowPersistence<Scope, Receipt> {\n /**\n * Reauthorize scope on EVERY call; lock/serialize its draft/idempotency state\n * before work begins, including across replicas. Roll back ALL callback effects\n * on rejection. Resolve only after durable commit. Do not retry the callback.\n * Check signal before committing; once committed, return its result even if\n * signal subsequently aborts. Lost responses are reconciled by replay.\n */\n transaction<Result>(\n scope: Scope,\n options: StorageFileWorkflowOperation & {\n readonly permission: StorageFileWorkflowPermission;\n },\n work: (\n transaction: StorageFileWorkflowTransaction<Receipt>,\n ) => Promise<Result>,\n ): Promise<Result>;\n}\nexport interface StorageFileWorkflowOptions<Scope, Receipt> {\n readonly persistence: StorageFileWorkflowPersistence<Scope, Receipt>;\n readonly content: StorageStagedContent<Scope>;\n}\nexport interface MountStorageFileWorkflowOptions extends StorageFileWorkflowOperation {\n readonly permissions?: Iterable<StorageFileWorkflowPermission>;\n /** Checked against each persisted draft on append/cancel/commit, including replay. */\n readonly mutations?: Iterable<StorageFileWorkflowMutation>;\n readonly limits?: Partial<StorageFileWorkflowLimits>;\n}\n/** A host-scope-bound capability. Scope, provider keys and staged bodies stay private. */\nexport interface StorageFileWorkflowCapability<Receipt = unknown> {\n readonly kind: 'storage-file-workflow';\n readonly version: 1;\n readonly limits: Readonly<StorageFileWorkflowLimits>;\n allows(permission: StorageFileWorkflowPermission): boolean;\n /** Narrow only; cannot change scope, widen grants/limits, or detach parent abort. */\n restrict(\n options: MountStorageFileWorkflowOptions,\n ): StorageFileWorkflowCapability<Receipt>;\n /** Atomically save a bounded text buffer as a sealed, resumable checkpoint. */\n stageText(\n input: StorageFileDraftStageText,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Stage arbitrary-size text or binary source in bounded, integrity-checked chunks. */\n stageStream(\n input: StorageFileDraftStageStream,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Save a new sealed checkpoint; preserve the source and original head precondition. */\n reviseText(\n input: StorageFileDraftReviseText,\n ): Promise<StorageFileDraft<Receipt>>;\n /** Recover a host command receipt without reopening its source. */\n lookup(\n input: StorageFileWorkflowOperation & { readonly idempotencyKey: string },\n ): Promise<StorageFileDraft<Receipt> | null>;\n begin(input: StorageFileDraftBegin): Promise<StorageFileDraft<Receipt>>;\n list(\n input?: StorageFileDraftPageRequest,\n ): Promise<StorageFileWorkflowPage<StorageFileDraft<Receipt>>>;\n read(\n input: StorageFileDraftRequest & StorageFileDraftPageRequest,\n ): Promise<StorageFileDraft<Receipt> & StorageTextWindow>;\n /** Host-only stream of an exact checkpoint; end is exclusive. */\n readStream(\n input: StorageFileDraftRequest & {\n readonly expectedSize: number;\n readonly start?: number | undefined;\n readonly end?: number | undefined;\n },\n ): Promise<\n StorageFileDraft<Receipt> & { readonly body: ReadableStream<Uint8Array> }\n >;\n searchText(\n input: StorageFileDraftRequest &\n StorageFileDraftPageRequest & {\n readonly expectedSize: number;\n readonly query: string;\n },\n ): Promise<\n StorageTextSearchResult & { readonly path: string; readonly etag: string }\n >;\n /** Buffer one exact text revision within maxTextBytes for host validation. */\n readText(\n input: StorageFileDraftRequest & { readonly expectedSize: number },\n ): Promise<StorageFileDraft<Receipt> & { readonly content: string }>;\n append(input: StorageFileDraftAppend): Promise<StorageFileDraft<Receipt>>;\n parts(\n input: StorageFileDraftRequest & StorageFileDraftPageRequest,\n ): Promise<StorageFileWorkflowPage<StorageFilePartReceipt>>;\n cancel(input: StorageFileDraftRequest): Promise<StorageFileDraft<Receipt>>;\n commit(input: StorageFileWorkflowCommit): Promise<readonly Receipt[]>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-working-files.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-working-files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,4BAA4B,EAC5B,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,EAE7B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;CACxB;AACD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,6FAA6F;AAC7F,qBAAa,mBAAmB,CAAC,OAAO,SAAS,yBAAyB;IAGtE,QAAQ,CAAC,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC;IAH3D,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAAC;IAC7E,YACW,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC,EAC5C,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"storage-working-files.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-working-files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,4BAA4B,EAC5B,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,4BAA4B,EAE7B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;CACxB;AACD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,6FAA6F;AAC7F,qBAAa,mBAAmB,CAAC,OAAO,SAAS,yBAAyB;IAGtE,QAAQ,CAAC,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC;IAH3D,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAAC;IAC7E,YACW,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC,EAC5C,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC,EA2H1D;IAEK,KAAK,CACT,KAAK,EAAE,qBAAqB,GAAG;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC1D,OAAO,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAkDvC;IAED,6FAA6F;IACvF,KAAK,CACT,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAyB3C;IAED,4FAA4F;IACtF,OAAO,CACX,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,CAyBtC;YAEa,IAAI;IAuDlB,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,YAAY;IAGpB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,QAAQ;CAMjB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { StorageError, isStorageError } from '../storage.error.js';
|
|
3
3
|
import { storageBytesStream, storageInteger } from '../core/storage-streams.js';
|
|
4
|
-
import {
|
|
4
|
+
import { editStorageTextStream } from '../core/storage-text-stream-edit.js';
|
|
5
5
|
/** A path-based editing view over durable checkpoints. Saved heads change only on commit. */
|
|
6
6
|
export class StorageWorkingFiles {
|
|
7
7
|
files;
|
|
@@ -39,6 +39,19 @@ export class StorageWorkingFiles {
|
|
|
39
39
|
totalBytes: page.size,
|
|
40
40
|
};
|
|
41
41
|
},
|
|
42
|
+
readStream: async (input) => {
|
|
43
|
+
const draft = await this.draft(input);
|
|
44
|
+
if (!draft || draft.status === 'committed')
|
|
45
|
+
return files.readStream(this.saved(input, draft));
|
|
46
|
+
const stream = await workflow.readStream({
|
|
47
|
+
draftId: draft.id,
|
|
48
|
+
expectedSize: draft.size,
|
|
49
|
+
start: input.start,
|
|
50
|
+
end: input.end,
|
|
51
|
+
signal: input.signal,
|
|
52
|
+
});
|
|
53
|
+
return { ...this.receipt(draft), body: stream.body };
|
|
54
|
+
},
|
|
42
55
|
searchContent: async (input) => {
|
|
43
56
|
const draft = await this.draft(input);
|
|
44
57
|
if (!draft || draft.status === 'committed')
|
|
@@ -64,17 +77,39 @@ export class StorageWorkingFiles {
|
|
|
64
77
|
idempotencyKey: input.commandId,
|
|
65
78
|
signal: input.signal,
|
|
66
79
|
});
|
|
67
|
-
|
|
80
|
+
const source = prior?.sourceDraftId
|
|
68
81
|
? await workflow.read({
|
|
69
82
|
draftId: prior.sourceDraftId,
|
|
70
83
|
signal: input.signal,
|
|
71
84
|
})
|
|
72
85
|
: await this.draft(input);
|
|
73
|
-
if (!source || (!prior && source.status === 'committed'))
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
if (!source || (!prior && source.status === 'committed')) {
|
|
87
|
+
const saved = this.saved(input, source);
|
|
88
|
+
const result = await workflow.stageStream({
|
|
89
|
+
path: input.path,
|
|
90
|
+
expectedEtag: saved.expectedEtag,
|
|
91
|
+
text: true,
|
|
92
|
+
signal: input.signal,
|
|
93
|
+
idempotencyKey: input.commandId,
|
|
94
|
+
contentIdentity: createHash('sha256')
|
|
95
|
+
.update(JSON.stringify([
|
|
96
|
+
'catalog-edit',
|
|
97
|
+
input.path,
|
|
98
|
+
input.expectedEtag,
|
|
99
|
+
changes,
|
|
100
|
+
]))
|
|
101
|
+
.digest('hex'),
|
|
102
|
+
body: async () => {
|
|
103
|
+
const stream = await files.readStream(saved);
|
|
104
|
+
return editStorageTextStream(stream.body, changes, {
|
|
105
|
+
maxEditBytes: files.limits.maxWriteBytes,
|
|
106
|
+
maxEdits: workflow.limits.maxEdits,
|
|
107
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
108
|
+
});
|
|
109
|
+
},
|
|
77
110
|
});
|
|
111
|
+
return this.result(result);
|
|
112
|
+
}
|
|
78
113
|
const result = await workflow.reviseText({
|
|
79
114
|
draftId: source.id,
|
|
80
115
|
expectedSize: source.size,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-working-files.js","sourceRoot":"","sources":["../../src/workspace/storage-working-files.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { StorageError, isStorageError } from '../storage.error.js';\nimport { storageBytesStream, storageInteger } from '../core/storage-streams.js';\nimport { checkoutStorageCatalogText } from './storage-catalog-checkout.js';\nimport type {\n StorageFileCatalogCapability,\n StorageCatalogFile,\n StorageCatalogPath,\n StorageCatalogCommand,\n StorageCatalogPage,\n} from './storage-file-catalog.types.js';\nimport type {\n StorageFileDraft,\n StorageFileWorkflowCapability,\n StorageFileWorkflowOperation,\n StorageFileWorkflowPage,\n} from './storage-file-workflow.types.js';\n\nexport interface StorageWorkingFile extends StorageCatalogFile {\n readonly operation: 'created' | 'updated';\n readonly pending: true;\n}\nexport interface StorageWorkingFileReceipt {\n readonly path: string;\n readonly etag: string;\n readonly size: number;\n}\n\n/** A path-based editing view over durable checkpoints. Saved heads change only on commit. */\nexport class StorageWorkingFiles<Receipt extends StorageWorkingFileReceipt> {\n readonly catalog: StorageFileCatalogCapability<Receipt | StorageWorkingFile>;\n constructor(\n readonly files: StorageFileCatalogCapability<Receipt>,\n readonly workflow: StorageFileWorkflowCapability<Receipt>,\n ) {\n this.catalog = Object.freeze<\n StorageFileCatalogCapability<Receipt | StorageWorkingFile>\n >({\n ...files,\n list: (input) => this.page(input, 'list'),\n search: (input) => this.page(input, 'search'),\n stat: async (input) => {\n const draft = await this.draft(input);\n return draft && draft.status !== 'committed'\n ? this.receipt(draft)\n : files.stat(this.saved(input, draft));\n },\n readWindow: async (input) => {\n const draft = await this.draft(input);\n if (!draft || draft.status === 'committed')\n return files.readWindow(this.saved(input, draft));\n const page = await workflow.read({\n draftId: draft.id,\n offset: input.offset,\n signal: input.signal,\n });\n if (page.size !== draft.size) this.conflict();\n return {\n ...this.receipt(draft),\n content: page.content,\n offset: page.offset,\n nextOffset: page.nextOffset,\n totalBytes: page.size,\n };\n },\n searchContent: async (input) => {\n const draft = await this.draft(input);\n if (!draft || draft.status === 'committed')\n return files.searchContent(this.saved(input, draft));\n return workflow.searchText({\n draftId: draft.id,\n expectedSize: draft.size,\n query: input.query,\n offset: input.offset,\n signal: input.signal,\n });\n },\n write: (input) => this.write(input),\n edit: async (input) => {\n this.requireWrite();\n const changes =\n input.change.kind === 'batch' ? input.change.changes : [input.change];\n this.textLimit(\n changes\n .map((change) =>\n change.kind === 'append'\n ? change.text\n : change.oldText + change.newText,\n )\n .join(''),\n );\n const prior = await workflow.lookup({\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n let source: StorageFileDraft<Receipt> | null = prior?.sourceDraftId\n ? await workflow.read({\n draftId: prior.sourceDraftId,\n signal: input.signal,\n })\n : await this.draft(input);\n if (!source || (!prior && source.status === 'committed'))\n source = await checkoutStorageCatalogText(files, workflow, {\n ...this.saved(input, source),\n commandId: `checkout:${input.commandId}`,\n });\n const result = await workflow.reviseText({\n draftId: source.id,\n expectedSize: source.size,\n changes,\n requestIdentity: JSON.stringify([input.path, input.expectedEtag]),\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n // The workflow fingerprint includes the source, but the host also fences its public path.\n if (result.path !== input.path) this.conflict();\n return this.result(result);\n },\n });\n }\n\n async write(\n input: StorageCatalogCommand & { readonly content: string },\n ): Promise<Receipt | StorageWorkingFile> {\n this.requireWrite();\n this.textLimit(input.content);\n const prior = await this.workflow.lookup({\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n let source: StorageFileDraft<Receipt> | null = prior?.sourceDraftId\n ? await this.workflow.read({\n draftId: prior.sourceDraftId,\n signal: input.signal,\n })\n : null;\n let originalEtag = prior?.expectedEtag ?? undefined;\n if (!prior) {\n source = await this.draft(input);\n const saved = this.saved(input, source);\n if (input.expectedEtag === undefined) {\n if (source) this.conflict();\n try {\n await this.files.stat(input);\n this.conflict();\n } catch (error) {\n if (!isStorageError(error) || error.code !== 'NOT_FOUND') throw error;\n }\n } else if (!source || source.status === 'committed') {\n const file = await this.files.stat(saved);\n if (file.etag !== saved.expectedEtag) this.conflict();\n }\n if (source?.status === 'committed') source = null;\n originalEtag = source\n ? (source.expectedEtag ?? undefined)\n : saved.expectedEtag;\n }\n const bytes = new TextEncoder().encode(input.content);\n const result = await this.workflow.stageStream({\n path: input.path,\n text: true,\n idempotencyKey: input.commandId,\n expectedEtag: originalEtag,\n contentIdentity: createHash('sha256')\n .update(JSON.stringify([input.expectedEtag ?? null, input.content]))\n .digest('hex'),\n body: () => storageBytesStream(bytes),\n signal: input.signal,\n ...(source\n ? { sourceDraftId: source.id, expectedSize: source.size }\n : {}),\n });\n return this.result(result);\n }\n\n /** Resolve an exact candidate (including committed replay) or the unique unfinished leaf. */\n async draft(\n input: StorageCatalogPath,\n ): Promise<StorageFileDraft<Receipt> | null> {\n if (!this.files.allows('read')) this.denied();\n if (input.expectedEtag !== undefined) {\n try {\n const draft = await this.workflow.read({\n draftId: input.expectedEtag,\n signal: input.signal,\n });\n if (draft.path !== input.path || draft.status === 'cancelled')\n this.conflict();\n return draft;\n } catch (error) {\n if (!isStorageError(error) || error.code !== 'NOT_FOUND') throw error;\n return null;\n }\n }\n const matches = (await this.pending(input)).filter(\n (draft) => draft.path === input.path,\n );\n if (matches.length > 1)\n throw new StorageError(\n 'Several unfinished revisions exist. Read an exact listed ETag before editing.',\n { code: 'CONFLICT' },\n );\n return matches[0] ?? null;\n }\n\n /** Discovery derives from persisted lineage, so process restarts need no local registry. */\n async pending(\n input: StorageFileWorkflowOperation,\n ): Promise<StorageFileDraft<Receipt>[]> {\n if (!this.files.allows('read')) this.denied();\n const drafts: StorageFileDraft<Receipt>[] = [];\n let offset: number | null = 0;\n do {\n const page = await this.workflow.list({ offset, signal: input.signal });\n drafts.push(...page.items);\n if (page.nextOffset !== null && page.nextOffset <= offset)\n throw new StorageError('Invalid draft pagination.', {\n code: 'PROVIDER',\n });\n offset = page.nextOffset;\n } while (offset !== null);\n const predecessors = new Set(\n drafts.flatMap((draft) =>\n draft.status !== 'cancelled' && draft.sourceDraftId\n ? [draft.sourceDraftId]\n : [],\n ),\n );\n return drafts.filter(\n (draft) =>\n ['open', 'sealed'].includes(draft.status) &&\n !predecessors.has(draft.id),\n );\n }\n\n private async page(\n input: StorageCatalogPage & {\n directory?: string | undefined;\n query?: string;\n },\n mode: 'list' | 'search',\n ) {\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset', 0);\n const pending = await this.pending(input);\n const paths = new Set(pending.map((draft) => draft.path));\n const items: StorageCatalogFile[] = [];\n const savedByPath = new Map<string, StorageCatalogFile>();\n let cursor: number | null = 0;\n do {\n const page: StorageFileWorkflowPage<StorageCatalogFile> =\n mode === 'list'\n ? await this.files.list({ ...input, offset: cursor })\n : await this.files.search({\n ...input,\n query: input.query!,\n offset: cursor,\n });\n for (const file of page.items) savedByPath.set(file.path, file);\n items.push(...page.items.filter((file) => !paths.has(file.path)));\n if (page.nextOffset !== null && page.nextOffset <= cursor)\n throw new StorageError('Invalid catalog pagination.', {\n code: 'PROVIDER',\n });\n cursor = page.nextOffset;\n } while (cursor !== null);\n const directory = input.directory?.replace(/\\/$/u, '');\n items.push(\n ...pending\n .filter((draft) =>\n mode === 'search'\n ? draft.path.toLowerCase().includes(input.query!.toLowerCase())\n : !directory ||\n directory === '.' ||\n draft.path.startsWith(`${directory}/`),\n )\n .map((draft) => ({\n ...savedByPath.get(draft.path),\n ...this.receipt(draft),\n })),\n );\n items.sort(\n (a, b) => a.path.localeCompare(b.path) || a.etag.localeCompare(b.etag),\n );\n const next = offset + this.files.limits.maxPageSize;\n return {\n items: items.slice(offset, next),\n nextOffset: next < items.length ? next : null,\n };\n }\n private saved<T extends StorageCatalogPath>(\n input: T,\n draft: StorageFileDraft<Receipt> | null,\n ): T {\n if (draft?.status !== 'committed') return input;\n if (!draft.result || draft.result.path !== input.path) this.conflict();\n return { ...input, expectedEtag: draft.result.etag };\n }\n private result(\n draft: StorageFileDraft<Receipt>,\n ): Receipt | StorageWorkingFile {\n if (draft.status === 'cancelled') this.conflict();\n if (draft.status === 'committed') {\n if (!draft.result) this.conflict();\n return draft.result;\n }\n return this.receipt(draft);\n }\n private receipt(draft: StorageFileDraft<Receipt>): StorageWorkingFile {\n return {\n path: draft.path,\n fileId: draft.id,\n etag: draft.id,\n size: draft.size,\n contentType: draft.text ? 'text/plain' : 'application/octet-stream',\n operation: draft.expectedEtag === null ? 'created' : 'updated',\n pending: true,\n };\n }\n private textLimit(text: string) {\n if (/[\\uD800-\\uDFFF]/u.test(text))\n throw new StorageError('Text must be well-formed UTF-8.', {\n code: 'INVALID_ARGUMENT',\n });\n if (\n new TextEncoder().encode(text).byteLength >\n this.files.limits.maxWriteBytes\n )\n throw new StorageError('Write exceeds the per-call text limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n }\n private requireWrite() {\n if (!this.files.allows('write')) this.denied();\n }\n private denied(): never {\n throw new StorageError('Working file operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n }\n private conflict(): never {\n throw new StorageError(\n 'The working file revision changed. Read the current file before editing.',\n { code: 'CONFLICT' },\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage-working-files.js","sourceRoot":"","sources":["../../src/workspace/storage-working-files.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { StorageError, isStorageError } from '../storage.error.js';\nimport { storageBytesStream, storageInteger } from '../core/storage-streams.js';\nimport { editStorageTextStream } from '../core/storage-text-stream-edit.js';\nimport type {\n StorageFileCatalogCapability,\n StorageCatalogFile,\n StorageCatalogPath,\n StorageCatalogCommand,\n StorageCatalogPage,\n} from './storage-file-catalog.types.js';\nimport type {\n StorageFileDraft,\n StorageFileWorkflowCapability,\n StorageFileWorkflowOperation,\n StorageFileWorkflowPage,\n} from './storage-file-workflow.types.js';\n\nexport interface StorageWorkingFile extends StorageCatalogFile {\n readonly operation: 'created' | 'updated';\n readonly pending: true;\n}\nexport interface StorageWorkingFileReceipt {\n readonly path: string;\n readonly etag: string;\n readonly size: number;\n}\n\n/** A path-based editing view over durable checkpoints. Saved heads change only on commit. */\nexport class StorageWorkingFiles<Receipt extends StorageWorkingFileReceipt> {\n readonly catalog: StorageFileCatalogCapability<Receipt | StorageWorkingFile>;\n constructor(\n readonly files: StorageFileCatalogCapability<Receipt>,\n readonly workflow: StorageFileWorkflowCapability<Receipt>,\n ) {\n this.catalog = Object.freeze<\n StorageFileCatalogCapability<Receipt | StorageWorkingFile>\n >({\n ...files,\n list: (input) => this.page(input, 'list'),\n search: (input) => this.page(input, 'search'),\n stat: async (input) => {\n const draft = await this.draft(input);\n return draft && draft.status !== 'committed'\n ? this.receipt(draft)\n : files.stat(this.saved(input, draft));\n },\n readWindow: async (input) => {\n const draft = await this.draft(input);\n if (!draft || draft.status === 'committed')\n return files.readWindow(this.saved(input, draft));\n const page = await workflow.read({\n draftId: draft.id,\n offset: input.offset,\n signal: input.signal,\n });\n if (page.size !== draft.size) this.conflict();\n return {\n ...this.receipt(draft),\n content: page.content,\n offset: page.offset,\n nextOffset: page.nextOffset,\n totalBytes: page.size,\n };\n },\n readStream: async (input) => {\n const draft = await this.draft(input);\n if (!draft || draft.status === 'committed')\n return files.readStream(this.saved(input, draft));\n const stream = await workflow.readStream({\n draftId: draft.id,\n expectedSize: draft.size,\n start: input.start,\n end: input.end,\n signal: input.signal,\n });\n return { ...this.receipt(draft), body: stream.body };\n },\n searchContent: async (input) => {\n const draft = await this.draft(input);\n if (!draft || draft.status === 'committed')\n return files.searchContent(this.saved(input, draft));\n return workflow.searchText({\n draftId: draft.id,\n expectedSize: draft.size,\n query: input.query,\n offset: input.offset,\n signal: input.signal,\n });\n },\n write: (input) => this.write(input),\n edit: async (input) => {\n this.requireWrite();\n const changes =\n input.change.kind === 'batch' ? input.change.changes : [input.change];\n this.textLimit(\n changes\n .map((change) =>\n change.kind === 'append'\n ? change.text\n : change.oldText + change.newText,\n )\n .join(''),\n );\n const prior = await workflow.lookup({\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n const source: StorageFileDraft<Receipt> | null = prior?.sourceDraftId\n ? await workflow.read({\n draftId: prior.sourceDraftId,\n signal: input.signal,\n })\n : await this.draft(input);\n if (!source || (!prior && source.status === 'committed')) {\n const saved = this.saved(input, source);\n const result = await workflow.stageStream({\n path: input.path,\n expectedEtag: saved.expectedEtag,\n text: true,\n signal: input.signal,\n idempotencyKey: input.commandId,\n contentIdentity: createHash('sha256')\n .update(\n JSON.stringify([\n 'catalog-edit',\n input.path,\n input.expectedEtag,\n changes,\n ]),\n )\n .digest('hex'),\n body: async () => {\n const stream = await files.readStream(saved);\n return editStorageTextStream(stream.body, changes, {\n maxEditBytes: files.limits.maxWriteBytes,\n maxEdits: workflow.limits.maxEdits,\n ...(input.signal ? { signal: input.signal } : {}),\n });\n },\n });\n return this.result(result);\n }\n const result = await workflow.reviseText({\n draftId: source.id,\n expectedSize: source.size,\n changes,\n requestIdentity: JSON.stringify([input.path, input.expectedEtag]),\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n // The workflow fingerprint includes the source, but the host also fences its public path.\n if (result.path !== input.path) this.conflict();\n return this.result(result);\n },\n });\n }\n\n async write(\n input: StorageCatalogCommand & { readonly content: string },\n ): Promise<Receipt | StorageWorkingFile> {\n this.requireWrite();\n this.textLimit(input.content);\n const prior = await this.workflow.lookup({\n idempotencyKey: input.commandId,\n signal: input.signal,\n });\n let source: StorageFileDraft<Receipt> | null = prior?.sourceDraftId\n ? await this.workflow.read({\n draftId: prior.sourceDraftId,\n signal: input.signal,\n })\n : null;\n let originalEtag = prior?.expectedEtag ?? undefined;\n if (!prior) {\n source = await this.draft(input);\n const saved = this.saved(input, source);\n if (input.expectedEtag === undefined) {\n if (source) this.conflict();\n try {\n await this.files.stat(input);\n this.conflict();\n } catch (error) {\n if (!isStorageError(error) || error.code !== 'NOT_FOUND') throw error;\n }\n } else if (!source || source.status === 'committed') {\n const file = await this.files.stat(saved);\n if (file.etag !== saved.expectedEtag) this.conflict();\n }\n if (source?.status === 'committed') source = null;\n originalEtag = source\n ? (source.expectedEtag ?? undefined)\n : saved.expectedEtag;\n }\n const bytes = new TextEncoder().encode(input.content);\n const result = await this.workflow.stageStream({\n path: input.path,\n text: true,\n idempotencyKey: input.commandId,\n expectedEtag: originalEtag,\n contentIdentity: createHash('sha256')\n .update(JSON.stringify([input.expectedEtag ?? null, input.content]))\n .digest('hex'),\n body: () => storageBytesStream(bytes),\n signal: input.signal,\n ...(source\n ? { sourceDraftId: source.id, expectedSize: source.size }\n : {}),\n });\n return this.result(result);\n }\n\n /** Resolve an exact candidate (including committed replay) or the unique unfinished leaf. */\n async draft(\n input: StorageCatalogPath,\n ): Promise<StorageFileDraft<Receipt> | null> {\n if (!this.files.allows('read')) this.denied();\n if (input.expectedEtag !== undefined) {\n try {\n const draft = await this.workflow.read({\n draftId: input.expectedEtag,\n signal: input.signal,\n });\n if (draft.path !== input.path || draft.status === 'cancelled')\n this.conflict();\n return draft;\n } catch (error) {\n if (!isStorageError(error) || error.code !== 'NOT_FOUND') throw error;\n return null;\n }\n }\n const matches = (await this.pending(input)).filter(\n (draft) => draft.path === input.path,\n );\n if (matches.length > 1)\n throw new StorageError(\n 'Several unfinished revisions exist. Read an exact listed ETag before editing.',\n { code: 'CONFLICT' },\n );\n return matches[0] ?? null;\n }\n\n /** Discovery derives from persisted lineage, so process restarts need no local registry. */\n async pending(\n input: StorageFileWorkflowOperation,\n ): Promise<StorageFileDraft<Receipt>[]> {\n if (!this.files.allows('read')) this.denied();\n const drafts: StorageFileDraft<Receipt>[] = [];\n let offset: number | null = 0;\n do {\n const page = await this.workflow.list({ offset, signal: input.signal });\n drafts.push(...page.items);\n if (page.nextOffset !== null && page.nextOffset <= offset)\n throw new StorageError('Invalid draft pagination.', {\n code: 'PROVIDER',\n });\n offset = page.nextOffset;\n } while (offset !== null);\n const predecessors = new Set(\n drafts.flatMap((draft) =>\n draft.status !== 'cancelled' && draft.sourceDraftId\n ? [draft.sourceDraftId]\n : [],\n ),\n );\n return drafts.filter(\n (draft) =>\n ['open', 'sealed'].includes(draft.status) &&\n !predecessors.has(draft.id),\n );\n }\n\n private async page(\n input: StorageCatalogPage & {\n directory?: string | undefined;\n query?: string;\n },\n mode: 'list' | 'search',\n ) {\n const offset = input.offset ?? 0;\n storageInteger(offset, 'offset', 0);\n const pending = await this.pending(input);\n const paths = new Set(pending.map((draft) => draft.path));\n const items: StorageCatalogFile[] = [];\n const savedByPath = new Map<string, StorageCatalogFile>();\n let cursor: number | null = 0;\n do {\n const page: StorageFileWorkflowPage<StorageCatalogFile> =\n mode === 'list'\n ? await this.files.list({ ...input, offset: cursor })\n : await this.files.search({\n ...input,\n query: input.query!,\n offset: cursor,\n });\n for (const file of page.items) savedByPath.set(file.path, file);\n items.push(...page.items.filter((file) => !paths.has(file.path)));\n if (page.nextOffset !== null && page.nextOffset <= cursor)\n throw new StorageError('Invalid catalog pagination.', {\n code: 'PROVIDER',\n });\n cursor = page.nextOffset;\n } while (cursor !== null);\n const directory = input.directory?.replace(/\\/$/u, '');\n items.push(\n ...pending\n .filter((draft) =>\n mode === 'search'\n ? draft.path.toLowerCase().includes(input.query!.toLowerCase())\n : !directory ||\n directory === '.' ||\n draft.path.startsWith(`${directory}/`),\n )\n .map((draft) => ({\n ...savedByPath.get(draft.path),\n ...this.receipt(draft),\n })),\n );\n items.sort(\n (a, b) => a.path.localeCompare(b.path) || a.etag.localeCompare(b.etag),\n );\n const next = offset + this.files.limits.maxPageSize;\n return {\n items: items.slice(offset, next),\n nextOffset: next < items.length ? next : null,\n };\n }\n private saved<T extends StorageCatalogPath>(\n input: T,\n draft: StorageFileDraft<Receipt> | null,\n ): T {\n if (draft?.status !== 'committed') return input;\n if (!draft.result || draft.result.path !== input.path) this.conflict();\n return { ...input, expectedEtag: draft.result.etag };\n }\n private result(\n draft: StorageFileDraft<Receipt>,\n ): Receipt | StorageWorkingFile {\n if (draft.status === 'cancelled') this.conflict();\n if (draft.status === 'committed') {\n if (!draft.result) this.conflict();\n return draft.result;\n }\n return this.receipt(draft);\n }\n private receipt(draft: StorageFileDraft<Receipt>): StorageWorkingFile {\n return {\n path: draft.path,\n fileId: draft.id,\n etag: draft.id,\n size: draft.size,\n contentType: draft.text ? 'text/plain' : 'application/octet-stream',\n operation: draft.expectedEtag === null ? 'created' : 'updated',\n pending: true,\n };\n }\n private textLimit(text: string) {\n if (/[\\uD800-\\uDFFF]/u.test(text))\n throw new StorageError('Text must be well-formed UTF-8.', {\n code: 'INVALID_ARGUMENT',\n });\n if (\n new TextEncoder().encode(text).byteLength >\n this.files.limits.maxWriteBytes\n )\n throw new StorageError('Write exceeds the per-call text limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n }\n private requireWrite() {\n if (!this.files.allows('write')) this.denied();\n }\n private denied(): never {\n throw new StorageError('Working file operation is not permitted.', {\n code: 'UNAUTHORIZED',\n });\n }\n private conflict(): never {\n throw new StorageError(\n 'The working file revision changed. Read the current file before editing.',\n { code: 'CONFLICT' },\n );\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestm/storage",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.19",
|
|
4
4
|
"description": "Framework-neutral storage clients, capability-scoped agent workspaces, NestJS 12 integration, and guarded HTTP access.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kauan Guesser",
|