opfs-worker 0.3.3 → 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/dist/raw.js CHANGED
@@ -1,21 +1,18 @@
1
- import { expose as p } from "comlink";
2
- import { d as S, O as n, b as l, s as w, P as g, i as v, o as I, F as f, w as D, j as C, e as d, f as y, k as M, r as T, n as u, l as b } from "./helpers-DxFcNkZe.js";
3
- class A {
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
+ class $ {
4
4
  /** Root directory handle for the file system */
5
5
  root = null;
6
- /** Map of watched paths to their last known state */
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 */
15
11
  broadcastChannel = null;
16
12
  /** Configuration options */
17
13
  options = {
18
- watchInterval: 1e3,
14
+ root: "/",
15
+ namespace: "",
19
16
  maxFileSize: 50 * 1024 * 1024,
20
17
  hashAlgorithm: null,
21
18
  broadcastChannel: "opfs-worker"
@@ -32,38 +29,40 @@ class A {
32
29
  async notifyChange(t) {
33
30
  if (!this.options.broadcastChannel)
34
31
  return;
35
- let e;
36
- if (this.options.hashAlgorithm && !t.isDirectory && t.type !== "removed")
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)
37
37
  try {
38
- const i = await this.stat(t.path);
39
- i.isFile && i.hash && (e = i.hash);
40
- } catch (i) {
41
- console.warn(`Failed to calculate hash for ${t.path}:`, i);
38
+ a = (await this.stat(e)).hash;
39
+ } catch {
42
40
  }
43
41
  try {
44
42
  this.broadcastChannel || (this.broadcastChannel = new BroadcastChannel(this.options.broadcastChannel));
45
- const i = {
46
- root: this.root.name,
43
+ const r = {
44
+ namespace: this.options.namespace,
47
45
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
48
46
  ...t,
49
- ...e && { hash: e }
47
+ ...a && { hash: a }
50
48
  };
51
- this.broadcastChannel.postMessage(i);
52
- } catch (i) {
53
- console.warn("Failed to send event via BroadcastChannel:", i);
49
+ this.broadcastChannel.postMessage(r);
50
+ } catch (r) {
51
+ console.warn("Failed to send event via BroadcastChannel:", r);
54
52
  }
55
53
  }
56
54
  /**
57
55
  * Creates a new OPFSFileSystem instance
58
56
  *
59
57
  * @param options - Optional configuration options
58
+ * @param options.root - Root path for the file system (default: '/')
60
59
  * @param options.watchInterval - Polling interval in milliseconds for file watching
61
60
  * @param options.hashAlgorithm - Hash algorithm for file hashing
62
61
  * @param options.maxFileSize - Maximum file size for hashing in bytes (default: 50MB)
63
62
  * @throws {OPFSError} If OPFS is not supported in the current browser
64
63
  */
65
64
  constructor(t) {
66
- S(), t && this.setOptions(t), this.mount("/");
65
+ v(), t && this.setOptions(t);
67
66
  }
68
67
  /**
69
68
  * Initialize the file system within a given directory
@@ -86,14 +85,13 @@ class A {
86
85
  * await fs.mount('/my-app');
87
86
  * ```
88
87
  */
89
- async mount(t = "/") {
90
- return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (e, i) => {
91
- this.root = null;
88
+ async mount(t = this.options.root) {
89
+ return this.mountingPromise && await this.mountingPromise, t = y(t), this.mountingPromise = new Promise(async (e, i) => {
92
90
  try {
93
91
  const a = await navigator.storage.getDirectory();
94
92
  t === "/" ? this.root = a : this.root = await this.getDirectoryHandle(t, !0, a), e(!0);
95
- } catch (a) {
96
- console.error(a), i(new n("Failed to initialize OPFS", "INIT_FAILED"));
93
+ } catch {
94
+ i(new o("Failed to initialize OPFS", "INIT_FAILED"));
97
95
  } finally {
98
96
  this.mountingPromise = null;
99
97
  }
@@ -103,31 +101,14 @@ class A {
103
101
  * Update configuration options
104
102
  *
105
103
  * @param options - Configuration options to update
104
+ * @param options.root - Root path for the file system
106
105
  * @param options.watchInterval - Polling interval in milliseconds for file watching
107
106
  * @param options.hashAlgorithm - Hash algorithm for file hashing
108
107
  * @param options.maxFileSize - Maximum file size for hashing in bytes
109
108
  * @param options.broadcastChannel - Custom name for the broadcast channel
110
109
  */
111
- setOptions(t) {
112
- t.watchInterval !== void 0 && (this.options.watchInterval = t.watchInterval), 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);
113
- }
114
- /**
115
- * Automatically mount the OPFS root if not already mounted
116
- *
117
- * This method is called internally when file operations are performed
118
- * without explicitly mounting first.
119
- *
120
- * @returns Promise that resolves when auto-mount is complete
121
- * @throws {OPFSError} If auto-mount fails
122
- */
123
- async ensureMounted() {
124
- if (!this.root) {
125
- if (this.mountingPromise) {
126
- await this.mountingPromise;
127
- return;
128
- }
129
- throw new n("OPFS not mounted", "NOT_MOUNTED");
130
- }
110
+ async setOptions(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));
131
112
  }
132
113
  /**
133
114
  * Get a directory handle from a path
@@ -148,9 +129,7 @@ class A {
148
129
  * ```
149
130
  */
150
131
  async getDirectoryHandle(t, e = !1, i = this.root) {
151
- if (!i)
152
- throw new l();
153
- const a = Array.isArray(t) ? t : w(t);
132
+ const a = Array.isArray(t) ? t : d(t);
154
133
  let r = i;
155
134
  for (const s of a)
156
135
  r = await r.getDirectoryHandle(s, { create: e });
@@ -176,11 +155,9 @@ class A {
176
155
  * ```
177
156
  */
178
157
  async getFileHandle(t, e = !1, i = this.root) {
179
- if (!i)
180
- throw new l();
181
- const a = w(t);
158
+ const a = d(t);
182
159
  if (a.length === 0)
183
- throw new g("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
160
+ throw new p("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
184
161
  const r = a.pop();
185
162
  return (await this.getDirectoryHandle(a, e, i)).getFileHandle(r, { create: e });
186
163
  }
@@ -209,10 +186,10 @@ class A {
209
186
  for (const r of a) {
210
187
  const s = `${i === "/" ? "" : i}/${r.name}`;
211
188
  try {
212
- const o = await this.stat(s);
213
- t.set(s, o), o.isDirectory && await e(s);
214
- } catch (o) {
215
- console.warn(`Skipping broken entry: ${s}`, o);
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);
216
193
  }
217
194
  }
218
195
  };
@@ -226,12 +203,12 @@ class A {
226
203
  }), await e("/"), t;
227
204
  }
228
205
  async readFile(t, e = "utf-8") {
229
- await this.ensureMounted();
206
+ await this.mount();
230
207
  try {
231
- const i = await this.getFileHandle(t, !1), a = await v(i);
232
- return e === "binary" ? a : I(a, e);
208
+ const i = await this.getFileHandle(t, !1), a = await S(i, t);
209
+ return e === "binary" ? a : C(a, e);
233
210
  } catch (i) {
234
- throw console.error(i), new f(t);
211
+ throw new w(t, i);
235
212
  }
236
213
  }
237
214
  /**
@@ -260,9 +237,9 @@ class A {
260
237
  * ```
261
238
  */
262
239
  async writeFile(t, e, i) {
263
- await this.ensureMounted();
264
- const a = await this.getFileHandle(t, !0);
265
- await D(a, e, i, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
240
+ await this.mount();
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 });
266
243
  }
267
244
  /**
268
245
  * Append data to a file
@@ -287,9 +264,9 @@ class A {
287
264
  * ```
288
265
  */
289
266
  async appendFile(t, e, i) {
290
- await this.ensureMounted();
267
+ await this.mount();
291
268
  const a = await this.getFileHandle(t, !0);
292
- await D(a, e, i, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
269
+ await u(a, e, i, { append: !0 }, t), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
293
270
  }
294
271
  /**
295
272
  * Create a directory
@@ -313,19 +290,20 @@ class A {
313
290
  * ```
314
291
  */
315
292
  async mkdir(t, e) {
316
- if (await this.ensureMounted(), !this.root)
317
- throw new l();
318
- const i = e?.recursive ?? !1, a = w(t);
293
+ await this.mount();
294
+ const i = e?.recursive ?? !1, a = d(t);
319
295
  let r = this.root;
320
296
  for (let s = 0; s < a.length; s++) {
321
- const o = a[s];
297
+ const n = a[s];
322
298
  try {
323
- r = await r.getDirectoryHandle(o, { create: i || s === a.length - 1 });
299
+ r = await r.getDirectoryHandle(n, { create: i || s === a.length - 1 });
324
300
  } catch (c) {
325
- throw c.name === "NotFoundError" ? new n(
326
- `Parent directory does not exist: ${C(a.slice(0, s + 1))}`,
327
- "ENOENT"
328
- ) : c.name === "TypeMismatchError" ? new n(`Path segment is not a directory: ${o}`, "ENOTDIR") : new n("Failed to create directory", "MKDIR_FAILED");
301
+ throw c.name === "NotFoundError" ? new o(
302
+ `Parent directory does not exist: ${b(a.slice(0, s + 1))}`,
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);
329
307
  }
330
308
  }
331
309
  await this.notifyChange({ path: t, type: "added", isDirectory: !0 });
@@ -353,7 +331,7 @@ class A {
353
331
  * ```
354
332
  */
355
333
  async stat(t) {
356
- if (await this.ensureMounted(), t === "/")
334
+ if (await this.mount(), t === "/")
357
335
  return {
358
336
  kind: "directory",
359
337
  size: 0,
@@ -362,9 +340,9 @@ class A {
362
340
  isFile: !1,
363
341
  isDirectory: !0
364
342
  };
365
- const e = d(t), i = await this.getDirectoryHandle(y(t), !1), a = this.options.hashAlgorithm !== null;
343
+ const e = g(t), i = await this.getDirectoryHandle(f(t), !1), a = this.options.hashAlgorithm !== null;
366
344
  try {
367
- const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), o = {
345
+ const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), n = {
368
346
  kind: "file",
369
347
  size: s.size,
370
348
  mtime: new Date(s.lastModified).toISOString(),
@@ -374,15 +352,15 @@ class A {
374
352
  };
375
353
  if (a && this.options.hashAlgorithm)
376
354
  try {
377
- const c = await M(s, this.options.hashAlgorithm, this.options.maxFileSize);
378
- o.hash = c;
355
+ const c = await A(s, this.options.hashAlgorithm, this.options.maxFileSize);
356
+ n.hash = c;
379
357
  } catch (c) {
380
358
  console.warn(`Failed to calculate hash for ${t}:`, c);
381
359
  }
382
- return o;
360
+ return n;
383
361
  } catch (r) {
384
362
  if (r.name !== "TypeMismatchError" && r.name !== "NotFoundError")
385
- throw new n("Failed to stat (file)", "STAT_FAILED");
363
+ throw new o("Failed to stat (file)", "STAT_FAILED", void 0, r);
386
364
  }
387
365
  try {
388
366
  return await i.getDirectoryHandle(e, { create: !1 }), {
@@ -394,7 +372,7 @@ class A {
394
372
  isDirectory: !0
395
373
  };
396
374
  } catch (r) {
397
- throw r.name === "NotFoundError" ? new n(`No such file or directory: ${t}`, "ENOENT") : new n("Failed to stat (directory)", "STAT_FAILED");
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);
398
376
  }
399
377
  }
400
378
  /**
@@ -416,7 +394,7 @@ class A {
416
394
  * ```
417
395
  */
418
396
  async readDir(t) {
419
- await this.ensureMounted();
397
+ await this.mount();
420
398
  const e = await this.getDirectoryHandle(t, !1), i = [];
421
399
  for await (const [a, r] of e.entries()) {
422
400
  const s = r.kind === "file";
@@ -444,12 +422,12 @@ class A {
444
422
  * ```
445
423
  */
446
424
  async exists(t) {
447
- if (await this.ensureMounted(), t === "/")
425
+ if (await this.mount(), t === "/")
448
426
  return !0;
449
- const e = d(t);
427
+ const e = g(t);
450
428
  let i = null;
451
429
  try {
452
- i = await this.getDirectoryHandle(y(t), !1);
430
+ i = await this.getDirectoryHandle(f(t), !1);
453
431
  } catch (a) {
454
432
  throw (a.name === "NotFoundError" || a.name === "TypeMismatchError") && (i = null), a;
455
433
  }
@@ -460,14 +438,14 @@ class A {
460
438
  } catch (a) {
461
439
  if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
462
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
+ }
463
448
  }
464
- try {
465
- return await i.getDirectoryHandle(e, { create: !1 }), !0;
466
- } catch (a) {
467
- if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
468
- throw a;
469
- }
470
- return !1;
471
449
  }
472
450
  /**
473
451
  * Clear all contents of a directory without removing the directory itself
@@ -489,7 +467,7 @@ class A {
489
467
  * ```
490
468
  */
491
469
  async clear(t = "/") {
492
- await this.ensureMounted();
470
+ await this.mount();
493
471
  try {
494
472
  const e = await this.readDir(t);
495
473
  for (const i of e) {
@@ -498,7 +476,7 @@ class A {
498
476
  }
499
477
  await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
500
478
  } catch (e) {
501
- throw e instanceof n ? e : new n(`Failed to clear directory: ${t}`, "CLEAR_FAILED");
479
+ throw e instanceof o ? e : new o(`Failed to clear directory: ${t}`, "CLEAR_FAILED", void 0, e);
502
480
  }
503
481
  }
504
482
  /**
@@ -526,23 +504,10 @@ class A {
526
504
  * ```
527
505
  */
528
506
  async remove(t, e) {
529
- await this.ensureMounted();
530
- const i = e?.recursive ?? !1, a = e?.force ?? !1;
531
- if (t === "/")
532
- throw new n("Cannot remove root directory", "EROOT");
533
- const r = d(t);
534
- if (!r)
535
- throw new g("Invalid path", t);
536
- const s = await this.getDirectoryHandle(y(t), !1);
537
- try {
538
- await s.removeEntry(r, { recursive: i });
539
- } catch (o) {
540
- if (o.name === "NotFoundError") {
541
- if (!a)
542
- throw new n(`No such file or directory: ${t}`, "ENOENT");
543
- } 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");
544
- }
545
- 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 });
546
511
  }
547
512
  /**
548
513
  * Resolve a path to an absolute path
@@ -563,14 +528,14 @@ class A {
563
528
  * ```
564
529
  */
565
530
  async realpath(t) {
566
- await this.ensureMounted();
531
+ await this.mount();
567
532
  try {
568
- const e = T(t);
533
+ const e = I(t);
569
534
  if (!await this.exists(e))
570
- throw new f(e);
535
+ throw new w(e);
571
536
  return e;
572
537
  } catch (e) {
573
- throw e instanceof n ? e : new n(`Failed to resolve path: ${t}`, "REALPATH_FAILED");
538
+ throw e instanceof o ? e : new o(`Failed to resolve path: ${t}`, "REALPATH_FAILED", void 0, e);
574
539
  }
575
540
  }
576
541
  /**
@@ -590,13 +555,13 @@ class A {
590
555
  * ```
591
556
  */
592
557
  async rename(t, e) {
593
- await this.ensureMounted();
558
+ await this.mount();
594
559
  try {
595
560
  if (!await this.exists(t))
596
- throw new f(t);
561
+ throw new w(t);
597
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 });
598
563
  } catch (i) {
599
- throw i instanceof n ? i : new n(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED");
564
+ throw i instanceof o ? i : new o(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED", void 0, i);
600
565
  }
601
566
  }
602
567
  /**
@@ -625,47 +590,70 @@ class A {
625
590
  * ```
626
591
  */
627
592
  async copy(t, e, i) {
628
- await this.ensureMounted();
593
+ await this.mount();
629
594
  try {
630
595
  const a = i?.recursive ?? !1, r = i?.force ?? !0;
631
596
  if (!await this.exists(t))
632
- throw new n(`Source does not exist: ${t}`, "ENOENT");
597
+ throw new o(`Source does not exist: ${t}`, "ENOENT", void 0);
633
598
  if (await this.exists(e) && !r)
634
- throw new n(`Destination already exists: ${e}`, "EEXIST");
599
+ throw new o(`Destination already exists: ${e}`, "EEXIST", void 0);
635
600
  if ((await this.stat(t)).isFile) {
636
601
  const h = await this.readFile(t, "binary");
637
602
  await this.writeFile(e, h);
638
603
  } else {
639
604
  if (!a)
640
- throw new n(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
605
+ throw new o(`Cannot copy directory without recursive option: ${t}`, "EISDIR", void 0);
641
606
  await this.mkdir(e, { recursive: !0 });
642
607
  const h = await this.readDir(t);
643
608
  for (const m of h) {
644
- const F = `${t}/${m.name}`, E = `${e}/${m.name}`;
645
- await this.copy(F, E, { recursive: !0, force: r });
609
+ const F = `${t}/${m.name}`, D = `${e}/${m.name}`;
610
+ await this.copy(F, D, { recursive: !0, force: r });
646
611
  }
647
612
  }
648
- await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
649
613
  } catch (a) {
650
- throw a instanceof n ? a : new n(`Failed to copy from ${t} to ${e}`, "CP_FAILED");
614
+ throw a instanceof o ? a : new o(`Failed to copy from ${t} to ${e}`, "CP_FAILED", void 0, a);
651
615
  }
652
616
  }
653
617
  /**
654
618
  * Start watching a file or directory for changes
619
+ *
620
+ * @param path - The path to watch (minimatch syntax allowed)
621
+ * @param options - Watch options
622
+ * @param options.recursive - Whether to watch recursively (default: true)
623
+ * @param options.exclude - Glob pattern(s) to exclude (minimatch).
624
+ * @returns Promise that resolves when watching starts
625
+ *
626
+ * @example
627
+ * ```typescript
628
+ * // Watch entire directory tree recursively (default)
629
+ * await fs.watch('/data');
630
+ *
631
+ * // Watch only immediate children (shallow)
632
+ * await fs.watch('/data', { recursive: false });
633
+ *
634
+ * // Watch a single file
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
+ *
640
+ * ```
655
641
  */
656
- async watch(t) {
657
- await this.ensureMounted();
658
- const e = u(t), i = await this.buildSnapshot(e);
659
- this.watchers.set(e, i), this.watchTimer || (this.watchTimer = setInterval(() => {
660
- this.scanWatches();
661
- }, this.options.watchInterval));
642
+ async watch(t, e) {
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);
662
651
  }
663
652
  /**
664
653
  * Stop watching a previously watched path
665
654
  */
666
655
  unwatch(t) {
667
- const e = u(t);
668
- this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
656
+ this.watchers.delete(t);
669
657
  }
670
658
  /**
671
659
  * Dispose of resources and clean up the file system instance
@@ -674,49 +662,7 @@ class A {
674
662
  * to properly clean up resources like the broadcast channel and watch timers.
675
663
  */
676
664
  dispose() {
677
- this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null), this.watchers.clear();
678
- }
679
- async buildSnapshot(t) {
680
- const e = /* @__PURE__ */ new Map(), i = async (a) => {
681
- const r = await this.stat(a);
682
- if (e.set(a, r), r.isDirectory) {
683
- const s = await this.readDir(a);
684
- for (const o of s) {
685
- const c = `${a === "/" ? "" : a}/${o.name}`;
686
- await i(c);
687
- }
688
- }
689
- };
690
- return await i(t), e;
691
- }
692
- async scanWatches() {
693
- if (!this.scanning) {
694
- this.scanning = !0;
695
- try {
696
- await Promise.all(
697
- [...this.watchers.entries()].map(async ([t, e]) => {
698
- let i;
699
- try {
700
- i = await this.buildSnapshot(t);
701
- } catch {
702
- i = /* @__PURE__ */ new Map();
703
- }
704
- for (const [a, r] of i) {
705
- const s = e.get(a);
706
- s ? (s.mtime !== r.mtime || s.size !== r.size) && await this.notifyChange({ path: a, type: "changed", isDirectory: r.isDirectory }) : await this.notifyChange({ path: a, type: "added", isDirectory: r.isDirectory });
707
- }
708
- for (const a of e.keys())
709
- if (!i.has(a)) {
710
- const r = e.get(a);
711
- await this.notifyChange({ path: a, type: "removed", isDirectory: r?.isDirectory ?? !1 });
712
- }
713
- this.watchers.set(t, i);
714
- })
715
- );
716
- } finally {
717
- this.scanning = !1;
718
- }
719
- }
665
+ this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.watchers.clear();
720
666
  }
721
667
  /**
722
668
  * Synchronize the file system with external data
@@ -747,22 +693,21 @@ class A {
747
693
  * ```
748
694
  */
749
695
  async sync(t, e) {
750
- await this.ensureMounted();
696
+ await this.mount();
751
697
  try {
752
698
  (e?.cleanBefore ?? !1) && await this.clear("/");
753
699
  for (const [a, r] of t) {
754
- const s = u(a);
755
- let o;
756
- r instanceof Blob ? o = await b(r) : o = r, await this.writeFile(s, o);
700
+ const s = y(a);
701
+ let n;
702
+ r instanceof Blob ? n = await O(r) : n = r, await this.writeFile(s, n);
757
703
  }
758
- await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
759
704
  } catch (i) {
760
- throw i instanceof n ? i : new n("Failed to sync file system", "SYNC_FAILED");
705
+ throw i instanceof o ? i : new o("Failed to sync file system", "SYNC_FAILED", void 0, i);
761
706
  }
762
707
  }
763
708
  }
764
- typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && p(new A());
709
+ typeof globalThis < "u" && globalThis.constructor.name === "DedicatedWorkerGlobalScope" && E(new $());
765
710
  export {
766
- A as OPFSWorker
711
+ $ as OPFSWorker
767
712
  };
768
713
  //# sourceMappingURL=raw.js.map