opfs-worker 0.2.6 → 0.3.1
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 +117 -47
- package/dist/assets/worker-DilNsKoO.js.map +1 -0
- package/dist/helpers-B87wz5kv.cjs +2 -0
- package/dist/helpers-B87wz5kv.cjs.map +1 -0
- package/dist/{helpers-C0nyU6hv.js → helpers-DxFcNkZe.js} +51 -51
- package/dist/helpers-DxFcNkZe.js.map +1 -0
- package/dist/index.cjs +255 -234
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +284 -266
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +143 -122
- package/dist/raw.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +9 -0
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/worker.d.ts +16 -27
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-CHy3JxL1.js.map +0 -1
- package/dist/helpers-C0nyU6hv.js.map +0 -1
- package/dist/helpers-FvdHLObV.cjs +0 -2
- package/dist/helpers-FvdHLObV.cjs.map +0 -1
package/dist/raw.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { expose as
|
|
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
|
|
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 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 {
|
|
4
4
|
/** Root directory handle for the file system */
|
|
5
5
|
root = null;
|
|
6
|
-
/** Watch event callback */
|
|
7
|
-
watchCallback = null;
|
|
8
6
|
/** Map of watched paths to their last known state */
|
|
9
7
|
watchers = /* @__PURE__ */ new Map();
|
|
10
8
|
/** Interval handle for polling watched paths */
|
|
@@ -13,11 +11,14 @@ class O {
|
|
|
13
11
|
scanning = !1;
|
|
14
12
|
/** Promise to prevent concurrent mount operations */
|
|
15
13
|
mountingPromise = null;
|
|
14
|
+
/** BroadcastChannel instance for sending events */
|
|
15
|
+
broadcastChannel = null;
|
|
16
16
|
/** Configuration options */
|
|
17
17
|
options = {
|
|
18
18
|
watchInterval: 1e3,
|
|
19
19
|
maxFileSize: 50 * 1024 * 1024,
|
|
20
|
-
hashAlgorithm: null
|
|
20
|
+
hashAlgorithm: null,
|
|
21
|
+
broadcastChannel: "opfs-worker"
|
|
21
22
|
};
|
|
22
23
|
/**
|
|
23
24
|
* Notify about internal changes to the file system
|
|
@@ -29,7 +30,7 @@ class O {
|
|
|
29
30
|
* @param type - The type of change (create, change, delete)
|
|
30
31
|
*/
|
|
31
32
|
async notifyChange(t) {
|
|
32
|
-
if (!this.
|
|
33
|
+
if (!this.options.broadcastChannel)
|
|
33
34
|
return;
|
|
34
35
|
let e;
|
|
35
36
|
if (this.options.hashAlgorithm && !t.isDirectory && t.type !== "removed")
|
|
@@ -39,24 +40,29 @@ class O {
|
|
|
39
40
|
} catch (i) {
|
|
40
41
|
console.warn(`Failed to calculate hash for ${t.path}:`, i);
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
try {
|
|
44
|
+
this.broadcastChannel || (this.broadcastChannel = new BroadcastChannel(this.options.broadcastChannel));
|
|
45
|
+
const i = {
|
|
46
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47
|
+
...t,
|
|
48
|
+
...e && { hash: e }
|
|
49
|
+
};
|
|
50
|
+
this.broadcastChannel.postMessage(i);
|
|
51
|
+
} catch (i) {
|
|
52
|
+
console.warn("Failed to send event via BroadcastChannel:", i);
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
49
56
|
* Creates a new OPFSFileSystem instance
|
|
50
57
|
*
|
|
51
|
-
* @param watchCallback - Optional callback for file change events
|
|
52
58
|
* @param options - Optional configuration options
|
|
53
59
|
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
54
60
|
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
55
61
|
* @param options.maxFileSize - Maximum file size for hashing in bytes (default: 50MB)
|
|
56
62
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
57
63
|
*/
|
|
58
|
-
constructor(t
|
|
59
|
-
S(), t &&
|
|
64
|
+
constructor(t) {
|
|
65
|
+
S(), t && this.setOptions(t), this.mount("/");
|
|
60
66
|
}
|
|
61
67
|
/**
|
|
62
68
|
* Initialize the file system within a given directory
|
|
@@ -83,23 +89,15 @@ class O {
|
|
|
83
89
|
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (e, i) => {
|
|
84
90
|
this.root = null;
|
|
85
91
|
try {
|
|
86
|
-
const
|
|
87
|
-
t === "/" ? this.root =
|
|
88
|
-
} catch (
|
|
89
|
-
console.error(
|
|
92
|
+
const a = await navigator.storage.getDirectory();
|
|
93
|
+
t === "/" ? this.root = a : this.root = await this.getDirectoryHandle(t, !0, a), e(!0);
|
|
94
|
+
} catch (a) {
|
|
95
|
+
console.error(a), i(new n("Failed to initialize OPFS", "INIT_FAILED"));
|
|
90
96
|
} finally {
|
|
91
97
|
this.mountingPromise = null;
|
|
92
98
|
}
|
|
93
99
|
}), this.mountingPromise;
|
|
94
100
|
}
|
|
95
|
-
/**
|
|
96
|
-
* Set the watch callback for file change events
|
|
97
|
-
*
|
|
98
|
-
* @param callback - The callback function to invoke when files change
|
|
99
|
-
*/
|
|
100
|
-
setWatchCallback(t) {
|
|
101
|
-
this.watchCallback = t;
|
|
102
|
-
}
|
|
103
101
|
/**
|
|
104
102
|
* Update configuration options
|
|
105
103
|
*
|
|
@@ -107,9 +105,10 @@ class O {
|
|
|
107
105
|
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
108
106
|
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
109
107
|
* @param options.maxFileSize - Maximum file size for hashing in bytes
|
|
108
|
+
* @param options.broadcastChannel - Custom name for the broadcast channel
|
|
110
109
|
*/
|
|
111
110
|
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);
|
|
111
|
+
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
112
|
}
|
|
114
113
|
/**
|
|
115
114
|
* Automatically mount the OPFS root if not already mounted
|
|
@@ -150,11 +149,11 @@ class O {
|
|
|
150
149
|
async getDirectoryHandle(t, e = !1, i = this.root) {
|
|
151
150
|
if (!i)
|
|
152
151
|
throw new l();
|
|
153
|
-
const
|
|
154
|
-
let
|
|
155
|
-
for (const s of
|
|
156
|
-
|
|
157
|
-
return
|
|
152
|
+
const a = Array.isArray(t) ? t : w(t);
|
|
153
|
+
let r = i;
|
|
154
|
+
for (const s of a)
|
|
155
|
+
r = await r.getDirectoryHandle(s, { create: e });
|
|
156
|
+
return r;
|
|
158
157
|
}
|
|
159
158
|
/**
|
|
160
159
|
* Get a file handle from a path
|
|
@@ -178,11 +177,11 @@ class O {
|
|
|
178
177
|
async getFileHandle(t, e = !1, i = this.root) {
|
|
179
178
|
if (!i)
|
|
180
179
|
throw new l();
|
|
181
|
-
const
|
|
182
|
-
if (
|
|
180
|
+
const a = w(t);
|
|
181
|
+
if (a.length === 0)
|
|
183
182
|
throw new g("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
184
|
-
const
|
|
185
|
-
return (await this.getDirectoryHandle(
|
|
183
|
+
const r = a.pop();
|
|
184
|
+
return (await this.getDirectoryHandle(a, e, i)).getFileHandle(r, { create: e });
|
|
186
185
|
}
|
|
187
186
|
/**
|
|
188
187
|
* Get a complete index of all files and directories in the file system
|
|
@@ -205,9 +204,9 @@ class O {
|
|
|
205
204
|
*/
|
|
206
205
|
async index() {
|
|
207
206
|
const t = /* @__PURE__ */ new Map(), e = async (i) => {
|
|
208
|
-
const
|
|
209
|
-
for (const
|
|
210
|
-
const s = `${i === "/" ? "" : i}/${
|
|
207
|
+
const a = await this.readDir(i);
|
|
208
|
+
for (const r of a) {
|
|
209
|
+
const s = `${i === "/" ? "" : i}/${r.name}`;
|
|
211
210
|
try {
|
|
212
211
|
const o = await this.stat(s);
|
|
213
212
|
t.set(s, o), o.isDirectory && await e(s);
|
|
@@ -228,8 +227,8 @@ class O {
|
|
|
228
227
|
async readFile(t, e = "utf-8") {
|
|
229
228
|
await this.ensureMounted();
|
|
230
229
|
try {
|
|
231
|
-
const i = await this.getFileHandle(t, !1),
|
|
232
|
-
return e === "binary" ?
|
|
230
|
+
const i = await this.getFileHandle(t, !1), a = await v(i);
|
|
231
|
+
return e === "binary" ? a : I(a, e);
|
|
233
232
|
} catch (i) {
|
|
234
233
|
throw console.error(i), new f(t);
|
|
235
234
|
}
|
|
@@ -261,8 +260,8 @@ class O {
|
|
|
261
260
|
*/
|
|
262
261
|
async writeFile(t, e, i) {
|
|
263
262
|
await this.ensureMounted();
|
|
264
|
-
const
|
|
265
|
-
await
|
|
263
|
+
const a = await this.getFileHandle(t, !0);
|
|
264
|
+
await D(a, e, i, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
266
265
|
}
|
|
267
266
|
/**
|
|
268
267
|
* Append data to a file
|
|
@@ -288,8 +287,8 @@ class O {
|
|
|
288
287
|
*/
|
|
289
288
|
async appendFile(t, e, i) {
|
|
290
289
|
await this.ensureMounted();
|
|
291
|
-
const
|
|
292
|
-
await
|
|
290
|
+
const a = await this.getFileHandle(t, !0);
|
|
291
|
+
await D(a, e, i, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
293
292
|
}
|
|
294
293
|
/**
|
|
295
294
|
* Create a directory
|
|
@@ -315,15 +314,15 @@ class O {
|
|
|
315
314
|
async mkdir(t, e) {
|
|
316
315
|
if (await this.ensureMounted(), !this.root)
|
|
317
316
|
throw new l();
|
|
318
|
-
const i = e?.recursive ?? !1,
|
|
319
|
-
let
|
|
320
|
-
for (let s = 0; s <
|
|
321
|
-
const o =
|
|
317
|
+
const i = e?.recursive ?? !1, a = w(t);
|
|
318
|
+
let r = this.root;
|
|
319
|
+
for (let s = 0; s < a.length; s++) {
|
|
320
|
+
const o = a[s];
|
|
322
321
|
try {
|
|
323
|
-
|
|
322
|
+
r = await r.getDirectoryHandle(o, { create: i || s === a.length - 1 });
|
|
324
323
|
} catch (c) {
|
|
325
324
|
throw c.name === "NotFoundError" ? new n(
|
|
326
|
-
`Parent directory does not exist: ${
|
|
325
|
+
`Parent directory does not exist: ${C(a.slice(0, s + 1))}`,
|
|
327
326
|
"ENOENT"
|
|
328
327
|
) : c.name === "TypeMismatchError" ? new n(`Path segment is not a directory: ${o}`, "ENOTDIR") : new n("Failed to create directory", "MKDIR_FAILED");
|
|
329
328
|
}
|
|
@@ -362,7 +361,7 @@ class O {
|
|
|
362
361
|
isFile: !1,
|
|
363
362
|
isDirectory: !0
|
|
364
363
|
};
|
|
365
|
-
const e =
|
|
364
|
+
const e = d(t), i = await this.getDirectoryHandle(y(t), !1), a = this.options.hashAlgorithm !== null;
|
|
366
365
|
try {
|
|
367
366
|
const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), o = {
|
|
368
367
|
kind: "file",
|
|
@@ -372,7 +371,7 @@ class O {
|
|
|
372
371
|
isFile: !0,
|
|
373
372
|
isDirectory: !1
|
|
374
373
|
};
|
|
375
|
-
if (
|
|
374
|
+
if (a && this.options.hashAlgorithm)
|
|
376
375
|
try {
|
|
377
376
|
const c = await M(s, this.options.hashAlgorithm, this.options.maxFileSize);
|
|
378
377
|
o.hash = c;
|
|
@@ -380,8 +379,8 @@ class O {
|
|
|
380
379
|
console.warn(`Failed to calculate hash for ${t}:`, c);
|
|
381
380
|
}
|
|
382
381
|
return o;
|
|
383
|
-
} catch (
|
|
384
|
-
if (
|
|
382
|
+
} catch (r) {
|
|
383
|
+
if (r.name !== "TypeMismatchError" && r.name !== "NotFoundError")
|
|
385
384
|
throw new n("Failed to stat (file)", "STAT_FAILED");
|
|
386
385
|
}
|
|
387
386
|
try {
|
|
@@ -393,31 +392,41 @@ class O {
|
|
|
393
392
|
isFile: !1,
|
|
394
393
|
isDirectory: !0
|
|
395
394
|
};
|
|
396
|
-
} catch (
|
|
397
|
-
throw
|
|
395
|
+
} catch (r) {
|
|
396
|
+
throw r.name === "NotFoundError" ? new n(`No such file or directory: ${t}`, "ENOENT") : new n("Failed to stat (directory)", "STAT_FAILED");
|
|
398
397
|
}
|
|
399
398
|
}
|
|
400
|
-
|
|
399
|
+
/**
|
|
400
|
+
* Read a directory's contents
|
|
401
|
+
*
|
|
402
|
+
* Lists all files and subdirectories within the specified directory.
|
|
403
|
+
*
|
|
404
|
+
* @param path - The path to the directory to read
|
|
405
|
+
* @returns Promise that resolves to an array of detailed file/directory information
|
|
406
|
+
* @throws {OPFSError} If the directory does not exist or cannot be accessed
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```typescript
|
|
410
|
+
* // Get detailed information about files and directories
|
|
411
|
+
* const detailed = await fs.readDir('/users/john/documents');
|
|
412
|
+
* detailed.forEach(item => {
|
|
413
|
+
* console.log(`${item.name} - ${item.isFile ? 'file' : 'directory'}`);
|
|
414
|
+
* });
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
async readDir(t) {
|
|
401
418
|
await this.ensureMounted();
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
isDirectory: !c
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
return a;
|
|
415
|
-
} else {
|
|
416
|
-
const a = [];
|
|
417
|
-
for await (const [s] of r.entries())
|
|
418
|
-
a.push(s);
|
|
419
|
-
return a;
|
|
419
|
+
const e = await this.getDirectoryHandle(t, !1), i = [];
|
|
420
|
+
for await (const [a, r] of e.entries()) {
|
|
421
|
+
const s = r.kind === "file";
|
|
422
|
+
i.push({
|
|
423
|
+
name: a,
|
|
424
|
+
kind: r.kind,
|
|
425
|
+
isFile: s,
|
|
426
|
+
isDirectory: !s
|
|
427
|
+
});
|
|
420
428
|
}
|
|
429
|
+
return i;
|
|
421
430
|
}
|
|
422
431
|
/**
|
|
423
432
|
* Check if a file or directory exists
|
|
@@ -436,26 +445,26 @@ class O {
|
|
|
436
445
|
async exists(t) {
|
|
437
446
|
if (await this.ensureMounted(), t === "/")
|
|
438
447
|
return !0;
|
|
439
|
-
const e =
|
|
448
|
+
const e = d(t);
|
|
440
449
|
let i = null;
|
|
441
450
|
try {
|
|
442
|
-
i = await this.getDirectoryHandle(
|
|
443
|
-
} catch (
|
|
444
|
-
throw (
|
|
451
|
+
i = await this.getDirectoryHandle(y(t), !1);
|
|
452
|
+
} catch (a) {
|
|
453
|
+
throw (a.name === "NotFoundError" || a.name === "TypeMismatchError") && (i = null), a;
|
|
445
454
|
}
|
|
446
455
|
if (!i || !e)
|
|
447
456
|
return !1;
|
|
448
457
|
try {
|
|
449
458
|
return await i.getFileHandle(e, { create: !1 }), !0;
|
|
450
|
-
} catch (
|
|
451
|
-
if (
|
|
452
|
-
throw
|
|
459
|
+
} catch (a) {
|
|
460
|
+
if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
|
|
461
|
+
throw a;
|
|
453
462
|
}
|
|
454
463
|
try {
|
|
455
464
|
return await i.getDirectoryHandle(e, { create: !1 }), !0;
|
|
456
|
-
} catch (
|
|
457
|
-
if (
|
|
458
|
-
throw
|
|
465
|
+
} catch (a) {
|
|
466
|
+
if (a.name !== "NotFoundError" && a.name !== "TypeMismatchError")
|
|
467
|
+
throw a;
|
|
459
468
|
}
|
|
460
469
|
return !1;
|
|
461
470
|
}
|
|
@@ -481,10 +490,10 @@ class O {
|
|
|
481
490
|
async clear(t = "/") {
|
|
482
491
|
await this.ensureMounted();
|
|
483
492
|
try {
|
|
484
|
-
const e = await this.
|
|
493
|
+
const e = await this.readDir(t);
|
|
485
494
|
for (const i of e) {
|
|
486
|
-
const
|
|
487
|
-
await this.remove(
|
|
495
|
+
const a = `${t === "/" ? "" : t}/${i.name}`;
|
|
496
|
+
await this.remove(a, { recursive: !0 });
|
|
488
497
|
}
|
|
489
498
|
await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
|
|
490
499
|
} catch (e) {
|
|
@@ -517,18 +526,18 @@ class O {
|
|
|
517
526
|
*/
|
|
518
527
|
async remove(t, e) {
|
|
519
528
|
await this.ensureMounted();
|
|
520
|
-
const i = e?.recursive ?? !1,
|
|
529
|
+
const i = e?.recursive ?? !1, a = e?.force ?? !1;
|
|
521
530
|
if (t === "/")
|
|
522
531
|
throw new n("Cannot remove root directory", "EROOT");
|
|
523
|
-
const
|
|
524
|
-
if (!
|
|
532
|
+
const r = d(t);
|
|
533
|
+
if (!r)
|
|
525
534
|
throw new g("Invalid path", t);
|
|
526
|
-
const s = await this.getDirectoryHandle(
|
|
535
|
+
const s = await this.getDirectoryHandle(y(t), !1);
|
|
527
536
|
try {
|
|
528
|
-
await s.removeEntry(
|
|
537
|
+
await s.removeEntry(r, { recursive: i });
|
|
529
538
|
} catch (o) {
|
|
530
539
|
if (o.name === "NotFoundError") {
|
|
531
|
-
if (!
|
|
540
|
+
if (!a)
|
|
532
541
|
throw new n(`No such file or directory: ${t}`, "ENOENT");
|
|
533
542
|
} 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");
|
|
534
543
|
}
|
|
@@ -555,7 +564,7 @@ class O {
|
|
|
555
564
|
async realpath(t) {
|
|
556
565
|
await this.ensureMounted();
|
|
557
566
|
try {
|
|
558
|
-
const e =
|
|
567
|
+
const e = T(t);
|
|
559
568
|
if (!await this.exists(e))
|
|
560
569
|
throw new f(e);
|
|
561
570
|
return e;
|
|
@@ -617,27 +626,27 @@ class O {
|
|
|
617
626
|
async copy(t, e, i) {
|
|
618
627
|
await this.ensureMounted();
|
|
619
628
|
try {
|
|
620
|
-
const
|
|
629
|
+
const a = i?.recursive ?? !1, r = i?.force ?? !0;
|
|
621
630
|
if (!await this.exists(t))
|
|
622
631
|
throw new n(`Source does not exist: ${t}`, "ENOENT");
|
|
623
|
-
if (await this.exists(e) && !
|
|
632
|
+
if (await this.exists(e) && !r)
|
|
624
633
|
throw new n(`Destination already exists: ${e}`, "EEXIST");
|
|
625
634
|
if ((await this.stat(t)).isFile) {
|
|
626
635
|
const h = await this.readFile(t, "binary");
|
|
627
636
|
await this.writeFile(e, h);
|
|
628
637
|
} else {
|
|
629
|
-
if (!
|
|
638
|
+
if (!a)
|
|
630
639
|
throw new n(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
|
|
631
640
|
await this.mkdir(e, { recursive: !0 });
|
|
632
|
-
const h = await this.
|
|
641
|
+
const h = await this.readDir(t);
|
|
633
642
|
for (const m of h) {
|
|
634
|
-
const
|
|
635
|
-
await this.copy(
|
|
643
|
+
const F = `${t}/${m.name}`, E = `${e}/${m.name}`;
|
|
644
|
+
await this.copy(F, E, { recursive: !0, force: r });
|
|
636
645
|
}
|
|
637
646
|
}
|
|
638
647
|
await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
|
|
639
|
-
} catch (
|
|
640
|
-
throw
|
|
648
|
+
} catch (a) {
|
|
649
|
+
throw a instanceof n ? a : new n(`Failed to copy from ${t} to ${e}`, "CP_FAILED");
|
|
641
650
|
}
|
|
642
651
|
}
|
|
643
652
|
/**
|
|
@@ -645,7 +654,7 @@ class O {
|
|
|
645
654
|
*/
|
|
646
655
|
async watch(t) {
|
|
647
656
|
await this.ensureMounted();
|
|
648
|
-
const e =
|
|
657
|
+
const e = u(t), i = await this.buildSnapshot(e);
|
|
649
658
|
this.watchers.set(e, i), this.watchTimer || (this.watchTimer = setInterval(() => {
|
|
650
659
|
this.scanWatches();
|
|
651
660
|
}, this.options.watchInterval));
|
|
@@ -654,16 +663,25 @@ class O {
|
|
|
654
663
|
* Stop watching a previously watched path
|
|
655
664
|
*/
|
|
656
665
|
unwatch(t) {
|
|
657
|
-
const e =
|
|
666
|
+
const e = u(t);
|
|
658
667
|
this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
659
668
|
}
|
|
669
|
+
/**
|
|
670
|
+
* Dispose of resources and clean up the file system instance
|
|
671
|
+
*
|
|
672
|
+
* This method should be called when the file system instance is no longer needed
|
|
673
|
+
* to properly clean up resources like the broadcast channel and watch timers.
|
|
674
|
+
*/
|
|
675
|
+
dispose() {
|
|
676
|
+
this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null), this.watchers.clear();
|
|
677
|
+
}
|
|
660
678
|
async buildSnapshot(t) {
|
|
661
|
-
const e = /* @__PURE__ */ new Map(), i = async (
|
|
662
|
-
const
|
|
663
|
-
if (e.set(
|
|
664
|
-
const s = await this.
|
|
679
|
+
const e = /* @__PURE__ */ new Map(), i = async (a) => {
|
|
680
|
+
const r = await this.stat(a);
|
|
681
|
+
if (e.set(a, r), r.isDirectory) {
|
|
682
|
+
const s = await this.readDir(a);
|
|
665
683
|
for (const o of s) {
|
|
666
|
-
const c = `${
|
|
684
|
+
const c = `${a === "/" ? "" : a}/${o.name}`;
|
|
667
685
|
await i(c);
|
|
668
686
|
}
|
|
669
687
|
}
|
|
@@ -682,12 +700,15 @@ class O {
|
|
|
682
700
|
} catch {
|
|
683
701
|
i = /* @__PURE__ */ new Map();
|
|
684
702
|
}
|
|
685
|
-
for (const [
|
|
686
|
-
const s = e.get(
|
|
687
|
-
s ? (s.mtime !==
|
|
703
|
+
for (const [a, r] of i) {
|
|
704
|
+
const s = e.get(a);
|
|
705
|
+
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 });
|
|
688
706
|
}
|
|
689
|
-
for (const
|
|
690
|
-
i.has(
|
|
707
|
+
for (const a of e.keys())
|
|
708
|
+
if (!i.has(a)) {
|
|
709
|
+
const r = e.get(a);
|
|
710
|
+
await this.notifyChange({ path: a, type: "removed", isDirectory: r?.isDirectory ?? !1 });
|
|
711
|
+
}
|
|
691
712
|
this.watchers.set(t, i);
|
|
692
713
|
})
|
|
693
714
|
);
|
|
@@ -728,10 +749,10 @@ class O {
|
|
|
728
749
|
await this.ensureMounted();
|
|
729
750
|
try {
|
|
730
751
|
(e?.cleanBefore ?? !1) && await this.clear("/");
|
|
731
|
-
for (const [
|
|
732
|
-
const s =
|
|
752
|
+
for (const [a, r] of t) {
|
|
753
|
+
const s = u(a);
|
|
733
754
|
let o;
|
|
734
|
-
|
|
755
|
+
r instanceof Blob ? o = await b(r) : o = r, await this.writeFile(s, o);
|
|
735
756
|
}
|
|
736
757
|
await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
|
|
737
758
|
} catch (i) {
|
|
@@ -739,8 +760,8 @@ class O {
|
|
|
739
760
|
}
|
|
740
761
|
}
|
|
741
762
|
}
|
|
742
|
-
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" &&
|
|
763
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && p(new A());
|
|
743
764
|
export {
|
|
744
|
-
|
|
765
|
+
A as OPFSWorker
|
|
745
766
|
};
|
|
746
767
|
//# sourceMappingURL=raw.js.map
|