@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/filesystem/indexeddb-store.ts"],"sourcesContent":["/**\n * Minimal, error-propagating IndexedDB store used by the virtual filesystem.\n *\n * The previous Squisq LocalForage adapter intentionally converted failed\n * reads/enumerations/removals into null/empty/success. Those semantics are\n * unsuitable for filesystem mutations: an unavailable database must never be\n * interpreted as an absent file. This layer opens the old database and object\n * store directly so existing data can be migrated in one transaction.\n */\n\nexport type IndexedDBFileSystemTransactionMode = 'readonly' | 'readwrite';\n\n/** The database holding one browser-local workspace's files. */\nexport function indexedDBWorkspaceDatabaseName(workspaceId: string): string {\n return `docblocks-fs-${workspaceId}`;\n}\n\n/**\n * Delete a database and everything in it.\n *\n * Open connections do not have to be closed first: deletion fires\n * `versionchange` on them, and this module's connections close themselves in\n * response, after which the deletion proceeds. A `blocked` event is therefore\n * transient (an in-flight transaction) and is deliberately not treated as a\n * failure — the deletion still completes once that transaction finishes.\n */\nexport function deleteIndexedDBDatabase(databaseName: string): Promise<void> {\n if (typeof indexedDB === 'undefined') {\n return Promise.reject(new Error('IndexedDB is not available in this environment.'));\n }\n return new Promise((resolve, reject) => {\n const request = indexedDB.deleteDatabase(databaseName);\n request.onsuccess = () => resolve();\n request.onerror = () =>\n reject(request.error ?? new Error(`Failed to delete the \"${databaseName}\" database.`));\n });\n}\n\n/**\n * Delete a browser-local workspace's stored files.\n *\n * Removing a workspace descriptor alone leaves these bytes behind: invisible to\n * the user, still counted against the origin's quota, and ready to reappear\n * under any later workspace that reuses the same id.\n */\nexport function deleteIndexedDBWorkspaceData(workspaceId: string): Promise<void> {\n return deleteIndexedDBDatabase(indexedDBWorkspaceDatabaseName(workspaceId));\n}\n\nexport interface IndexedDBFileSystemTransaction {\n get<T>(key: string): Promise<T | null>;\n put<T>(key: string, value: T): Promise<void>;\n delete(key: string): Promise<void>;\n keys(): Promise<string[]>;\n /** O(log n) namespace probe in the concrete IndexedDB implementation. */\n hasKeyWithPrefix(prefix: string): Promise<boolean>;\n}\n\nexport interface IndexedDBFileSystemStore {\n transaction<T>(\n mode: IndexedDBFileSystemTransactionMode,\n operation: (transaction: IndexedDBFileSystemTransaction) => Promise<T>,\n ): Promise<T>;\n close?(): void;\n}\n\nexport class RawIndexedDBFileSystemStore implements IndexedDBFileSystemStore {\n private database: IDBDatabase | null = null;\n private opening: Promise<IDBDatabase> | null = null;\n private closed = false;\n\n public constructor(\n private readonly databaseName: string,\n private readonly storeName: string,\n ) {}\n\n public async transaction<T>(\n mode: IndexedDBFileSystemTransactionMode,\n operation: (transaction: IndexedDBFileSystemTransaction) => Promise<T>,\n ): Promise<T> {\n const database = await this.getDatabase();\n const nativeTransaction = database.transaction(this.storeName, mode);\n const completion = waitForTransaction(nativeTransaction);\n const transaction = new RawIndexedDBFileSystemTransaction(\n nativeTransaction.objectStore(this.storeName),\n );\n\n let result: T;\n try {\n result = await operation(transaction);\n } catch (error: unknown) {\n try {\n nativeTransaction.abort();\n } catch {\n // The request failure may already have aborted the transaction.\n }\n await completion.catch(() => undefined);\n throw error;\n }\n\n await completion;\n return result;\n }\n\n public close(): void {\n if (this.closed) return;\n this.closed = true;\n this.database?.close();\n this.database = null;\n this.opening = null;\n }\n\n private getDatabase(): Promise<IDBDatabase> {\n if (this.closed) {\n return Promise.reject(new Error('The IndexedDB filesystem store is closed.'));\n }\n if (this.database) return Promise.resolve(this.database);\n if (this.opening) return this.opening;\n if (typeof indexedDB === 'undefined') {\n return Promise.reject(new Error('IndexedDB is not available in this environment.'));\n }\n\n this.opening = openDatabaseWithStore(this.databaseName, this.storeName)\n .then((database) => {\n if (this.closed) {\n database.close();\n throw new Error('The IndexedDB filesystem store is closed.');\n }\n this.database = database;\n this.opening = null;\n database.onversionchange = () => {\n database.close();\n if (this.database === database) this.database = null;\n };\n return database;\n })\n .catch((error: unknown) => {\n this.opening = null;\n throw error;\n });\n return this.opening;\n }\n}\n\nclass RawIndexedDBFileSystemTransaction implements IndexedDBFileSystemTransaction {\n public constructor(private readonly store: IDBObjectStore) {}\n\n public async get<T>(key: string): Promise<T | null> {\n const value = await requestResult(this.store.get(key));\n return value === undefined ? null : (value as T);\n }\n\n public async put<T>(key: string, value: T): Promise<void> {\n await requestResult(this.store.put(value, key));\n }\n\n public async delete(key: string): Promise<void> {\n await requestResult(this.store.delete(key));\n }\n\n public async keys(): Promise<string[]> {\n const keys = await requestResult(this.store.getAllKeys());\n return keys.map((key) => {\n if (typeof key !== 'string') {\n throw new Error('The DocBlocks filesystem store contains a non-string key.');\n }\n return key;\n });\n }\n\n public async hasKeyWithPrefix(prefix: string): Promise<boolean> {\n const cursor = await requestResult(this.store.openKeyCursor(IDBKeyRange.lowerBound(prefix)));\n return cursor !== null && typeof cursor.key === 'string' && cursor.key.startsWith(prefix);\n }\n}\n\nasync function openDatabaseWithStore(\n databaseName: string,\n storeName: string,\n): Promise<IDBDatabase> {\n const database = await openDatabase(databaseName, undefined, (upgradeDatabase) => {\n if (!upgradeDatabase.objectStoreNames.contains(storeName)) {\n upgradeDatabase.createObjectStore(storeName);\n }\n });\n if (database.objectStoreNames.contains(storeName)) return database;\n\n const nextVersion = database.version + 1;\n database.close();\n return openDatabase(databaseName, nextVersion, (upgradeDatabase) => {\n if (!upgradeDatabase.objectStoreNames.contains(storeName)) {\n upgradeDatabase.createObjectStore(storeName);\n }\n });\n}\n\nfunction openDatabase(\n databaseName: string,\n version: number | undefined,\n upgrade: (database: IDBDatabase) => void,\n): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request =\n version === undefined ? indexedDB.open(databaseName) : indexedDB.open(databaseName, version);\n let settled = false;\n\n request.onupgradeneeded = () => upgrade(request.result);\n request.onsuccess = () => {\n if (settled) {\n request.result.close();\n return;\n }\n settled = true;\n resolve(request.result);\n };\n request.onerror = () => {\n if (settled) return;\n settled = true;\n reject(request.error ?? new Error(`Could not open IndexedDB database ${databaseName}.`));\n };\n request.onblocked = () => {\n if (settled) return;\n settled = true;\n reject(new Error(`IndexedDB database ${databaseName} is blocked by another open page.`));\n };\n });\n}\n\nfunction requestResult<T>(request: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error('IndexedDB request failed.'));\n });\n}\n\nfunction waitForTransaction(transaction: IDBTransaction): Promise<void> {\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => resolve();\n transaction.onabort = () =>\n reject(transaction.error ?? new Error('IndexedDB transaction was aborted.'));\n transaction.onerror = () =>\n reject(transaction.error ?? new Error('IndexedDB transaction failed.'));\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/filesystem/internal/records.ts"],"sourcesContent":["/**\n * Structural guard shared by the filesystem providers that validate untrusted\n * payloads — stored IndexedDB records and Electron transport messages.\n */\n\n/** True for any non-null object, including arrays and class instances. */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":";AAMO,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;","names":[]}
|
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ELECTRON_FILE_SYSTEM_V2_CAPABILITIES,
|
|
3
|
+
maybeGetDocBlocksHost
|
|
4
|
+
} from "./chunk-BNKV7MTO.js";
|
|
5
|
+
import {
|
|
6
|
+
isRecord
|
|
7
|
+
} from "./chunk-U722UUFN.js";
|
|
8
|
+
import {
|
|
9
|
+
compareSnapshotsByPath,
|
|
10
|
+
compareText,
|
|
11
|
+
copyBytes,
|
|
12
|
+
parseFileSystemVersion
|
|
13
|
+
} from "./chunk-P4WATND4.js";
|
|
14
|
+
import {
|
|
15
|
+
FsError,
|
|
16
|
+
WORKSPACE_ROOT,
|
|
17
|
+
deserializeFsError,
|
|
18
|
+
fsErrorFromUnknown,
|
|
19
|
+
isSerializedFsError,
|
|
20
|
+
parseWorkspacePath,
|
|
21
|
+
workspacePathBasename,
|
|
22
|
+
workspacePathDirname
|
|
23
|
+
} from "./chunk-JS6XFWQK.js";
|
|
24
|
+
|
|
25
|
+
// src/filesystem/electron-provider-v2.ts
|
|
26
|
+
var fallbackInstanceSequence = 0;
|
|
27
|
+
function getHostFsV2(operation) {
|
|
28
|
+
const host = maybeGetDocBlocksHost();
|
|
29
|
+
if (!host?.fsV2) {
|
|
30
|
+
throw new FsError("not-supported", "Electron filesystem v2 host is unavailable.", {
|
|
31
|
+
operation
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return host.fsV2;
|
|
35
|
+
}
|
|
36
|
+
var ElectronFileSystemProviderV2 = class {
|
|
37
|
+
constructor(id, label, rootPath) {
|
|
38
|
+
this.capabilities = ELECTRON_FILE_SYSTEM_V2_CAPABILITIES;
|
|
39
|
+
this.instanceId = createInstanceId();
|
|
40
|
+
this.watchers = /* @__PURE__ */ new Map();
|
|
41
|
+
this.subscriptions = /* @__PURE__ */ new Set();
|
|
42
|
+
this.inFlight = /* @__PURE__ */ new Set();
|
|
43
|
+
this.openPromise = null;
|
|
44
|
+
this.removeWatchBridge = null;
|
|
45
|
+
this.disposePromise = null;
|
|
46
|
+
this.hostOpened = false;
|
|
47
|
+
this.disposed = false;
|
|
48
|
+
this.id = id;
|
|
49
|
+
this.label = label;
|
|
50
|
+
this.rootPath = rootPath;
|
|
51
|
+
}
|
|
52
|
+
getRootPath() {
|
|
53
|
+
return this.rootPath;
|
|
54
|
+
}
|
|
55
|
+
async stat(path) {
|
|
56
|
+
const canonical = parseWorkspacePath(String(path));
|
|
57
|
+
return this.request(
|
|
58
|
+
"stat",
|
|
59
|
+
() => getHostFsV2("stat").stat(this.instanceId, canonical),
|
|
60
|
+
(value) => value ? normalizeEntry(value) : null
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
async readFile(path) {
|
|
64
|
+
const canonical = parseWorkspacePath(String(path));
|
|
65
|
+
return this.request(
|
|
66
|
+
"read",
|
|
67
|
+
() => getHostFsV2("read").readFile(this.instanceId, canonical),
|
|
68
|
+
(value) => {
|
|
69
|
+
if (!value) return null;
|
|
70
|
+
const entry = normalizeFile(value.entry);
|
|
71
|
+
const data = copyWireBuffer(value.data);
|
|
72
|
+
if (data.byteLength !== entry.size) {
|
|
73
|
+
throw new TypeError("Filesystem transport returned file bytes with the wrong size.");
|
|
74
|
+
}
|
|
75
|
+
return Object.freeze({ entry, data });
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
async readDirectory(path) {
|
|
80
|
+
const canonical = parseWorkspacePath(String(path));
|
|
81
|
+
return this.request(
|
|
82
|
+
"list",
|
|
83
|
+
() => getHostFsV2("list").readDirectory(this.instanceId, canonical),
|
|
84
|
+
(value) => normalizeDirectoryListing(value, canonical)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
async writeFile(path, data, options) {
|
|
88
|
+
const canonical = parseWorkspacePath(String(path));
|
|
89
|
+
const owned = copyBytes(data);
|
|
90
|
+
return this.request(
|
|
91
|
+
"write",
|
|
92
|
+
() => getHostFsV2("write").writeFile(this.instanceId, canonical, owned, options),
|
|
93
|
+
normalizeFile
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
async createDirectory(path, options) {
|
|
97
|
+
const canonical = parseWorkspacePath(String(path));
|
|
98
|
+
return this.request(
|
|
99
|
+
"create-directory",
|
|
100
|
+
() => getHostFsV2("create-directory").createDirectory(this.instanceId, canonical, options),
|
|
101
|
+
normalizeDirectory
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
async remove(path, options) {
|
|
105
|
+
const canonical = parseWorkspacePath(String(path));
|
|
106
|
+
return this.request(
|
|
107
|
+
"remove",
|
|
108
|
+
() => getHostFsV2("remove").remove(this.instanceId, canonical, options),
|
|
109
|
+
normalizeRemoveResult
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
async move(oldPath, newPath, options) {
|
|
113
|
+
const source = parseWorkspacePath(String(oldPath));
|
|
114
|
+
const destination = parseWorkspacePath(String(newPath));
|
|
115
|
+
return this.request(
|
|
116
|
+
"move",
|
|
117
|
+
() => getHostFsV2("move").move(this.instanceId, source, destination, options),
|
|
118
|
+
normalizeEntry
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
async snapshot() {
|
|
122
|
+
return this.request(
|
|
123
|
+
"snapshot",
|
|
124
|
+
() => getHostFsV2("snapshot").snapshot(this.instanceId),
|
|
125
|
+
normalizeSnapshot
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
watch(listener, options = {}) {
|
|
129
|
+
this.assertOpen("watch");
|
|
130
|
+
this.ensureWatchBridge();
|
|
131
|
+
const subscriptionId = createInstanceId();
|
|
132
|
+
const watcher = { listener, onError: options.onError };
|
|
133
|
+
this.watchers.set(subscriptionId, watcher);
|
|
134
|
+
let closed = false;
|
|
135
|
+
let subscribed = false;
|
|
136
|
+
let closePromise = null;
|
|
137
|
+
const ready = this.ensureOpen("watch").then(async () => {
|
|
138
|
+
if (closed) return;
|
|
139
|
+
unwrap(await getHostFsV2("watch").watchSubscribe(this.instanceId, subscriptionId), "watch");
|
|
140
|
+
subscribed = true;
|
|
141
|
+
}).catch((error) => {
|
|
142
|
+
closed = true;
|
|
143
|
+
this.watchers.delete(subscriptionId);
|
|
144
|
+
const typed = error instanceof FsError ? error : new FsError("io", String(error));
|
|
145
|
+
try {
|
|
146
|
+
watcher.onError?.(typed);
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
throw typed;
|
|
150
|
+
});
|
|
151
|
+
const subscription = {
|
|
152
|
+
get closed() {
|
|
153
|
+
return closed;
|
|
154
|
+
},
|
|
155
|
+
ready,
|
|
156
|
+
dispose: () => {
|
|
157
|
+
if (closePromise) return closePromise;
|
|
158
|
+
closed = true;
|
|
159
|
+
this.watchers.delete(subscriptionId);
|
|
160
|
+
this.subscriptions.delete(subscription);
|
|
161
|
+
closePromise = (async () => {
|
|
162
|
+
await ready.catch(() => void 0);
|
|
163
|
+
if (subscribed) {
|
|
164
|
+
unwrap(
|
|
165
|
+
await getHostFsV2("watch").watchUnsubscribe(this.instanceId, subscriptionId),
|
|
166
|
+
"watch"
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
})();
|
|
170
|
+
return closePromise;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
this.subscriptions.add(subscription);
|
|
174
|
+
return subscription;
|
|
175
|
+
}
|
|
176
|
+
dispose() {
|
|
177
|
+
if (this.disposePromise) return this.disposePromise;
|
|
178
|
+
this.disposed = true;
|
|
179
|
+
this.disposePromise = (async () => {
|
|
180
|
+
await Promise.allSettled([...this.inFlight]);
|
|
181
|
+
await Promise.all([...this.subscriptions].map((subscription) => subscription.dispose()));
|
|
182
|
+
try {
|
|
183
|
+
if (this.openPromise) {
|
|
184
|
+
try {
|
|
185
|
+
await this.openPromise;
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (this.hostOpened) {
|
|
190
|
+
try {
|
|
191
|
+
unwrap(await getHostFsV2("dispose").dispose(this.instanceId), "dispose");
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (!(error instanceof FsError && error.code === "closed")) throw error;
|
|
194
|
+
} finally {
|
|
195
|
+
this.hostOpened = false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} finally {
|
|
199
|
+
this.removeWatchBridge?.();
|
|
200
|
+
this.removeWatchBridge = null;
|
|
201
|
+
}
|
|
202
|
+
})();
|
|
203
|
+
return this.disposePromise;
|
|
204
|
+
}
|
|
205
|
+
request(operation, send, normalize) {
|
|
206
|
+
this.assertOpen(operation);
|
|
207
|
+
const promise = this.ensureOpen(operation).then(async () => {
|
|
208
|
+
try {
|
|
209
|
+
return normalize(unwrap(await send(), operation));
|
|
210
|
+
} catch (error) {
|
|
211
|
+
throw transportErrorFromUnknown(error, operation);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
this.inFlight.add(promise);
|
|
215
|
+
void promise.then(
|
|
216
|
+
() => this.inFlight.delete(promise),
|
|
217
|
+
() => this.inFlight.delete(promise)
|
|
218
|
+
);
|
|
219
|
+
return promise;
|
|
220
|
+
}
|
|
221
|
+
ensureOpen(operation) {
|
|
222
|
+
this.assertOpen(operation);
|
|
223
|
+
if (!this.openPromise) {
|
|
224
|
+
const attempt = getHostFsV2(operation).open({
|
|
225
|
+
instanceId: this.instanceId,
|
|
226
|
+
providerId: this.id,
|
|
227
|
+
label: this.label
|
|
228
|
+
}).then((result) => {
|
|
229
|
+
if (isRecord(result) && result.ok === true) this.hostOpened = true;
|
|
230
|
+
const capabilities = unwrap(result, operation);
|
|
231
|
+
assertCapabilities(capabilities, operation);
|
|
232
|
+
}).catch((error) => {
|
|
233
|
+
const typed = withOperation(fsErrorFromUnknown(error, { operation }), operation);
|
|
234
|
+
if (typed.retryable && this.openPromise === attempt) this.openPromise = null;
|
|
235
|
+
throw typed;
|
|
236
|
+
});
|
|
237
|
+
this.openPromise = attempt;
|
|
238
|
+
}
|
|
239
|
+
return this.openPromise;
|
|
240
|
+
}
|
|
241
|
+
ensureWatchBridge() {
|
|
242
|
+
if (this.removeWatchBridge) return;
|
|
243
|
+
this.removeWatchBridge = getHostFsV2("watch").onWatchMessage(
|
|
244
|
+
(message) => this.handleWatchMessage(message)
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
handleWatchMessage(message) {
|
|
248
|
+
if (message.instanceId !== this.instanceId) return;
|
|
249
|
+
const watcher = this.watchers.get(message.subscriptionId);
|
|
250
|
+
if (!watcher) return;
|
|
251
|
+
if (message.kind === "error") {
|
|
252
|
+
const typed = isSerializedFsError(message.error) ? deserializeFsError(message.error) : invalidTransport("watch", "Filesystem transport returned an invalid watch error.");
|
|
253
|
+
try {
|
|
254
|
+
watcher.onError?.(typed);
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
let event;
|
|
260
|
+
try {
|
|
261
|
+
event = normalizeWatchEvent(message.event);
|
|
262
|
+
} catch (error) {
|
|
263
|
+
try {
|
|
264
|
+
watcher.onError?.(transportErrorFromUnknown(error, "watch"));
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
watcher.listener(event);
|
|
271
|
+
} catch {
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
assertOpen(operation) {
|
|
275
|
+
if (!this.disposed) return;
|
|
276
|
+
throw new FsError("disposed", "Filesystem provider is disposed.", { operation });
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
function unwrap(result, operation) {
|
|
280
|
+
if (!isRecord(result) || typeof result.ok !== "boolean") {
|
|
281
|
+
throw invalidTransport(operation, "Filesystem transport returned an invalid result envelope.");
|
|
282
|
+
}
|
|
283
|
+
if (result.ok) {
|
|
284
|
+
if (!("value" in result)) {
|
|
285
|
+
throw invalidTransport(operation, "Filesystem transport omitted a result value.");
|
|
286
|
+
}
|
|
287
|
+
return result.value;
|
|
288
|
+
}
|
|
289
|
+
if (!isSerializedFsError(result.error)) {
|
|
290
|
+
throw invalidTransport(operation, "Filesystem transport returned an invalid error envelope.");
|
|
291
|
+
}
|
|
292
|
+
throw deserializeFsError(result.error);
|
|
293
|
+
}
|
|
294
|
+
function normalizeEntry(entry) {
|
|
295
|
+
if (!isRecord(entry)) throw new TypeError("Expected a filesystem entry object.");
|
|
296
|
+
if (typeof entry.path !== "string")
|
|
297
|
+
throw new TypeError("Filesystem entry path must be a string.");
|
|
298
|
+
if (typeof entry.name !== "string")
|
|
299
|
+
throw new TypeError("Filesystem entry name must be a string.");
|
|
300
|
+
if (typeof entry.lastModified !== "string") {
|
|
301
|
+
throw new TypeError("Filesystem entry timestamp must be a string.");
|
|
302
|
+
}
|
|
303
|
+
const path = parseWorkspacePath(entry.path);
|
|
304
|
+
if (entry.name !== workspacePathBasename(path)) {
|
|
305
|
+
throw new TypeError("Filesystem entry name does not match its canonical path.");
|
|
306
|
+
}
|
|
307
|
+
const common = {
|
|
308
|
+
path,
|
|
309
|
+
name: entry.name,
|
|
310
|
+
version: parseFileSystemVersion(entry.version),
|
|
311
|
+
lastModified: new Date(entry.lastModified).toISOString()
|
|
312
|
+
};
|
|
313
|
+
if (entry.kind === "file") {
|
|
314
|
+
if (!isNonNegativeSafeInteger(entry.size)) {
|
|
315
|
+
throw new TypeError("Filesystem file size must be a non-negative safe integer.");
|
|
316
|
+
}
|
|
317
|
+
return Object.freeze({ ...common, kind: "file", size: entry.size });
|
|
318
|
+
}
|
|
319
|
+
if (entry.kind === "directory") {
|
|
320
|
+
if (entry.size !== null) throw new TypeError("Filesystem directory size must be null.");
|
|
321
|
+
return Object.freeze({ ...common, kind: "directory", size: null });
|
|
322
|
+
}
|
|
323
|
+
throw new TypeError("Unknown filesystem entry kind.");
|
|
324
|
+
}
|
|
325
|
+
function normalizeDirectoryListing(value, parent) {
|
|
326
|
+
if (!Array.isArray(value)) throw new TypeError("Expected a filesystem directory listing.");
|
|
327
|
+
const entries = value.map(normalizeEntry);
|
|
328
|
+
const seen = /* @__PURE__ */ new Set();
|
|
329
|
+
for (const entry of entries) {
|
|
330
|
+
if (entry.path === WORKSPACE_ROOT || workspacePathDirname(entry.path) !== parent) {
|
|
331
|
+
throw new TypeError("Filesystem listing contained a non-child entry.");
|
|
332
|
+
}
|
|
333
|
+
if (seen.has(entry.path)) throw new TypeError("Filesystem listing contained a duplicate path.");
|
|
334
|
+
seen.add(entry.path);
|
|
335
|
+
}
|
|
336
|
+
const ordered = [...entries].sort(compareSnapshotsByPath);
|
|
337
|
+
if (ordered.some((entry, index) => entry.path !== entries[index]?.path)) {
|
|
338
|
+
throw new TypeError("Filesystem listing was not in canonical deterministic order.");
|
|
339
|
+
}
|
|
340
|
+
return Object.freeze(entries);
|
|
341
|
+
}
|
|
342
|
+
function normalizeFile(entry) {
|
|
343
|
+
const normalized = normalizeEntry(entry);
|
|
344
|
+
if (normalized.kind !== "file") throw new TypeError("Expected a file snapshot.");
|
|
345
|
+
return normalized;
|
|
346
|
+
}
|
|
347
|
+
function normalizeDirectory(entry) {
|
|
348
|
+
const normalized = normalizeEntry(entry);
|
|
349
|
+
if (normalized.kind !== "directory") throw new TypeError("Expected a directory snapshot.");
|
|
350
|
+
return normalized;
|
|
351
|
+
}
|
|
352
|
+
function normalizeSnapshot(snapshot) {
|
|
353
|
+
if (!isRecord(snapshot) || !Array.isArray(snapshot.entries)) {
|
|
354
|
+
throw new TypeError("Expected a filesystem snapshot object.");
|
|
355
|
+
}
|
|
356
|
+
const version = parseFileSystemVersion(snapshot.version);
|
|
357
|
+
const entries = snapshot.entries.map((entry) => {
|
|
358
|
+
if (entry.kind === "file") {
|
|
359
|
+
const file = normalizeFile(entry);
|
|
360
|
+
const data = copyWireBuffer(entry.data);
|
|
361
|
+
if (data.byteLength !== file.size) {
|
|
362
|
+
throw new TypeError("Filesystem snapshot file bytes have the wrong size.");
|
|
363
|
+
}
|
|
364
|
+
return Object.freeze({ ...file, data });
|
|
365
|
+
}
|
|
366
|
+
if (entry.kind === "directory") return normalizeDirectory(entry);
|
|
367
|
+
throw new TypeError("Unknown filesystem snapshot entry kind.");
|
|
368
|
+
});
|
|
369
|
+
const roots = entries.filter((entry) => entry.path === WORKSPACE_ROOT);
|
|
370
|
+
if (roots.length !== 1 || roots[0]?.kind !== "directory" || roots[0].version !== version) {
|
|
371
|
+
throw new TypeError("Filesystem snapshot must contain one matching root directory.");
|
|
372
|
+
}
|
|
373
|
+
const seen = /* @__PURE__ */ new Set();
|
|
374
|
+
for (const entry of entries) {
|
|
375
|
+
if (seen.has(entry.path))
|
|
376
|
+
throw new TypeError("Filesystem snapshot contained a duplicate path.");
|
|
377
|
+
seen.add(entry.path);
|
|
378
|
+
}
|
|
379
|
+
const ordered = [...entries].sort((left, right) => compareText(left.path, right.path));
|
|
380
|
+
if (ordered.some((entry, index) => entry.path !== entries[index]?.path)) {
|
|
381
|
+
throw new TypeError("Filesystem snapshot was not in canonical deterministic order.");
|
|
382
|
+
}
|
|
383
|
+
return Object.freeze({
|
|
384
|
+
version,
|
|
385
|
+
entries: Object.freeze(entries)
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
function normalizeWatchEvent(event) {
|
|
389
|
+
if (!isRecord(event)) throw new TypeError("Expected a filesystem watch event object.");
|
|
390
|
+
if (!isPositiveSafeInteger(event.sequence)) {
|
|
391
|
+
throw new TypeError("Filesystem watch sequence must be a positive safe integer.");
|
|
392
|
+
}
|
|
393
|
+
if (!isWatchOrigin(event.origin)) throw new TypeError("Unknown filesystem watch origin.");
|
|
394
|
+
if (typeof event.path !== "string") throw new TypeError("Watch event path must be a string.");
|
|
395
|
+
const path = parseWorkspacePath(event.path);
|
|
396
|
+
if (event.type === "overflow") {
|
|
397
|
+
if (event.kind !== null || event.destinationPath !== null || event.version !== null || event.previousVersion !== null) {
|
|
398
|
+
throw new TypeError("Filesystem overflow event has entry-specific fields.");
|
|
399
|
+
}
|
|
400
|
+
return Object.freeze({
|
|
401
|
+
sequence: event.sequence,
|
|
402
|
+
origin: event.origin,
|
|
403
|
+
type: "overflow",
|
|
404
|
+
kind: null,
|
|
405
|
+
path,
|
|
406
|
+
destinationPath: null,
|
|
407
|
+
version: null,
|
|
408
|
+
previousVersion: null
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
if (!isEntryWatchType(event.type)) throw new TypeError("Unknown filesystem watch event type.");
|
|
412
|
+
if (event.kind !== "file" && event.kind !== "directory") {
|
|
413
|
+
throw new TypeError("Unknown filesystem watch entry kind.");
|
|
414
|
+
}
|
|
415
|
+
const destinationPath = event.destinationPath === null ? null : typeof event.destinationPath === "string" ? parseWorkspacePath(event.destinationPath) : (() => {
|
|
416
|
+
throw new TypeError("Watch destination path must be a string or null.");
|
|
417
|
+
})();
|
|
418
|
+
if (event.type === "moved" !== (destinationPath !== null)) {
|
|
419
|
+
throw new TypeError("Only moved watch events may have a destination path.");
|
|
420
|
+
}
|
|
421
|
+
return Object.freeze({
|
|
422
|
+
sequence: event.sequence,
|
|
423
|
+
origin: event.origin,
|
|
424
|
+
type: event.type,
|
|
425
|
+
kind: event.kind,
|
|
426
|
+
path,
|
|
427
|
+
destinationPath,
|
|
428
|
+
version: event.version === null ? null : parseFileSystemVersion(event.version),
|
|
429
|
+
previousVersion: event.previousVersion === null ? null : parseFileSystemVersion(event.previousVersion)
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
function normalizeRemoveResult(value) {
|
|
433
|
+
if (!isRecord(value) || typeof value.removed !== "boolean") {
|
|
434
|
+
throw new TypeError("Filesystem transport returned an invalid remove result.");
|
|
435
|
+
}
|
|
436
|
+
return Object.freeze({ removed: value.removed, version: parseFileSystemVersion(value.version) });
|
|
437
|
+
}
|
|
438
|
+
function assertCapabilities(value, operation) {
|
|
439
|
+
if (!isRecord(value)) {
|
|
440
|
+
throw invalidTransport(operation, "Filesystem host returned invalid capabilities.");
|
|
441
|
+
}
|
|
442
|
+
for (const key of Object.keys(ELECTRON_FILE_SYSTEM_V2_CAPABILITIES)) {
|
|
443
|
+
if (value[key] !== ELECTRON_FILE_SYSTEM_V2_CAPABILITIES[key]) {
|
|
444
|
+
throw invalidTransport(operation, `Filesystem host capability mismatch: ${key}.`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
function isWatchOrigin(value) {
|
|
449
|
+
return value === "local" || value === "external" || value === "unknown";
|
|
450
|
+
}
|
|
451
|
+
function isEntryWatchType(value) {
|
|
452
|
+
return value === "created" || value === "modified" || value === "removed" || value === "moved";
|
|
453
|
+
}
|
|
454
|
+
function isNonNegativeSafeInteger(value) {
|
|
455
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
456
|
+
}
|
|
457
|
+
function isPositiveSafeInteger(value) {
|
|
458
|
+
return isNonNegativeSafeInteger(value) && value > 0;
|
|
459
|
+
}
|
|
460
|
+
function invalidTransport(operation, message) {
|
|
461
|
+
return new FsError("io", message, { operation, retryable: false });
|
|
462
|
+
}
|
|
463
|
+
function transportErrorFromUnknown(error, operation) {
|
|
464
|
+
if (error instanceof TypeError) return invalidTransport(operation, error.message);
|
|
465
|
+
return withOperation(fsErrorFromUnknown(error, { operation }), operation);
|
|
466
|
+
}
|
|
467
|
+
function withOperation(error, operation) {
|
|
468
|
+
if (error.operation === operation) return error;
|
|
469
|
+
return new FsError(error.code, error.message, {
|
|
470
|
+
operation,
|
|
471
|
+
path: error.path ?? void 0,
|
|
472
|
+
destinationPath: error.destinationPath ?? void 0,
|
|
473
|
+
retryable: error.retryable
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function copyWireBuffer(data) {
|
|
477
|
+
if (Object.prototype.toString.call(data) !== "[object ArrayBuffer]") {
|
|
478
|
+
throw new TypeError("Expected an ArrayBuffer from the filesystem transport.");
|
|
479
|
+
}
|
|
480
|
+
return data.slice(0);
|
|
481
|
+
}
|
|
482
|
+
function createInstanceId() {
|
|
483
|
+
const randomUUID = globalThis.crypto?.randomUUID;
|
|
484
|
+
if (typeof randomUUID === "function") return randomUUID.call(globalThis.crypto);
|
|
485
|
+
fallbackInstanceSequence += 1;
|
|
486
|
+
return `electron-fs-v2-${Date.now()}-${fallbackInstanceSequence}`;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// src/filesystem/electron-provider.ts
|
|
490
|
+
function getHostFs() {
|
|
491
|
+
const host = maybeGetDocBlocksHost();
|
|
492
|
+
if (!host) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
"ElectronFileSystemProvider: docBlocksHost is not available \u2014 not running under Electron?"
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
return host.fs;
|
|
498
|
+
}
|
|
499
|
+
var ElectronFileSystemProvider = class {
|
|
500
|
+
constructor(id, label, rootPath) {
|
|
501
|
+
this.id = id;
|
|
502
|
+
this.label = label;
|
|
503
|
+
this.rootPath = rootPath;
|
|
504
|
+
this.v2 = new ElectronFileSystemProviderV2(id, label, rootPath);
|
|
505
|
+
}
|
|
506
|
+
/** Absolute path this provider is rooted at. */
|
|
507
|
+
getRootPath() {
|
|
508
|
+
return this.rootPath;
|
|
509
|
+
}
|
|
510
|
+
readFile(path) {
|
|
511
|
+
return getHostFs().readFile(this.id, path);
|
|
512
|
+
}
|
|
513
|
+
writeFile(path, content) {
|
|
514
|
+
return getHostFs().writeFile(this.id, path, content);
|
|
515
|
+
}
|
|
516
|
+
commitFile(path, content, expectedContent) {
|
|
517
|
+
return getHostFs().commitFile(this.id, path, content, expectedContent);
|
|
518
|
+
}
|
|
519
|
+
delete(path) {
|
|
520
|
+
return getHostFs().delete(this.id, path);
|
|
521
|
+
}
|
|
522
|
+
rename(oldPath, newPath) {
|
|
523
|
+
return getHostFs().rename(this.id, oldPath, newPath);
|
|
524
|
+
}
|
|
525
|
+
readDirectory(path) {
|
|
526
|
+
return getHostFs().readDirectory(this.id, path);
|
|
527
|
+
}
|
|
528
|
+
exists(path) {
|
|
529
|
+
return getHostFs().exists(this.id, path);
|
|
530
|
+
}
|
|
531
|
+
createDirectory(path) {
|
|
532
|
+
return getHostFs().createDirectory(this.id, path);
|
|
533
|
+
}
|
|
534
|
+
stat(path) {
|
|
535
|
+
return getHostFs().stat(this.id, path);
|
|
536
|
+
}
|
|
537
|
+
readBinary(path) {
|
|
538
|
+
return getHostFs().readBinary(this.id, path);
|
|
539
|
+
}
|
|
540
|
+
writeBinary(path, data) {
|
|
541
|
+
return getHostFs().writeBinary(this.id, path, data);
|
|
542
|
+
}
|
|
543
|
+
/** Subscribe to external change notifications under this root. */
|
|
544
|
+
watch(onChange) {
|
|
545
|
+
return getHostFs().watch(this.id, onChange);
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
export {
|
|
550
|
+
ElectronFileSystemProviderV2,
|
|
551
|
+
ElectronFileSystemProvider
|
|
552
|
+
};
|
|
553
|
+
//# sourceMappingURL=chunk-VTCSF7VS.js.map
|