opfs-worker 0.2.3 → 0.2.5

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,6 +1,6 @@
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 $ {
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 I, o as v, F as f, w as F, j as T, e as y, f as u, k as M, r as A, n as d, l as $ } from "./helpers-3TGPHd1h.js";
3
+ class O {
4
4
  /** Root directory handle for the file system */
5
5
  root = null;
6
6
  /** Watch event callback */
@@ -15,15 +15,45 @@ class $ {
15
15
  scanning = !1;
16
16
  /** Promise to prevent concurrent mount operations */
17
17
  mountingPromise = null;
18
+ /** Hash algorithm for file hashing (null means no hashing) */
19
+ hashAlgorithm = null;
20
+ /**
21
+ * Notify about internal changes to the file system
22
+ *
23
+ * This method is called by internal operations to notify clients about
24
+ * changes, even when no specific paths are being watched.
25
+ *
26
+ * @param path - The path that was changed
27
+ * @param type - The type of change (create, change, delete)
28
+ */
29
+ async notifyChange(t) {
30
+ if (!this.watchCallback)
31
+ return;
32
+ let e;
33
+ if (this.hashAlgorithm && !t.isDirectory && t.type !== "removed")
34
+ try {
35
+ const i = await this.stat(t.path);
36
+ i.isFile && i.hash && (e = i.hash);
37
+ } catch (i) {
38
+ console.warn(`Failed to calculate hash for ${t.path}:`, i);
39
+ }
40
+ this.watchCallback({
41
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
42
+ ...t,
43
+ ...e && { hash: e }
44
+ });
45
+ }
18
46
  /**
19
47
  * Creates a new OPFSFileSystem instance
20
48
  *
21
49
  * @param watchCallback - Optional callback for file change events
22
- * @param watchOptions - Optional configuration for watching
50
+ * @param options - Optional configuration options
51
+ * @param options.watchInterval - Polling interval in milliseconds for file watching
52
+ * @param options.hashAlgorithm - Hash algorithm for file hashing
23
53
  * @throws {OPFSError} If OPFS is not supported in the current browser
24
54
  */
25
55
  constructor(t, e) {
26
- I(), t && (this.watchCallback = t, e?.watchInterval && (this.watchInterval = e.watchInterval)), this.mount("/");
56
+ S(), t && (this.watchCallback = t), e && this.setOptions(e), this.mount("/");
27
57
  }
28
58
  /**
29
59
  * Initialize the file system within a given directory
@@ -53,7 +83,7 @@ class $ {
53
83
  const r = await navigator.storage.getDirectory();
54
84
  t === "/" ? this.root = r : this.root = await this.getDirectoryHandle(t, !0, r), e(!0);
55
85
  } catch (r) {
56
- console.error(r), i(new o("Failed to initialize OPFS", "INIT_FAILED"));
86
+ console.error(r), i(new n("Failed to initialize OPFS", "INIT_FAILED"));
57
87
  } finally {
58
88
  this.mountingPromise = null;
59
89
  }
@@ -63,10 +93,19 @@ class $ {
63
93
  * Set the watch callback for file change events
64
94
  *
65
95
  * @param callback - The callback function to invoke when files change
66
- * @param options - Optional configuration for watching
67
96
  */
68
- setWatchCallback(t, e) {
69
- this.watchCallback = t, e?.watchInterval && (this.watchInterval = e.watchInterval);
97
+ setWatchCallback(t) {
98
+ this.watchCallback = t;
99
+ }
100
+ /**
101
+ * Set configuration options for the file system
102
+ *
103
+ * @param options - Configuration options to update
104
+ * @param options.watchInterval - Polling interval in milliseconds for file watching
105
+ * @param options.hashAlgorithm - Hash algorithm for file hashing
106
+ */
107
+ setOptions(t) {
108
+ t.watchInterval !== void 0 && (this.watchInterval = t.watchInterval), t.hashAlgorithm !== void 0 && (this.hashAlgorithm = t.hashAlgorithm);
70
109
  }
71
110
  /**
72
111
  * Automatically mount the OPFS root if not already mounted
@@ -83,7 +122,7 @@ class $ {
83
122
  await this.mountingPromise;
84
123
  return;
85
124
  }
86
- throw new o("OPFS not mounted", "NOT_MOUNTED");
125
+ throw new n("OPFS not mounted", "NOT_MOUNTED");
87
126
  }
88
127
  }
89
128
  /**
@@ -106,11 +145,11 @@ class $ {
106
145
  */
107
146
  async getDirectoryHandle(t, e = !1, i = this.root) {
108
147
  if (!i)
109
- throw new f();
110
- const r = Array.isArray(t) ? t : u(t);
148
+ throw new l();
149
+ const r = Array.isArray(t) ? t : w(t);
111
150
  let a = i;
112
- for (const n of r)
113
- a = await a.getDirectoryHandle(n, { create: e });
151
+ for (const s of r)
152
+ a = await a.getDirectoryHandle(s, { create: e });
114
153
  return a;
115
154
  }
116
155
  /**
@@ -134,43 +173,25 @@ class $ {
134
173
  */
135
174
  async getFileHandle(t, e = !1, i = this.root) {
136
175
  if (!i)
137
- throw new f();
138
- const r = u(t);
176
+ throw new l();
177
+ const r = w(t);
139
178
  if (r.length === 0)
140
179
  throw new g("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
141
180
  const a = r.pop();
142
181
  return (await this.getDirectoryHandle(r, e, i)).getFileHandle(a, { create: e });
143
182
  }
144
183
  /**
145
- * Recursively list all files and directories with their stats
184
+ * Get a complete index of all files and directories in the file system
146
185
  *
147
- * Traverses the entire file system starting from the root and returns
148
- * a Map containing all paths and their corresponding file statistics.
186
+ * This method recursively traverses the entire file system and returns
187
+ * a Map containing FileStat objects for every file and directory.
149
188
  *
150
- * @param options - Options for indexing
151
- * @param options.includeHash - Whether to calculate file hash (default: false)
152
- * @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
153
- * @returns Promise that resolves to a Map of path => FileStat
154
- * @throws {OPFSError} If the indexing operation fails
189
+ * @returns Promise that resolves to a Map of paths to FileStat objects
190
+ * @throws {OPFSError} If the file system is not mounted
155
191
  *
156
192
  * @example
157
193
  * ```typescript
158
- * // Basic index without hash
159
194
  * const index = await fs.index();
160
- *
161
- * // Index with file hash
162
- * const indexWithHash = await fs.index({
163
- * includeHash: true,
164
- * hashAlgorithm: 'SHA-1'
165
- * });
166
- *
167
- * // Iterate through all files and directories
168
- * for (const [path, stat] of index) {
169
- * console.log(`${path}: ${stat.isFile ? 'file' : 'directory'} (${stat.size} bytes)`);
170
- * if (stat.hash) console.log(` Hash: ${stat.hash}`);
171
- * }
172
- *
173
- * // Get specific file stats
174
195
  * const fileStats = index.get('/data/config.json');
175
196
  * if (fileStats) {
176
197
  * console.log(`File size: ${fileStats.size} bytes`);
@@ -178,35 +199,35 @@ class $ {
178
199
  * }
179
200
  * ```
180
201
  */
181
- async index(t) {
182
- const e = /* @__PURE__ */ new Map(), i = async (r) => {
183
- const a = await this.readdir(r, { withFileTypes: !0 });
184
- for (const n of a) {
185
- const s = `${r === "/" ? "" : r}/${n.name}`;
202
+ async index() {
203
+ const t = /* @__PURE__ */ new Map(), e = async (i) => {
204
+ const r = await this.readdir(i, { withFileTypes: !0 });
205
+ for (const a of r) {
206
+ const s = `${i === "/" ? "" : i}/${a.name}`;
186
207
  try {
187
- const c = await this.stat(s, t);
188
- e.set(s, c), c.isDirectory && await i(s);
189
- } catch (c) {
190
- console.warn(`Skipping broken entry: ${s}`, c);
208
+ const o = await this.stat(s);
209
+ t.set(s, o), o.isDirectory && await e(s);
210
+ } catch (o) {
211
+ console.warn(`Skipping broken entry: ${s}`, o);
191
212
  }
192
213
  }
193
214
  };
194
- return e.set("/", {
215
+ return t.set("/", {
195
216
  kind: "directory",
196
217
  size: 0,
197
218
  mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
198
219
  ctime: (/* @__PURE__ */ new Date(0)).toISOString(),
199
220
  isFile: !1,
200
221
  isDirectory: !0
201
- }), await i("/"), e;
222
+ }), await e("/"), t;
202
223
  }
203
224
  async readFile(t, e = "utf-8") {
204
225
  await this.ensureMounted();
205
226
  try {
206
- const i = await this.getFileHandle(t, !1), r = await p(i);
207
- return e === "binary" ? r : S(r, e);
227
+ const i = await this.getFileHandle(t, !1), r = await I(i);
228
+ return e === "binary" ? r : v(r, e);
208
229
  } catch (i) {
209
- throw console.error(i), new d(t);
230
+ throw console.error(i), new f(t);
210
231
  }
211
232
  }
212
233
  /**
@@ -237,7 +258,7 @@ class $ {
237
258
  async writeFile(t, e, i) {
238
259
  await this.ensureMounted();
239
260
  const r = await this.getFileHandle(t, !0);
240
- await E(r, e, i, { truncate: !0 });
261
+ await F(r, e, i, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
241
262
  }
242
263
  /**
243
264
  * Append data to a file
@@ -264,7 +285,7 @@ class $ {
264
285
  async appendFile(t, e, i) {
265
286
  await this.ensureMounted();
266
287
  const r = await this.getFileHandle(t, !0);
267
- await E(r, e, i, { append: !0 });
288
+ await F(r, e, i, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
268
289
  }
269
290
  /**
270
291
  * Create a directory
@@ -289,51 +310,45 @@ class $ {
289
310
  */
290
311
  async mkdir(t, e) {
291
312
  if (await this.ensureMounted(), !this.root)
292
- throw new f();
293
- const i = e?.recursive ?? !1, r = u(t);
313
+ throw new l();
314
+ const i = e?.recursive ?? !1, r = w(t);
294
315
  let a = this.root;
295
- for (let n = 0; n < r.length; n++) {
296
- const s = r[n];
316
+ for (let s = 0; s < r.length; s++) {
317
+ const o = r[s];
297
318
  try {
298
- a = await a.getDirectoryHandle(s, { create: i || n === r.length - 1 });
319
+ a = await a.getDirectoryHandle(o, { create: i || s === r.length - 1 });
299
320
  } catch (c) {
300
- throw c.name === "NotFoundError" ? new o(
301
- `Parent directory does not exist: ${T(r.slice(0, n + 1))}`,
321
+ throw c.name === "NotFoundError" ? new n(
322
+ `Parent directory does not exist: ${T(r.slice(0, s + 1))}`,
302
323
  "ENOENT"
303
- ) : c.name === "TypeMismatchError" ? new o(`Path segment is not a directory: ${s}`, "ENOTDIR") : new o("Failed to create directory", "MKDIR_FAILED");
324
+ ) : c.name === "TypeMismatchError" ? new n(`Path segment is not a directory: ${o}`, "ENOTDIR") : new n("Failed to create directory", "MKDIR_FAILED");
304
325
  }
305
326
  }
327
+ await this.notifyChange({ path: t, type: "added", isDirectory: !0 });
306
328
  }
307
329
  /**
308
- * Get file or directory stats
330
+ * Get file or directory statistics
309
331
  *
310
- * Retrieves metadata about a file or directory, including size, modification time,
311
- * type information, and optionally file hashes.
332
+ * Returns detailed information about a file or directory, including
333
+ * size, modification time, and optionally a hash of the file content.
312
334
  *
313
335
  * @param path - The path to the file or directory
314
- * @param options - Options for stat operation
315
- * @param options.includeHash - Whether to calculate file hash (default: false, only for files)
316
- * @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
317
- * @returns Promise that resolves to file/directory statistics
318
- * @throws {OPFSError} If the file or directory does not exist or cannot be accessed
336
+ * @returns Promise that resolves to FileStat object
337
+ * @throws {OPFSError} If the path does not exist or cannot be accessed
319
338
  *
320
339
  * @example
321
340
  * ```typescript
322
- * // Basic stats
323
- * const stats = await fs.stat('/config/settings.json');
341
+ * const stats = await fs.stat('/data/config.json');
324
342
  * console.log(`File size: ${stats.size} bytes`);
325
- * console.log(`Is file: ${stats.isFile}`);
326
- * console.log(`Modified: ${stats.mtime}`);
327
- *
328
- * // Stats with hash (SHA-1 is fastest)
329
- * const statsWithHash = await fs.stat('/config/settings.json', {
330
- * includeHash: true,
331
- * hashAlgorithm: 'SHA-1'
332
- * });
333
- * console.log(`Hash: ${statsWithHash.hash}`);
343
+ * console.log(`Last modified: ${stats.mtime}`);
344
+ *
345
+ * // If hashing is enabled, hash will be included
346
+ * if (stats.hash) {
347
+ * console.log(`Hash: ${stats.hash}`);
348
+ * }
334
349
  * ```
335
350
  */
336
- async stat(t, e) {
351
+ async stat(t) {
337
352
  if (await this.ensureMounted(), t === "/")
338
353
  return {
339
354
  kind: "directory",
@@ -343,30 +358,30 @@ class $ {
343
358
  isFile: !1,
344
359
  isDirectory: !0
345
360
  };
346
- const i = m(t), r = await this.getDirectoryHandle(y(t), !1), a = e?.includeHash ?? !1, n = e?.hashAlgorithm ?? "SHA-1";
361
+ const e = y(t), i = await this.getDirectoryHandle(u(t), !1), r = this.hashAlgorithm !== null;
347
362
  try {
348
- const c = await (await r.getFileHandle(i, { create: !1 })).getFile(), l = {
363
+ const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), o = {
349
364
  kind: "file",
350
- size: c.size,
351
- mtime: new Date(c.lastModified).toISOString(),
352
- ctime: new Date(c.lastModified).toISOString(),
365
+ size: s.size,
366
+ mtime: new Date(s.lastModified).toISOString(),
367
+ ctime: new Date(s.lastModified).toISOString(),
353
368
  isFile: !0,
354
369
  isDirectory: !1
355
370
  };
356
- if (a)
371
+ if (r && this.hashAlgorithm)
357
372
  try {
358
- const h = new Uint8Array(await c.arrayBuffer()), w = await M(h, n);
359
- l.hash = w;
360
- } catch (h) {
361
- console.warn(`Failed to calculate hash for ${t}:`, h);
373
+ const c = await M(s, this.hashAlgorithm);
374
+ o.hash = c;
375
+ } catch (c) {
376
+ console.warn(`Failed to calculate hash for ${t}:`, c);
362
377
  }
363
- return l;
364
- } catch (s) {
365
- if (s.name !== "TypeMismatchError" && s.name !== "NotFoundError")
366
- throw new o("Failed to stat (file)", "STAT_FAILED");
378
+ return o;
379
+ } catch (a) {
380
+ if (a.name !== "TypeMismatchError" && a.name !== "NotFoundError")
381
+ throw new n("Failed to stat (file)", "STAT_FAILED");
367
382
  }
368
383
  try {
369
- return await r.getDirectoryHandle(i, { create: !1 }), {
384
+ return await i.getDirectoryHandle(e, { create: !1 }), {
370
385
  kind: "directory",
371
386
  size: 0,
372
387
  mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
@@ -374,8 +389,8 @@ class $ {
374
389
  isFile: !1,
375
390
  isDirectory: !0
376
391
  };
377
- } catch (s) {
378
- throw s.name === "NotFoundError" ? new o(`No such file or directory: ${t}`, "ENOENT") : new o("Failed to stat (directory)", "STAT_FAILED");
392
+ } catch (a) {
393
+ throw a.name === "NotFoundError" ? new n(`No such file or directory: ${t}`, "ENOENT") : new n("Failed to stat (directory)", "STAT_FAILED");
379
394
  }
380
395
  }
381
396
  async readdir(t, e) {
@@ -383,11 +398,11 @@ class $ {
383
398
  const i = e?.withFileTypes ?? !1, r = await this.getDirectoryHandle(t, !1);
384
399
  if (i) {
385
400
  const a = [];
386
- for await (const [n, s] of r.entries()) {
387
- const c = s.kind === "file";
401
+ for await (const [s, o] of r.entries()) {
402
+ const c = o.kind === "file";
388
403
  a.push({
389
- name: n,
390
- kind: s.kind,
404
+ name: s,
405
+ kind: o.kind,
391
406
  isFile: c,
392
407
  isDirectory: !c
393
408
  });
@@ -395,8 +410,8 @@ class $ {
395
410
  return a;
396
411
  } else {
397
412
  const a = [];
398
- for await (const [n] of r.entries())
399
- a.push(n);
413
+ for await (const [s] of r.entries())
414
+ a.push(s);
400
415
  return a;
401
416
  }
402
417
  }
@@ -417,10 +432,10 @@ class $ {
417
432
  async exists(t) {
418
433
  if (await this.ensureMounted(), t === "/")
419
434
  return !0;
420
- const e = m(t);
435
+ const e = y(t);
421
436
  let i = null;
422
437
  try {
423
- i = await this.getDirectoryHandle(y(t), !1);
438
+ i = await this.getDirectoryHandle(u(t), !1);
424
439
  } catch (r) {
425
440
  throw (r.name === "NotFoundError" || r.name === "TypeMismatchError") && (i = null), r;
426
441
  }
@@ -467,8 +482,9 @@ class $ {
467
482
  const r = `${t === "/" ? "" : t}/${i.name}`;
468
483
  await this.remove(r, { recursive: !0 });
469
484
  }
485
+ await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
470
486
  } catch (e) {
471
- throw e instanceof o ? e : new o(`Failed to clear directory: ${t}`, "CLEAR_FAILED");
487
+ throw e instanceof n ? e : new n(`Failed to clear directory: ${t}`, "CLEAR_FAILED");
472
488
  }
473
489
  }
474
490
  /**
@@ -499,19 +515,20 @@ class $ {
499
515
  await this.ensureMounted();
500
516
  const i = e?.recursive ?? !1, r = e?.force ?? !1;
501
517
  if (t === "/")
502
- throw new o("Cannot remove root directory", "EROOT");
503
- const a = m(t);
518
+ throw new n("Cannot remove root directory", "EROOT");
519
+ const a = y(t);
504
520
  if (!a)
505
521
  throw new g("Invalid path", t);
506
- const n = await this.getDirectoryHandle(y(t), !1);
522
+ const s = await this.getDirectoryHandle(u(t), !1);
507
523
  try {
508
- await n.removeEntry(a, { recursive: i });
509
- } catch (s) {
510
- if (s.name === "NotFoundError") {
524
+ await s.removeEntry(a, { recursive: i });
525
+ } catch (o) {
526
+ if (o.name === "NotFoundError") {
511
527
  if (!r)
512
- throw new o(`No such file or directory: ${t}`, "ENOENT");
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");
528
+ throw new n(`No such file or directory: ${t}`, "ENOENT");
529
+ } 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");
514
530
  }
531
+ await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
515
532
  }
516
533
  /**
517
534
  * Resolve a path to an absolute path
@@ -534,12 +551,12 @@ class $ {
534
551
  async realpath(t) {
535
552
  await this.ensureMounted();
536
553
  try {
537
- const e = H(t);
554
+ const e = A(t);
538
555
  if (!await this.exists(e))
539
- throw new d(e);
556
+ throw new f(e);
540
557
  return e;
541
558
  } catch (e) {
542
- throw e instanceof o ? e : new o(`Failed to resolve path: ${t}`, "REALPATH_FAILED");
559
+ throw e instanceof n ? e : new n(`Failed to resolve path: ${t}`, "REALPATH_FAILED");
543
560
  }
544
561
  }
545
562
  /**
@@ -562,10 +579,10 @@ class $ {
562
579
  await this.ensureMounted();
563
580
  try {
564
581
  if (!await this.exists(t))
565
- throw new d(t);
566
- await this.copy(t, e, { recursive: !0 }), await this.remove(t, { recursive: !0 });
582
+ throw new f(t);
583
+ 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 });
567
584
  } catch (i) {
568
- throw i instanceof o ? i : new o(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED");
585
+ throw i instanceof n ? i : new n(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED");
569
586
  }
570
587
  }
571
588
  /**
@@ -598,24 +615,25 @@ class $ {
598
615
  try {
599
616
  const r = i?.recursive ?? !1, a = i?.force ?? !0;
600
617
  if (!await this.exists(t))
601
- throw new o(`Source does not exist: ${t}`, "ENOENT");
618
+ throw new n(`Source does not exist: ${t}`, "ENOENT");
602
619
  if (await this.exists(e) && !a)
603
- throw new o(`Destination already exists: ${e}`, "EEXIST");
620
+ throw new n(`Destination already exists: ${e}`, "EEXIST");
604
621
  if ((await this.stat(t)).isFile) {
605
- const l = await this.readFile(t, "binary");
606
- await this.writeFile(e, l);
622
+ const h = await this.readFile(t, "binary");
623
+ await this.writeFile(e, h);
607
624
  } else {
608
625
  if (!r)
609
- throw new o(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
626
+ throw new n(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
610
627
  await this.mkdir(e, { recursive: !0 });
611
- const l = await this.readdir(t, { withFileTypes: !0 });
612
- for (const h of l) {
613
- const w = `${t}/${h.name}`, D = `${e}/${h.name}`;
614
- await this.copy(w, D, { recursive: !0, force: a });
628
+ const h = await this.readdir(t, { withFileTypes: !0 });
629
+ for (const m of h) {
630
+ const D = `${t}/${m.name}`, E = `${e}/${m.name}`;
631
+ await this.copy(D, E, { recursive: !0, force: a });
615
632
  }
616
633
  }
634
+ await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
617
635
  } catch (r) {
618
- throw r instanceof o ? r : new o(`Failed to copy from ${t} to ${e}`, "CP_FAILED");
636
+ throw r instanceof n ? r : new n(`Failed to copy from ${t} to ${e}`, "CP_FAILED");
619
637
  }
620
638
  }
621
639
  /**
@@ -623,7 +641,7 @@ class $ {
623
641
  */
624
642
  async watch(t) {
625
643
  await this.ensureMounted();
626
- const e = F(t), i = await this.buildSnapshot(e);
644
+ const e = d(t), i = await this.buildSnapshot(e);
627
645
  this.watchers.set(e, i), this.watchTimer || (this.watchTimer = setInterval(() => {
628
646
  this.scanWatches();
629
647
  }, this.watchInterval));
@@ -632,16 +650,16 @@ class $ {
632
650
  * Stop watching a previously watched path
633
651
  */
634
652
  unwatch(t) {
635
- const e = F(t);
653
+ const e = d(t);
636
654
  this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
637
655
  }
638
656
  async buildSnapshot(t) {
639
657
  const e = /* @__PURE__ */ new Map(), i = async (r) => {
640
658
  const a = await this.stat(r);
641
659
  if (e.set(r, a), a.isDirectory) {
642
- const n = await this.readdir(r, { withFileTypes: !0 });
643
- for (const s of n) {
644
- const c = `${r === "/" ? "" : r}/${s.name}`;
660
+ const s = await this.readdir(r, { withFileTypes: !0 });
661
+ for (const o of s) {
662
+ const c = `${r === "/" ? "" : r}/${o.name}`;
645
663
  await i(c);
646
664
  }
647
665
  }
@@ -660,16 +678,12 @@ class $ {
660
678
  } catch {
661
679
  i = /* @__PURE__ */ new Map();
662
680
  }
663
- const r = [];
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" });
681
+ for (const [r, a] of i) {
682
+ const s = e.get(r);
683
+ s ? (s.mtime !== a.mtime || s.size !== a.size) && await this.notifyChange({ path: r, type: "changed", isDirectory: !1 }) : await this.notifyChange({ path: r, type: "added", isDirectory: !1 });
667
684
  }
668
- for (const a of e.keys())
669
- i.has(a) || r.push({ path: a, type: "delete" });
670
- if (r.length && this.watchCallback)
671
- for (const a of r)
672
- this.watchCallback(a);
685
+ for (const r of e.keys())
686
+ i.has(r) || await this.notifyChange({ path: r, type: "removed", isDirectory: !1 });
673
687
  this.watchers.set(t, i);
674
688
  })
675
689
  );
@@ -711,17 +725,18 @@ class $ {
711
725
  try {
712
726
  (e?.cleanBefore ?? !1) && await this.clear("/");
713
727
  for (const [r, a] of t) {
714
- const n = F(r);
715
- let s;
716
- a instanceof Blob ? s = await P(a) : s = a, await this.writeFile(n, s);
728
+ const s = d(r);
729
+ let o;
730
+ a instanceof Blob ? o = await $(a) : o = a, await this.writeFile(s, o);
717
731
  }
732
+ await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
718
733
  } catch (i) {
719
- throw i instanceof o ? i : new o("Failed to sync file system", "SYNC_FAILED");
734
+ throw i instanceof n ? i : new n("Failed to sync file system", "SYNC_FAILED");
720
735
  }
721
736
  }
722
737
  }
723
- typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && v(new $());
738
+ typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && p(new O());
724
739
  export {
725
- $ as OPFSWorker
740
+ O as OPFSWorker
726
741
  };
727
742
  //# sourceMappingURL=raw.js.map