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/README.md +5 -3
- package/dist/assets/worker-BL3varjN.js.map +1 -0
- package/dist/{helpers-Co-qCBmA.js → helpers-3TGPHd1h.js} +6 -5
- package/dist/{helpers-Co-qCBmA.js.map → helpers-3TGPHd1h.js.map} +1 -1
- package/dist/{helpers-hEpet7x7.cjs → helpers-DjY2OR7f.cjs} +2 -2
- package/dist/{helpers-hEpet7x7.cjs.map → helpers-DjY2OR7f.cjs.map} +1 -1
- package/dist/index.cjs +480 -464
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +500 -481
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +168 -153
- package/dist/raw.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +1 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/worker.d.ts +45 -53
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-CRHhlrlS.js.map +0 -1
package/dist/raw.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { expose as
|
|
2
|
-
import { d 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 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
|
|
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
|
-
|
|
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
|
|
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
|
|
69
|
-
this.watchCallback = t
|
|
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
|
|
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
|
|
110
|
-
const r = Array.isArray(t) ? t :
|
|
148
|
+
throw new l();
|
|
149
|
+
const r = Array.isArray(t) ? t : w(t);
|
|
111
150
|
let a = i;
|
|
112
|
-
for (const
|
|
113
|
-
a = await a.getDirectoryHandle(
|
|
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
|
|
138
|
-
const r =
|
|
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
|
-
*
|
|
184
|
+
* Get a complete index of all files and directories in the file system
|
|
146
185
|
*
|
|
147
|
-
*
|
|
148
|
-
* a Map containing
|
|
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
|
-
* @
|
|
151
|
-
* @
|
|
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(
|
|
182
|
-
const
|
|
183
|
-
const
|
|
184
|
-
for (const
|
|
185
|
-
const s = `${
|
|
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
|
|
188
|
-
|
|
189
|
-
} catch (
|
|
190
|
-
console.warn(`Skipping broken entry: ${s}`,
|
|
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
|
|
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
|
|
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
|
|
207
|
-
return e === "binary" ? r :
|
|
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
|
|
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
|
|
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
|
|
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
|
|
293
|
-
const i = e?.recursive ?? !1, r =
|
|
313
|
+
throw new l();
|
|
314
|
+
const i = e?.recursive ?? !1, r = w(t);
|
|
294
315
|
let a = this.root;
|
|
295
|
-
for (let
|
|
296
|
-
const
|
|
316
|
+
for (let s = 0; s < r.length; s++) {
|
|
317
|
+
const o = r[s];
|
|
297
318
|
try {
|
|
298
|
-
a = await a.getDirectoryHandle(
|
|
319
|
+
a = await a.getDirectoryHandle(o, { create: i || s === r.length - 1 });
|
|
299
320
|
} catch (c) {
|
|
300
|
-
throw c.name === "NotFoundError" ? new
|
|
301
|
-
`Parent directory does not exist: ${T(r.slice(0,
|
|
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
|
|
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
|
|
330
|
+
* Get file or directory statistics
|
|
309
331
|
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
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
|
-
* @
|
|
315
|
-
* @
|
|
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
|
-
*
|
|
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(`
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
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
|
|
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
|
|
361
|
+
const e = y(t), i = await this.getDirectoryHandle(u(t), !1), r = this.hashAlgorithm !== null;
|
|
347
362
|
try {
|
|
348
|
-
const
|
|
363
|
+
const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), o = {
|
|
349
364
|
kind: "file",
|
|
350
|
-
size:
|
|
351
|
-
mtime: new Date(
|
|
352
|
-
ctime: new Date(
|
|
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 (
|
|
371
|
+
if (r && this.hashAlgorithm)
|
|
357
372
|
try {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
} catch (
|
|
361
|
-
console.warn(`Failed to calculate hash for ${t}:`,
|
|
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
|
|
364
|
-
} catch (
|
|
365
|
-
if (
|
|
366
|
-
throw new
|
|
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
|
|
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 (
|
|
378
|
-
throw
|
|
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 [
|
|
387
|
-
const c =
|
|
401
|
+
for await (const [s, o] of r.entries()) {
|
|
402
|
+
const c = o.kind === "file";
|
|
388
403
|
a.push({
|
|
389
|
-
name:
|
|
390
|
-
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 [
|
|
399
|
-
a.push(
|
|
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 =
|
|
435
|
+
const e = y(t);
|
|
421
436
|
let i = null;
|
|
422
437
|
try {
|
|
423
|
-
i = await this.getDirectoryHandle(
|
|
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
|
|
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
|
|
503
|
-
const a =
|
|
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
|
|
522
|
+
const s = await this.getDirectoryHandle(u(t), !1);
|
|
507
523
|
try {
|
|
508
|
-
await
|
|
509
|
-
} catch (
|
|
510
|
-
if (
|
|
524
|
+
await s.removeEntry(a, { recursive: i });
|
|
525
|
+
} catch (o) {
|
|
526
|
+
if (o.name === "NotFoundError") {
|
|
511
527
|
if (!r)
|
|
512
|
-
throw new
|
|
513
|
-
} else throw
|
|
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 =
|
|
554
|
+
const e = A(t);
|
|
538
555
|
if (!await this.exists(e))
|
|
539
|
-
throw new
|
|
556
|
+
throw new f(e);
|
|
540
557
|
return e;
|
|
541
558
|
} catch (e) {
|
|
542
|
-
throw e instanceof
|
|
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
|
|
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
|
|
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
|
|
618
|
+
throw new n(`Source does not exist: ${t}`, "ENOENT");
|
|
602
619
|
if (await this.exists(e) && !a)
|
|
603
|
-
throw new
|
|
620
|
+
throw new n(`Destination already exists: ${e}`, "EEXIST");
|
|
604
621
|
if ((await this.stat(t)).isFile) {
|
|
605
|
-
const
|
|
606
|
-
await this.writeFile(e,
|
|
622
|
+
const h = await this.readFile(t, "binary");
|
|
623
|
+
await this.writeFile(e, h);
|
|
607
624
|
} else {
|
|
608
625
|
if (!r)
|
|
609
|
-
throw new
|
|
626
|
+
throw new n(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
|
|
610
627
|
await this.mkdir(e, { recursive: !0 });
|
|
611
|
-
const
|
|
612
|
-
for (const
|
|
613
|
-
const
|
|
614
|
-
await this.copy(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
643
|
-
for (const
|
|
644
|
-
const c = `${r === "/" ? "" : r}/${
|
|
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
|
-
|
|
665
|
-
|
|
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
|
|
669
|
-
i.has(
|
|
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
|
|
715
|
-
let
|
|
716
|
-
a instanceof Blob ?
|
|
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
|
|
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" &&
|
|
738
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && p(new O());
|
|
724
739
|
export {
|
|
725
|
-
|
|
740
|
+
O as OPFSWorker
|
|
726
741
|
};
|
|
727
742
|
//# sourceMappingURL=raw.js.map
|