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