opfs-worker 0.1.2 → 0.2.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/index.cjs CHANGED
@@ -1,19 +1,19 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("comlink"),a=`/**
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("comlink"),a=`/**
2
2
  * @license
3
3
  * Copyright 2019 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- const C = Symbol("Comlink.proxy"), v = Symbol("Comlink.endpoint"), _ = Symbol("Comlink.releaseProxy"), D = Symbol("Comlink.finalizer"), p = Symbol("Comlink.thrown"), M = (e) => typeof e == "object" && e !== null || typeof e == "function", R = {
7
- canHandle: (e) => M(e) && e[C],
6
+ const k = Symbol("Comlink.proxy"), U = Symbol("Comlink.endpoint"), z = Symbol("Comlink.releaseProxy"), T = Symbol("Comlink.finalizer"), E = Symbol("Comlink.thrown"), C = (e) => typeof e == "object" && e !== null || typeof e == "function", _ = {
7
+ canHandle: (e) => C(e) && e[k],
8
8
  serialize(e) {
9
9
  const { port1: t, port2: r } = new MessageChannel();
10
- return O(e, t), [r, [r]];
10
+ return x(e, t), [r, [r]];
11
11
  },
12
12
  deserialize(e) {
13
- return e.start(), V(e);
13
+ return e.start(), j(e);
14
14
  }
15
- }, z = {
16
- canHandle: (e) => M(e) && p in e,
15
+ }, R = {
16
+ canHandle: (e) => C(e) && E in e,
17
17
  serialize({ value: e }) {
18
18
  let t;
19
19
  return e instanceof Error ? t = {
@@ -28,187 +28,187 @@ const C = Symbol("Comlink.proxy"), v = Symbol("Comlink.endpoint"), _ = Symbol("C
28
28
  deserialize(e) {
29
29
  throw e.isError ? Object.assign(new Error(e.value.message), e.value) : e.value;
30
30
  }
31
- }, k = /* @__PURE__ */ new Map([
32
- ["proxy", R],
33
- ["throw", z]
31
+ }, M = /* @__PURE__ */ new Map([
32
+ ["proxy", _],
33
+ ["throw", R]
34
34
  ]);
35
- function B(e, t) {
35
+ function W(e, t) {
36
36
  for (const r of e)
37
37
  if (t === r || r === "*" || r instanceof RegExp && r.test(t))
38
38
  return !0;
39
39
  return !1;
40
40
  }
41
- function O(e, t = globalThis, r = ["*"]) {
41
+ function x(e, t = globalThis, r = ["*"]) {
42
42
  t.addEventListener("message", function a(n) {
43
43
  if (!n || !n.data)
44
44
  return;
45
- if (!B(r, n.origin)) {
45
+ if (!W(r, n.origin)) {
46
46
  console.warn(\`Invalid origin '\${n.origin}' for comlink proxy\`);
47
47
  return;
48
48
  }
49
- const { id: o, type: s, path: c } = Object.assign({ path: [] }, n.data), i = (n.data.argumentList || []).map(d);
50
- let u;
49
+ const { id: s, type: i, path: o } = Object.assign({ path: [] }, n.data), c = (n.data.argumentList || []).map(d);
50
+ let f;
51
51
  try {
52
- const f = c.slice(0, -1).reduce((h, g) => h[g], e), w = c.reduce((h, g) => h[g], e);
53
- switch (s) {
52
+ const u = o.slice(0, -1).reduce((h, g) => h[g], e), w = o.reduce((h, g) => h[g], e);
53
+ switch (i) {
54
54
  case "GET":
55
- u = w;
55
+ f = w;
56
56
  break;
57
57
  case "SET":
58
- f[c.slice(-1)[0]] = d(n.data.value), u = !0;
58
+ u[o.slice(-1)[0]] = d(n.data.value), f = !0;
59
59
  break;
60
60
  case "APPLY":
61
- u = w.apply(f, i);
61
+ f = w.apply(u, c);
62
62
  break;
63
63
  case "CONSTRUCT":
64
64
  {
65
- const h = new w(...i);
66
- u = q(h);
65
+ const h = new w(...c);
66
+ f = q(h);
67
67
  }
68
68
  break;
69
69
  case "ENDPOINT":
70
70
  {
71
71
  const { port1: h, port2: g } = new MessageChannel();
72
- O(e, g), u = X(h, [h]);
72
+ x(e, g), f = X(h, [h]);
73
73
  }
74
74
  break;
75
75
  case "RELEASE":
76
- u = void 0;
76
+ f = void 0;
77
77
  break;
78
78
  default:
79
79
  return;
80
80
  }
81
- } catch (f) {
82
- u = { value: f, [p]: 0 };
81
+ } catch (u) {
82
+ f = { value: u, [E]: 0 };
83
83
  }
84
- Promise.resolve(u).catch((f) => ({ value: f, [p]: 0 })).then((f) => {
85
- const [w, h] = S(f);
86
- t.postMessage(Object.assign(Object.assign({}, w), { id: o }), h), s === "RELEASE" && (t.removeEventListener("message", a), $(t), D in e && typeof e[D] == "function" && e[D]());
87
- }).catch((f) => {
88
- const [w, h] = S({
84
+ Promise.resolve(f).catch((u) => ({ value: u, [E]: 0 })).then((u) => {
85
+ const [w, h] = A(u);
86
+ t.postMessage(Object.assign(Object.assign({}, w), { id: s }), h), i === "RELEASE" && (t.removeEventListener("message", a), v(t), T in e && typeof e[T] == "function" && e[T]());
87
+ }).catch((u) => {
88
+ const [w, h] = A({
89
89
  value: new TypeError("Unserializable return value"),
90
- [p]: 0
90
+ [E]: 0
91
91
  });
92
- t.postMessage(Object.assign(Object.assign({}, w), { id: o }), h);
92
+ t.postMessage(Object.assign(Object.assign({}, w), { id: s }), h);
93
93
  });
94
94
  }), t.start && t.start();
95
95
  }
96
- function j(e) {
96
+ function B(e) {
97
97
  return e.constructor.name === "MessagePort";
98
98
  }
99
- function $(e) {
100
- j(e) && e.close();
99
+ function v(e) {
100
+ B(e) && e.close();
101
101
  }
102
- function V(e, t) {
102
+ function j(e, t) {
103
103
  const r = /* @__PURE__ */ new Map();
104
104
  return e.addEventListener("message", function(n) {
105
- const { data: o } = n;
106
- if (!o || !o.id)
105
+ const { data: s } = n;
106
+ if (!s || !s.id)
107
107
  return;
108
- const s = r.get(o.id);
109
- if (s)
108
+ const i = r.get(s.id);
109
+ if (i)
110
110
  try {
111
- s(o);
111
+ i(s);
112
112
  } finally {
113
- r.delete(o.id);
113
+ r.delete(s.id);
114
114
  }
115
- }), b(e, r, [], t);
115
+ }), I(e, r, [], t);
116
116
  }
117
- function E(e) {
117
+ function p(e) {
118
118
  if (e)
119
119
  throw new Error("Proxy has been released and is not useable");
120
120
  }
121
- function L(e) {
121
+ function $(e) {
122
122
  return m(e, /* @__PURE__ */ new Map(), {
123
123
  type: "RELEASE"
124
124
  }).then(() => {
125
- $(e);
125
+ v(e);
126
126
  });
127
127
  }
128
- const F = /* @__PURE__ */ new WeakMap(), A = "FinalizationRegistry" in globalThis && new FinalizationRegistry((e) => {
128
+ const F = /* @__PURE__ */ new WeakMap(), S = "FinalizationRegistry" in globalThis && new FinalizationRegistry((e) => {
129
129
  const t = (F.get(e) || 0) - 1;
130
- F.set(e, t), t === 0 && L(e);
130
+ F.set(e, t), t === 0 && $(e);
131
131
  });
132
- function W(e, t) {
132
+ function V(e, t) {
133
133
  const r = (F.get(t) || 0) + 1;
134
- F.set(t, r), A && A.register(e, t, e);
134
+ F.set(t, r), S && S.register(e, t, e);
135
135
  }
136
- function Y(e) {
137
- A && A.unregister(e);
136
+ function G(e) {
137
+ S && S.unregister(e);
138
138
  }
139
- function b(e, t, r = [], a = function() {
139
+ function I(e, t, r = [], a = function() {
140
140
  }) {
141
141
  let n = !1;
142
- const o = new Proxy(a, {
143
- get(s, c) {
144
- if (E(n), c === _)
142
+ const s = new Proxy(a, {
143
+ get(i, o) {
144
+ if (p(n), o === z)
145
145
  return () => {
146
- Y(o), L(e), t.clear(), n = !0;
146
+ G(s), $(e), t.clear(), n = !0;
147
147
  };
148
- if (c === "then") {
148
+ if (o === "then") {
149
149
  if (r.length === 0)
150
- return { then: () => o };
151
- const i = m(e, t, {
150
+ return { then: () => s };
151
+ const c = m(e, t, {
152
152
  type: "GET",
153
- path: r.map((u) => u.toString())
153
+ path: r.map((f) => f.toString())
154
154
  }).then(d);
155
- return i.then.bind(i);
155
+ return c.then.bind(c);
156
156
  }
157
- return b(e, t, [...r, c]);
157
+ return I(e, t, [...r, o]);
158
158
  },
159
- set(s, c, i) {
160
- E(n);
161
- const [u, f] = S(i);
159
+ set(i, o, c) {
160
+ p(n);
161
+ const [f, u] = A(c);
162
162
  return m(e, t, {
163
163
  type: "SET",
164
- path: [...r, c].map((w) => w.toString()),
165
- value: u
166
- }, f).then(d);
164
+ path: [...r, o].map((w) => w.toString()),
165
+ value: f
166
+ }, u).then(d);
167
167
  },
168
- apply(s, c, i) {
169
- E(n);
170
- const u = r[r.length - 1];
171
- if (u === v)
168
+ apply(i, o, c) {
169
+ p(n);
170
+ const f = r[r.length - 1];
171
+ if (f === U)
172
172
  return m(e, t, {
173
173
  type: "ENDPOINT"
174
174
  }).then(d);
175
- if (u === "bind")
176
- return b(e, t, r.slice(0, -1));
177
- const [f, w] = I(i);
175
+ if (f === "bind")
176
+ return I(e, t, r.slice(0, -1));
177
+ const [u, w] = O(c);
178
178
  return m(e, t, {
179
179
  type: "APPLY",
180
180
  path: r.map((h) => h.toString()),
181
- argumentList: f
181
+ argumentList: u
182
182
  }, w).then(d);
183
183
  },
184
- construct(s, c) {
185
- E(n);
186
- const [i, u] = I(c);
184
+ construct(i, o) {
185
+ p(n);
186
+ const [c, f] = O(o);
187
187
  return m(e, t, {
188
188
  type: "CONSTRUCT",
189
- path: r.map((f) => f.toString()),
190
- argumentList: i
191
- }, u).then(d);
189
+ path: r.map((u) => u.toString()),
190
+ argumentList: c
191
+ }, f).then(d);
192
192
  }
193
193
  });
194
- return W(o, e), o;
194
+ return V(s, e), s;
195
195
  }
196
- function G(e) {
196
+ function Y(e) {
197
197
  return Array.prototype.concat.apply([], e);
198
198
  }
199
- function I(e) {
200
- const t = e.map(S);
201
- return [t.map((r) => r[0]), G(t.map((r) => r[1]))];
199
+ function O(e) {
200
+ const t = e.map(A);
201
+ return [t.map((r) => r[0]), Y(t.map((r) => r[1]))];
202
202
  }
203
- const U = /* @__PURE__ */ new WeakMap();
203
+ const L = /* @__PURE__ */ new WeakMap();
204
204
  function X(e, t) {
205
- return U.set(e, t), e;
205
+ return L.set(e, t), e;
206
206
  }
207
207
  function q(e) {
208
- return Object.assign(e, { [C]: !0 });
208
+ return Object.assign(e, { [k]: !0 });
209
209
  }
210
- function S(e) {
211
- for (const [t, r] of k)
210
+ function A(e) {
211
+ for (const [t, r] of M)
212
212
  if (r.canHandle(e)) {
213
213
  const [a, n] = r.serialize(e);
214
214
  return [
@@ -225,21 +225,21 @@ function S(e) {
225
225
  type: "RAW",
226
226
  value: e
227
227
  },
228
- U.get(e) || []
228
+ L.get(e) || []
229
229
  ];
230
230
  }
231
231
  function d(e) {
232
232
  switch (e.type) {
233
233
  case "HANDLER":
234
- return k.get(e.name).deserialize(e.value);
234
+ return M.get(e.name).deserialize(e.value);
235
235
  case "RAW":
236
236
  return e.value;
237
237
  }
238
238
  }
239
239
  function m(e, t, r, a) {
240
240
  return new Promise((n) => {
241
- const o = K();
242
- t.set(o, n), e.start && e.start(), e.postMessage(Object.assign({ id: o }, r), a);
241
+ const s = K();
242
+ t.set(s, n), e.start && e.start(), e.postMessage(Object.assign({ id: s }, r), a);
243
243
  });
244
244
  }
245
245
  function K() {
@@ -255,17 +255,17 @@ class J extends l {
255
255
  super("OPFS is not supported in this browser", "OPFS_NOT_SUPPORTED");
256
256
  }
257
257
  }
258
- class T extends l {
258
+ class D extends l {
259
259
  constructor() {
260
260
  super("OPFS is not mounted", "OPFS_NOT_MOUNTED");
261
261
  }
262
262
  }
263
- class N extends l {
263
+ class P extends l {
264
264
  constructor(t, r) {
265
265
  super(t, "INVALID_PATH", r);
266
266
  }
267
267
  }
268
- class x extends l {
268
+ class b extends l {
269
269
  constructor(t) {
270
270
  super(\`File not found: \${t}\`, "FILE_NOT_FOUND", t);
271
271
  }
@@ -350,13 +350,13 @@ function ae() {
350
350
  function y(e) {
351
351
  return Array.isArray(e) ? e : e.split("/").filter(Boolean);
352
352
  }
353
- function P(e) {
353
+ function N(e) {
354
354
  return typeof e == "string" ? e ?? "/" : \`/\${e.join("/")}\`;
355
355
  }
356
- function oe(e, t = "utf-8") {
356
+ function se(e, t = "utf-8") {
357
357
  return typeof e == "string" ? Q(e, t) : e instanceof Uint8Array ? e : new Uint8Array(e);
358
358
  }
359
- async function se(e) {
359
+ async function ie(e) {
360
360
  const t = await e.createSyncAccessHandle();
361
361
  try {
362
362
  const r = t.getSize(), a = new Uint8Array(r);
@@ -369,12 +369,12 @@ async function H(e, t, r, a = {}) {
369
369
  let n = null;
370
370
  try {
371
371
  n = await e.createSyncAccessHandle();
372
- const o = oe(t, r), s = a.append ? n.getSize() : 0;
373
- n.write(o, { at: s }), a.truncate && !a.append && n.truncate(o.byteLength), n.flush();
374
- } catch (o) {
375
- console.error(o);
376
- const s = a.append ? "append" : "write";
377
- throw new l(\`Failed to \${s} file\`, \`\${s.toUpperCase()}_FAILED\`);
372
+ const s = se(t, r), i = a.append ? n.getSize() : 0;
373
+ n.write(s, { at: i }), a.truncate && !a.append && n.truncate(s.byteLength), n.flush();
374
+ } catch (s) {
375
+ console.error(s);
376
+ const i = a.append ? "append" : "write";
377
+ throw new l(\`Failed to \${i} file\`, \`\${i.toUpperCase()}_FAILED\`);
378
378
  } finally {
379
379
  if (n)
380
380
  try {
@@ -383,10 +383,10 @@ async function H(e, t, r, a = {}) {
383
383
  }
384
384
  }
385
385
  }
386
- async function ie(e, t = "SHA-1") {
386
+ async function oe(e, t = "SHA-1") {
387
387
  try {
388
388
  const r = new Uint8Array(e), a = await crypto.subtle.digest(t, r);
389
- return Array.from(new Uint8Array(a)).map((o) => o.toString(16).padStart(2, "0")).join("");
389
+ return Array.from(new Uint8Array(a)).map((s) => s.toString(16).padStart(2, "0")).join("");
390
390
  } catch (r) {
391
391
  throw console.warn(\`Failed to calculate \${t} hash:\`, r), r;
392
392
  }
@@ -394,6 +394,16 @@ async function ie(e, t = "SHA-1") {
394
394
  class ce {
395
395
  /** Root directory handle for the file system */
396
396
  root = null;
397
+ /** Watch event callback */
398
+ watchCallback = null;
399
+ /** Map of watched paths to their last known state */
400
+ watchers = /* @__PURE__ */ new Map();
401
+ /** Interval handle for polling watched paths */
402
+ watchTimer = null;
403
+ /** Polling interval in milliseconds */
404
+ watchInterval = 1e3;
405
+ /** Flag to avoid concurrent scans */
406
+ scanning = !1;
397
407
  /**
398
408
  * Creates a new OPFSFileSystem instance
399
409
  *
@@ -418,12 +428,12 @@ class ce {
418
428
  * const success = await fs.init('/my-app');
419
429
  * \`\`\`
420
430
  */
421
- async mount(t = "/") {
431
+ async mount(t = "/", r, a) {
422
432
  try {
423
- const r = await navigator.storage.getDirectory();
424
- return this.root = await this.getDirectoryHandle(t, !0, r), !0;
425
- } catch (r) {
426
- throw console.error(r), new l("Failed to initialize OPFS", "INIT_FAILED");
433
+ const n = await navigator.storage.getDirectory();
434
+ return this.root = await this.getDirectoryHandle(t, !0, n), r && (this.watchCallback = r, a?.watchInterval && (this.watchInterval = a.watchInterval)), !0;
435
+ } catch (n) {
436
+ throw console.error(n), new l("Failed to initialize OPFS", "INIT_FAILED");
427
437
  }
428
438
  }
429
439
  /**
@@ -446,12 +456,12 @@ class ce {
446
456
  */
447
457
  async getDirectoryHandle(t, r = !1, a = this.root) {
448
458
  if (!a)
449
- throw new T();
459
+ throw new D();
450
460
  const n = Array.isArray(t) ? t : y(t);
451
- let o = a;
452
- for (const s of n)
453
- o = await o.getDirectoryHandle(s, { create: r });
454
- return o;
461
+ let s = a;
462
+ for (const i of n)
463
+ s = await s.getDirectoryHandle(i, { create: r });
464
+ return s;
455
465
  }
456
466
  /**
457
467
  * Get a file handle from a path
@@ -474,12 +484,12 @@ class ce {
474
484
  */
475
485
  async getFileHandle(t, r = !1, a = this.root) {
476
486
  if (!a)
477
- throw new T();
487
+ throw new D();
478
488
  const n = y(t);
479
489
  if (n.length === 0)
480
- throw new N("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
481
- const o = n.pop();
482
- return (await this.getDirectoryHandle(n, r, a)).getFileHandle(o, { create: r });
490
+ throw new P("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
491
+ const s = n.pop();
492
+ return (await this.getDirectoryHandle(n, r, a)).getFileHandle(s, { create: r });
483
493
  }
484
494
  /**
485
495
  * Recursively list all files and directories with their stats
@@ -520,14 +530,14 @@ class ce {
520
530
  */
521
531
  async index(t) {
522
532
  const r = /* @__PURE__ */ new Map(), a = async (n) => {
523
- const o = await this.readdir(n, { withFileTypes: !0 });
524
- for (const s of o) {
525
- const c = \`\${n === "/" ? "" : n}/\${s.name}\`;
533
+ const s = await this.readdir(n, { withFileTypes: !0 });
534
+ for (const i of s) {
535
+ const o = \`\${n === "/" ? "" : n}/\${i.name}\`;
526
536
  try {
527
- const i = await this.stat(c, t);
528
- r.set(c, i), i.isDirectory && await a(c);
529
- } catch (i) {
530
- console.warn(\`Skipping broken entry: \${c}\`, i);
537
+ const c = await this.stat(o, t);
538
+ r.set(o, c), c.isDirectory && await a(o);
539
+ } catch (c) {
540
+ console.warn(\`Skipping broken entry: \${o}\`, c);
531
541
  }
532
542
  }
533
543
  };
@@ -542,10 +552,10 @@ class ce {
542
552
  }
543
553
  async readFile(t, r = "utf-8") {
544
554
  try {
545
- const a = await this.getFileHandle(t, !1), n = await se(a);
555
+ const a = await this.getFileHandle(t, !1), n = await ie(a);
546
556
  return r === "binary" ? n : Z(n, r);
547
557
  } catch (a) {
548
- throw console.error(a), new x(t);
558
+ throw console.error(a), new b(t);
549
559
  }
550
560
  }
551
561
  /**
@@ -626,18 +636,18 @@ class ce {
626
636
  */
627
637
  async mkdir(t, r) {
628
638
  if (!this.root)
629
- throw new T();
639
+ throw new D();
630
640
  const a = r?.recursive ?? !1, n = y(t);
631
- let o = this.root;
632
- for (let s = 0; s < n.length; s++) {
633
- const c = n[s];
641
+ let s = this.root;
642
+ for (let i = 0; i < n.length; i++) {
643
+ const o = n[i];
634
644
  try {
635
- o = await o.getDirectoryHandle(c, { create: a || s === n.length - 1 });
636
- } catch (i) {
637
- throw i.name === "NotFoundError" ? new l(
638
- \`Parent directory does not exist: \${P(n.slice(0, s + 1))}\`,
645
+ s = await s.getDirectoryHandle(o, { create: a || i === n.length - 1 });
646
+ } catch (c) {
647
+ throw c.name === "NotFoundError" ? new l(
648
+ \`Parent directory does not exist: \${N(n.slice(0, i + 1))}\`,
639
649
  "ENOENT"
640
- ) : i.name === "TypeMismatchError" ? new l(\`Path segment is not a directory: \${c}\`, "ENOTDIR") : new l("Failed to create directory", "MKDIR_FAILED");
650
+ ) : c.name === "TypeMismatchError" ? new l(\`Path segment is not a directory: \${o}\`, "ENOTDIR") : new l("Failed to create directory", "MKDIR_FAILED");
641
651
  }
642
652
  }
643
653
  }
@@ -671,30 +681,30 @@ class ce {
671
681
  * \`\`\`
672
682
  */
673
683
  async stat(t, r) {
674
- const a = y(t), n = a.pop(), o = await this.getDirectoryHandle(a, !1), s = r?.includeHash ?? !1, c = r?.hashAlgorithm ?? "SHA-1";
684
+ const a = y(t), n = a.pop(), s = await this.getDirectoryHandle(a, !1), i = r?.includeHash ?? !1, o = r?.hashAlgorithm ?? "SHA-1";
675
685
  try {
676
- const u = await (await o.getFileHandle(n, { create: !1 })).getFile(), f = {
686
+ const f = await (await s.getFileHandle(n, { create: !1 })).getFile(), u = {
677
687
  kind: "file",
678
- size: u.size,
679
- mtime: new Date(u.lastModified).toISOString(),
680
- ctime: new Date(u.lastModified).toISOString(),
688
+ size: f.size,
689
+ mtime: new Date(f.lastModified).toISOString(),
690
+ ctime: new Date(f.lastModified).toISOString(),
681
691
  isFile: !0,
682
692
  isDirectory: !1
683
693
  };
684
- if (s)
694
+ if (i)
685
695
  try {
686
- const w = new Uint8Array(await u.arrayBuffer()), h = await ie(w, c);
687
- f.hash = h;
696
+ const w = new Uint8Array(await f.arrayBuffer()), h = await oe(w, o);
697
+ u.hash = h;
688
698
  } catch (w) {
689
699
  console.warn(\`Failed to calculate hash for \${t}:\`, w);
690
700
  }
691
- return f;
692
- } catch (i) {
693
- if (i.name !== "TypeMismatchError" && i.name !== "NotFoundError")
701
+ return u;
702
+ } catch (c) {
703
+ if (c.name !== "TypeMismatchError" && c.name !== "NotFoundError")
694
704
  throw new l("Failed to stat (file)", "STAT_FAILED");
695
705
  }
696
706
  try {
697
- return await o.getDirectoryHandle(n, { create: !1 }), {
707
+ return await s.getDirectoryHandle(n, { create: !1 }), {
698
708
  kind: "directory",
699
709
  size: 0,
700
710
  mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
@@ -703,29 +713,29 @@ class ce {
703
713
  isDirectory: !0
704
714
  // Directories don't have hashes
705
715
  };
706
- } catch (i) {
707
- throw i.name === "NotFoundError" ? new l(\`No such file or directory: \${t}\`, "ENOENT") : new l("Failed to stat (directory)", "STAT_FAILED");
716
+ } catch (c) {
717
+ throw c.name === "NotFoundError" ? new l(\`No such file or directory: \${t}\`, "ENOENT") : new l("Failed to stat (directory)", "STAT_FAILED");
708
718
  }
709
719
  }
710
720
  async readdir(t, r) {
711
721
  const a = r?.withFileTypes ?? !1, n = await this.getDirectoryHandle(t, !1);
712
722
  if (a) {
713
- const o = [];
714
- for await (const [s, c] of n.entries()) {
715
- const i = c.kind === "file";
716
- o.push({
717
- name: s,
718
- kind: c.kind,
719
- isFile: i,
720
- isDirectory: !i
723
+ const s = [];
724
+ for await (const [i, o] of n.entries()) {
725
+ const c = o.kind === "file";
726
+ s.push({
727
+ name: i,
728
+ kind: o.kind,
729
+ isFile: c,
730
+ isDirectory: !c
721
731
  });
722
732
  }
723
- return o;
733
+ return s;
724
734
  } else {
725
- const o = [];
726
- for await (const [s] of n.entries())
727
- o.push(s);
728
- return o;
735
+ const s = [];
736
+ for await (const [i] of n.entries())
737
+ s.push(i);
738
+ return s;
729
739
  }
730
740
  }
731
741
  /**
@@ -747,22 +757,22 @@ class ce {
747
757
  let n = null;
748
758
  try {
749
759
  n = await this.getDirectoryHandle(r, !1);
750
- } catch (o) {
751
- throw (o.name === "NotFoundError" || o.name === "TypeMismatchError") && (n = null), o;
760
+ } catch (s) {
761
+ throw (s.name === "NotFoundError" || s.name === "TypeMismatchError") && (n = null), s;
752
762
  }
753
763
  if (!n || !a)
754
764
  return !1;
755
765
  try {
756
766
  return await n.getFileHandle(a, { create: !1 }), !0;
757
- } catch (o) {
758
- if (o.name !== "NotFoundError" && o.name !== "TypeMismatchError")
759
- throw o;
767
+ } catch (s) {
768
+ if (s.name !== "NotFoundError" && s.name !== "TypeMismatchError")
769
+ throw s;
760
770
  }
761
771
  try {
762
772
  return await n.getDirectoryHandle(a, { create: !1 }), !0;
763
- } catch (o) {
764
- if (o.name !== "NotFoundError" && o.name !== "TypeMismatchError")
765
- throw o;
773
+ } catch (s) {
774
+ if (s.name !== "NotFoundError" && s.name !== "TypeMismatchError")
775
+ throw s;
766
776
  }
767
777
  return !1;
768
778
  }
@@ -821,17 +831,17 @@ class ce {
821
831
  * \`\`\`
822
832
  */
823
833
  async remove(t, r) {
824
- const a = r?.recursive ?? !1, n = r?.force ?? !1, o = y(t), s = o.pop();
825
- if (!s)
826
- throw new N("Invalid path", t);
827
- const c = await this.getDirectoryHandle(o, !1);
834
+ const a = r?.recursive ?? !1, n = r?.force ?? !1, s = y(t), i = s.pop();
835
+ if (!i)
836
+ throw new P("Invalid path", t);
837
+ const o = await this.getDirectoryHandle(s, !1);
828
838
  try {
829
- await c.removeEntry(s, { recursive: a });
830
- } catch (i) {
831
- if (i.name === "NotFoundError") {
839
+ await o.removeEntry(i, { recursive: a });
840
+ } catch (c) {
841
+ if (c.name === "NotFoundError") {
832
842
  if (!n)
833
843
  throw new l(\`No such file or directory: \${t}\`, "ENOENT");
834
- } else throw i.name === "InvalidModificationError" ? new l(\`Directory not empty: \${t}. Use recursive option to force removal.\`, "ENOTEMPTY") : i.name === "TypeMismatchError" && !a ? new l(\`Cannot remove directory without recursive option: \${t}\`, "EISDIR") : new l(\`Failed to remove path: \${t}\`, "RM_FAILED");
844
+ } else throw c.name === "InvalidModificationError" ? new l(\`Directory not empty: \${t}. Use recursive option to force removal.\`, "ENOTEMPTY") : c.name === "TypeMismatchError" && !a ? new l(\`Cannot remove directory without recursive option: \${t}\`, "EISDIR") : new l(\`Failed to remove path: \${t}\`, "RM_FAILED");
835
845
  }
836
846
  }
837
847
  /**
@@ -855,17 +865,17 @@ class ce {
855
865
  async realpath(t) {
856
866
  try {
857
867
  const r = y(t), a = [];
858
- for (const s of r)
859
- if (!(s === "." || s === ""))
860
- if (s === "..") {
868
+ for (const i of r)
869
+ if (!(i === "." || i === ""))
870
+ if (i === "..") {
861
871
  if (a.length === 0)
862
872
  throw new l("Path escapes root", "EINVAL");
863
873
  a.length > 0 && a.pop();
864
874
  } else
865
- a.push(s);
866
- const n = P(a);
875
+ a.push(i);
876
+ const n = N(a);
867
877
  if (!await this.exists(n))
868
- throw new x(n);
878
+ throw new b(n);
869
879
  return n;
870
880
  } catch (r) {
871
881
  throw r instanceof l ? r : new l(\`Failed to resolve path: \${t}\`, "REALPATH_FAILED");
@@ -890,7 +900,7 @@ class ce {
890
900
  async rename(t, r) {
891
901
  try {
892
902
  if (!await this.exists(t))
893
- throw new x(t);
903
+ throw new b(t);
894
904
  await this.copy(t, r, { recursive: !0 }), await this.remove(t, { recursive: !0 });
895
905
  } catch (a) {
896
906
  throw a instanceof l ? a : new l(\`Failed to rename from \${t} to \${r}\`, "RENAME_FAILED");
@@ -923,28 +933,87 @@ class ce {
923
933
  */
924
934
  async copy(t, r, a) {
925
935
  try {
926
- const n = a?.recursive ?? !1, o = a?.force ?? !0;
936
+ const n = a?.recursive ?? !1, s = a?.force ?? !0;
927
937
  if (!await this.exists(t))
928
938
  throw new l(\`Source does not exist: \${t}\`, "ENOENT");
929
- if (await this.exists(r) && !o)
939
+ if (await this.exists(r) && !s)
930
940
  throw new l(\`Destination already exists: \${r}\`, "EEXIST");
931
941
  if ((await this.stat(t)).isFile) {
932
- const u = await this.readFile(t, "binary");
933
- await this.writeFile(r, u);
942
+ const f = await this.readFile(t, "binary");
943
+ await this.writeFile(r, f);
934
944
  } else {
935
945
  if (!n)
936
946
  throw new l(\`Cannot copy directory without recursive option: \${t}\`, "EISDIR");
937
947
  await this.mkdir(r, { recursive: !0 });
938
- const u = await this.readdir(t, { withFileTypes: !0 });
939
- for (const f of u) {
940
- const w = \`\${t}/\${f.name}\`, h = \`\${r}/\${f.name}\`;
941
- await this.copy(w, h, { recursive: !0, force: o });
948
+ const f = await this.readdir(t, { withFileTypes: !0 });
949
+ for (const u of f) {
950
+ const w = \`\${t}/\${u.name}\`, h = \`\${r}/\${u.name}\`;
951
+ await this.copy(w, h, { recursive: !0, force: s });
942
952
  }
943
953
  }
944
954
  } catch (n) {
945
955
  throw n instanceof l ? n : new l(\`Failed to copy from \${t} to \${r}\`, "CP_FAILED");
946
956
  }
947
957
  }
958
+ /**
959
+ * Start watching a file or directory for changes
960
+ */
961
+ async watch(t) {
962
+ const r = t.startsWith("/") ? t : \`/\${t}\`, a = await this.buildSnapshot(r);
963
+ this.watchers.set(r, a), this.watchTimer || (this.watchTimer = setInterval(() => {
964
+ this.scanWatches();
965
+ }, this.watchInterval));
966
+ }
967
+ /**
968
+ * Stop watching a previously watched path
969
+ */
970
+ unwatch(t) {
971
+ const r = t.startsWith("/") ? t : \`/\${t}\`;
972
+ this.watchers.delete(r), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
973
+ }
974
+ async buildSnapshot(t) {
975
+ const r = /* @__PURE__ */ new Map(), a = async (n) => {
976
+ const s = await this.stat(n);
977
+ if (r.set(n, s), s.isDirectory) {
978
+ const i = await this.readdir(n, { withFileTypes: !0 });
979
+ for (const o of i) {
980
+ const c = \`\${n === "/" ? "" : n}/\${o.name}\`;
981
+ await a(c);
982
+ }
983
+ }
984
+ };
985
+ return await a(t), r;
986
+ }
987
+ async scanWatches() {
988
+ if (!this.scanning) {
989
+ this.scanning = !0;
990
+ try {
991
+ await Promise.all(
992
+ [...this.watchers.entries()].map(async ([t, r]) => {
993
+ let a;
994
+ try {
995
+ a = await this.buildSnapshot(t);
996
+ } catch {
997
+ a = /* @__PURE__ */ new Map();
998
+ }
999
+ const n = [];
1000
+ for (const [s, i] of a) {
1001
+ const o = r.get(s);
1002
+ o ? (o.mtime !== i.mtime || o.size !== i.size) && n.push({ path: s, type: "change" }) : n.push({ path: s, type: "create" });
1003
+ }
1004
+ for (const s of r.keys())
1005
+ a.has(s) || n.push({ path: s, type: "delete" });
1006
+ if (n.length && this.watchCallback)
1007
+ for (const s of n)
1008
+ this.watchCallback(s);
1009
+ this.watchers.set(t, a);
1010
+ })
1011
+ );
1012
+ } finally {
1013
+ this.scanning = !1;
1014
+ }
1015
+ }
1016
+ }
948
1017
  /**
949
1018
  * Synchronize the file system with external data
950
1019
  *
@@ -976,22 +1045,22 @@ class ce {
976
1045
  async sync(t, r) {
977
1046
  try {
978
1047
  (r?.cleanBefore ?? !1) && await this.clear("/");
979
- for (const [n, o] of t) {
980
- const s = n.startsWith("/") ? n : \`/\${n}\`;
981
- let c;
982
- if (o instanceof Blob) {
983
- const i = await o.arrayBuffer();
984
- c = new Uint8Array(i);
1048
+ for (const [n, s] of t) {
1049
+ const i = n.startsWith("/") ? n : \`/\${n}\`;
1050
+ let o;
1051
+ if (s instanceof Blob) {
1052
+ const c = await s.arrayBuffer();
1053
+ o = new Uint8Array(c);
985
1054
  } else
986
- c = o;
987
- await this.writeFile(s, c);
1055
+ o = s;
1056
+ await this.writeFile(i, o);
988
1057
  }
989
1058
  } catch (a) {
990
1059
  throw a instanceof l ? a : new l("Failed to sync file system", "SYNC_FAILED");
991
1060
  }
992
1061
  }
993
1062
  }
994
- O(new ce());
995
- //# sourceMappingURL=worker-BiWuxhcz.js.map
996
- `,r=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",a],{type:"text/javascript;charset=utf-8"});function i(t){let n;try{if(n=r&&(self.URL||self.webkitURL).createObjectURL(r),!n)throw"";const e=new Worker(n,{type:"module",name:t?.name});return e.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(n)}),e}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(a),{type:"module",name:t?.name})}}function s(){return o.wrap(new i)}exports.createWorker=s;
1063
+ typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && x(new ce());
1064
+ //# sourceMappingURL=worker-D5GbafFH.js.map
1065
+ `,r=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",a],{type:"text/javascript;charset=utf-8"});function s(t){let n;try{if(n=r&&(self.URL||self.webkitURL).createObjectURL(r),!n)throw"";const e=new Worker(n,{type:"module",name:t?.name});return e.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(n)}),e}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(a),{type:"module",name:t?.name})}}function o(){return i.wrap(new s)}exports.createWorker=o;
997
1066
  //# sourceMappingURL=index.cjs.map