@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.
Files changed (114) hide show
  1. package/COPYING +674 -0
  2. package/README.cn.md +301 -0
  3. package/README.md +241 -0
  4. package/dist/main.cjs +1840 -0
  5. package/dist/main.cjs.map +1 -0
  6. package/dist/main.mjs +1751 -0
  7. package/dist/main.mjs.map +1 -0
  8. package/dist/types.d.ts +920 -0
  9. package/dist/types.d.ts.map +1 -0
  10. package/docs/README.md +115 -0
  11. package/docs/classes/SyncMessenger.md +42 -0
  12. package/docs/functions/appendFile.md +29 -0
  13. package/docs/functions/appendFileSync.md +26 -0
  14. package/docs/functions/assertAbsolutePath.md +29 -0
  15. package/docs/functions/assertFileUrl.md +29 -0
  16. package/docs/functions/connectSyncAgent.md +25 -0
  17. package/docs/functions/copy.md +35 -0
  18. package/docs/functions/copySync.md +30 -0
  19. package/docs/functions/createFile.md +27 -0
  20. package/docs/functions/createFileSync.md +25 -0
  21. package/docs/functions/deleteTemp.md +23 -0
  22. package/docs/functions/deleteTempSync.md +19 -0
  23. package/docs/functions/downloadFile.md +58 -0
  24. package/docs/functions/emptyDir.md +28 -0
  25. package/docs/functions/emptyDirSync.md +25 -0
  26. package/docs/functions/exists.md +29 -0
  27. package/docs/functions/existsSync.md +26 -0
  28. package/docs/functions/generateTempPath.md +27 -0
  29. package/docs/functions/getFileDataByHandle.md +27 -0
  30. package/docs/functions/getSyncMessenger.md +22 -0
  31. package/docs/functions/isDirectoryHandle.md +27 -0
  32. package/docs/functions/isFileHandle.md +27 -0
  33. package/docs/functions/isFileHandleLike.md +27 -0
  34. package/docs/functions/isOPFSSupported.md +21 -0
  35. package/docs/functions/isTempPath.md +27 -0
  36. package/docs/functions/mkTemp.md +28 -0
  37. package/docs/functions/mkTempSync.md +25 -0
  38. package/docs/functions/mkdir.md +27 -0
  39. package/docs/functions/mkdirSync.md +25 -0
  40. package/docs/functions/move.md +34 -0
  41. package/docs/functions/moveSync.md +30 -0
  42. package/docs/functions/pruneTemp.md +28 -0
  43. package/docs/functions/pruneTempSync.md +25 -0
  44. package/docs/functions/readBlobFile.md +28 -0
  45. package/docs/functions/readBlobFileSync.md +25 -0
  46. package/docs/functions/readDir.md +28 -0
  47. package/docs/functions/readDirSync.md +26 -0
  48. package/docs/functions/readFile.md +132 -0
  49. package/docs/functions/readFileSync.md +70 -0
  50. package/docs/functions/readJsonFile.md +35 -0
  51. package/docs/functions/readJsonFileSync.md +31 -0
  52. package/docs/functions/readTextFile.md +28 -0
  53. package/docs/functions/readTextFileSync.md +25 -0
  54. package/docs/functions/remove.md +27 -0
  55. package/docs/functions/removeSync.md +25 -0
  56. package/docs/functions/setSyncMessenger.md +26 -0
  57. package/docs/functions/startSyncAgent.md +21 -0
  58. package/docs/functions/stat.md +27 -0
  59. package/docs/functions/statSync.md +25 -0
  60. package/docs/functions/toFileSystemHandleLike.md +27 -0
  61. package/docs/functions/unzip.md +32 -0
  62. package/docs/functions/unzipFromUrl.md +36 -0
  63. package/docs/functions/unzipSync.md +26 -0
  64. package/docs/functions/uploadFile.md +33 -0
  65. package/docs/functions/writeFile.md +32 -0
  66. package/docs/functions/writeFileSync.md +30 -0
  67. package/docs/functions/zip.md +65 -0
  68. package/docs/functions/zipFromUrl.md +63 -0
  69. package/docs/functions/zipSync.md +55 -0
  70. package/docs/interfaces/CopyOptions.md +17 -0
  71. package/docs/interfaces/DownloadFileTempResponse.md +18 -0
  72. package/docs/interfaces/ErrorLike.md +18 -0
  73. package/docs/interfaces/ExistsOptions.md +18 -0
  74. package/docs/interfaces/FileLike.md +21 -0
  75. package/docs/interfaces/FileSystemFileHandleLike.md +25 -0
  76. package/docs/interfaces/FileSystemHandleLike.md +22 -0
  77. package/docs/interfaces/MoveOptions.md +17 -0
  78. package/docs/interfaces/ReadDirEntry.md +18 -0
  79. package/docs/interfaces/ReadDirEntrySync.md +18 -0
  80. package/docs/interfaces/ReadDirOptions.md +17 -0
  81. package/docs/interfaces/ReadOptions.md +17 -0
  82. package/docs/interfaces/SyncAgentOptions.md +19 -0
  83. package/docs/interfaces/TempOptions.md +19 -0
  84. package/docs/interfaces/UploadRequestInit.md +21 -0
  85. package/docs/interfaces/WriteOptions.md +19 -0
  86. package/docs/interfaces/ZipOptions.md +17 -0
  87. package/docs/type-aliases/FileEncoding.md +15 -0
  88. package/docs/type-aliases/FsRequestInit.md +15 -0
  89. package/docs/type-aliases/ReadFileContent.md +15 -0
  90. package/docs/type-aliases/WriteFileContent.md +15 -0
  91. package/docs/type-aliases/WriteSyncFileContent.md +16 -0
  92. package/docs/variables/CURRENT_DIR.md +15 -0
  93. package/docs/variables/NOT_FOUND_ERROR.md +18 -0
  94. package/docs/variables/ROOT_DIR.md +15 -0
  95. package/docs/variables/TMP_DIR.md +15 -0
  96. package/package.json +141 -0
  97. package/src/fs/assertions.ts +63 -0
  98. package/src/fs/constants.ts +63 -0
  99. package/src/fs/defines.ts +352 -0
  100. package/src/fs/helpers.ts +338 -0
  101. package/src/fs/opfs_core.ts +413 -0
  102. package/src/fs/opfs_download.ts +174 -0
  103. package/src/fs/opfs_ext.ts +504 -0
  104. package/src/fs/opfs_tmp.ts +131 -0
  105. package/src/fs/opfs_unzip.ts +168 -0
  106. package/src/fs/opfs_upload.ts +126 -0
  107. package/src/fs/opfs_zip.ts +314 -0
  108. package/src/fs/support.ts +36 -0
  109. package/src/fs/utils.ts +176 -0
  110. package/src/mod.ts +41 -0
  111. package/src/worker/helpers.ts +168 -0
  112. package/src/worker/opfs_worker.ts +298 -0
  113. package/src/worker/opfs_worker_adapter.ts +666 -0
  114. 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
+ }