@bendyline/docblocks-react 2.7.3 → 2.7.4
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/THIRD_PARTY_NOTICES.txt +23 -23
- package/dist/{AiDiagrams-QE3LVYFK.js → AiDiagrams-QZMJNGDT.js} +3 -3
- package/dist/{AiEditorAssistant-YLJ5OZK2.js → AiEditorAssistant-4HFFGVU4.js} +5 -5
- package/dist/{AiStudyDialog-4TQZZGU3.js → AiStudyDialog-P3E7PJV5.js} +2 -2
- package/dist/{AudioExportDialog-F23QXNPB.js → AudioExportDialog-IOYIEAER.js} +1 -1
- package/dist/{DocumentConflictDialog-5LRVIGXS.js → DocumentConflictDialog-DZ2BV2IH.js} +1 -1
- package/dist/ExportDialog-LGWBXIWN.js +9 -0
- package/dist/{ExportToolbarControls-A2YBKUUD.js → ExportToolbarControls-HOV424TO.js} +84 -13
- package/dist/{GitUI-RCWUZVS6.js → GitUI-F3CNBURE.js} +1 -1
- package/dist/{KeyboardShortcutsDialog-G5OBDTNR.js → KeyboardShortcutsDialog-HVKDFP5Z.js} +1 -1
- package/dist/{PresentationMaker-P2JP6UUX.js → PresentationMaker-MUMFAXEI.js} +3 -3
- package/dist/{QuickOpenDialog-2KK4SEBU.js → QuickOpenDialog-ENVFGIHS.js} +1 -1
- package/dist/{Settings-ByNImjk5.d.ts → Settings-CfhY489G.d.ts} +1 -1
- package/dist/{ShareDialog-XUA2OVGI.js → ShareDialog-PF7D7ORP.js} +1 -1
- package/dist/{SpeechToolbarControl-CLU7RB2G.js → SpeechToolbarControl-KNI2C4JJ.js} +1 -1
- package/dist/{TextFromNarration-NITJQ4IB.js → TextFromNarration-EYOMW2IW.js} +1 -1
- package/dist/{chunk-6PA7QBZT.js → chunk-7CSBRAMT.js} +20 -4
- package/dist/{chunk-YPIVCCTB.js → chunk-7V34VUK6.js} +1 -1
- package/dist/{chunk-3CE5RH2B.js → chunk-D4HIOS7E.js} +2 -2
- package/dist/{chunk-ZMCQO57Q.js → chunk-FBPCURCS.js} +8 -1
- package/dist/{chunk-Y5OE3HJC.js → chunk-GFK4TCKN.js} +11 -5
- package/dist/chunk-H3BK5MK6.js +34 -0
- package/dist/{chunk-6B7G33D5.js → chunk-KBUHWZCF.js} +1 -1
- package/dist/{chunk-EOU2JWAQ.js → chunk-PNZFIIWW.js} +70 -11
- package/dist/{chunk-56KO2LYN.js → chunk-VJPGZCFS.js} +4 -0
- package/dist/editor.js +3 -3
- package/dist/export/index.d.ts +9 -2
- package/dist/export/index.js +4 -4
- package/dist/index.d.ts +7 -3
- package/dist/index.js +503 -186
- package/dist/{run-export-OHRNT2TP.js → run-export-SPNNH32M.js} +1 -1
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js +2 -2
- package/package.json +8 -8
- package/src/styles/docblocks.css +32 -9
- package/dist/ExportDialog-JRVZCG3J.js +0 -9
- package/dist/chunk-YBEYTVU2.js +0 -12
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./chunk-DICE7VBJ.js";
|
|
18
18
|
import {
|
|
19
19
|
useConfirmDialog
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-KBUHWZCF.js";
|
|
21
21
|
import {
|
|
22
22
|
createSpeechInputProvider
|
|
23
23
|
} from "./chunk-KBDZDFPU.js";
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
} from "./chunk-KWG6UP5O.js";
|
|
52
52
|
import {
|
|
53
53
|
runExport
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-7CSBRAMT.js";
|
|
55
55
|
import {
|
|
56
56
|
createImageSaveOutput
|
|
57
57
|
} from "./chunk-UONFWKJ7.js";
|
|
@@ -87,7 +87,7 @@ import {
|
|
|
87
87
|
saveProofingPreferences,
|
|
88
88
|
saveThemePreference,
|
|
89
89
|
saveWriteCanvasPreferences
|
|
90
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-FBPCURCS.js";
|
|
91
91
|
import {
|
|
92
92
|
FindButton,
|
|
93
93
|
focusFindInput,
|
|
@@ -100,18 +100,18 @@ import {
|
|
|
100
100
|
matchShortcut,
|
|
101
101
|
shortcutLabel
|
|
102
102
|
} from "./chunk-ACQF63SB.js";
|
|
103
|
-
import "./chunk-
|
|
103
|
+
import "./chunk-PNZFIIWW.js";
|
|
104
104
|
import {
|
|
105
105
|
buildIssueReportUrl,
|
|
106
106
|
displayBuildDate,
|
|
107
107
|
localDateStamp,
|
|
108
108
|
openExternalUrl
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-7V34VUK6.js";
|
|
110
110
|
import "./chunk-K4I3NJFL.js";
|
|
111
111
|
import {
|
|
112
112
|
ExportDialog
|
|
113
|
-
} from "./chunk-
|
|
114
|
-
import "./chunk-
|
|
113
|
+
} from "./chunk-GFK4TCKN.js";
|
|
114
|
+
import "./chunk-H3BK5MK6.js";
|
|
115
115
|
import {
|
|
116
116
|
DEFAULT_OPTIONS,
|
|
117
117
|
loadLastExportOptions
|
|
@@ -119,13 +119,14 @@ import {
|
|
|
119
119
|
import {
|
|
120
120
|
Dialog,
|
|
121
121
|
dismissTopmostDialog
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-VJPGZCFS.js";
|
|
123
123
|
|
|
124
124
|
// src/FileExplorer/FileExplorer.tsx
|
|
125
125
|
import { useCallback as useCallback5, useEffect as useEffect5, useMemo, useRef as useRef5, useState as useState4 } from "react";
|
|
126
126
|
import {
|
|
127
127
|
isFileSystemMoveStateError,
|
|
128
|
-
parseWorkspacePath as parseWorkspacePath4
|
|
128
|
+
parseWorkspacePath as parseWorkspacePath4,
|
|
129
|
+
tryParseWorkspacePath as tryParseWorkspacePath2
|
|
129
130
|
} from "@bendyline/docblocks/filesystem";
|
|
130
131
|
|
|
131
132
|
// src/FileExplorer/useFileTree.ts
|
|
@@ -139,6 +140,7 @@ import {
|
|
|
139
140
|
workspacePathDirname
|
|
140
141
|
} from "@bendyline/docblocks/filesystem";
|
|
141
142
|
var DIRECTORY_NOT_FOUND_RETRY_DELAYS_MS = Object.freeze([40, 120]);
|
|
143
|
+
var AUTO_RETRY_DELAYS_MS = Object.freeze([1e3, 4e3, 15e3]);
|
|
142
144
|
function normalisePath(path) {
|
|
143
145
|
return parseWorkspacePath(path);
|
|
144
146
|
}
|
|
@@ -167,10 +169,13 @@ function sameEntry(left, right) {
|
|
|
167
169
|
if (left.kind !== right.kind || left.name !== right.name || left.path !== right.path)
|
|
168
170
|
return false;
|
|
169
171
|
if (left.kind === "file" && right.kind === "file") {
|
|
170
|
-
return left.lastModified === right.lastModified;
|
|
172
|
+
return left.lastModified === right.lastModified && left.readIssue?.code === right.readIssue?.code && left.readIssue?.message === right.readIssue?.message;
|
|
171
173
|
}
|
|
172
174
|
return true;
|
|
173
175
|
}
|
|
176
|
+
function hasUnreadableFile(entries) {
|
|
177
|
+
return entries.some((entry) => entry.kind === "file" && entry.readIssue !== void 0);
|
|
178
|
+
}
|
|
174
179
|
function reconcileEntries(current, incoming) {
|
|
175
180
|
const currentByPath = new Map(current.map((entry) => [entry.path, entry]));
|
|
176
181
|
const reconciled = incoming.map((entry) => {
|
|
@@ -189,7 +194,8 @@ async function readProviderDirectory(provider, path) {
|
|
|
189
194
|
kind: entry.kind,
|
|
190
195
|
name: entry.name,
|
|
191
196
|
path: entry.path,
|
|
192
|
-
...entry.kind === "file" ? { lastModified: entry.lastModified } : {}
|
|
197
|
+
...entry.kind === "file" ? { lastModified: entry.lastModified } : {},
|
|
198
|
+
...entry.kind === "file" && entry.readIssue ? { readIssue: entry.readIssue } : {}
|
|
193
199
|
}));
|
|
194
200
|
};
|
|
195
201
|
for (let attempt = 0; ; attempt += 1) {
|
|
@@ -237,64 +243,111 @@ function useFileTree(provider, metadataRefreshKey, metadataRefreshPath) {
|
|
|
237
243
|
providerRef.current = provider;
|
|
238
244
|
const directoryRequestSequenceRef = useRef(0);
|
|
239
245
|
const directoryRequestsRef = useRef(/* @__PURE__ */ new Map());
|
|
246
|
+
const autoRetriesRef = useRef(/* @__PURE__ */ new Map());
|
|
247
|
+
const autoRetryLoadRef = useRef(async () => void 0);
|
|
240
248
|
const reportRootIssue = useCallback((caught) => {
|
|
241
249
|
setRootIssue(readIssue(caught, ""));
|
|
242
250
|
}, []);
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
setLoading(false);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
const requestId = ++directoryRequestSequenceRef.current;
|
|
251
|
-
directoryRequestsRef.current.set("", requestId);
|
|
252
|
-
const isCurrent = () => providerRef.current === sourceProvider && directoryRequestsRef.current.get("") === requestId;
|
|
253
|
-
if (showLoading) setLoading(true);
|
|
254
|
-
try {
|
|
255
|
-
const root = await readProviderDirectory(sourceProvider, "");
|
|
256
|
-
if (!isCurrent()) return;
|
|
257
|
-
setEntries((current) => reconcileEntries(current, root));
|
|
258
|
-
setRootIssue(null);
|
|
259
|
-
} catch (caught) {
|
|
260
|
-
if (isCurrent()) setRootIssue(readIssue(caught, ""));
|
|
261
|
-
} finally {
|
|
262
|
-
if (isCurrent()) setLoading(false);
|
|
263
|
-
}
|
|
251
|
+
const cancelAutoRetry = useCallback((directoryPath) => {
|
|
252
|
+
const state = autoRetriesRef.current.get(directoryPath);
|
|
253
|
+
if (state?.timer) clearTimeout(state.timer);
|
|
254
|
+
autoRetriesRef.current.delete(directoryPath);
|
|
264
255
|
}, []);
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
const canonical = normalisePath(dirPath);
|
|
269
|
-
const requestId = ++directoryRequestSequenceRef.current;
|
|
270
|
-
directoryRequestsRef.current.set(canonical, requestId);
|
|
271
|
-
const isCurrent = () => providerRef.current === sourceProvider && directoryRequestsRef.current.get(canonical) === requestId;
|
|
272
|
-
try {
|
|
273
|
-
const children = await readProviderDirectory(sourceProvider, dirPath);
|
|
274
|
-
if (!isCurrent()) return;
|
|
275
|
-
setChildEntries((prev) => {
|
|
276
|
-
const current = prev.get(canonical) ?? [];
|
|
277
|
-
const reconciled = reconcileEntries(current, children);
|
|
278
|
-
if (prev.has(canonical) && reconciled === current) return prev;
|
|
279
|
-
const next = new Map(prev);
|
|
280
|
-
next.set(canonical, reconciled);
|
|
281
|
-
return next;
|
|
282
|
-
});
|
|
283
|
-
setChildIssues((prev) => {
|
|
284
|
-
if (!prev.has(canonical)) return prev;
|
|
285
|
-
const next = new Map(prev);
|
|
286
|
-
next.delete(canonical);
|
|
287
|
-
return next;
|
|
288
|
-
});
|
|
289
|
-
} catch (caught) {
|
|
290
|
-
if (!isCurrent()) return;
|
|
291
|
-
setChildIssues((prev) => {
|
|
292
|
-
const next = new Map(prev);
|
|
293
|
-
next.set(canonical, readIssue(caught, dirPath));
|
|
294
|
-
return next;
|
|
295
|
-
});
|
|
256
|
+
const cancelAllAutoRetries = useCallback(() => {
|
|
257
|
+
for (const state of autoRetriesRef.current.values()) {
|
|
258
|
+
if (state.timer) clearTimeout(state.timer);
|
|
296
259
|
}
|
|
260
|
+
autoRetriesRef.current.clear();
|
|
297
261
|
}, []);
|
|
262
|
+
const settleAutoRetry = useCallback(
|
|
263
|
+
(directoryPath, needsRetry) => {
|
|
264
|
+
if (!needsRetry) {
|
|
265
|
+
cancelAutoRetry(directoryPath);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const current = autoRetriesRef.current.get(directoryPath);
|
|
269
|
+
if (current?.timer) return;
|
|
270
|
+
const attempts = current?.attempts ?? 0;
|
|
271
|
+
const delay = AUTO_RETRY_DELAYS_MS[attempts];
|
|
272
|
+
if (delay === void 0) return;
|
|
273
|
+
const next = { attempts: attempts + 1, timer: null };
|
|
274
|
+
next.timer = setTimeout(() => {
|
|
275
|
+
next.timer = null;
|
|
276
|
+
void autoRetryLoadRef.current(directoryPath);
|
|
277
|
+
}, delay);
|
|
278
|
+
autoRetriesRef.current.set(directoryPath, next);
|
|
279
|
+
},
|
|
280
|
+
[cancelAutoRetry]
|
|
281
|
+
);
|
|
282
|
+
const loadRoot = useCallback(
|
|
283
|
+
async (showLoading = true) => {
|
|
284
|
+
const sourceProvider = providerRef.current;
|
|
285
|
+
if (!sourceProvider) {
|
|
286
|
+
setEntries([]);
|
|
287
|
+
setLoading(false);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const requestId = ++directoryRequestSequenceRef.current;
|
|
291
|
+
directoryRequestsRef.current.set("", requestId);
|
|
292
|
+
const isCurrent = () => providerRef.current === sourceProvider && directoryRequestsRef.current.get("") === requestId;
|
|
293
|
+
if (showLoading) setLoading(true);
|
|
294
|
+
try {
|
|
295
|
+
const root = await readProviderDirectory(sourceProvider, "");
|
|
296
|
+
if (!isCurrent()) return;
|
|
297
|
+
setEntries((current) => reconcileEntries(current, root));
|
|
298
|
+
setRootIssue(null);
|
|
299
|
+
settleAutoRetry("", hasUnreadableFile(root));
|
|
300
|
+
} catch (caught) {
|
|
301
|
+
if (isCurrent()) {
|
|
302
|
+
const issue = readIssue(caught, "");
|
|
303
|
+
setRootIssue(issue);
|
|
304
|
+
settleAutoRetry("", issue.retryable);
|
|
305
|
+
}
|
|
306
|
+
} finally {
|
|
307
|
+
if (isCurrent()) setLoading(false);
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
[settleAutoRetry]
|
|
311
|
+
);
|
|
312
|
+
const loadChildren = useCallback(
|
|
313
|
+
async (dirPath) => {
|
|
314
|
+
const sourceProvider = providerRef.current;
|
|
315
|
+
if (!sourceProvider) return;
|
|
316
|
+
const canonical = normalisePath(dirPath);
|
|
317
|
+
const requestId = ++directoryRequestSequenceRef.current;
|
|
318
|
+
directoryRequestsRef.current.set(canonical, requestId);
|
|
319
|
+
const isCurrent = () => providerRef.current === sourceProvider && directoryRequestsRef.current.get(canonical) === requestId;
|
|
320
|
+
try {
|
|
321
|
+
const children = await readProviderDirectory(sourceProvider, dirPath);
|
|
322
|
+
if (!isCurrent()) return;
|
|
323
|
+
setChildEntries((prev) => {
|
|
324
|
+
const current = prev.get(canonical) ?? [];
|
|
325
|
+
const reconciled = reconcileEntries(current, children);
|
|
326
|
+
if (prev.has(canonical) && reconciled === current) return prev;
|
|
327
|
+
const next = new Map(prev);
|
|
328
|
+
next.set(canonical, reconciled);
|
|
329
|
+
return next;
|
|
330
|
+
});
|
|
331
|
+
setChildIssues((prev) => {
|
|
332
|
+
if (!prev.has(canonical)) return prev;
|
|
333
|
+
const next = new Map(prev);
|
|
334
|
+
next.delete(canonical);
|
|
335
|
+
return next;
|
|
336
|
+
});
|
|
337
|
+
settleAutoRetry(canonical, hasUnreadableFile(children));
|
|
338
|
+
} catch (caught) {
|
|
339
|
+
if (!isCurrent()) return;
|
|
340
|
+
const issue = readIssue(caught, dirPath);
|
|
341
|
+
setChildIssues((prev) => {
|
|
342
|
+
const next = new Map(prev);
|
|
343
|
+
next.set(canonical, issue);
|
|
344
|
+
return next;
|
|
345
|
+
});
|
|
346
|
+
settleAutoRetry(canonical, issue.retryable);
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
[settleAutoRetry]
|
|
350
|
+
);
|
|
298
351
|
useEffect(() => {
|
|
299
352
|
setEntries([]);
|
|
300
353
|
setExpanded(/* @__PURE__ */ new Set());
|
|
@@ -304,8 +357,10 @@ function useFileTree(provider, metadataRefreshKey, metadataRefreshPath) {
|
|
|
304
357
|
setSelectedKind(null);
|
|
305
358
|
setRootIssue(null);
|
|
306
359
|
directoryRequestsRef.current.clear();
|
|
360
|
+
cancelAllAutoRetries();
|
|
307
361
|
void loadRoot();
|
|
308
|
-
|
|
362
|
+
return cancelAllAutoRetries;
|
|
363
|
+
}, [provider, loadRoot, cancelAllAutoRetries]);
|
|
309
364
|
const toggleExpand = useCallback(
|
|
310
365
|
(path) => {
|
|
311
366
|
setExpanded((prev) => {
|
|
@@ -352,10 +407,12 @@ function useFileTree(provider, metadataRefreshKey, metadataRefreshPath) {
|
|
|
352
407
|
}, [loadRoot, loadChildren, expanded]);
|
|
353
408
|
const retryDirectory = useCallback(
|
|
354
409
|
async (path) => {
|
|
355
|
-
|
|
410
|
+
const canonical = normalisePath(path);
|
|
411
|
+
cancelAutoRetry(canonical);
|
|
412
|
+
if (canonical === "") await loadRoot();
|
|
356
413
|
else await loadChildren(path);
|
|
357
414
|
},
|
|
358
|
-
[loadRoot, loadChildren]
|
|
415
|
+
[loadRoot, loadChildren, cancelAutoRetry]
|
|
359
416
|
);
|
|
360
417
|
const refreshRef = useRef(refresh);
|
|
361
418
|
refreshRef.current = refresh;
|
|
@@ -366,6 +423,7 @@ function useFileTree(provider, metadataRefreshKey, metadataRefreshPath) {
|
|
|
366
423
|
},
|
|
367
424
|
[loadChildren, loadRoot]
|
|
368
425
|
);
|
|
426
|
+
autoRetryLoadRef.current = refreshDirectory;
|
|
369
427
|
const previousMetadataRefreshKeyRef = useRef(metadataRefreshKey);
|
|
370
428
|
useEffect(() => {
|
|
371
429
|
if (Object.is(previousMetadataRefreshKeyRef.current, metadataRefreshKey)) return;
|
|
@@ -542,12 +600,13 @@ function useFileTree(provider, metadataRefreshKey, metadataRefreshPath) {
|
|
|
542
600
|
setExpanded(nextExpanded);
|
|
543
601
|
setChildEntries(/* @__PURE__ */ new Map());
|
|
544
602
|
setChildIssues(/* @__PURE__ */ new Map());
|
|
603
|
+
cancelAllAutoRetries();
|
|
545
604
|
await loadRoot();
|
|
546
605
|
for (const dirPath of nextExpanded) {
|
|
547
606
|
await loadChildren(dirPath);
|
|
548
607
|
}
|
|
549
608
|
},
|
|
550
|
-
[selectedPath, entries, childEntries, expanded, loadRoot, loadChildren]
|
|
609
|
+
[selectedPath, entries, childEntries, expanded, loadRoot, loadChildren, cancelAllAutoRetries]
|
|
551
610
|
);
|
|
552
611
|
return {
|
|
553
612
|
entries,
|
|
@@ -788,6 +847,11 @@ function FileTreeNode({
|
|
|
788
847
|
}) {
|
|
789
848
|
const [renaming, setRenaming] = useState2(false);
|
|
790
849
|
const [renameValue, setRenameValue] = useState2(entry.name);
|
|
850
|
+
const readIssue2 = entry.kind === "file" ? entry.readIssue : void 0;
|
|
851
|
+
const rowStatus = [
|
|
852
|
+
badge?.label,
|
|
853
|
+
readIssue2 ? `could not be read: ${readIssue2.message}` : void 0
|
|
854
|
+
].filter((part) => part !== void 0);
|
|
791
855
|
const [showContext, setShowContext] = useState2(false);
|
|
792
856
|
const [contextPos, setContextPos] = useState2({ x: 0, y: 0 });
|
|
793
857
|
const [actionError, setActionError] = useState2(null);
|
|
@@ -1034,7 +1098,7 @@ function FileTreeNode({
|
|
|
1034
1098
|
"data-path": entry.path,
|
|
1035
1099
|
"aria-expanded": isDir ? expanded : void 0,
|
|
1036
1100
|
"aria-selected": selected,
|
|
1037
|
-
"aria-label":
|
|
1101
|
+
"aria-label": rowStatus.length > 0 ? `${entry.name}, ${rowStatus.join(", ")}` : void 0,
|
|
1038
1102
|
"aria-level": depth + 1,
|
|
1039
1103
|
"aria-posinset": posInSet,
|
|
1040
1104
|
"aria-setsize": setSize,
|
|
@@ -1086,6 +1150,15 @@ function FileTreeNode({
|
|
|
1086
1150
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1087
1151
|
/* @__PURE__ */ jsx2("span", { className: "db-tree-label", children: displayFileName(entry.name) }),
|
|
1088
1152
|
badge && /* @__PURE__ */ jsx2("span", { className: `db-git-badge db-git-badge--${badge.kind}`, "aria-hidden": "true", children: badge.glyph }),
|
|
1153
|
+
readIssue2 && /* @__PURE__ */ jsx2(
|
|
1154
|
+
"span",
|
|
1155
|
+
{
|
|
1156
|
+
className: "db-tree-read-issue",
|
|
1157
|
+
title: `Could not read this file: ${readIssue2.message}`,
|
|
1158
|
+
"aria-hidden": "true",
|
|
1159
|
+
children: "!"
|
|
1160
|
+
}
|
|
1161
|
+
),
|
|
1089
1162
|
entry.kind === "file" && entry.lastModified && /* @__PURE__ */ jsx2(LastModifiedTime, { value: entry.lastModified }),
|
|
1090
1163
|
/* @__PURE__ */ jsx2(
|
|
1091
1164
|
"button",
|
|
@@ -1717,6 +1790,7 @@ import {
|
|
|
1717
1790
|
FsError as FsError3,
|
|
1718
1791
|
SQUISQ_RUNTIME_DIRECTORY_NAME,
|
|
1719
1792
|
getFileSystemProviderV2 as getFileSystemProviderV23,
|
|
1793
|
+
findWikiArticle,
|
|
1720
1794
|
parseWorkspacePath as parseWorkspacePath3
|
|
1721
1795
|
} from "@bendyline/docblocks/filesystem";
|
|
1722
1796
|
import {
|
|
@@ -2149,10 +2223,7 @@ async function writeRuntimeIfNeeded(provider, runtimePath) {
|
|
|
2149
2223
|
if (current !== PLAYER_BUNDLE) await writeProviderText(provider, runtimePath, PLAYER_BUNDLE);
|
|
2150
2224
|
}
|
|
2151
2225
|
async function renderPlainOutsideInHtml(provider, layout, markdown, themeId) {
|
|
2152
|
-
const
|
|
2153
|
-
import("@bendyline/squisq/markdown"),
|
|
2154
|
-
import("@bendyline/squisq-formats/html")
|
|
2155
|
-
]);
|
|
2226
|
+
const { markdownDocToPlainHtml } = await import("@bendyline/squisq-formats/html");
|
|
2156
2227
|
const container = new FileSystemContentContainer(provider, layout.companionDirectory);
|
|
2157
2228
|
const images = /* @__PURE__ */ new Map();
|
|
2158
2229
|
for (const entry of await container.listFiles()) {
|
|
@@ -2161,7 +2232,7 @@ async function renderPlainOutsideInHtml(provider, layout, markdown, themeId) {
|
|
|
2161
2232
|
images.set(`./${entry.path}`, outputPath);
|
|
2162
2233
|
}
|
|
2163
2234
|
return new TextEncoder().encode(
|
|
2164
|
-
markdownDocToPlainHtml(
|
|
2235
|
+
markdownDocToPlainHtml(markdown, {
|
|
2165
2236
|
title: layout.stem,
|
|
2166
2237
|
images: images.size > 0 ? images : void 0,
|
|
2167
2238
|
...themeId ? { themeId } : {}
|
|
@@ -2171,9 +2242,22 @@ async function renderPlainOutsideInHtml(provider, layout, markdown, themeId) {
|
|
|
2171
2242
|
async function prepareOutsideInRender(provider, layout, markdown, render) {
|
|
2172
2243
|
const themeId = await resolveFallbackRenderTheme(markdown, render);
|
|
2173
2244
|
const htmlOutput = layout.format === "html" ? await readOutsideInHtmlOutput(markdown) : null;
|
|
2245
|
+
let renderedSource = markdown;
|
|
2246
|
+
if (layout.format === "html") {
|
|
2247
|
+
const { parseMarkdown, resolveWikiLinks } = await import("@bendyline/squisq/markdown");
|
|
2248
|
+
renderedSource = await resolveWikiLinks(parseMarkdown(markdown), async (target) => {
|
|
2249
|
+
const article = await findWikiArticle(provider, layout.targetPath, target, ".html");
|
|
2250
|
+
return article.exists ? article.relativePath.split("/").map(encodeURIComponent).join("/") : null;
|
|
2251
|
+
});
|
|
2252
|
+
}
|
|
2174
2253
|
if (htmlOutput === "static") {
|
|
2175
2254
|
return {
|
|
2176
|
-
bytes: await renderPlainOutsideInHtml(
|
|
2255
|
+
bytes: await renderPlainOutsideInHtml(
|
|
2256
|
+
provider,
|
|
2257
|
+
layout,
|
|
2258
|
+
renderedSource,
|
|
2259
|
+
themeId
|
|
2260
|
+
),
|
|
2177
2261
|
runtimePath: null
|
|
2178
2262
|
};
|
|
2179
2263
|
}
|
|
@@ -2181,7 +2265,7 @@ async function prepareOutsideInRender(provider, layout, markdown, render) {
|
|
|
2181
2265
|
const outputDirectory = dirname(layout.targetPath);
|
|
2182
2266
|
const rendered = await renderOutsideInDocument(
|
|
2183
2267
|
{
|
|
2184
|
-
markdown,
|
|
2268
|
+
markdown: renderedSource,
|
|
2185
2269
|
targetPath: layout.targetPath,
|
|
2186
2270
|
container: new FileSystemContentContainer(provider, layout.companionDirectory)
|
|
2187
2271
|
},
|
|
@@ -2416,6 +2500,10 @@ var NEW_ITEM_HINT_ID = "db-new-item-hint";
|
|
|
2416
2500
|
function normalisePath2(path) {
|
|
2417
2501
|
return parseWorkspacePath4(path);
|
|
2418
2502
|
}
|
|
2503
|
+
function readIssueText(issue) {
|
|
2504
|
+
const failingPath = tryParseWorkspacePath2(issue.path);
|
|
2505
|
+
return failingPath && failingPath !== issue.directoryPath ? `${failingPath}: ${issue.message}` : issue.message;
|
|
2506
|
+
}
|
|
2419
2507
|
function hasEquivalentPath2(paths, path) {
|
|
2420
2508
|
const canonical = normalisePath2(path);
|
|
2421
2509
|
return paths.has(path) || paths.has(canonical) || canonical !== "" && paths.has(`/${canonical}`);
|
|
@@ -2880,7 +2968,7 @@ function FileExplorer({
|
|
|
2880
2968
|
role: "alert",
|
|
2881
2969
|
"data-directory-path": childIssue.directoryPath,
|
|
2882
2970
|
children: [
|
|
2883
|
-
/* @__PURE__ */ jsx5("span", { children: childIssue
|
|
2971
|
+
/* @__PURE__ */ jsx5("span", { children: readIssueText(childIssue) }),
|
|
2884
2972
|
" ",
|
|
2885
2973
|
/* @__PURE__ */ jsx5(
|
|
2886
2974
|
"button",
|
|
@@ -3161,7 +3249,7 @@ function FileExplorer({
|
|
|
3161
3249
|
role: "alert",
|
|
3162
3250
|
"data-directory-path": tree.rootIssue.directoryPath,
|
|
3163
3251
|
children: [
|
|
3164
|
-
/* @__PURE__ */ jsx5("span", { children: tree.rootIssue
|
|
3252
|
+
/* @__PURE__ */ jsx5("span", { children: readIssueText(tree.rootIssue) }),
|
|
3165
3253
|
" ",
|
|
3166
3254
|
/* @__PURE__ */ jsx5(
|
|
3167
3255
|
"button",
|
|
@@ -3686,13 +3774,15 @@ import {
|
|
|
3686
3774
|
FileSystemContentContainer as FileSystemContentContainer2,
|
|
3687
3775
|
createFileMediaProvider,
|
|
3688
3776
|
decodeUtf8Text,
|
|
3689
|
-
FsError as
|
|
3690
|
-
getFileSystemProviderV2 as
|
|
3777
|
+
FsError as FsError6,
|
|
3778
|
+
getFileSystemProviderV2 as getFileSystemProviderV211,
|
|
3691
3779
|
isQuotaExceededError,
|
|
3692
3780
|
moveFileSystemEntry as moveFileSystemEntry2,
|
|
3693
3781
|
rewriteCompanionReferences,
|
|
3694
3782
|
parseWorkspacePath as parseWorkspacePath8,
|
|
3695
|
-
workspacePathContains
|
|
3783
|
+
workspacePathContains,
|
|
3784
|
+
findWikiArticle as findWikiArticle2,
|
|
3785
|
+
suggestWikiArticles
|
|
3696
3786
|
} from "@bendyline/docblocks/filesystem";
|
|
3697
3787
|
import {
|
|
3698
3788
|
createFileSystemDocumentTarget as createFileSystemDocumentTarget2,
|
|
@@ -3715,12 +3805,14 @@ import {
|
|
|
3715
3805
|
getWorkspace,
|
|
3716
3806
|
listWorkspaces as listWorkspaces2,
|
|
3717
3807
|
reconcileElectronWorkspaceDescriptors,
|
|
3718
|
-
removeWorkspace,
|
|
3719
|
-
saveWorkspace as
|
|
3808
|
+
removeWorkspace as removeWorkspace2,
|
|
3809
|
+
saveWorkspace as saveWorkspace3,
|
|
3720
3810
|
touchWorkspace as touchWorkspace2,
|
|
3721
3811
|
registerTransientWorkspace,
|
|
3722
3812
|
getTransientWorkspace,
|
|
3723
|
-
unregisterTransientWorkspace
|
|
3813
|
+
unregisterTransientWorkspace,
|
|
3814
|
+
appendWorkspaceBackup,
|
|
3815
|
+
finishWorkspaceBackup
|
|
3724
3816
|
} from "@bendyline/docblocks/workspace";
|
|
3725
3817
|
|
|
3726
3818
|
// src/AppMenu/AppMenu.tsx
|
|
@@ -4077,6 +4169,7 @@ function AppMenu({
|
|
|
4077
4169
|
onVersioningPreferenceChange,
|
|
4078
4170
|
onOpenWorkspaceSettings,
|
|
4079
4171
|
onDownloadAllWorkspaces,
|
|
4172
|
+
onRestoreBackup,
|
|
4080
4173
|
onShowKeyboardShortcuts,
|
|
4081
4174
|
onKeepBrowserData,
|
|
4082
4175
|
onInstallApp,
|
|
@@ -4211,7 +4304,7 @@ function AppMenu({
|
|
|
4211
4304
|
children: "Install DocBlocks\u2026"
|
|
4212
4305
|
}
|
|
4213
4306
|
),
|
|
4214
|
-
(onDownloadAllWorkspaces || onKeepBrowserData) && /* @__PURE__ */ jsx8("div", { className: "db-app-menu-divider" }),
|
|
4307
|
+
(onDownloadAllWorkspaces || onRestoreBackup || onKeepBrowserData) && /* @__PURE__ */ jsx8("div", { className: "db-app-menu-divider" }),
|
|
4215
4308
|
onDownloadAllWorkspaces && /* @__PURE__ */ jsx8(
|
|
4216
4309
|
"button",
|
|
4217
4310
|
{
|
|
@@ -4222,6 +4315,16 @@ function AppMenu({
|
|
|
4222
4315
|
children: "Back up all workspaces"
|
|
4223
4316
|
}
|
|
4224
4317
|
),
|
|
4318
|
+
onRestoreBackup && /* @__PURE__ */ jsx8(
|
|
4319
|
+
"button",
|
|
4320
|
+
{
|
|
4321
|
+
className: "db-app-menu-item",
|
|
4322
|
+
role: "menuitem",
|
|
4323
|
+
tabIndex: -1,
|
|
4324
|
+
onClick: () => handleAction(onRestoreBackup),
|
|
4325
|
+
children: "Restore backup\u2026"
|
|
4326
|
+
}
|
|
4327
|
+
),
|
|
4225
4328
|
onKeepBrowserData && /* @__PURE__ */ jsx8(
|
|
4226
4329
|
"button",
|
|
4227
4330
|
{
|
|
@@ -4473,6 +4576,59 @@ function AppMenu({
|
|
|
4473
4576
|
] });
|
|
4474
4577
|
}
|
|
4475
4578
|
|
|
4579
|
+
// src/DocBlocksShell/restore-backup.ts
|
|
4580
|
+
import {
|
|
4581
|
+
readWorkspaceBackup,
|
|
4582
|
+
restoreWorkspaceBackup,
|
|
4583
|
+
WORKSPACE_BACKUP_LIMITS,
|
|
4584
|
+
saveWorkspace as saveWorkspace2,
|
|
4585
|
+
removeWorkspace
|
|
4586
|
+
} from "@bendyline/docblocks/workspace";
|
|
4587
|
+
async function restoreBrowserBackup(file) {
|
|
4588
|
+
if (file.size > 256 * 1024 * 1024) throw new Error("Backup ZIPs must be smaller than 256 MiB.");
|
|
4589
|
+
const { zipToContainer } = await import("@bendyline/squisq-formats/container");
|
|
4590
|
+
const container = await zipToContainer(await file.arrayBuffer(), WORKSPACE_BACKUP_LIMITS);
|
|
4591
|
+
const workspaces = await readWorkspaceBackup(
|
|
4592
|
+
container,
|
|
4593
|
+
file.name.replace(/\.zip$/i, "") || "Workspace"
|
|
4594
|
+
);
|
|
4595
|
+
const { IndexedDBFileSystemProvider, deleteIndexedDBWorkspaceData } = await import("@bendyline/docblocks/filesystem/indexeddb");
|
|
4596
|
+
const staged = [];
|
|
4597
|
+
try {
|
|
4598
|
+
for (const workspace of workspaces) {
|
|
4599
|
+
const descriptor = {
|
|
4600
|
+
id: `restored-${crypto.randomUUID()}`,
|
|
4601
|
+
name: `${workspace.name.slice(0, 1013)} (restored)`,
|
|
4602
|
+
type: "indexeddb",
|
|
4603
|
+
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
4604
|
+
};
|
|
4605
|
+
const provider = new IndexedDBFileSystemProvider(descriptor.id, descriptor.name).v2;
|
|
4606
|
+
staged.push({ descriptor, provider });
|
|
4607
|
+
await restoreWorkspaceBackup(workspace, provider);
|
|
4608
|
+
}
|
|
4609
|
+
for (const { descriptor } of staged) await saveWorkspace2(descriptor);
|
|
4610
|
+
return staged.map(({ descriptor }) => descriptor);
|
|
4611
|
+
} catch (error) {
|
|
4612
|
+
const failures = [error];
|
|
4613
|
+
for (const { descriptor, provider } of staged) {
|
|
4614
|
+
try {
|
|
4615
|
+
await provider.dispose();
|
|
4616
|
+
await removeWorkspace(descriptor.id);
|
|
4617
|
+
await deleteIndexedDBWorkspaceData(descriptor.id);
|
|
4618
|
+
} catch (cleanupError) {
|
|
4619
|
+
failures.push(cleanupError);
|
|
4620
|
+
}
|
|
4621
|
+
}
|
|
4622
|
+
if (failures.length > 1)
|
|
4623
|
+
throw new Error(
|
|
4624
|
+
`Restore failed; temporary workspace cleanup also failed. ${failures.map((failure) => failure instanceof Error ? failure.message : String(failure)).join("; ")}`
|
|
4625
|
+
);
|
|
4626
|
+
throw error;
|
|
4627
|
+
} finally {
|
|
4628
|
+
for (const { provider } of staged) await provider.dispose();
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
|
|
4476
4632
|
// src/WorkspacePicker/WorkspaceSettingsButton.tsx
|
|
4477
4633
|
import { useState as useState8, useCallback as useCallback9, useRef as useRef9, useEffect as useEffect9 } from "react";
|
|
4478
4634
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -4995,7 +5151,7 @@ function useDocumentSession(autoSaveDelayMs = 500) {
|
|
|
4995
5151
|
import { lazy, Suspense } from "react";
|
|
4996
5152
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
4997
5153
|
var ExportToolbarControlsImplementation = lazy(
|
|
4998
|
-
() => import("./ExportToolbarControls-
|
|
5154
|
+
() => import("./ExportToolbarControls-HOV424TO.js").then((module) => ({
|
|
4999
5155
|
default: module.ExportToolbarControls
|
|
5000
5156
|
}))
|
|
5001
5157
|
);
|
|
@@ -5565,7 +5721,7 @@ function resolveShellEditorLinkTarget(href, documentPath) {
|
|
|
5565
5721
|
targetSegments.push(segment);
|
|
5566
5722
|
}
|
|
5567
5723
|
const path = targetSegments.join("/");
|
|
5568
|
-
if (!path || path.length > HOST_WIRE_LIMITS2.pathCharacters || !isMarkdownFileName(path)) {
|
|
5724
|
+
if (!path || path.length > HOST_WIRE_LIMITS2.pathCharacters || !isMarkdownFileName(path) && !/\.html?$/i.test(path)) {
|
|
5569
5725
|
return null;
|
|
5570
5726
|
}
|
|
5571
5727
|
return { kind: "workspace", path };
|
|
@@ -5588,10 +5744,36 @@ function hasControlCharacter(value) {
|
|
|
5588
5744
|
return false;
|
|
5589
5745
|
}
|
|
5590
5746
|
|
|
5591
|
-
// src/DocBlocksShell/
|
|
5747
|
+
// src/DocBlocksShell/wiki-articles.ts
|
|
5592
5748
|
import {
|
|
5749
|
+
ensureWikiArticle,
|
|
5750
|
+
wikiArticleExists,
|
|
5593
5751
|
FsError as FsError4,
|
|
5594
|
-
getFileSystemProviderV2 as getFileSystemProviderV27
|
|
5752
|
+
getFileSystemProviderV2 as getFileSystemProviderV27
|
|
5753
|
+
} from "@bendyline/docblocks/filesystem";
|
|
5754
|
+
function wikiArticleExtension(format) {
|
|
5755
|
+
return newFileHtmlOutput(format) ? ".html" : ".md";
|
|
5756
|
+
}
|
|
5757
|
+
async function ensureShellWikiArticle(provider, path, format, render) {
|
|
5758
|
+
if (!/\.html?$/i.test(path)) return ensureWikiArticle(provider, path);
|
|
5759
|
+
if (await wikiArticleExists(provider, path)) return false;
|
|
5760
|
+
if (!getFileSystemProviderV27(provider)) {
|
|
5761
|
+
throw new FsError4("not-supported", "This workspace cannot create articles safely.");
|
|
5762
|
+
}
|
|
5763
|
+
try {
|
|
5764
|
+
await createNewOutsideInDocument(provider, path, newFileHtmlOutput(format), render);
|
|
5765
|
+
return true;
|
|
5766
|
+
} catch (error) {
|
|
5767
|
+
if (error instanceof FsError4 && (error.code === "already-exists" || error.code === "conflict") && await wikiArticleExists(provider, path))
|
|
5768
|
+
return false;
|
|
5769
|
+
throw error;
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
|
|
5773
|
+
// src/DocBlocksShell/import-files.ts
|
|
5774
|
+
import {
|
|
5775
|
+
FsError as FsError5,
|
|
5776
|
+
getFileSystemProviderV2 as getFileSystemProviderV28,
|
|
5595
5777
|
parseWorkspacePath as parseWorkspacePath6
|
|
5596
5778
|
} from "@bendyline/docblocks/filesystem";
|
|
5597
5779
|
var MAX_NAME_ATTEMPTS = 100;
|
|
@@ -5602,7 +5784,7 @@ function withCopySuffix(path, n) {
|
|
|
5602
5784
|
return `${path.slice(0, dot)} (${n})${path.slice(dot)}`;
|
|
5603
5785
|
}
|
|
5604
5786
|
function isAlreadyExists(error) {
|
|
5605
|
-
return error instanceof
|
|
5787
|
+
return error instanceof FsError5 && error.code === "already-exists";
|
|
5606
5788
|
}
|
|
5607
5789
|
async function claimAvailablePath(provider, desiredPath) {
|
|
5608
5790
|
for (let attempt = 1; attempt <= MAX_NAME_ATTEMPTS; attempt++) {
|
|
@@ -5617,7 +5799,7 @@ async function claimAvailablePath(provider, desiredPath) {
|
|
|
5617
5799
|
throw new Error(`Too many documents are already named like \u201C${desiredPath}\u201D.`);
|
|
5618
5800
|
}
|
|
5619
5801
|
async function writeProviderBytes(provider, path, data, mode) {
|
|
5620
|
-
const providerV2 =
|
|
5802
|
+
const providerV2 = getFileSystemProviderV28(provider);
|
|
5621
5803
|
if (providerV2) {
|
|
5622
5804
|
await providerV2.writeFile(parseWorkspacePath6(path), data, {
|
|
5623
5805
|
mode,
|
|
@@ -5627,7 +5809,7 @@ async function writeProviderBytes(provider, path, data, mode) {
|
|
|
5627
5809
|
return;
|
|
5628
5810
|
}
|
|
5629
5811
|
if (mode === "create" && await providerEntryExists(provider, path)) {
|
|
5630
|
-
throw new
|
|
5812
|
+
throw new FsError5("already-exists", "File already exists.", { operation: "write", path });
|
|
5631
5813
|
}
|
|
5632
5814
|
await provider.writeBinary(path, data);
|
|
5633
5815
|
}
|
|
@@ -5660,7 +5842,7 @@ function directoriesUnder(files, root) {
|
|
|
5660
5842
|
return [...directories].sort((a, b) => b.split("/").length - a.split("/").length);
|
|
5661
5843
|
}
|
|
5662
5844
|
async function removeIfEmptyDirectory(provider, path) {
|
|
5663
|
-
const providerV2 =
|
|
5845
|
+
const providerV2 = getFileSystemProviderV28(provider);
|
|
5664
5846
|
if (!providerV2) return;
|
|
5665
5847
|
await providerV2.remove(parseWorkspacePath6(path), { recursive: false, missing: "ignore" }).catch(() => void 0);
|
|
5666
5848
|
}
|
|
@@ -6038,7 +6220,7 @@ function resolveShellTheme({
|
|
|
6038
6220
|
}
|
|
6039
6221
|
|
|
6040
6222
|
// src/DocBlocksShell/last-state.ts
|
|
6041
|
-
import { tryParseWorkspacePath as
|
|
6223
|
+
import { tryParseWorkspacePath as tryParseWorkspacePath3 } from "@bendyline/docblocks/filesystem";
|
|
6042
6224
|
var LAST_STATE_KEY = "docblocks:lastState";
|
|
6043
6225
|
var MAX_WORKSPACE_ID_CHARACTERS = 256;
|
|
6044
6226
|
var MAX_WORKSPACE_PATH_CHARACTERS = 4096;
|
|
@@ -6059,7 +6241,7 @@ function parseLastState(value) {
|
|
|
6059
6241
|
if (!hasExactKeys(record, ["workspaceId", "filePath", "view"])) return null;
|
|
6060
6242
|
if (!isBoundedText(record.workspaceId, MAX_WORKSPACE_ID_CHARACTERS)) return null;
|
|
6061
6243
|
if (!isBoundedText(record.filePath, MAX_WORKSPACE_PATH_CHARACTERS)) return null;
|
|
6062
|
-
const parsedPath =
|
|
6244
|
+
const parsedPath = tryParseWorkspacePath3(record.filePath);
|
|
6063
6245
|
if (!parsedPath) return null;
|
|
6064
6246
|
if (typeof record.view !== "string" || !EDITOR_VIEWS.has(record.view)) return null;
|
|
6065
6247
|
return {
|
|
@@ -6853,7 +7035,7 @@ function useDocumentLinkProvider(index, selectedFile, ensureIndex) {
|
|
|
6853
7035
|
|
|
6854
7036
|
// src/WorkspaceIndex/useWorkspaceIndex.ts
|
|
6855
7037
|
import { useCallback as useCallback17, useEffect as useEffect28, useMemo as useMemo5, useRef as useRef18, useState as useState22, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
6856
|
-
import { getFileSystemProviderV2 as
|
|
7038
|
+
import { getFileSystemProviderV2 as getFileSystemProviderV29 } from "@bendyline/docblocks/filesystem";
|
|
6857
7039
|
import { maybeGetDocBlocksHost as maybeGetDocBlocksHost3 } from "@bendyline/docblocks/host";
|
|
6858
7040
|
var IDLE_WORKSPACE_INDEX_STATUS = Object.freeze({
|
|
6859
7041
|
phase: "idle",
|
|
@@ -6883,7 +7065,7 @@ function whenIdle(callback) {
|
|
|
6883
7065
|
return () => clearTimeout(handle);
|
|
6884
7066
|
}
|
|
6885
7067
|
function useWorkspaceIndex(provider, workspaceId, mode = "eager") {
|
|
6886
|
-
const providerV2 = provider && mode !== "off" ?
|
|
7068
|
+
const providerV2 = provider && mode !== "off" ? getFileSystemProviderV29(provider) : null;
|
|
6887
7069
|
const [index, setIndex] = useState22(null);
|
|
6888
7070
|
const startRequestedRef = useRef18(false);
|
|
6889
7071
|
useEffect28(() => {
|
|
@@ -6946,7 +7128,7 @@ function useWorkspaceIndex(provider, workspaceId, mode = "eager") {
|
|
|
6946
7128
|
}
|
|
6947
7129
|
|
|
6948
7130
|
// src/WorkspaceIndex/recent-documents.ts
|
|
6949
|
-
import { tryParseWorkspacePath as
|
|
7131
|
+
import { tryParseWorkspacePath as tryParseWorkspacePath4 } from "@bendyline/docblocks/filesystem";
|
|
6950
7132
|
var RECENT_DOCUMENTS_STORAGE_KEY = "docblocks:recentDocuments:v1";
|
|
6951
7133
|
var MAX_PATHS_PER_WORKSPACE = 50;
|
|
6952
7134
|
var MAX_WORKSPACES = 50;
|
|
@@ -6965,7 +7147,7 @@ function defaultStorage() {
|
|
|
6965
7147
|
}
|
|
6966
7148
|
function canonicalPath(path) {
|
|
6967
7149
|
if (path.length === 0 || path.length > MAX_PATH_LENGTH) return null;
|
|
6968
|
-
return
|
|
7150
|
+
return tryParseWorkspacePath4(path) || null;
|
|
6969
7151
|
}
|
|
6970
7152
|
function parseRecentDocuments(value) {
|
|
6971
7153
|
const parsed = /* @__PURE__ */ new Map();
|
|
@@ -7071,14 +7253,14 @@ var WorkspaceAuthorityBarrier = class {
|
|
|
7071
7253
|
|
|
7072
7254
|
// src/DocBlocksShell/transient-workspace-move.ts
|
|
7073
7255
|
import {
|
|
7074
|
-
getFileSystemProviderV2 as
|
|
7256
|
+
getFileSystemProviderV2 as getFileSystemProviderV210
|
|
7075
7257
|
} from "@bendyline/docblocks/filesystem";
|
|
7076
7258
|
function pathDepth(path) {
|
|
7077
7259
|
return path ? path.split("/").length : 0;
|
|
7078
7260
|
}
|
|
7079
7261
|
async function copyTransientWorkspaceContents(source, destination) {
|
|
7080
|
-
const sourceV2 =
|
|
7081
|
-
const destinationV2 =
|
|
7262
|
+
const sourceV2 = getFileSystemProviderV210(source);
|
|
7263
|
+
const destinationV2 = getFileSystemProviderV210(destination);
|
|
7082
7264
|
if (!sourceV2 || !destinationV2) {
|
|
7083
7265
|
throw new Error("Moving a temporary document requires a current workspace provider.");
|
|
7084
7266
|
}
|
|
@@ -7243,13 +7425,13 @@ function loadEditorShell() {
|
|
|
7243
7425
|
return editorShellModulePromise;
|
|
7244
7426
|
}
|
|
7245
7427
|
var EditorShell = lazy2(loadEditorShell);
|
|
7246
|
-
var DocumentConflictDialog = lazy2(() => import("./DocumentConflictDialog-
|
|
7247
|
-
var GitUI = lazy2(() => import("./GitUI-
|
|
7428
|
+
var DocumentConflictDialog = lazy2(() => import("./DocumentConflictDialog-DZ2BV2IH.js"));
|
|
7429
|
+
var GitUI = lazy2(() => import("./GitUI-F3CNBURE.js").then((m) => ({ default: m.GitUI })));
|
|
7248
7430
|
var QuickOpenDialog = lazy2(
|
|
7249
|
-
() => import("./QuickOpenDialog-
|
|
7431
|
+
() => import("./QuickOpenDialog-ENVFGIHS.js").then((m) => ({ default: m.QuickOpenDialog }))
|
|
7250
7432
|
);
|
|
7251
7433
|
var KeyboardShortcutsDialog = lazy2(
|
|
7252
|
-
() => import("./KeyboardShortcutsDialog-
|
|
7434
|
+
() => import("./KeyboardShortcutsDialog-HVKDFP5Z.js").then((m) => ({ default: m.KeyboardShortcutsDialog }))
|
|
7253
7435
|
);
|
|
7254
7436
|
var WorkspaceSearchPanel = lazy2(
|
|
7255
7437
|
() => import("./WorkspaceSearchPanel-J6BKEZQJ.js").then((m) => ({
|
|
@@ -7263,37 +7445,37 @@ var GitToolbarControl = lazy2(
|
|
|
7263
7445
|
() => import("./GitToolbarControl-B7KG4MFP.js").then((m) => ({ default: m.GitToolbarControl }))
|
|
7264
7446
|
);
|
|
7265
7447
|
var AiToolbarControl = lazy2(
|
|
7266
|
-
() => import("./AiEditorAssistant-
|
|
7448
|
+
() => import("./AiEditorAssistant-4HFFGVU4.js").then((module) => ({
|
|
7267
7449
|
default: module.AiToolbarControl
|
|
7268
7450
|
}))
|
|
7269
7451
|
);
|
|
7270
7452
|
var PresentationMaker = lazy2(
|
|
7271
|
-
() => import("./PresentationMaker-
|
|
7453
|
+
() => import("./PresentationMaker-MUMFAXEI.js").then((module) => ({
|
|
7272
7454
|
default: module.PresentationMaker
|
|
7273
7455
|
}))
|
|
7274
7456
|
);
|
|
7275
7457
|
var AiReviewPanel = lazy2(
|
|
7276
|
-
() => import("./AiEditorAssistant-
|
|
7458
|
+
() => import("./AiEditorAssistant-4HFFGVU4.js").then((module) => ({
|
|
7277
7459
|
default: module.AiReviewPanel
|
|
7278
7460
|
}))
|
|
7279
7461
|
);
|
|
7280
7462
|
var AiIllustratePanel = lazy2(
|
|
7281
|
-
() => import("./AiDiagrams-
|
|
7463
|
+
() => import("./AiDiagrams-QZMJNGDT.js").then((module) => ({
|
|
7282
7464
|
default: module.AiIllustratePanel
|
|
7283
7465
|
}))
|
|
7284
7466
|
);
|
|
7285
7467
|
var TextFromNarration = lazy2(
|
|
7286
|
-
() => import("./TextFromNarration-
|
|
7468
|
+
() => import("./TextFromNarration-EYOMW2IW.js").then((module) => ({
|
|
7287
7469
|
default: module.TextFromNarration
|
|
7288
7470
|
}))
|
|
7289
7471
|
);
|
|
7290
7472
|
var SpeechToolbarControl = lazy2(
|
|
7291
|
-
() => import("./SpeechToolbarControl-
|
|
7473
|
+
() => import("./SpeechToolbarControl-KNI2C4JJ.js").then((module) => ({
|
|
7292
7474
|
default: module.SpeechToolbarControl
|
|
7293
7475
|
}))
|
|
7294
7476
|
);
|
|
7295
7477
|
var SpeechMenuBridge = lazy2(
|
|
7296
|
-
() => import("./SpeechToolbarControl-
|
|
7478
|
+
() => import("./SpeechToolbarControl-KNI2C4JJ.js").then((module) => ({
|
|
7297
7479
|
default: module.SpeechMenuBridge
|
|
7298
7480
|
}))
|
|
7299
7481
|
);
|
|
@@ -7434,19 +7616,19 @@ function pathContains(parentPath2, candidatePath) {
|
|
|
7434
7616
|
return workspacePathContains(parseWorkspacePath8(parentPath2), parseWorkspacePath8(candidatePath));
|
|
7435
7617
|
}
|
|
7436
7618
|
async function readProviderDirectory2(provider, path) {
|
|
7437
|
-
const providerV2 =
|
|
7619
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7438
7620
|
if (!providerV2) return provider.readDirectory(path);
|
|
7439
7621
|
const entries = await providerV2.readDirectory(parseWorkspacePath8(path));
|
|
7440
7622
|
return entries.map((entry) => ({ kind: entry.kind, name: entry.name, path: entry.path }));
|
|
7441
7623
|
}
|
|
7442
7624
|
async function readProviderText(provider, path) {
|
|
7443
|
-
const providerV2 =
|
|
7625
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7444
7626
|
if (!providerV2) return provider.readFile(path);
|
|
7445
7627
|
const file = await providerV2.readFile(parseWorkspacePath8(path));
|
|
7446
7628
|
return file ? decodeUtf8Text(file.data, { label: "The document", path: parseWorkspacePath8(path) }) : null;
|
|
7447
7629
|
}
|
|
7448
7630
|
async function pinnedProviderFileExists(provider, path) {
|
|
7449
|
-
const providerV2 =
|
|
7631
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7450
7632
|
if (!providerV2) return provider.exists(path);
|
|
7451
7633
|
const entry = await providerV2.stat(parseWorkspacePath8(path));
|
|
7452
7634
|
if (!entry) return false;
|
|
@@ -7454,7 +7636,7 @@ async function pinnedProviderFileExists(provider, path) {
|
|
|
7454
7636
|
return true;
|
|
7455
7637
|
}
|
|
7456
7638
|
async function removePinnedProviderFile(provider, path) {
|
|
7457
|
-
const providerV2 =
|
|
7639
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7458
7640
|
if (providerV2) {
|
|
7459
7641
|
const canonical = parseWorkspacePath8(path);
|
|
7460
7642
|
const entry = await providerV2.stat(canonical);
|
|
@@ -7472,7 +7654,7 @@ async function removePinnedProviderFile(provider, path) {
|
|
|
7472
7654
|
return true;
|
|
7473
7655
|
}
|
|
7474
7656
|
async function readStableFileSnapshot(provider, path) {
|
|
7475
|
-
const providerV2 =
|
|
7657
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7476
7658
|
if (providerV2) {
|
|
7477
7659
|
const read2 = await providerV2.readFile(parseWorkspacePath8(path));
|
|
7478
7660
|
return {
|
|
@@ -7516,7 +7698,7 @@ async function ensureHandleWritePermission(handle) {
|
|
|
7516
7698
|
}
|
|
7517
7699
|
}
|
|
7518
7700
|
async function copyProviderToContainer(src, container, pathPrefix) {
|
|
7519
|
-
const providerV2 =
|
|
7701
|
+
const providerV2 = getFileSystemProviderV211(src);
|
|
7520
7702
|
if (providerV2) {
|
|
7521
7703
|
const snapshot = await providerV2.snapshot();
|
|
7522
7704
|
for (const entry of snapshot.entries) {
|
|
@@ -7859,7 +8041,7 @@ function DocBlocksShell({
|
|
|
7859
8041
|
const effectiveProofingIgnoreStore = proofingIgnoreStore === void 0 ? defaultProofingIgnoreStore : proofingIgnoreStore;
|
|
7860
8042
|
useEffect29(() => {
|
|
7861
8043
|
if (!provider || getTransientWorkspace(provider.id)) return;
|
|
7862
|
-
const providerV2 =
|
|
8044
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7863
8045
|
return providerV2 ? retainFileSystemProvider(providerV2) : void 0;
|
|
7864
8046
|
}, [provider]);
|
|
7865
8047
|
const [descriptorRefreshKey, setDescriptorRefreshKey] = useState23(0);
|
|
@@ -7947,7 +8129,7 @@ function DocBlocksShell({
|
|
|
7947
8129
|
void scan();
|
|
7948
8130
|
const scanOnFocus = () => void scan();
|
|
7949
8131
|
window.addEventListener("focus", scanOnFocus);
|
|
7950
|
-
const providerV2 =
|
|
8132
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
7951
8133
|
const subscription = providerV2?.capabilities.watch ? providerV2.watch(
|
|
7952
8134
|
(event) => {
|
|
7953
8135
|
if (event.type !== "modified") void scan();
|
|
@@ -8056,7 +8238,7 @@ function DocBlocksShell({
|
|
|
8056
8238
|
if (descriptor && descriptor.versioningOverride !== void 0) {
|
|
8057
8239
|
const moved = { ...descriptor };
|
|
8058
8240
|
delete moved.versioningOverride;
|
|
8059
|
-
await
|
|
8241
|
+
await saveWorkspace3(moved);
|
|
8060
8242
|
setDescriptorRefreshKey((k) => k + 1);
|
|
8061
8243
|
}
|
|
8062
8244
|
},
|
|
@@ -8153,7 +8335,13 @@ function DocBlocksShell({
|
|
|
8153
8335
|
return {
|
|
8154
8336
|
resolveTarget: (filename) => resolveTarget(documentId, filename),
|
|
8155
8337
|
pickTarget: (filename, currentTarget) => pickTarget(documentId, filename, currentTarget?.grantId ?? null),
|
|
8156
|
-
saveBlob: (blob, filename, target) => saveBlobToHost(exports, documentId, blob, filename, target?.grantId ?? null)
|
|
8338
|
+
saveBlob: (blob, filename, target) => saveBlobToHost(exports, documentId, blob, filename, target?.grantId ?? null),
|
|
8339
|
+
...hostSupports2("openSavedExports") && exports.openSaved ? {
|
|
8340
|
+
openSaved: async (target) => {
|
|
8341
|
+
if (!target.grantId) throw new Error("The saved export has no native target.");
|
|
8342
|
+
await exports.openSaved(documentId, target.grantId);
|
|
8343
|
+
}
|
|
8344
|
+
} : {}
|
|
8157
8345
|
};
|
|
8158
8346
|
}
|
|
8159
8347
|
}
|
|
@@ -8212,7 +8400,7 @@ function DocBlocksShell({
|
|
|
8212
8400
|
const workspaceOutputsResult = workspaceOutputs.status.result;
|
|
8213
8401
|
useEffect29(() => {
|
|
8214
8402
|
if (!workspaceOutputsResult?.outputs.some((output) => output.created)) return;
|
|
8215
|
-
if (provider &&
|
|
8403
|
+
if (provider && getFileSystemProviderV211(provider)?.capabilities.watch) return;
|
|
8216
8404
|
setExplorerKey((key) => key + 1);
|
|
8217
8405
|
}, [provider, workspaceOutputsResult]);
|
|
8218
8406
|
const [fileExplorerSortMode, setFileExplorerSortMode] = useState23(loadFileExplorerSortMode);
|
|
@@ -8515,7 +8703,7 @@ function DocBlocksShell({
|
|
|
8515
8703
|
}
|
|
8516
8704
|
return fsProvider;
|
|
8517
8705
|
} finally {
|
|
8518
|
-
if (!transient && !adopted) await
|
|
8706
|
+
if (!transient && !adopted) await getFileSystemProviderV211(fsProvider)?.dispose();
|
|
8519
8707
|
}
|
|
8520
8708
|
},
|
|
8521
8709
|
[adoptSelectedDocument, createDocumentTarget, documentSession, pushHash]
|
|
@@ -8567,7 +8755,7 @@ function DocBlocksShell({
|
|
|
8567
8755
|
)
|
|
8568
8756
|
});
|
|
8569
8757
|
} catch (error) {
|
|
8570
|
-
await
|
|
8758
|
+
await getFileSystemProviderV211(mem)?.dispose();
|
|
8571
8759
|
throw error;
|
|
8572
8760
|
}
|
|
8573
8761
|
return adoptTransientWorkspace({
|
|
@@ -8613,7 +8801,7 @@ function DocBlocksShell({
|
|
|
8613
8801
|
try {
|
|
8614
8802
|
await writeProviderText(fs, welcomePath, welcomeContent, "create");
|
|
8615
8803
|
} catch (error) {
|
|
8616
|
-
if (!(error instanceof
|
|
8804
|
+
if (!(error instanceof FsError6 && error.code === "already-exists")) throw error;
|
|
8617
8805
|
const existing = await readProviderText(fs, welcomePath);
|
|
8618
8806
|
if (existing === null) throw error;
|
|
8619
8807
|
seededContent = existing;
|
|
@@ -8669,8 +8857,8 @@ function DocBlocksShell({
|
|
|
8669
8857
|
getDocBlocksHost().env.platform,
|
|
8670
8858
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
8671
8859
|
);
|
|
8672
|
-
for (const id of reconciliation.removeIds) await
|
|
8673
|
-
for (const workspace of reconciliation.upsert) await
|
|
8860
|
+
for (const id of reconciliation.removeIds) await removeWorkspace2(id);
|
|
8861
|
+
for (const workspace of reconciliation.upsert) await saveWorkspace3(workspace);
|
|
8674
8862
|
workspaceIdRemap = reconciliation.idRemap;
|
|
8675
8863
|
for (const workspace of hostWorkspaces) {
|
|
8676
8864
|
if (workspace.isDefault === true) defaultHostWorkspaceIds.add(workspace.id);
|
|
@@ -8763,12 +8951,12 @@ function DocBlocksShell({
|
|
|
8763
8951
|
const p = await createHostProviderFromWorkspace(ws);
|
|
8764
8952
|
if (!p) continue;
|
|
8765
8953
|
if (!isCurrent()) {
|
|
8766
|
-
await
|
|
8954
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8767
8955
|
return;
|
|
8768
8956
|
}
|
|
8769
8957
|
await touchWorkspace2(ws.id);
|
|
8770
8958
|
if (!isCurrent()) {
|
|
8771
|
-
await
|
|
8959
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8772
8960
|
return;
|
|
8773
8961
|
}
|
|
8774
8962
|
fsProvider = p;
|
|
@@ -8777,12 +8965,12 @@ function DocBlocksShell({
|
|
|
8777
8965
|
const restored = await (await loadNativeFileSystem()).restoreNativeFolder(ws.id);
|
|
8778
8966
|
if (restored) {
|
|
8779
8967
|
if (!isCurrent()) {
|
|
8780
|
-
await
|
|
8968
|
+
await getFileSystemProviderV211(restored)?.dispose();
|
|
8781
8969
|
return;
|
|
8782
8970
|
}
|
|
8783
8971
|
await touchWorkspace2(ws.id);
|
|
8784
8972
|
if (!isCurrent()) {
|
|
8785
|
-
await
|
|
8973
|
+
await getFileSystemProviderV211(restored)?.dispose();
|
|
8786
8974
|
return;
|
|
8787
8975
|
}
|
|
8788
8976
|
fsProvider = restored;
|
|
@@ -8791,12 +8979,12 @@ function DocBlocksShell({
|
|
|
8791
8979
|
} else {
|
|
8792
8980
|
const p = await createIndexedDbFileSystemProvider(ws.id, ws.name);
|
|
8793
8981
|
if (!isCurrent()) {
|
|
8794
|
-
await
|
|
8982
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8795
8983
|
return;
|
|
8796
8984
|
}
|
|
8797
8985
|
await touchWorkspace2(ws.id);
|
|
8798
8986
|
if (!isCurrent()) {
|
|
8799
|
-
await
|
|
8987
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8800
8988
|
return;
|
|
8801
8989
|
}
|
|
8802
8990
|
fsProvider = p;
|
|
@@ -8814,11 +9002,11 @@ function DocBlocksShell({
|
|
|
8814
9002
|
rootPath: info.rootPath,
|
|
8815
9003
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
8816
9004
|
};
|
|
8817
|
-
await
|
|
9005
|
+
await saveWorkspace3(descriptor);
|
|
8818
9006
|
if (!isCurrent()) return;
|
|
8819
9007
|
const p = await createHostFileSystemProvider(info.id, info.name, info.rootPath);
|
|
8820
9008
|
if (!isCurrent()) {
|
|
8821
|
-
await
|
|
9009
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8822
9010
|
return;
|
|
8823
9011
|
}
|
|
8824
9012
|
fsProvider = p;
|
|
@@ -8827,7 +9015,7 @@ function DocBlocksShell({
|
|
|
8827
9015
|
if (!isCurrent()) return;
|
|
8828
9016
|
const p = await createIndexedDbFileSystemProvider(defaultWs.id, defaultWs.name);
|
|
8829
9017
|
if (!isCurrent()) {
|
|
8830
|
-
await
|
|
9018
|
+
await getFileSystemProviderV211(p)?.dispose();
|
|
8831
9019
|
return;
|
|
8832
9020
|
}
|
|
8833
9021
|
fsProvider = p;
|
|
@@ -8848,7 +9036,7 @@ function DocBlocksShell({
|
|
|
8848
9036
|
setActiveWorkspaceId(fsProvider.id);
|
|
8849
9037
|
adopted = true;
|
|
8850
9038
|
} finally {
|
|
8851
|
-
if (!adopted) await
|
|
9039
|
+
if (!adopted) await getFileSystemProviderV211(fsProvider)?.dispose();
|
|
8852
9040
|
}
|
|
8853
9041
|
})().catch(() => {
|
|
8854
9042
|
if (isCurrent()) {
|
|
@@ -9101,7 +9289,7 @@ function DocBlocksShell({
|
|
|
9101
9289
|
}, [selectedFile, selectedManagedOutput, workspaceOutputsResult]);
|
|
9102
9290
|
useEffect29(() => {
|
|
9103
9291
|
if (!provider) return;
|
|
9104
|
-
const providerV2 =
|
|
9292
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
9105
9293
|
const lifecycle = maybeGetDocBlocksHost4()?.lifecycle;
|
|
9106
9294
|
if (!providerV2 || !providerV2.capabilities.watch && !lifecycle?.onResume && !managedOutputRefreshToken)
|
|
9107
9295
|
return;
|
|
@@ -9499,7 +9687,7 @@ function DocBlocksShell({
|
|
|
9499
9687
|
} finally {
|
|
9500
9688
|
if (nextProvider && ownsNextProvider && !adoptedNextProvider) {
|
|
9501
9689
|
try {
|
|
9502
|
-
await
|
|
9690
|
+
await getFileSystemProviderV211(nextProvider)?.dispose();
|
|
9503
9691
|
} catch {
|
|
9504
9692
|
}
|
|
9505
9693
|
}
|
|
@@ -9605,14 +9793,14 @@ function DocBlocksShell({
|
|
|
9605
9793
|
}
|
|
9606
9794
|
}
|
|
9607
9795
|
try {
|
|
9608
|
-
await
|
|
9796
|
+
await removeWorkspace2(activeWorkspaceId);
|
|
9609
9797
|
} catch {
|
|
9610
9798
|
}
|
|
9611
9799
|
setDescriptorRefreshKey((key) => key + 1);
|
|
9612
9800
|
} catch (error) {
|
|
9613
9801
|
if (destinationProvider && !adoptedDestination) {
|
|
9614
9802
|
try {
|
|
9615
|
-
await
|
|
9803
|
+
await getFileSystemProviderV211(destinationProvider)?.dispose();
|
|
9616
9804
|
} catch {
|
|
9617
9805
|
}
|
|
9618
9806
|
}
|
|
@@ -9647,7 +9835,7 @@ function DocBlocksShell({
|
|
|
9647
9835
|
rootPath: info.rootPath,
|
|
9648
9836
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
9649
9837
|
};
|
|
9650
|
-
await
|
|
9838
|
+
await saveWorkspace3(descriptor2);
|
|
9651
9839
|
if (requestId !== navigationRequestRef.current) return;
|
|
9652
9840
|
const provider2 = await createHostFileSystemProvider(info.id, info.name, info.rootPath);
|
|
9653
9841
|
if (!await transitionAwayFromDocument(requestId)) return;
|
|
@@ -9667,7 +9855,7 @@ function DocBlocksShell({
|
|
|
9667
9855
|
type: "native",
|
|
9668
9856
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
9669
9857
|
};
|
|
9670
|
-
await
|
|
9858
|
+
await saveWorkspace3(descriptor);
|
|
9671
9859
|
if (requestId !== navigationRequestRef.current) return;
|
|
9672
9860
|
if (!await transitionAwayFromDocument(requestId)) return;
|
|
9673
9861
|
setProvider(nativeProvider);
|
|
@@ -9690,7 +9878,7 @@ function DocBlocksShell({
|
|
|
9690
9878
|
rootPath: info.rootPath,
|
|
9691
9879
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
9692
9880
|
};
|
|
9693
|
-
await
|
|
9881
|
+
await saveWorkspace3(descriptor);
|
|
9694
9882
|
if (requestId !== navigationRequestRef.current) return;
|
|
9695
9883
|
const cloneProvider = await createHostFileSystemProvider(info.id, info.name, info.rootPath);
|
|
9696
9884
|
if (!await transitionAwayFromDocument(requestId)) return;
|
|
@@ -9718,12 +9906,12 @@ function DocBlocksShell({
|
|
|
9718
9906
|
if (requestId !== navigationRequestRef.current) return null;
|
|
9719
9907
|
if (format === "markdown") {
|
|
9720
9908
|
const content = "# " + filename.replace(/\.[^.]+$/, "") + "\n";
|
|
9721
|
-
const providerV2 =
|
|
9909
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
9722
9910
|
if (providerV2) {
|
|
9723
9911
|
try {
|
|
9724
9912
|
await writeProviderText(provider, path, content, "create");
|
|
9725
9913
|
} catch (error) {
|
|
9726
|
-
if (error instanceof
|
|
9914
|
+
if (error instanceof FsError6 && error.code === "already-exists") {
|
|
9727
9915
|
throw new Error("A document with that name already exists.");
|
|
9728
9916
|
}
|
|
9729
9917
|
throw error;
|
|
@@ -9822,7 +10010,7 @@ function DocBlocksShell({
|
|
|
9822
10010
|
}
|
|
9823
10011
|
const path = `/${folderName}`;
|
|
9824
10012
|
try {
|
|
9825
|
-
const providerV2 =
|
|
10013
|
+
const providerV2 = getFileSystemProviderV211(provider);
|
|
9826
10014
|
if (providerV2) {
|
|
9827
10015
|
await providerV2.createDirectory(parseWorkspacePath8(path), { mode: "create" });
|
|
9828
10016
|
} else {
|
|
@@ -9832,7 +10020,7 @@ function DocBlocksShell({
|
|
|
9832
10020
|
await provider.createDirectory(path);
|
|
9833
10021
|
}
|
|
9834
10022
|
} catch (error) {
|
|
9835
|
-
const message = error instanceof
|
|
10023
|
+
const message = error instanceof FsError6 && error.code === "already-exists" ? "A file or folder with that name already exists." : error instanceof Error ? error.message : "Could not create the folder.";
|
|
9836
10024
|
showToast("error", message);
|
|
9837
10025
|
return;
|
|
9838
10026
|
}
|
|
@@ -10058,7 +10246,7 @@ function DocBlocksShell({
|
|
|
10058
10246
|
});
|
|
10059
10247
|
}, [handleNewFile, handleOpenFolder, handleRevealWorkspace, acknowledge, openFind]);
|
|
10060
10248
|
const handleSelect = useCallback18(
|
|
10061
|
-
async (path, kind) => {
|
|
10249
|
+
async (path, kind, createWikiArticle = false) => {
|
|
10062
10250
|
if (!provider || !activeWorkspaceId) return;
|
|
10063
10251
|
const requestId = ++navigationRequestRef.current;
|
|
10064
10252
|
if (kind === "directory") {
|
|
@@ -10075,6 +10263,17 @@ function DocBlocksShell({
|
|
|
10075
10263
|
try {
|
|
10076
10264
|
const transitioned = await documentSession.transitionWithLoad(async () => {
|
|
10077
10265
|
if (requestId !== navigationRequestRef.current) return null;
|
|
10266
|
+
if (createWikiArticle) {
|
|
10267
|
+
if (await ensureShellWikiArticle(
|
|
10268
|
+
provider,
|
|
10269
|
+
parseWorkspacePath8(path),
|
|
10270
|
+
defaultNewFileFormat,
|
|
10271
|
+
outsideInRenderRef.current
|
|
10272
|
+
)) {
|
|
10273
|
+
notifyWorkspaceChanged(activeWorkspaceId, path);
|
|
10274
|
+
}
|
|
10275
|
+
if (requestId !== navigationRequestRef.current) return null;
|
|
10276
|
+
}
|
|
10078
10277
|
openedDocument = await loadEditableShellDocument(
|
|
10079
10278
|
provider,
|
|
10080
10279
|
path,
|
|
@@ -10126,9 +10325,72 @@ function DocBlocksShell({
|
|
|
10126
10325
|
documentSession,
|
|
10127
10326
|
notifyWorkspaceChanged,
|
|
10128
10327
|
transitionAwayFromDocument,
|
|
10129
|
-
showToast
|
|
10328
|
+
showToast,
|
|
10329
|
+
defaultNewFileFormat
|
|
10130
10330
|
]
|
|
10131
10331
|
);
|
|
10332
|
+
const wikiNavigationRef = useRef19(handleSelect);
|
|
10333
|
+
wikiNavigationRef.current = handleSelect;
|
|
10334
|
+
const wikiLinks = useMemo6(() => {
|
|
10335
|
+
if (!provider || !selectedFile || !activeWorkspaceId) return null;
|
|
10336
|
+
const source = selectedFile;
|
|
10337
|
+
const extension = wikiArticleExtension(defaultNewFileFormat);
|
|
10338
|
+
const lookups = /* @__PURE__ */ new Map();
|
|
10339
|
+
let queue = Promise.resolve();
|
|
10340
|
+
const lookup = (target) => {
|
|
10341
|
+
let result = lookups.get(target);
|
|
10342
|
+
if (!result) {
|
|
10343
|
+
result = queue.then(() => findWikiArticle2(provider, source, target, extension));
|
|
10344
|
+
queue = result.then(
|
|
10345
|
+
() => void 0,
|
|
10346
|
+
() => void 0
|
|
10347
|
+
);
|
|
10348
|
+
lookups.set(target, result);
|
|
10349
|
+
}
|
|
10350
|
+
return result;
|
|
10351
|
+
};
|
|
10352
|
+
return {
|
|
10353
|
+
async suggest(query) {
|
|
10354
|
+
const index = workspaceIndex.index;
|
|
10355
|
+
if (!index) return [];
|
|
10356
|
+
workspaceIndex.ensure();
|
|
10357
|
+
await index.whenListed({ timeoutMs: 5e3 });
|
|
10358
|
+
return suggestWikiArticles(
|
|
10359
|
+
index.getFiles(),
|
|
10360
|
+
index.getDirectories(),
|
|
10361
|
+
source,
|
|
10362
|
+
query,
|
|
10363
|
+
extension
|
|
10364
|
+
);
|
|
10365
|
+
},
|
|
10366
|
+
async exists(target) {
|
|
10367
|
+
return (await lookup(target)).exists;
|
|
10368
|
+
},
|
|
10369
|
+
async resolve(target) {
|
|
10370
|
+
const article = await lookup(target);
|
|
10371
|
+
if (!article.exists) return null;
|
|
10372
|
+
const href = selectedSourceFile !== selectedFile ? `/${article.path}` : article.relativePath;
|
|
10373
|
+
return href.split("/").map(encodeURIComponent).join("/");
|
|
10374
|
+
},
|
|
10375
|
+
async open(target, { create }) {
|
|
10376
|
+
const requestId = navigationRequestRef.current;
|
|
10377
|
+
const navigate = wikiNavigationRef.current;
|
|
10378
|
+
const { path } = await lookup(target);
|
|
10379
|
+
if (requestId !== navigationRequestRef.current || navigate !== wikiNavigationRef.current)
|
|
10380
|
+
return;
|
|
10381
|
+
await navigate(path, "file", create);
|
|
10382
|
+
}
|
|
10383
|
+
};
|
|
10384
|
+
}, [
|
|
10385
|
+
provider,
|
|
10386
|
+
selectedFile,
|
|
10387
|
+
selectedSourceFile,
|
|
10388
|
+
activeWorkspaceId,
|
|
10389
|
+
defaultNewFileFormat,
|
|
10390
|
+
workspaceIndex.index,
|
|
10391
|
+
workspaceIndex.ensure,
|
|
10392
|
+
workspaceIndex.status.generation
|
|
10393
|
+
]);
|
|
10132
10394
|
const handleEnableOutsideInEditing = useCallback18(
|
|
10133
10395
|
async (path) => {
|
|
10134
10396
|
if (!provider || !activeWorkspaceId) {
|
|
@@ -10256,7 +10518,7 @@ function DocBlocksShell({
|
|
|
10256
10518
|
if (!target) {
|
|
10257
10519
|
showToast(
|
|
10258
10520
|
"error",
|
|
10259
|
-
"DocBlocks only opens HTTP(S) links or Markdown files inside this workspace."
|
|
10521
|
+
"DocBlocks only opens HTTP(S) links or Markdown and HTML files inside this workspace."
|
|
10260
10522
|
);
|
|
10261
10523
|
return true;
|
|
10262
10524
|
}
|
|
@@ -10274,14 +10536,14 @@ function DocBlocksShell({
|
|
|
10274
10536
|
if (!provider) return;
|
|
10275
10537
|
try {
|
|
10276
10538
|
if (!await providerEntryExists(provider, target.path)) {
|
|
10277
|
-
showToast("error", "The linked
|
|
10539
|
+
showToast("error", "The linked document was not found in this workspace.");
|
|
10278
10540
|
return;
|
|
10279
10541
|
}
|
|
10280
10542
|
await handleSelect(target.path, "file");
|
|
10281
10543
|
} catch (error) {
|
|
10282
10544
|
showToast(
|
|
10283
10545
|
"error",
|
|
10284
|
-
error instanceof Error ? error.message : "Could not open the linked
|
|
10546
|
+
error instanceof Error ? error.message : "Could not open the linked document."
|
|
10285
10547
|
);
|
|
10286
10548
|
}
|
|
10287
10549
|
})();
|
|
@@ -10555,7 +10817,7 @@ function DocBlocksShell({
|
|
|
10555
10817
|
} finally {
|
|
10556
10818
|
if (access.owned) {
|
|
10557
10819
|
try {
|
|
10558
|
-
await
|
|
10820
|
+
await getFileSystemProviderV211(access.provider)?.dispose();
|
|
10559
10821
|
} catch {
|
|
10560
10822
|
}
|
|
10561
10823
|
}
|
|
@@ -10624,7 +10886,7 @@ function DocBlocksShell({
|
|
|
10624
10886
|
} finally {
|
|
10625
10887
|
if (access.owned) {
|
|
10626
10888
|
try {
|
|
10627
|
-
await
|
|
10889
|
+
await getFileSystemProviderV211(access.provider)?.dispose();
|
|
10628
10890
|
} catch {
|
|
10629
10891
|
}
|
|
10630
10892
|
}
|
|
@@ -10642,32 +10904,73 @@ function DocBlocksShell({
|
|
|
10642
10904
|
showToast
|
|
10643
10905
|
]
|
|
10644
10906
|
);
|
|
10907
|
+
const restoreInputRef = useRef19(null);
|
|
10908
|
+
const restoreInProgress = useRef19(false);
|
|
10909
|
+
const handleRestoreBackup = useCallback18(
|
|
10910
|
+
async (file) => {
|
|
10911
|
+
if (restoreInProgress.current) {
|
|
10912
|
+
showToast("error", "A backup is already being restored. Please wait.");
|
|
10913
|
+
return;
|
|
10914
|
+
}
|
|
10915
|
+
restoreInProgress.current = true;
|
|
10916
|
+
try {
|
|
10917
|
+
await documentSession.flush("backup");
|
|
10918
|
+
const restored = await restoreBrowserBackup(file);
|
|
10919
|
+
setDescriptorRefreshKey((key) => key + 1);
|
|
10920
|
+
if (restored[0]) await handleWorkspaceSelect(restored[0]);
|
|
10921
|
+
showToast(
|
|
10922
|
+
"success",
|
|
10923
|
+
`Restored ${restored.length} workspace(s) as new copies. Your existing workspaces are unchanged.`
|
|
10924
|
+
);
|
|
10925
|
+
} catch (error) {
|
|
10926
|
+
showToast(
|
|
10927
|
+
"error",
|
|
10928
|
+
`Could not restore ${file.name}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
10929
|
+
);
|
|
10930
|
+
} finally {
|
|
10931
|
+
restoreInProgress.current = false;
|
|
10932
|
+
}
|
|
10933
|
+
},
|
|
10934
|
+
[documentSession, handleWorkspaceSelect, showToast]
|
|
10935
|
+
);
|
|
10936
|
+
const importOrRestore = useCallback18(
|
|
10937
|
+
async (files) => {
|
|
10938
|
+
const backups = hostSupports2("nativeWorkspaces") ? [] : files.filter((file) => /\.zip$/i.test(file.name));
|
|
10939
|
+
const documents = files.filter((file) => !backups.includes(file));
|
|
10940
|
+
const result = provider ? await importDroppedFiles(documents, provider) : null;
|
|
10941
|
+
for (const file of backups) await handleRestoreBackup(file);
|
|
10942
|
+
return result;
|
|
10943
|
+
},
|
|
10944
|
+
[handleRestoreBackup, provider]
|
|
10945
|
+
);
|
|
10645
10946
|
const handleImportFiles = useCallback18(
|
|
10646
10947
|
async (files) => {
|
|
10647
10948
|
if (!provider) return;
|
|
10648
|
-
const result = await
|
|
10949
|
+
const result = await importOrRestore(files);
|
|
10950
|
+
if (!result) return;
|
|
10649
10951
|
notifyWorkspaceChanged(activeWorkspaceId);
|
|
10650
10952
|
setExplorerKey((k) => k + 1);
|
|
10651
10953
|
const summary = summariseImport(result);
|
|
10652
10954
|
if (summary) showToast(summary.kind, summary.message);
|
|
10653
10955
|
},
|
|
10654
|
-
[activeWorkspaceId, notifyWorkspaceChanged, provider, showToast]
|
|
10956
|
+
[activeWorkspaceId, notifyWorkspaceChanged, provider, showToast, importOrRestore]
|
|
10655
10957
|
);
|
|
10656
10958
|
const handleImportFilesToEditor = useCallback18(
|
|
10657
10959
|
async (files) => {
|
|
10658
10960
|
if (!provider) return;
|
|
10659
|
-
const result = await
|
|
10961
|
+
const result = await importOrRestore(files);
|
|
10962
|
+
if (!result) return;
|
|
10660
10963
|
notifyWorkspaceChanged(activeWorkspaceId);
|
|
10661
10964
|
setExplorerKey((k) => k + 1);
|
|
10662
10965
|
const summary = summariseImport(result);
|
|
10663
10966
|
if (summary) showToast(summary.kind, summary.message);
|
|
10664
10967
|
const imported = result.imported;
|
|
10665
|
-
if (imported.length === 1 && result.failed.length === 0) {
|
|
10968
|
+
if (imported.length === 1 && result.failed.length === 0 && !files.some((file) => /\.zip$/i.test(file.name))) {
|
|
10666
10969
|
const only = imported[0];
|
|
10667
10970
|
if (only) void handleSelect(only.path, "file");
|
|
10668
10971
|
}
|
|
10669
10972
|
},
|
|
10670
|
-
[activeWorkspaceId, notifyWorkspaceChanged, provider, showToast, handleSelect]
|
|
10973
|
+
[activeWorkspaceId, notifyWorkspaceChanged, provider, showToast, handleSelect, importOrRestore]
|
|
10671
10974
|
);
|
|
10672
10975
|
const editorDropActive = useEditorFileDrop(
|
|
10673
10976
|
editorAreaRef,
|
|
@@ -10695,7 +10998,7 @@ function DocBlocksShell({
|
|
|
10695
10998
|
confirmLabel: "Rename"
|
|
10696
10999
|
});
|
|
10697
11000
|
if (!newName || newName === ws.name) return;
|
|
10698
|
-
await
|
|
11001
|
+
await saveWorkspace3({ ...ws, name: newName });
|
|
10699
11002
|
setPinnedDocuments(
|
|
10700
11003
|
(current) => renamePinnedDocumentWorkspace(current, activeWorkspaceId, newName)
|
|
10701
11004
|
);
|
|
@@ -10721,7 +11024,7 @@ function DocBlocksShell({
|
|
|
10721
11024
|
throw error;
|
|
10722
11025
|
}
|
|
10723
11026
|
if (!isCurrent()) {
|
|
10724
|
-
await
|
|
11027
|
+
await getFileSystemProviderV211(mem)?.dispose();
|
|
10725
11028
|
await revokeAbandonedResource();
|
|
10726
11029
|
return;
|
|
10727
11030
|
}
|
|
@@ -10769,7 +11072,7 @@ function DocBlocksShell({
|
|
|
10769
11072
|
} finally {
|
|
10770
11073
|
try {
|
|
10771
11074
|
if (!adoptionStarted) {
|
|
10772
|
-
await
|
|
11075
|
+
await getFileSystemProviderV211(mem)?.dispose();
|
|
10773
11076
|
}
|
|
10774
11077
|
} finally {
|
|
10775
11078
|
if (!opened) await revokeAbandonedResource();
|
|
@@ -10840,7 +11143,7 @@ function DocBlocksShell({
|
|
|
10840
11143
|
push: true
|
|
10841
11144
|
});
|
|
10842
11145
|
} finally {
|
|
10843
|
-
if (!adoptionStarted) await
|
|
11146
|
+
if (!adoptionStarted) await getFileSystemProviderV211(mem)?.dispose();
|
|
10844
11147
|
}
|
|
10845
11148
|
},
|
|
10846
11149
|
[adoptTransientWorkspace]
|
|
@@ -10870,8 +11173,11 @@ function DocBlocksShell({
|
|
|
10870
11173
|
import("@bendyline/squisq-formats/container")
|
|
10871
11174
|
]);
|
|
10872
11175
|
const container = new MemoryContentContainer();
|
|
10873
|
-
|
|
10874
|
-
|
|
11176
|
+
const source = getFileSystemProviderV211(provider);
|
|
11177
|
+
if (!source) throw new Error("This workspace does not support complete backups.");
|
|
11178
|
+
const workspaces = await appendWorkspaceBackup(container, source, []);
|
|
11179
|
+
await finishWorkspaceBackup(container, workspaces);
|
|
11180
|
+
const blob = await containerToZip(container, { compression: "STORE" });
|
|
10875
11181
|
const url = URL.createObjectURL(blob);
|
|
10876
11182
|
const a = document.createElement("a");
|
|
10877
11183
|
a.href = url;
|
|
@@ -10880,8 +11186,7 @@ function DocBlocksShell({
|
|
|
10880
11186
|
a.click();
|
|
10881
11187
|
URL.revokeObjectURL(url);
|
|
10882
11188
|
} catch (err) {
|
|
10883
|
-
|
|
10884
|
-
showToast("error", "Failed to download workspace. See console for details.");
|
|
11189
|
+
showToast("error", err instanceof Error ? err.message : "Failed to download workspace.");
|
|
10885
11190
|
}
|
|
10886
11191
|
}, [provider, documentSession, showToast]);
|
|
10887
11192
|
const handleDownloadAllWorkspaces = useCallback18(async () => {
|
|
@@ -10901,7 +11206,7 @@ function DocBlocksShell({
|
|
|
10901
11206
|
return;
|
|
10902
11207
|
}
|
|
10903
11208
|
const container = new MemoryContentContainer();
|
|
10904
|
-
|
|
11209
|
+
let backupWorkspaces = [];
|
|
10905
11210
|
const skipped = [];
|
|
10906
11211
|
for (const ws of candidates) {
|
|
10907
11212
|
let p = null;
|
|
@@ -10927,24 +11232,20 @@ function DocBlocksShell({
|
|
|
10927
11232
|
skipped.push(ws.name);
|
|
10928
11233
|
continue;
|
|
10929
11234
|
}
|
|
10930
|
-
const base = (ws.name || "workspace").replace(/[^a-z0-9_\- ]/gi, "_").trim() || "workspace";
|
|
10931
|
-
let folder = base;
|
|
10932
|
-
let suffix = 2;
|
|
10933
|
-
while (usedFolders.has(folder)) {
|
|
10934
|
-
folder = `${base} (${suffix++})`;
|
|
10935
|
-
}
|
|
10936
|
-
usedFolders.add(folder);
|
|
10937
11235
|
try {
|
|
10938
|
-
|
|
11236
|
+
const source = getFileSystemProviderV211(p);
|
|
11237
|
+
if (!source) throw new Error("This workspace does not support complete backups.");
|
|
11238
|
+
backupWorkspaces = await appendWorkspaceBackup(container, source, backupWorkspaces);
|
|
10939
11239
|
} finally {
|
|
10940
|
-
if (ownsProvider) await
|
|
11240
|
+
if (ownsProvider) await getFileSystemProviderV211(p)?.dispose();
|
|
10941
11241
|
}
|
|
10942
11242
|
}
|
|
10943
|
-
if (
|
|
11243
|
+
if (backupWorkspaces.length === 0) {
|
|
10944
11244
|
showToast("error", "No workspaces could be opened for download.");
|
|
10945
11245
|
return;
|
|
10946
11246
|
}
|
|
10947
|
-
|
|
11247
|
+
await finishWorkspaceBackup(container, backupWorkspaces);
|
|
11248
|
+
const blob = await containerToZip(container, { compression: "STORE" });
|
|
10948
11249
|
const url = URL.createObjectURL(blob);
|
|
10949
11250
|
const a = document.createElement("a");
|
|
10950
11251
|
a.href = url;
|
|
@@ -10954,12 +11255,11 @@ function DocBlocksShell({
|
|
|
10954
11255
|
if (skipped.length > 0) {
|
|
10955
11256
|
await acknowledge({
|
|
10956
11257
|
title: "Some workspaces were skipped",
|
|
10957
|
-
message: `Downloaded ${
|
|
11258
|
+
message: `Downloaded ${backupWorkspaces.length} workspace(s). Skipped ${skipped.length} that require re-granting access: ${skipped.join(", ")}.`
|
|
10958
11259
|
});
|
|
10959
11260
|
}
|
|
10960
11261
|
} catch (err) {
|
|
10961
|
-
|
|
10962
|
-
showToast("error", "Failed to download all workspaces. See console for details.");
|
|
11262
|
+
showToast("error", err instanceof Error ? err.message : "Failed to download all workspaces.");
|
|
10963
11263
|
}
|
|
10964
11264
|
}, [documentSession, acknowledge, showToast]);
|
|
10965
11265
|
const handleKeepBrowserData = useCallback18(async () => {
|
|
@@ -11050,7 +11350,7 @@ function DocBlocksShell({
|
|
|
11050
11350
|
} else if (ws?.type === "indexeddb") {
|
|
11051
11351
|
await (await loadIndexedDbFileSystem()).deleteIndexedDBWorkspaceData(workspaceId);
|
|
11052
11352
|
}
|
|
11053
|
-
await
|
|
11353
|
+
await removeWorkspace2(workspaceId);
|
|
11054
11354
|
forgetRecentDocuments(workspaceId);
|
|
11055
11355
|
for (const document2 of pinnedDocuments) {
|
|
11056
11356
|
if (document2.workspaceId === workspaceId) {
|
|
@@ -11078,7 +11378,7 @@ function DocBlocksShell({
|
|
|
11078
11378
|
rootPath: info.rootPath,
|
|
11079
11379
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
11080
11380
|
};
|
|
11081
|
-
await
|
|
11381
|
+
await saveWorkspace3(descriptor);
|
|
11082
11382
|
const p = await createHostFileSystemProvider(info.id, info.name, info.rootPath);
|
|
11083
11383
|
setProvider(p);
|
|
11084
11384
|
setActiveWorkspaceId(info.id);
|
|
@@ -11219,6 +11519,7 @@ function DocBlocksShell({
|
|
|
11219
11519
|
onVersioningPreferenceChange: handleVersioningPreferenceChange,
|
|
11220
11520
|
onOpenWorkspaceSettings: activeWorkspaceDescriptor ? handleOpenWorkspaceSettings : void 0,
|
|
11221
11521
|
onDownloadAllWorkspaces: handleDownloadAllWorkspaces,
|
|
11522
|
+
onRestoreBackup: hostSupports2("nativeWorkspaces") ? void 0 : () => restoreInputRef.current?.click(),
|
|
11222
11523
|
onShowKeyboardShortcuts: singlePane ? void 0 : openKeyboardShortcuts,
|
|
11223
11524
|
onKeepBrowserData: showBrowserStorageWarning && !browserStoragePersistent ? handleKeepBrowserData : void 0,
|
|
11224
11525
|
onInstallApp: installPromptEvent ? handleInstallApp : void 0,
|
|
@@ -11231,6 +11532,21 @@ function DocBlocksShell({
|
|
|
11231
11532
|
settingsRequest
|
|
11232
11533
|
}
|
|
11233
11534
|
),
|
|
11535
|
+
/* @__PURE__ */ jsx18(
|
|
11536
|
+
"input",
|
|
11537
|
+
{
|
|
11538
|
+
ref: restoreInputRef,
|
|
11539
|
+
type: "file",
|
|
11540
|
+
accept: ".zip,application/zip",
|
|
11541
|
+
"aria-label": "Restore workspace backup",
|
|
11542
|
+
hidden: true,
|
|
11543
|
+
onChange: (event) => {
|
|
11544
|
+
const file = event.currentTarget.files?.[0];
|
|
11545
|
+
event.currentTarget.value = "";
|
|
11546
|
+
if (file) void handleRestoreBackup(file);
|
|
11547
|
+
}
|
|
11548
|
+
}
|
|
11549
|
+
),
|
|
11234
11550
|
/* @__PURE__ */ jsx18(
|
|
11235
11551
|
WorkspacePicker,
|
|
11236
11552
|
{
|
|
@@ -11437,6 +11753,7 @@ function DocBlocksShell({
|
|
|
11437
11753
|
saveDashboardImageOutput: saveRenderedImageOutput,
|
|
11438
11754
|
onChange: handleEditorChange,
|
|
11439
11755
|
onLinkClick: handleEditorLinkClick,
|
|
11756
|
+
wikiLinks,
|
|
11440
11757
|
colorScheme: resolvedTheme,
|
|
11441
11758
|
defaultThemeId: workspaceDefaultThemeId,
|
|
11442
11759
|
defaultThemeLabel: "Workspace default",
|