@bendyline/docblocks 2.0.0 → 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/dist/{chunk-J32GU3F3.js → chunk-6IYMTYMQ.js} +249 -221
- package/dist/chunk-6IYMTYMQ.js.map +1 -0
- package/dist/{chunk-75UUF6C4.js → chunk-B56KWCSE.js} +2 -2
- package/dist/{chunk-RVQHY3XU.js → chunk-BNKV7MTO.js} +1 -1
- package/dist/{chunk-RVQHY3XU.js.map → chunk-BNKV7MTO.js.map} +1 -1
- package/dist/chunk-BXMF5YQJ.js +149 -0
- package/dist/chunk-BXMF5YQJ.js.map +1 -0
- package/dist/{chunk-PGR7LK6D.js → chunk-COYQXQK3.js} +14 -5
- package/dist/chunk-COYQXQK3.js.map +1 -0
- package/dist/{chunk-RQJRQF46.js → chunk-DN7A33LL.js} +42 -49
- package/dist/chunk-DN7A33LL.js.map +1 -0
- package/dist/chunk-FA7UNOXK.js +20 -0
- package/dist/chunk-FA7UNOXK.js.map +1 -0
- package/dist/chunk-GM5YXU4L.js +29 -0
- package/dist/chunk-GM5YXU4L.js.map +1 -0
- package/dist/{chunk-SI2LU2RP.js → chunk-JS6XFWQK.js} +2 -1
- package/dist/chunk-JS6XFWQK.js.map +1 -0
- package/dist/{chunk-EGNDADXB.js → chunk-MNSZ7EZN.js} +2 -2
- 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-GCPBEMMH.js → chunk-VTCSF7VS.js} +11 -21
- package/dist/chunk-VTCSF7VS.js.map +1 -0
- package/dist/{chunk-2D7Y4IR3.js → chunk-WJKYY5QR.js} +123 -66
- package/dist/chunk-WJKYY5QR.js.map +1 -0
- package/dist/{chunk-5MYAICRE.js → chunk-XUML3MKV.js} +44 -56
- package/dist/chunk-XUML3MKV.js.map +1 -0
- package/dist/document/index.d.ts +358 -6
- package/dist/document/index.js +24 -3
- package/dist/document/index.js.map +1 -1
- package/dist/filesystem/electron.d.ts +73 -4
- package/dist/filesystem/electron.js +16 -3
- package/dist/filesystem/electron.js.map +1 -1
- package/dist/filesystem/index.d.ts +228 -22
- package/dist/filesystem/index.js +133 -19
- package/dist/filesystem/index.js.map +1 -1
- package/dist/filesystem/indexeddb.d.ts +284 -5
- package/dist/filesystem/indexeddb.js +22 -4
- package/dist/filesystem/indexeddb.js.map +1 -1
- package/dist/filesystem/memory.d.ts +152 -4
- package/dist/filesystem/memory.js +12 -3
- package/dist/filesystem/memory.js.map +1 -1
- package/dist/filesystem/native.d.ts +136 -4
- package/dist/filesystem/native.js +27 -3
- package/dist/filesystem/native.js.map +1 -1
- package/dist/host/index.d.ts +32 -9
- package/dist/host/index.js +26 -29
- package/dist/host/index.js.map +1 -1
- package/dist/index.d.ts +14 -10
- package/dist/index.js +204 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +33 -4
- package/dist/mcp/index.js +31 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/zod.d.ts +637 -635
- package/dist/mcp/zod.js +700 -884
- package/dist/mcp/zod.js.map +1 -1
- 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-CsX6EN2t.d.ts → types-BEg5SQ1_.d.ts} +1 -1
- package/dist/{types-eOlt9J7n.d.ts → types-CueK0tvU.d.ts} +34 -11
- package/dist/vscode/index.d.ts +220 -3
- package/dist/vscode/index.js +382 -2
- package/dist/vscode/index.js.map +1 -1
- package/dist/workspace/index.d.ts +141 -4
- package/dist/workspace/index.js +28 -2
- package/dist/workspace/index.js.map +1 -1
- package/package.json +9 -5
- package/dist/chunk-2D7Y4IR3.js.map +0 -1
- package/dist/chunk-5MYAICRE.js.map +0 -1
- package/dist/chunk-AYZ4HN5M.js +0 -20
- package/dist/chunk-AYZ4HN5M.js.map +0 -1
- package/dist/chunk-GCPBEMMH.js.map +0 -1
- package/dist/chunk-J32GU3F3.js.map +0 -1
- package/dist/chunk-PGR7LK6D.js.map +0 -1
- package/dist/chunk-RQJRQF46.js.map +0 -1
- package/dist/chunk-SI2LU2RP.js.map +0 -1
- package/dist/chunk-W5UUUII5.js +0 -142
- package/dist/chunk-W5UUUII5.js.map +0 -1
- package/dist/document/document-session.d.ts +0 -127
- package/dist/document/document-session.d.ts.map +0 -1
- package/dist/document/document-session.js +0 -749
- package/dist/document/document-session.js.map +0 -1
- package/dist/document/filesystem-target.d.ts +0 -17
- package/dist/document/filesystem-target.d.ts.map +0 -1
- package/dist/document/filesystem-target.js +0 -70
- package/dist/document/filesystem-target.js.map +0 -1
- package/dist/document/index.d.ts.map +0 -1
- package/dist/document/recovery-journal.d.ts +0 -125
- package/dist/document/recovery-journal.d.ts.map +0 -1
- package/dist/document/recovery-journal.js +0 -385
- package/dist/document/recovery-journal.js.map +0 -1
- package/dist/document/types.d.ts +0 -89
- package/dist/document/types.d.ts.map +0 -1
- package/dist/document/types.js +0 -9
- package/dist/document/types.js.map +0 -1
- package/dist/filesystem/commit-lock.d.ts +0 -3
- package/dist/filesystem/commit-lock.d.ts.map +0 -1
- package/dist/filesystem/commit-lock.js +0 -20
- package/dist/filesystem/commit-lock.js.map +0 -1
- package/dist/filesystem/dbk-workspace.d.ts +0 -34
- package/dist/filesystem/dbk-workspace.d.ts.map +0 -1
- package/dist/filesystem/dbk-workspace.js +0 -85
- package/dist/filesystem/dbk-workspace.js.map +0 -1
- package/dist/filesystem/electron-provider-v2.d.ts +0 -36
- package/dist/filesystem/electron-provider-v2.d.ts.map +0 -1
- package/dist/filesystem/electron-provider-v2.js +0 -503
- package/dist/filesystem/electron-provider-v2.js.map +0 -1
- package/dist/filesystem/electron-provider.d.ts +0 -35
- package/dist/filesystem/electron-provider.d.ts.map +0 -1
- package/dist/filesystem/electron-provider.js +0 -69
- package/dist/filesystem/electron-provider.js.map +0 -1
- package/dist/filesystem/electron.d.ts.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 -153
- package/dist/filesystem/filesystem-content-container.js.map +0 -1
- package/dist/filesystem/fs-error.d.ts +0 -46
- package/dist/filesystem/fs-error.d.ts.map +0 -1
- package/dist/filesystem/fs-error.js +0 -170
- package/dist/filesystem/fs-error.js.map +0 -1
- package/dist/filesystem/index.d.ts.map +0 -1
- package/dist/filesystem/indexeddb-content-container.d.ts +0 -22
- package/dist/filesystem/indexeddb-content-container.d.ts.map +0 -1
- package/dist/filesystem/indexeddb-content-container.js +0 -100
- package/dist/filesystem/indexeddb-content-container.js.map +0 -1
- package/dist/filesystem/indexeddb-provider-v2.d.ts +0 -96
- package/dist/filesystem/indexeddb-provider-v2.d.ts.map +0 -1
- package/dist/filesystem/indexeddb-provider-v2.js +0 -1241
- package/dist/filesystem/indexeddb-provider-v2.js.map +0 -1
- package/dist/filesystem/indexeddb-provider.d.ts +0 -39
- package/dist/filesystem/indexeddb-provider.d.ts.map +0 -1
- package/dist/filesystem/indexeddb-provider.js +0 -145
- package/dist/filesystem/indexeddb-provider.js.map +0 -1
- package/dist/filesystem/indexeddb-store.d.ts +0 -34
- package/dist/filesystem/indexeddb-store.d.ts.map +0 -1
- package/dist/filesystem/indexeddb-store.js +0 -165
- package/dist/filesystem/indexeddb-store.js.map +0 -1
- package/dist/filesystem/indexeddb.d.ts.map +0 -1
- package/dist/filesystem/legacy-v2-adapter.d.ts +0 -62
- package/dist/filesystem/legacy-v2-adapter.d.ts.map +0 -1
- package/dist/filesystem/legacy-v2-adapter.js +0 -499
- package/dist/filesystem/legacy-v2-adapter.js.map +0 -1
- package/dist/filesystem/memory-provider-v2.d.ts +0 -92
- package/dist/filesystem/memory-provider-v2.d.ts.map +0 -1
- package/dist/filesystem/memory-provider-v2.js +0 -615
- package/dist/filesystem/memory-provider-v2.js.map +0 -1
- package/dist/filesystem/memory-provider.d.ts +0 -54
- package/dist/filesystem/memory-provider.d.ts.map +0 -1
- package/dist/filesystem/memory-provider.js +0 -132
- package/dist/filesystem/memory-provider.js.map +0 -1
- package/dist/filesystem/memory.d.ts.map +0 -1
- package/dist/filesystem/move-entry.d.ts +0 -9
- package/dist/filesystem/move-entry.d.ts.map +0 -1
- package/dist/filesystem/move-entry.js +0 -103
- package/dist/filesystem/move-entry.js.map +0 -1
- package/dist/filesystem/move-error.d.ts +0 -53
- package/dist/filesystem/move-error.d.ts.map +0 -1
- package/dist/filesystem/move-error.js +0 -99
- package/dist/filesystem/move-error.js.map +0 -1
- package/dist/filesystem/native-provider-v2.d.ts +0 -75
- package/dist/filesystem/native-provider-v2.d.ts.map +0 -1
- package/dist/filesystem/native-provider-v2.js +0 -849
- package/dist/filesystem/native-provider-v2.js.map +0 -1
- package/dist/filesystem/native-provider.d.ts +0 -53
- package/dist/filesystem/native-provider.d.ts.map +0 -1
- package/dist/filesystem/native-provider.js +0 -471
- package/dist/filesystem/native-provider.js.map +0 -1
- package/dist/filesystem/native.d.ts.map +0 -1
- package/dist/filesystem/types.d.ts +0 -83
- package/dist/filesystem/types.d.ts.map +0 -1
- package/dist/filesystem/types.js +0 -16
- package/dist/filesystem/types.js.map +0 -1
- package/dist/filesystem/v2.d.ts +0 -172
- package/dist/filesystem/v2.d.ts.map +0 -1
- package/dist/filesystem/v2.js +0 -16
- package/dist/filesystem/v2.js.map +0 -1
- package/dist/filesystem/workspace-path.d.ts +0 -21
- package/dist/filesystem/workspace-path.d.ts.map +0 -1
- package/dist/filesystem/workspace-path.js +0 -80
- package/dist/filesystem/workspace-path.js.map +0 -1
- package/dist/host/filesystem-v2.d.ts +0 -45
- package/dist/host/filesystem-v2.d.ts.map +0 -1
- package/dist/host/filesystem-v2.js +0 -13
- package/dist/host/filesystem-v2.js.map +0 -1
- package/dist/host/git.d.ts +0 -200
- package/dist/host/git.d.ts.map +0 -1
- package/dist/host/git.js +0 -15
- package/dist/host/git.js.map +0 -1
- package/dist/host/index.d.ts.map +0 -1
- package/dist/host/types.d.ts +0 -232
- 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/host/wire-policy.d.ts +0 -22
- package/dist/host/wire-policy.d.ts.map +0 -1
- package/dist/host/wire-policy.js +0 -92
- package/dist/host/wire-policy.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/types.d.ts +0 -466
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js +0 -25
- package/dist/mcp/types.js.map +0 -1
- package/dist/mcp/wire.d.ts +0 -29
- package/dist/mcp/wire.d.ts.map +0 -1
- package/dist/mcp/wire.js +0 -1046
- package/dist/mcp/wire.js.map +0 -1
- package/dist/mcp/zod.d.ts.map +0 -1
- package/dist/vscode/index.d.ts.map +0 -1
- package/dist/vscode/messages.d.ts +0 -204
- package/dist/vscode/messages.d.ts.map +0 -1
- package/dist/vscode/messages.js +0 -494
- package/dist/vscode/messages.js.map +0 -1
- package/dist/workspace/index.d.ts.map +0 -1
- package/dist/workspace/reconcile-electron.d.ts +0 -19
- package/dist/workspace/reconcile-electron.d.ts.map +0 -1
- package/dist/workspace/reconcile-electron.js +0 -42
- package/dist/workspace/reconcile-electron.js.map +0 -1
- package/dist/workspace/types.d.ts +0 -69
- package/dist/workspace/types.d.ts.map +0 -1
- package/dist/workspace/types.js +0 -2
- package/dist/workspace/types.js.map +0 -1
- package/dist/workspace/workspace-manager.d.ts +0 -47
- package/dist/workspace/workspace-manager.d.ts.map +0 -1
- package/dist/workspace/workspace-manager.js +0 -126
- package/dist/workspace/workspace-manager.js.map +0 -1
- package/src/document/document-session.ts +0 -834
- package/src/document/filesystem-target.ts +0 -109
- package/src/document/index.ts +0 -41
- package/src/document/recovery-journal.ts +0 -536
- package/src/document/types.ts +0 -116
- package/src/filesystem/commit-lock.ts +0 -29
- package/src/filesystem/dbk-workspace.ts +0 -135
- package/src/filesystem/electron-provider-v2.ts +0 -630
- package/src/filesystem/electron-provider.ts +0 -99
- package/src/filesystem/electron.ts +0 -3
- package/src/filesystem/file-media-provider.ts +0 -103
- package/src/filesystem/filesystem-content-container.ts +0 -164
- package/src/filesystem/fs-error.ts +0 -234
- package/src/filesystem/index.ts +0 -143
- package/src/filesystem/indexeddb-content-container.ts +0 -112
- package/src/filesystem/indexeddb-provider-v2.ts +0 -1740
- package/src/filesystem/indexeddb-provider.ts +0 -171
- package/src/filesystem/indexeddb-store.ts +0 -207
- package/src/filesystem/indexeddb.ts +0 -12
- package/src/filesystem/legacy-v2-adapter.ts +0 -779
- package/src/filesystem/memory-provider-v2.ts +0 -896
- package/src/filesystem/memory-provider.ts +0 -180
- package/src/filesystem/memory.ts +0 -15
- package/src/filesystem/move-entry.ts +0 -142
- package/src/filesystem/move-error.ts +0 -159
- package/src/filesystem/native-provider-v2.ts +0 -1165
- package/src/filesystem/native-provider.ts +0 -537
- package/src/filesystem/native.ts +0 -16
- package/src/filesystem/types.ts +0 -114
- package/src/filesystem/v2.ts +0 -231
- package/src/filesystem/workspace-path.ts +0 -92
- package/src/host/filesystem-v2.ts +0 -104
- package/src/host/git.ts +0 -246
- package/src/host/index.ts +0 -93
- package/src/host/types.ts +0 -274
- package/src/host/wire-policy.ts +0 -103
- package/src/index.ts +0 -10
- package/src/mcp/index.ts +0 -3
- package/src/mcp/types.ts +0 -594
- package/src/mcp/wire.ts +0 -1280
- package/src/mcp/zod.ts +0 -1000
- package/src/vscode/index.ts +0 -2
- package/src/vscode/messages.ts +0 -704
- package/src/workspace/index.ts +0 -17
- package/src/workspace/reconcile-electron.ts +0 -65
- package/src/workspace/types.ts +0 -67
- package/src/workspace/workspace-manager.ts +0 -151
- /package/dist/{chunk-75UUF6C4.js.map → chunk-B56KWCSE.js.map} +0 -0
- /package/dist/{chunk-EGNDADXB.js.map → chunk-MNSZ7EZN.js.map} +0 -0
|
@@ -2,8 +2,21 @@ import {
|
|
|
2
2
|
withFileCommitLock
|
|
3
3
|
} from "./chunk-AEHCVWU5.js";
|
|
4
4
|
import {
|
|
5
|
+
parentChainWithRoot
|
|
6
|
+
} from "./chunk-GM5YXU4L.js";
|
|
7
|
+
import {
|
|
8
|
+
isRecord
|
|
9
|
+
} from "./chunk-U722UUFN.js";
|
|
10
|
+
import {
|
|
11
|
+
bytesEqual,
|
|
12
|
+
compareSnapshotsByName,
|
|
13
|
+
compareText,
|
|
14
|
+
copyBytes,
|
|
5
15
|
parseFileSystemVersion
|
|
6
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-P4WATND4.js";
|
|
17
|
+
import {
|
|
18
|
+
decodeUtf8Text
|
|
19
|
+
} from "./chunk-FA7UNOXK.js";
|
|
7
20
|
import {
|
|
8
21
|
FsError,
|
|
9
22
|
WORKSPACE_ROOT,
|
|
@@ -12,160 +25,19 @@ import {
|
|
|
12
25
|
workspacePathBasename,
|
|
13
26
|
workspacePathContains,
|
|
14
27
|
workspacePathDirname
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.databaseName = databaseName;
|
|
21
|
-
this.storeName = storeName;
|
|
22
|
-
this.database = null;
|
|
23
|
-
this.opening = null;
|
|
24
|
-
this.closed = false;
|
|
25
|
-
}
|
|
26
|
-
async transaction(mode, operation) {
|
|
27
|
-
const database = await this.getDatabase();
|
|
28
|
-
const nativeTransaction = database.transaction(this.storeName, mode);
|
|
29
|
-
const completion = waitForTransaction(nativeTransaction);
|
|
30
|
-
const transaction = new RawIndexedDBFileSystemTransaction(
|
|
31
|
-
nativeTransaction.objectStore(this.storeName)
|
|
32
|
-
);
|
|
33
|
-
let result;
|
|
34
|
-
try {
|
|
35
|
-
result = await operation(transaction);
|
|
36
|
-
} catch (error) {
|
|
37
|
-
try {
|
|
38
|
-
nativeTransaction.abort();
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
|
-
await completion.catch(() => void 0);
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
await completion;
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
close() {
|
|
48
|
-
if (this.closed) return;
|
|
49
|
-
this.closed = true;
|
|
50
|
-
this.database?.close();
|
|
51
|
-
this.database = null;
|
|
52
|
-
this.opening = null;
|
|
53
|
-
}
|
|
54
|
-
getDatabase() {
|
|
55
|
-
if (this.closed) {
|
|
56
|
-
return Promise.reject(new Error("The IndexedDB filesystem store is closed."));
|
|
57
|
-
}
|
|
58
|
-
if (this.database) return Promise.resolve(this.database);
|
|
59
|
-
if (this.opening) return this.opening;
|
|
60
|
-
if (typeof indexedDB === "undefined") {
|
|
61
|
-
return Promise.reject(new Error("IndexedDB is not available in this environment."));
|
|
62
|
-
}
|
|
63
|
-
this.opening = openDatabaseWithStore(this.databaseName, this.storeName).then((database) => {
|
|
64
|
-
if (this.closed) {
|
|
65
|
-
database.close();
|
|
66
|
-
throw new Error("The IndexedDB filesystem store is closed.");
|
|
67
|
-
}
|
|
68
|
-
this.database = database;
|
|
69
|
-
this.opening = null;
|
|
70
|
-
database.onversionchange = () => {
|
|
71
|
-
database.close();
|
|
72
|
-
if (this.database === database) this.database = null;
|
|
73
|
-
};
|
|
74
|
-
return database;
|
|
75
|
-
}).catch((error) => {
|
|
76
|
-
this.opening = null;
|
|
77
|
-
throw error;
|
|
78
|
-
});
|
|
79
|
-
return this.opening;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
var RawIndexedDBFileSystemTransaction = class {
|
|
83
|
-
constructor(store) {
|
|
84
|
-
this.store = store;
|
|
85
|
-
}
|
|
86
|
-
async get(key) {
|
|
87
|
-
const value = await requestResult(this.store.get(key));
|
|
88
|
-
return value === void 0 ? null : value;
|
|
89
|
-
}
|
|
90
|
-
async put(key, value) {
|
|
91
|
-
await requestResult(this.store.put(value, key));
|
|
92
|
-
}
|
|
93
|
-
async delete(key) {
|
|
94
|
-
await requestResult(this.store.delete(key));
|
|
95
|
-
}
|
|
96
|
-
async keys() {
|
|
97
|
-
const keys = await requestResult(this.store.getAllKeys());
|
|
98
|
-
return keys.map((key) => {
|
|
99
|
-
if (typeof key !== "string") {
|
|
100
|
-
throw new Error("The DocBlocks filesystem store contains a non-string key.");
|
|
101
|
-
}
|
|
102
|
-
return key;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
async hasKeyWithPrefix(prefix) {
|
|
106
|
-
const cursor = await requestResult(this.store.openKeyCursor(IDBKeyRange.lowerBound(prefix)));
|
|
107
|
-
return cursor !== null && typeof cursor.key === "string" && cursor.key.startsWith(prefix);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
async function openDatabaseWithStore(databaseName, storeName) {
|
|
111
|
-
const database = await openDatabase(databaseName, void 0, (upgradeDatabase) => {
|
|
112
|
-
if (!upgradeDatabase.objectStoreNames.contains(storeName)) {
|
|
113
|
-
upgradeDatabase.createObjectStore(storeName);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
if (database.objectStoreNames.contains(storeName)) return database;
|
|
117
|
-
const nextVersion = database.version + 1;
|
|
118
|
-
database.close();
|
|
119
|
-
return openDatabase(databaseName, nextVersion, (upgradeDatabase) => {
|
|
120
|
-
if (!upgradeDatabase.objectStoreNames.contains(storeName)) {
|
|
121
|
-
upgradeDatabase.createObjectStore(storeName);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
function openDatabase(databaseName, version, upgrade) {
|
|
126
|
-
return new Promise((resolve, reject) => {
|
|
127
|
-
const request = version === void 0 ? indexedDB.open(databaseName) : indexedDB.open(databaseName, version);
|
|
128
|
-
let settled = false;
|
|
129
|
-
request.onupgradeneeded = () => upgrade(request.result);
|
|
130
|
-
request.onsuccess = () => {
|
|
131
|
-
if (settled) {
|
|
132
|
-
request.result.close();
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
settled = true;
|
|
136
|
-
resolve(request.result);
|
|
137
|
-
};
|
|
138
|
-
request.onerror = () => {
|
|
139
|
-
if (settled) return;
|
|
140
|
-
settled = true;
|
|
141
|
-
reject(request.error ?? new Error(`Could not open IndexedDB database ${databaseName}.`));
|
|
142
|
-
};
|
|
143
|
-
request.onblocked = () => {
|
|
144
|
-
if (settled) return;
|
|
145
|
-
settled = true;
|
|
146
|
-
reject(new Error(`IndexedDB database ${databaseName} is blocked by another open page.`));
|
|
147
|
-
};
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
function requestResult(request) {
|
|
151
|
-
return new Promise((resolve, reject) => {
|
|
152
|
-
request.onsuccess = () => resolve(request.result);
|
|
153
|
-
request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed."));
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
function waitForTransaction(transaction) {
|
|
157
|
-
return new Promise((resolve, reject) => {
|
|
158
|
-
transaction.oncomplete = () => resolve();
|
|
159
|
-
transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction was aborted."));
|
|
160
|
-
transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed."));
|
|
161
|
-
});
|
|
162
|
-
}
|
|
28
|
+
} from "./chunk-JS6XFWQK.js";
|
|
29
|
+
import {
|
|
30
|
+
RawIndexedDBFileSystemStore,
|
|
31
|
+
indexedDBWorkspaceDatabaseName
|
|
32
|
+
} from "./chunk-RVPGQBWR.js";
|
|
163
33
|
|
|
164
34
|
// src/filesystem/indexeddb-provider-v2.ts
|
|
165
35
|
var ENTRY_SCHEMA_VERSION = 1;
|
|
166
36
|
var STATE_SCHEMA_VERSION = 1;
|
|
167
37
|
var LEGACY_CONFLICT_SCHEMA_VERSION = 2;
|
|
168
38
|
var LEGACY_CONFLICT_SCHEMA_VERSION_V1 = 1;
|
|
39
|
+
var LEGACY_OPAQUE_SCHEMA_VERSION = 2;
|
|
40
|
+
var LEGACY_OPAQUE_SCHEMA_VERSION_V1 = 1;
|
|
169
41
|
var ENTRY_PREFIX = "v2:entry:";
|
|
170
42
|
var STATE_KEY = "v2:state";
|
|
171
43
|
var LEGACY_CONFLICT_PREFIX = "v2:legacy-conflict:";
|
|
@@ -200,7 +72,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
200
72
|
this.disposed = false;
|
|
201
73
|
this.id = id;
|
|
202
74
|
this.label = label;
|
|
203
|
-
this.store = options.store ?? new RawIndexedDBFileSystemStore(
|
|
75
|
+
this.store = options.store ?? new RawIndexedDBFileSystemStore(indexedDBWorkspaceDatabaseName(id), "files");
|
|
204
76
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
205
77
|
this.closeStoreOnDispose = options.closeStoreOnDispose ?? true;
|
|
206
78
|
this.versionPrefix = `idb-${encodeURIComponent(id).slice(0, 900) || "workspace"}`;
|
|
@@ -268,7 +140,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
268
140
|
children.push(toEntrySnapshot(entry));
|
|
269
141
|
}
|
|
270
142
|
}
|
|
271
|
-
children.sort(
|
|
143
|
+
children.sort(compareSnapshotsByName);
|
|
272
144
|
return Object.freeze(children);
|
|
273
145
|
});
|
|
274
146
|
}
|
|
@@ -377,6 +249,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
377
249
|
await this.ensureInitialized("remove");
|
|
378
250
|
return this.withMutationLock(
|
|
379
251
|
() => this.transaction("readwrite", { operation: "remove", path: canonical }, async (tx) => {
|
|
252
|
+
await assertNoLegacyConflictInSubtree(tx, canonical, "remove");
|
|
380
253
|
const mutation = new EntryMutation(tx);
|
|
381
254
|
const existing = await mutation.get(canonical);
|
|
382
255
|
const state = await readRequiredState(tx);
|
|
@@ -418,8 +291,8 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
418
291
|
"readwrite",
|
|
419
292
|
{ operation: "move", path: sourcePath, destinationPath },
|
|
420
293
|
async (tx) => {
|
|
421
|
-
await
|
|
422
|
-
await
|
|
294
|
+
await assertNoLegacyConflictInSubtree(tx, sourcePath, "move");
|
|
295
|
+
await assertNoLegacyConflictInSubtree(tx, destinationPath, "move");
|
|
423
296
|
const mutation = new EntryMutation(tx);
|
|
424
297
|
const source = await mutation.get(sourcePath);
|
|
425
298
|
if (!source) {
|
|
@@ -652,6 +525,91 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
652
525
|
})
|
|
653
526
|
);
|
|
654
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* List the unrecognized legacy keys this workspace archived during migration.
|
|
530
|
+
*
|
|
531
|
+
* Migration deletes the legacy `fs:` namespace, but a key it cannot interpret
|
|
532
|
+
* is copied aside first rather than dropped: those bytes belong to whatever
|
|
533
|
+
* tool wrote them against this origin, and DocBlocks is not entitled to
|
|
534
|
+
* decide they are worthless. Nothing else reads that archive, so without this
|
|
535
|
+
* call the bytes are invisible and their quota is unaccountable.
|
|
536
|
+
*
|
|
537
|
+
* Values are deliberately excluded — an archive large enough to matter is an
|
|
538
|
+
* archive too large to materialize just to count it. Use
|
|
539
|
+
* {@link readLegacyOpaqueRecord} for the values themselves.
|
|
540
|
+
*/
|
|
541
|
+
async listLegacyOpaqueRecords() {
|
|
542
|
+
this.assertOpen("read");
|
|
543
|
+
await this.ensureInitialized("read");
|
|
544
|
+
return this.transaction("readonly", { operation: "read" }, async (tx) => {
|
|
545
|
+
const keys = (await tx.keys()).filter((key) => key.startsWith(LEGACY_OPAQUE_PREFIX));
|
|
546
|
+
const summaries = [];
|
|
547
|
+
for (const key of keys) {
|
|
548
|
+
summaries.push(
|
|
549
|
+
toOpaqueSummary(validateLegacyOpaqueRecord(await tx.get(key), key))
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
summaries.sort((left, right) => compareText(left.key, right.key));
|
|
553
|
+
return Object.freeze(summaries);
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
/** Retrieve every archived value for one unrecognized legacy key. */
|
|
557
|
+
async readLegacyOpaqueRecord(key) {
|
|
558
|
+
this.assertOpen("read");
|
|
559
|
+
await this.ensureInitialized("read");
|
|
560
|
+
return this.transaction("readonly", { operation: "read" }, async (tx) => {
|
|
561
|
+
const archiveKey = legacyOpaqueKey(key);
|
|
562
|
+
const raw = await tx.get(archiveKey);
|
|
563
|
+
if (raw === null) return null;
|
|
564
|
+
return toPublicOpaqueRecord(validateLegacyOpaqueRecord(raw, archiveKey));
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Permanently destroy archived legacy values. This is the only operation that
|
|
569
|
+
* can lose data the archive exists to protect.
|
|
570
|
+
*
|
|
571
|
+
* For every target, all of that key's archived value snapshots are erased and
|
|
572
|
+
* the quota they held is reclaimed. There is no undo, no tombstone, and no
|
|
573
|
+
* other copy: migration already deleted the original `fs:` key, so the
|
|
574
|
+
* archive is the last one. Retrieve anything worth keeping with
|
|
575
|
+
* {@link readLegacyOpaqueRecord} before calling this.
|
|
576
|
+
*
|
|
577
|
+
* Each target must carry the `valueCount` the caller actually observed, which
|
|
578
|
+
* is why a target is a value returned by {@link listLegacyOpaqueRecords} or
|
|
579
|
+
* {@link readLegacyOpaqueRecord} rather than a bare key. A stale client can
|
|
580
|
+
* append a new snapshot at any time; if any target has grown since it was
|
|
581
|
+
* observed, the whole call fails with `conflict` and destroys nothing, so
|
|
582
|
+
* re-list and look again. A key that is already absent is not an error —
|
|
583
|
+
* discarding what is gone is a no-op — but a key whose count disagrees is.
|
|
584
|
+
*
|
|
585
|
+
* @returns how many records were destroyed.
|
|
586
|
+
*/
|
|
587
|
+
async discardLegacyOpaqueRecords(targets) {
|
|
588
|
+
this.assertOpen("remove");
|
|
589
|
+
if (targets.length === 0) return 0;
|
|
590
|
+
await this.ensureInitialized("remove");
|
|
591
|
+
return this.withMutationLock(
|
|
592
|
+
() => this.transaction("readwrite", { operation: "remove" }, async (tx) => {
|
|
593
|
+
const doomed = [];
|
|
594
|
+
for (const target of targets) {
|
|
595
|
+
const archiveKey = legacyOpaqueKey(target.key);
|
|
596
|
+
const raw = await tx.get(archiveKey);
|
|
597
|
+
if (raw === null) continue;
|
|
598
|
+
const record = validateLegacyOpaqueRecord(raw, archiveKey);
|
|
599
|
+
if (record.values.length !== target.valueCount) {
|
|
600
|
+
throw new FsError(
|
|
601
|
+
"conflict",
|
|
602
|
+
`Archived legacy key ${target.key} now holds ${record.values.length} values, not ${target.valueCount}. Read it again before discarding it.`,
|
|
603
|
+
{ operation: "remove", retryable: false }
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
doomed.push(archiveKey);
|
|
607
|
+
}
|
|
608
|
+
for (const archiveKey of doomed) await tx.delete(archiveKey);
|
|
609
|
+
return doomed.length;
|
|
610
|
+
})
|
|
611
|
+
);
|
|
612
|
+
}
|
|
655
613
|
async ensureInitialized(operation) {
|
|
656
614
|
this.assertOpen(operation);
|
|
657
615
|
if (this.initialization) return this.initialization;
|
|
@@ -754,7 +712,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
754
712
|
for (const entry of entries.values()) {
|
|
755
713
|
await tx.put(entryKey(entry.path), entry);
|
|
756
714
|
}
|
|
757
|
-
await deleteLegacyNamespace(tx, keys);
|
|
715
|
+
await deleteLegacyNamespace(tx, keys, now);
|
|
758
716
|
const state = {
|
|
759
717
|
schemaVersion: STATE_SCHEMA_VERSION,
|
|
760
718
|
migrationVersion: 2,
|
|
@@ -793,7 +751,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
793
751
|
fileRecoveryCandidate(legacy, entry?.kind === "directory" ? "kind-collision" : reason, now)
|
|
794
752
|
);
|
|
795
753
|
}
|
|
796
|
-
await deleteLegacyNamespace(tx, keys);
|
|
754
|
+
await deleteLegacyNamespace(tx, keys, now);
|
|
797
755
|
for (const key of keys) {
|
|
798
756
|
if (key.startsWith(LEGACY_IGNORED_PREFIX)) await tx.delete(key);
|
|
799
757
|
}
|
|
@@ -880,7 +838,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
880
838
|
}
|
|
881
839
|
async planParents(mutation, path, createParents, operation) {
|
|
882
840
|
const missing = [];
|
|
883
|
-
for (const parent of
|
|
841
|
+
for (const parent of parentChainWithRoot(path)) {
|
|
884
842
|
const entry = await mutation.get(parent);
|
|
885
843
|
if (entry?.kind === "file") {
|
|
886
844
|
throw this.error(
|
|
@@ -905,7 +863,7 @@ var IndexedDBFileSystemProviderV2 = class {
|
|
|
905
863
|
}
|
|
906
864
|
}
|
|
907
865
|
async touchParents(mutation, path, next) {
|
|
908
|
-
for (const parent of
|
|
866
|
+
for (const parent of parentChainWithRoot(path)) {
|
|
909
867
|
const entry = await mutation.get(parent);
|
|
910
868
|
if (entry?.kind === "directory") {
|
|
911
869
|
mutation.set(parent, directoryRecord(parent, next.version, next.lastModified));
|
|
@@ -1119,15 +1077,21 @@ function validateIgnoredLegacyPath(value) {
|
|
|
1119
1077
|
if (!path) throw corrupt("Ignored legacy recovery marker cannot target the workspace root.");
|
|
1120
1078
|
return path;
|
|
1121
1079
|
}
|
|
1122
|
-
function bytesEqual(left, right) {
|
|
1123
|
-
const leftBytes = ArrayBuffer.isView(left) ? new Uint8Array(left.buffer, left.byteOffset, left.byteLength) : new Uint8Array(left);
|
|
1124
|
-
const rightBytes = ArrayBuffer.isView(right) ? new Uint8Array(right.buffer, right.byteOffset, right.byteLength) : new Uint8Array(right);
|
|
1125
|
-
if (leftBytes.byteLength !== rightBytes.byteLength) return false;
|
|
1126
|
-
return leftBytes.every((byte, index) => byte === rightBytes[index]);
|
|
1127
|
-
}
|
|
1128
1080
|
async function assertNoLegacyConflict(transaction, path, operation) {
|
|
1129
1081
|
if (await transaction.get(legacyConflictKey(path)) === null) return;
|
|
1130
|
-
throw
|
|
1082
|
+
throw legacyConflictBlocked(path, operation);
|
|
1083
|
+
}
|
|
1084
|
+
async function assertNoLegacyConflictInSubtree(transaction, path, operation) {
|
|
1085
|
+
for (const key of await transaction.keys()) {
|
|
1086
|
+
if (!key.startsWith(LEGACY_CONFLICT_PREFIX)) continue;
|
|
1087
|
+
const conflictPath = parseWorkspacePath(key.slice(LEGACY_CONFLICT_PREFIX.length));
|
|
1088
|
+
if (conflictPath === path || workspacePathContains(path, conflictPath, false)) {
|
|
1089
|
+
throw legacyConflictBlocked(conflictPath, operation);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
function legacyConflictBlocked(path, operation) {
|
|
1094
|
+
return new FsError(
|
|
1131
1095
|
"conflict",
|
|
1132
1096
|
"Resolve the legacy migration conflict before mutating this path.",
|
|
1133
1097
|
{
|
|
@@ -1282,18 +1246,91 @@ function legacyPayloadsMatchEntry(legacy, entry) {
|
|
|
1282
1246
|
return (legacy.content === null || bytesEqual(new TextEncoder().encode(legacy.content), entry.data)) && (legacy.binary === null || bytesEqual(legacy.binary, entry.data));
|
|
1283
1247
|
}
|
|
1284
1248
|
function hasFileAncestor(entries, path) {
|
|
1285
|
-
return
|
|
1249
|
+
return parentChainWithRoot(path).some((parent) => entries.get(parent)?.kind === "file");
|
|
1250
|
+
}
|
|
1251
|
+
function legacyOpaqueKey(key) {
|
|
1252
|
+
return `${LEGACY_OPAQUE_PREFIX}${encodeURIComponent(key)}`;
|
|
1253
|
+
}
|
|
1254
|
+
function validateLegacyOpaqueRecord(value, archiveKey) {
|
|
1255
|
+
if (!isRecord(value) || !Array.isArray(value.values)) {
|
|
1256
|
+
throw corrupt(`Archived legacy record is corrupt: ${archiveKey}.`);
|
|
1257
|
+
}
|
|
1258
|
+
const key = readString(value.key, "archived legacy key");
|
|
1259
|
+
if (legacyOpaqueKey(key) !== archiveKey) {
|
|
1260
|
+
throw corrupt(`Archived legacy record key does not match its key: ${archiveKey}.`);
|
|
1261
|
+
}
|
|
1262
|
+
if (value.schemaVersion === LEGACY_OPAQUE_SCHEMA_VERSION_V1) {
|
|
1263
|
+
return {
|
|
1264
|
+
schemaVersion: LEGACY_OPAQUE_SCHEMA_VERSION,
|
|
1265
|
+
key,
|
|
1266
|
+
values: Object.freeze(
|
|
1267
|
+
value.values.map(
|
|
1268
|
+
(item) => ({ value: item, archivedAt: null })
|
|
1269
|
+
)
|
|
1270
|
+
)
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
if (value.schemaVersion !== LEGACY_OPAQUE_SCHEMA_VERSION) {
|
|
1274
|
+
throw corrupt(`Unsupported archived legacy record schema: ${archiveKey}.`);
|
|
1275
|
+
}
|
|
1276
|
+
const values = value.values.map((item) => {
|
|
1277
|
+
if (!isRecord(item)) throw corrupt(`Archived legacy value is corrupt: ${archiveKey}.`);
|
|
1278
|
+
return {
|
|
1279
|
+
value: item.value,
|
|
1280
|
+
// A v2 record legitimately carries null here for values it inherited from
|
|
1281
|
+
// the untimestamped v1 shape, so this must stay nullable on the way back
|
|
1282
|
+
// in or re-archiving a v1 record would make it permanently unreadable.
|
|
1283
|
+
archivedAt: item.archivedAt === null ? null : readString(item.archivedAt, "archived legacy timestamp")
|
|
1284
|
+
};
|
|
1285
|
+
});
|
|
1286
|
+
if (values.length === 0) throw corrupt(`Archived legacy record has no values: ${archiveKey}.`);
|
|
1287
|
+
return { schemaVersion: LEGACY_OPAQUE_SCHEMA_VERSION, key, values: Object.freeze(values) };
|
|
1288
|
+
}
|
|
1289
|
+
function opaqueValueByteLength(value) {
|
|
1290
|
+
if (value instanceof ArrayBuffer) return value.byteLength;
|
|
1291
|
+
if (ArrayBuffer.isView(value)) return value.byteLength;
|
|
1292
|
+
if (typeof value === "string") return new TextEncoder().encode(value).byteLength;
|
|
1293
|
+
return null;
|
|
1294
|
+
}
|
|
1295
|
+
function toOpaqueSummary(record) {
|
|
1296
|
+
let byteLength = 0;
|
|
1297
|
+
for (const item of record.values) {
|
|
1298
|
+
const size = opaqueValueByteLength(item.value);
|
|
1299
|
+
byteLength = size === null || byteLength === null ? null : byteLength + size;
|
|
1300
|
+
}
|
|
1301
|
+
const stamps = record.values.map((item) => item.archivedAt);
|
|
1302
|
+
return Object.freeze({
|
|
1303
|
+
key: record.key,
|
|
1304
|
+
valueCount: record.values.length,
|
|
1305
|
+
byteLength,
|
|
1306
|
+
firstArchivedAt: stamps[0] ?? null,
|
|
1307
|
+
lastArchivedAt: stamps[stamps.length - 1] ?? null
|
|
1308
|
+
});
|
|
1286
1309
|
}
|
|
1287
|
-
|
|
1310
|
+
function toPublicOpaqueRecord(record) {
|
|
1311
|
+
return Object.freeze({
|
|
1312
|
+
...toOpaqueSummary(record),
|
|
1313
|
+
values: Object.freeze(
|
|
1314
|
+
record.values.map(
|
|
1315
|
+
(item) => Object.freeze({
|
|
1316
|
+
value: item.value instanceof ArrayBuffer ? copyBytes(item.value) : item.value,
|
|
1317
|
+
byteLength: opaqueValueByteLength(item.value),
|
|
1318
|
+
archivedAt: item.archivedAt
|
|
1319
|
+
})
|
|
1320
|
+
)
|
|
1321
|
+
)
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
async function deleteLegacyNamespace(transaction, keys, archivedAt) {
|
|
1288
1325
|
for (const key of keys) {
|
|
1289
1326
|
if (key.startsWith(LEGACY_PREFIX) && !isRecognizedLegacyKey(key)) {
|
|
1290
|
-
const archiveKey =
|
|
1327
|
+
const archiveKey = legacyOpaqueKey(key);
|
|
1291
1328
|
const existing = await transaction.get(archiveKey);
|
|
1292
|
-
const values =
|
|
1329
|
+
const values = existing === null ? [] : validateLegacyOpaqueRecord(existing, archiveKey).values;
|
|
1293
1330
|
await transaction.put(archiveKey, {
|
|
1294
|
-
schemaVersion:
|
|
1331
|
+
schemaVersion: LEGACY_OPAQUE_SCHEMA_VERSION,
|
|
1295
1332
|
key,
|
|
1296
|
-
values: [...values, await transaction.get(key)]
|
|
1333
|
+
values: [...values, { value: await transaction.get(key), archivedAt }]
|
|
1297
1334
|
});
|
|
1298
1335
|
}
|
|
1299
1336
|
if (key.startsWith(LEGACY_PREFIX) || key.startsWith(LEGACY_IGNORED_PREFIX))
|
|
@@ -1354,19 +1391,10 @@ function selectLegacyPayload(conflict, resolution, path) {
|
|
|
1354
1391
|
return { kind: "file", data: copyBytes(data) };
|
|
1355
1392
|
}
|
|
1356
1393
|
function addParentDirectories(entries, path, version, lastModified) {
|
|
1357
|
-
for (const parent of
|
|
1394
|
+
for (const parent of parentChainWithRoot(path)) {
|
|
1358
1395
|
if (!entries.has(parent)) entries.set(parent, directoryRecord(parent, version, lastModified));
|
|
1359
1396
|
}
|
|
1360
1397
|
}
|
|
1361
|
-
function parentChain(path) {
|
|
1362
|
-
const parents = [];
|
|
1363
|
-
let current = workspacePathDirname(path);
|
|
1364
|
-
while (true) {
|
|
1365
|
-
parents.unshift(current);
|
|
1366
|
-
if (!current) return parents;
|
|
1367
|
-
current = workspacePathDirname(current);
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
1398
|
function directoryRecord(path, version, lastModified) {
|
|
1371
1399
|
return {
|
|
1372
1400
|
schemaVersion: ENTRY_SCHEMA_VERSION,
|
|
@@ -1413,19 +1441,6 @@ function toDirectorySnapshot(entry) {
|
|
|
1413
1441
|
lastModified: entry.lastModified
|
|
1414
1442
|
});
|
|
1415
1443
|
}
|
|
1416
|
-
function compareSnapshots(left, right) {
|
|
1417
|
-
if (left.kind !== right.kind) return left.kind === "directory" ? -1 : 1;
|
|
1418
|
-
return compareText(left.name, right.name);
|
|
1419
|
-
}
|
|
1420
|
-
function compareText(left, right) {
|
|
1421
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
1422
|
-
}
|
|
1423
|
-
function copyBytes(data) {
|
|
1424
|
-
const source = ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);
|
|
1425
|
-
const copy = new Uint8Array(source.byteLength);
|
|
1426
|
-
copy.set(source);
|
|
1427
|
-
return copy.buffer;
|
|
1428
|
-
}
|
|
1429
1444
|
function validateBytes(value, path) {
|
|
1430
1445
|
if (value instanceof ArrayBuffer) return copyBytes(value);
|
|
1431
1446
|
if (value instanceof Uint8Array) return copyBytes(value);
|
|
@@ -1435,9 +1450,6 @@ function readString(value, label) {
|
|
|
1435
1450
|
if (typeof value !== "string") throw corrupt(`Invalid ${label}.`);
|
|
1436
1451
|
return value;
|
|
1437
1452
|
}
|
|
1438
|
-
function isRecord(value) {
|
|
1439
|
-
return typeof value === "object" && value !== null;
|
|
1440
|
-
}
|
|
1441
1453
|
function corrupt(message, path) {
|
|
1442
1454
|
return new FsError("io", message, { operation: "read", path, retryable: false });
|
|
1443
1455
|
}
|
|
@@ -1448,7 +1460,7 @@ var IndexedDBFileSystemProvider = class {
|
|
|
1448
1460
|
this.disposed = false;
|
|
1449
1461
|
this.id = id;
|
|
1450
1462
|
this.label = label;
|
|
1451
|
-
const store = options.store ?? new RawIndexedDBFileSystemStore(
|
|
1463
|
+
const store = options.store ?? new RawIndexedDBFileSystemStore(indexedDBWorkspaceDatabaseName(id), "files");
|
|
1452
1464
|
this.v2 = new IndexedDBFileSystemProviderV2(id, label, {
|
|
1453
1465
|
store,
|
|
1454
1466
|
now: options.now,
|
|
@@ -1462,20 +1474,21 @@ var IndexedDBFileSystemProvider = class {
|
|
|
1462
1474
|
}
|
|
1463
1475
|
async readFile(path) {
|
|
1464
1476
|
this.assertOpen("read");
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1477
|
+
const canonical = this.path(path);
|
|
1478
|
+
const read = await this.v2.readFile(canonical);
|
|
1479
|
+
return read ? this.decode(read.data, canonical, "read") : null;
|
|
1467
1480
|
}
|
|
1468
1481
|
async writeFile(path, content) {
|
|
1469
1482
|
this.assertOpen("write");
|
|
1470
|
-
await this.v2.writeFile(this.path(path
|
|
1483
|
+
await this.v2.writeFile(this.path(path), new TextEncoder().encode(content), {
|
|
1471
1484
|
createParents: true
|
|
1472
1485
|
});
|
|
1473
1486
|
}
|
|
1474
1487
|
async commitFile(path, content, expectedContent) {
|
|
1475
1488
|
this.assertOpen("write");
|
|
1476
|
-
const canonical = this.path(path
|
|
1489
|
+
const canonical = this.path(path);
|
|
1477
1490
|
const current = await this.v2.readFile(canonical);
|
|
1478
|
-
const currentContent = current ?
|
|
1491
|
+
const currentContent = current ? this.decode(current.data, canonical, "write") : null;
|
|
1479
1492
|
if (currentContent !== expectedContent && currentContent !== content) {
|
|
1480
1493
|
return {
|
|
1481
1494
|
status: "conflict",
|
|
@@ -1494,28 +1507,28 @@ var IndexedDBFileSystemProvider = class {
|
|
|
1494
1507
|
const latest = await this.v2.readFile(canonical);
|
|
1495
1508
|
return {
|
|
1496
1509
|
status: "conflict",
|
|
1497
|
-
content: latest ?
|
|
1510
|
+
content: latest ? this.decode(latest.data, canonical, "write") : null,
|
|
1498
1511
|
version: latest?.entry.version ?? null
|
|
1499
1512
|
};
|
|
1500
1513
|
}
|
|
1501
1514
|
}
|
|
1502
1515
|
async delete(path) {
|
|
1503
1516
|
this.assertOpen("remove");
|
|
1504
|
-
await this.v2.remove(this.path(path
|
|
1517
|
+
await this.v2.remove(this.path(path), {
|
|
1505
1518
|
recursive: true,
|
|
1506
1519
|
missing: "ignore"
|
|
1507
1520
|
});
|
|
1508
1521
|
}
|
|
1509
1522
|
async rename(oldPath, newPath) {
|
|
1510
1523
|
this.assertOpen("move");
|
|
1511
|
-
await this.v2.move(this.path(oldPath
|
|
1524
|
+
await this.v2.move(this.path(oldPath), this.path(newPath), {
|
|
1512
1525
|
createParents: true
|
|
1513
1526
|
});
|
|
1514
1527
|
}
|
|
1515
1528
|
async readDirectory(path) {
|
|
1516
1529
|
this.assertOpen("list");
|
|
1517
1530
|
try {
|
|
1518
|
-
const entries = await this.v2.readDirectory(this.path(path
|
|
1531
|
+
const entries = await this.v2.readDirectory(this.path(path));
|
|
1519
1532
|
return entries.map((entry) => ({
|
|
1520
1533
|
kind: entry.kind,
|
|
1521
1534
|
name: entry.name,
|
|
@@ -1528,18 +1541,18 @@ var IndexedDBFileSystemProvider = class {
|
|
|
1528
1541
|
}
|
|
1529
1542
|
async exists(path) {
|
|
1530
1543
|
this.assertOpen("stat");
|
|
1531
|
-
return await this.v2.stat(this.path(path
|
|
1544
|
+
return await this.v2.stat(this.path(path)) !== null;
|
|
1532
1545
|
}
|
|
1533
1546
|
async createDirectory(path) {
|
|
1534
1547
|
this.assertOpen("create-directory");
|
|
1535
|
-
await this.v2.createDirectory(this.path(path
|
|
1548
|
+
await this.v2.createDirectory(this.path(path), {
|
|
1536
1549
|
createParents: true,
|
|
1537
1550
|
mode: "ensure"
|
|
1538
1551
|
});
|
|
1539
1552
|
}
|
|
1540
1553
|
async stat(path) {
|
|
1541
1554
|
this.assertOpen("stat");
|
|
1542
|
-
const entry = await this.v2.stat(this.path(path
|
|
1555
|
+
const entry = await this.v2.stat(this.path(path));
|
|
1543
1556
|
if (!entry || entry.kind !== "file") return null;
|
|
1544
1557
|
return {
|
|
1545
1558
|
name: entry.name,
|
|
@@ -1550,28 +1563,40 @@ var IndexedDBFileSystemProvider = class {
|
|
|
1550
1563
|
}
|
|
1551
1564
|
async readBinary(path) {
|
|
1552
1565
|
this.assertOpen("read");
|
|
1553
|
-
return (await this.v2.readFile(this.path(path
|
|
1566
|
+
return (await this.v2.readFile(this.path(path)))?.data ?? null;
|
|
1554
1567
|
}
|
|
1555
1568
|
async writeBinary(path, data) {
|
|
1556
1569
|
this.assertOpen("write");
|
|
1557
|
-
await this.v2.writeFile(this.path(path
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1570
|
+
await this.v2.writeFile(this.path(path), data, { createParents: true });
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Canonicalize only. Root policy is the v2 authority's to state: it accepts
|
|
1574
|
+
* the root wherever the root is a legitimate target (`stat`, `readDirectory`,
|
|
1575
|
+
* `createDirectory`) and rejects it with one consistent code and message
|
|
1576
|
+
* everywhere else. Re-deriving that policy here is how this facade previously
|
|
1577
|
+
* drifted from both v2 and its sibling facades.
|
|
1578
|
+
*/
|
|
1579
|
+
path(path) {
|
|
1580
|
+
return parseWorkspacePath(path);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Byte-authoritative entries may hold payloads that are not valid UTF-8. A
|
|
1584
|
+
* lossy decode would hand the caller replacement characters that a later save
|
|
1585
|
+
* writes back over the user's original bytes, so surface the fault instead.
|
|
1586
|
+
*/
|
|
1587
|
+
decode(data, path, operation) {
|
|
1588
|
+
return decodeUtf8Text(data, { label: "The file", operation, path });
|
|
1566
1589
|
}
|
|
1567
1590
|
assertOpen(operation) {
|
|
1568
1591
|
if (!this.disposed) return;
|
|
1569
|
-
throw new FsError("
|
|
1592
|
+
throw new FsError("disposed", "Filesystem provider is disposed.", { operation });
|
|
1570
1593
|
}
|
|
1571
1594
|
};
|
|
1572
1595
|
|
|
1573
1596
|
// src/filesystem/indexeddb-content-container.ts
|
|
1574
1597
|
import { findDocumentPath } from "@bendyline/squisq/storage";
|
|
1598
|
+
|
|
1599
|
+
// src/filesystem/internal/mime.ts
|
|
1575
1600
|
var EXTENSION_MIME_MAP = {
|
|
1576
1601
|
".md": "text/markdown",
|
|
1577
1602
|
".txt": "text/plain",
|
|
@@ -1595,6 +1620,8 @@ function guessMimeType(path) {
|
|
|
1595
1620
|
const ext = path.slice(dot).toLowerCase();
|
|
1596
1621
|
return EXTENSION_MIME_MAP[ext] ?? "application/octet-stream";
|
|
1597
1622
|
}
|
|
1623
|
+
|
|
1624
|
+
// src/filesystem/indexeddb-content-container.ts
|
|
1598
1625
|
var IndexedDBContentContainer = class {
|
|
1599
1626
|
constructor(workspaceId) {
|
|
1600
1627
|
this.provider = new IndexedDBFileSystemProviderV2(`${workspaceId}-media`, "Media Storage");
|
|
@@ -1659,6 +1686,7 @@ var IndexedDBContentContainer = class {
|
|
|
1659
1686
|
export {
|
|
1660
1687
|
IndexedDBFileSystemProviderV2,
|
|
1661
1688
|
IndexedDBFileSystemProvider,
|
|
1689
|
+
guessMimeType,
|
|
1662
1690
|
IndexedDBContentContainer
|
|
1663
1691
|
};
|
|
1664
|
-
//# sourceMappingURL=chunk-
|
|
1692
|
+
//# sourceMappingURL=chunk-6IYMTYMQ.js.map
|