opfs-worker 0.2.4 → 0.2.6
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 +150 -35
- package/dist/assets/worker-CHy3JxL1.js.map +1 -0
- package/dist/{helpers-Co-qCBmA.js → helpers-C0nyU6hv.js} +56 -58
- package/dist/{helpers-Co-qCBmA.js.map → helpers-C0nyU6hv.js.map} +1 -1
- package/dist/helpers-FvdHLObV.cjs +2 -0
- package/dist/{helpers-hEpet7x7.cjs.map → helpers-FvdHLObV.cjs.map} +1 -1
- package/dist/index.cjs +472 -475
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +495 -495
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +166 -167
- package/dist/raw.js.map +1 -1
- package/dist/types.d.ts +12 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +4 -2
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/worker.d.ts +37 -61
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-DCm4BiWM.js.map +0 -1
- package/dist/helpers-hEpet7x7.cjs +0 -2
package/dist/raw.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { expose as
|
|
2
|
-
import { d as
|
|
3
|
-
class
|
|
1
|
+
import { expose as E } 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 F, j as T, e as y, f as u, k as M, r as A, n as d, l as $ } from "./helpers-C0nyU6hv.js";
|
|
3
|
+
class O {
|
|
4
4
|
/** Root directory handle for the file system */
|
|
5
5
|
root = null;
|
|
6
6
|
/** Watch event callback */
|
|
@@ -9,12 +9,16 @@ class N {
|
|
|
9
9
|
watchers = /* @__PURE__ */ new Map();
|
|
10
10
|
/** Interval handle for polling watched paths */
|
|
11
11
|
watchTimer = null;
|
|
12
|
-
/** Polling interval in milliseconds */
|
|
13
|
-
watchInterval = 1e3;
|
|
14
12
|
/** Flag to avoid concurrent scans */
|
|
15
13
|
scanning = !1;
|
|
16
14
|
/** Promise to prevent concurrent mount operations */
|
|
17
15
|
mountingPromise = null;
|
|
16
|
+
/** Configuration options */
|
|
17
|
+
options = {
|
|
18
|
+
watchInterval: 1e3,
|
|
19
|
+
maxFileSize: 50 * 1024 * 1024,
|
|
20
|
+
hashAlgorithm: null
|
|
21
|
+
};
|
|
18
22
|
/**
|
|
19
23
|
* Notify about internal changes to the file system
|
|
20
24
|
*
|
|
@@ -24,21 +28,35 @@ class N {
|
|
|
24
28
|
* @param path - The path that was changed
|
|
25
29
|
* @param type - The type of change (create, change, delete)
|
|
26
30
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
async notifyChange(t) {
|
|
32
|
+
if (!this.watchCallback)
|
|
33
|
+
return;
|
|
34
|
+
let e;
|
|
35
|
+
if (this.options.hashAlgorithm && !t.isDirectory && t.type !== "removed")
|
|
36
|
+
try {
|
|
37
|
+
const i = await this.stat(t.path);
|
|
38
|
+
i.isFile && i.hash && (e = i.hash);
|
|
39
|
+
} catch (i) {
|
|
40
|
+
console.warn(`Failed to calculate hash for ${t.path}:`, i);
|
|
41
|
+
}
|
|
42
|
+
this.watchCallback({
|
|
43
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44
|
+
...t,
|
|
45
|
+
...e && { hash: e }
|
|
31
46
|
});
|
|
32
47
|
}
|
|
33
48
|
/**
|
|
34
49
|
* Creates a new OPFSFileSystem instance
|
|
35
50
|
*
|
|
36
51
|
* @param watchCallback - Optional callback for file change events
|
|
37
|
-
* @param
|
|
52
|
+
* @param options - Optional configuration options
|
|
53
|
+
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
54
|
+
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
55
|
+
* @param options.maxFileSize - Maximum file size for hashing in bytes (default: 50MB)
|
|
38
56
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
39
57
|
*/
|
|
40
58
|
constructor(t, e) {
|
|
41
|
-
|
|
59
|
+
S(), t && (this.watchCallback = t), e && this.setOptions(e), this.mount("/");
|
|
42
60
|
}
|
|
43
61
|
/**
|
|
44
62
|
* Initialize the file system within a given directory
|
|
@@ -68,7 +86,7 @@ class N {
|
|
|
68
86
|
const r = await navigator.storage.getDirectory();
|
|
69
87
|
t === "/" ? this.root = r : this.root = await this.getDirectoryHandle(t, !0, r), e(!0);
|
|
70
88
|
} catch (r) {
|
|
71
|
-
console.error(r), i(new
|
|
89
|
+
console.error(r), i(new n("Failed to initialize OPFS", "INIT_FAILED"));
|
|
72
90
|
} finally {
|
|
73
91
|
this.mountingPromise = null;
|
|
74
92
|
}
|
|
@@ -78,10 +96,20 @@ class N {
|
|
|
78
96
|
* Set the watch callback for file change events
|
|
79
97
|
*
|
|
80
98
|
* @param callback - The callback function to invoke when files change
|
|
81
|
-
* @param options - Optional configuration for watching
|
|
82
99
|
*/
|
|
83
|
-
setWatchCallback(t
|
|
84
|
-
this.watchCallback = t
|
|
100
|
+
setWatchCallback(t) {
|
|
101
|
+
this.watchCallback = t;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Update configuration options
|
|
105
|
+
*
|
|
106
|
+
* @param options - Configuration options to update
|
|
107
|
+
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
108
|
+
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
109
|
+
* @param options.maxFileSize - Maximum file size for hashing in bytes
|
|
110
|
+
*/
|
|
111
|
+
setOptions(t) {
|
|
112
|
+
t.watchInterval !== void 0 && (this.options.watchInterval = t.watchInterval), t.hashAlgorithm !== void 0 && (this.options.hashAlgorithm = t.hashAlgorithm), t.maxFileSize !== void 0 && (this.options.maxFileSize = t.maxFileSize);
|
|
85
113
|
}
|
|
86
114
|
/**
|
|
87
115
|
* Automatically mount the OPFS root if not already mounted
|
|
@@ -98,7 +126,7 @@ class N {
|
|
|
98
126
|
await this.mountingPromise;
|
|
99
127
|
return;
|
|
100
128
|
}
|
|
101
|
-
throw new
|
|
129
|
+
throw new n("OPFS not mounted", "NOT_MOUNTED");
|
|
102
130
|
}
|
|
103
131
|
}
|
|
104
132
|
/**
|
|
@@ -121,11 +149,11 @@ class N {
|
|
|
121
149
|
*/
|
|
122
150
|
async getDirectoryHandle(t, e = !1, i = this.root) {
|
|
123
151
|
if (!i)
|
|
124
|
-
throw new
|
|
125
|
-
const r = Array.isArray(t) ? t :
|
|
152
|
+
throw new l();
|
|
153
|
+
const r = Array.isArray(t) ? t : w(t);
|
|
126
154
|
let a = i;
|
|
127
|
-
for (const
|
|
128
|
-
a = await a.getDirectoryHandle(
|
|
155
|
+
for (const s of r)
|
|
156
|
+
a = await a.getDirectoryHandle(s, { create: e });
|
|
129
157
|
return a;
|
|
130
158
|
}
|
|
131
159
|
/**
|
|
@@ -149,43 +177,25 @@ class N {
|
|
|
149
177
|
*/
|
|
150
178
|
async getFileHandle(t, e = !1, i = this.root) {
|
|
151
179
|
if (!i)
|
|
152
|
-
throw new
|
|
153
|
-
const r =
|
|
180
|
+
throw new l();
|
|
181
|
+
const r = w(t);
|
|
154
182
|
if (r.length === 0)
|
|
155
|
-
throw new
|
|
183
|
+
throw new g("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
156
184
|
const a = r.pop();
|
|
157
185
|
return (await this.getDirectoryHandle(r, e, i)).getFileHandle(a, { create: e });
|
|
158
186
|
}
|
|
159
187
|
/**
|
|
160
|
-
*
|
|
188
|
+
* Get a complete index of all files and directories in the file system
|
|
161
189
|
*
|
|
162
|
-
*
|
|
163
|
-
* a Map containing
|
|
190
|
+
* This method recursively traverses the entire file system and returns
|
|
191
|
+
* a Map containing FileStat objects for every file and directory.
|
|
164
192
|
*
|
|
165
|
-
* @
|
|
166
|
-
* @
|
|
167
|
-
* @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
|
|
168
|
-
* @returns Promise that resolves to a Map of path => FileStat
|
|
169
|
-
* @throws {OPFSError} If the indexing operation fails
|
|
193
|
+
* @returns Promise that resolves to a Map of paths to FileStat objects
|
|
194
|
+
* @throws {OPFSError} If the file system is not mounted
|
|
170
195
|
*
|
|
171
196
|
* @example
|
|
172
197
|
* ```typescript
|
|
173
|
-
* // Basic index without hash
|
|
174
198
|
* const index = await fs.index();
|
|
175
|
-
*
|
|
176
|
-
* // Index with file hash
|
|
177
|
-
* const indexWithHash = await fs.index({
|
|
178
|
-
* includeHash: true,
|
|
179
|
-
* hashAlgorithm: 'SHA-1'
|
|
180
|
-
* });
|
|
181
|
-
*
|
|
182
|
-
* // Iterate through all files and directories
|
|
183
|
-
* for (const [path, stat] of index) {
|
|
184
|
-
* console.log(`${path}: ${stat.isFile ? 'file' : 'directory'} (${stat.size} bytes)`);
|
|
185
|
-
* if (stat.hash) console.log(` Hash: ${stat.hash}`);
|
|
186
|
-
* }
|
|
187
|
-
*
|
|
188
|
-
* // Get specific file stats
|
|
189
199
|
* const fileStats = index.get('/data/config.json');
|
|
190
200
|
* if (fileStats) {
|
|
191
201
|
* console.log(`File size: ${fileStats.size} bytes`);
|
|
@@ -193,35 +203,35 @@ class N {
|
|
|
193
203
|
* }
|
|
194
204
|
* ```
|
|
195
205
|
*/
|
|
196
|
-
async index(
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
for (const
|
|
200
|
-
const s = `${
|
|
206
|
+
async index() {
|
|
207
|
+
const t = /* @__PURE__ */ new Map(), e = async (i) => {
|
|
208
|
+
const r = await this.readdir(i, { withFileTypes: !0 });
|
|
209
|
+
for (const a of r) {
|
|
210
|
+
const s = `${i === "/" ? "" : i}/${a.name}`;
|
|
201
211
|
try {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
} catch (
|
|
205
|
-
console.warn(`Skipping broken entry: ${s}`,
|
|
212
|
+
const o = await this.stat(s);
|
|
213
|
+
t.set(s, o), o.isDirectory && await e(s);
|
|
214
|
+
} catch (o) {
|
|
215
|
+
console.warn(`Skipping broken entry: ${s}`, o);
|
|
206
216
|
}
|
|
207
217
|
}
|
|
208
218
|
};
|
|
209
|
-
return
|
|
219
|
+
return t.set("/", {
|
|
210
220
|
kind: "directory",
|
|
211
221
|
size: 0,
|
|
212
222
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
213
223
|
ctime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
214
224
|
isFile: !1,
|
|
215
225
|
isDirectory: !0
|
|
216
|
-
}), await
|
|
226
|
+
}), await e("/"), t;
|
|
217
227
|
}
|
|
218
228
|
async readFile(t, e = "utf-8") {
|
|
219
229
|
await this.ensureMounted();
|
|
220
230
|
try {
|
|
221
|
-
const i = await this.getFileHandle(t, !1), r = await
|
|
222
|
-
return e === "binary" ? r :
|
|
231
|
+
const i = await this.getFileHandle(t, !1), r = await v(i);
|
|
232
|
+
return e === "binary" ? r : I(r, e);
|
|
223
233
|
} catch (i) {
|
|
224
|
-
throw console.error(i), new
|
|
234
|
+
throw console.error(i), new f(t);
|
|
225
235
|
}
|
|
226
236
|
}
|
|
227
237
|
/**
|
|
@@ -252,7 +262,7 @@ class N {
|
|
|
252
262
|
async writeFile(t, e, i) {
|
|
253
263
|
await this.ensureMounted();
|
|
254
264
|
const r = await this.getFileHandle(t, !0);
|
|
255
|
-
await
|
|
265
|
+
await F(r, e, i, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
256
266
|
}
|
|
257
267
|
/**
|
|
258
268
|
* Append data to a file
|
|
@@ -279,7 +289,7 @@ class N {
|
|
|
279
289
|
async appendFile(t, e, i) {
|
|
280
290
|
await this.ensureMounted();
|
|
281
291
|
const r = await this.getFileHandle(t, !0);
|
|
282
|
-
await
|
|
292
|
+
await F(r, e, i, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
283
293
|
}
|
|
284
294
|
/**
|
|
285
295
|
* Create a directory
|
|
@@ -304,52 +314,45 @@ class N {
|
|
|
304
314
|
*/
|
|
305
315
|
async mkdir(t, e) {
|
|
306
316
|
if (await this.ensureMounted(), !this.root)
|
|
307
|
-
throw new
|
|
308
|
-
const i = e?.recursive ?? !1, r =
|
|
317
|
+
throw new l();
|
|
318
|
+
const i = e?.recursive ?? !1, r = w(t);
|
|
309
319
|
let a = this.root;
|
|
310
|
-
for (let
|
|
311
|
-
const
|
|
320
|
+
for (let s = 0; s < r.length; s++) {
|
|
321
|
+
const o = r[s];
|
|
312
322
|
try {
|
|
313
|
-
a = await a.getDirectoryHandle(
|
|
323
|
+
a = await a.getDirectoryHandle(o, { create: i || s === r.length - 1 });
|
|
314
324
|
} catch (c) {
|
|
315
|
-
throw c.name === "NotFoundError" ? new
|
|
316
|
-
`Parent directory does not exist: ${
|
|
325
|
+
throw c.name === "NotFoundError" ? new n(
|
|
326
|
+
`Parent directory does not exist: ${T(r.slice(0, s + 1))}`,
|
|
317
327
|
"ENOENT"
|
|
318
|
-
) : c.name === "TypeMismatchError" ? new
|
|
328
|
+
) : c.name === "TypeMismatchError" ? new n(`Path segment is not a directory: ${o}`, "ENOTDIR") : new n("Failed to create directory", "MKDIR_FAILED");
|
|
319
329
|
}
|
|
320
330
|
}
|
|
321
|
-
this.
|
|
331
|
+
await this.notifyChange({ path: t, type: "added", isDirectory: !0 });
|
|
322
332
|
}
|
|
323
333
|
/**
|
|
324
|
-
* Get file or directory
|
|
334
|
+
* Get file or directory statistics
|
|
325
335
|
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
336
|
+
* Returns detailed information about a file or directory, including
|
|
337
|
+
* size, modification time, and optionally a hash of the file content.
|
|
328
338
|
*
|
|
329
339
|
* @param path - The path to the file or directory
|
|
330
|
-
* @
|
|
331
|
-
* @
|
|
332
|
-
* @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
|
|
333
|
-
* @returns Promise that resolves to file/directory statistics
|
|
334
|
-
* @throws {OPFSError} If the file or directory does not exist or cannot be accessed
|
|
340
|
+
* @returns Promise that resolves to FileStat object
|
|
341
|
+
* @throws {OPFSError} If the path does not exist or cannot be accessed
|
|
335
342
|
*
|
|
336
343
|
* @example
|
|
337
344
|
* ```typescript
|
|
338
|
-
*
|
|
339
|
-
* const stats = await fs.stat('/config/settings.json');
|
|
345
|
+
* const stats = await fs.stat('/data/config.json');
|
|
340
346
|
* console.log(`File size: ${stats.size} bytes`);
|
|
341
|
-
* console.log(`
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
* hashAlgorithm: 'SHA-1'
|
|
348
|
-
* });
|
|
349
|
-
* console.log(`Hash: ${statsWithHash.hash}`);
|
|
347
|
+
* console.log(`Last modified: ${stats.mtime}`);
|
|
348
|
+
*
|
|
349
|
+
* // If hashing is enabled, hash will be included
|
|
350
|
+
* if (stats.hash) {
|
|
351
|
+
* console.log(`Hash: ${stats.hash}`);
|
|
352
|
+
* }
|
|
350
353
|
* ```
|
|
351
354
|
*/
|
|
352
|
-
async stat(t
|
|
355
|
+
async stat(t) {
|
|
353
356
|
if (await this.ensureMounted(), t === "/")
|
|
354
357
|
return {
|
|
355
358
|
kind: "directory",
|
|
@@ -359,30 +362,30 @@ class N {
|
|
|
359
362
|
isFile: !1,
|
|
360
363
|
isDirectory: !0
|
|
361
364
|
};
|
|
362
|
-
const
|
|
365
|
+
const e = y(t), i = await this.getDirectoryHandle(u(t), !1), r = this.options.hashAlgorithm !== null;
|
|
363
366
|
try {
|
|
364
|
-
const
|
|
367
|
+
const s = await (await i.getFileHandle(e, { create: !1 })).getFile(), o = {
|
|
365
368
|
kind: "file",
|
|
366
|
-
size:
|
|
367
|
-
mtime: new Date(
|
|
368
|
-
ctime: new Date(
|
|
369
|
+
size: s.size,
|
|
370
|
+
mtime: new Date(s.lastModified).toISOString(),
|
|
371
|
+
ctime: new Date(s.lastModified).toISOString(),
|
|
369
372
|
isFile: !0,
|
|
370
373
|
isDirectory: !1
|
|
371
374
|
};
|
|
372
|
-
if (
|
|
375
|
+
if (r && this.options.hashAlgorithm)
|
|
373
376
|
try {
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
} catch (
|
|
377
|
-
console.warn(`Failed to calculate hash for ${t}:`,
|
|
377
|
+
const c = await M(s, this.options.hashAlgorithm, this.options.maxFileSize);
|
|
378
|
+
o.hash = c;
|
|
379
|
+
} catch (c) {
|
|
380
|
+
console.warn(`Failed to calculate hash for ${t}:`, c);
|
|
378
381
|
}
|
|
379
|
-
return
|
|
380
|
-
} catch (
|
|
381
|
-
if (
|
|
382
|
-
throw new
|
|
382
|
+
return o;
|
|
383
|
+
} catch (a) {
|
|
384
|
+
if (a.name !== "TypeMismatchError" && a.name !== "NotFoundError")
|
|
385
|
+
throw new n("Failed to stat (file)", "STAT_FAILED");
|
|
383
386
|
}
|
|
384
387
|
try {
|
|
385
|
-
return await
|
|
388
|
+
return await i.getDirectoryHandle(e, { create: !1 }), {
|
|
386
389
|
kind: "directory",
|
|
387
390
|
size: 0,
|
|
388
391
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
@@ -390,8 +393,8 @@ class N {
|
|
|
390
393
|
isFile: !1,
|
|
391
394
|
isDirectory: !0
|
|
392
395
|
};
|
|
393
|
-
} catch (
|
|
394
|
-
throw
|
|
396
|
+
} catch (a) {
|
|
397
|
+
throw a.name === "NotFoundError" ? new n(`No such file or directory: ${t}`, "ENOENT") : new n("Failed to stat (directory)", "STAT_FAILED");
|
|
395
398
|
}
|
|
396
399
|
}
|
|
397
400
|
async readdir(t, e) {
|
|
@@ -399,11 +402,11 @@ class N {
|
|
|
399
402
|
const i = e?.withFileTypes ?? !1, r = await this.getDirectoryHandle(t, !1);
|
|
400
403
|
if (i) {
|
|
401
404
|
const a = [];
|
|
402
|
-
for await (const [
|
|
403
|
-
const c =
|
|
405
|
+
for await (const [s, o] of r.entries()) {
|
|
406
|
+
const c = o.kind === "file";
|
|
404
407
|
a.push({
|
|
405
|
-
name:
|
|
406
|
-
kind:
|
|
408
|
+
name: s,
|
|
409
|
+
kind: o.kind,
|
|
407
410
|
isFile: c,
|
|
408
411
|
isDirectory: !c
|
|
409
412
|
});
|
|
@@ -411,8 +414,8 @@ class N {
|
|
|
411
414
|
return a;
|
|
412
415
|
} else {
|
|
413
416
|
const a = [];
|
|
414
|
-
for await (const [
|
|
415
|
-
a.push(
|
|
417
|
+
for await (const [s] of r.entries())
|
|
418
|
+
a.push(s);
|
|
416
419
|
return a;
|
|
417
420
|
}
|
|
418
421
|
}
|
|
@@ -433,10 +436,10 @@ class N {
|
|
|
433
436
|
async exists(t) {
|
|
434
437
|
if (await this.ensureMounted(), t === "/")
|
|
435
438
|
return !0;
|
|
436
|
-
const e =
|
|
439
|
+
const e = y(t);
|
|
437
440
|
let i = null;
|
|
438
441
|
try {
|
|
439
|
-
i = await this.getDirectoryHandle(
|
|
442
|
+
i = await this.getDirectoryHandle(u(t), !1);
|
|
440
443
|
} catch (r) {
|
|
441
444
|
throw (r.name === "NotFoundError" || r.name === "TypeMismatchError") && (i = null), r;
|
|
442
445
|
}
|
|
@@ -483,9 +486,9 @@ class N {
|
|
|
483
486
|
const r = `${t === "/" ? "" : t}/${i.name}`;
|
|
484
487
|
await this.remove(r, { recursive: !0 });
|
|
485
488
|
}
|
|
486
|
-
this.
|
|
489
|
+
await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
|
|
487
490
|
} catch (e) {
|
|
488
|
-
throw e instanceof
|
|
491
|
+
throw e instanceof n ? e : new n(`Failed to clear directory: ${t}`, "CLEAR_FAILED");
|
|
489
492
|
}
|
|
490
493
|
}
|
|
491
494
|
/**
|
|
@@ -516,20 +519,20 @@ class N {
|
|
|
516
519
|
await this.ensureMounted();
|
|
517
520
|
const i = e?.recursive ?? !1, r = e?.force ?? !1;
|
|
518
521
|
if (t === "/")
|
|
519
|
-
throw new
|
|
520
|
-
const a =
|
|
522
|
+
throw new n("Cannot remove root directory", "EROOT");
|
|
523
|
+
const a = y(t);
|
|
521
524
|
if (!a)
|
|
522
|
-
throw new
|
|
523
|
-
const
|
|
525
|
+
throw new g("Invalid path", t);
|
|
526
|
+
const s = await this.getDirectoryHandle(u(t), !1);
|
|
524
527
|
try {
|
|
525
|
-
await
|
|
526
|
-
} catch (
|
|
527
|
-
if (
|
|
528
|
+
await s.removeEntry(a, { recursive: i });
|
|
529
|
+
} catch (o) {
|
|
530
|
+
if (o.name === "NotFoundError") {
|
|
528
531
|
if (!r)
|
|
529
|
-
throw new
|
|
530
|
-
} else throw
|
|
532
|
+
throw new n(`No such file or directory: ${t}`, "ENOENT");
|
|
533
|
+
} 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");
|
|
531
534
|
}
|
|
532
|
-
this.
|
|
535
|
+
await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
|
|
533
536
|
}
|
|
534
537
|
/**
|
|
535
538
|
* Resolve a path to an absolute path
|
|
@@ -552,12 +555,12 @@ class N {
|
|
|
552
555
|
async realpath(t) {
|
|
553
556
|
await this.ensureMounted();
|
|
554
557
|
try {
|
|
555
|
-
const e =
|
|
558
|
+
const e = A(t);
|
|
556
559
|
if (!await this.exists(e))
|
|
557
|
-
throw new
|
|
560
|
+
throw new f(e);
|
|
558
561
|
return e;
|
|
559
562
|
} catch (e) {
|
|
560
|
-
throw e instanceof
|
|
563
|
+
throw e instanceof n ? e : new n(`Failed to resolve path: ${t}`, "REALPATH_FAILED");
|
|
561
564
|
}
|
|
562
565
|
}
|
|
563
566
|
/**
|
|
@@ -580,10 +583,10 @@ class N {
|
|
|
580
583
|
await this.ensureMounted();
|
|
581
584
|
try {
|
|
582
585
|
if (!await this.exists(t))
|
|
583
|
-
throw new
|
|
584
|
-
await this.copy(t, e, { recursive: !0 }), await this.remove(t, { recursive: !0 }), this.
|
|
586
|
+
throw new f(t);
|
|
587
|
+
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 });
|
|
585
588
|
} catch (i) {
|
|
586
|
-
throw i instanceof
|
|
589
|
+
throw i instanceof n ? i : new n(`Failed to rename from ${t} to ${e}`, "RENAME_FAILED");
|
|
587
590
|
}
|
|
588
591
|
}
|
|
589
592
|
/**
|
|
@@ -616,25 +619,25 @@ class N {
|
|
|
616
619
|
try {
|
|
617
620
|
const r = i?.recursive ?? !1, a = i?.force ?? !0;
|
|
618
621
|
if (!await this.exists(t))
|
|
619
|
-
throw new
|
|
622
|
+
throw new n(`Source does not exist: ${t}`, "ENOENT");
|
|
620
623
|
if (await this.exists(e) && !a)
|
|
621
|
-
throw new
|
|
624
|
+
throw new n(`Destination already exists: ${e}`, "EEXIST");
|
|
622
625
|
if ((await this.stat(t)).isFile) {
|
|
623
|
-
const
|
|
624
|
-
await this.writeFile(e,
|
|
626
|
+
const h = await this.readFile(t, "binary");
|
|
627
|
+
await this.writeFile(e, h);
|
|
625
628
|
} else {
|
|
626
629
|
if (!r)
|
|
627
|
-
throw new
|
|
630
|
+
throw new n(`Cannot copy directory without recursive option: ${t}`, "EISDIR");
|
|
628
631
|
await this.mkdir(e, { recursive: !0 });
|
|
629
|
-
const
|
|
630
|
-
for (const
|
|
631
|
-
const
|
|
632
|
-
await this.copy(
|
|
632
|
+
const h = await this.readdir(t, { withFileTypes: !0 });
|
|
633
|
+
for (const m of h) {
|
|
634
|
+
const D = `${t}/${m.name}`, p = `${e}/${m.name}`;
|
|
635
|
+
await this.copy(D, p, { recursive: !0, force: a });
|
|
633
636
|
}
|
|
634
637
|
}
|
|
635
|
-
this.
|
|
638
|
+
await this.notifyChange({ path: e, type: "added", isDirectory: !1 });
|
|
636
639
|
} catch (r) {
|
|
637
|
-
throw r instanceof
|
|
640
|
+
throw r instanceof n ? r : new n(`Failed to copy from ${t} to ${e}`, "CP_FAILED");
|
|
638
641
|
}
|
|
639
642
|
}
|
|
640
643
|
/**
|
|
@@ -642,25 +645,25 @@ class N {
|
|
|
642
645
|
*/
|
|
643
646
|
async watch(t) {
|
|
644
647
|
await this.ensureMounted();
|
|
645
|
-
const e =
|
|
648
|
+
const e = d(t), i = await this.buildSnapshot(e);
|
|
646
649
|
this.watchers.set(e, i), this.watchTimer || (this.watchTimer = setInterval(() => {
|
|
647
650
|
this.scanWatches();
|
|
648
|
-
}, this.watchInterval));
|
|
651
|
+
}, this.options.watchInterval));
|
|
649
652
|
}
|
|
650
653
|
/**
|
|
651
654
|
* Stop watching a previously watched path
|
|
652
655
|
*/
|
|
653
656
|
unwatch(t) {
|
|
654
|
-
const e =
|
|
657
|
+
const e = d(t);
|
|
655
658
|
this.watchers.delete(e), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
656
659
|
}
|
|
657
660
|
async buildSnapshot(t) {
|
|
658
661
|
const e = /* @__PURE__ */ new Map(), i = async (r) => {
|
|
659
662
|
const a = await this.stat(r);
|
|
660
663
|
if (e.set(r, a), a.isDirectory) {
|
|
661
|
-
const
|
|
662
|
-
for (const
|
|
663
|
-
const c = `${r === "/" ? "" : r}/${
|
|
664
|
+
const s = await this.readdir(r, { withFileTypes: !0 });
|
|
665
|
+
for (const o of s) {
|
|
666
|
+
const c = `${r === "/" ? "" : r}/${o.name}`;
|
|
664
667
|
await i(c);
|
|
665
668
|
}
|
|
666
669
|
}
|
|
@@ -679,16 +682,12 @@ class N {
|
|
|
679
682
|
} catch {
|
|
680
683
|
i = /* @__PURE__ */ new Map();
|
|
681
684
|
}
|
|
682
|
-
const r
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
s ? (s.mtime !== n.mtime || s.size !== n.size) && r.push({ path: a, type: "change" }) : r.push({ path: a, type: "create" });
|
|
685
|
+
for (const [r, a] of i) {
|
|
686
|
+
const s = e.get(r);
|
|
687
|
+
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 });
|
|
686
688
|
}
|
|
687
|
-
for (const
|
|
688
|
-
i.has(
|
|
689
|
-
if (r.length && this.watchCallback)
|
|
690
|
-
for (const a of r)
|
|
691
|
-
this.watchCallback(a);
|
|
689
|
+
for (const r of e.keys())
|
|
690
|
+
i.has(r) || await this.notifyChange({ path: r, type: "removed", isDirectory: !1 });
|
|
692
691
|
this.watchers.set(t, i);
|
|
693
692
|
})
|
|
694
693
|
);
|
|
@@ -730,18 +729,18 @@ class N {
|
|
|
730
729
|
try {
|
|
731
730
|
(e?.cleanBefore ?? !1) && await this.clear("/");
|
|
732
731
|
for (const [r, a] of t) {
|
|
733
|
-
const
|
|
734
|
-
let
|
|
735
|
-
a instanceof Blob ?
|
|
732
|
+
const s = d(r);
|
|
733
|
+
let o;
|
|
734
|
+
a instanceof Blob ? o = await $(a) : o = a, await this.writeFile(s, o);
|
|
736
735
|
}
|
|
737
|
-
this.
|
|
736
|
+
await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
|
|
738
737
|
} catch (i) {
|
|
739
|
-
throw i instanceof
|
|
738
|
+
throw i instanceof n ? i : new n("Failed to sync file system", "SYNC_FAILED");
|
|
740
739
|
}
|
|
741
740
|
}
|
|
742
741
|
}
|
|
743
|
-
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" &&
|
|
742
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && E(new O());
|
|
744
743
|
export {
|
|
745
|
-
|
|
744
|
+
O as OPFSWorker
|
|
746
745
|
};
|
|
747
746
|
//# sourceMappingURL=raw.js.map
|