opfs-worker 0.4.2 → 0.5.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/README.md +204 -880
- package/dist/assets/worker-3SMz_DAt.js.map +1 -0
- package/dist/{helpers-BgMlBRWa.js → helpers-Bm2TWyPQ.js} +290 -251
- package/dist/helpers-Bm2TWyPQ.js.map +1 -0
- package/dist/helpers-BoLdVbGk.cjs +4 -0
- package/dist/helpers-BoLdVbGk.cjs.map +1 -0
- package/dist/index.cjs +532 -579
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +560 -602
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +97 -159
- package/dist/raw.js.map +1 -1
- package/dist/types.d.ts +14 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +9 -9
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +26 -2
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/worker.d.ts +7 -9
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-Bra0Mewp.js.map +0 -1
- package/dist/helpers-BgMlBRWa.js.map +0 -1
- package/dist/helpers-DuJbWewc.cjs +0 -4
- package/dist/helpers-DuJbWewc.cjs.map +0 -1
package/dist/raw.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { expose as
|
|
2
|
-
import {
|
|
1
|
+
import { expose as E } from "comlink";
|
|
2
|
+
import { m as l, d as v, n as y, O as o, s as d, P as p, l as S, x as C, F as w, o as u, j as b, e as g, f, p as A, u as x, r as I, g as H, t as O } from "./helpers-Bm2TWyPQ.js";
|
|
3
3
|
class $ {
|
|
4
4
|
/** Root directory handle for the file system */
|
|
5
5
|
root = null;
|
|
6
|
-
/** Map of watched paths
|
|
6
|
+
/** Map of watched paths and options */
|
|
7
7
|
watchers = /* @__PURE__ */ new Map();
|
|
8
|
-
/** Interval handle for polling watched paths */
|
|
9
|
-
watchTimer = null;
|
|
10
|
-
/** Flag to avoid concurrent scans */
|
|
11
|
-
scanning = !1;
|
|
12
8
|
/** Promise to prevent concurrent mount operations */
|
|
13
9
|
mountingPromise = null;
|
|
14
10
|
/** BroadcastChannel instance for sending events */
|
|
@@ -16,7 +12,7 @@ class $ {
|
|
|
16
12
|
/** Configuration options */
|
|
17
13
|
options = {
|
|
18
14
|
root: "/",
|
|
19
|
-
|
|
15
|
+
namespace: "",
|
|
20
16
|
maxFileSize: 50 * 1024 * 1024,
|
|
21
17
|
hashAlgorithm: null,
|
|
22
18
|
broadcastChannel: "opfs-worker"
|
|
@@ -33,25 +29,26 @@ class $ {
|
|
|
33
29
|
async notifyChange(t) {
|
|
34
30
|
if (!this.options.broadcastChannel)
|
|
35
31
|
return;
|
|
36
|
-
|
|
37
|
-
if (this.
|
|
32
|
+
const e = t.path;
|
|
33
|
+
if (![...this.watchers.values()].some((r) => l(e, r.pattern) && r.include.some((s) => s && l(e, s)) && !r.exclude.some((s) => s && l(e, s))))
|
|
34
|
+
return;
|
|
35
|
+
let a;
|
|
36
|
+
if (this.options.hashAlgorithm)
|
|
38
37
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} catch (i) {
|
|
42
|
-
console.warn(`Failed to calculate hash for ${t.path}:`, i);
|
|
38
|
+
a = (await this.stat(e)).hash;
|
|
39
|
+
} catch {
|
|
43
40
|
}
|
|
44
41
|
try {
|
|
45
42
|
this.broadcastChannel || (this.broadcastChannel = new BroadcastChannel(this.options.broadcastChannel));
|
|
46
|
-
const
|
|
47
|
-
|
|
43
|
+
const r = {
|
|
44
|
+
namespace: this.options.namespace,
|
|
48
45
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
49
46
|
...t,
|
|
50
|
-
...
|
|
47
|
+
...a && { hash: a }
|
|
51
48
|
};
|
|
52
|
-
this.broadcastChannel.postMessage(
|
|
53
|
-
} catch (
|
|
54
|
-
console.warn("Failed to send event via BroadcastChannel:",
|
|
49
|
+
this.broadcastChannel.postMessage(r);
|
|
50
|
+
} catch (r) {
|
|
51
|
+
console.warn("Failed to send event via BroadcastChannel:", r);
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
/**
|
|
@@ -65,7 +62,7 @@ class $ {
|
|
|
65
62
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
66
63
|
*/
|
|
67
64
|
constructor(t) {
|
|
68
|
-
|
|
65
|
+
v(), t && this.setOptions(t);
|
|
69
66
|
}
|
|
70
67
|
/**
|
|
71
68
|
* Initialize the file system within a given directory
|
|
@@ -89,13 +86,12 @@ class $ {
|
|
|
89
86
|
* ```
|
|
90
87
|
*/
|
|
91
88
|
async mount(t = this.options.root) {
|
|
92
|
-
return this.mountingPromise && await this.mountingPromise, t =
|
|
93
|
-
this.root = null;
|
|
89
|
+
return this.mountingPromise && await this.mountingPromise, t = y(t), this.mountingPromise = new Promise(async (e, i) => {
|
|
94
90
|
try {
|
|
95
91
|
const a = await navigator.storage.getDirectory();
|
|
96
92
|
t === "/" ? this.root = a : this.root = await this.getDirectoryHandle(t, !0, a), e(!0);
|
|
97
|
-
} catch
|
|
98
|
-
|
|
93
|
+
} catch {
|
|
94
|
+
i(new o("Failed to initialize OPFS", "INIT_FAILED"));
|
|
99
95
|
} finally {
|
|
100
96
|
this.mountingPromise = null;
|
|
101
97
|
}
|
|
@@ -112,7 +108,7 @@ class $ {
|
|
|
112
108
|
* @param options.broadcastChannel - Custom name for the broadcast channel
|
|
113
109
|
*/
|
|
114
110
|
async setOptions(t) {
|
|
115
|
-
t.
|
|
111
|
+
t.hashAlgorithm !== void 0 && (this.options.hashAlgorithm = t.hashAlgorithm), t.maxFileSize !== void 0 && (this.options.maxFileSize = t.maxFileSize), t.broadcastChannel !== void 0 && (this.broadcastChannel && this.options.broadcastChannel !== t.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.options.broadcastChannel = t.broadcastChannel), t.namespace && (this.options.namespace = t.namespace), t.root !== void 0 && (this.options.root = t.root, this.options.namespace || (this.options.namespace = `opfs-worker:${this.options.root}`), await this.mount(this.options.root));
|
|
116
112
|
}
|
|
117
113
|
/**
|
|
118
114
|
* Get a directory handle from a path
|
|
@@ -133,9 +129,7 @@ class $ {
|
|
|
133
129
|
* ```
|
|
134
130
|
*/
|
|
135
131
|
async getDirectoryHandle(t, e = !1, i = this.root) {
|
|
136
|
-
|
|
137
|
-
throw new m();
|
|
138
|
-
const a = Array.isArray(t) ? t : u(t);
|
|
132
|
+
const a = Array.isArray(t) ? t : d(t);
|
|
139
133
|
let r = i;
|
|
140
134
|
for (const s of a)
|
|
141
135
|
r = await r.getDirectoryHandle(s, { create: e });
|
|
@@ -161,11 +155,9 @@ class $ {
|
|
|
161
155
|
* ```
|
|
162
156
|
*/
|
|
163
157
|
async getFileHandle(t, e = !1, i = this.root) {
|
|
164
|
-
|
|
165
|
-
throw new m();
|
|
166
|
-
const a = u(t);
|
|
158
|
+
const a = d(t);
|
|
167
159
|
if (a.length === 0)
|
|
168
|
-
throw new
|
|
160
|
+
throw new p("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
169
161
|
const r = a.pop();
|
|
170
162
|
return (await this.getDirectoryHandle(a, e, i)).getFileHandle(r, { create: e });
|
|
171
163
|
}
|
|
@@ -194,10 +186,10 @@ class $ {
|
|
|
194
186
|
for (const r of a) {
|
|
195
187
|
const s = `${i === "/" ? "" : i}/${r.name}`;
|
|
196
188
|
try {
|
|
197
|
-
const
|
|
198
|
-
t.set(s,
|
|
199
|
-
} catch (
|
|
200
|
-
console.warn(`Skipping broken entry: ${s}`,
|
|
189
|
+
const n = await this.stat(s);
|
|
190
|
+
t.set(s, n), n.isDirectory && await e(s);
|
|
191
|
+
} catch (n) {
|
|
192
|
+
console.warn(`Skipping broken entry: ${s}`, n);
|
|
201
193
|
}
|
|
202
194
|
}
|
|
203
195
|
};
|
|
@@ -213,10 +205,10 @@ class $ {
|
|
|
213
205
|
async readFile(t, e = "utf-8") {
|
|
214
206
|
await this.mount();
|
|
215
207
|
try {
|
|
216
|
-
const i = await this.getFileHandle(t, !1), a = await
|
|
208
|
+
const i = await this.getFileHandle(t, !1), a = await S(i, t);
|
|
217
209
|
return e === "binary" ? a : C(a, e);
|
|
218
210
|
} catch (i) {
|
|
219
|
-
throw
|
|
211
|
+
throw new w(t, i);
|
|
220
212
|
}
|
|
221
213
|
}
|
|
222
214
|
/**
|
|
@@ -246,8 +238,8 @@ class $ {
|
|
|
246
238
|
*/
|
|
247
239
|
async writeFile(t, e, i) {
|
|
248
240
|
await this.mount();
|
|
249
|
-
const a = await this.getFileHandle(t, !0);
|
|
250
|
-
await
|
|
241
|
+
const a = await this.exists(t), r = await this.getFileHandle(t, !0);
|
|
242
|
+
await u(r, e, i, {}, t), a ? await this.notifyChange({ path: t, type: "changed", isDirectory: !1 }) : await this.notifyChange({ path: t, type: "added", isDirectory: !1 });
|
|
251
243
|
}
|
|
252
244
|
/**
|
|
253
245
|
* Append data to a file
|
|
@@ -274,7 +266,7 @@ class $ {
|
|
|
274
266
|
async appendFile(t, e, i) {
|
|
275
267
|
await this.mount();
|
|
276
268
|
const a = await this.getFileHandle(t, !0);
|
|
277
|
-
await
|
|
269
|
+
await u(a, e, i, { append: !0 }, t), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
278
270
|
}
|
|
279
271
|
/**
|
|
280
272
|
* Create a directory
|
|
@@ -298,19 +290,20 @@ class $ {
|
|
|
298
290
|
* ```
|
|
299
291
|
*/
|
|
300
292
|
async mkdir(t, e) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const i = e?.recursive ?? !1, a = u(t);
|
|
293
|
+
await this.mount();
|
|
294
|
+
const i = e?.recursive ?? !1, a = d(t);
|
|
304
295
|
let r = this.root;
|
|
305
296
|
for (let s = 0; s < a.length; s++) {
|
|
306
|
-
const
|
|
297
|
+
const n = a[s];
|
|
307
298
|
try {
|
|
308
|
-
r = await r.getDirectoryHandle(
|
|
299
|
+
r = await r.getDirectoryHandle(n, { create: i || s === a.length - 1 });
|
|
309
300
|
} catch (c) {
|
|
310
|
-
throw c.name === "NotFoundError" ? new
|
|
301
|
+
throw c.name === "NotFoundError" ? new o(
|
|
311
302
|
`Parent directory does not exist: ${b(a.slice(0, s + 1))}`,
|
|
312
|
-
"ENOENT"
|
|
313
|
-
|
|
303
|
+
"ENOENT",
|
|
304
|
+
void 0,
|
|
305
|
+
c
|
|
306
|
+
) : c.name === "TypeMismatchError" ? new o(`Path segment is not a directory: ${n}`, "ENOTDIR", void 0, c) : new o("Failed to create directory", "MKDIR_FAILED", void 0, c);
|
|
314
307
|
}
|
|
315
308
|
}
|
|
316
309
|
await this.notifyChange({ path: t, type: "added", isDirectory: !0 });
|
|
@@ -347,9 +340,9 @@ class $ {
|
|
|
347
340
|
isFile: !1,
|
|
348
341
|
isDirectory: !0
|
|
349
342
|
};
|
|
350
|
-
const e =
|
|
343
|
+
const e = g(t), i = await this.getDirectoryHandle(f(t), !1), a = this.options.hashAlgorithm !== null;
|
|
351
344
|
try {
|
|
352
|
-
const s = await (await i.getFileHandle(e, { create: !1 })).getFile(),
|
|
345
|
+
const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), n = {
|
|
353
346
|
kind: "file",
|
|
354
347
|
size: s.size,
|
|
355
348
|
mtime: new Date(s.lastModified).toISOString(),
|
|
@@ -359,15 +352,15 @@ class $ {
|
|
|
359
352
|
};
|
|
360
353
|
if (a && this.options.hashAlgorithm)
|
|
361
354
|
try {
|
|
362
|
-
const c = await
|
|
363
|
-
|
|
355
|
+
const c = await A(s, this.options.hashAlgorithm, this.options.maxFileSize);
|
|
356
|
+
n.hash = c;
|
|
364
357
|
} catch (c) {
|
|
365
358
|
console.warn(`Failed to calculate hash for ${t}:`, c);
|
|
366
359
|
}
|
|
367
|
-
return
|
|
360
|
+
return n;
|
|
368
361
|
} catch (r) {
|
|
369
362
|
if (r.name !== "TypeMismatchError" && r.name !== "NotFoundError")
|
|
370
|
-
throw new
|
|
363
|
+
throw new o("Failed to stat (file)", "STAT_FAILED", void 0, r);
|
|
371
364
|
}
|
|
372
365
|
try {
|
|
373
366
|
return await i.getDirectoryHandle(e, { create: !1 }), {
|
|
@@ -379,7 +372,7 @@ class $ {
|
|
|
379
372
|
isDirectory: !0
|
|
380
373
|
};
|
|
381
374
|
} catch (r) {
|
|
382
|
-
throw r.name === "NotFoundError" ? new
|
|
375
|
+
throw r.name === "NotFoundError" ? new o(`No such file or directory: ${t}`, "ENOENT", void 0, r) : new o("Failed to stat (directory)", "STAT_FAILED", void 0, r);
|
|
383
376
|
}
|
|
384
377
|
}
|
|
385
378
|
/**
|
|
@@ -431,10 +424,10 @@ class $ {
|
|
|
431
424
|
async exists(t) {
|
|
432
425
|
if (await this.mount(), t === "/")
|
|
433
426
|
return !0;
|
|
434
|
-
const e =
|
|
427
|
+
const e = g(t);
|
|
435
428
|
let i = null;
|
|
436
429
|
try {
|
|
437
|
-
i = await this.getDirectoryHandle(
|
|
430
|
+
i = await this.getDirectoryHandle(f(t), !1);
|
|
438
431
|
} catch (a) {
|
|
439
432
|
throw (a.name === "NotFoundError" || a.name === "TypeMismatchError") && (i = null), a;
|
|
440
433
|
}
|
|
@@ -445,14 +438,14 @@ class $ {
|
|
|
445
438
|
} catch (a) {
|
|
446
439
|
if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
|
|
447
440
|
throw a;
|
|
441
|
+
try {
|
|
442
|
+
return await i.getDirectoryHandle(e, { create: !1 }), !0;
|
|
443
|
+
} catch (r) {
|
|
444
|
+
if (r.name !== "NotFoundError" && r.name !== "TypeMismatchError")
|
|
445
|
+
throw r;
|
|
446
|
+
return !1;
|
|
447
|
+
}
|
|
448
448
|
}
|
|
449
|
-
try {
|
|
450
|
-
return await i.getDirectoryHandle(e, { create: !1 }), !0;
|
|
451
|
-
} catch (a) {
|
|
452
|
-
if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
|
|
453
|
-
throw a;
|
|
454
|
-
}
|
|
455
|
-
return !1;
|
|
456
449
|
}
|
|
457
450
|
/**
|
|
458
451
|
* Clear all contents of a directory without removing the directory itself
|
|
@@ -483,7 +476,7 @@ class $ {
|
|
|
483
476
|
}
|
|
484
477
|
await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
|
|
485
478
|
} catch (e) {
|
|
486
|
-
throw e instanceof
|
|
479
|
+
throw e instanceof o ? e : new o(`Failed to clear directory: ${t}`, "CLEAR_FAILED", void 0, e);
|
|
487
480
|
}
|
|
488
481
|
}
|
|
489
482
|
/**
|
|
@@ -511,23 +504,10 @@ class $ {
|
|
|
511
504
|
* ```
|
|
512
505
|
*/
|
|
513
506
|
async remove(t, e) {
|
|
514
|
-
await this.mount()
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const r = D(t);
|
|
519
|
-
if (!r)
|
|
520
|
-
throw new E("Invalid path", t);
|
|
521
|
-
const s = await this.getDirectoryHandle(F(t), !1);
|
|
522
|
-
try {
|
|
523
|
-
await s.removeEntry(r, { recursive: i });
|
|
524
|
-
} catch (o) {
|
|
525
|
-
if (o.name === "NotFoundError") {
|
|
526
|
-
if (!a)
|
|
527
|
-
throw new n(`No such file or directory: ${t}`, "ENOENT");
|
|
528
|
-
} else throw o.name === "InvalidModificationError" ? new n(`Directory not empty: ${t}. Use recursive option to force removal.`, "ENOTEMPTY") : o.name === "TypeMismatchError" && !i ? new n(`Cannot remove directory without recursive option: ${t}`, "EISDIR") : new n(`Failed to remove path: ${t}`, "RM_FAILED");
|
|
529
|
-
}
|
|
530
|
-
await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
|
|
507
|
+
if (await this.mount(), t === "/")
|
|
508
|
+
throw new o("Cannot remove root directory", "EROOT");
|
|
509
|
+
const i = await this.getDirectoryHandle(f(t), !1);
|
|
510
|
+
await x(i, t, e), await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
|
|
531
511
|
}
|
|
532
512
|
/**
|
|
533
513
|
* Resolve a path to an absolute path
|
|
@@ -550,12 +530,12 @@ class $ {
|
|
|
550
530
|
async realpath(t) {
|
|
551
531
|
await this.mount();
|
|
552
532
|
try {
|
|
553
|
-
const e =
|
|
533
|
+
const e = I(t);
|
|
554
534
|
if (!await this.exists(e))
|
|
555
|
-
throw new
|
|
535
|
+
throw new w(e);
|
|
556
536
|
return e;
|
|
557
537
|
} catch (e) {
|
|
558
|
-
throw e instanceof
|
|
538
|
+
throw e instanceof o ? e : new o(`Failed to resolve path: ${t}`, "REALPATH_FAILED", void 0, e);
|
|
559
539
|
}
|
|
560
540
|
}
|
|
561
541
|
/**
|
|
@@ -578,10 +558,10 @@ class $ {
|
|
|
578
558
|
await this.mount();
|
|
579
559
|
try {
|
|
580
560
|
if (!await this.exists(t))
|
|
581
|
-
throw new
|
|
561
|
+
throw new w(t);
|
|
582
562
|
await this.copy(t, e, { recursive: !0 }), await this.remove(t, { recursive: !0 }), await this.notifyChange({ path: t, type: "removed", isDirectory: !1 }), await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
|
|
583
563
|
} catch (i) {
|
|
584
|
-
throw i instanceof
|
|
564
|
+
throw i instanceof o ? i : new o(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED", void 0, i);
|
|
585
565
|
}
|
|
586
566
|
}
|
|
587
567
|
/**
|
|
@@ -614,34 +594,33 @@ class $ {
|
|
|
614
594
|
try {
|
|
615
595
|
const a = i?.recursive ?? !1, r = i?.force ?? !0;
|
|
616
596
|
if (!await this.exists(t))
|
|
617
|
-
throw new
|
|
597
|
+
throw new o(`Source does not exist: ${t}`, "ENOENT", void 0);
|
|
618
598
|
if (await this.exists(e) && !r)
|
|
619
|
-
throw new
|
|
599
|
+
throw new o(`Destination already exists: ${e}`, "EEXIST", void 0);
|
|
620
600
|
if ((await this.stat(t)).isFile) {
|
|
621
601
|
const h = await this.readFile(t, "binary");
|
|
622
602
|
await this.writeFile(e, h);
|
|
623
603
|
} else {
|
|
624
604
|
if (!a)
|
|
625
|
-
throw new
|
|
605
|
+
throw new o(`Cannot copy directory without recursive option: ${t}`, "EISDIR", void 0);
|
|
626
606
|
await this.mkdir(e, { recursive: !0 });
|
|
627
607
|
const h = await this.readDir(t);
|
|
628
|
-
for (const
|
|
629
|
-
const
|
|
630
|
-
await this.copy(
|
|
608
|
+
for (const m of h) {
|
|
609
|
+
const F = `${t}/${m.name}`, D = `${e}/${m.name}`;
|
|
610
|
+
await this.copy(F, D, { recursive: !0, force: r });
|
|
631
611
|
}
|
|
632
612
|
}
|
|
633
|
-
await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
|
|
634
613
|
} catch (a) {
|
|
635
|
-
throw a instanceof
|
|
614
|
+
throw a instanceof o ? a : new o(`Failed to copy from ${t} to ${e}`, "CP_FAILED", void 0, a);
|
|
636
615
|
}
|
|
637
616
|
}
|
|
638
617
|
/**
|
|
639
618
|
* Start watching a file or directory for changes
|
|
640
619
|
*
|
|
641
|
-
* @param path - The path to watch
|
|
620
|
+
* @param path - The path to watch (minimatch syntax allowed)
|
|
642
621
|
* @param options - Watch options
|
|
643
622
|
* @param options.recursive - Whether to watch recursively (default: true)
|
|
644
|
-
* @param options.
|
|
623
|
+
* @param options.exclude - Glob pattern(s) to exclude (minimatch).
|
|
645
624
|
* @returns Promise that resolves when watching starts
|
|
646
625
|
*
|
|
647
626
|
* @example
|
|
@@ -654,21 +633,27 @@ class $ {
|
|
|
654
633
|
*
|
|
655
634
|
* // Watch a single file
|
|
656
635
|
* await fs.watch('/config.json', { recursive: false });
|
|
636
|
+
*
|
|
637
|
+
* // Watch all json files but not in dist directory
|
|
638
|
+
* await fs.watch('/**\/*.json', { recursive: false, exclude: ['dist/**'] });
|
|
639
|
+
*
|
|
657
640
|
* ```
|
|
658
641
|
*/
|
|
659
642
|
async watch(t, e) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
643
|
+
if (!this.options.broadcastChannel)
|
|
644
|
+
throw new o("This instance is not configured to send events. Please specify options.broadcastChannel to enable watching.", "ENOENT");
|
|
645
|
+
const i = {
|
|
646
|
+
pattern: H(t, e?.recursive ?? !0),
|
|
647
|
+
include: Array.isArray(e?.include) ? e.include : [e?.include ?? "**"],
|
|
648
|
+
exclude: Array.isArray(e?.exclude) ? e.exclude : [e?.exclude ?? ""]
|
|
649
|
+
};
|
|
650
|
+
this.watchers.set(t, i);
|
|
665
651
|
}
|
|
666
652
|
/**
|
|
667
653
|
* Stop watching a previously watched path
|
|
668
654
|
*/
|
|
669
655
|
unwatch(t) {
|
|
670
|
-
|
|
671
|
-
this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
656
|
+
this.watchers.delete(t);
|
|
672
657
|
}
|
|
673
658
|
/**
|
|
674
659
|
* Dispose of resources and clean up the file system instance
|
|
@@ -677,53 +662,7 @@ class $ {
|
|
|
677
662
|
* to properly clean up resources like the broadcast channel and watch timers.
|
|
678
663
|
*/
|
|
679
664
|
dispose() {
|
|
680
|
-
this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.
|
|
681
|
-
}
|
|
682
|
-
async buildSnapshot(t, e) {
|
|
683
|
-
const i = /* @__PURE__ */ new Map(), a = e?.recursive ?? !0, r = e?.excludes, s = async (c) => {
|
|
684
|
-
const h = await this.stat(c);
|
|
685
|
-
return i.set(c, h), h;
|
|
686
|
-
}, o = async (c) => {
|
|
687
|
-
if (d(c, r))
|
|
688
|
-
return;
|
|
689
|
-
if ((await s(c)).isDirectory) {
|
|
690
|
-
const w = await this.readDir(c);
|
|
691
|
-
for (const y of w) {
|
|
692
|
-
const l = `${c === "/" ? "" : c}/${y.name}`;
|
|
693
|
-
a ? await o(l) : d(l, r) || await s(l);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
};
|
|
697
|
-
return await o(t), i;
|
|
698
|
-
}
|
|
699
|
-
async scanWatches() {
|
|
700
|
-
if (!this.scanning) {
|
|
701
|
-
this.scanning = !0;
|
|
702
|
-
try {
|
|
703
|
-
await Promise.all(
|
|
704
|
-
[...this.watchers.entries()].map(async ([t, { snapshot: e, options: i }]) => {
|
|
705
|
-
let a;
|
|
706
|
-
try {
|
|
707
|
-
a = await this.buildSnapshot(t, i);
|
|
708
|
-
} catch {
|
|
709
|
-
a = /* @__PURE__ */ new Map();
|
|
710
|
-
}
|
|
711
|
-
for (const [r, s] of a) {
|
|
712
|
-
const o = e.get(r);
|
|
713
|
-
d(r, i.excludes) || (o ? (o.mtime !== s.mtime || o.size !== s.size) && await this.notifyChange({ path: r, type: "changed", isDirectory: s.isDirectory }) : await this.notifyChange({ path: r, type: "added", isDirectory: s.isDirectory }));
|
|
714
|
-
}
|
|
715
|
-
for (const r of e.keys())
|
|
716
|
-
if (!d(r, i.excludes) && !a.has(r)) {
|
|
717
|
-
const s = e.get(r);
|
|
718
|
-
await this.notifyChange({ path: r, type: "removed", isDirectory: s?.isDirectory ?? !1 });
|
|
719
|
-
}
|
|
720
|
-
this.watchers.set(t, { snapshot: a, options: i });
|
|
721
|
-
})
|
|
722
|
-
);
|
|
723
|
-
} finally {
|
|
724
|
-
this.scanning = !1;
|
|
725
|
-
}
|
|
726
|
-
}
|
|
665
|
+
this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.watchers.clear();
|
|
727
666
|
}
|
|
728
667
|
/**
|
|
729
668
|
* Synchronize the file system with external data
|
|
@@ -758,17 +697,16 @@ class $ {
|
|
|
758
697
|
try {
|
|
759
698
|
(e?.cleanBefore ?? !1) && await this.clear("/");
|
|
760
699
|
for (const [a, r] of t) {
|
|
761
|
-
const s =
|
|
762
|
-
let
|
|
763
|
-
r instanceof Blob ?
|
|
700
|
+
const s = y(a);
|
|
701
|
+
let n;
|
|
702
|
+
r instanceof Blob ? n = await O(r) : n = r, await this.writeFile(s, n);
|
|
764
703
|
}
|
|
765
|
-
await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
|
|
766
704
|
} catch (i) {
|
|
767
|
-
throw i instanceof
|
|
705
|
+
throw i instanceof o ? i : new o("Failed to sync file system", "SYNC_FAILED", void 0, i);
|
|
768
706
|
}
|
|
769
707
|
}
|
|
770
708
|
}
|
|
771
|
-
typeof
|
|
709
|
+
typeof globalThis < "u" && globalThis.constructor.name === "DedicatedWorkerGlobalScope" && E(new $());
|
|
772
710
|
export {
|
|
773
711
|
$ as OPFSWorker
|
|
774
712
|
};
|