@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,168 @@
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 { fetchT } from '@happy-ts/fetch-t';
28
+ import { join,
29
+ SEPARATOR } from '@std/path/posix';
30
+ import * as fflate from 'fflate/browser';
31
+ import { Err,
32
+ type AsyncVoidIOResult,
33
+ type VoidIOResult } from 'happy-rusty';
34
+ import { Future } from 'tiny-future';
35
+ import { assertAbsolutePath,
36
+ assertFileUrl } from './assertions.ts';
37
+ import type { FsRequestInit } from './defines.ts';
38
+ import { getFinalResult } from './helpers.ts';
39
+ import { readFile,
40
+ writeFile } from './opfs_core.ts';
41
+
42
+ /**
43
+ * Unzip a buffer then write to the target path.
44
+ * @param buffer - Zipped ArrayBuffer.
45
+ * @param targetPath - Target directory path.
46
+ */
47
+ async function
48
+ unzipBufferToTarget(
49
+ buffer:
50
+ ArrayBuffer,
51
+ targetPath:
52
+ string):
53
+ AsyncVoidIOResult {
54
+ const
55
+ data =
56
+ new Uint8Array(
57
+ buffer);
58
+ const
59
+ future =
60
+ new Future<VoidIOResult>();
61
+ fflate.unzip(
62
+ data,
63
+ async (err, unzipped) => {
64
+ if (err) {
65
+ future.resolve(
66
+ Err(
67
+ err));
68
+ return;
69
+ }
70
+ const
71
+ tasks:
72
+ AsyncVoidIOResult[] =
73
+ [];
74
+ for ( const path in unzipped ) {
75
+ // ignore directory
76
+ if ( path.at(
77
+ -1) !== SEPARATOR ) {
78
+ tasks.push(
79
+ writeFile(
80
+ join(
81
+ targetPath,
82
+ path),
83
+ unzipped[
84
+ path]));
85
+ }
86
+ }
87
+ future.resolve(
88
+ getFinalResult(
89
+ tasks));
90
+ });
91
+ return await future.promise;
92
+ }
93
+
94
+ /**
95
+ * Unzip a zip file to a directory.
96
+ * Equivalent to `unzip -o <zipFilePath> -d <targetPath>
97
+ *
98
+ * Usees [fflate](https://github.com/101arrowz/fflate) as the unzip backend.
99
+ * @param zipFilePath - Zip file path.
100
+ * @param targetPath - The directory to unzip to.
101
+ * @returns A promise that resolves to an `AsyncIOResult`
102
+ * indicating whether the zip file was successfully unzipped.
103
+ */
104
+ export
105
+ async function
106
+ unzip(
107
+ zipFilePath:
108
+ string,
109
+ targetPath:
110
+ string):
111
+ AsyncVoidIOResult {
112
+ assertAbsolutePath(
113
+ targetPath);
114
+ const
115
+ fileRes =
116
+ await readFile(
117
+ zipFilePath);
118
+ return fileRes.andThenAsync(
119
+ buffer => {
120
+ return unzipBufferToTarget(
121
+ buffer,
122
+ targetPath);
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Unzip a remote zip file to a directory.
128
+ * Equivalent to `unzip -o <zipFilePath> -d <targetPath>
129
+ *
130
+ * Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.
131
+ * @param zipFileUrl - Zip file url.
132
+ * @param targetPath - The directory to unzip to.
133
+ * @param requestInit - Optional request initialization parameters.
134
+ * @returns A promise that resolves to an `AsyncIOResult`
135
+ * indicating whether the zip file was successfully unzipped.
136
+ */
137
+ export
138
+ async function
139
+ unzipFromUrl(
140
+ zipFileUrl:
141
+ string,
142
+ targetPath:
143
+ string,
144
+ requestInit?:
145
+ FsRequestInit):
146
+ AsyncVoidIOResult {
147
+ assertFileUrl(
148
+ zipFileUrl);
149
+ assertAbsolutePath(
150
+ targetPath);
151
+ const
152
+ fetchRes =
153
+ await fetchT(
154
+ zipFileUrl,
155
+ { redirect:
156
+ 'follow',
157
+ ...requestInit,
158
+ responseType:
159
+ 'arraybuffer',
160
+ abortable:
161
+ false });
162
+ return fetchRes.andThenAsync(
163
+ buffer => {
164
+ return unzipBufferToTarget(
165
+ buffer,
166
+ targetPath);
167
+ });
168
+ }
@@ -0,0 +1,126 @@
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 { fetchT,
28
+ type FetchResponse,
29
+ type FetchTask } from '@happy-ts/fetch-t';
30
+ import { basename } from '@std/path/posix';
31
+ import { Err } from 'happy-rusty';
32
+ import { assertFileUrl } from './assertions.ts';
33
+ import type { UploadRequestInit } from './defines.ts';
34
+ import { createAbortError } from './helpers.ts';
35
+ import { readBlobFile } from './opfs_ext.ts';
36
+
37
+ /**
38
+ * Uploads a file from the specified path to a URL.
39
+ *
40
+ * @param filePath - The path of the file to upload.
41
+ * @param fileUrl - The URL where the file will be uploaded.
42
+ * @param requestInit - Optional request initialization parameters.
43
+ * @returns A promise that resolves to an `AsyncIOResult`
44
+ * indicating whether the file was successfully uploaded.
45
+ */
46
+ export function
47
+ uploadFile(
48
+ filePath:
49
+ string,
50
+ fileUrl:
51
+ string,
52
+ requestInit?:
53
+ UploadRequestInit):
54
+ FetchTask<Response> {
55
+ type T =
56
+ Response;
57
+ let
58
+ aborted:
59
+ boolean;
60
+ let
61
+ fetchTask:
62
+ FetchTask<T>;
63
+ assertFileUrl(
64
+ fileUrl);
65
+ aborted =
66
+ false;
67
+ const
68
+ response =
69
+ ( async ():
70
+ FetchResponse<Response> => {
71
+ const
72
+ fileRes =
73
+ await readBlobFile(
74
+ filePath);
75
+ return fileRes.andThenAsync(
76
+ async file => {
77
+ // maybe aborted
78
+ if ( aborted ) {
79
+ return Err(
80
+ createAbortError());
81
+ }
82
+ const
83
+ { // default file name
84
+ filename = basename(filePath),
85
+ ...rest } =
86
+ requestInit ??
87
+ {};
88
+ const
89
+ formData =
90
+ new FormData();
91
+ formData.append(
92
+ filename,
93
+ file,
94
+ filename);
95
+ fetchTask =
96
+ fetchT(
97
+ fileUrl,
98
+ { method:
99
+ 'POST',
100
+ ...rest,
101
+ abortable:
102
+ true,
103
+ body:
104
+ formData });
105
+ return fetchTask.response;
106
+ });
107
+ })();
108
+ return {
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
+ abort(reason?: any):
111
+ void {
112
+ aborted =
113
+ true;
114
+ fetchTask?.abort(
115
+ reason);
116
+ },
117
+ get aborted():
118
+ boolean {
119
+ return aborted;
120
+ },
121
+ get response():
122
+ FetchResponse<Response> {
123
+ return response;
124
+ },
125
+ };
126
+ }
@@ -0,0 +1,314 @@
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 { fetchT } from '@happy-ts/fetch-t';
28
+ import { basename,
29
+ join } from '@std/path/posix';
30
+ import * as fflate from 'fflate/browser';
31
+ import { Err,
32
+ Ok,
33
+ type AsyncIOResult,
34
+ type AsyncVoidIOResult,
35
+ type IOResult } from 'happy-rusty';
36
+ import { Future } from 'tiny-future';
37
+ import { assertAbsolutePath,
38
+ assertFileUrl } from './assertions.ts';
39
+ import type { FsRequestInit,
40
+ ZipOptions } from './defines.ts';
41
+ import { readDir,
42
+ stat,
43
+ writeFile } from './opfs_core.ts';
44
+ import { getFileDataByHandle,
45
+ isFileHandle } from './utils.ts';
46
+
47
+ /**
48
+ * Zip a zippable data then write to the target path.
49
+ * @param zippable - Zippable data.
50
+ * @param zipFilePath - Target zip file path.
51
+ */
52
+ async function
53
+ zipTo<T>(
54
+ zippable:
55
+ fflate.AsyncZippable,
56
+ zipFilePath?:
57
+ string):
58
+ AsyncIOResult<T> {
59
+ const
60
+ future =
61
+ new Future<IOResult<T>>();
62
+ fflate.zip(
63
+ zippable,
64
+ { consume:
65
+ true },
66
+ async (err,
67
+ u8a) => {
68
+ if ( err ) {
69
+ future.resolve(
70
+ Err(
71
+ err));
72
+ return;
73
+ }
74
+ // whether to write to file
75
+ if ( zipFilePath ) {
76
+ const
77
+ res =
78
+ await writeFile(
79
+ zipFilePath,
80
+ u8a);
81
+ future.resolve(
82
+ res as IOResult<T>);
83
+ }
84
+ else {
85
+ future.resolve(
86
+ Ok( u8a as T ));
87
+ }
88
+ });
89
+ return await future.promise;
90
+ }
91
+
92
+ /**
93
+ * Zip a file or directory and write to a zip file.
94
+ * Equivalent to `zip -r <zipFilePath> <targetPath>`.
95
+ *
96
+ * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
97
+ * @param sourcePath - The path to be zipped.
98
+ * @param zipFilePath - The path to the zip file.
99
+ * @param options - Options of zip.
100
+ * @returns A promise that resolves to an `AsyncIOResult`
101
+ * indicating whether the source was successfully zipped.
102
+ */
103
+ export
104
+ async function
105
+ zip(
106
+ sourcePath:
107
+ string,
108
+ zipFilePath:
109
+ string,
110
+ options?:
111
+ ZipOptions):
112
+ AsyncVoidIOResult;
113
+
114
+ /**
115
+ * Zip a file or directory and return the zip file data.
116
+ * Equivalent to `zip -r <zipFilePath> <targetPath>`.
117
+ *
118
+ * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
119
+ * @param sourcePath - The path to be zipped.
120
+ * @param options - Options of zip.
121
+ * @returns A promise that resolves to an `AsyncIOResult` indicating
122
+ * whether the source was successfully zipped.
123
+ */
124
+ export
125
+ async function
126
+ zip(
127
+ sourcePath:
128
+ string,
129
+ options?:
130
+ ZipOptions):
131
+ AsyncIOResult<Uint8Array>;
132
+ export
133
+ async function
134
+ zip<T>(
135
+ sourcePath:
136
+ string,
137
+ zipFilePath?:
138
+ string |
139
+ ZipOptions,
140
+ options?:
141
+ ZipOptions):
142
+ AsyncIOResult<T> {
143
+ if ( typeof zipFilePath === 'string' ) {
144
+ assertAbsolutePath(
145
+ zipFilePath);
146
+ }
147
+ else {
148
+ options =
149
+ zipFilePath;
150
+ zipFilePath =
151
+ undefined;
152
+ }
153
+ const
154
+ statRes =
155
+ await stat(
156
+ sourcePath);
157
+ return statRes.andThenAsync(
158
+ async handle => {
159
+ const
160
+ sourceName =
161
+ basename(
162
+ sourcePath);
163
+ const
164
+ zippable:
165
+ fflate.AsyncZippable =
166
+ {};
167
+ if ( isFileHandle(
168
+ handle) ) {
169
+ // file
170
+ const
171
+ data =
172
+ await getFileDataByHandle(
173
+ handle);
174
+ zippable[
175
+ sourceName] =
176
+ data;
177
+ }
178
+ else {
179
+ // directory
180
+ const
181
+ readDirRes =
182
+ await readDir(
183
+ sourcePath,
184
+ { recursive:
185
+ true });
186
+ if ( readDirRes.isErr() ) {
187
+ return readDirRes.asErr();
188
+ }
189
+ // default to preserve root
190
+ const
191
+ preserveRoot =
192
+ options?.preserveRoot ??
193
+ true;
194
+ for await ( const { path,
195
+ handle } of readDirRes.unwrap()) {
196
+ // path
197
+ if ( isFileHandle(
198
+ handle) ) {
199
+ const
200
+ entryName =
201
+ preserveRoot ?
202
+ join(
203
+ sourceName,
204
+ path) :
205
+ path;
206
+ const
207
+ data =
208
+ await getFileDataByHandle(
209
+ handle);
210
+ zippable[
211
+ entryName] =
212
+ data;
213
+ }
214
+ }
215
+ }
216
+ return zipTo(
217
+ zippable,
218
+ zipFilePath);
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Zip a remote file and write to a zip file.
224
+ *
225
+ * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
226
+ * @param sourceUrl - The url to be zipped.
227
+ * @param zipFilePath - The path to the zip file.
228
+ * @param requestInit - Optional request initialization parameters.
229
+ * @returns A promise that resolves to an `AsyncIOResult`
230
+ * indicating whether the source was successfully zipped.
231
+ */
232
+ export
233
+ async function
234
+ zipFromUrl(
235
+ sourceUrl:
236
+ string,
237
+ zipFilePath:
238
+ string,
239
+ requestInit?:
240
+ FsRequestInit):
241
+ AsyncVoidIOResult;
242
+
243
+ /**
244
+ * Zip a remote file and return the zip file data.
245
+ *
246
+ * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
247
+ * @param sourceUrl - The url to be zipped.
248
+ * @param requestInit - Optional request initialization parameters.
249
+ * @returns A promise that resolves to an `AsyncIOResult` indicating
250
+ * whether the source was successfully zipped.
251
+ */
252
+ export
253
+ async function
254
+ zipFromUrl(
255
+ sourceUrl:
256
+ string,
257
+ requestInit?:
258
+ FsRequestInit):
259
+ AsyncIOResult<Uint8Array>;
260
+
261
+ export
262
+ async function
263
+ zipFromUrl<T>(
264
+ sourceUrl:
265
+ string,
266
+ zipFilePath?:
267
+ string |
268
+ FsRequestInit,
269
+ requestInit?:
270
+ FsRequestInit):
271
+ AsyncIOResult<T> {
272
+ assertFileUrl(
273
+ sourceUrl);
274
+ if ( typeof zipFilePath === 'string' ) {
275
+ assertAbsolutePath(
276
+ zipFilePath);
277
+ }
278
+ else {
279
+ requestInit =
280
+ zipFilePath;
281
+ zipFilePath =
282
+ undefined;
283
+ }
284
+ const
285
+ fetchRes =
286
+ await fetchT(
287
+ sourceUrl,
288
+ { redirect:
289
+ 'follow',
290
+ ...requestInit,
291
+ responseType:
292
+ 'arraybuffer',
293
+ abortable:
294
+ false,
295
+ });
296
+ return fetchRes.andThenAsync(
297
+ buffer => {
298
+ const
299
+ sourceName =
300
+ basename(
301
+ sourceUrl);
302
+ const
303
+ zippable:
304
+ fflate.AsyncZippable =
305
+ {};
306
+ zippable[
307
+ sourceName] =
308
+ new Uint8Array(
309
+ buffer);
310
+ return zipTo(
311
+ zippable,
312
+ zipFilePath);
313
+ });
314
+ }
@@ -0,0 +1,36 @@
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
+ /**
28
+ * Checks if the Origin Private File System (OPFS) is supported in the current environment.
29
+ *
30
+ * @returns A boolean indicating whether OPFS is supported.
31
+ */
32
+ export function
33
+ isOPFSSupported():
34
+ boolean {
35
+ return typeof navigator?.storage?.getDirectory === 'function';
36
+ }