opfs-worker 0.2.1 → 0.2.3
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/README.md +260 -27
- package/dist/assets/worker-CRHhlrlS.js.map +1 -0
- package/dist/index.cjs +429 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1196 -11
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +169 -103
- package/dist/raw.js.map +1 -1
- package/dist/worker.d.ts +36 -8
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-ChfzBM-o.js.map +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/encoder.js +0 -83
- package/dist/utils/errors.js +0 -77
- package/dist/utils/helpers.js +0 -246
- package/dist/worker.js +0 -818
package/dist/raw.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { expose as
|
|
2
|
-
import { d as
|
|
3
|
-
class
|
|
1
|
+
import { expose as v } from "comlink";
|
|
2
|
+
import { d as I, O as o, b as f, s as u, P as g, i as p, o as S, F as d, w as E, j as T, e as m, f as y, k as M, r as H, n as F, l as P } from "./helpers-Co-qCBmA.js";
|
|
3
|
+
class $ {
|
|
4
4
|
/** Root directory handle for the file system */
|
|
5
5
|
root = null;
|
|
6
6
|
/** Watch event callback */
|
|
@@ -13,19 +13,23 @@ class N {
|
|
|
13
13
|
watchInterval = 1e3;
|
|
14
14
|
/** Flag to avoid concurrent scans */
|
|
15
15
|
scanning = !1;
|
|
16
|
+
/** Promise to prevent concurrent mount operations */
|
|
17
|
+
mountingPromise = null;
|
|
16
18
|
/**
|
|
17
19
|
* Creates a new OPFSFileSystem instance
|
|
18
20
|
*
|
|
21
|
+
* @param watchCallback - Optional callback for file change events
|
|
22
|
+
* @param watchOptions - Optional configuration for watching
|
|
19
23
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
20
24
|
*/
|
|
21
|
-
constructor() {
|
|
22
|
-
|
|
25
|
+
constructor(t, e) {
|
|
26
|
+
I(), t && (this.watchCallback = t, e?.watchInterval && (this.watchInterval = e.watchInterval)), this.mount("/");
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* Initialize the file system within a given directory
|
|
26
30
|
*
|
|
27
31
|
* This method sets up the root directory for all subsequent operations.
|
|
28
|
-
*
|
|
32
|
+
* If no root is specified, it will use the OPFS root directory.
|
|
29
33
|
*
|
|
30
34
|
* @param root - The root path for the file system (default: '/')
|
|
31
35
|
* @returns Promise that resolves to true if initialization was successful
|
|
@@ -34,15 +38,52 @@ class N {
|
|
|
34
38
|
* @example
|
|
35
39
|
* ```typescript
|
|
36
40
|
* const fs = new OPFSFileSystem();
|
|
37
|
-
*
|
|
41
|
+
*
|
|
42
|
+
* // Use OPFS root (default)
|
|
43
|
+
* await fs.mount();
|
|
44
|
+
*
|
|
45
|
+
* // Use custom directory
|
|
46
|
+
* await fs.mount('/my-app');
|
|
38
47
|
* ```
|
|
39
48
|
*/
|
|
40
|
-
async mount(t = "/"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
async mount(t = "/") {
|
|
50
|
+
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (e, i) => {
|
|
51
|
+
this.root = null;
|
|
52
|
+
try {
|
|
53
|
+
const r = await navigator.storage.getDirectory();
|
|
54
|
+
t === "/" ? this.root = r : this.root = await this.getDirectoryHandle(t, !0, r), e(!0);
|
|
55
|
+
} catch (r) {
|
|
56
|
+
console.error(r), i(new o("Failed to initialize OPFS", "INIT_FAILED"));
|
|
57
|
+
} finally {
|
|
58
|
+
this.mountingPromise = null;
|
|
59
|
+
}
|
|
60
|
+
}), this.mountingPromise;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Set the watch callback for file change events
|
|
64
|
+
*
|
|
65
|
+
* @param callback - The callback function to invoke when files change
|
|
66
|
+
* @param options - Optional configuration for watching
|
|
67
|
+
*/
|
|
68
|
+
setWatchCallback(t, e) {
|
|
69
|
+
this.watchCallback = t, e?.watchInterval && (this.watchInterval = e.watchInterval);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Automatically mount the OPFS root if not already mounted
|
|
73
|
+
*
|
|
74
|
+
* This method is called internally when file operations are performed
|
|
75
|
+
* without explicitly mounting first.
|
|
76
|
+
*
|
|
77
|
+
* @returns Promise that resolves when auto-mount is complete
|
|
78
|
+
* @throws {OPFSError} If auto-mount fails
|
|
79
|
+
*/
|
|
80
|
+
async ensureMounted() {
|
|
81
|
+
if (!this.root) {
|
|
82
|
+
if (this.mountingPromise) {
|
|
83
|
+
await this.mountingPromise;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
throw new o("OPFS not mounted", "NOT_MOUNTED");
|
|
46
87
|
}
|
|
47
88
|
}
|
|
48
89
|
/**
|
|
@@ -63,14 +104,14 @@ class N {
|
|
|
63
104
|
* const docsDir2 = await fs.getDirectoryHandle(['users', 'john', 'documents'], true);
|
|
64
105
|
* ```
|
|
65
106
|
*/
|
|
66
|
-
async getDirectoryHandle(t, e = !1,
|
|
67
|
-
if (!
|
|
107
|
+
async getDirectoryHandle(t, e = !1, i = this.root) {
|
|
108
|
+
if (!i)
|
|
68
109
|
throw new f();
|
|
69
|
-
const r = Array.isArray(t) ? t :
|
|
70
|
-
let
|
|
110
|
+
const r = Array.isArray(t) ? t : u(t);
|
|
111
|
+
let a = i;
|
|
71
112
|
for (const n of r)
|
|
72
|
-
|
|
73
|
-
return
|
|
113
|
+
a = await a.getDirectoryHandle(n, { create: e });
|
|
114
|
+
return a;
|
|
74
115
|
}
|
|
75
116
|
/**
|
|
76
117
|
* Get a file handle from a path
|
|
@@ -91,14 +132,14 @@ class N {
|
|
|
91
132
|
* const fileHandle2 = await fs.getFileHandle(['config', 'settings.json'], true);
|
|
92
133
|
* ```
|
|
93
134
|
*/
|
|
94
|
-
async getFileHandle(t, e = !1,
|
|
95
|
-
if (!
|
|
135
|
+
async getFileHandle(t, e = !1, i = this.root) {
|
|
136
|
+
if (!i)
|
|
96
137
|
throw new f();
|
|
97
|
-
const r =
|
|
138
|
+
const r = u(t);
|
|
98
139
|
if (r.length === 0)
|
|
99
|
-
throw new
|
|
100
|
-
const
|
|
101
|
-
return (await this.getDirectoryHandle(r, e,
|
|
140
|
+
throw new g("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
141
|
+
const a = r.pop();
|
|
142
|
+
return (await this.getDirectoryHandle(r, e, i)).getFileHandle(a, { create: e });
|
|
102
143
|
}
|
|
103
144
|
/**
|
|
104
145
|
* Recursively list all files and directories with their stats
|
|
@@ -138,13 +179,13 @@ class N {
|
|
|
138
179
|
* ```
|
|
139
180
|
*/
|
|
140
181
|
async index(t) {
|
|
141
|
-
const e = /* @__PURE__ */ new Map(),
|
|
142
|
-
const
|
|
143
|
-
for (const n of
|
|
182
|
+
const e = /* @__PURE__ */ new Map(), i = async (r) => {
|
|
183
|
+
const a = await this.readdir(r, { withFileTypes: !0 });
|
|
184
|
+
for (const n of a) {
|
|
144
185
|
const s = `${r === "/" ? "" : r}/${n.name}`;
|
|
145
186
|
try {
|
|
146
187
|
const c = await this.stat(s, t);
|
|
147
|
-
e.set(s, c), c.isDirectory && await
|
|
188
|
+
e.set(s, c), c.isDirectory && await i(s);
|
|
148
189
|
} catch (c) {
|
|
149
190
|
console.warn(`Skipping broken entry: ${s}`, c);
|
|
150
191
|
}
|
|
@@ -157,14 +198,15 @@ class N {
|
|
|
157
198
|
ctime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
158
199
|
isFile: !1,
|
|
159
200
|
isDirectory: !0
|
|
160
|
-
}), await
|
|
201
|
+
}), await i("/"), e;
|
|
161
202
|
}
|
|
162
203
|
async readFile(t, e = "utf-8") {
|
|
204
|
+
await this.ensureMounted();
|
|
163
205
|
try {
|
|
164
|
-
const
|
|
206
|
+
const i = await this.getFileHandle(t, !1), r = await p(i);
|
|
165
207
|
return e === "binary" ? r : S(r, e);
|
|
166
|
-
} catch (
|
|
167
|
-
throw console.error(
|
|
208
|
+
} catch (i) {
|
|
209
|
+
throw console.error(i), new d(t);
|
|
168
210
|
}
|
|
169
211
|
}
|
|
170
212
|
/**
|
|
@@ -192,9 +234,10 @@ class N {
|
|
|
192
234
|
* await fs.writeFile('/data/utf16.txt', 'Hello World', 'utf-16le');
|
|
193
235
|
* ```
|
|
194
236
|
*/
|
|
195
|
-
async writeFile(t, e,
|
|
237
|
+
async writeFile(t, e, i) {
|
|
238
|
+
await this.ensureMounted();
|
|
196
239
|
const r = await this.getFileHandle(t, !0);
|
|
197
|
-
await
|
|
240
|
+
await E(r, e, i, { truncate: !0 });
|
|
198
241
|
}
|
|
199
242
|
/**
|
|
200
243
|
* Append data to a file
|
|
@@ -218,9 +261,10 @@ class N {
|
|
|
218
261
|
* await fs.appendFile('/data/binary.dat', additionalData);
|
|
219
262
|
* ```
|
|
220
263
|
*/
|
|
221
|
-
async appendFile(t, e,
|
|
264
|
+
async appendFile(t, e, i) {
|
|
265
|
+
await this.ensureMounted();
|
|
222
266
|
const r = await this.getFileHandle(t, !0);
|
|
223
|
-
await
|
|
267
|
+
await E(r, e, i, { append: !0 });
|
|
224
268
|
}
|
|
225
269
|
/**
|
|
226
270
|
* Create a directory
|
|
@@ -244,14 +288,14 @@ class N {
|
|
|
244
288
|
* ```
|
|
245
289
|
*/
|
|
246
290
|
async mkdir(t, e) {
|
|
247
|
-
if (!this.root)
|
|
291
|
+
if (await this.ensureMounted(), !this.root)
|
|
248
292
|
throw new f();
|
|
249
|
-
const
|
|
250
|
-
let
|
|
293
|
+
const i = e?.recursive ?? !1, r = u(t);
|
|
294
|
+
let a = this.root;
|
|
251
295
|
for (let n = 0; n < r.length; n++) {
|
|
252
296
|
const s = r[n];
|
|
253
297
|
try {
|
|
254
|
-
|
|
298
|
+
a = await a.getDirectoryHandle(s, { create: i || n === r.length - 1 });
|
|
255
299
|
} catch (c) {
|
|
256
300
|
throw c.name === "NotFoundError" ? new o(
|
|
257
301
|
`Parent directory does not exist: ${T(r.slice(0, n + 1))}`,
|
|
@@ -290,9 +334,18 @@ class N {
|
|
|
290
334
|
* ```
|
|
291
335
|
*/
|
|
292
336
|
async stat(t, e) {
|
|
293
|
-
|
|
337
|
+
if (await this.ensureMounted(), t === "/")
|
|
338
|
+
return {
|
|
339
|
+
kind: "directory",
|
|
340
|
+
size: 0,
|
|
341
|
+
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
342
|
+
ctime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
343
|
+
isFile: !1,
|
|
344
|
+
isDirectory: !0
|
|
345
|
+
};
|
|
346
|
+
const i = m(t), r = await this.getDirectoryHandle(y(t), !1), a = e?.includeHash ?? !1, n = e?.hashAlgorithm ?? "SHA-1";
|
|
294
347
|
try {
|
|
295
|
-
const c = await (await r.getFileHandle(
|
|
348
|
+
const c = await (await r.getFileHandle(i, { create: !1 })).getFile(), l = {
|
|
296
349
|
kind: "file",
|
|
297
350
|
size: c.size,
|
|
298
351
|
mtime: new Date(c.lastModified).toISOString(),
|
|
@@ -300,9 +353,9 @@ class N {
|
|
|
300
353
|
isFile: !0,
|
|
301
354
|
isDirectory: !1
|
|
302
355
|
};
|
|
303
|
-
if (
|
|
356
|
+
if (a)
|
|
304
357
|
try {
|
|
305
|
-
const h = new Uint8Array(await c.arrayBuffer()), w = await
|
|
358
|
+
const h = new Uint8Array(await c.arrayBuffer()), w = await M(h, n);
|
|
306
359
|
l.hash = w;
|
|
307
360
|
} catch (h) {
|
|
308
361
|
console.warn(`Failed to calculate hash for ${t}:`, h);
|
|
@@ -313,7 +366,7 @@ class N {
|
|
|
313
366
|
throw new o("Failed to stat (file)", "STAT_FAILED");
|
|
314
367
|
}
|
|
315
368
|
try {
|
|
316
|
-
return await r.getDirectoryHandle(
|
|
369
|
+
return await r.getDirectoryHandle(i, { create: !1 }), {
|
|
317
370
|
kind: "directory",
|
|
318
371
|
size: 0,
|
|
319
372
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
@@ -326,24 +379,25 @@ class N {
|
|
|
326
379
|
}
|
|
327
380
|
}
|
|
328
381
|
async readdir(t, e) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
382
|
+
await this.ensureMounted();
|
|
383
|
+
const i = e?.withFileTypes ?? !1, r = await this.getDirectoryHandle(t, !1);
|
|
384
|
+
if (i) {
|
|
385
|
+
const a = [];
|
|
332
386
|
for await (const [n, s] of r.entries()) {
|
|
333
387
|
const c = s.kind === "file";
|
|
334
|
-
|
|
388
|
+
a.push({
|
|
335
389
|
name: n,
|
|
336
390
|
kind: s.kind,
|
|
337
391
|
isFile: c,
|
|
338
392
|
isDirectory: !c
|
|
339
393
|
});
|
|
340
394
|
}
|
|
341
|
-
return
|
|
395
|
+
return a;
|
|
342
396
|
} else {
|
|
343
|
-
const
|
|
397
|
+
const a = [];
|
|
344
398
|
for await (const [n] of r.entries())
|
|
345
|
-
|
|
346
|
-
return
|
|
399
|
+
a.push(n);
|
|
400
|
+
return a;
|
|
347
401
|
}
|
|
348
402
|
}
|
|
349
403
|
/**
|
|
@@ -361,23 +415,25 @@ class N {
|
|
|
361
415
|
* ```
|
|
362
416
|
*/
|
|
363
417
|
async exists(t) {
|
|
364
|
-
|
|
365
|
-
|
|
418
|
+
if (await this.ensureMounted(), t === "/")
|
|
419
|
+
return !0;
|
|
420
|
+
const e = m(t);
|
|
421
|
+
let i = null;
|
|
366
422
|
try {
|
|
367
|
-
|
|
423
|
+
i = await this.getDirectoryHandle(y(t), !1);
|
|
368
424
|
} catch (r) {
|
|
369
|
-
throw (r.name === "NotFoundError" || r.name === "TypeMismatchError") && (
|
|
425
|
+
throw (r.name === "NotFoundError" || r.name === "TypeMismatchError") && (i = null), r;
|
|
370
426
|
}
|
|
371
|
-
if (!
|
|
427
|
+
if (!i || !e)
|
|
372
428
|
return !1;
|
|
373
429
|
try {
|
|
374
|
-
return await
|
|
430
|
+
return await i.getFileHandle(e, { create: !1 }), !0;
|
|
375
431
|
} catch (r) {
|
|
376
432
|
if (r.name !== "NotFoundError" && r.name !== "TypeMismatchError")
|
|
377
433
|
throw r;
|
|
378
434
|
}
|
|
379
435
|
try {
|
|
380
|
-
return await
|
|
436
|
+
return await i.getDirectoryHandle(e, { create: !1 }), !0;
|
|
381
437
|
} catch (r) {
|
|
382
438
|
if (r.name !== "NotFoundError" && r.name !== "TypeMismatchError")
|
|
383
439
|
throw r;
|
|
@@ -404,10 +460,11 @@ class N {
|
|
|
404
460
|
* ```
|
|
405
461
|
*/
|
|
406
462
|
async clear(t = "/") {
|
|
463
|
+
await this.ensureMounted();
|
|
407
464
|
try {
|
|
408
465
|
const e = await this.readdir(t, { withFileTypes: !0 });
|
|
409
|
-
for (const
|
|
410
|
-
const r = `${t === "/" ? "" : t}/${
|
|
466
|
+
for (const i of e) {
|
|
467
|
+
const r = `${t === "/" ? "" : t}/${i.name}`;
|
|
411
468
|
await this.remove(r, { recursive: !0 });
|
|
412
469
|
}
|
|
413
470
|
} catch (e) {
|
|
@@ -439,17 +496,21 @@ class N {
|
|
|
439
496
|
* ```
|
|
440
497
|
*/
|
|
441
498
|
async remove(t, e) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
499
|
+
await this.ensureMounted();
|
|
500
|
+
const i = e?.recursive ?? !1, r = e?.force ?? !1;
|
|
501
|
+
if (t === "/")
|
|
502
|
+
throw new o("Cannot remove root directory", "EROOT");
|
|
503
|
+
const a = m(t);
|
|
504
|
+
if (!a)
|
|
505
|
+
throw new g("Invalid path", t);
|
|
506
|
+
const n = await this.getDirectoryHandle(y(t), !1);
|
|
446
507
|
try {
|
|
447
|
-
await n.removeEntry(
|
|
508
|
+
await n.removeEntry(a, { recursive: i });
|
|
448
509
|
} catch (s) {
|
|
449
510
|
if (s.name === "NotFoundError") {
|
|
450
511
|
if (!r)
|
|
451
512
|
throw new o(`No such file or directory: ${t}`, "ENOENT");
|
|
452
|
-
} else throw s.name === "InvalidModificationError" ? new o(`Directory not empty: ${t}. Use recursive option to force removal.`, "ENOTEMPTY") : s.name === "TypeMismatchError" && !
|
|
513
|
+
} else throw s.name === "InvalidModificationError" ? new o(`Directory not empty: ${t}. Use recursive option to force removal.`, "ENOTEMPTY") : s.name === "TypeMismatchError" && !i ? new o(`Cannot remove directory without recursive option: ${t}`, "EISDIR") : new o(`Failed to remove path: ${t}`, "RM_FAILED");
|
|
453
514
|
}
|
|
454
515
|
}
|
|
455
516
|
/**
|
|
@@ -471,8 +532,9 @@ class N {
|
|
|
471
532
|
* ```
|
|
472
533
|
*/
|
|
473
534
|
async realpath(t) {
|
|
535
|
+
await this.ensureMounted();
|
|
474
536
|
try {
|
|
475
|
-
const e =
|
|
537
|
+
const e = H(t);
|
|
476
538
|
if (!await this.exists(e))
|
|
477
539
|
throw new d(e);
|
|
478
540
|
return e;
|
|
@@ -497,12 +559,13 @@ class N {
|
|
|
497
559
|
* ```
|
|
498
560
|
*/
|
|
499
561
|
async rename(t, e) {
|
|
562
|
+
await this.ensureMounted();
|
|
500
563
|
try {
|
|
501
564
|
if (!await this.exists(t))
|
|
502
565
|
throw new d(t);
|
|
503
566
|
await this.copy(t, e, { recursive: !0 }), await this.remove(t, { recursive: !0 });
|
|
504
|
-
} catch (
|
|
505
|
-
throw
|
|
567
|
+
} catch (i) {
|
|
568
|
+
throw i instanceof o ? i : new o(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED");
|
|
506
569
|
}
|
|
507
570
|
}
|
|
508
571
|
/**
|
|
@@ -521,21 +584,22 @@ class N {
|
|
|
521
584
|
* @example
|
|
522
585
|
* ```typescript
|
|
523
586
|
* // Copy a file
|
|
524
|
-
* await fs.
|
|
587
|
+
* await fs.copy('/source/file.txt', '/dest/file.txt');
|
|
525
588
|
*
|
|
526
589
|
* // Copy a directory and all its contents
|
|
527
|
-
* await fs.
|
|
590
|
+
* await fs.copy('/source/dir', '/dest/dir', { recursive: true });
|
|
528
591
|
*
|
|
529
592
|
* // Copy without overwriting existing files
|
|
530
|
-
* await fs.
|
|
593
|
+
* await fs.copy('/source', '/dest', { recursive: true, force: false });
|
|
531
594
|
* ```
|
|
532
595
|
*/
|
|
533
|
-
async copy(t, e,
|
|
596
|
+
async copy(t, e, i) {
|
|
597
|
+
await this.ensureMounted();
|
|
534
598
|
try {
|
|
535
|
-
const r =
|
|
599
|
+
const r = i?.recursive ?? !1, a = i?.force ?? !0;
|
|
536
600
|
if (!await this.exists(t))
|
|
537
601
|
throw new o(`Source does not exist: ${t}`, "ENOENT");
|
|
538
|
-
if (await this.exists(e) && !
|
|
602
|
+
if (await this.exists(e) && !a)
|
|
539
603
|
throw new o(`Destination already exists: ${e}`, "EEXIST");
|
|
540
604
|
if ((await this.stat(t)).isFile) {
|
|
541
605
|
const l = await this.readFile(t, "binary");
|
|
@@ -547,7 +611,7 @@ class N {
|
|
|
547
611
|
const l = await this.readdir(t, { withFileTypes: !0 });
|
|
548
612
|
for (const h of l) {
|
|
549
613
|
const w = `${t}/${h.name}`, D = `${e}/${h.name}`;
|
|
550
|
-
await this.copy(w, D, { recursive: !0, force:
|
|
614
|
+
await this.copy(w, D, { recursive: !0, force: a });
|
|
551
615
|
}
|
|
552
616
|
}
|
|
553
617
|
} catch (r) {
|
|
@@ -558,8 +622,9 @@ class N {
|
|
|
558
622
|
* Start watching a file or directory for changes
|
|
559
623
|
*/
|
|
560
624
|
async watch(t) {
|
|
561
|
-
|
|
562
|
-
|
|
625
|
+
await this.ensureMounted();
|
|
626
|
+
const e = F(t), i = await this.buildSnapshot(e);
|
|
627
|
+
this.watchers.set(e, i), this.watchTimer || (this.watchTimer = setInterval(() => {
|
|
563
628
|
this.scanWatches();
|
|
564
629
|
}, this.watchInterval));
|
|
565
630
|
}
|
|
@@ -571,17 +636,17 @@ class N {
|
|
|
571
636
|
this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
572
637
|
}
|
|
573
638
|
async buildSnapshot(t) {
|
|
574
|
-
const e = /* @__PURE__ */ new Map(),
|
|
575
|
-
const
|
|
576
|
-
if (e.set(r,
|
|
639
|
+
const e = /* @__PURE__ */ new Map(), i = async (r) => {
|
|
640
|
+
const a = await this.stat(r);
|
|
641
|
+
if (e.set(r, a), a.isDirectory) {
|
|
577
642
|
const n = await this.readdir(r, { withFileTypes: !0 });
|
|
578
643
|
for (const s of n) {
|
|
579
644
|
const c = `${r === "/" ? "" : r}/${s.name}`;
|
|
580
|
-
await
|
|
645
|
+
await i(c);
|
|
581
646
|
}
|
|
582
647
|
}
|
|
583
648
|
};
|
|
584
|
-
return await
|
|
649
|
+
return await i(t), e;
|
|
585
650
|
}
|
|
586
651
|
async scanWatches() {
|
|
587
652
|
if (!this.scanning) {
|
|
@@ -589,23 +654,23 @@ class N {
|
|
|
589
654
|
try {
|
|
590
655
|
await Promise.all(
|
|
591
656
|
[...this.watchers.entries()].map(async ([t, e]) => {
|
|
592
|
-
let
|
|
657
|
+
let i;
|
|
593
658
|
try {
|
|
594
|
-
|
|
659
|
+
i = await this.buildSnapshot(t);
|
|
595
660
|
} catch {
|
|
596
|
-
|
|
661
|
+
i = /* @__PURE__ */ new Map();
|
|
597
662
|
}
|
|
598
663
|
const r = [];
|
|
599
|
-
for (const [
|
|
600
|
-
const s = e.get(
|
|
601
|
-
s ? (s.mtime !== n.mtime || s.size !== n.size) && r.push({ path:
|
|
664
|
+
for (const [a, n] of i) {
|
|
665
|
+
const s = e.get(a);
|
|
666
|
+
s ? (s.mtime !== n.mtime || s.size !== n.size) && r.push({ path: a, type: "change" }) : r.push({ path: a, type: "create" });
|
|
602
667
|
}
|
|
603
|
-
for (const
|
|
604
|
-
|
|
668
|
+
for (const a of e.keys())
|
|
669
|
+
i.has(a) || r.push({ path: a, type: "delete" });
|
|
605
670
|
if (r.length && this.watchCallback)
|
|
606
|
-
for (const
|
|
607
|
-
this.watchCallback(
|
|
608
|
-
this.watchers.set(t,
|
|
671
|
+
for (const a of r)
|
|
672
|
+
this.watchCallback(a);
|
|
673
|
+
this.watchers.set(t, i);
|
|
609
674
|
})
|
|
610
675
|
);
|
|
611
676
|
} finally {
|
|
@@ -642,20 +707,21 @@ class N {
|
|
|
642
707
|
* ```
|
|
643
708
|
*/
|
|
644
709
|
async sync(t, e) {
|
|
710
|
+
await this.ensureMounted();
|
|
645
711
|
try {
|
|
646
712
|
(e?.cleanBefore ?? !1) && await this.clear("/");
|
|
647
|
-
for (const [r,
|
|
713
|
+
for (const [r, a] of t) {
|
|
648
714
|
const n = F(r);
|
|
649
715
|
let s;
|
|
650
|
-
|
|
716
|
+
a instanceof Blob ? s = await P(a) : s = a, await this.writeFile(n, s);
|
|
651
717
|
}
|
|
652
|
-
} catch (
|
|
653
|
-
throw
|
|
718
|
+
} catch (i) {
|
|
719
|
+
throw i instanceof o ? i : new o("Failed to sync file system", "SYNC_FAILED");
|
|
654
720
|
}
|
|
655
721
|
}
|
|
656
722
|
}
|
|
657
|
-
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" &&
|
|
723
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && v(new $());
|
|
658
724
|
export {
|
|
659
|
-
|
|
725
|
+
$ as OPFSWorker
|
|
660
726
|
};
|
|
661
727
|
//# sourceMappingURL=raw.js.map
|