@lvce-editor/file-system-worker 5.20.3 → 5.21.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/fileSystemWorkerMain.js +621 -118
- package/package.json +1 -1
|
@@ -64,10 +64,10 @@ const Object$1 = 1;
|
|
|
64
64
|
const Number$1 = 2;
|
|
65
65
|
const Array$1 = 3;
|
|
66
66
|
const String$1 = 4;
|
|
67
|
-
const Boolean = 5;
|
|
67
|
+
const Boolean$1 = 5;
|
|
68
68
|
const Function = 6;
|
|
69
69
|
const Null = 7;
|
|
70
|
-
const Unknown = 8;
|
|
70
|
+
const Unknown$1 = 8;
|
|
71
71
|
const getType = value => {
|
|
72
72
|
switch (typeof value) {
|
|
73
73
|
case 'number':
|
|
@@ -85,9 +85,9 @@ const getType = value => {
|
|
|
85
85
|
}
|
|
86
86
|
return Object$1;
|
|
87
87
|
case 'boolean':
|
|
88
|
-
return Boolean;
|
|
88
|
+
return Boolean$1;
|
|
89
89
|
default:
|
|
90
|
-
return Unknown;
|
|
90
|
+
return Unknown$1;
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
const object = value => {
|
|
@@ -601,7 +601,7 @@ const callbacks = Object.create(null);
|
|
|
601
601
|
const get$1 = id => {
|
|
602
602
|
return callbacks[id];
|
|
603
603
|
};
|
|
604
|
-
const remove$
|
|
604
|
+
const remove$7 = id => {
|
|
605
605
|
delete callbacks[id];
|
|
606
606
|
};
|
|
607
607
|
class JsonRpcError extends Error {
|
|
@@ -826,7 +826,7 @@ const resolve = (id, response) => {
|
|
|
826
826
|
return;
|
|
827
827
|
}
|
|
828
828
|
fn(response);
|
|
829
|
-
remove$
|
|
829
|
+
remove$7(id);
|
|
830
830
|
};
|
|
831
831
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
832
832
|
const getErrorType = prettyError => {
|
|
@@ -1316,7 +1316,7 @@ const set$5 = (id, rpc) => {
|
|
|
1316
1316
|
const get = id => {
|
|
1317
1317
|
return rpcs[id];
|
|
1318
1318
|
};
|
|
1319
|
-
const remove$
|
|
1319
|
+
const remove$6 = id => {
|
|
1320
1320
|
delete rpcs[id];
|
|
1321
1321
|
};
|
|
1322
1322
|
|
|
@@ -1346,7 +1346,7 @@ const create = rpcId => {
|
|
|
1346
1346
|
set$5(rpcId, mockRpc);
|
|
1347
1347
|
// @ts-ignore
|
|
1348
1348
|
mockRpc[Symbol.dispose] = () => {
|
|
1349
|
-
remove$
|
|
1349
|
+
remove$6(rpcId);
|
|
1350
1350
|
};
|
|
1351
1351
|
// @ts-ignore
|
|
1352
1352
|
return mockRpc;
|
|
@@ -1359,6 +1359,7 @@ const create = rpcId => {
|
|
|
1359
1359
|
|
|
1360
1360
|
const Directory$1 = 3;
|
|
1361
1361
|
const File$3 = 7;
|
|
1362
|
+
const Unknown = 12;
|
|
1362
1363
|
|
|
1363
1364
|
const DebugWorker = 55;
|
|
1364
1365
|
const ExtensionHostWorker = 44;
|
|
@@ -1375,17 +1376,17 @@ const {
|
|
|
1375
1376
|
invoke: invoke$3,
|
|
1376
1377
|
set: set$3
|
|
1377
1378
|
} = create(FileSystemProcess$1);
|
|
1378
|
-
const remove$
|
|
1379
|
+
const remove$5 = async uri => {
|
|
1379
1380
|
return invoke$3('FileSystem.remove', uri);
|
|
1380
1381
|
};
|
|
1381
|
-
const readFile$
|
|
1382
|
+
const readFile$5 = async uri => {
|
|
1382
1383
|
return invoke$3('FileSystem.readFile', uri);
|
|
1383
1384
|
};
|
|
1384
1385
|
const appendFile$2 = async (uri, text) => {
|
|
1385
1386
|
// @ts-ignore
|
|
1386
1387
|
return invoke$3('FileSystem.appendFile', uri, text);
|
|
1387
1388
|
};
|
|
1388
|
-
const readDirWithFileTypes$
|
|
1389
|
+
const readDirWithFileTypes$5 = async uri => {
|
|
1389
1390
|
return invoke$3('FileSystem.readDirWithFileTypes', uri);
|
|
1390
1391
|
};
|
|
1391
1392
|
const readJson$4 = async root => {
|
|
@@ -1400,11 +1401,11 @@ const stat$4 = async path => {
|
|
|
1400
1401
|
// @ts-ignore
|
|
1401
1402
|
return invoke$3('FileSystem.stat', path);
|
|
1402
1403
|
};
|
|
1403
|
-
const writeFile$
|
|
1404
|
+
const writeFile$5 = async (path, content) => {
|
|
1404
1405
|
// @ts-ignore
|
|
1405
1406
|
return invoke$3('FileSystem.writeFile', path, content);
|
|
1406
1407
|
};
|
|
1407
|
-
const mkdir$
|
|
1408
|
+
const mkdir$5 = async path => {
|
|
1408
1409
|
// @ts-ignore
|
|
1409
1410
|
return invoke$3('FileSystem.mkdir', path);
|
|
1410
1411
|
};
|
|
@@ -1420,7 +1421,7 @@ const getFolderSize$4 = async uri => {
|
|
|
1420
1421
|
// @ts-ignore
|
|
1421
1422
|
return invoke$3('FileSystem.getFolderSize', uri);
|
|
1422
1423
|
};
|
|
1423
|
-
const exists$
|
|
1424
|
+
const exists$5 = async uri => {
|
|
1424
1425
|
// @ts-ignore
|
|
1425
1426
|
return invoke$3('FileSystem.exists', uri);
|
|
1426
1427
|
};
|
|
@@ -1429,19 +1430,19 @@ const FileSystemProcess = {
|
|
|
1429
1430
|
__proto__: null,
|
|
1430
1431
|
appendFile: appendFile$2,
|
|
1431
1432
|
copy: copy$4,
|
|
1432
|
-
exists: exists$
|
|
1433
|
+
exists: exists$5,
|
|
1433
1434
|
getFolderSize: getFolderSize$4,
|
|
1434
1435
|
getRealPath: getRealPath$4,
|
|
1435
1436
|
invoke: invoke$3,
|
|
1436
|
-
mkdir: mkdir$
|
|
1437
|
-
readDirWithFileTypes: readDirWithFileTypes$
|
|
1438
|
-
readFile: readFile$
|
|
1437
|
+
mkdir: mkdir$5,
|
|
1438
|
+
readDirWithFileTypes: readDirWithFileTypes$5,
|
|
1439
|
+
readFile: readFile$5,
|
|
1439
1440
|
readJson: readJson$4,
|
|
1440
|
-
remove: remove$
|
|
1441
|
+
remove: remove$5,
|
|
1441
1442
|
rename: rename$4,
|
|
1442
1443
|
set: set$3,
|
|
1443
1444
|
stat: stat$4,
|
|
1444
|
-
writeFile: writeFile$
|
|
1445
|
+
writeFile: writeFile$5
|
|
1445
1446
|
};
|
|
1446
1447
|
|
|
1447
1448
|
const createLazyRpc = rpcId => {
|
|
@@ -1481,7 +1482,7 @@ const createLazyRpc = rpcId => {
|
|
|
1481
1482
|
activeRpc = undefined;
|
|
1482
1483
|
rpcPromise = undefined;
|
|
1483
1484
|
if (rpc && get(rpcId) === rpc) {
|
|
1484
|
-
remove$
|
|
1485
|
+
remove$6(rpcId);
|
|
1485
1486
|
}
|
|
1486
1487
|
if (notify) {
|
|
1487
1488
|
for (const listener of resetListeners) {
|
|
@@ -1556,19 +1557,19 @@ const getFileHashes$1 = async uris => {
|
|
|
1556
1557
|
const {
|
|
1557
1558
|
appendFile: appendFile$1,
|
|
1558
1559
|
copy: copy$3,
|
|
1559
|
-
exists: exists$
|
|
1560
|
+
exists: exists$4,
|
|
1560
1561
|
getFolderSize: getFolderSize$3,
|
|
1561
1562
|
getRealPath: getRealPath$3,
|
|
1562
1563
|
invoke: invoke$1,
|
|
1563
|
-
mkdir: mkdir$
|
|
1564
|
-
readDirWithFileTypes: readDirWithFileTypes$
|
|
1565
|
-
readFile: readFile$
|
|
1564
|
+
mkdir: mkdir$4,
|
|
1565
|
+
readDirWithFileTypes: readDirWithFileTypes$4,
|
|
1566
|
+
readFile: readFile$4,
|
|
1566
1567
|
readJson: readJson$3,
|
|
1567
|
-
remove: remove$
|
|
1568
|
+
remove: remove$4,
|
|
1568
1569
|
rename: rename$3,
|
|
1569
1570
|
set,
|
|
1570
1571
|
stat: stat$3,
|
|
1571
|
-
writeFile: writeFile$
|
|
1572
|
+
writeFile: writeFile$4
|
|
1572
1573
|
} = FileSystemProcess;
|
|
1573
1574
|
|
|
1574
1575
|
const Http = 'http:';
|
|
@@ -1689,11 +1690,11 @@ const readFileAsBlob$2 = async uri => {
|
|
|
1689
1690
|
if (entry.type !== file) throw new Error(`File is a directory: ${uri}`);
|
|
1690
1691
|
return entry.content;
|
|
1691
1692
|
};
|
|
1692
|
-
const readFile$
|
|
1693
|
+
const readFile$3 = async uri => {
|
|
1693
1694
|
const blob = await readFileAsBlob$2(uri);
|
|
1694
1695
|
return blob.text();
|
|
1695
1696
|
};
|
|
1696
|
-
const writeFile$
|
|
1697
|
+
const writeFile$3 = async (uri, content) => {
|
|
1697
1698
|
const path = getPath(uri);
|
|
1698
1699
|
ensureParentDirs(path);
|
|
1699
1700
|
files.set(path, {
|
|
@@ -1704,9 +1705,9 @@ const writeFile$2 = async (uri, content) => {
|
|
|
1704
1705
|
});
|
|
1705
1706
|
await triggerMemfsFileWatcher(uri);
|
|
1706
1707
|
};
|
|
1707
|
-
const exists$
|
|
1708
|
-
const createFile$2 = async uri => writeFile$
|
|
1709
|
-
const mkdir$
|
|
1708
|
+
const exists$3 = async uri => !!getEntry(uri);
|
|
1709
|
+
const createFile$2 = async uri => writeFile$3(uri, '');
|
|
1710
|
+
const mkdir$3 = async uri => {
|
|
1710
1711
|
const path = getPath(uri);
|
|
1711
1712
|
ensureParentDirs(path);
|
|
1712
1713
|
files.set(path, {
|
|
@@ -1715,14 +1716,14 @@ const mkdir$2 = async uri => {
|
|
|
1715
1716
|
});
|
|
1716
1717
|
await triggerMemfsFileWatcher(uri);
|
|
1717
1718
|
};
|
|
1718
|
-
const remove$
|
|
1719
|
+
const remove$3 = async uri => {
|
|
1719
1720
|
const path = getPath(uri);
|
|
1720
1721
|
for (const key of files.keys()) {
|
|
1721
1722
|
if (key === path || key.startsWith(`${path}/`)) files.delete(key);
|
|
1722
1723
|
}
|
|
1723
1724
|
await triggerMemfsFileWatcher(uri);
|
|
1724
1725
|
};
|
|
1725
|
-
const readDirWithFileTypes$
|
|
1726
|
+
const readDirWithFileTypes$3 = async uri => {
|
|
1726
1727
|
const path = `${getPath(uri)}/`;
|
|
1727
1728
|
const entries = new Map();
|
|
1728
1729
|
for (const [key, value] of files) {
|
|
@@ -1756,7 +1757,7 @@ const rename$2 = async (oldUri, newUri) => {
|
|
|
1756
1757
|
await triggerMemfsFileWatcher(oldUri);
|
|
1757
1758
|
await triggerMemfsFileWatcher(newUri);
|
|
1758
1759
|
};
|
|
1759
|
-
const copy$2 = async (oldUri, newUri) => writeFile$
|
|
1760
|
+
const copy$2 = async (oldUri, newUri) => writeFile$3(newUri, await readFile$3(oldUri));
|
|
1760
1761
|
const stat$2 = async uri => {
|
|
1761
1762
|
const entry = getEntry(uri);
|
|
1762
1763
|
return entry ? {
|
|
@@ -1768,7 +1769,7 @@ const stat$2 = async uri => {
|
|
|
1768
1769
|
size: 0
|
|
1769
1770
|
};
|
|
1770
1771
|
};
|
|
1771
|
-
const readJson$2 = async uri => JSON.parse(await readFile$
|
|
1772
|
+
const readJson$2 = async uri => JSON.parse(await readFile$3(uri));
|
|
1772
1773
|
const getPathSeparator$1 = async _root => '/';
|
|
1773
1774
|
const getRealPath$2 = async uri => uri;
|
|
1774
1775
|
const getFolderSize$2 = async uri => {
|
|
@@ -1789,20 +1790,20 @@ const FileSystemMemory = {
|
|
|
1789
1790
|
__proto__: null,
|
|
1790
1791
|
copy: copy$2,
|
|
1791
1792
|
createFile: createFile$2,
|
|
1792
|
-
exists: exists$
|
|
1793
|
+
exists: exists$3,
|
|
1793
1794
|
getFiles,
|
|
1794
1795
|
getFolderSize: getFolderSize$2,
|
|
1795
1796
|
getPathSeparator: getPathSeparator$1,
|
|
1796
1797
|
getRealPath: getRealPath$2,
|
|
1797
|
-
mkdir: mkdir$
|
|
1798
|
-
readDirWithFileTypes: readDirWithFileTypes$
|
|
1799
|
-
readFile: readFile$
|
|
1798
|
+
mkdir: mkdir$3,
|
|
1799
|
+
readDirWithFileTypes: readDirWithFileTypes$3,
|
|
1800
|
+
readFile: readFile$3,
|
|
1800
1801
|
readFileAsBlob: readFileAsBlob$2,
|
|
1801
1802
|
readJson: readJson$2,
|
|
1802
|
-
remove: remove$
|
|
1803
|
+
remove: remove$3,
|
|
1803
1804
|
rename: rename$2,
|
|
1804
1805
|
stat: stat$2,
|
|
1805
|
-
writeFile: writeFile$
|
|
1806
|
+
writeFile: writeFile$3
|
|
1806
1807
|
};
|
|
1807
1808
|
|
|
1808
1809
|
const memoryRoot = id => `memfs:///applications/${encodeURIComponent(id)}`;
|
|
@@ -1826,7 +1827,7 @@ const execute = async (id, method, ...args) => {
|
|
|
1826
1827
|
// This callback handles only non-memory URIs, never file contents storage.
|
|
1827
1828
|
return invoke$2('Application.execute', id, `FileSystem.${method}`, ...args);
|
|
1828
1829
|
};
|
|
1829
|
-
const dispose = async id => remove$
|
|
1830
|
+
const dispose = async id => remove$3(memoryRoot(id));
|
|
1830
1831
|
|
|
1831
1832
|
const connect = async port => {
|
|
1832
1833
|
const {
|
|
@@ -1838,10 +1839,10 @@ const connect = async port => {
|
|
|
1838
1839
|
});
|
|
1839
1840
|
};
|
|
1840
1841
|
|
|
1841
|
-
const remove$
|
|
1842
|
+
const remove$2 = async dirent => {
|
|
1842
1843
|
throw new Error('not implemented');
|
|
1843
1844
|
};
|
|
1844
|
-
const readFile$
|
|
1845
|
+
const readFile$2 = async uri => {
|
|
1845
1846
|
const response = await fetch(uri);
|
|
1846
1847
|
if (!response.ok) {
|
|
1847
1848
|
throw new Error(response.statusText);
|
|
@@ -1857,11 +1858,11 @@ const readFileAsBlob$1 = async uri => {
|
|
|
1857
1858
|
const result = await response.blob();
|
|
1858
1859
|
return result;
|
|
1859
1860
|
};
|
|
1860
|
-
const exists$
|
|
1861
|
+
const exists$2 = async uri => {
|
|
1861
1862
|
const response = await fetch(uri);
|
|
1862
1863
|
return response.ok;
|
|
1863
1864
|
};
|
|
1864
|
-
const readDirWithFileTypes$
|
|
1865
|
+
const readDirWithFileTypes$2 = async uri => {
|
|
1865
1866
|
throw new Error('not implemented');
|
|
1866
1867
|
};
|
|
1867
1868
|
const readJson$1 = async uri => {
|
|
@@ -1881,10 +1882,10 @@ const stat$1 = async dirent => {
|
|
|
1881
1882
|
const createFile$1 = async uri => {
|
|
1882
1883
|
throw new Error('not implemented');
|
|
1883
1884
|
};
|
|
1884
|
-
const writeFile$
|
|
1885
|
+
const writeFile$2 = async (uri, content) => {
|
|
1885
1886
|
throw new Error('not implemented');
|
|
1886
1887
|
};
|
|
1887
|
-
const mkdir$
|
|
1888
|
+
const mkdir$2 = async uri => {
|
|
1888
1889
|
throw new Error('not implemented');
|
|
1889
1890
|
};
|
|
1890
1891
|
const rename$1 = async (oldUri, newUri) => {
|
|
@@ -1901,18 +1902,464 @@ const FileSystemFetch = {
|
|
|
1901
1902
|
__proto__: null,
|
|
1902
1903
|
copy: copy$1,
|
|
1903
1904
|
createFile: createFile$1,
|
|
1904
|
-
exists: exists$
|
|
1905
|
+
exists: exists$2,
|
|
1905
1906
|
getFolderSize: getFolderSize$1,
|
|
1906
1907
|
getRealPath: getRealPath$1,
|
|
1907
|
-
mkdir: mkdir$
|
|
1908
|
-
readDirWithFileTypes: readDirWithFileTypes$
|
|
1909
|
-
readFile: readFile$
|
|
1908
|
+
mkdir: mkdir$2,
|
|
1909
|
+
readDirWithFileTypes: readDirWithFileTypes$2,
|
|
1910
|
+
readFile: readFile$2,
|
|
1910
1911
|
readFileAsBlob: readFileAsBlob$1,
|
|
1911
1912
|
readJson: readJson$1,
|
|
1912
|
-
remove: remove$
|
|
1913
|
+
remove: remove$2,
|
|
1913
1914
|
rename: rename$1,
|
|
1914
1915
|
stat: stat$1,
|
|
1915
|
-
writeFile: writeFile$
|
|
1916
|
+
writeFile: writeFile$2
|
|
1917
|
+
};
|
|
1918
|
+
|
|
1919
|
+
const hasName = (error, name) => {
|
|
1920
|
+
return typeof error === 'object' && error !== null && 'name' in error && error.name === name;
|
|
1921
|
+
};
|
|
1922
|
+
const isNotAllowedError = error => hasName(error, 'NotAllowedError');
|
|
1923
|
+
const isNotFoundError = error => hasName(error, 'NotFoundError');
|
|
1924
|
+
|
|
1925
|
+
const Granted = 'granted';
|
|
1926
|
+
const Prompt = 'prompt';
|
|
1927
|
+
const Denied = 'denied';
|
|
1928
|
+
|
|
1929
|
+
const Directory = 'directory';
|
|
1930
|
+
const File$1 = 'file';
|
|
1931
|
+
|
|
1932
|
+
const getDirentType = fileHandleKind => {
|
|
1933
|
+
switch (fileHandleKind) {
|
|
1934
|
+
case Directory:
|
|
1935
|
+
return Directory$1;
|
|
1936
|
+
case File$1:
|
|
1937
|
+
return File$3;
|
|
1938
|
+
default:
|
|
1939
|
+
return Unknown;
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
|
|
1943
|
+
class FileNotFoundError extends Error {
|
|
1944
|
+
code = 'ENOENT';
|
|
1945
|
+
constructor(path) {
|
|
1946
|
+
super(`File not found '${path}'`);
|
|
1947
|
+
this.name = 'FileNotFoundError';
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* Do not use directly, use FileSystemHtml.getChildHandles
|
|
1953
|
+
* instead which prompts for the required permission to
|
|
1954
|
+
* retrieve the child handles
|
|
1955
|
+
*/
|
|
1956
|
+
const getChildHandles$1 = async handle => {
|
|
1957
|
+
object(handle);
|
|
1958
|
+
// @ts-ignore - values() exists on FileSystemDirectoryHandle but TypeScript types may not include it
|
|
1959
|
+
const handles = await Array.fromAsync(handle.values());
|
|
1960
|
+
return handles;
|
|
1961
|
+
};
|
|
1962
|
+
const getFileHandle$1 = (handle, name, options) => {
|
|
1963
|
+
return handle.getFileHandle(name, options);
|
|
1964
|
+
};
|
|
1965
|
+
const getDirectoryHandle$1 = (handle, name) => {
|
|
1966
|
+
return handle.getDirectoryHandle(name);
|
|
1967
|
+
};
|
|
1968
|
+
|
|
1969
|
+
const getBinaryString$1 = async file => {
|
|
1970
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
1971
|
+
const chunks = [];
|
|
1972
|
+
const chunkSize = 32_768;
|
|
1973
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
1974
|
+
chunks.push(String.fromCodePoint(...bytes.subarray(i, i + chunkSize)));
|
|
1975
|
+
}
|
|
1976
|
+
return chunks.join('');
|
|
1977
|
+
};
|
|
1978
|
+
|
|
1979
|
+
const getFile = async handle => {
|
|
1980
|
+
if ('file' in handle) return handle.file;
|
|
1981
|
+
return handle.getFile();
|
|
1982
|
+
};
|
|
1983
|
+
const getBinaryString = async handle => {
|
|
1984
|
+
const file = await getFile(handle);
|
|
1985
|
+
const text = await getBinaryString$1(file);
|
|
1986
|
+
return text;
|
|
1987
|
+
};
|
|
1988
|
+
const write = async (handle, content) => {
|
|
1989
|
+
if ('readonly' in handle && handle.readonly) {
|
|
1990
|
+
throw new Error(`File ${handle.name} is read-only`);
|
|
1991
|
+
}
|
|
1992
|
+
const writable = await handle.createWritable();
|
|
1993
|
+
await writable.write(content);
|
|
1994
|
+
await writable.close();
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1997
|
+
const {
|
|
1998
|
+
invoke} = createLazyRpc(RendererProcess);
|
|
1999
|
+
|
|
2000
|
+
const requestPermission = async (handle, options) => {
|
|
2001
|
+
// query permission, but from renderer process
|
|
2002
|
+
// because handle.requestPermission is not implemented
|
|
2003
|
+
// in a worker, see https://github.com/WICG/file-system-access/issues/289
|
|
2004
|
+
const permissionTypeNow = await invoke('FileSystemHandle.requestPermission', handle, options);
|
|
2005
|
+
return permissionTypeNow;
|
|
2006
|
+
};
|
|
2007
|
+
const queryPermission = async (handle, options) => {
|
|
2008
|
+
// @ts-ignore - queryPermission exists on FileSystemHandle but TypeScript types may not include it
|
|
2009
|
+
return handle.queryPermission(options);
|
|
2010
|
+
};
|
|
2011
|
+
|
|
2012
|
+
const join = (pathSeparator, ...parts) => {
|
|
2013
|
+
return parts.join(pathSeparator);
|
|
2014
|
+
};
|
|
2015
|
+
const dirname = (pathSeparator, path) => {
|
|
2016
|
+
const index = path.lastIndexOf(pathSeparator);
|
|
2017
|
+
return index === -1 ? path : path.slice(0, index);
|
|
2018
|
+
};
|
|
2019
|
+
const getBaseName = (pathSeparator, path) => {
|
|
2020
|
+
return path.slice(path.lastIndexOf(pathSeparator) + 1);
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
// Native IDB events expose a generic result that may itself be mutable.
|
|
2024
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2025
|
+
const requestToPromise = request => {
|
|
2026
|
+
return new Promise((resolve, reject) => {
|
|
2027
|
+
request.addEventListener('success', () => resolve(request.result), {
|
|
2028
|
+
once: true
|
|
2029
|
+
});
|
|
2030
|
+
request.addEventListener('error', () => reject(request.error || new Error('IndexedDB request failed')), {
|
|
2031
|
+
once: true
|
|
2032
|
+
});
|
|
2033
|
+
});
|
|
2034
|
+
};
|
|
2035
|
+
const state$1 = {};
|
|
2036
|
+
const getDatabase = () => {
|
|
2037
|
+
state$1.databasePromise ||= (() => {
|
|
2038
|
+
// Keep the renderer's database and store names so existing workspaces restore.
|
|
2039
|
+
const request = indexedDB.open('handle', 1);
|
|
2040
|
+
request.onupgradeneeded = () => {
|
|
2041
|
+
const database = request.result;
|
|
2042
|
+
if (!database.objectStoreNames.contains('file-handles-store')) {
|
|
2043
|
+
database.createObjectStore('file-handles-store');
|
|
2044
|
+
}
|
|
2045
|
+
};
|
|
2046
|
+
return requestToPromise(request);
|
|
2047
|
+
})();
|
|
2048
|
+
return state$1.databasePromise;
|
|
2049
|
+
};
|
|
2050
|
+
const addHandle$1 = async (uri, handle) => {
|
|
2051
|
+
const database = await getDatabase();
|
|
2052
|
+
await requestToPromise(database.transaction('file-handles-store', 'readwrite').objectStore('file-handles-store').put(handle, uri));
|
|
2053
|
+
};
|
|
2054
|
+
const getHandle$1 = async uri => {
|
|
2055
|
+
const database = await getDatabase();
|
|
2056
|
+
return requestToPromise(database.transaction('file-handles-store').objectStore('file-handles-store').get(uri));
|
|
2057
|
+
};
|
|
2058
|
+
|
|
2059
|
+
const handles = Object.create(null);
|
|
2060
|
+
const getLegacyHtmlKeys = uri => {
|
|
2061
|
+
if (!uri.startsWith('html://')) {
|
|
2062
|
+
return [];
|
|
2063
|
+
}
|
|
2064
|
+
const strippedUri = uri.slice('html://'.length);
|
|
2065
|
+
const legacyKeys = [];
|
|
2066
|
+
if (strippedUri) {
|
|
2067
|
+
legacyKeys.push(strippedUri);
|
|
2068
|
+
}
|
|
2069
|
+
if (strippedUri.startsWith('/')) {
|
|
2070
|
+
legacyKeys.push(strippedUri.slice(1));
|
|
2071
|
+
}
|
|
2072
|
+
return legacyKeys.filter((value, index, array) => value && array.indexOf(value) === index);
|
|
2073
|
+
};
|
|
2074
|
+
const addHandle = async (uri, handle) => {
|
|
2075
|
+
try {
|
|
2076
|
+
handles[uri] = handle;
|
|
2077
|
+
await addHandle$1(uri, handle);
|
|
2078
|
+
} catch (error) {
|
|
2079
|
+
throw new VError(error, 'Failed to add handle');
|
|
2080
|
+
}
|
|
2081
|
+
};
|
|
2082
|
+
const addHandles = async (parentUri, childHandles) => {
|
|
2083
|
+
const promises = [];
|
|
2084
|
+
for (const childHandle of childHandles) {
|
|
2085
|
+
const childUri = parentUri + '/' + childHandle.name;
|
|
2086
|
+
if (childUri in handles) {
|
|
2087
|
+
continue;
|
|
2088
|
+
}
|
|
2089
|
+
handles[childUri] = childHandle;
|
|
2090
|
+
promises.push(addHandle(childUri, childHandle));
|
|
2091
|
+
}
|
|
2092
|
+
await Promise.all(promises);
|
|
2093
|
+
};
|
|
2094
|
+
const removeHandle = uri => {
|
|
2095
|
+
delete handles[uri];
|
|
2096
|
+
const prefix = `${uri}/`;
|
|
2097
|
+
for (const key in handles) {
|
|
2098
|
+
if (key.startsWith(prefix)) {
|
|
2099
|
+
delete handles[key];
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
};
|
|
2103
|
+
const getHandle = async uri => {
|
|
2104
|
+
try {
|
|
2105
|
+
if (uri in handles) {
|
|
2106
|
+
return handles[uri];
|
|
2107
|
+
}
|
|
2108
|
+
let handle = await getHandle$1(uri);
|
|
2109
|
+
if (!handle) {
|
|
2110
|
+
const legacyKeys = getLegacyHtmlKeys(uri);
|
|
2111
|
+
for (const legacyKey of legacyKeys) {
|
|
2112
|
+
handle = await getHandle$1(legacyKey);
|
|
2113
|
+
if (handle) {
|
|
2114
|
+
await addHandle(uri, handle);
|
|
2115
|
+
handles[legacyKey] = handle;
|
|
2116
|
+
break;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
if (handle) {
|
|
2121
|
+
handles[uri] = handle;
|
|
2122
|
+
}
|
|
2123
|
+
return handle;
|
|
2124
|
+
} catch (error) {
|
|
2125
|
+
throw new VError(error, 'Failed to get handle');
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
|
|
2129
|
+
const pathSeparator$2 = '/';
|
|
2130
|
+
const getDirectoryHandleWithDependencies = async (uri, dependencies) => {
|
|
2131
|
+
const handle = await dependencies.getHandle(uri);
|
|
2132
|
+
if (handle) {
|
|
2133
|
+
return handle;
|
|
2134
|
+
}
|
|
2135
|
+
const dirname$1 = dirname(pathSeparator$2, uri);
|
|
2136
|
+
if (uri === dirname$1) {
|
|
2137
|
+
return undefined;
|
|
2138
|
+
}
|
|
2139
|
+
const parentHandle = await getDirectoryHandleWithDependencies(dirname$1, dependencies);
|
|
2140
|
+
if (!parentHandle) {
|
|
2141
|
+
return undefined;
|
|
2142
|
+
}
|
|
2143
|
+
const baseName = getBaseName(pathSeparator$2, uri);
|
|
2144
|
+
try {
|
|
2145
|
+
const directoryHandle = await dependencies.getDirectoryHandle(parentHandle, baseName);
|
|
2146
|
+
await dependencies.addHandle(uri, directoryHandle);
|
|
2147
|
+
return directoryHandle;
|
|
2148
|
+
} catch (error) {
|
|
2149
|
+
if (isNotFoundError(error)) return undefined;
|
|
2150
|
+
throw error;
|
|
2151
|
+
}
|
|
2152
|
+
};
|
|
2153
|
+
const getDirectoryHandle = async uri => {
|
|
2154
|
+
return getDirectoryHandleWithDependencies(uri, {
|
|
2155
|
+
addHandle: addHandle,
|
|
2156
|
+
getDirectoryHandle: getDirectoryHandle$1,
|
|
2157
|
+
getHandle: async path => {
|
|
2158
|
+
const handle = await getHandle(path);
|
|
2159
|
+
return handle;
|
|
2160
|
+
}
|
|
2161
|
+
});
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
const pathSeparator$1 = '/';
|
|
2165
|
+
const getFileHandle = async (uri, options) => {
|
|
2166
|
+
const handle = await getHandle(uri);
|
|
2167
|
+
if (handle) {
|
|
2168
|
+
return handle;
|
|
2169
|
+
}
|
|
2170
|
+
const dirname$1 = dirname(pathSeparator$1, uri);
|
|
2171
|
+
const parentHandle = await getDirectoryHandle(dirname$1);
|
|
2172
|
+
if (!parentHandle) {
|
|
2173
|
+
return undefined;
|
|
2174
|
+
}
|
|
2175
|
+
const baseName = getBaseName(pathSeparator$1, uri);
|
|
2176
|
+
const fileHandle = await getFileHandle$1(parentHandle, baseName, options);
|
|
2177
|
+
return fileHandle;
|
|
2178
|
+
};
|
|
2179
|
+
|
|
2180
|
+
const pathSeparator = '/';
|
|
2181
|
+
const exists$1 = async uri => {
|
|
2182
|
+
const handle = await getHandle(uri);
|
|
2183
|
+
return Boolean(handle);
|
|
2184
|
+
};
|
|
2185
|
+
const getDirent = handle => {
|
|
2186
|
+
const {
|
|
2187
|
+
kind,
|
|
2188
|
+
name
|
|
2189
|
+
} = handle;
|
|
2190
|
+
const type = getDirentType(kind);
|
|
2191
|
+
return {
|
|
2192
|
+
name,
|
|
2193
|
+
type
|
|
2194
|
+
};
|
|
2195
|
+
};
|
|
2196
|
+
const getDirents = handles => {
|
|
2197
|
+
const dirents = handles.map(getDirent);
|
|
2198
|
+
return dirents;
|
|
2199
|
+
};
|
|
2200
|
+
const getChildHandlesFallbackPrompt = async handle => {
|
|
2201
|
+
// TODO cannot prompt without user activation, else error occurs
|
|
2202
|
+
// maybe need to show
|
|
2203
|
+
const permissionTypeNow = await requestPermission(handle, {
|
|
2204
|
+
mode: 'readwrite'
|
|
2205
|
+
});
|
|
2206
|
+
switch (permissionTypeNow) {
|
|
2207
|
+
case Denied:
|
|
2208
|
+
case Prompt:
|
|
2209
|
+
return [];
|
|
2210
|
+
case Granted:
|
|
2211
|
+
return getChildHandles$1(handle);
|
|
2212
|
+
default:
|
|
2213
|
+
return [];
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
const getChildHandlesFallback = async handle => {
|
|
2217
|
+
const permissionType = await queryPermission(handle, {
|
|
2218
|
+
mode: 'readwrite'
|
|
2219
|
+
});
|
|
2220
|
+
switch (permissionType) {
|
|
2221
|
+
case Denied:
|
|
2222
|
+
return [];
|
|
2223
|
+
case Granted:
|
|
2224
|
+
throw new VError('invalid state');
|
|
2225
|
+
case Prompt:
|
|
2226
|
+
return await getChildHandlesFallbackPrompt(handle);
|
|
2227
|
+
default:
|
|
2228
|
+
return [];
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
const getChildHandles = async handle => {
|
|
2232
|
+
try {
|
|
2233
|
+
return await getChildHandles$1(handle);
|
|
2234
|
+
} catch (error) {
|
|
2235
|
+
if (isNotAllowedError(error)) {
|
|
2236
|
+
return getChildHandlesFallback(handle);
|
|
2237
|
+
}
|
|
2238
|
+
throw new VError(error, 'failed to get child handles');
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
const readDirWithFileTypes$1 = async uri => {
|
|
2242
|
+
try {
|
|
2243
|
+
const handle = await getHandle(uri);
|
|
2244
|
+
if (!handle) {
|
|
2245
|
+
throw new Error(`File system handle not found for ${uri}`);
|
|
2246
|
+
}
|
|
2247
|
+
const childHandles = await getChildHandles(handle);
|
|
2248
|
+
await addHandles(uri, childHandles);
|
|
2249
|
+
const dirents = getDirents(childHandles);
|
|
2250
|
+
return dirents;
|
|
2251
|
+
} catch (error) {
|
|
2252
|
+
throw new VError(error, 'failed to read directory');
|
|
2253
|
+
}
|
|
2254
|
+
};
|
|
2255
|
+
const readFile$1 = async uri => {
|
|
2256
|
+
try {
|
|
2257
|
+
const handle = await getFileHandle(uri);
|
|
2258
|
+
if (!handle) {
|
|
2259
|
+
throw new VError(`File not found ${uri}`);
|
|
2260
|
+
}
|
|
2261
|
+
const file = await getFile(handle);
|
|
2262
|
+
const text = await file.text();
|
|
2263
|
+
return text;
|
|
2264
|
+
} catch (error) {
|
|
2265
|
+
if (isNotFoundError(error)) {
|
|
2266
|
+
throw new FileNotFoundError(uri);
|
|
2267
|
+
}
|
|
2268
|
+
throw new VError(error, 'Failed to read file');
|
|
2269
|
+
}
|
|
2270
|
+
};
|
|
2271
|
+
const writeFile$1 = async (uri, content) => {
|
|
2272
|
+
try {
|
|
2273
|
+
const handle = await getFileHandle(uri, {
|
|
2274
|
+
create: true
|
|
2275
|
+
});
|
|
2276
|
+
if (!handle) {
|
|
2277
|
+
throw new VError(`File not found ${uri}`);
|
|
2278
|
+
}
|
|
2279
|
+
await write(handle, content);
|
|
2280
|
+
} catch (error) {
|
|
2281
|
+
throw new VError(error, 'Failed to save file');
|
|
2282
|
+
}
|
|
2283
|
+
};
|
|
2284
|
+
const writeBlob$1 = async (uri, blob) => {
|
|
2285
|
+
try {
|
|
2286
|
+
const handle = await getFileHandle(uri, {
|
|
2287
|
+
create: true
|
|
2288
|
+
});
|
|
2289
|
+
if (!handle) {
|
|
2290
|
+
throw new VError(`File not found ${uri}`);
|
|
2291
|
+
}
|
|
2292
|
+
await write(handle, blob);
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
throw new VError(error, 'Failed to save file');
|
|
2295
|
+
}
|
|
2296
|
+
};
|
|
2297
|
+
const remove$1 = async uri => {
|
|
2298
|
+
try {
|
|
2299
|
+
const dirname$1 = dirname(pathSeparator, uri);
|
|
2300
|
+
const parentHandle = await getDirectoryHandle(dirname$1);
|
|
2301
|
+
if (!parentHandle) {
|
|
2302
|
+
throw new FileNotFoundError(uri);
|
|
2303
|
+
}
|
|
2304
|
+
const existingHandle = await getHandle(uri);
|
|
2305
|
+
const baseName = getBaseName(pathSeparator, uri);
|
|
2306
|
+
if (existingHandle?.kind === 'directory') {
|
|
2307
|
+
await parentHandle.removeEntry(baseName, {
|
|
2308
|
+
recursive: true
|
|
2309
|
+
});
|
|
2310
|
+
} else {
|
|
2311
|
+
await parentHandle.removeEntry(baseName);
|
|
2312
|
+
}
|
|
2313
|
+
removeHandle(uri);
|
|
2314
|
+
} catch (error) {
|
|
2315
|
+
if (error instanceof FileNotFoundError || isNotFoundError(error)) {
|
|
2316
|
+
throw new FileNotFoundError(uri);
|
|
2317
|
+
}
|
|
2318
|
+
throw new VError(error, 'Failed to remove');
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
const ensureDirectoryHandle = async uri => {
|
|
2322
|
+
const existingHandle = await getHandle(uri);
|
|
2323
|
+
if (existingHandle) {
|
|
2324
|
+
if (existingHandle.kind !== 'directory') {
|
|
2325
|
+
throw new VError(`Expected directory at ${uri}`);
|
|
2326
|
+
}
|
|
2327
|
+
return existingHandle;
|
|
2328
|
+
}
|
|
2329
|
+
const dirname$1 = dirname(pathSeparator, uri);
|
|
2330
|
+
if (uri === dirname$1) {
|
|
2331
|
+
throw new VError(`Directory handle not found for ${uri}`);
|
|
2332
|
+
}
|
|
2333
|
+
let parentHandle = await getDirectoryHandle(dirname$1);
|
|
2334
|
+
if (!parentHandle) {
|
|
2335
|
+
parentHandle = await ensureDirectoryHandle(dirname$1);
|
|
2336
|
+
}
|
|
2337
|
+
const baseName = getBaseName(pathSeparator, uri);
|
|
2338
|
+
const directoryHandle = await parentHandle.getDirectoryHandle(baseName, {
|
|
2339
|
+
create: true
|
|
2340
|
+
});
|
|
2341
|
+
await addHandle(uri, directoryHandle);
|
|
2342
|
+
return directoryHandle;
|
|
2343
|
+
};
|
|
2344
|
+
const mkdir$1 = async uri => {
|
|
2345
|
+
try {
|
|
2346
|
+
await ensureDirectoryHandle(uri);
|
|
2347
|
+
} catch (error) {
|
|
2348
|
+
throw new VError(error, 'Failed to create directory');
|
|
2349
|
+
}
|
|
2350
|
+
};
|
|
2351
|
+
const isReadonly$1 = async uri => {
|
|
2352
|
+
const handle = await getHandle(uri);
|
|
2353
|
+
return Boolean(handle && 'readonly' in handle && handle.readonly);
|
|
2354
|
+
};
|
|
2355
|
+
const getBlob = async uri => {
|
|
2356
|
+
const handle = await getFileHandle(uri);
|
|
2357
|
+
if (!handle) {
|
|
2358
|
+
throw new Error(`file not found`);
|
|
2359
|
+
}
|
|
2360
|
+
const file = await getFile(handle);
|
|
2361
|
+
// TODO convert handle to blob mime type?
|
|
2362
|
+
return file;
|
|
1916
2363
|
};
|
|
1917
2364
|
|
|
1918
2365
|
const isFetch = uri => {
|
|
@@ -1938,29 +2385,31 @@ const isProviderUri = uri => {
|
|
|
1938
2385
|
};
|
|
1939
2386
|
|
|
1940
2387
|
const remove = async dirent => {
|
|
2388
|
+
if (isHtml(dirent)) return remove$1(dirent);
|
|
1941
2389
|
if (isMemory(dirent)) {
|
|
1942
|
-
return remove$
|
|
2390
|
+
return remove$3(dirent);
|
|
1943
2391
|
}
|
|
1944
2392
|
if (isProviderUri(dirent)) {
|
|
1945
2393
|
return invoke$2('FileSystem.remove', dirent);
|
|
1946
2394
|
}
|
|
1947
|
-
return remove$
|
|
2395
|
+
return remove$4(dirent);
|
|
1948
2396
|
};
|
|
1949
2397
|
const readFile = async uri => {
|
|
2398
|
+
if (isHtml(uri)) return readFile$1(uri);
|
|
1950
2399
|
if (uri.startsWith('untitled:')) return '';
|
|
1951
|
-
if (isFetch(uri)
|
|
2400
|
+
if (isFetch(uri)) {
|
|
1952
2401
|
return invoke$2('FileSystem.readFile', uri);
|
|
1953
2402
|
}
|
|
1954
2403
|
if (isHttp(uri)) {
|
|
1955
|
-
return readFile$
|
|
2404
|
+
return readFile$2(uri);
|
|
1956
2405
|
}
|
|
1957
2406
|
if (isMemory(uri)) {
|
|
1958
|
-
return readFile$
|
|
2407
|
+
return readFile$3(uri);
|
|
1959
2408
|
}
|
|
1960
2409
|
if (isProviderUri(uri)) {
|
|
1961
2410
|
return invoke$2('FileSystem.readFile', uri);
|
|
1962
2411
|
}
|
|
1963
|
-
return readFile$
|
|
2412
|
+
return readFile$4(uri);
|
|
1964
2413
|
};
|
|
1965
2414
|
const getFileHash = async uri => {
|
|
1966
2415
|
return getFileHash$1(uri);
|
|
@@ -1972,21 +2421,24 @@ const appendFile = async (uri, text) => {
|
|
|
1972
2421
|
return appendFile$1(uri, text);
|
|
1973
2422
|
};
|
|
1974
2423
|
const readDirWithFileTypes = async uri => {
|
|
1975
|
-
if (
|
|
2424
|
+
if (isHtml(uri)) return readDirWithFileTypes$1(uri);
|
|
2425
|
+
if (isFetch(uri)) {
|
|
1976
2426
|
return invoke$2('FileSystem.readDirWithFileTypes', uri);
|
|
1977
2427
|
}
|
|
1978
2428
|
if (isMemory(uri)) {
|
|
1979
|
-
return readDirWithFileTypes$
|
|
2429
|
+
return readDirWithFileTypes$3(uri);
|
|
1980
2430
|
}
|
|
1981
2431
|
if (isProviderUri(uri)) {
|
|
1982
2432
|
return invoke$2('FileSystem.readDirWithFileTypes', uri);
|
|
1983
2433
|
}
|
|
1984
|
-
return readDirWithFileTypes$
|
|
2434
|
+
return readDirWithFileTypes$4(uri);
|
|
1985
2435
|
};
|
|
1986
2436
|
const isReadonly = async uri => {
|
|
2437
|
+
if (isHtml(uri)) return isReadonly$1(uri);
|
|
1987
2438
|
return invoke$1('FileSystem.isReadonly', uri);
|
|
1988
2439
|
};
|
|
1989
2440
|
const readJson = async uri => {
|
|
2441
|
+
if (isHtml(uri)) return JSON.parse(await readFile$1(uri));
|
|
1990
2442
|
if (isHttp(uri)) {
|
|
1991
2443
|
return readJson$1(uri);
|
|
1992
2444
|
}
|
|
@@ -2006,6 +2458,7 @@ const getFileSize = async uri => {
|
|
|
2006
2458
|
return invoke$1('FileSystem.getFileSize', uri);
|
|
2007
2459
|
};
|
|
2008
2460
|
const readFileAsBlob = async uri => {
|
|
2461
|
+
if (isHtml(uri)) return getBlob(uri);
|
|
2009
2462
|
if (isHttp(uri)) {
|
|
2010
2463
|
return readFileAsBlob$1(uri);
|
|
2011
2464
|
}
|
|
@@ -2032,31 +2485,34 @@ const stat = async dirent => {
|
|
|
2032
2485
|
return stat$3(dirent);
|
|
2033
2486
|
};
|
|
2034
2487
|
const exists = async uri => {
|
|
2035
|
-
if (
|
|
2488
|
+
if (isHtml(uri)) return exists$1(uri);
|
|
2489
|
+
if (isMemory(uri)) {
|
|
2490
|
+
return exists$3(uri);
|
|
2491
|
+
}
|
|
2492
|
+
if (isFetch(uri) || isProviderUri(uri)) {
|
|
2036
2493
|
return invoke$2('FileSystem.exists', uri);
|
|
2037
2494
|
}
|
|
2038
2495
|
if (isHttp(uri)) {
|
|
2039
|
-
return exists$1(uri);
|
|
2040
|
-
}
|
|
2041
|
-
if (isMemory(uri)) {
|
|
2042
2496
|
return exists$2(uri);
|
|
2043
2497
|
}
|
|
2044
|
-
return exists$
|
|
2498
|
+
return exists$4(uri);
|
|
2045
2499
|
};
|
|
2046
2500
|
const createFile = async uri => {
|
|
2047
2501
|
if (isMemory(uri)) {
|
|
2048
2502
|
return createFile$2(uri);
|
|
2049
2503
|
}
|
|
2050
|
-
return writeFile$
|
|
2504
|
+
if (isHtml(uri)) return writeFile$1(uri, '');
|
|
2505
|
+
return writeFile$4(uri, '');
|
|
2051
2506
|
};
|
|
2052
2507
|
const writeFile = async (uri, content) => {
|
|
2508
|
+
if (isHtml(uri)) return writeFile$1(uri, content);
|
|
2053
2509
|
if (isMemory(uri)) {
|
|
2054
|
-
return writeFile$
|
|
2510
|
+
return writeFile$3(uri, content);
|
|
2055
2511
|
}
|
|
2056
2512
|
if (isProviderUri(uri)) {
|
|
2057
2513
|
return invoke$2('FileSystem.writeFile', uri, content);
|
|
2058
2514
|
}
|
|
2059
|
-
return writeFile$
|
|
2515
|
+
return writeFile$4(uri, content);
|
|
2060
2516
|
};
|
|
2061
2517
|
const getBytes = async blob => {
|
|
2062
2518
|
if (blob.bytes) {
|
|
@@ -2067,16 +2523,18 @@ const getBytes = async blob => {
|
|
|
2067
2523
|
return bytes;
|
|
2068
2524
|
};
|
|
2069
2525
|
const writeBlob = async (uri, blob) => {
|
|
2526
|
+
if (isHtml(uri)) return writeBlob$1(uri, blob);
|
|
2070
2527
|
const bytes = await getBytes(blob);
|
|
2071
2528
|
// @ts-ignore
|
|
2072
2529
|
await invoke$1('FileSystem.writeBuffer', uri, bytes);
|
|
2073
2530
|
};
|
|
2074
2531
|
const mkdir = async uri => {
|
|
2532
|
+
if (isHtml(uri)) return mkdir$1(uri);
|
|
2075
2533
|
if (isMemory(uri)) {
|
|
2076
|
-
await mkdir$
|
|
2534
|
+
await mkdir$3(uri);
|
|
2077
2535
|
return;
|
|
2078
2536
|
}
|
|
2079
|
-
return mkdir$
|
|
2537
|
+
return mkdir$4(uri);
|
|
2080
2538
|
};
|
|
2081
2539
|
const rename = async (oldUri, newUri) => {
|
|
2082
2540
|
if (isMemory(oldUri) || isMemory(newUri)) {
|
|
@@ -2365,6 +2823,87 @@ const glob = async (root, pattern) => {
|
|
|
2365
2823
|
return globWithFileSystem(FileSystemDisk, root, pattern);
|
|
2366
2824
|
};
|
|
2367
2825
|
|
|
2826
|
+
const FILE_RESULT = 1;
|
|
2827
|
+
const MATCH_RESULT = 2;
|
|
2828
|
+
const USE_REGULAR_EXPRESSION = 1 << 1;
|
|
2829
|
+
const MATCH_WHOLE_WORD = 1 << 3;
|
|
2830
|
+
const MATCH_CASE = 1 << 4;
|
|
2831
|
+
const getLineMatch = (line, lineNumber, query, flags) => {
|
|
2832
|
+
if (flags & USE_REGULAR_EXPRESSION) {
|
|
2833
|
+
const regex = new RegExp(query, flags & MATCH_CASE ? '' : 'i');
|
|
2834
|
+
const match = line.match(regex);
|
|
2835
|
+
return match && typeof match.index === 'number' ? [{
|
|
2836
|
+
end: match.index + match[0].length,
|
|
2837
|
+
lineNumber,
|
|
2838
|
+
start: match.index,
|
|
2839
|
+
text: line,
|
|
2840
|
+
type: MATCH_RESULT
|
|
2841
|
+
}] : [];
|
|
2842
|
+
}
|
|
2843
|
+
const source = flags & MATCH_CASE ? line : line.toLowerCase();
|
|
2844
|
+
const needle = flags & MATCH_CASE ? query : query.toLowerCase();
|
|
2845
|
+
const index = source.indexOf(needle);
|
|
2846
|
+
if (index === -1) {
|
|
2847
|
+
return [];
|
|
2848
|
+
}
|
|
2849
|
+
if (flags & MATCH_WHOLE_WORD) {
|
|
2850
|
+
const before = line[index - 1];
|
|
2851
|
+
const after = line[index + query.length];
|
|
2852
|
+
if (before && /[\p{L}\p{N}_]/u.test(before) || after && /[\p{L}\p{N}_]/u.test(after)) {
|
|
2853
|
+
return [];
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
return [{
|
|
2857
|
+
end: index + query.length,
|
|
2858
|
+
lineNumber,
|
|
2859
|
+
start: index,
|
|
2860
|
+
text: line,
|
|
2861
|
+
type: MATCH_RESULT
|
|
2862
|
+
}];
|
|
2863
|
+
};
|
|
2864
|
+
const searchText = (file, content, query, flags = 0) => {
|
|
2865
|
+
const matches = content.split(/\r?\n/).flatMap((line, index) => getLineMatch(line, index, query, flags));
|
|
2866
|
+
return matches.length === 0 ? [] : [{
|
|
2867
|
+
end: 0,
|
|
2868
|
+
lineNumber: 0,
|
|
2869
|
+
start: 0,
|
|
2870
|
+
text: file,
|
|
2871
|
+
type: FILE_RESULT
|
|
2872
|
+
}, ...matches];
|
|
2873
|
+
};
|
|
2874
|
+
const searchHtmlDirectory = async (uri, relativePath, query, flags) => {
|
|
2875
|
+
const entries = await readDirWithFileTypes$1(uri);
|
|
2876
|
+
const results = [];
|
|
2877
|
+
for (const entry of entries) {
|
|
2878
|
+
const childUri = `${uri}/${entry.name}`;
|
|
2879
|
+
const childRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
2880
|
+
if (entry.type === Directory$1) {
|
|
2881
|
+
results.push(...(await searchHtmlDirectory(childUri, childRelativePath, query, flags)));
|
|
2882
|
+
} else {
|
|
2883
|
+
const content = await readFile$1(childUri);
|
|
2884
|
+
results.push(...searchText(childRelativePath, content, query, flags));
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
return results;
|
|
2888
|
+
};
|
|
2889
|
+
const textSearch = async (root, query, options = {}) => {
|
|
2890
|
+
return searchHtmlDirectory(root, '', query, options.flags || 0);
|
|
2891
|
+
};
|
|
2892
|
+
const searchDirectory = async (uri, prefix = '') => {
|
|
2893
|
+
const entries = await readDirWithFileTypes$1(uri);
|
|
2894
|
+
const results = [];
|
|
2895
|
+
for (const entry of entries) {
|
|
2896
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
2897
|
+
if (entry.type === Directory$1) {
|
|
2898
|
+
results.push(...(await searchDirectory(`${uri}/${entry.name}`, relativePath)));
|
|
2899
|
+
} else {
|
|
2900
|
+
results.push(relativePath);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
return results;
|
|
2904
|
+
};
|
|
2905
|
+
const fileSearch = uri => searchDirectory(uri);
|
|
2906
|
+
|
|
2368
2907
|
const handleMessagePort = async (port, rpcId) => {
|
|
2369
2908
|
const rpc = await create$6({
|
|
2370
2909
|
commandMap: {},
|
|
@@ -2468,54 +3007,13 @@ const initialize = async platform => {
|
|
|
2468
3007
|
await initializeFileSystemProcess(platform);
|
|
2469
3008
|
};
|
|
2470
3009
|
|
|
2471
|
-
const Directory = 'directory';
|
|
2472
|
-
const File$1 = 'file';
|
|
2473
|
-
|
|
2474
|
-
const {
|
|
2475
|
-
invoke} = createLazyRpc(RendererProcess);
|
|
2476
|
-
|
|
2477
|
-
/**
|
|
2478
|
-
* Do not use directly, use FileSystemHtml.getChildHandles
|
|
2479
|
-
* instead which prompts for the required permission to
|
|
2480
|
-
* retrieve the child handles
|
|
2481
|
-
*/
|
|
2482
|
-
const getChildHandles = async handle => {
|
|
2483
|
-
object(handle);
|
|
2484
|
-
// @ts-ignore - values() exists on FileSystemDirectoryHandle but TypeScript types may not include it
|
|
2485
|
-
const handles = await Array.fromAsync(handle.values());
|
|
2486
|
-
return handles;
|
|
2487
|
-
};
|
|
2488
|
-
|
|
2489
3010
|
const uploadDirectory = async (fileSystemHandle, pathSeparator, root, uploadHandles) => {
|
|
2490
3011
|
const folderPath = root + pathSeparator + fileSystemHandle.name;
|
|
2491
3012
|
await mkdir(folderPath);
|
|
2492
|
-
const childHandles = await getChildHandles(fileSystemHandle);
|
|
3013
|
+
const childHandles = await getChildHandles$1(fileSystemHandle);
|
|
2493
3014
|
await uploadHandles(childHandles, pathSeparator, folderPath);
|
|
2494
3015
|
};
|
|
2495
3016
|
|
|
2496
|
-
const getBinaryString$1 = async file => {
|
|
2497
|
-
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
2498
|
-
const chunks = [];
|
|
2499
|
-
const chunkSize = 32_768;
|
|
2500
|
-
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
2501
|
-
chunks.push(String.fromCodePoint(...bytes.subarray(i, i + chunkSize)));
|
|
2502
|
-
}
|
|
2503
|
-
return chunks.join('');
|
|
2504
|
-
};
|
|
2505
|
-
|
|
2506
|
-
const getFile = handle => {
|
|
2507
|
-
return handle.getFile();
|
|
2508
|
-
};
|
|
2509
|
-
const getBinaryString = async handle => {
|
|
2510
|
-
const file = await getFile(handle);
|
|
2511
|
-
const text = await getBinaryString$1(file);
|
|
2512
|
-
return text;
|
|
2513
|
-
};
|
|
2514
|
-
|
|
2515
|
-
const join = (pathSeparator, ...parts) => {
|
|
2516
|
-
return parts.join(pathSeparator);
|
|
2517
|
-
};
|
|
2518
|
-
|
|
2519
3017
|
const uploadFile = async (fileSystemHandle, pathSeparator, root) => {
|
|
2520
3018
|
const content = await getBinaryString(fileSystemHandle);
|
|
2521
3019
|
const to = join(pathSeparator, root, fileSystemHandle.name);
|
|
@@ -2549,7 +3047,7 @@ const uploadFileSystemHandles = async (root, pathSeparator, fileSystemHandles) =
|
|
|
2549
3047
|
name
|
|
2550
3048
|
} = file;
|
|
2551
3049
|
if (kind === Directory) {
|
|
2552
|
-
await
|
|
3050
|
+
await addHandle(`html:///${name}`, file);
|
|
2553
3051
|
await invoke('Workspace.setPath', `html:///${name}`);
|
|
2554
3052
|
return true;
|
|
2555
3053
|
}
|
|
@@ -2589,8 +3087,13 @@ const commandMap = {
|
|
|
2589
3087
|
'FileSystem.watchFile': watchFile,
|
|
2590
3088
|
'FileSystem.writeBlob': writeBlob,
|
|
2591
3089
|
'FileSystem.writeFile': writeFile,
|
|
3090
|
+
'FileSystemHtml.fileSearch': fileSearch,
|
|
3091
|
+
'FileSystemHtml.textSearch': textSearch,
|
|
2592
3092
|
'FileSystemMemory.getFiles': getFiles,
|
|
2593
|
-
'Initialize.initialize': initialize
|
|
3093
|
+
'Initialize.initialize': initialize,
|
|
3094
|
+
'PersistentFileHandle.addHandle': addHandle,
|
|
3095
|
+
'PersistentFileHandle.getHandle': getHandle,
|
|
3096
|
+
'PersistentFileHandle.removeHandle': removeHandle
|
|
2594
3097
|
};
|
|
2595
3098
|
|
|
2596
3099
|
const CommandMap = {
|