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/index.cjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("comlink"),n=require("./helpers-B87wz5kv.cjs"),i=`/**
|
|
2
2
|
* @license
|
|
3
3
|
* Copyright 2019 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
const H = Symbol("Comlink.proxy"), R = Symbol("Comlink.endpoint"), B = Symbol("Comlink.releaseProxy"),
|
|
6
|
+
const H = Symbol("Comlink.proxy"), R = Symbol("Comlink.endpoint"), B = Symbol("Comlink.releaseProxy"), C = Symbol("Comlink.finalizer"), p = Symbol("Comlink.thrown"), $ = (e) => typeof e == "object" && e !== null || typeof e == "function", W = {
|
|
7
7
|
canHandle: (e) => $(e) && e[H],
|
|
8
8
|
serialize(e) {
|
|
9
9
|
const { port1: t, port2: r } = new MessageChannel();
|
|
10
|
-
return
|
|
10
|
+
return x(e, t), [r, [r]];
|
|
11
11
|
},
|
|
12
12
|
deserialize(e) {
|
|
13
13
|
return e.start(), Y(e);
|
|
14
14
|
}
|
|
15
15
|
}, j = {
|
|
16
|
-
canHandle: (e) => $(e) &&
|
|
16
|
+
canHandle: (e) => $(e) && p in e,
|
|
17
17
|
serialize({ value: e }) {
|
|
18
18
|
let t;
|
|
19
19
|
return e instanceof Error ? t = {
|
|
@@ -38,15 +38,15 @@ function V(e, t) {
|
|
|
38
38
|
return !0;
|
|
39
39
|
return !1;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
t.addEventListener("message", function n
|
|
43
|
-
if (!
|
|
41
|
+
function x(e, t = globalThis, r = ["*"]) {
|
|
42
|
+
t.addEventListener("message", function i(n) {
|
|
43
|
+
if (!n || !n.data)
|
|
44
44
|
return;
|
|
45
|
-
if (!V(r,
|
|
46
|
-
console.warn(\`Invalid origin '\${
|
|
45
|
+
if (!V(r, n.origin)) {
|
|
46
|
+
console.warn(\`Invalid origin '\${n.origin}' for comlink proxy\`);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
const { id: a, type: s, path: o } = Object.assign({ path: [] },
|
|
49
|
+
const { id: a, type: s, path: o } = Object.assign({ path: [] }, n.data), l = (n.data.argumentList || []).map(d);
|
|
50
50
|
let h;
|
|
51
51
|
try {
|
|
52
52
|
const u = o.slice(0, -1).reduce((f, g) => f[g], e), w = o.reduce((f, g) => f[g], e);
|
|
@@ -55,7 +55,7 @@ function I(e, t = globalThis, r = ["*"]) {
|
|
|
55
55
|
h = w;
|
|
56
56
|
break;
|
|
57
57
|
case "SET":
|
|
58
|
-
u[o.slice(-1)[0]] =
|
|
58
|
+
u[o.slice(-1)[0]] = d(n.data.value), h = !0;
|
|
59
59
|
break;
|
|
60
60
|
case "APPLY":
|
|
61
61
|
h = w.apply(u, l);
|
|
@@ -69,7 +69,7 @@ function I(e, t = globalThis, r = ["*"]) {
|
|
|
69
69
|
case "ENDPOINT":
|
|
70
70
|
{
|
|
71
71
|
const { port1: f, port2: g } = new MessageChannel();
|
|
72
|
-
|
|
72
|
+
x(e, g), h = J(f, [f]);
|
|
73
73
|
}
|
|
74
74
|
break;
|
|
75
75
|
case "RELEASE":
|
|
@@ -79,15 +79,15 @@ function I(e, t = globalThis, r = ["*"]) {
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
} catch (u) {
|
|
82
|
-
h = { value: u, [
|
|
82
|
+
h = { value: u, [p]: 0 };
|
|
83
83
|
}
|
|
84
|
-
Promise.resolve(h).catch((u) => ({ value: u, [
|
|
84
|
+
Promise.resolve(h).catch((u) => ({ value: u, [p]: 0 })).then((u) => {
|
|
85
85
|
const [w, f] = A(u);
|
|
86
|
-
t.postMessage(Object.assign(Object.assign({}, w), { id: a }), f), s === "RELEASE" && (t.removeEventListener("message",
|
|
86
|
+
t.postMessage(Object.assign(Object.assign({}, w), { id: a }), f), s === "RELEASE" && (t.removeEventListener("message", i), L(t), C in e && typeof e[C] == "function" && e[C]());
|
|
87
87
|
}).catch((u) => {
|
|
88
88
|
const [w, f] = A({
|
|
89
89
|
value: new TypeError("Unserializable return value"),
|
|
90
|
-
[
|
|
90
|
+
[p]: 0
|
|
91
91
|
});
|
|
92
92
|
t.postMessage(Object.assign(Object.assign({}, w), { id: a }), f);
|
|
93
93
|
});
|
|
@@ -101,8 +101,8 @@ function L(e) {
|
|
|
101
101
|
}
|
|
102
102
|
function Y(e, t) {
|
|
103
103
|
const r = /* @__PURE__ */ new Map();
|
|
104
|
-
return e.addEventListener("message", function(
|
|
105
|
-
const { data: a } =
|
|
104
|
+
return e.addEventListener("message", function(n) {
|
|
105
|
+
const { data: a } = n;
|
|
106
106
|
if (!a || !a.id)
|
|
107
107
|
return;
|
|
108
108
|
const s = r.get(a.id);
|
|
@@ -114,81 +114,81 @@ function Y(e, t) {
|
|
|
114
114
|
}
|
|
115
115
|
}), M(e, r, [], t);
|
|
116
116
|
}
|
|
117
|
-
function
|
|
117
|
+
function E(e) {
|
|
118
118
|
if (e)
|
|
119
119
|
throw new Error("Proxy has been released and is not useable");
|
|
120
120
|
}
|
|
121
121
|
function U(e) {
|
|
122
|
-
return
|
|
122
|
+
return y(e, /* @__PURE__ */ new Map(), {
|
|
123
123
|
type: "RELEASE"
|
|
124
124
|
}).then(() => {
|
|
125
125
|
L(e);
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
-
const
|
|
129
|
-
const t = (
|
|
130
|
-
|
|
128
|
+
const S = /* @__PURE__ */ new WeakMap(), D = "FinalizationRegistry" in globalThis && new FinalizationRegistry((e) => {
|
|
129
|
+
const t = (S.get(e) || 0) - 1;
|
|
130
|
+
S.set(e, t), t === 0 && U(e);
|
|
131
131
|
});
|
|
132
132
|
function X(e, t) {
|
|
133
|
-
const r = (
|
|
134
|
-
|
|
133
|
+
const r = (S.get(t) || 0) + 1;
|
|
134
|
+
S.set(t, r), D && D.register(e, t, e);
|
|
135
135
|
}
|
|
136
136
|
function q(e) {
|
|
137
|
-
|
|
137
|
+
D && D.unregister(e);
|
|
138
138
|
}
|
|
139
|
-
function M(e, t, r = [],
|
|
139
|
+
function M(e, t, r = [], i = function() {
|
|
140
140
|
}) {
|
|
141
|
-
let
|
|
142
|
-
const a = new Proxy(
|
|
141
|
+
let n = !1;
|
|
142
|
+
const a = new Proxy(i, {
|
|
143
143
|
get(s, o) {
|
|
144
|
-
if (
|
|
144
|
+
if (E(n), o === B)
|
|
145
145
|
return () => {
|
|
146
|
-
q(a), U(e), t.clear(),
|
|
146
|
+
q(a), U(e), t.clear(), n = !0;
|
|
147
147
|
};
|
|
148
148
|
if (o === "then") {
|
|
149
149
|
if (r.length === 0)
|
|
150
150
|
return { then: () => a };
|
|
151
|
-
const l =
|
|
151
|
+
const l = y(e, t, {
|
|
152
152
|
type: "GET",
|
|
153
153
|
path: r.map((h) => h.toString())
|
|
154
|
-
}).then(
|
|
154
|
+
}).then(d);
|
|
155
155
|
return l.then.bind(l);
|
|
156
156
|
}
|
|
157
157
|
return M(e, t, [...r, o]);
|
|
158
158
|
},
|
|
159
159
|
set(s, o, l) {
|
|
160
|
-
|
|
160
|
+
E(n);
|
|
161
161
|
const [h, u] = A(l);
|
|
162
|
-
return
|
|
162
|
+
return y(e, t, {
|
|
163
163
|
type: "SET",
|
|
164
164
|
path: [...r, o].map((w) => w.toString()),
|
|
165
165
|
value: h
|
|
166
|
-
}, u).then(
|
|
166
|
+
}, u).then(d);
|
|
167
167
|
},
|
|
168
168
|
apply(s, o, l) {
|
|
169
|
-
|
|
169
|
+
E(n);
|
|
170
170
|
const h = r[r.length - 1];
|
|
171
171
|
if (h === R)
|
|
172
|
-
return
|
|
172
|
+
return y(e, t, {
|
|
173
173
|
type: "ENDPOINT"
|
|
174
|
-
}).then(
|
|
174
|
+
}).then(d);
|
|
175
175
|
if (h === "bind")
|
|
176
176
|
return M(e, t, r.slice(0, -1));
|
|
177
|
-
const [u, w] =
|
|
178
|
-
return
|
|
177
|
+
const [u, w] = v(l);
|
|
178
|
+
return y(e, t, {
|
|
179
179
|
type: "APPLY",
|
|
180
180
|
path: r.map((f) => f.toString()),
|
|
181
181
|
argumentList: u
|
|
182
|
-
}, w).then(
|
|
182
|
+
}, w).then(d);
|
|
183
183
|
},
|
|
184
184
|
construct(s, o) {
|
|
185
|
-
|
|
186
|
-
const [l, h] =
|
|
187
|
-
return
|
|
185
|
+
E(n);
|
|
186
|
+
const [l, h] = v(o);
|
|
187
|
+
return y(e, t, {
|
|
188
188
|
type: "CONSTRUCT",
|
|
189
189
|
path: r.map((u) => u.toString()),
|
|
190
190
|
argumentList: l
|
|
191
|
-
}, h).then(
|
|
191
|
+
}, h).then(d);
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
return X(a, e), a;
|
|
@@ -196,7 +196,7 @@ function M(e, t, r = [], n = function() {
|
|
|
196
196
|
function K(e) {
|
|
197
197
|
return Array.prototype.concat.apply([], e);
|
|
198
198
|
}
|
|
199
|
-
function
|
|
199
|
+
function v(e) {
|
|
200
200
|
const t = e.map(A);
|
|
201
201
|
return [t.map((r) => r[0]), K(t.map((r) => r[1]))];
|
|
202
202
|
}
|
|
@@ -210,14 +210,14 @@ function Q(e) {
|
|
|
210
210
|
function A(e) {
|
|
211
211
|
for (const [t, r] of z)
|
|
212
212
|
if (r.canHandle(e)) {
|
|
213
|
-
const [
|
|
213
|
+
const [i, n] = r.serialize(e);
|
|
214
214
|
return [
|
|
215
215
|
{
|
|
216
216
|
type: "HANDLER",
|
|
217
217
|
name: t,
|
|
218
|
-
value:
|
|
218
|
+
value: i
|
|
219
219
|
},
|
|
220
|
-
|
|
220
|
+
n
|
|
221
221
|
];
|
|
222
222
|
}
|
|
223
223
|
return [
|
|
@@ -228,7 +228,7 @@ function A(e) {
|
|
|
228
228
|
_.get(e) || []
|
|
229
229
|
];
|
|
230
230
|
}
|
|
231
|
-
function
|
|
231
|
+
function d(e) {
|
|
232
232
|
switch (e.type) {
|
|
233
233
|
case "HANDLER":
|
|
234
234
|
return z.get(e.name).deserialize(e.value);
|
|
@@ -236,18 +236,18 @@ function y(e) {
|
|
|
236
236
|
return e.value;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
-
function
|
|
240
|
-
return new Promise((
|
|
239
|
+
function y(e, t, r, i) {
|
|
240
|
+
return new Promise((n) => {
|
|
241
241
|
const a = Z();
|
|
242
|
-
t.set(a,
|
|
242
|
+
t.set(a, n), e.start && e.start(), e.postMessage(Object.assign({ id: a }, r), i);
|
|
243
243
|
});
|
|
244
244
|
}
|
|
245
245
|
function Z() {
|
|
246
246
|
return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-");
|
|
247
247
|
}
|
|
248
248
|
class c extends Error {
|
|
249
|
-
constructor(t, r,
|
|
250
|
-
super(t), this.code = r, this.path =
|
|
249
|
+
constructor(t, r, i) {
|
|
250
|
+
super(t), this.code = r, this.path = i, this.name = "OPFSError";
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
class tt extends c {
|
|
@@ -255,17 +255,17 @@ class tt extends c {
|
|
|
255
255
|
super("OPFS is not supported in this browser", "OPFS_NOT_SUPPORTED");
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
class
|
|
258
|
+
class b extends c {
|
|
259
259
|
constructor() {
|
|
260
260
|
super("OPFS is not mounted", "OPFS_NOT_MOUNTED");
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
class
|
|
263
|
+
class N extends c {
|
|
264
264
|
constructor(t, r) {
|
|
265
265
|
super(t, "INVALID_PATH", r);
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
|
-
class
|
|
268
|
+
class T extends c {
|
|
269
269
|
constructor(t) {
|
|
270
270
|
super(\`File not found: \${t}\`, "FILE_NOT_FOUND", t);
|
|
271
271
|
}
|
|
@@ -321,8 +321,8 @@ function rt(e, t = "utf-8") {
|
|
|
321
321
|
function nt(e) {
|
|
322
322
|
const t = new Uint8Array(e.length * 2);
|
|
323
323
|
for (let r = 0; r < e.length; r++) {
|
|
324
|
-
const
|
|
325
|
-
t[r * 2] =
|
|
324
|
+
const i = e.charCodeAt(r);
|
|
325
|
+
t[r * 2] = i & 255, t[r * 2 + 1] = i >> 8;
|
|
326
326
|
}
|
|
327
327
|
return t;
|
|
328
328
|
}
|
|
@@ -348,33 +348,33 @@ function ot() {
|
|
|
348
348
|
throw new tt();
|
|
349
349
|
}
|
|
350
350
|
function m(e) {
|
|
351
|
-
return Array.isArray(e) ? e : e.split("/").filter(Boolean);
|
|
351
|
+
return Array.isArray(e) ? e : (e.startsWith("~/") ? e.slice(2) : e).split("/").filter(Boolean);
|
|
352
352
|
}
|
|
353
|
-
function
|
|
353
|
+
function I(e) {
|
|
354
354
|
return typeof e == "string" ? e ?? "/" : \`/\${e.join("/")}\`;
|
|
355
355
|
}
|
|
356
|
-
function
|
|
356
|
+
function O(e) {
|
|
357
357
|
const t = m(e);
|
|
358
358
|
return t[t.length - 1] || "";
|
|
359
359
|
}
|
|
360
|
-
function
|
|
360
|
+
function P(e) {
|
|
361
361
|
const t = m(e);
|
|
362
|
-
return t.pop(),
|
|
362
|
+
return t.pop(), I(t);
|
|
363
363
|
}
|
|
364
|
-
function
|
|
365
|
-
return !e || e === "/" ? "/" : e.startsWith("/") ? e : \`/\${e}\`;
|
|
364
|
+
function F(e) {
|
|
365
|
+
return !e || e === "/" ? "/" : e.startsWith("~/") ? \`/\${e.slice(2)}\` : e.startsWith("/") ? e : \`/\${e}\`;
|
|
366
366
|
}
|
|
367
367
|
function ct(e) {
|
|
368
|
-
const t =
|
|
369
|
-
for (const n of
|
|
368
|
+
const t = F(e), r = m(t), i = [];
|
|
369
|
+
for (const n of r)
|
|
370
370
|
if (!(n === "." || n === ""))
|
|
371
371
|
if (n === "..") {
|
|
372
|
-
if (
|
|
372
|
+
if (i.length === 0)
|
|
373
373
|
continue;
|
|
374
|
-
|
|
374
|
+
i.pop();
|
|
375
375
|
} else
|
|
376
|
-
|
|
377
|
-
return
|
|
376
|
+
i.push(n);
|
|
377
|
+
return I(i);
|
|
378
378
|
}
|
|
379
379
|
function lt(e, t = "utf-8") {
|
|
380
380
|
return typeof e == "string" ? et(e, t) : e instanceof Uint8Array ? e : new Uint8Array(e);
|
|
@@ -382,26 +382,26 @@ function lt(e, t = "utf-8") {
|
|
|
382
382
|
async function ht(e) {
|
|
383
383
|
const t = await e.createSyncAccessHandle();
|
|
384
384
|
try {
|
|
385
|
-
const r = t.getSize(),
|
|
386
|
-
return t.read(
|
|
385
|
+
const r = t.getSize(), i = new Uint8Array(r);
|
|
386
|
+
return t.read(i, { at: 0 }), i;
|
|
387
387
|
} finally {
|
|
388
388
|
t.close();
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
|
-
async function
|
|
392
|
-
let
|
|
391
|
+
async function k(e, t, r, i = {}) {
|
|
392
|
+
let n = null;
|
|
393
393
|
try {
|
|
394
|
-
|
|
395
|
-
const a = lt(t, r), s =
|
|
396
|
-
|
|
394
|
+
n = await e.createSyncAccessHandle();
|
|
395
|
+
const a = lt(t, r), s = i.append ? n.getSize() : 0;
|
|
396
|
+
n.write(a, { at: s }), i.truncate && !i.append && n.truncate(a.byteLength), n.flush();
|
|
397
397
|
} catch (a) {
|
|
398
398
|
console.error(a);
|
|
399
|
-
const s =
|
|
399
|
+
const s = i.append ? "append" : "write";
|
|
400
400
|
throw new c(\`Failed to \${s} file\`, \`\${s.toUpperCase()}_FAILED\`);
|
|
401
401
|
} finally {
|
|
402
|
-
if (
|
|
402
|
+
if (n)
|
|
403
403
|
try {
|
|
404
|
-
|
|
404
|
+
n.close();
|
|
405
405
|
} catch {
|
|
406
406
|
}
|
|
407
407
|
}
|
|
@@ -409,8 +409,8 @@ async function v(e, t, r, n = {}) {
|
|
|
409
409
|
async function ut(e, t = "SHA-1", r = 50 * 1024 * 1024) {
|
|
410
410
|
if (e instanceof File && (e = await e.arrayBuffer()), e.byteLength > r)
|
|
411
411
|
throw new Error(\`File size \${e.byteLength} bytes exceeds maximum allowed size \${r} bytes\`);
|
|
412
|
-
const
|
|
413
|
-
return Array.from(new Uint8Array(
|
|
412
|
+
const i = new Uint8Array(e), n = await crypto.subtle.digest(t, i);
|
|
413
|
+
return Array.from(new Uint8Array(n)).map((s) => s.toString(16).padStart(2, "0")).join("");
|
|
414
414
|
}
|
|
415
415
|
async function ft(e) {
|
|
416
416
|
const t = await e.arrayBuffer();
|
|
@@ -419,8 +419,6 @@ async function ft(e) {
|
|
|
419
419
|
class wt {
|
|
420
420
|
/** Root directory handle for the file system */
|
|
421
421
|
root = null;
|
|
422
|
-
/** Watch event callback */
|
|
423
|
-
watchCallback = null;
|
|
424
422
|
/** Map of watched paths to their last known state */
|
|
425
423
|
watchers = /* @__PURE__ */ new Map();
|
|
426
424
|
/** Interval handle for polling watched paths */
|
|
@@ -429,11 +427,14 @@ class wt {
|
|
|
429
427
|
scanning = !1;
|
|
430
428
|
/** Promise to prevent concurrent mount operations */
|
|
431
429
|
mountingPromise = null;
|
|
430
|
+
/** BroadcastChannel instance for sending events */
|
|
431
|
+
broadcastChannel = null;
|
|
432
432
|
/** Configuration options */
|
|
433
433
|
options = {
|
|
434
434
|
watchInterval: 1e3,
|
|
435
435
|
maxFileSize: 50 * 1024 * 1024,
|
|
436
|
-
hashAlgorithm: null
|
|
436
|
+
hashAlgorithm: null,
|
|
437
|
+
broadcastChannel: "opfs-worker"
|
|
437
438
|
};
|
|
438
439
|
/**
|
|
439
440
|
* Notify about internal changes to the file system
|
|
@@ -445,34 +446,39 @@ class wt {
|
|
|
445
446
|
* @param type - The type of change (create, change, delete)
|
|
446
447
|
*/
|
|
447
448
|
async notifyChange(t) {
|
|
448
|
-
if (!this.
|
|
449
|
+
if (!this.options.broadcastChannel)
|
|
449
450
|
return;
|
|
450
451
|
let r;
|
|
451
452
|
if (this.options.hashAlgorithm && !t.isDirectory && t.type !== "removed")
|
|
452
453
|
try {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
} catch (
|
|
456
|
-
console.warn(\`Failed to calculate hash for \${t.path}:\`,
|
|
454
|
+
const i = await this.stat(t.path);
|
|
455
|
+
i.isFile && i.hash && (r = i.hash);
|
|
456
|
+
} catch (i) {
|
|
457
|
+
console.warn(\`Failed to calculate hash for \${t.path}:\`, i);
|
|
457
458
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
try {
|
|
460
|
+
this.broadcastChannel || (this.broadcastChannel = new BroadcastChannel(this.options.broadcastChannel));
|
|
461
|
+
const i = {
|
|
462
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
463
|
+
...t,
|
|
464
|
+
...r && { hash: r }
|
|
465
|
+
};
|
|
466
|
+
this.broadcastChannel.postMessage(i);
|
|
467
|
+
} catch (i) {
|
|
468
|
+
console.warn("Failed to send event via BroadcastChannel:", i);
|
|
469
|
+
}
|
|
463
470
|
}
|
|
464
471
|
/**
|
|
465
472
|
* Creates a new OPFSFileSystem instance
|
|
466
473
|
*
|
|
467
|
-
* @param watchCallback - Optional callback for file change events
|
|
468
474
|
* @param options - Optional configuration options
|
|
469
475
|
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
470
476
|
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
471
477
|
* @param options.maxFileSize - Maximum file size for hashing in bytes (default: 50MB)
|
|
472
478
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
473
479
|
*/
|
|
474
|
-
constructor(t
|
|
475
|
-
ot(), t &&
|
|
480
|
+
constructor(t) {
|
|
481
|
+
ot(), t && this.setOptions(t), this.mount("/");
|
|
476
482
|
}
|
|
477
483
|
/**
|
|
478
484
|
* Initialize the file system within a given directory
|
|
@@ -496,26 +502,18 @@ class wt {
|
|
|
496
502
|
* \`\`\`
|
|
497
503
|
*/
|
|
498
504
|
async mount(t = "/") {
|
|
499
|
-
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (r,
|
|
505
|
+
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (r, i) => {
|
|
500
506
|
this.root = null;
|
|
501
507
|
try {
|
|
502
|
-
const
|
|
503
|
-
t === "/" ? this.root =
|
|
504
|
-
} catch (
|
|
505
|
-
console.error(
|
|
508
|
+
const n = await navigator.storage.getDirectory();
|
|
509
|
+
t === "/" ? this.root = n : this.root = await this.getDirectoryHandle(t, !0, n), r(!0);
|
|
510
|
+
} catch (n) {
|
|
511
|
+
console.error(n), i(new c("Failed to initialize OPFS", "INIT_FAILED"));
|
|
506
512
|
} finally {
|
|
507
513
|
this.mountingPromise = null;
|
|
508
514
|
}
|
|
509
515
|
}), this.mountingPromise;
|
|
510
516
|
}
|
|
511
|
-
/**
|
|
512
|
-
* Set the watch callback for file change events
|
|
513
|
-
*
|
|
514
|
-
* @param callback - The callback function to invoke when files change
|
|
515
|
-
*/
|
|
516
|
-
setWatchCallback(t) {
|
|
517
|
-
this.watchCallback = t;
|
|
518
|
-
}
|
|
519
517
|
/**
|
|
520
518
|
* Update configuration options
|
|
521
519
|
*
|
|
@@ -523,9 +521,10 @@ class wt {
|
|
|
523
521
|
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
524
522
|
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
525
523
|
* @param options.maxFileSize - Maximum file size for hashing in bytes
|
|
524
|
+
* @param options.broadcastChannel - Custom name for the broadcast channel
|
|
526
525
|
*/
|
|
527
526
|
setOptions(t) {
|
|
528
|
-
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);
|
|
527
|
+
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);
|
|
529
528
|
}
|
|
530
529
|
/**
|
|
531
530
|
* Automatically mount the OPFS root if not already mounted
|
|
@@ -563,12 +562,12 @@ class wt {
|
|
|
563
562
|
* const docsDir2 = await fs.getDirectoryHandle(['users', 'john', 'documents'], true);
|
|
564
563
|
* \`\`\`
|
|
565
564
|
*/
|
|
566
|
-
async getDirectoryHandle(t, r = !1,
|
|
567
|
-
if (!
|
|
568
|
-
throw new
|
|
569
|
-
const
|
|
570
|
-
let a =
|
|
571
|
-
for (const s of
|
|
565
|
+
async getDirectoryHandle(t, r = !1, i = this.root) {
|
|
566
|
+
if (!i)
|
|
567
|
+
throw new b();
|
|
568
|
+
const n = Array.isArray(t) ? t : m(t);
|
|
569
|
+
let a = i;
|
|
570
|
+
for (const s of n)
|
|
572
571
|
a = await a.getDirectoryHandle(s, { create: r });
|
|
573
572
|
return a;
|
|
574
573
|
}
|
|
@@ -591,14 +590,14 @@ class wt {
|
|
|
591
590
|
* const fileHandle2 = await fs.getFileHandle(['config', 'settings.json'], true);
|
|
592
591
|
* \`\`\`
|
|
593
592
|
*/
|
|
594
|
-
async getFileHandle(t, r = !1,
|
|
595
|
-
if (!
|
|
596
|
-
throw new
|
|
597
|
-
const
|
|
598
|
-
if (
|
|
599
|
-
throw new
|
|
600
|
-
const a =
|
|
601
|
-
return (await this.getDirectoryHandle(
|
|
593
|
+
async getFileHandle(t, r = !1, i = this.root) {
|
|
594
|
+
if (!i)
|
|
595
|
+
throw new b();
|
|
596
|
+
const n = m(t);
|
|
597
|
+
if (n.length === 0)
|
|
598
|
+
throw new N("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
599
|
+
const a = n.pop();
|
|
600
|
+
return (await this.getDirectoryHandle(n, r, i)).getFileHandle(a, { create: r });
|
|
602
601
|
}
|
|
603
602
|
/**
|
|
604
603
|
* Get a complete index of all files and directories in the file system
|
|
@@ -620,10 +619,10 @@ class wt {
|
|
|
620
619
|
* \`\`\`
|
|
621
620
|
*/
|
|
622
621
|
async index() {
|
|
623
|
-
const t = /* @__PURE__ */ new Map(), r = async (
|
|
624
|
-
const
|
|
625
|
-
for (const a of
|
|
626
|
-
const s = \`\${
|
|
622
|
+
const t = /* @__PURE__ */ new Map(), r = async (i) => {
|
|
623
|
+
const n = await this.readDir(i);
|
|
624
|
+
for (const a of n) {
|
|
625
|
+
const s = \`\${i === "/" ? "" : i}/\${a.name}\`;
|
|
627
626
|
try {
|
|
628
627
|
const o = await this.stat(s);
|
|
629
628
|
t.set(s, o), o.isDirectory && await r(s);
|
|
@@ -644,10 +643,10 @@ class wt {
|
|
|
644
643
|
async readFile(t, r = "utf-8") {
|
|
645
644
|
await this.ensureMounted();
|
|
646
645
|
try {
|
|
647
|
-
const
|
|
648
|
-
return r === "binary" ?
|
|
649
|
-
} catch (
|
|
650
|
-
throw console.error(
|
|
646
|
+
const i = await this.getFileHandle(t, !1), n = await ht(i);
|
|
647
|
+
return r === "binary" ? n : rt(n, r);
|
|
648
|
+
} catch (i) {
|
|
649
|
+
throw console.error(i), new T(t);
|
|
651
650
|
}
|
|
652
651
|
}
|
|
653
652
|
/**
|
|
@@ -675,10 +674,10 @@ class wt {
|
|
|
675
674
|
* await fs.writeFile('/data/utf16.txt', 'Hello World', 'utf-16le');
|
|
676
675
|
* \`\`\`
|
|
677
676
|
*/
|
|
678
|
-
async writeFile(t, r,
|
|
677
|
+
async writeFile(t, r, i) {
|
|
679
678
|
await this.ensureMounted();
|
|
680
|
-
const
|
|
681
|
-
await
|
|
679
|
+
const n = await this.getFileHandle(t, !0);
|
|
680
|
+
await k(n, r, i, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
682
681
|
}
|
|
683
682
|
/**
|
|
684
683
|
* Append data to a file
|
|
@@ -702,10 +701,10 @@ class wt {
|
|
|
702
701
|
* await fs.appendFile('/data/binary.dat', additionalData);
|
|
703
702
|
* \`\`\`
|
|
704
703
|
*/
|
|
705
|
-
async appendFile(t, r,
|
|
704
|
+
async appendFile(t, r, i) {
|
|
706
705
|
await this.ensureMounted();
|
|
707
|
-
const
|
|
708
|
-
await
|
|
706
|
+
const n = await this.getFileHandle(t, !0);
|
|
707
|
+
await k(n, r, i, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
709
708
|
}
|
|
710
709
|
/**
|
|
711
710
|
* Create a directory
|
|
@@ -730,16 +729,16 @@ class wt {
|
|
|
730
729
|
*/
|
|
731
730
|
async mkdir(t, r) {
|
|
732
731
|
if (await this.ensureMounted(), !this.root)
|
|
733
|
-
throw new
|
|
734
|
-
const
|
|
732
|
+
throw new b();
|
|
733
|
+
const i = r?.recursive ?? !1, n = m(t);
|
|
735
734
|
let a = this.root;
|
|
736
|
-
for (let s = 0; s <
|
|
737
|
-
const o =
|
|
735
|
+
for (let s = 0; s < n.length; s++) {
|
|
736
|
+
const o = n[s];
|
|
738
737
|
try {
|
|
739
|
-
a = await a.getDirectoryHandle(o, { create:
|
|
738
|
+
a = await a.getDirectoryHandle(o, { create: i || s === n.length - 1 });
|
|
740
739
|
} catch (l) {
|
|
741
740
|
throw l.name === "NotFoundError" ? new c(
|
|
742
|
-
\`Parent directory does not exist: \${
|
|
741
|
+
\`Parent directory does not exist: \${I(n.slice(0, s + 1))}\`,
|
|
743
742
|
"ENOENT"
|
|
744
743
|
) : l.name === "TypeMismatchError" ? new c(\`Path segment is not a directory: \${o}\`, "ENOTDIR") : new c("Failed to create directory", "MKDIR_FAILED");
|
|
745
744
|
}
|
|
@@ -778,9 +777,9 @@ class wt {
|
|
|
778
777
|
isFile: !1,
|
|
779
778
|
isDirectory: !0
|
|
780
779
|
};
|
|
781
|
-
const r =
|
|
780
|
+
const r = O(t), i = await this.getDirectoryHandle(P(t), !1), n = this.options.hashAlgorithm !== null;
|
|
782
781
|
try {
|
|
783
|
-
const s = await (await
|
|
782
|
+
const s = await (await i.getFileHandle(r, { create: !1 })).getFile(), o = {
|
|
784
783
|
kind: "file",
|
|
785
784
|
size: s.size,
|
|
786
785
|
mtime: new Date(s.lastModified).toISOString(),
|
|
@@ -788,7 +787,7 @@ class wt {
|
|
|
788
787
|
isFile: !0,
|
|
789
788
|
isDirectory: !1
|
|
790
789
|
};
|
|
791
|
-
if (
|
|
790
|
+
if (n && this.options.hashAlgorithm)
|
|
792
791
|
try {
|
|
793
792
|
const l = await ut(s, this.options.hashAlgorithm, this.options.maxFileSize);
|
|
794
793
|
o.hash = l;
|
|
@@ -801,7 +800,7 @@ class wt {
|
|
|
801
800
|
throw new c("Failed to stat (file)", "STAT_FAILED");
|
|
802
801
|
}
|
|
803
802
|
try {
|
|
804
|
-
return await
|
|
803
|
+
return await i.getDirectoryHandle(r, { create: !1 }), {
|
|
805
804
|
kind: "directory",
|
|
806
805
|
size: 0,
|
|
807
806
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
@@ -813,27 +812,37 @@ class wt {
|
|
|
813
812
|
throw a.name === "NotFoundError" ? new c(\`No such file or directory: \${t}\`, "ENOENT") : new c("Failed to stat (directory)", "STAT_FAILED");
|
|
814
813
|
}
|
|
815
814
|
}
|
|
816
|
-
|
|
815
|
+
/**
|
|
816
|
+
* Read a directory's contents
|
|
817
|
+
*
|
|
818
|
+
* Lists all files and subdirectories within the specified directory.
|
|
819
|
+
*
|
|
820
|
+
* @param path - The path to the directory to read
|
|
821
|
+
* @returns Promise that resolves to an array of detailed file/directory information
|
|
822
|
+
* @throws {OPFSError} If the directory does not exist or cannot be accessed
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* \`\`\`typescript
|
|
826
|
+
* // Get detailed information about files and directories
|
|
827
|
+
* const detailed = await fs.readDir('/users/john/documents');
|
|
828
|
+
* detailed.forEach(item => {
|
|
829
|
+
* console.log(\`\${item.name} - \${item.isFile ? 'file' : 'directory'}\`);
|
|
830
|
+
* });
|
|
831
|
+
* \`\`\`
|
|
832
|
+
*/
|
|
833
|
+
async readDir(t) {
|
|
817
834
|
await this.ensureMounted();
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
a.
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
isDirectory: !l
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
return a;
|
|
831
|
-
} else {
|
|
832
|
-
const a = [];
|
|
833
|
-
for await (const [s] of i.entries())
|
|
834
|
-
a.push(s);
|
|
835
|
-
return a;
|
|
835
|
+
const r = await this.getDirectoryHandle(t, !1), i = [];
|
|
836
|
+
for await (const [n, a] of r.entries()) {
|
|
837
|
+
const s = a.kind === "file";
|
|
838
|
+
i.push({
|
|
839
|
+
name: n,
|
|
840
|
+
kind: a.kind,
|
|
841
|
+
isFile: s,
|
|
842
|
+
isDirectory: !s
|
|
843
|
+
});
|
|
836
844
|
}
|
|
845
|
+
return i;
|
|
837
846
|
}
|
|
838
847
|
/**
|
|
839
848
|
* Check if a file or directory exists
|
|
@@ -852,26 +861,26 @@ class wt {
|
|
|
852
861
|
async exists(t) {
|
|
853
862
|
if (await this.ensureMounted(), t === "/")
|
|
854
863
|
return !0;
|
|
855
|
-
const r =
|
|
856
|
-
let
|
|
864
|
+
const r = O(t);
|
|
865
|
+
let i = null;
|
|
857
866
|
try {
|
|
858
|
-
|
|
859
|
-
} catch (
|
|
860
|
-
throw (
|
|
867
|
+
i = await this.getDirectoryHandle(P(t), !1);
|
|
868
|
+
} catch (n) {
|
|
869
|
+
throw (n.name === "NotFoundError" || n.name === "TypeMismatchError") && (i = null), n;
|
|
861
870
|
}
|
|
862
|
-
if (!
|
|
871
|
+
if (!i || !r)
|
|
863
872
|
return !1;
|
|
864
873
|
try {
|
|
865
|
-
return await
|
|
866
|
-
} catch (
|
|
867
|
-
if (
|
|
868
|
-
throw
|
|
874
|
+
return await i.getFileHandle(r, { create: !1 }), !0;
|
|
875
|
+
} catch (n) {
|
|
876
|
+
if (n.name !== "NotFoundError" && n.name !== "TypeMismatchError")
|
|
877
|
+
throw n;
|
|
869
878
|
}
|
|
870
879
|
try {
|
|
871
|
-
return await
|
|
872
|
-
} catch (
|
|
873
|
-
if (
|
|
874
|
-
throw
|
|
880
|
+
return await i.getDirectoryHandle(r, { create: !1 }), !0;
|
|
881
|
+
} catch (n) {
|
|
882
|
+
if (n.name !== "NotFoundError" && n.name !== "TypeMismatchError")
|
|
883
|
+
throw n;
|
|
875
884
|
}
|
|
876
885
|
return !1;
|
|
877
886
|
}
|
|
@@ -897,10 +906,10 @@ class wt {
|
|
|
897
906
|
async clear(t = "/") {
|
|
898
907
|
await this.ensureMounted();
|
|
899
908
|
try {
|
|
900
|
-
const r = await this.
|
|
901
|
-
for (const
|
|
902
|
-
const
|
|
903
|
-
await this.remove(
|
|
909
|
+
const r = await this.readDir(t);
|
|
910
|
+
for (const i of r) {
|
|
911
|
+
const n = \`\${t === "/" ? "" : t}/\${i.name}\`;
|
|
912
|
+
await this.remove(n, { recursive: !0 });
|
|
904
913
|
}
|
|
905
914
|
await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
|
|
906
915
|
} catch (r) {
|
|
@@ -933,20 +942,20 @@ class wt {
|
|
|
933
942
|
*/
|
|
934
943
|
async remove(t, r) {
|
|
935
944
|
await this.ensureMounted();
|
|
936
|
-
const
|
|
945
|
+
const i = r?.recursive ?? !1, n = r?.force ?? !1;
|
|
937
946
|
if (t === "/")
|
|
938
947
|
throw new c("Cannot remove root directory", "EROOT");
|
|
939
|
-
const a =
|
|
948
|
+
const a = O(t);
|
|
940
949
|
if (!a)
|
|
941
|
-
throw new
|
|
942
|
-
const s = await this.getDirectoryHandle(
|
|
950
|
+
throw new N("Invalid path", t);
|
|
951
|
+
const s = await this.getDirectoryHandle(P(t), !1);
|
|
943
952
|
try {
|
|
944
|
-
await s.removeEntry(a, { recursive:
|
|
953
|
+
await s.removeEntry(a, { recursive: i });
|
|
945
954
|
} catch (o) {
|
|
946
955
|
if (o.name === "NotFoundError") {
|
|
947
|
-
if (!
|
|
956
|
+
if (!n)
|
|
948
957
|
throw new c(\`No such file or directory: \${t}\`, "ENOENT");
|
|
949
|
-
} else throw o.name === "InvalidModificationError" ? new c(\`Directory not empty: \${t}. Use recursive option to force removal.\`, "ENOTEMPTY") : o.name === "TypeMismatchError" && !
|
|
958
|
+
} else throw o.name === "InvalidModificationError" ? new c(\`Directory not empty: \${t}. Use recursive option to force removal.\`, "ENOTEMPTY") : o.name === "TypeMismatchError" && !i ? new c(\`Cannot remove directory without recursive option: \${t}\`, "EISDIR") : new c(\`Failed to remove path: \${t}\`, "RM_FAILED");
|
|
950
959
|
}
|
|
951
960
|
await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
|
|
952
961
|
}
|
|
@@ -973,7 +982,7 @@ class wt {
|
|
|
973
982
|
try {
|
|
974
983
|
const r = ct(t);
|
|
975
984
|
if (!await this.exists(r))
|
|
976
|
-
throw new
|
|
985
|
+
throw new T(r);
|
|
977
986
|
return r;
|
|
978
987
|
} catch (r) {
|
|
979
988
|
throw r instanceof c ? r : new c(\`Failed to resolve path: \${t}\`, "REALPATH_FAILED");
|
|
@@ -999,10 +1008,10 @@ class wt {
|
|
|
999
1008
|
await this.ensureMounted();
|
|
1000
1009
|
try {
|
|
1001
1010
|
if (!await this.exists(t))
|
|
1002
|
-
throw new
|
|
1011
|
+
throw new T(t);
|
|
1003
1012
|
await this.copy(t, r, { recursive: !0 }), await this.remove(t, { recursive: !0 }), await this.notifyChange({ path: t, type: "removed", isDirectory: !1 }), await this.notifyChange({ path: r, type: "added", isDirectory: !1 });
|
|
1004
|
-
} catch (
|
|
1005
|
-
throw
|
|
1013
|
+
} catch (i) {
|
|
1014
|
+
throw i instanceof c ? i : new c(\`Failed to rename from \${t} to \${r}\`, "RENAME_FAILED");
|
|
1006
1015
|
}
|
|
1007
1016
|
}
|
|
1008
1017
|
/**
|
|
@@ -1030,10 +1039,10 @@ class wt {
|
|
|
1030
1039
|
* await fs.copy('/source', '/dest', { recursive: true, force: false });
|
|
1031
1040
|
* \`\`\`
|
|
1032
1041
|
*/
|
|
1033
|
-
async copy(t, r,
|
|
1042
|
+
async copy(t, r, i) {
|
|
1034
1043
|
await this.ensureMounted();
|
|
1035
1044
|
try {
|
|
1036
|
-
const
|
|
1045
|
+
const n = i?.recursive ?? !1, a = i?.force ?? !0;
|
|
1037
1046
|
if (!await this.exists(t))
|
|
1038
1047
|
throw new c(\`Source does not exist: \${t}\`, "ENOENT");
|
|
1039
1048
|
if (await this.exists(r) && !a)
|
|
@@ -1042,18 +1051,18 @@ class wt {
|
|
|
1042
1051
|
const h = await this.readFile(t, "binary");
|
|
1043
1052
|
await this.writeFile(r, h);
|
|
1044
1053
|
} else {
|
|
1045
|
-
if (!
|
|
1054
|
+
if (!n)
|
|
1046
1055
|
throw new c(\`Cannot copy directory without recursive option: \${t}\`, "EISDIR");
|
|
1047
1056
|
await this.mkdir(r, { recursive: !0 });
|
|
1048
|
-
const h = await this.
|
|
1057
|
+
const h = await this.readDir(t);
|
|
1049
1058
|
for (const u of h) {
|
|
1050
1059
|
const w = \`\${t}/\${u.name}\`, f = \`\${r}/\${u.name}\`;
|
|
1051
1060
|
await this.copy(w, f, { recursive: !0, force: a });
|
|
1052
1061
|
}
|
|
1053
1062
|
}
|
|
1054
1063
|
await this.notifyChange({ path: r, type: "added", isDirectory: !1 });
|
|
1055
|
-
} catch (
|
|
1056
|
-
throw
|
|
1064
|
+
} catch (n) {
|
|
1065
|
+
throw n instanceof c ? n : new c(\`Failed to copy from \${t} to \${r}\`, "CP_FAILED");
|
|
1057
1066
|
}
|
|
1058
1067
|
}
|
|
1059
1068
|
/**
|
|
@@ -1061,8 +1070,8 @@ class wt {
|
|
|
1061
1070
|
*/
|
|
1062
1071
|
async watch(t) {
|
|
1063
1072
|
await this.ensureMounted();
|
|
1064
|
-
const r =
|
|
1065
|
-
this.watchers.set(r,
|
|
1073
|
+
const r = F(t), i = await this.buildSnapshot(r);
|
|
1074
|
+
this.watchers.set(r, i), this.watchTimer || (this.watchTimer = setInterval(() => {
|
|
1066
1075
|
this.scanWatches();
|
|
1067
1076
|
}, this.options.watchInterval));
|
|
1068
1077
|
}
|
|
@@ -1070,21 +1079,30 @@ class wt {
|
|
|
1070
1079
|
* Stop watching a previously watched path
|
|
1071
1080
|
*/
|
|
1072
1081
|
unwatch(t) {
|
|
1073
|
-
const r =
|
|
1082
|
+
const r = F(t);
|
|
1074
1083
|
this.watchers.delete(r), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
1075
1084
|
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Dispose of resources and clean up the file system instance
|
|
1087
|
+
*
|
|
1088
|
+
* This method should be called when the file system instance is no longer needed
|
|
1089
|
+
* to properly clean up resources like the broadcast channel and watch timers.
|
|
1090
|
+
*/
|
|
1091
|
+
dispose() {
|
|
1092
|
+
this.broadcastChannel && (this.broadcastChannel.close(), this.broadcastChannel = null), this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null), this.watchers.clear();
|
|
1093
|
+
}
|
|
1076
1094
|
async buildSnapshot(t) {
|
|
1077
|
-
const r = /* @__PURE__ */ new Map(),
|
|
1078
|
-
const a = await this.stat(
|
|
1079
|
-
if (r.set(
|
|
1080
|
-
const s = await this.
|
|
1095
|
+
const r = /* @__PURE__ */ new Map(), i = async (n) => {
|
|
1096
|
+
const a = await this.stat(n);
|
|
1097
|
+
if (r.set(n, a), a.isDirectory) {
|
|
1098
|
+
const s = await this.readDir(n);
|
|
1081
1099
|
for (const o of s) {
|
|
1082
|
-
const l = \`\${
|
|
1083
|
-
await
|
|
1100
|
+
const l = \`\${n === "/" ? "" : n}/\${o.name}\`;
|
|
1101
|
+
await i(l);
|
|
1084
1102
|
}
|
|
1085
1103
|
}
|
|
1086
1104
|
};
|
|
1087
|
-
return await
|
|
1105
|
+
return await i(t), r;
|
|
1088
1106
|
}
|
|
1089
1107
|
async scanWatches() {
|
|
1090
1108
|
if (!this.scanning) {
|
|
@@ -1092,19 +1110,22 @@ class wt {
|
|
|
1092
1110
|
try {
|
|
1093
1111
|
await Promise.all(
|
|
1094
1112
|
[...this.watchers.entries()].map(async ([t, r]) => {
|
|
1095
|
-
let
|
|
1113
|
+
let i;
|
|
1096
1114
|
try {
|
|
1097
|
-
|
|
1115
|
+
i = await this.buildSnapshot(t);
|
|
1098
1116
|
} catch {
|
|
1099
|
-
|
|
1117
|
+
i = /* @__PURE__ */ new Map();
|
|
1100
1118
|
}
|
|
1101
|
-
for (const [
|
|
1102
|
-
const s = r.get(
|
|
1103
|
-
s ? (s.mtime !== a.mtime || s.size !== a.size) && await this.notifyChange({ path:
|
|
1119
|
+
for (const [n, a] of i) {
|
|
1120
|
+
const s = r.get(n);
|
|
1121
|
+
s ? (s.mtime !== a.mtime || s.size !== a.size) && await this.notifyChange({ path: n, type: "changed", isDirectory: a.isDirectory }) : await this.notifyChange({ path: n, type: "added", isDirectory: a.isDirectory });
|
|
1104
1122
|
}
|
|
1105
|
-
for (const
|
|
1106
|
-
|
|
1107
|
-
|
|
1123
|
+
for (const n of r.keys())
|
|
1124
|
+
if (!i.has(n)) {
|
|
1125
|
+
const a = r.get(n);
|
|
1126
|
+
await this.notifyChange({ path: n, type: "removed", isDirectory: a?.isDirectory ?? !1 });
|
|
1127
|
+
}
|
|
1128
|
+
this.watchers.set(t, i);
|
|
1108
1129
|
})
|
|
1109
1130
|
);
|
|
1110
1131
|
} finally {
|
|
@@ -1144,18 +1165,18 @@ class wt {
|
|
|
1144
1165
|
await this.ensureMounted();
|
|
1145
1166
|
try {
|
|
1146
1167
|
(r?.cleanBefore ?? !1) && await this.clear("/");
|
|
1147
|
-
for (const [
|
|
1148
|
-
const s =
|
|
1168
|
+
for (const [n, a] of t) {
|
|
1169
|
+
const s = F(n);
|
|
1149
1170
|
let o;
|
|
1150
1171
|
a instanceof Blob ? o = await ft(a) : o = a, await this.writeFile(s, o);
|
|
1151
1172
|
}
|
|
1152
1173
|
await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
|
|
1153
|
-
} catch (
|
|
1154
|
-
throw
|
|
1174
|
+
} catch (i) {
|
|
1175
|
+
throw i instanceof c ? i : new c("Failed to sync file system", "SYNC_FAILED");
|
|
1155
1176
|
}
|
|
1156
1177
|
}
|
|
1157
1178
|
}
|
|
1158
|
-
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" &&
|
|
1159
|
-
//# sourceMappingURL=worker-
|
|
1160
|
-
`,
|
|
1179
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && x(new wt());
|
|
1180
|
+
//# sourceMappingURL=worker-DilNsKoO.js.map
|
|
1181
|
+
`,a=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",i],{type:"text/javascript;charset=utf-8"});function s(e){let t;try{if(t=a&&(self.URL||self.webkitURL).createObjectURL(a),!t)throw"";const r=new Worker(t,{type:"module",name:e?.name});return r.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),r}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(i),{type:"module",name:e?.name})}}function c(e){const t=o.wrap(new s);return e&&t.setOptions(e),t}exports.DirectoryNotFoundError=n.DirectoryNotFoundError;exports.FileNotFoundError=n.FileNotFoundError;exports.OPFSError=n.OPFSError;exports.OPFSNotMountedError=n.OPFSNotMountedError;exports.OPFSNotSupportedError=n.OPFSNotSupportedError;exports.PathError=n.PathError;exports.PermissionError=n.PermissionError;exports.StorageError=n.StorageError;exports.TimeoutError=n.TimeoutError;exports.basename=n.basename;exports.calculateFileHash=n.calculateFileHash;exports.checkOPFSSupport=n.checkOPFSSupport;exports.convertBlobToUint8Array=n.convertBlobToUint8Array;exports.createBuffer=n.createBuffer;exports.decodeBuffer=n.decodeBuffer;exports.dirname=n.dirname;exports.encodeString=n.encodeString;exports.extname=n.extname;exports.joinPath=n.joinPath;exports.normalizePath=n.normalizePath;exports.readFileData=n.readFileData;exports.resolvePath=n.resolvePath;exports.splitPath=n.splitPath;exports.writeFileData=n.writeFileData;exports.createWorker=c;
|
|
1161
1182
|
//# sourceMappingURL=index.cjs.map
|