@themartiancompany/opfs 1.8.11
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/COPYING +674 -0
- package/README.cn.md +301 -0
- package/README.md +241 -0
- package/dist/main.cjs +1840 -0
- package/dist/main.cjs.map +1 -0
- package/dist/main.mjs +1751 -0
- package/dist/main.mjs.map +1 -0
- package/dist/types.d.ts +920 -0
- package/dist/types.d.ts.map +1 -0
- package/docs/README.md +115 -0
- package/docs/classes/SyncMessenger.md +42 -0
- package/docs/functions/appendFile.md +29 -0
- package/docs/functions/appendFileSync.md +26 -0
- package/docs/functions/assertAbsolutePath.md +29 -0
- package/docs/functions/assertFileUrl.md +29 -0
- package/docs/functions/connectSyncAgent.md +25 -0
- package/docs/functions/copy.md +35 -0
- package/docs/functions/copySync.md +30 -0
- package/docs/functions/createFile.md +27 -0
- package/docs/functions/createFileSync.md +25 -0
- package/docs/functions/deleteTemp.md +23 -0
- package/docs/functions/deleteTempSync.md +19 -0
- package/docs/functions/downloadFile.md +58 -0
- package/docs/functions/emptyDir.md +28 -0
- package/docs/functions/emptyDirSync.md +25 -0
- package/docs/functions/exists.md +29 -0
- package/docs/functions/existsSync.md +26 -0
- package/docs/functions/generateTempPath.md +27 -0
- package/docs/functions/getFileDataByHandle.md +27 -0
- package/docs/functions/getSyncMessenger.md +22 -0
- package/docs/functions/isDirectoryHandle.md +27 -0
- package/docs/functions/isFileHandle.md +27 -0
- package/docs/functions/isFileHandleLike.md +27 -0
- package/docs/functions/isOPFSSupported.md +21 -0
- package/docs/functions/isTempPath.md +27 -0
- package/docs/functions/mkTemp.md +28 -0
- package/docs/functions/mkTempSync.md +25 -0
- package/docs/functions/mkdir.md +27 -0
- package/docs/functions/mkdirSync.md +25 -0
- package/docs/functions/move.md +34 -0
- package/docs/functions/moveSync.md +30 -0
- package/docs/functions/pruneTemp.md +28 -0
- package/docs/functions/pruneTempSync.md +25 -0
- package/docs/functions/readBlobFile.md +28 -0
- package/docs/functions/readBlobFileSync.md +25 -0
- package/docs/functions/readDir.md +28 -0
- package/docs/functions/readDirSync.md +26 -0
- package/docs/functions/readFile.md +132 -0
- package/docs/functions/readFileSync.md +70 -0
- package/docs/functions/readJsonFile.md +35 -0
- package/docs/functions/readJsonFileSync.md +31 -0
- package/docs/functions/readTextFile.md +28 -0
- package/docs/functions/readTextFileSync.md +25 -0
- package/docs/functions/remove.md +27 -0
- package/docs/functions/removeSync.md +25 -0
- package/docs/functions/setSyncMessenger.md +26 -0
- package/docs/functions/startSyncAgent.md +21 -0
- package/docs/functions/stat.md +27 -0
- package/docs/functions/statSync.md +25 -0
- package/docs/functions/toFileSystemHandleLike.md +27 -0
- package/docs/functions/unzip.md +32 -0
- package/docs/functions/unzipFromUrl.md +36 -0
- package/docs/functions/unzipSync.md +26 -0
- package/docs/functions/uploadFile.md +33 -0
- package/docs/functions/writeFile.md +32 -0
- package/docs/functions/writeFileSync.md +30 -0
- package/docs/functions/zip.md +65 -0
- package/docs/functions/zipFromUrl.md +63 -0
- package/docs/functions/zipSync.md +55 -0
- package/docs/interfaces/CopyOptions.md +17 -0
- package/docs/interfaces/DownloadFileTempResponse.md +18 -0
- package/docs/interfaces/ErrorLike.md +18 -0
- package/docs/interfaces/ExistsOptions.md +18 -0
- package/docs/interfaces/FileLike.md +21 -0
- package/docs/interfaces/FileSystemFileHandleLike.md +25 -0
- package/docs/interfaces/FileSystemHandleLike.md +22 -0
- package/docs/interfaces/MoveOptions.md +17 -0
- package/docs/interfaces/ReadDirEntry.md +18 -0
- package/docs/interfaces/ReadDirEntrySync.md +18 -0
- package/docs/interfaces/ReadDirOptions.md +17 -0
- package/docs/interfaces/ReadOptions.md +17 -0
- package/docs/interfaces/SyncAgentOptions.md +19 -0
- package/docs/interfaces/TempOptions.md +19 -0
- package/docs/interfaces/UploadRequestInit.md +21 -0
- package/docs/interfaces/WriteOptions.md +19 -0
- package/docs/interfaces/ZipOptions.md +17 -0
- package/docs/type-aliases/FileEncoding.md +15 -0
- package/docs/type-aliases/FsRequestInit.md +15 -0
- package/docs/type-aliases/ReadFileContent.md +15 -0
- package/docs/type-aliases/WriteFileContent.md +15 -0
- package/docs/type-aliases/WriteSyncFileContent.md +16 -0
- package/docs/variables/CURRENT_DIR.md +15 -0
- package/docs/variables/NOT_FOUND_ERROR.md +18 -0
- package/docs/variables/ROOT_DIR.md +15 -0
- package/docs/variables/TMP_DIR.md +15 -0
- package/package.json +141 -0
- package/src/fs/assertions.ts +63 -0
- package/src/fs/constants.ts +63 -0
- package/src/fs/defines.ts +352 -0
- package/src/fs/helpers.ts +338 -0
- package/src/fs/opfs_core.ts +413 -0
- package/src/fs/opfs_download.ts +174 -0
- package/src/fs/opfs_ext.ts +504 -0
- package/src/fs/opfs_tmp.ts +131 -0
- package/src/fs/opfs_unzip.ts +168 -0
- package/src/fs/opfs_upload.ts +126 -0
- package/src/fs/opfs_zip.ts +314 -0
- package/src/fs/support.ts +36 -0
- package/src/fs/utils.ts +176 -0
- package/src/mod.ts +41 -0
- package/src/worker/helpers.ts +168 -0
- package/src/worker/opfs_worker.ts +298 -0
- package/src/worker/opfs_worker_adapter.ts +666 -0
- package/src/worker/shared.ts +400 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import type { FetchInit } from '@happy-ts/fetch-t';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Represents the possible content types that can be written to a file.
|
|
31
|
+
*/
|
|
32
|
+
export type WriteFileContent =
|
|
33
|
+
BufferSource |
|
|
34
|
+
Blob |
|
|
35
|
+
string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Represents the possible content types that can be
|
|
39
|
+
* written synchronously to a file.
|
|
40
|
+
*/
|
|
41
|
+
export type WriteSyncFileContent =
|
|
42
|
+
BufferSource |
|
|
43
|
+
string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Represents the possible content types that can be read from a file.
|
|
47
|
+
*/
|
|
48
|
+
export type ReadFileContent =
|
|
49
|
+
ArrayBuffer |
|
|
50
|
+
File |
|
|
51
|
+
string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Options for reading files with specified encoding.
|
|
55
|
+
*/
|
|
56
|
+
export interface ReadOptions {
|
|
57
|
+
/**
|
|
58
|
+
* The encoding to use for reading the file's content.
|
|
59
|
+
* @defaultValue `'binary'`
|
|
60
|
+
*/
|
|
61
|
+
encoding?:
|
|
62
|
+
FileEncoding;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Options for writing files, including flags for creation
|
|
67
|
+
* and appending.
|
|
68
|
+
*/
|
|
69
|
+
export interface WriteOptions {
|
|
70
|
+
/**
|
|
71
|
+
* Whether to create the file if it does not exist.
|
|
72
|
+
* @defaultValue `true`
|
|
73
|
+
*/
|
|
74
|
+
create?:
|
|
75
|
+
boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Whether to append to the file if it already exists.
|
|
78
|
+
* @defaultValue `false`
|
|
79
|
+
*/
|
|
80
|
+
append?:
|
|
81
|
+
boolean;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Options to determine the existence of a file or directory.
|
|
86
|
+
*/
|
|
87
|
+
export interface ExistsOptions {
|
|
88
|
+
/**
|
|
89
|
+
* Whether to check for the existence of a directory.
|
|
90
|
+
* @defaultValue `false`
|
|
91
|
+
*/
|
|
92
|
+
isDirectory?:
|
|
93
|
+
boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Whether to check for the existence of a file.
|
|
96
|
+
* @defaultValue `false`
|
|
97
|
+
*/
|
|
98
|
+
isFile?:
|
|
99
|
+
boolean;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Supported file encodings for reading and writing files.
|
|
104
|
+
*/
|
|
105
|
+
export type FileEncoding =
|
|
106
|
+
'binary' |
|
|
107
|
+
'utf8' |
|
|
108
|
+
'blob';
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* fetch-t options for download and upload.
|
|
112
|
+
*/
|
|
113
|
+
export type FsRequestInit =
|
|
114
|
+
Omit<FetchInit,
|
|
115
|
+
'abortable' |
|
|
116
|
+
'responseType'>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* fetch-t request options for uploading files.
|
|
120
|
+
*/
|
|
121
|
+
export interface UploadRequestInit extends FsRequestInit {
|
|
122
|
+
/**
|
|
123
|
+
* The filename to use when uploading the file.
|
|
124
|
+
*/
|
|
125
|
+
filename?:
|
|
126
|
+
string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Options for reading directories.
|
|
131
|
+
*/
|
|
132
|
+
export interface ReadDirOptions {
|
|
133
|
+
/**
|
|
134
|
+
* Whether to recursively read the contents of directories.
|
|
135
|
+
*/
|
|
136
|
+
recursive:
|
|
137
|
+
boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* An entry returned by `readDir`.
|
|
142
|
+
*/
|
|
143
|
+
export interface ReadDirEntry {
|
|
144
|
+
/**
|
|
145
|
+
* The relative path of the entry from readDir the path parameter.
|
|
146
|
+
*/
|
|
147
|
+
path:
|
|
148
|
+
string;
|
|
149
|
+
/**
|
|
150
|
+
* The handle of the entry.
|
|
151
|
+
*/
|
|
152
|
+
handle:
|
|
153
|
+
FileSystemHandle;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* An entry returned by `readDirSync`.
|
|
158
|
+
*/
|
|
159
|
+
export interface ReadDirEntrySync {
|
|
160
|
+
/**
|
|
161
|
+
* The relative path of the entry from readDir the path parameter.
|
|
162
|
+
*/
|
|
163
|
+
path:
|
|
164
|
+
string;
|
|
165
|
+
/**
|
|
166
|
+
* The handle of the entry.
|
|
167
|
+
*/
|
|
168
|
+
handle:
|
|
169
|
+
FileSystemHandleLike;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* A handle to a file or directory returned by `statSync`.
|
|
174
|
+
*/
|
|
175
|
+
export interface FileSystemHandleLike {
|
|
176
|
+
/**
|
|
177
|
+
* The name of the entry.
|
|
178
|
+
*/
|
|
179
|
+
name:
|
|
180
|
+
string;
|
|
181
|
+
/**
|
|
182
|
+
* The kind of the entry.
|
|
183
|
+
*/
|
|
184
|
+
kind:
|
|
185
|
+
FileSystemHandleKind;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface FileSystemFileHandleLike extends FileSystemHandleLike {
|
|
189
|
+
/**
|
|
190
|
+
* The type of the file.
|
|
191
|
+
*/
|
|
192
|
+
type:
|
|
193
|
+
string;
|
|
194
|
+
/**
|
|
195
|
+
* The size of the file.
|
|
196
|
+
*/
|
|
197
|
+
size:
|
|
198
|
+
number;
|
|
199
|
+
/**
|
|
200
|
+
* The last modified time of the file.
|
|
201
|
+
*/
|
|
202
|
+
lastModified:
|
|
203
|
+
number;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Serializable version of Error.
|
|
208
|
+
*/
|
|
209
|
+
export interface ErrorLike {
|
|
210
|
+
/**
|
|
211
|
+
* The name of the error.
|
|
212
|
+
*/
|
|
213
|
+
name:
|
|
214
|
+
string;
|
|
215
|
+
/**
|
|
216
|
+
* The message of the error.
|
|
217
|
+
*/
|
|
218
|
+
message:
|
|
219
|
+
string;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Serializable version of File.
|
|
224
|
+
*/
|
|
225
|
+
export interface FileLike {
|
|
226
|
+
/**
|
|
227
|
+
* The name of the file.
|
|
228
|
+
*/
|
|
229
|
+
name:
|
|
230
|
+
string;
|
|
231
|
+
/**
|
|
232
|
+
* The type of the file.
|
|
233
|
+
*/
|
|
234
|
+
type:
|
|
235
|
+
string;
|
|
236
|
+
/**
|
|
237
|
+
* The last modified time of the file.
|
|
238
|
+
*/
|
|
239
|
+
lastModified:
|
|
240
|
+
number;
|
|
241
|
+
/**
|
|
242
|
+
* The size of the file.
|
|
243
|
+
*/
|
|
244
|
+
size:
|
|
245
|
+
number;
|
|
246
|
+
/**
|
|
247
|
+
* The binary data of the file.
|
|
248
|
+
*/
|
|
249
|
+
data:
|
|
250
|
+
ArrayBuffer;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Setup options of `connectSyncAgent`.
|
|
255
|
+
*/
|
|
256
|
+
export interface SyncAgentOptions {
|
|
257
|
+
/**
|
|
258
|
+
* The worker to communicate with.
|
|
259
|
+
*/
|
|
260
|
+
worker:
|
|
261
|
+
Worker |
|
|
262
|
+
URL |
|
|
263
|
+
string;
|
|
264
|
+
/**
|
|
265
|
+
* The length of the buffer to use for communication.
|
|
266
|
+
*/
|
|
267
|
+
bufferLength?:
|
|
268
|
+
number;
|
|
269
|
+
/**
|
|
270
|
+
* The timeout for operations.
|
|
271
|
+
*/
|
|
272
|
+
opTimeout?:
|
|
273
|
+
number;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Options for `zip`.
|
|
278
|
+
*/
|
|
279
|
+
export interface ZipOptions {
|
|
280
|
+
/**
|
|
281
|
+
* Whether to preserve the root directory in the zip file.
|
|
282
|
+
* @defaultValue `true`
|
|
283
|
+
*/
|
|
284
|
+
preserveRoot:
|
|
285
|
+
boolean;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Options for `mkTemp`.
|
|
290
|
+
*/
|
|
291
|
+
export interface TempOptions {
|
|
292
|
+
/**
|
|
293
|
+
* Whether to create a directory.
|
|
294
|
+
* eg: `mktemp -d`
|
|
295
|
+
* @defaultValue `false`
|
|
296
|
+
*/
|
|
297
|
+
isDirectory?:
|
|
298
|
+
boolean;
|
|
299
|
+
/**
|
|
300
|
+
* The basename of the file or directory.
|
|
301
|
+
* eg: `mktemp -t basename.XXX`
|
|
302
|
+
* @defaultValue `tmp`
|
|
303
|
+
*/
|
|
304
|
+
basename?:
|
|
305
|
+
string;
|
|
306
|
+
/**
|
|
307
|
+
* The extension of the file.
|
|
308
|
+
* eg: `mktemp --suffix .txt`
|
|
309
|
+
*/
|
|
310
|
+
extname?:
|
|
311
|
+
string;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Options for `copy`.
|
|
316
|
+
*/
|
|
317
|
+
export interface CopyOptions {
|
|
318
|
+
/**
|
|
319
|
+
* Whether to overwrite the destination file if it already exists.
|
|
320
|
+
* @defaultValue `true`
|
|
321
|
+
*/
|
|
322
|
+
overwrite?:
|
|
323
|
+
boolean;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Result of `downloadFile` when the file is saved to a temporary path.
|
|
328
|
+
*/
|
|
329
|
+
export interface DownloadFileTempResponse {
|
|
330
|
+
/**
|
|
331
|
+
* The temporary path of the downloaded file to be saved.
|
|
332
|
+
*/
|
|
333
|
+
tempFilePath:
|
|
334
|
+
string;
|
|
335
|
+
/**
|
|
336
|
+
* The raw response.
|
|
337
|
+
*/
|
|
338
|
+
rawResponse:
|
|
339
|
+
Response;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Options for `move`.
|
|
344
|
+
*/
|
|
345
|
+
export interface MoveOptions {
|
|
346
|
+
/**
|
|
347
|
+
* Whether to overwrite the destination file if it already exists.
|
|
348
|
+
* @defaultValue `true`
|
|
349
|
+
*/
|
|
350
|
+
overwrite?:
|
|
351
|
+
boolean;
|
|
352
|
+
}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { SEPARATOR,
|
|
28
|
+
basename,
|
|
29
|
+
dirname } from '@std/path/posix';
|
|
30
|
+
import { Err,
|
|
31
|
+
Ok,
|
|
32
|
+
RESULT_VOID,
|
|
33
|
+
type AsyncIOResult,
|
|
34
|
+
type AsyncVoidIOResult } from 'happy-rusty';
|
|
35
|
+
import { ABORT_ERROR,
|
|
36
|
+
CURRENT_DIR,
|
|
37
|
+
NOT_FOUND_ERROR,
|
|
38
|
+
ROOT_DIR } from './constants.ts';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The root directory handle of the file system.
|
|
42
|
+
*/
|
|
43
|
+
let
|
|
44
|
+
fsRoot:
|
|
45
|
+
FileSystemDirectoryHandle;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Retrieves the root directory handle of the file system.
|
|
49
|
+
*
|
|
50
|
+
* @returns A promise that resolves to the
|
|
51
|
+
* `FileSystemDirectoryHandle` of
|
|
52
|
+
* the root directory.
|
|
53
|
+
*/
|
|
54
|
+
async function
|
|
55
|
+
getFsRoot():
|
|
56
|
+
Promise<FileSystemDirectoryHandle> {
|
|
57
|
+
fsRoot ??=
|
|
58
|
+
await navigator.storage.getDirectory();
|
|
59
|
+
return fsRoot;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Checks if the provided path is the root directory path.
|
|
64
|
+
*
|
|
65
|
+
* @param path - The path to check.
|
|
66
|
+
* @returns A boolean indicating whether the path is the root directory path.
|
|
67
|
+
*/
|
|
68
|
+
export function
|
|
69
|
+
isRootPath(
|
|
70
|
+
path:
|
|
71
|
+
string):
|
|
72
|
+
boolean {
|
|
73
|
+
return path === ROOT_DIR;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Checks if the provided directory path is the current directory.
|
|
78
|
+
*
|
|
79
|
+
* @param dirPath - The directory path to check.
|
|
80
|
+
* @returns A boolean indicating whether the directory path is the current directory.
|
|
81
|
+
*/
|
|
82
|
+
export function
|
|
83
|
+
isCurrentDir(
|
|
84
|
+
dirPath:
|
|
85
|
+
string):
|
|
86
|
+
boolean {
|
|
87
|
+
return dirPath === CURRENT_DIR;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Asynchronously obtains a handle to a child directory from the given parent directory handle.
|
|
92
|
+
*
|
|
93
|
+
* @param dirHandle - The handle to the parent directory.
|
|
94
|
+
* @param dirName - The name of the child directory to retrieve.
|
|
95
|
+
* @param options - Optional parameters that specify options such as whether to create the directory if it does not exist.
|
|
96
|
+
* @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemDirectoryHandle` for the child directory.
|
|
97
|
+
*/
|
|
98
|
+
async function
|
|
99
|
+
getChildDirHandle(
|
|
100
|
+
dirHandle:
|
|
101
|
+
FileSystemDirectoryHandle,
|
|
102
|
+
dirName:
|
|
103
|
+
string,
|
|
104
|
+
options?:
|
|
105
|
+
FileSystemGetDirectoryOptions):
|
|
106
|
+
AsyncIOResult<FileSystemDirectoryHandle> {
|
|
107
|
+
try {
|
|
108
|
+
const
|
|
109
|
+
handle =
|
|
110
|
+
await dirHandle.getDirectoryHandle(
|
|
111
|
+
dirName,
|
|
112
|
+
options);
|
|
113
|
+
return Ok(
|
|
114
|
+
handle);
|
|
115
|
+
} catch (
|
|
116
|
+
e) {
|
|
117
|
+
const
|
|
118
|
+
err =
|
|
119
|
+
e as DOMException;
|
|
120
|
+
const
|
|
121
|
+
error =
|
|
122
|
+
new Error(
|
|
123
|
+
`${ err.name }: ${ err.message } ` +
|
|
124
|
+
`When get child directory '${ dirName }' ` +
|
|
125
|
+
`from directory '${ dirHandle.name || ROOT_DIR }'.`);
|
|
126
|
+
error.name =
|
|
127
|
+
err.name;
|
|
128
|
+
return Err(
|
|
129
|
+
error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Retrieves a file handle for a child file within a directory.
|
|
135
|
+
*
|
|
136
|
+
* @param dirHandle - The directory handle to search within.
|
|
137
|
+
* @param fileName - The name of the file to retrieve.
|
|
138
|
+
* @param options - Optional parameters for getting the file handle.
|
|
139
|
+
* @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemFileHandle`.
|
|
140
|
+
*/
|
|
141
|
+
async function
|
|
142
|
+
getChildFileHandle(
|
|
143
|
+
dirHandle:
|
|
144
|
+
FileSystemDirectoryHandle,
|
|
145
|
+
fileName:
|
|
146
|
+
string,
|
|
147
|
+
options?:
|
|
148
|
+
FileSystemGetFileOptions):
|
|
149
|
+
AsyncIOResult<FileSystemFileHandle> {
|
|
150
|
+
try {
|
|
151
|
+
const
|
|
152
|
+
handle =
|
|
153
|
+
await dirHandle.getFileHandle(
|
|
154
|
+
fileName,
|
|
155
|
+
options);
|
|
156
|
+
return Ok(handle);
|
|
157
|
+
} catch (
|
|
158
|
+
e) {
|
|
159
|
+
const
|
|
160
|
+
err =
|
|
161
|
+
e as DOMException;
|
|
162
|
+
const
|
|
163
|
+
error =
|
|
164
|
+
new Error(
|
|
165
|
+
`${ err.name }: ${ err.message } ` +
|
|
166
|
+
`When get child file '${ fileName }' ` +
|
|
167
|
+
`from directory '${ dirHandle.name || ROOT_DIR }'.`);
|
|
168
|
+
error.name =
|
|
169
|
+
err.name;
|
|
170
|
+
return Err(
|
|
171
|
+
error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Retrieves a directory handle given a path.
|
|
177
|
+
*
|
|
178
|
+
* @param dirPath - The path of the directory to retrieve.
|
|
179
|
+
* @param options - Optional parameters for getting the directory handle.
|
|
180
|
+
* @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemDirectoryHandle`.
|
|
181
|
+
*/
|
|
182
|
+
export async function
|
|
183
|
+
getDirHandle(
|
|
184
|
+
dirPath:
|
|
185
|
+
string,
|
|
186
|
+
options?:
|
|
187
|
+
FileSystemGetDirectoryOptions):
|
|
188
|
+
AsyncIOResult<FileSystemDirectoryHandle> {
|
|
189
|
+
// create from root
|
|
190
|
+
let
|
|
191
|
+
dirHandle =
|
|
192
|
+
await getFsRoot();
|
|
193
|
+
if ( isRootPath(
|
|
194
|
+
dirPath) ) {
|
|
195
|
+
// root is already the a handle
|
|
196
|
+
return Ok(
|
|
197
|
+
dirHandle);
|
|
198
|
+
}
|
|
199
|
+
// start with /
|
|
200
|
+
let
|
|
201
|
+
childDirPath =
|
|
202
|
+
dirPath.slice(
|
|
203
|
+
1);
|
|
204
|
+
while ( childDirPath ) {
|
|
205
|
+
let
|
|
206
|
+
dirName =
|
|
207
|
+
'';
|
|
208
|
+
const
|
|
209
|
+
index =
|
|
210
|
+
childDirPath.indexOf(
|
|
211
|
+
SEPARATOR);
|
|
212
|
+
if (index === -1) {
|
|
213
|
+
dirName =
|
|
214
|
+
childDirPath;
|
|
215
|
+
childDirPath =
|
|
216
|
+
'';
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
dirName =
|
|
220
|
+
childDirPath.slice(
|
|
221
|
+
0,
|
|
222
|
+
index);
|
|
223
|
+
childDirPath =
|
|
224
|
+
childDirPath.slice(
|
|
225
|
+
index + 1);
|
|
226
|
+
// skip //
|
|
227
|
+
if ( index === 0 ) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const
|
|
232
|
+
dirHandleRes =
|
|
233
|
+
await getChildDirHandle(
|
|
234
|
+
dirHandle,
|
|
235
|
+
dirName,
|
|
236
|
+
options);
|
|
237
|
+
if ( dirHandleRes.isErr() ) {
|
|
238
|
+
// stop
|
|
239
|
+
return dirHandleRes;
|
|
240
|
+
}
|
|
241
|
+
dirHandle =
|
|
242
|
+
dirHandleRes.unwrap();
|
|
243
|
+
}
|
|
244
|
+
return Ok(
|
|
245
|
+
dirHandle);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Retrieves a file handle given a file path.
|
|
250
|
+
*
|
|
251
|
+
* @param filePath - The path of the file to retrieve.
|
|
252
|
+
* @param options - Optional parameters for getting the file handle.
|
|
253
|
+
* @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemFileHandle`.
|
|
254
|
+
*/
|
|
255
|
+
export async function
|
|
256
|
+
getFileHandle(
|
|
257
|
+
filePath:
|
|
258
|
+
string,
|
|
259
|
+
options?:
|
|
260
|
+
FileSystemGetFileOptions):
|
|
261
|
+
AsyncIOResult<FileSystemFileHandle> {
|
|
262
|
+
const
|
|
263
|
+
isCreate =
|
|
264
|
+
options?.create ?? false;
|
|
265
|
+
const
|
|
266
|
+
dirPath =
|
|
267
|
+
dirname(
|
|
268
|
+
filePath);
|
|
269
|
+
const
|
|
270
|
+
fileName =
|
|
271
|
+
basename(
|
|
272
|
+
filePath);
|
|
273
|
+
const
|
|
274
|
+
dirHandleRes =
|
|
275
|
+
await getDirHandle(
|
|
276
|
+
dirPath,
|
|
277
|
+
{ create:
|
|
278
|
+
isCreate,
|
|
279
|
+
});
|
|
280
|
+
return dirHandleRes.andThenAsync(
|
|
281
|
+
dirHandle => {
|
|
282
|
+
return getChildFileHandle(
|
|
283
|
+
dirHandle,
|
|
284
|
+
fileName,
|
|
285
|
+
{ create:
|
|
286
|
+
isCreate });
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Whether the error is a `NotFoundError`.
|
|
292
|
+
* @param err - The error to check.
|
|
293
|
+
* @returns `true` if the error is a `NotFoundError`, otherwise `false`.
|
|
294
|
+
*/
|
|
295
|
+
export function
|
|
296
|
+
isNotFoundError(
|
|
297
|
+
err:
|
|
298
|
+
Error):
|
|
299
|
+
boolean {
|
|
300
|
+
return err.name === NOT_FOUND_ERROR;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Gets the final result from a list of AsyncVoidIOResult tasks.
|
|
305
|
+
* @param tasks - The list of tasks to get the final result from.
|
|
306
|
+
* @returns The final result from the list of tasks.
|
|
307
|
+
*/
|
|
308
|
+
export async function
|
|
309
|
+
getFinalResult(
|
|
310
|
+
tasks:
|
|
311
|
+
AsyncVoidIOResult[]):
|
|
312
|
+
AsyncVoidIOResult {
|
|
313
|
+
const
|
|
314
|
+
allRes =
|
|
315
|
+
await Promise.all(
|
|
316
|
+
tasks);
|
|
317
|
+
// anyone failed?
|
|
318
|
+
const
|
|
319
|
+
fail =
|
|
320
|
+
allRes.find(
|
|
321
|
+
x => x.isErr());
|
|
322
|
+
return fail ?? RESULT_VOID;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Creates an `AbortError` Error.
|
|
327
|
+
* @returns An `AbortError` Error.
|
|
328
|
+
*/
|
|
329
|
+
export function
|
|
330
|
+
createAbortError():
|
|
331
|
+
Error {
|
|
332
|
+
const
|
|
333
|
+
error =
|
|
334
|
+
new Error();
|
|
335
|
+
error.name =
|
|
336
|
+
ABORT_ERROR;
|
|
337
|
+
return error;
|
|
338
|
+
}
|