@nestm/storage 0.1.0-alpha.14 → 0.1.0-alpha.16
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 +12 -0
- package/README.md +40 -0
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts +16 -2
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts.map +1 -1
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.js +99 -11
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/storage-text-edit.d.ts +38 -0
- package/dist/core/storage-text-edit.d.ts.map +1 -0
- package/dist/core/storage-text-edit.js +86 -0
- package/dist/core/storage-text-edit.js.map +1 -0
- package/dist/core/storage-text.d.ts +1 -12
- package/dist/core/storage-text.d.ts.map +1 -1
- package/dist/core/storage-text.js +1 -30
- package/dist/core/storage-text.js.map +1 -1
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +1 -0
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/storage-catalog-checkout.d.ts +7 -0
- package/dist/workspace/storage-catalog-checkout.d.ts.map +1 -0
- package/dist/workspace/storage-catalog-checkout.js +46 -0
- package/dist/workspace/storage-catalog-checkout.js.map +1 -0
- package/dist/workspace/storage-file-workflow.d.ts.map +1 -1
- package/dist/workspace/storage-file-workflow.js +116 -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 +41 -5
- package/dist/workspace/storage-file-workflow.protection.js.map +1 -1
- package/dist/workspace/storage-file-workflow.types.d.ts +24 -0
- package/dist/workspace/storage-file-workflow.types.d.ts.map +1 -1
- package/dist/workspace/storage-file-workflow.types.js +2 -0
- package/dist/workspace/storage-file-workflow.types.js.map +1 -1
- package/dist/workspace/storage-text-draft.d.ts +20 -0
- package/dist/workspace/storage-text-draft.d.ts.map +1 -0
- package/dist/workspace/storage-text-draft.js +80 -0
- package/dist/workspace/storage-text-draft.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-text-edit.js","sourceRoot":"","sources":["../../src/core/storage-text-edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA4BtD,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IAC9C,UAAU,CAA4B;IAC/C,YAAY,UAAqC;QAC/C,KAAK,CACH,wEAAwE,EACxE,EAAE,IAAI,EAAE,UAAU,EAAE,CACrB,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,kFAAkF;AAClF,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,KAAa;IAEb,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,CAAC;IACrC,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAE,KAAK,EAAE,CAAC;IAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvC,OAAO;QACL,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU;QACnD,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QACxC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,CAAC;aAChD,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aACb,IAAI,CAAC,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,IAAqB,EACrB,OAAkE;IAElE,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9D,cAAc,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;QACjE,MAAM,IAAI,YAAY,CAAC,yCAAyC,EAAE;YAChE,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;IACL,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE;QAChC,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,MAAM,IAAI,YAAY,CAAC,iCAAiC,EAAE;gBACxD,IAAI,EAAE,kBAAkB;aACzB,CAAC,CAAC;IACP,CAAC,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,MAAM,GACV,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9D,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC5D,MAAM,MAAM,GACV,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;oBACzB,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,KAAK,GAAG,CAAC;wBACT,CAAC,CAAC,gBAAgB;wBAClB,CAAC,CAAC,kBAAkB,CAAC;gBAC3B,8EAA8E;gBAC9E,MAAM,MAAM,GACV,MAAM,CAAC,OAAO;qBACX,KAAK,CAAC,IAAI,CAAC;qBACX,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;oBACvC,EAAE,IAAI,EAAE;qBACP,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;gBACxB,MAAM,IAAI,GACR,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjE,MAAM,IAAI,uBAAuB,CAAC;oBAChC,SAAS;oBACT,MAAM;oBACN,QAAQ,EAAE,CAAC,MAAM,KAAK,kBAAkB;wBACtC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC;wBACjB,CAAC,CAAC,CAAC,IAAI,CAAC,CACT,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;iBAC/C,CAAC,CAAC;YACL,CAAC;YACD,OAAO;gBACL,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;oBACvB,MAAM,CAAC,OAAO;oBACd,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ;YACjE,MAAM,IAAI,YAAY,CAAC,yCAAyC,EAAE;gBAChE,IAAI,EAAE,gBAAgB;aACvB,CAAC,CAAC;IACP,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { StorageError } from '../storage.error.js';\nimport { storageInteger } from './storage-streams.js';\n\nexport type StorageTextChange =\n | { readonly kind: 'append'; readonly text: string }\n | {\n readonly kind: 'replace';\n readonly oldText: string;\n readonly newText: string;\n };\nexport type StorageTextEdit =\n | StorageTextChange\n | {\n readonly kind: 'batch';\n readonly changes: readonly StorageTextChange[];\n };\nexport interface StorageTextContext {\n /** UTF-8 byte position and one-based UTF-16 line/column of the snippet start. */\n readonly offset: number;\n readonly line: number;\n readonly column: number;\n readonly text: string;\n}\nexport interface StorageTextEditDiagnostic {\n readonly editIndex: number;\n readonly reason: 'empty_target' | 'missing_target' | 'ambiguous_target';\n /** Bounded source data from the intermediate buffer; no edits were persisted. */\n readonly contexts: readonly StorageTextContext[];\n}\nexport class StorageTextEditConflict extends StorageError {\n readonly diagnostic: StorageTextEditDiagnostic;\n constructor(diagnostic: StorageTextEditDiagnostic) {\n super(\n 'The replacement target must match exactly once. No edits were applied.',\n { code: 'CONFLICT' },\n );\n this.diagnostic = diagnostic;\n }\n}\n\n/** A bounded source window. Coordinates count UTF-16 columns, like JS parsers. */\nexport function storageTextContext(\n content: string,\n index: number,\n): StorageTextContext {\n storageInteger(index, 'index');\n index = Math.min(index, content.length);\n let start = Math.max(0, index - 100);\n if (/[\\uDC00-\\uDFFF]/u.test(content.charAt(start))) start++;\n const before = content.slice(0, start);\n return {\n offset: new TextEncoder().encode(before).byteLength,\n line: before.split('\\n').length,\n column: start - before.lastIndexOf('\\n'),\n text: Array.from(content.slice(start, start + 640))\n .slice(0, 320)\n .join(''),\n };\n}\n\n/** Sequential exact edits in memory. The host persists only the complete result. */\nexport function applyStorageTextEdit(\n content: string,\n edit: StorageTextEdit,\n options: { readonly maxBytes: number; readonly maxEdits?: number },\n): string {\n storageInteger(options.maxBytes, 'maxBytes');\n const changes = edit.kind === 'batch' ? edit.changes : [edit];\n storageInteger(options.maxEdits ?? 64, 'maxEdits', 1);\n if (changes.length < 1 || changes.length > (options.maxEdits ?? 64))\n throw new StorageError('Edit batch exceeds the operation limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n const validate = (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 };\n validate(content);\n for (const [editIndex, change] of changes.entries()) {\n if (change.kind === 'append') {\n validate(change.text);\n content += change.text;\n } else {\n validate(change.oldText);\n validate(change.newText);\n const first = content.indexOf(change.oldText);\n const second =\n first < 0 ? -1 : content.indexOf(change.oldText, first + 1);\n if (change.oldText.length === 0 || first < 0 || second >= 0) {\n const reason =\n change.oldText.length === 0\n ? 'empty_target'\n : first < 0\n ? 'missing_target'\n : 'ambiguous_target';\n // An anchor helps locate stale whitespace/context; it never relaxes matching.\n const anchor =\n change.oldText\n .split('\\n')\n .find((line) => line.trim().length > 0)\n ?.trim()\n .slice(0, 80) ?? '';\n const near =\n anchor.length === 0 ? 0 : Math.max(0, content.indexOf(anchor));\n throw new StorageTextEditConflict({\n editIndex,\n reason,\n contexts: (reason === 'ambiguous_target'\n ? [first, second]\n : [near]\n ).map((at) => storageTextContext(content, at)),\n });\n }\n content =\n content.slice(0, first) +\n change.newText +\n content.slice(first + change.oldText.length);\n }\n if (new TextEncoder().encode(content).byteLength > options.maxBytes)\n throw new StorageError('Edited content exceeds the byte budget.', {\n code: 'LIMIT_EXCEEDED',\n });\n }\n return content;\n}\n"]}
|
|
@@ -18,16 +18,5 @@ export interface StorageTextSearchResult {
|
|
|
18
18
|
}
|
|
19
19
|
/** Literal, non-overlapping matches. Continuations retain cross-window candidates. */
|
|
20
20
|
export declare function searchStorageText(read: StorageRangeReader, options: StorageTextSearchOptions): Promise<StorageTextSearchResult>;
|
|
21
|
-
export type StorageTextEdit
|
|
22
|
-
readonly kind: 'append';
|
|
23
|
-
readonly text: string;
|
|
24
|
-
} | {
|
|
25
|
-
readonly kind: 'replace';
|
|
26
|
-
readonly oldText: string;
|
|
27
|
-
readonly newText: string;
|
|
28
|
-
};
|
|
29
|
-
/** Whole-text operation; callers must also bound the original buffered read. */
|
|
30
|
-
export declare function applyStorageTextEdit(content: string, change: StorageTextEdit, options: {
|
|
31
|
-
readonly maxBytes: number;
|
|
32
|
-
}): string;
|
|
21
|
+
export { applyStorageTextEdit, type StorageTextEdit, } from './storage-text-edit.js';
|
|
33
22
|
//# sourceMappingURL=storage-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-text.d.ts","sourceRoot":"","sources":["../../src/core/storage-text.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C;AACD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,sFAAsF;AACtF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAoElC;AAED,
|
|
1
|
+
{"version":3,"file":"storage-text.d.ts","sourceRoot":"","sources":["../../src/core/storage-text.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C;AACD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,sFAAsF;AACtF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAoElC;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC"}
|
|
@@ -65,34 +65,5 @@ export async function searchStorageText(read, options) {
|
|
|
65
65
|
}
|
|
66
66
|
return { matches, nextOffset: cursor < size ? pendingOffset : null };
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
export function applyStorageTextEdit(content, change, options) {
|
|
70
|
-
storageInteger(options.maxBytes, 'maxBytes');
|
|
71
|
-
const strings = change.kind === 'append'
|
|
72
|
-
? [content, change.text]
|
|
73
|
-
: [content, change.oldText, change.newText];
|
|
74
|
-
if (strings.some((value) => /[\uD800-\uDFFF]/u.test(value)))
|
|
75
|
-
throw new StorageError('Text must be well-formed UTF-8.', {
|
|
76
|
-
code: 'INVALID_ARGUMENT',
|
|
77
|
-
});
|
|
78
|
-
let result;
|
|
79
|
-
if (change.kind === 'append')
|
|
80
|
-
result = content + change.text;
|
|
81
|
-
else {
|
|
82
|
-
const first = content.indexOf(change.oldText);
|
|
83
|
-
if (change.oldText.length === 0 ||
|
|
84
|
-
first < 0 ||
|
|
85
|
-
content.indexOf(change.oldText, first + 1) >= 0)
|
|
86
|
-
throw new StorageError('The replacement target must match exactly once.', { code: 'CONFLICT' });
|
|
87
|
-
result =
|
|
88
|
-
content.slice(0, first) +
|
|
89
|
-
change.newText +
|
|
90
|
-
content.slice(first + change.oldText.length);
|
|
91
|
-
}
|
|
92
|
-
if (new TextEncoder().encode(result).byteLength > options.maxBytes)
|
|
93
|
-
throw new StorageError('Edited content exceeds the byte budget.', {
|
|
94
|
-
code: 'LIMIT_EXCEEDED',
|
|
95
|
-
});
|
|
96
|
-
return result;
|
|
97
|
-
}
|
|
68
|
+
export { applyStorageTextEdit, } from './storage-text-edit.js';
|
|
98
69
|
//# sourceMappingURL=storage-text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-text.js","sourceRoot":"","sources":["../../src/core/storage-text.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"storage-text.js","sourceRoot":"","sources":["../../src/core/storage-text.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageError } from '../storage.error.js';\nimport {\n readStorageTextWindow,\n storageInteger,\n type StorageRangeReader,\n} from './storage-streams.js';\n\nexport interface StorageTextSearchOptions {\n readonly size: number;\n readonly query: string;\n readonly offset?: number | undefined;\n readonly maxScanBytes: number;\n readonly maxMatches: number;\n readonly maxSnippetCharacters: number;\n readonly maxReadBytes: number;\n readonly signal?: AbortSignal | undefined;\n}\nexport interface StorageTextSearchResult {\n readonly matches: readonly {\n readonly offset: number;\n readonly text: string;\n }[];\n readonly nextOffset: number | null;\n}\n\n/** Literal, non-overlapping matches. Continuations retain cross-window candidates. */\nexport async function searchStorageText(\n read: StorageRangeReader,\n options: StorageTextSearchOptions,\n): Promise<StorageTextSearchResult> {\n const { query, size, signal } = options;\n const encode = (text: string) => new TextEncoder().encode(text).byteLength;\n if (\n query.length === 0 ||\n query.length > 256 ||\n /[\\uD800-\\uDFFF]/u.test(query)\n )\n throw new StorageError('Query must contain 1–256 well-formed characters.', {\n code: 'INVALID_ARGUMENT',\n });\n storageInteger(size, 'size');\n storageInteger(options.maxReadBytes, 'maxReadBytes', 4);\n storageInteger(options.maxScanBytes, 'maxScanBytes', encode(query) + 4);\n storageInteger(options.maxMatches, 'maxMatches', 1);\n storageInteger(options.maxSnippetCharacters, 'maxSnippetCharacters', 1);\n let cursor = options.offset ?? 0;\n storageInteger(cursor, 'offset');\n if (cursor > size)\n throw new StorageError('Offset exceeds body size.', {\n code: 'INVALID_ARGUMENT',\n });\n let pending = '';\n let pendingOffset = cursor;\n let scanned = 0;\n const matches: { offset: number; text: string }[] = [];\n signal?.throwIfAborted();\n while (cursor < size && options.maxScanBytes - scanned >= 4) {\n const maxBytes = Math.min(\n options.maxReadBytes,\n options.maxScanBytes - scanned,\n );\n const page = await readStorageTextWindow(read, {\n size,\n offset: cursor,\n maxBytes,\n signal,\n });\n scanned += Math.min(maxBytes, size - cursor);\n const text = pending + page.content;\n const safeEnd =\n page.nextOffset === null\n ? text.length\n : Math.max(0, text.length - query.length + 1);\n let at = 0;\n for (;;) {\n const found = text.indexOf(query, at);\n if (found < 0 || found >= safeEnd) break;\n matches.push({\n offset: pendingOffset + encode(text.slice(0, found)),\n text: Array.from(text.slice(found))\n .slice(0, options.maxSnippetCharacters)\n .join(''),\n });\n at = found + query.length;\n if (matches.length === options.maxMatches) {\n const next = pendingOffset + encode(text.slice(0, at));\n return { matches, nextOffset: next < size ? next : null };\n }\n }\n let consumed = Math.max(at, safeEnd);\n if (consumed > 0 && /[\\uDC00-\\uDFFF]/u.test(text.charAt(consumed)))\n consumed--;\n pendingOffset += encode(text.slice(0, consumed));\n pending = text.slice(consumed);\n cursor = page.nextOffset ?? size;\n }\n return { matches, nextOffset: cursor < size ? pendingOffset : null };\n}\n\nexport {\n applyStorageTextEdit,\n type StorageTextEdit,\n} from './storage-text-edit.js';\n"]}
|
|
@@ -7,4 +7,5 @@ export { protectStorageFileWorkflowWorkspace, protectStorageFileWorkflowOperatio
|
|
|
7
7
|
export { Aes256GcmStorageWorkspaceCursorCodec, STORAGE_WORKSPACE_CURSOR_VERSION, STORAGE_WORKSPACE_MAX_CURSOR_BYTES, type Aes256GcmStorageWorkspaceCursorCodecOptions, type StorageWorkspaceCursorCodec, type StorageWorkspaceCursorConfiguration, type StorageWorkspaceCursorEncodeOptions, } from './storage-workspace.cursor.js';
|
|
8
8
|
export { createStorageWorkspace, mountStorageWorkspace, } from './storage-workspace.js';
|
|
9
9
|
export { DEFAULT_STORAGE_WORKSPACE_LIMITS, STORAGE_WORKSPACE_PERMISSIONS, type MountStorageWorkspaceOptions, type StorageWorkspaceBody, type StorageWorkspaceByteFile, type StorageWorkspaceCopyOptions, type StorageWorkspaceDeleteOptions, type StorageWorkspace, type StorageWorkspaceDirectory, type StorageWorkspaceEntry, type StorageWorkspaceFile, type StorageWorkspaceLimits, type StorageWorkspaceListOptions, type StorageWorkspaceMountOptions, type StorageWorkspaceMutationOptions, type StorageWorkspaceOverwriteOptions, type StorageWorkspacePage, type StorageWorkspacePermission, type StorageWorkspaceReadOptions, type StorageWorkspaceSearchMatch, type StorageWorkspaceSearchOptions, type StorageWorkspaceTextFile, type StorageWorkspaceUnconditionalDeleteOptions, type StorageWorkspaceWriteOptions, } from './storage-workspace.types.js';
|
|
10
|
+
export { checkoutStorageCatalogText } from './storage-catalog-checkout.js';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AACxF,mBAAmB,kCAAkC,CAAC;AACtD,mBAAmB,iCAAiC,CAAC;AACrD,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,0CAA0C,GAChD,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,EAClC,KAAK,2CAA2C,EAChD,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,mCAAmC,GACzC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,0CAA0C,EAC/C,KAAK,4BAA4B,GAClC,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AACxF,mBAAmB,kCAAkC,CAAC;AACtD,mBAAmB,iCAAiC,CAAC;AACrD,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,0CAA0C,GAChD,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,EAClC,KAAK,2CAA2C,EAChD,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,mCAAmC,GACzC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,0CAA0C,EAC/C,KAAK,4BAA4B,GAClC,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC"}
|
package/dist/workspace/index.js
CHANGED
|
@@ -5,4 +5,5 @@ export { protectStorageFileWorkflowWorkspace, protectStorageFileWorkflowOperatio
|
|
|
5
5
|
export { Aes256GcmStorageWorkspaceCursorCodec, STORAGE_WORKSPACE_CURSOR_VERSION, STORAGE_WORKSPACE_MAX_CURSOR_BYTES, } from './storage-workspace.cursor.js';
|
|
6
6
|
export { createStorageWorkspace, mountStorageWorkspace, } from './storage-workspace.js';
|
|
7
7
|
export { DEFAULT_STORAGE_WORKSPACE_LIMITS, STORAGE_WORKSPACE_PERMISSIONS, } from './storage-workspace.types.js';
|
|
8
|
+
export { checkoutStorageCatalogText } from './storage-catalog-checkout.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AAGxF,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,GAItB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,GAKnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAuB9B,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n StorageWorkspaceError,\n isStorageWorkspaceError,\n} from './storage-workspace.error.js';\nexport { StorageFileWorkflow } from './storage-file-workflow.js';\nexport { DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS } from './storage-file-workflow.types.js';\nexport type * from './storage-file-workflow.types.js';\nexport type * from './storage-file-catalog.types.js';\nexport {\n protectStorageFileWorkflowWorkspace,\n protectStorageFileWorkflowOperation,\n getStorageFileWorkflow,\n getStorageFileCatalog,\n type StorageFileWorkflowProtection,\n type StorageFileWorkflowWorkspace,\n type ProtectStorageFileWorkflowWorkspaceOptions,\n} from './storage-file-workflow.protection.js';\nexport {\n Aes256GcmStorageWorkspaceCursorCodec,\n STORAGE_WORKSPACE_CURSOR_VERSION,\n STORAGE_WORKSPACE_MAX_CURSOR_BYTES,\n type Aes256GcmStorageWorkspaceCursorCodecOptions,\n type StorageWorkspaceCursorCodec,\n type StorageWorkspaceCursorConfiguration,\n type StorageWorkspaceCursorEncodeOptions,\n} from './storage-workspace.cursor.js';\nexport {\n createStorageWorkspace,\n mountStorageWorkspace,\n} from './storage-workspace.js';\nexport {\n DEFAULT_STORAGE_WORKSPACE_LIMITS,\n STORAGE_WORKSPACE_PERMISSIONS,\n type MountStorageWorkspaceOptions,\n type StorageWorkspaceBody,\n type StorageWorkspaceByteFile,\n type StorageWorkspaceCopyOptions,\n type StorageWorkspaceDeleteOptions,\n type StorageWorkspace,\n type StorageWorkspaceDirectory,\n type StorageWorkspaceEntry,\n type StorageWorkspaceFile,\n type StorageWorkspaceLimits,\n type StorageWorkspaceListOptions,\n type StorageWorkspaceMountOptions,\n type StorageWorkspaceMutationOptions,\n type StorageWorkspaceOverwriteOptions,\n type StorageWorkspacePage,\n type StorageWorkspacePermission,\n type StorageWorkspaceReadOptions,\n type StorageWorkspaceSearchMatch,\n type StorageWorkspaceSearchOptions,\n type StorageWorkspaceTextFile,\n type StorageWorkspaceUnconditionalDeleteOptions,\n type StorageWorkspaceWriteOptions,\n} from './storage-workspace.types.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AAGxF,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,GAItB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,GAKnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAuB9B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC","sourcesContent":["export {\n StorageWorkspaceError,\n isStorageWorkspaceError,\n} from './storage-workspace.error.js';\nexport { StorageFileWorkflow } from './storage-file-workflow.js';\nexport { DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS } from './storage-file-workflow.types.js';\nexport type * from './storage-file-workflow.types.js';\nexport type * from './storage-file-catalog.types.js';\nexport {\n protectStorageFileWorkflowWorkspace,\n protectStorageFileWorkflowOperation,\n getStorageFileWorkflow,\n getStorageFileCatalog,\n type StorageFileWorkflowProtection,\n type StorageFileWorkflowWorkspace,\n type ProtectStorageFileWorkflowWorkspaceOptions,\n} from './storage-file-workflow.protection.js';\nexport {\n Aes256GcmStorageWorkspaceCursorCodec,\n STORAGE_WORKSPACE_CURSOR_VERSION,\n STORAGE_WORKSPACE_MAX_CURSOR_BYTES,\n type Aes256GcmStorageWorkspaceCursorCodecOptions,\n type StorageWorkspaceCursorCodec,\n type StorageWorkspaceCursorConfiguration,\n type StorageWorkspaceCursorEncodeOptions,\n} from './storage-workspace.cursor.js';\nexport {\n createStorageWorkspace,\n mountStorageWorkspace,\n} from './storage-workspace.js';\nexport {\n DEFAULT_STORAGE_WORKSPACE_LIMITS,\n STORAGE_WORKSPACE_PERMISSIONS,\n type MountStorageWorkspaceOptions,\n type StorageWorkspaceBody,\n type StorageWorkspaceByteFile,\n type StorageWorkspaceCopyOptions,\n type StorageWorkspaceDeleteOptions,\n type StorageWorkspace,\n type StorageWorkspaceDirectory,\n type StorageWorkspaceEntry,\n type StorageWorkspaceFile,\n type StorageWorkspaceLimits,\n type StorageWorkspaceListOptions,\n type StorageWorkspaceMountOptions,\n type StorageWorkspaceMutationOptions,\n type StorageWorkspaceOverwriteOptions,\n type StorageWorkspacePage,\n type StorageWorkspacePermission,\n type StorageWorkspaceReadOptions,\n type StorageWorkspaceSearchMatch,\n type StorageWorkspaceSearchOptions,\n type StorageWorkspaceTextFile,\n type StorageWorkspaceUnconditionalDeleteOptions,\n type StorageWorkspaceWriteOptions,\n} from './storage-workspace.types.js';\n\nexport { checkoutStorageCatalogText } from './storage-catalog-checkout.js';\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StorageFileCatalogCapability, StorageCatalogCommand } from './storage-file-catalog.types.js';
|
|
2
|
+
import type { StorageFileWorkflowCapability } from './storage-file-workflow.types.js';
|
|
3
|
+
/** Bounded, exact-revision catalog read into a sealed text checkpoint. */
|
|
4
|
+
export declare function checkoutStorageCatalogText<Receipt>(catalog: StorageFileCatalogCapability<Receipt>, workflow: StorageFileWorkflowCapability<Receipt>, input: StorageCatalogCommand & {
|
|
5
|
+
readonly expectedEtag: string;
|
|
6
|
+
}): Promise<import("./storage-file-workflow.types.js").StorageFileDraft<Receipt>>;
|
|
7
|
+
//# sourceMappingURL=storage-catalog-checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-catalog-checkout.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAEtF,0EAA0E;AAC1E,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,iFA8CjE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { StorageError } from '../storage.error.js';
|
|
2
|
+
/** Bounded, exact-revision catalog read into a sealed text checkpoint. */
|
|
3
|
+
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
|
+
if (file.size > workflow.limits.maxTextBytes)
|
|
10
|
+
throw new StorageError('Checkout exceeds the buffered text limit.', {
|
|
11
|
+
code: 'LIMIT_EXCEEDED',
|
|
12
|
+
});
|
|
13
|
+
const pieces = [];
|
|
14
|
+
let offset = 0;
|
|
15
|
+
do {
|
|
16
|
+
const page = await catalog.readWindow({ ...input, offset });
|
|
17
|
+
if (page.etag !== input.expectedEtag ||
|
|
18
|
+
page.totalBytes !== file.size ||
|
|
19
|
+
page.offset !== offset)
|
|
20
|
+
throw new StorageError('The catalog revision changed.', {
|
|
21
|
+
code: 'CONFLICT',
|
|
22
|
+
});
|
|
23
|
+
if (page.content === null)
|
|
24
|
+
throw new StorageError('Checkout requires a text file.', {
|
|
25
|
+
code: 'INVALID_ARGUMENT',
|
|
26
|
+
});
|
|
27
|
+
const next = offset + new TextEncoder().encode(page.content).byteLength;
|
|
28
|
+
if (next > file.size ||
|
|
29
|
+
(page.nextOffset === null
|
|
30
|
+
? next !== file.size
|
|
31
|
+
: page.nextOffset !== next || next <= offset))
|
|
32
|
+
throw new StorageError('Invalid catalog text window.', {
|
|
33
|
+
code: 'PROVIDER',
|
|
34
|
+
});
|
|
35
|
+
pieces.push(page.content);
|
|
36
|
+
offset = next;
|
|
37
|
+
if (page.nextOffset === null)
|
|
38
|
+
break;
|
|
39
|
+
} while (offset < file.size);
|
|
40
|
+
return workflow.stageText({
|
|
41
|
+
...input,
|
|
42
|
+
content: pieces.join(''),
|
|
43
|
+
idempotencyKey: input.commandId,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=storage-catalog-checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-catalog-checkout.js","sourceRoot":"","sources":["../../src/workspace/storage-catalog-checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAOnD,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAA8C,EAC9C,QAAgD,EAChD,KAAgE;IAEhE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,YAAY;QAClC,MAAM,IAAI,YAAY,CAAC,+BAA+B,EAAE;YACtD,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;IACL,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY;QAC1C,MAAM,IAAI,YAAY,CAAC,2CAA2C,EAAE;YAClE,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;IACL,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,GAAG,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5D,IACE,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,YAAY;YAChC,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI;YAC7B,IAAI,CAAC,MAAM,KAAK,MAAM;YAEtB,MAAM,IAAI,YAAY,CAAC,+BAA+B,EAAE;gBACtD,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;YACvB,MAAM,IAAI,YAAY,CAAC,gCAAgC,EAAE;gBACvD,IAAI,EAAE,kBAAkB;aACzB,CAAC,CAAC;QACL,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;QACxE,IACE,IAAI,GAAG,IAAI,CAAC,IAAI;YAChB,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI;gBACvB,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;gBACpB,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC;YAE/C,MAAM,IAAI,YAAY,CAAC,8BAA8B,EAAE;gBACrD,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,MAAM,GAAG,IAAI,CAAC;QACd,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,MAAM;IACtC,CAAC,QAAQ,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE;IAC7B,OAAO,QAAQ,CAAC,SAAS,CAAC;QACxB,GAAG,KAAK;QACR,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,cAAc,EAAE,KAAK,CAAC,SAAS;KAChC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { StorageError } from '../storage.error.js';\nimport type {\n StorageFileCatalogCapability,\n StorageCatalogCommand,\n} from './storage-file-catalog.types.js';\nimport type { StorageFileWorkflowCapability } from './storage-file-workflow.types.js';\n\n/** Bounded, exact-revision catalog read into a sealed text checkpoint. */\nexport async function checkoutStorageCatalogText<Receipt>(\n catalog: StorageFileCatalogCapability<Receipt>,\n workflow: StorageFileWorkflowCapability<Receipt>,\n input: StorageCatalogCommand & { readonly expectedEtag: string },\n) {\n const file = await catalog.stat(input);\n if (file.etag !== input.expectedEtag)\n throw new StorageError('The catalog revision changed.', {\n code: 'CONFLICT',\n });\n if (file.size > workflow.limits.maxTextBytes)\n throw new StorageError('Checkout exceeds the buffered text limit.', {\n code: 'LIMIT_EXCEEDED',\n });\n const pieces: string[] = [];\n let offset = 0;\n do {\n const page = await catalog.readWindow({ ...input, offset });\n if (\n page.etag !== input.expectedEtag ||\n page.totalBytes !== file.size ||\n page.offset !== offset\n )\n throw new StorageError('The catalog revision changed.', {\n code: 'CONFLICT',\n });\n if (page.content === null)\n throw new StorageError('Checkout requires a text file.', {\n code: 'INVALID_ARGUMENT',\n });\n const next = offset + new TextEncoder().encode(page.content).byteLength;\n if (\n next > file.size ||\n (page.nextOffset === null\n ? next !== file.size\n : page.nextOffset !== next || next <= offset)\n )\n throw new StorageError('Invalid catalog text window.', {\n code: 'PROVIDER',\n });\n pieces.push(page.content);\n offset = next;\n if (page.nextOffset === null) break;\n } while (offset < file.size);\n return workflow.stageText({\n ...input,\n content: pieces.join(''),\n idempotencyKey: input.commandId,\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-file-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"AAYA,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,CAoiBxC;CA6FF"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { applyStorageTextEdit } from '../core/storage-text-edit.js';
|
|
2
|
+
import { stageStorageTextDraft } from './storage-text-draft.js';
|
|
1
3
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
4
|
import { StorageError } from '../storage.error.js';
|
|
3
5
|
import { assertWorkspacePath } from './storage-workspace.path.js';
|
|
@@ -86,6 +88,7 @@ export class StorageFileWorkflow {
|
|
|
86
88
|
id: randomUUID(),
|
|
87
89
|
path: input.path,
|
|
88
90
|
expectedEtag: input.expectedEtag ?? null,
|
|
91
|
+
sourceDraftId: null,
|
|
89
92
|
text: input.text,
|
|
90
93
|
status: 'open',
|
|
91
94
|
size: 0,
|
|
@@ -99,6 +102,91 @@ export class StorageFileWorkflow {
|
|
|
99
102
|
return summary(record);
|
|
100
103
|
});
|
|
101
104
|
},
|
|
105
|
+
stageText: async (request) => {
|
|
106
|
+
const input = { ...request };
|
|
107
|
+
const signal = operation('write', input);
|
|
108
|
+
requireMutation(input.expectedEtag);
|
|
109
|
+
validateIdentity(input.idempotencyKey);
|
|
110
|
+
assertWorkspacePath(input.path, limits.maxPathBytes, {
|
|
111
|
+
allowRoot: false,
|
|
112
|
+
});
|
|
113
|
+
if (input.expectedEtag !== undefined &&
|
|
114
|
+
(input.expectedEtag.length < 1 || input.expectedEtag.length > 1024))
|
|
115
|
+
invalid('Invalid ETag.');
|
|
116
|
+
if (new TextEncoder().encode(input.content).byteLength >
|
|
117
|
+
limits.maxTextBytes)
|
|
118
|
+
throw new StorageError('Text checkpoint exceeds the buffered text limit.', { code: 'LIMIT_EXCEEDED' });
|
|
119
|
+
return summary(await stageStorageTextDraft({
|
|
120
|
+
scope,
|
|
121
|
+
signal,
|
|
122
|
+
limits,
|
|
123
|
+
content,
|
|
124
|
+
requireMutation,
|
|
125
|
+
transaction: (work) => transaction(signal, work),
|
|
126
|
+
idempotencyKey: input.idempotencyKey,
|
|
127
|
+
fingerprint: digest(new TextEncoder().encode(JSON.stringify([
|
|
128
|
+
'stage-text',
|
|
129
|
+
input.path,
|
|
130
|
+
input.expectedEtag ?? null,
|
|
131
|
+
input.content,
|
|
132
|
+
]))),
|
|
133
|
+
load: async () => ({
|
|
134
|
+
content: input.content,
|
|
135
|
+
path: input.path,
|
|
136
|
+
expectedEtag: input.expectedEtag ?? null,
|
|
137
|
+
source: null,
|
|
138
|
+
}),
|
|
139
|
+
}));
|
|
140
|
+
},
|
|
141
|
+
reviseText: async (request) => {
|
|
142
|
+
const input = {
|
|
143
|
+
...request,
|
|
144
|
+
changes: request.changes.map((change) => ({ ...change })),
|
|
145
|
+
};
|
|
146
|
+
operation('read', input);
|
|
147
|
+
const signal = operation('write', input);
|
|
148
|
+
validateIdentity(input.idempotencyKey);
|
|
149
|
+
validateIdentity(input.draftId);
|
|
150
|
+
storageInteger(input.expectedSize, 'expectedSize');
|
|
151
|
+
if (input.expectedSize > limits.maxTextBytes ||
|
|
152
|
+
input.changes.length < 1 ||
|
|
153
|
+
input.changes.length > limits.maxEdits)
|
|
154
|
+
throw new StorageError('Text editing exceeds the configured limits.', { code: 'LIMIT_EXCEEDED' });
|
|
155
|
+
return summary(await stageStorageTextDraft({
|
|
156
|
+
scope,
|
|
157
|
+
signal,
|
|
158
|
+
limits,
|
|
159
|
+
content,
|
|
160
|
+
requireMutation,
|
|
161
|
+
transaction: (work) => transaction(signal, work),
|
|
162
|
+
idempotencyKey: input.idempotencyKey,
|
|
163
|
+
fingerprint: digest(new TextEncoder().encode(JSON.stringify([
|
|
164
|
+
'revise-text',
|
|
165
|
+
input.draftId,
|
|
166
|
+
input.expectedSize,
|
|
167
|
+
input.changes,
|
|
168
|
+
]))),
|
|
169
|
+
load: async () => {
|
|
170
|
+
const source = await transaction(signal, (tx) => requireDraft(tx, input.draftId));
|
|
171
|
+
requireMutation(source.expectedEtag);
|
|
172
|
+
if (!source.text ||
|
|
173
|
+
!['open', 'sealed'].includes(source.status) ||
|
|
174
|
+
source.size !== input.expectedSize)
|
|
175
|
+
conflict('The source must be an unfinished text draft at the expected size.');
|
|
176
|
+
const bytes = await collectStorageBytes(this.#stream(scope, source, limits, signal), limits.maxTextBytes, signal);
|
|
177
|
+
const original = new TextDecoder('utf-8', {
|
|
178
|
+
fatal: true,
|
|
179
|
+
ignoreBOM: true,
|
|
180
|
+
}).decode(bytes);
|
|
181
|
+
return {
|
|
182
|
+
source,
|
|
183
|
+
path: source.path,
|
|
184
|
+
expectedEtag: source.expectedEtag,
|
|
185
|
+
content: applyStorageTextEdit(original, { kind: 'batch', changes: input.changes }, { maxBytes: limits.maxTextBytes, maxEdits: limits.maxEdits }),
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
}));
|
|
189
|
+
},
|
|
102
190
|
list: async (input = {}) => {
|
|
103
191
|
const signal = operation('read', input);
|
|
104
192
|
const offset = input.offset ?? 0;
|
|
@@ -134,6 +222,32 @@ export class StorageFileWorkflow {
|
|
|
134
222
|
: { content: null, offset, nextOffset: null };
|
|
135
223
|
return { ...summary(draft), ...window };
|
|
136
224
|
},
|
|
225
|
+
readText: async (request) => {
|
|
226
|
+
const input = { ...request };
|
|
227
|
+
const signal = operation('read', input);
|
|
228
|
+
storageInteger(input.expectedSize, 'expectedSize');
|
|
229
|
+
if (input.expectedSize > limits.maxTextBytes)
|
|
230
|
+
throw new StorageError('Text read exceeds the buffered text limit.', {
|
|
231
|
+
code: 'LIMIT_EXCEEDED',
|
|
232
|
+
});
|
|
233
|
+
const draft = await transaction(signal, (tx) => requireDraft(tx, input.draftId));
|
|
234
|
+
if (!draft.text ||
|
|
235
|
+
draft.status === 'cancelled' ||
|
|
236
|
+
draft.size !== input.expectedSize)
|
|
237
|
+
conflict('The source must be an available text draft at the expected size.');
|
|
238
|
+
const bytes = await collectStorageBytes(this.#stream(scope, draft, limits, signal), limits.maxTextBytes, signal);
|
|
239
|
+
const current = await transaction(signal, (tx) => requireDraft(tx, input.draftId));
|
|
240
|
+
if (current.status === 'cancelled' ||
|
|
241
|
+
current.size !== input.expectedSize)
|
|
242
|
+
conflict('The source draft changed while reading.');
|
|
243
|
+
return {
|
|
244
|
+
...summary(current),
|
|
245
|
+
content: new TextDecoder('utf-8', {
|
|
246
|
+
fatal: true,
|
|
247
|
+
ignoreBOM: true,
|
|
248
|
+
}).decode(bytes),
|
|
249
|
+
};
|
|
250
|
+
},
|
|
137
251
|
append: async (input) => {
|
|
138
252
|
const signal = operation('write', input);
|
|
139
253
|
storageInteger(input.offset, 'offset');
|
|
@@ -409,11 +523,12 @@ async function appendState(tx, draft, offset, size, sha256) {
|
|
|
409
523
|
return { draft, replay: false };
|
|
410
524
|
}
|
|
411
525
|
function summary(draft) {
|
|
412
|
-
const { id, path, expectedEtag, text, status, size, result, createdAt } = draft;
|
|
526
|
+
const { id, path, expectedEtag, sourceDraftId, text, status, size, result, createdAt, } = draft;
|
|
413
527
|
return Object.freeze({
|
|
414
528
|
id,
|
|
415
529
|
path,
|
|
416
530
|
expectedEtag,
|
|
531
|
+
sourceDraftId,
|
|
417
532
|
text,
|
|
418
533
|
status,
|
|
419
534
|
size,
|