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