@bendyline/docblocks 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -11
- package/dist/chunk-2D7Y4IR3.js +1293 -0
- package/dist/chunk-2D7Y4IR3.js.map +1 -0
- package/dist/chunk-5MYAICRE.js +957 -0
- package/dist/chunk-5MYAICRE.js.map +1 -0
- package/dist/chunk-75UUF6C4.js +802 -0
- package/dist/chunk-75UUF6C4.js.map +1 -0
- package/dist/chunk-AEHCVWU5.js +25 -0
- package/dist/chunk-AEHCVWU5.js.map +1 -0
- package/dist/chunk-AYZ4HN5M.js +20 -0
- package/dist/chunk-AYZ4HN5M.js.map +1 -0
- package/dist/chunk-EGNDADXB.js +111 -0
- package/dist/chunk-EGNDADXB.js.map +1 -0
- package/dist/chunk-EZKJZUNJ.js +13 -0
- package/dist/chunk-EZKJZUNJ.js.map +1 -0
- package/dist/chunk-FNW556FN.js +75 -0
- package/dist/chunk-FNW556FN.js.map +1 -0
- package/dist/chunk-GCPBEMMH.js +563 -0
- package/dist/chunk-GCPBEMMH.js.map +1 -0
- package/dist/chunk-J32GU3F3.js +1664 -0
- package/dist/chunk-J32GU3F3.js.map +1 -0
- package/dist/chunk-PGR7LK6D.js +1062 -0
- package/dist/chunk-PGR7LK6D.js.map +1 -0
- package/dist/chunk-RQJRQF46.js +787 -0
- package/dist/chunk-RQJRQF46.js.map +1 -0
- package/dist/{chunk-ME76RUMR.js → chunk-RVQHY3XU.js} +15 -1
- package/dist/chunk-RVQHY3XU.js.map +1 -0
- package/dist/chunk-SI2LU2RP.js +224 -0
- package/dist/chunk-SI2LU2RP.js.map +1 -0
- package/dist/chunk-W5UUUII5.js +142 -0
- package/dist/chunk-W5UUUII5.js.map +1 -0
- package/dist/document/document-session.d.ts +127 -0
- package/dist/document/document-session.d.ts.map +1 -0
- package/dist/document/document-session.js +749 -0
- package/dist/document/document-session.js.map +1 -0
- package/dist/document/filesystem-target.d.ts +17 -0
- package/dist/document/filesystem-target.d.ts.map +1 -0
- package/dist/document/filesystem-target.js +70 -0
- package/dist/document/filesystem-target.js.map +1 -0
- package/dist/document/index.d.ts +6 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +4 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/recovery-journal.d.ts +125 -0
- package/dist/document/recovery-journal.d.ts.map +1 -0
- package/dist/document/recovery-journal.js +385 -0
- package/dist/document/recovery-journal.js.map +1 -0
- package/dist/document/types.d.ts +89 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +9 -0
- package/dist/document/types.js.map +1 -0
- package/dist/filesystem/commit-lock.d.ts +3 -0
- package/dist/filesystem/commit-lock.d.ts.map +1 -0
- package/dist/filesystem/commit-lock.js +20 -0
- package/dist/filesystem/commit-lock.js.map +1 -0
- package/dist/filesystem/dbk-workspace.d.ts +34 -0
- package/dist/filesystem/dbk-workspace.d.ts.map +1 -0
- package/dist/filesystem/dbk-workspace.js +85 -0
- package/dist/filesystem/dbk-workspace.js.map +1 -0
- package/dist/filesystem/electron-provider-v2.d.ts +36 -0
- package/dist/filesystem/electron-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/electron-provider-v2.js +503 -0
- package/dist/filesystem/electron-provider-v2.js.map +1 -0
- package/dist/filesystem/electron-provider.d.ts +6 -3
- package/dist/filesystem/electron-provider.d.ts.map +1 -1
- package/dist/filesystem/electron-provider.js +18 -13
- package/dist/filesystem/electron-provider.js.map +1 -1
- package/dist/filesystem/electron.d.ts +4 -0
- package/dist/filesystem/electron.d.ts.map +1 -0
- package/dist/filesystem/electron.js +4 -0
- package/dist/filesystem/electron.js.map +1 -0
- package/dist/filesystem/filesystem-content-container.d.ts +1 -1
- package/dist/filesystem/filesystem-content-container.d.ts.map +1 -1
- package/dist/filesystem/filesystem-content-container.js +50 -13
- package/dist/filesystem/filesystem-content-container.js.map +1 -1
- package/dist/filesystem/fs-error.d.ts +46 -0
- package/dist/filesystem/fs-error.d.ts.map +1 -0
- package/dist/filesystem/fs-error.js +170 -0
- package/dist/filesystem/fs-error.js.map +1 -0
- package/dist/filesystem/index.d.ts +15 -1
- package/dist/filesystem/index.d.ts.map +1 -1
- package/dist/filesystem/index.js +13 -0
- package/dist/filesystem/index.js.map +1 -1
- package/dist/filesystem/indexeddb-content-container.d.ts +3 -1
- package/dist/filesystem/indexeddb-content-container.d.ts.map +1 -1
- package/dist/filesystem/indexeddb-content-container.js +18 -11
- package/dist/filesystem/indexeddb-content-container.js.map +1 -1
- package/dist/filesystem/indexeddb-provider-v2.d.ts +96 -0
- package/dist/filesystem/indexeddb-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/indexeddb-provider-v2.js +1241 -0
- package/dist/filesystem/indexeddb-provider-v2.js.map +1 -0
- package/dist/filesystem/indexeddb-provider.d.ts +21 -14
- package/dist/filesystem/indexeddb-provider.d.ts.map +1 -1
- package/dist/filesystem/indexeddb-provider.js +111 -261
- package/dist/filesystem/indexeddb-provider.js.map +1 -1
- package/dist/filesystem/indexeddb-store.d.ts +34 -0
- package/dist/filesystem/indexeddb-store.d.ts.map +1 -0
- package/dist/filesystem/indexeddb-store.js +165 -0
- package/dist/filesystem/indexeddb-store.js.map +1 -0
- package/dist/filesystem/indexeddb.d.ts +5 -0
- package/dist/filesystem/indexeddb.d.ts.map +1 -0
- package/dist/filesystem/indexeddb.js +5 -0
- package/dist/filesystem/indexeddb.js.map +1 -0
- package/dist/filesystem/legacy-v2-adapter.d.ts +62 -0
- package/dist/filesystem/legacy-v2-adapter.d.ts.map +1 -0
- package/dist/filesystem/legacy-v2-adapter.js +499 -0
- package/dist/filesystem/legacy-v2-adapter.js.map +1 -0
- package/dist/filesystem/memory-provider-v2.d.ts +92 -0
- package/dist/filesystem/memory-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/memory-provider-v2.js +615 -0
- package/dist/filesystem/memory-provider-v2.js.map +1 -0
- package/dist/filesystem/memory-provider.d.ts +54 -0
- package/dist/filesystem/memory-provider.d.ts.map +1 -0
- package/dist/filesystem/memory-provider.js +132 -0
- package/dist/filesystem/memory-provider.js.map +1 -0
- package/dist/filesystem/memory.d.ts +4 -0
- package/dist/filesystem/memory.d.ts.map +1 -0
- package/dist/filesystem/memory.js +4 -0
- package/dist/filesystem/memory.js.map +1 -0
- package/dist/filesystem/move-entry.d.ts +9 -0
- package/dist/filesystem/move-entry.d.ts.map +1 -0
- package/dist/filesystem/move-entry.js +103 -0
- package/dist/filesystem/move-entry.js.map +1 -0
- package/dist/filesystem/move-error.d.ts +53 -0
- package/dist/filesystem/move-error.d.ts.map +1 -0
- package/dist/filesystem/move-error.js +99 -0
- package/dist/filesystem/move-error.js.map +1 -0
- package/dist/filesystem/native-provider-v2.d.ts +75 -0
- package/dist/filesystem/native-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/native-provider-v2.js +849 -0
- package/dist/filesystem/native-provider-v2.js.map +1 -0
- package/dist/filesystem/native-provider.d.ts +9 -1
- package/dist/filesystem/native-provider.d.ts.map +1 -1
- package/dist/filesystem/native-provider.js +172 -37
- package/dist/filesystem/native-provider.js.map +1 -1
- package/dist/filesystem/native.d.ts +4 -0
- package/dist/filesystem/native.d.ts.map +1 -0
- package/dist/filesystem/native.js +4 -0
- package/dist/filesystem/native.js.map +1 -0
- package/dist/filesystem/types.d.ts +37 -4
- package/dist/filesystem/types.d.ts.map +1 -1
- package/dist/filesystem/types.js +11 -3
- package/dist/filesystem/types.js.map +1 -1
- package/dist/filesystem/v2.d.ts +172 -0
- package/dist/filesystem/v2.d.ts.map +1 -0
- package/dist/filesystem/v2.js +16 -0
- package/dist/filesystem/v2.js.map +1 -0
- package/dist/filesystem/workspace-path.d.ts +21 -0
- package/dist/filesystem/workspace-path.d.ts.map +1 -0
- package/dist/filesystem/workspace-path.js +80 -0
- package/dist/filesystem/workspace-path.js.map +1 -0
- package/dist/host/filesystem-v2.d.ts +45 -0
- package/dist/host/filesystem-v2.d.ts.map +1 -0
- package/dist/host/filesystem-v2.js +13 -0
- package/dist/host/filesystem-v2.js.map +1 -0
- package/dist/host/git.d.ts +200 -0
- package/dist/host/git.d.ts.map +1 -0
- package/dist/host/git.js +15 -0
- package/dist/host/git.js.map +1 -0
- package/dist/host/index.d.ts +4 -1
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +2 -0
- package/dist/host/index.js.map +1 -1
- package/dist/host/types.d.ts +114 -31
- package/dist/host/types.d.ts.map +1 -1
- package/dist/host/wire-policy.d.ts +22 -0
- package/dist/host/wire-policy.d.ts.map +1 -0
- package/dist/host/wire-policy.js +92 -0
- package/dist/host/wire-policy.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/types.d.ts +466 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +25 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp/wire.d.ts +29 -0
- package/dist/mcp/wire.d.ts.map +1 -0
- package/dist/mcp/wire.js +1046 -0
- package/dist/mcp/wire.js.map +1 -0
- package/dist/mcp/zod.d.ts +5763 -0
- package/dist/mcp/zod.d.ts.map +1 -0
- package/dist/mcp/zod.js +908 -0
- package/dist/mcp/zod.js.map +1 -0
- package/dist/types-CX893hgH.d.ts +468 -0
- package/dist/types-CsX6EN2t.d.ts +301 -0
- package/dist/types-eOlt9J7n.d.ts +478 -0
- package/dist/vscode/index.d.ts +3 -0
- package/dist/vscode/index.d.ts.map +1 -0
- package/dist/vscode/index.js +3 -0
- package/dist/vscode/index.js.map +1 -0
- package/dist/vscode/messages.d.ts +204 -0
- package/dist/vscode/messages.d.ts.map +1 -0
- package/dist/vscode/messages.js +494 -0
- package/dist/vscode/messages.js.map +1 -0
- package/dist/workspace/index.d.ts +3 -2
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +2 -1
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/reconcile-electron.d.ts +19 -0
- package/dist/workspace/reconcile-electron.d.ts.map +1 -0
- package/dist/workspace/reconcile-electron.js +42 -0
- package/dist/workspace/reconcile-electron.js.map +1 -0
- package/dist/workspace/types.d.ts +41 -1
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/types.js +0 -4
- package/dist/workspace/types.js.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +17 -5
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.js +55 -11
- package/dist/workspace/workspace-manager.js.map +1 -1
- package/dist/workspace-path-CWVrcuPL.d.ts +21 -0
- package/package.json +43 -2
- package/src/document/document-session.ts +834 -0
- package/src/document/filesystem-target.ts +109 -0
- package/src/document/index.ts +41 -0
- package/src/document/recovery-journal.ts +536 -0
- package/src/document/types.ts +116 -0
- package/src/filesystem/commit-lock.ts +29 -0
- package/src/filesystem/dbk-workspace.ts +135 -0
- package/src/filesystem/electron-provider-v2.ts +630 -0
- package/src/filesystem/electron-provider.ts +25 -14
- package/src/filesystem/electron.ts +3 -0
- package/src/filesystem/filesystem-content-container.ts +53 -15
- package/src/filesystem/fs-error.ts +234 -0
- package/src/filesystem/index.ts +119 -0
- package/src/filesystem/indexeddb-content-container.ts +20 -12
- package/src/filesystem/indexeddb-provider-v2.ts +1740 -0
- package/src/filesystem/indexeddb-provider.ts +126 -300
- package/src/filesystem/indexeddb-store.ts +207 -0
- package/src/filesystem/indexeddb.ts +12 -0
- package/src/filesystem/legacy-v2-adapter.ts +779 -0
- package/src/filesystem/memory-provider-v2.ts +896 -0
- package/src/filesystem/memory-provider.ts +180 -0
- package/src/filesystem/memory.ts +15 -0
- package/src/filesystem/move-entry.ts +142 -0
- package/src/filesystem/move-error.ts +159 -0
- package/src/filesystem/native-provider-v2.ts +1165 -0
- package/src/filesystem/native-provider.ts +194 -41
- package/src/filesystem/native.ts +16 -0
- package/src/filesystem/types.ts +49 -4
- package/src/filesystem/v2.ts +231 -0
- package/src/filesystem/workspace-path.ts +92 -0
- package/src/host/filesystem-v2.ts +104 -0
- package/src/host/git.ts +246 -0
- package/src/host/index.ts +46 -0
- package/src/host/types.ts +155 -34
- package/src/host/wire-policy.ts +103 -0
- package/src/index.ts +2 -1
- package/src/mcp/index.ts +3 -0
- package/src/mcp/types.ts +594 -0
- package/src/mcp/wire.ts +1280 -0
- package/src/mcp/zod.ts +1000 -0
- package/src/vscode/index.ts +2 -0
- package/src/vscode/messages.ts +704 -0
- package/src/workspace/index.ts +8 -1
- package/src/workspace/reconcile-electron.ts +65 -0
- package/src/workspace/types.ts +39 -1
- package/src/workspace/workspace-manager.ts +71 -10
- package/dist/chunk-GUNM43XZ.js +0 -63
- package/dist/chunk-GUNM43XZ.js.map +0 -1
- package/dist/chunk-IM7LCQJ6.js +0 -850
- package/dist/chunk-IM7LCQJ6.js.map +0 -1
- package/dist/chunk-ME76RUMR.js.map +0 -1
- package/dist/index-pgBHBQ9G.d.ts +0 -213
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseFileSystemVersion
|
|
3
|
+
} from "./chunk-AYZ4HN5M.js";
|
|
4
|
+
import {
|
|
5
|
+
FsError,
|
|
6
|
+
WORKSPACE_ROOT,
|
|
7
|
+
parseWorkspacePath,
|
|
8
|
+
workspacePathBasename,
|
|
9
|
+
workspacePathContains,
|
|
10
|
+
workspacePathDirname
|
|
11
|
+
} from "./chunk-SI2LU2RP.js";
|
|
12
|
+
|
|
13
|
+
// src/filesystem/memory-provider-v2.ts
|
|
14
|
+
var MEMORY_CAPABILITIES = Object.freeze({
|
|
15
|
+
writeAtomicity: "process",
|
|
16
|
+
moveAtomicity: "process",
|
|
17
|
+
snapshotAtomicity: "process",
|
|
18
|
+
conditionalWrite: "process",
|
|
19
|
+
recursiveRemove: true,
|
|
20
|
+
watch: true,
|
|
21
|
+
caseSensitivity: "sensitive",
|
|
22
|
+
symlinkPolicy: "unsupported",
|
|
23
|
+
durability: "volatile"
|
|
24
|
+
});
|
|
25
|
+
var MemoryFileSystemProviderV2 = class {
|
|
26
|
+
constructor(id, label) {
|
|
27
|
+
this.capabilities = MEMORY_CAPABILITIES;
|
|
28
|
+
this.watchers = /* @__PURE__ */ new Set();
|
|
29
|
+
this.subscriptions = /* @__PURE__ */ new Set();
|
|
30
|
+
this.pendingEvents = [];
|
|
31
|
+
this.emittingEvents = false;
|
|
32
|
+
this.mutationCounter = 0;
|
|
33
|
+
this.eventSequence = 0;
|
|
34
|
+
this.disposed = false;
|
|
35
|
+
this.disposePromise = null;
|
|
36
|
+
this.id = id;
|
|
37
|
+
this.label = label;
|
|
38
|
+
this.treeVersion = parseFileSystemVersion(`${id}:0`);
|
|
39
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
40
|
+
this.entries = /* @__PURE__ */ new Map([
|
|
41
|
+
[WORKSPACE_ROOT, { kind: "directory", version: this.treeVersion, lastModified: now }]
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
/** Monotonic in-process revision used by synchronous transient-workspace staging. */
|
|
45
|
+
get mutationRevision() {
|
|
46
|
+
return this.mutationCounter;
|
|
47
|
+
}
|
|
48
|
+
/** @internal Atomically couple owned bytes to their v1 compatibility kind. */
|
|
49
|
+
readCompatibilityFile(path) {
|
|
50
|
+
this.assertOpen("read");
|
|
51
|
+
const canonical = this.canonical(path);
|
|
52
|
+
const entry = this.entries.get(canonical);
|
|
53
|
+
if (!entry) return null;
|
|
54
|
+
if (entry.kind !== "file") {
|
|
55
|
+
throw this.error(
|
|
56
|
+
"type-mismatch",
|
|
57
|
+
"read",
|
|
58
|
+
canonical,
|
|
59
|
+
"Expected a file but found a directory."
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return Object.freeze({ data: entry.data.slice(0), payloadKind: entry.payloadKind });
|
|
63
|
+
}
|
|
64
|
+
/** @internal Capture an owned synchronous copy for DBK whole-tree staging. */
|
|
65
|
+
captureState() {
|
|
66
|
+
this.assertOpen("snapshot");
|
|
67
|
+
const files = [];
|
|
68
|
+
const directories = [];
|
|
69
|
+
for (const [path, entry] of [...this.entries].sort(
|
|
70
|
+
([left], [right]) => compareText(left, right)
|
|
71
|
+
)) {
|
|
72
|
+
if (!path) continue;
|
|
73
|
+
if (entry.kind === "directory") directories.push(path);
|
|
74
|
+
else {
|
|
75
|
+
files.push(
|
|
76
|
+
Object.freeze({ path, data: entry.data.slice(0), payloadKind: entry.payloadKind })
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return Object.freeze({
|
|
81
|
+
revision: this.mutationCounter,
|
|
82
|
+
files: Object.freeze(files),
|
|
83
|
+
directories: Object.freeze(directories)
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/** @internal Atomically replace a transient workspace after complete validation. */
|
|
87
|
+
replaceState(replacement, expectedRevision) {
|
|
88
|
+
this.assertOpen("write");
|
|
89
|
+
const stagedFiles = /* @__PURE__ */ new Map();
|
|
90
|
+
const stagedDirectories = /* @__PURE__ */ new Set();
|
|
91
|
+
const explicitDirectories = /* @__PURE__ */ new Set();
|
|
92
|
+
for (const rawDirectory of replacement.directories ?? []) {
|
|
93
|
+
const directory = this.canonicalNonRoot(rawDirectory, "create-directory");
|
|
94
|
+
if (explicitDirectories.has(directory)) {
|
|
95
|
+
throw this.error(
|
|
96
|
+
"already-exists",
|
|
97
|
+
"create-directory",
|
|
98
|
+
directory,
|
|
99
|
+
"Duplicate replacement directory."
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
explicitDirectories.add(directory);
|
|
103
|
+
stagedDirectories.add(directory);
|
|
104
|
+
addParentPaths(stagedDirectories, directory);
|
|
105
|
+
}
|
|
106
|
+
for (const rawFile of replacement.files) {
|
|
107
|
+
const path = this.canonicalNonRoot(rawFile.path, "write");
|
|
108
|
+
if (stagedFiles.has(path)) {
|
|
109
|
+
throw this.error("already-exists", "write", path, "Duplicate replacement file.");
|
|
110
|
+
}
|
|
111
|
+
if (!isMemoryFilePayloadKind(rawFile.payloadKind)) {
|
|
112
|
+
throw this.error("type-mismatch", "write", path, "Invalid replacement payload kind.");
|
|
113
|
+
}
|
|
114
|
+
stagedFiles.set(path, {
|
|
115
|
+
data: copyBytes(rawFile.data),
|
|
116
|
+
payloadKind: rawFile.payloadKind
|
|
117
|
+
});
|
|
118
|
+
addParentPaths(stagedDirectories, path);
|
|
119
|
+
}
|
|
120
|
+
for (const path of stagedFiles.keys()) {
|
|
121
|
+
if (stagedDirectories.has(path)) {
|
|
122
|
+
throw this.error(
|
|
123
|
+
"type-mismatch",
|
|
124
|
+
"write",
|
|
125
|
+
path,
|
|
126
|
+
"Replacement path has conflicting file and directory kinds."
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
for (const parent of parentChain(path)) {
|
|
130
|
+
if (parent && stagedFiles.has(parent)) {
|
|
131
|
+
throw this.error("type-mismatch", "write", parent, "A replacement parent is a file.");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (expectedRevision !== void 0 && expectedRevision !== this.mutationCounter) {
|
|
136
|
+
throw this.error(
|
|
137
|
+
"conflict",
|
|
138
|
+
"write",
|
|
139
|
+
WORKSPACE_ROOT,
|
|
140
|
+
"Memory filesystem changed while replacement contents were staged."
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const version = this.nextVersion();
|
|
144
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
145
|
+
const next = /* @__PURE__ */ new Map([
|
|
146
|
+
[WORKSPACE_ROOT, { kind: "directory", version, lastModified: now }]
|
|
147
|
+
]);
|
|
148
|
+
this.addDirectories(next, [...stagedDirectories], version, now);
|
|
149
|
+
for (const [path, file] of stagedFiles) {
|
|
150
|
+
next.set(path, {
|
|
151
|
+
kind: "file",
|
|
152
|
+
data: file.data,
|
|
153
|
+
payloadKind: file.payloadKind,
|
|
154
|
+
version,
|
|
155
|
+
lastModified: now
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
this.entries = next;
|
|
159
|
+
this.emit({
|
|
160
|
+
type: "overflow",
|
|
161
|
+
kind: null,
|
|
162
|
+
path: WORKSPACE_ROOT,
|
|
163
|
+
destinationPath: null,
|
|
164
|
+
version: null,
|
|
165
|
+
previousVersion: null
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/** @internal Synchronous setup hook used before a transient provider is published. */
|
|
169
|
+
seedText(path, content) {
|
|
170
|
+
this.writeFileNow(path, new TextEncoder().encode(content), { createParents: true }, "text");
|
|
171
|
+
}
|
|
172
|
+
/** @internal Legacy text write that preserves text/binary compatibility metadata. */
|
|
173
|
+
async writeText(path, content, options = {}) {
|
|
174
|
+
return this.writeFileNow(path, new TextEncoder().encode(content), options, "text");
|
|
175
|
+
}
|
|
176
|
+
/** @internal Legacy binary write that explicitly changes compatibility payload kind. */
|
|
177
|
+
async writeBinary(path, data, options = {}) {
|
|
178
|
+
return this.writeFileNow(path, data, options, "binary");
|
|
179
|
+
}
|
|
180
|
+
/** @internal Atomic legacy compare-and-write over the authoritative v2 entry. */
|
|
181
|
+
async commitText(path, content, expectedContent) {
|
|
182
|
+
this.assertOpen("write");
|
|
183
|
+
const canonical = this.canonicalNonRoot(path, "write");
|
|
184
|
+
const existing = this.entries.get(canonical);
|
|
185
|
+
if (existing?.kind === "directory") {
|
|
186
|
+
throw this.error("type-mismatch", "write", canonical, "Cannot replace a directory.");
|
|
187
|
+
}
|
|
188
|
+
const currentContent = existing?.kind === "file" && existing.payloadKind === "text" ? new TextDecoder().decode(existing.data) : null;
|
|
189
|
+
if (existing?.kind === "file" && existing.payloadKind === "binary" || currentContent !== expectedContent && currentContent !== content) {
|
|
190
|
+
return {
|
|
191
|
+
status: "conflict",
|
|
192
|
+
content: currentContent,
|
|
193
|
+
version: existing?.version ?? null
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const written = this.writeFileNow(
|
|
197
|
+
canonical,
|
|
198
|
+
new TextEncoder().encode(content),
|
|
199
|
+
{ createParents: true, expectedVersion: existing?.version ?? null },
|
|
200
|
+
"text"
|
|
201
|
+
);
|
|
202
|
+
return { status: "committed", version: written.version };
|
|
203
|
+
}
|
|
204
|
+
async stat(path) {
|
|
205
|
+
this.assertOpen("stat");
|
|
206
|
+
const canonical = this.canonical(path);
|
|
207
|
+
const entry = this.entries.get(canonical);
|
|
208
|
+
return entry ? this.toEntrySnapshot(canonical, entry) : null;
|
|
209
|
+
}
|
|
210
|
+
async readFile(path) {
|
|
211
|
+
this.assertOpen("read");
|
|
212
|
+
const canonical = this.canonical(path);
|
|
213
|
+
const entry = this.entries.get(canonical);
|
|
214
|
+
if (!entry) return null;
|
|
215
|
+
if (entry.kind !== "file") {
|
|
216
|
+
throw this.error(
|
|
217
|
+
"type-mismatch",
|
|
218
|
+
"read",
|
|
219
|
+
canonical,
|
|
220
|
+
"Expected a file but found a directory."
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
return Object.freeze({
|
|
224
|
+
entry: this.toFileSnapshot(canonical, entry),
|
|
225
|
+
data: entry.data.slice(0)
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
async readDirectory(path) {
|
|
229
|
+
this.assertOpen("list");
|
|
230
|
+
const canonical = this.canonical(path);
|
|
231
|
+
const directory = this.entries.get(canonical);
|
|
232
|
+
if (!directory) {
|
|
233
|
+
throw this.error("not-found", "list", canonical, "Directory does not exist.");
|
|
234
|
+
}
|
|
235
|
+
if (directory.kind !== "directory") {
|
|
236
|
+
throw this.error(
|
|
237
|
+
"type-mismatch",
|
|
238
|
+
"list",
|
|
239
|
+
canonical,
|
|
240
|
+
"Expected a directory but found a file."
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const children = [];
|
|
244
|
+
for (const [entryPath2, entry] of this.entries) {
|
|
245
|
+
if (entryPath2 && workspacePathDirname(entryPath2) === canonical) {
|
|
246
|
+
children.push(this.toEntrySnapshot(entryPath2, entry));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
children.sort(compareSnapshots);
|
|
250
|
+
return Object.freeze(children);
|
|
251
|
+
}
|
|
252
|
+
async writeFile(path, data, options = {}) {
|
|
253
|
+
return this.writeFileNow(path, data, options);
|
|
254
|
+
}
|
|
255
|
+
writeFileNow(path, data, options, payloadKind) {
|
|
256
|
+
this.assertOpen("write");
|
|
257
|
+
const canonical = this.canonicalNonRoot(path, "write");
|
|
258
|
+
const existing = this.entries.get(canonical);
|
|
259
|
+
if (existing?.kind === "directory") {
|
|
260
|
+
throw this.error(
|
|
261
|
+
"type-mismatch",
|
|
262
|
+
"write",
|
|
263
|
+
canonical,
|
|
264
|
+
"Cannot replace a directory with a file."
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const mode = options.mode ?? "upsert";
|
|
268
|
+
if (mode === "create" && existing) {
|
|
269
|
+
throw this.error("already-exists", "write", canonical, "File already exists.");
|
|
270
|
+
}
|
|
271
|
+
if (mode === "replace" && !existing) {
|
|
272
|
+
throw this.error("not-found", "write", canonical, "File does not exist.");
|
|
273
|
+
}
|
|
274
|
+
this.assertExpectedVersion(existing, options.expectedVersion, "write", canonical);
|
|
275
|
+
const missingParents = this.planParents(canonical, options.createParents ?? false, "write");
|
|
276
|
+
const ownedData = copyBytes(data);
|
|
277
|
+
const version = this.nextVersion();
|
|
278
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
279
|
+
const next = new Map(this.entries);
|
|
280
|
+
this.addDirectories(next, missingParents, version, now);
|
|
281
|
+
next.set(canonical, {
|
|
282
|
+
kind: "file",
|
|
283
|
+
data: ownedData,
|
|
284
|
+
payloadKind: payloadKind ?? (existing?.kind === "file" ? existing.payloadKind : "binary"),
|
|
285
|
+
version,
|
|
286
|
+
lastModified: now
|
|
287
|
+
});
|
|
288
|
+
this.touchParents(next, canonical, version, now);
|
|
289
|
+
this.entries = next;
|
|
290
|
+
for (const directoryPath of missingParents) {
|
|
291
|
+
this.emit({
|
|
292
|
+
type: "created",
|
|
293
|
+
kind: "directory",
|
|
294
|
+
path: directoryPath,
|
|
295
|
+
destinationPath: null,
|
|
296
|
+
version,
|
|
297
|
+
previousVersion: null
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
this.emit({
|
|
301
|
+
type: existing ? "modified" : "created",
|
|
302
|
+
kind: "file",
|
|
303
|
+
path: canonical,
|
|
304
|
+
destinationPath: null,
|
|
305
|
+
version,
|
|
306
|
+
previousVersion: existing?.version ?? null
|
|
307
|
+
});
|
|
308
|
+
return this.toFileSnapshot(canonical, next.get(canonical));
|
|
309
|
+
}
|
|
310
|
+
async createDirectory(path, options = {}) {
|
|
311
|
+
this.assertOpen("create-directory");
|
|
312
|
+
const canonical = this.canonical(path);
|
|
313
|
+
const existing = this.entries.get(canonical);
|
|
314
|
+
if (existing) {
|
|
315
|
+
if (existing.kind !== "directory") {
|
|
316
|
+
throw this.error(
|
|
317
|
+
"type-mismatch",
|
|
318
|
+
"create-directory",
|
|
319
|
+
canonical,
|
|
320
|
+
"Cannot replace a file with a directory."
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
if ((options.mode ?? "ensure") === "create") {
|
|
324
|
+
throw this.error(
|
|
325
|
+
"already-exists",
|
|
326
|
+
"create-directory",
|
|
327
|
+
canonical,
|
|
328
|
+
"Directory already exists."
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
return this.toDirectorySnapshot(canonical, existing);
|
|
332
|
+
}
|
|
333
|
+
const missingParents = this.planParents(
|
|
334
|
+
canonical,
|
|
335
|
+
options.createParents ?? false,
|
|
336
|
+
"create-directory"
|
|
337
|
+
);
|
|
338
|
+
const version = this.nextVersion();
|
|
339
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
340
|
+
const next = new Map(this.entries);
|
|
341
|
+
const created = [...missingParents, canonical];
|
|
342
|
+
this.addDirectories(next, created, version, now);
|
|
343
|
+
this.touchParents(next, canonical, version, now);
|
|
344
|
+
this.entries = next;
|
|
345
|
+
for (const directoryPath of created) {
|
|
346
|
+
this.emit({
|
|
347
|
+
type: "created",
|
|
348
|
+
kind: "directory",
|
|
349
|
+
path: directoryPath,
|
|
350
|
+
destinationPath: null,
|
|
351
|
+
version,
|
|
352
|
+
previousVersion: null
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return this.toDirectorySnapshot(canonical, next.get(canonical));
|
|
356
|
+
}
|
|
357
|
+
async remove(path, options = {}) {
|
|
358
|
+
this.assertOpen("remove");
|
|
359
|
+
const canonical = this.canonicalNonRoot(path, "remove");
|
|
360
|
+
const existing = this.entries.get(canonical);
|
|
361
|
+
if (!existing) {
|
|
362
|
+
if ((options.missing ?? "error") === "ignore") {
|
|
363
|
+
return Object.freeze({ removed: false, version: this.treeVersion });
|
|
364
|
+
}
|
|
365
|
+
throw this.error("not-found", "remove", canonical, "Entry does not exist.");
|
|
366
|
+
}
|
|
367
|
+
this.assertExpectedVersion(existing, options.expectedVersion, "remove", canonical);
|
|
368
|
+
const descendants = [...this.entries.keys()].filter(
|
|
369
|
+
(candidate) => workspacePathContains(canonical, candidate, false)
|
|
370
|
+
);
|
|
371
|
+
if (existing.kind === "directory" && descendants.length > 0 && !options.recursive) {
|
|
372
|
+
throw this.error("not-empty", "remove", canonical, "Directory is not empty.");
|
|
373
|
+
}
|
|
374
|
+
const version = this.nextVersion();
|
|
375
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
376
|
+
const next = new Map(this.entries);
|
|
377
|
+
next.delete(canonical);
|
|
378
|
+
if (existing.kind === "directory") {
|
|
379
|
+
for (const descendant of descendants) next.delete(descendant);
|
|
380
|
+
}
|
|
381
|
+
this.touchParents(next, canonical, version, now);
|
|
382
|
+
this.entries = next;
|
|
383
|
+
this.emit({
|
|
384
|
+
type: "removed",
|
|
385
|
+
kind: existing.kind,
|
|
386
|
+
path: canonical,
|
|
387
|
+
destinationPath: null,
|
|
388
|
+
version: null,
|
|
389
|
+
previousVersion: existing.version
|
|
390
|
+
});
|
|
391
|
+
return Object.freeze({ removed: true, version });
|
|
392
|
+
}
|
|
393
|
+
async move(oldPath, newPath, options = {}) {
|
|
394
|
+
this.assertOpen("move");
|
|
395
|
+
const sourcePath = this.canonicalNonRoot(oldPath, "move");
|
|
396
|
+
const destinationPath = this.canonicalNonRoot(newPath, "move");
|
|
397
|
+
const source = this.entries.get(sourcePath);
|
|
398
|
+
if (!source) throw this.error("not-found", "move", sourcePath, "Source does not exist.");
|
|
399
|
+
this.assertExpectedVersion(source, options.expectedVersion, "move", sourcePath);
|
|
400
|
+
if (sourcePath === destinationPath) return this.toEntrySnapshot(sourcePath, source);
|
|
401
|
+
if (this.entries.has(destinationPath)) {
|
|
402
|
+
throw new FsError("already-exists", "Destination already exists.", {
|
|
403
|
+
operation: "move",
|
|
404
|
+
path: sourcePath,
|
|
405
|
+
destinationPath
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
if (source.kind === "directory" && workspacePathContains(sourcePath, destinationPath, false)) {
|
|
409
|
+
throw new FsError("invalid-path", "Cannot move a directory into itself.", {
|
|
410
|
+
operation: "move",
|
|
411
|
+
path: sourcePath,
|
|
412
|
+
destinationPath
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
const missingParents = this.planParents(
|
|
416
|
+
destinationPath,
|
|
417
|
+
options.createParents ?? false,
|
|
418
|
+
"move"
|
|
419
|
+
);
|
|
420
|
+
const sourcePaths = [...this.entries.keys()].filter(
|
|
421
|
+
(candidate) => workspacePathContains(sourcePath, candidate)
|
|
422
|
+
);
|
|
423
|
+
const sourceSet = new Set(sourcePaths);
|
|
424
|
+
const remapped = sourcePaths.map((currentPath) => {
|
|
425
|
+
const suffix = currentPath.slice(sourcePath.length);
|
|
426
|
+
const target = parseWorkspacePath(`${destinationPath}${suffix}`);
|
|
427
|
+
if (this.entries.has(target) && !sourceSet.has(target)) {
|
|
428
|
+
throw new FsError("already-exists", "A destination descendant already exists.", {
|
|
429
|
+
operation: "move",
|
|
430
|
+
path: currentPath,
|
|
431
|
+
destinationPath: target
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return [currentPath, target];
|
|
435
|
+
});
|
|
436
|
+
const version = this.nextVersion();
|
|
437
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
438
|
+
const next = new Map(this.entries);
|
|
439
|
+
for (const currentPath of sourcePaths) next.delete(currentPath);
|
|
440
|
+
this.addDirectories(next, missingParents, version, now);
|
|
441
|
+
for (const [currentPath, targetPath] of remapped) {
|
|
442
|
+
const current = this.entries.get(currentPath);
|
|
443
|
+
next.set(targetPath, this.withVersion(current, version, now));
|
|
444
|
+
}
|
|
445
|
+
this.touchParents(next, sourcePath, version, now);
|
|
446
|
+
this.touchParents(next, destinationPath, version, now);
|
|
447
|
+
this.entries = next;
|
|
448
|
+
for (const directoryPath of missingParents) {
|
|
449
|
+
this.emit({
|
|
450
|
+
type: "created",
|
|
451
|
+
kind: "directory",
|
|
452
|
+
path: directoryPath,
|
|
453
|
+
destinationPath: null,
|
|
454
|
+
version,
|
|
455
|
+
previousVersion: null
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
this.emit({
|
|
459
|
+
type: "moved",
|
|
460
|
+
kind: source.kind,
|
|
461
|
+
path: sourcePath,
|
|
462
|
+
destinationPath,
|
|
463
|
+
version,
|
|
464
|
+
previousVersion: source.version
|
|
465
|
+
});
|
|
466
|
+
return this.toEntrySnapshot(destinationPath, next.get(destinationPath));
|
|
467
|
+
}
|
|
468
|
+
async snapshot() {
|
|
469
|
+
this.assertOpen("snapshot");
|
|
470
|
+
const entries = [...this.entries.entries()].sort(([left], [right]) => compareText(left, right)).map(([path, entry]) => {
|
|
471
|
+
if (entry.kind === "file") {
|
|
472
|
+
return Object.freeze({ ...this.toFileSnapshot(path, entry), data: entry.data.slice(0) });
|
|
473
|
+
}
|
|
474
|
+
return this.toDirectorySnapshot(path, entry);
|
|
475
|
+
});
|
|
476
|
+
return Object.freeze({ version: this.treeVersion, entries: Object.freeze(entries) });
|
|
477
|
+
}
|
|
478
|
+
watch(listener, options = {}) {
|
|
479
|
+
this.assertOpen("watch");
|
|
480
|
+
const watcher = { listener, onError: options.onError };
|
|
481
|
+
this.watchers.add(watcher);
|
|
482
|
+
let closed = false;
|
|
483
|
+
let disposePromise = null;
|
|
484
|
+
const subscription = {
|
|
485
|
+
get closed() {
|
|
486
|
+
return closed;
|
|
487
|
+
},
|
|
488
|
+
ready: Promise.resolve(),
|
|
489
|
+
dispose: () => {
|
|
490
|
+
if (disposePromise) return disposePromise;
|
|
491
|
+
closed = true;
|
|
492
|
+
this.watchers.delete(watcher);
|
|
493
|
+
this.subscriptions.delete(subscription);
|
|
494
|
+
disposePromise = Promise.resolve();
|
|
495
|
+
return disposePromise;
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
this.subscriptions.add(subscription);
|
|
499
|
+
return subscription;
|
|
500
|
+
}
|
|
501
|
+
dispose() {
|
|
502
|
+
if (this.disposePromise) return this.disposePromise;
|
|
503
|
+
this.disposed = true;
|
|
504
|
+
this.disposePromise = Promise.all(
|
|
505
|
+
[...this.subscriptions].map((subscription) => subscription.dispose())
|
|
506
|
+
).then(() => void 0);
|
|
507
|
+
return this.disposePromise;
|
|
508
|
+
}
|
|
509
|
+
canonical(path) {
|
|
510
|
+
return parseWorkspacePath(path);
|
|
511
|
+
}
|
|
512
|
+
canonicalNonRoot(path, operation) {
|
|
513
|
+
const canonical = this.canonical(path);
|
|
514
|
+
if (!canonical) {
|
|
515
|
+
throw this.error(
|
|
516
|
+
"invalid-path",
|
|
517
|
+
operation,
|
|
518
|
+
canonical,
|
|
519
|
+
"The workspace root is not a file entry."
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return canonical;
|
|
523
|
+
}
|
|
524
|
+
assertOpen(operation) {
|
|
525
|
+
if (!this.disposed) return;
|
|
526
|
+
throw new FsError("disposed", "Filesystem provider is disposed.", { operation });
|
|
527
|
+
}
|
|
528
|
+
assertExpectedVersion(entry, expected, operation, path) {
|
|
529
|
+
if (expected === void 0) return;
|
|
530
|
+
if (expected === null ? !entry : entry?.version === expected) return;
|
|
531
|
+
throw this.error(
|
|
532
|
+
"conflict",
|
|
533
|
+
operation,
|
|
534
|
+
path,
|
|
535
|
+
"Entry version does not match the expected version."
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
planParents(path, createParents, operation) {
|
|
539
|
+
const missing = [];
|
|
540
|
+
for (const parent of parentChain(path)) {
|
|
541
|
+
if (!parent) continue;
|
|
542
|
+
const entry = this.entries.get(parent);
|
|
543
|
+
if (entry?.kind === "file") {
|
|
544
|
+
throw this.error(
|
|
545
|
+
"type-mismatch",
|
|
546
|
+
operation,
|
|
547
|
+
parent,
|
|
548
|
+
"A parent path is a file, not a directory."
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
if (!entry) {
|
|
552
|
+
if (!createParents) {
|
|
553
|
+
throw this.error("not-found", operation, parent, "Parent directory does not exist.");
|
|
554
|
+
}
|
|
555
|
+
missing.push(parent);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return missing;
|
|
559
|
+
}
|
|
560
|
+
addDirectories(target, paths, version, lastModified) {
|
|
561
|
+
for (const path of paths) {
|
|
562
|
+
target.set(path, { kind: "directory", version, lastModified });
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
touchParents(target, path, version, lastModified) {
|
|
566
|
+
for (const parent of parentChain(path)) {
|
|
567
|
+
const entry = target.get(parent);
|
|
568
|
+
if (entry?.kind === "directory") {
|
|
569
|
+
target.set(parent, { kind: "directory", version, lastModified });
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
withVersion(entry, version, lastModified) {
|
|
574
|
+
return entry.kind === "file" ? {
|
|
575
|
+
kind: "file",
|
|
576
|
+
data: entry.data,
|
|
577
|
+
payloadKind: entry.payloadKind,
|
|
578
|
+
version,
|
|
579
|
+
lastModified
|
|
580
|
+
} : { kind: "directory", version, lastModified };
|
|
581
|
+
}
|
|
582
|
+
nextVersion() {
|
|
583
|
+
this.mutationCounter += 1;
|
|
584
|
+
this.treeVersion = parseFileSystemVersion(`${this.id}:${this.mutationCounter}`);
|
|
585
|
+
return this.treeVersion;
|
|
586
|
+
}
|
|
587
|
+
toEntrySnapshot(path, entry) {
|
|
588
|
+
return entry.kind === "file" ? this.toFileSnapshot(path, entry) : this.toDirectorySnapshot(path, entry);
|
|
589
|
+
}
|
|
590
|
+
toFileSnapshot(path, entry) {
|
|
591
|
+
return Object.freeze({
|
|
592
|
+
kind: "file",
|
|
593
|
+
path,
|
|
594
|
+
name: workspacePathBasename(path),
|
|
595
|
+
size: entry.data.byteLength,
|
|
596
|
+
version: entry.version,
|
|
597
|
+
lastModified: entry.lastModified
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
toDirectorySnapshot(path, entry) {
|
|
601
|
+
return Object.freeze({
|
|
602
|
+
kind: "directory",
|
|
603
|
+
path,
|
|
604
|
+
name: workspacePathBasename(path),
|
|
605
|
+
size: null,
|
|
606
|
+
version: entry.version,
|
|
607
|
+
lastModified: entry.lastModified
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
emit(event) {
|
|
611
|
+
const complete = Object.freeze({
|
|
612
|
+
...event,
|
|
613
|
+
sequence: ++this.eventSequence,
|
|
614
|
+
origin: "local"
|
|
615
|
+
});
|
|
616
|
+
this.pendingEvents.push(complete);
|
|
617
|
+
if (this.emittingEvents) return;
|
|
618
|
+
this.emittingEvents = true;
|
|
619
|
+
try {
|
|
620
|
+
while (this.pendingEvents.length > 0) {
|
|
621
|
+
const pending = this.pendingEvents.shift();
|
|
622
|
+
if (!pending) continue;
|
|
623
|
+
for (const watcher of [...this.watchers]) {
|
|
624
|
+
try {
|
|
625
|
+
watcher.listener(pending);
|
|
626
|
+
} catch {
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
} finally {
|
|
631
|
+
this.emittingEvents = false;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
error(code, operation, path, message) {
|
|
635
|
+
return new FsError(code, message, { operation, path });
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
function parentChain(path) {
|
|
639
|
+
const parents = [];
|
|
640
|
+
let current = workspacePathDirname(path);
|
|
641
|
+
while (true) {
|
|
642
|
+
parents.unshift(current);
|
|
643
|
+
if (!current) return parents;
|
|
644
|
+
current = workspacePathDirname(current);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
function addParentPaths(target, path) {
|
|
648
|
+
for (const parent of parentChain(path)) {
|
|
649
|
+
if (parent) target.add(parent);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
function isMemoryFilePayloadKind(value) {
|
|
653
|
+
return value === "text" || value === "binary";
|
|
654
|
+
}
|
|
655
|
+
function copyBytes(data) {
|
|
656
|
+
const source = ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);
|
|
657
|
+
const copy = new Uint8Array(source.byteLength);
|
|
658
|
+
copy.set(source);
|
|
659
|
+
return copy.buffer;
|
|
660
|
+
}
|
|
661
|
+
function compareSnapshots(left, right) {
|
|
662
|
+
if (left.kind !== right.kind) return left.kind === "directory" ? -1 : 1;
|
|
663
|
+
return compareText(left.name, right.name);
|
|
664
|
+
}
|
|
665
|
+
function compareText(left, right) {
|
|
666
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// src/filesystem/memory-provider.ts
|
|
670
|
+
function canonicalPath(path) {
|
|
671
|
+
return parseWorkspacePath(path);
|
|
672
|
+
}
|
|
673
|
+
function entryPath(path, operation) {
|
|
674
|
+
const canonical = canonicalPath(path);
|
|
675
|
+
if (!canonical) {
|
|
676
|
+
throw new FsError("invalid-path", "The workspace root is not a file entry.", {
|
|
677
|
+
operation,
|
|
678
|
+
path
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
return canonical;
|
|
682
|
+
}
|
|
683
|
+
function decode(data) {
|
|
684
|
+
return new TextDecoder().decode(data);
|
|
685
|
+
}
|
|
686
|
+
var MemoryFileSystemProvider = class {
|
|
687
|
+
constructor(id, label) {
|
|
688
|
+
this.id = id;
|
|
689
|
+
this.label = label;
|
|
690
|
+
this.v2 = new MemoryFileSystemProviderV2(id, label);
|
|
691
|
+
}
|
|
692
|
+
/** Monotonic version of the complete in-memory tree. */
|
|
693
|
+
get treeVersion() {
|
|
694
|
+
return this.v2.mutationRevision;
|
|
695
|
+
}
|
|
696
|
+
/** Capture an owned deterministic copy of the complete transient tree. */
|
|
697
|
+
captureContents() {
|
|
698
|
+
const state = this.v2.captureState();
|
|
699
|
+
return {
|
|
700
|
+
files: state.files.map(
|
|
701
|
+
(file) => file.payloadKind === "text" ? { kind: "text", path: file.path, content: decode(file.data) } : { kind: "binary", path: file.path, data: file.data.slice(0) }
|
|
702
|
+
),
|
|
703
|
+
directories: [...state.directories]
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
/** Atomically replace the complete tree after validating and owning all input. */
|
|
707
|
+
replaceContents(snapshot, expectedTreeVersion) {
|
|
708
|
+
const files = snapshot.files.map((file) => ({
|
|
709
|
+
path: entryPath(file.path, "write"),
|
|
710
|
+
payloadKind: file.kind,
|
|
711
|
+
data: file.kind === "text" ? new TextEncoder().encode(file.content) : file.data
|
|
712
|
+
}));
|
|
713
|
+
const directories = (snapshot.directories ?? []).map(
|
|
714
|
+
(path) => entryPath(path, "create-directory")
|
|
715
|
+
);
|
|
716
|
+
this.v2.replaceState({ files, directories }, expectedTreeVersion);
|
|
717
|
+
}
|
|
718
|
+
/** Seed synchronously before publishing a transient provider to consumers. */
|
|
719
|
+
seedText(path, content) {
|
|
720
|
+
this.v2.seedText(entryPath(path, "write"), content);
|
|
721
|
+
}
|
|
722
|
+
async readFile(path) {
|
|
723
|
+
const file = await this.v2.readFile(entryPath(path, "read"));
|
|
724
|
+
return file ? decode(file.data) : null;
|
|
725
|
+
}
|
|
726
|
+
async writeFile(path, content) {
|
|
727
|
+
await this.v2.writeText(entryPath(path, "write"), content, { createParents: true });
|
|
728
|
+
}
|
|
729
|
+
commitFile(path, content, expectedContent) {
|
|
730
|
+
return this.v2.commitText(entryPath(path, "write"), content, expectedContent);
|
|
731
|
+
}
|
|
732
|
+
async delete(path) {
|
|
733
|
+
await this.v2.remove(entryPath(path, "remove"), { recursive: true, missing: "ignore" });
|
|
734
|
+
}
|
|
735
|
+
async rename(oldPath, newPath) {
|
|
736
|
+
await this.v2.move(entryPath(oldPath, "move"), entryPath(newPath, "move"), {
|
|
737
|
+
createParents: true
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
async readDirectory(path) {
|
|
741
|
+
const canonical = canonicalPath(path);
|
|
742
|
+
try {
|
|
743
|
+
const entries = await this.v2.readDirectory(canonical);
|
|
744
|
+
return entries.map((entry) => ({
|
|
745
|
+
kind: entry.kind,
|
|
746
|
+
name: entry.name,
|
|
747
|
+
path: entry.path
|
|
748
|
+
}));
|
|
749
|
+
} catch (error) {
|
|
750
|
+
if (error instanceof FsError && error.code === "not-found") return [];
|
|
751
|
+
throw error;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
async exists(path) {
|
|
755
|
+
return await this.v2.stat(canonicalPath(path)) !== null;
|
|
756
|
+
}
|
|
757
|
+
async createDirectory(path) {
|
|
758
|
+
await this.v2.createDirectory(canonicalPath(path), { createParents: true });
|
|
759
|
+
}
|
|
760
|
+
async stat(path) {
|
|
761
|
+
const canonical = canonicalPath(path);
|
|
762
|
+
if (!canonical) return null;
|
|
763
|
+
const entry = await this.v2.stat(canonical);
|
|
764
|
+
if (!entry || entry.kind !== "file") return null;
|
|
765
|
+
return {
|
|
766
|
+
name: entry.name,
|
|
767
|
+
path: entry.path,
|
|
768
|
+
size: entry.size,
|
|
769
|
+
lastModified: entry.lastModified
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
async readBinary(path) {
|
|
773
|
+
const canonical = entryPath(path, "read");
|
|
774
|
+
const file = this.v2.readCompatibilityFile(canonical);
|
|
775
|
+
if (!file || file.payloadKind !== "binary") return null;
|
|
776
|
+
return file.data;
|
|
777
|
+
}
|
|
778
|
+
async writeBinary(path, data) {
|
|
779
|
+
await this.v2.writeBinary(entryPath(path, "write"), data, { createParents: true });
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
export {
|
|
784
|
+
MemoryFileSystemProviderV2,
|
|
785
|
+
MemoryFileSystemProvider
|
|
786
|
+
};
|
|
787
|
+
//# sourceMappingURL=chunk-RQJRQF46.js.map
|