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/index.cjs
CHANGED
|
@@ -1,256 +1,256 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("comlink"),n=require("./helpers-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("comlink"),n=require("./helpers-FvdHLObV.cjs"),o=`/**
|
|
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"),
|
|
7
|
-
canHandle: (
|
|
8
|
-
serialize(
|
|
9
|
-
const { port1:
|
|
10
|
-
return
|
|
6
|
+
const H = Symbol("Comlink.proxy"), R = Symbol("Comlink.endpoint"), B = Symbol("Comlink.releaseProxy"), D = Symbol("Comlink.finalizer"), E = Symbol("Comlink.thrown"), $ = (e) => typeof e == "object" && e !== null || typeof e == "function", W = {
|
|
7
|
+
canHandle: (e) => $(e) && e[H],
|
|
8
|
+
serialize(e) {
|
|
9
|
+
const { port1: t, port2: r } = new MessageChannel();
|
|
10
|
+
return I(e, t), [r, [r]];
|
|
11
11
|
},
|
|
12
|
-
deserialize(
|
|
13
|
-
return
|
|
12
|
+
deserialize(e) {
|
|
13
|
+
return e.start(), Y(e);
|
|
14
14
|
}
|
|
15
15
|
}, j = {
|
|
16
|
-
canHandle: (
|
|
17
|
-
serialize({ value:
|
|
18
|
-
let
|
|
19
|
-
return
|
|
16
|
+
canHandle: (e) => $(e) && E in e,
|
|
17
|
+
serialize({ value: e }) {
|
|
18
|
+
let t;
|
|
19
|
+
return e instanceof Error ? t = {
|
|
20
20
|
isError: !0,
|
|
21
21
|
value: {
|
|
22
|
-
message:
|
|
23
|
-
name:
|
|
24
|
-
stack:
|
|
22
|
+
message: e.message,
|
|
23
|
+
name: e.name,
|
|
24
|
+
stack: e.stack
|
|
25
25
|
}
|
|
26
|
-
} :
|
|
26
|
+
} : t = { isError: !1, value: e }, [t, []];
|
|
27
27
|
},
|
|
28
|
-
deserialize(
|
|
29
|
-
throw
|
|
28
|
+
deserialize(e) {
|
|
29
|
+
throw e.isError ? Object.assign(new Error(e.value.message), e.value) : e.value;
|
|
30
30
|
}
|
|
31
|
-
},
|
|
31
|
+
}, z = /* @__PURE__ */ new Map([
|
|
32
32
|
["proxy", W],
|
|
33
33
|
["throw", j]
|
|
34
34
|
]);
|
|
35
|
-
function V(
|
|
36
|
-
for (const r of
|
|
37
|
-
if (
|
|
35
|
+
function V(e, t) {
|
|
36
|
+
for (const r of e)
|
|
37
|
+
if (t === r || r === "*" || r instanceof RegExp && r.test(t))
|
|
38
38
|
return !0;
|
|
39
39
|
return !1;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
if (!
|
|
41
|
+
function I(e, t = globalThis, r = ["*"]) {
|
|
42
|
+
t.addEventListener("message", function n(i) {
|
|
43
|
+
if (!i || !i.data)
|
|
44
44
|
return;
|
|
45
|
-
if (!V(r,
|
|
46
|
-
console.warn(\`Invalid origin '\${
|
|
45
|
+
if (!V(r, i.origin)) {
|
|
46
|
+
console.warn(\`Invalid origin '\${i.origin}' for comlink proxy\`);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
const { id:
|
|
50
|
-
let
|
|
49
|
+
const { id: a, type: s, path: o } = Object.assign({ path: [] }, i.data), l = (i.data.argumentList || []).map(y);
|
|
50
|
+
let h;
|
|
51
51
|
try {
|
|
52
|
-
const
|
|
53
|
-
switch (
|
|
52
|
+
const u = o.slice(0, -1).reduce((f, g) => f[g], e), w = o.reduce((f, g) => f[g], e);
|
|
53
|
+
switch (s) {
|
|
54
54
|
case "GET":
|
|
55
|
-
|
|
55
|
+
h = w;
|
|
56
56
|
break;
|
|
57
57
|
case "SET":
|
|
58
|
-
|
|
58
|
+
u[o.slice(-1)[0]] = y(i.data.value), h = !0;
|
|
59
59
|
break;
|
|
60
60
|
case "APPLY":
|
|
61
|
-
|
|
61
|
+
h = w.apply(u, l);
|
|
62
62
|
break;
|
|
63
63
|
case "CONSTRUCT":
|
|
64
64
|
{
|
|
65
|
-
const
|
|
66
|
-
|
|
65
|
+
const f = new w(...l);
|
|
66
|
+
h = Q(f);
|
|
67
67
|
}
|
|
68
68
|
break;
|
|
69
69
|
case "ENDPOINT":
|
|
70
70
|
{
|
|
71
|
-
const { port1:
|
|
72
|
-
|
|
71
|
+
const { port1: f, port2: g } = new MessageChannel();
|
|
72
|
+
I(e, g), h = J(f, [f]);
|
|
73
73
|
}
|
|
74
74
|
break;
|
|
75
75
|
case "RELEASE":
|
|
76
|
-
|
|
76
|
+
h = void 0;
|
|
77
77
|
break;
|
|
78
78
|
default:
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
} catch (
|
|
82
|
-
|
|
81
|
+
} catch (u) {
|
|
82
|
+
h = { value: u, [E]: 0 };
|
|
83
83
|
}
|
|
84
|
-
Promise.resolve(
|
|
85
|
-
const [w,
|
|
86
|
-
|
|
87
|
-
}).catch((
|
|
88
|
-
const [w,
|
|
84
|
+
Promise.resolve(h).catch((u) => ({ value: u, [E]: 0 })).then((u) => {
|
|
85
|
+
const [w, f] = A(u);
|
|
86
|
+
t.postMessage(Object.assign(Object.assign({}, w), { id: a }), f), s === "RELEASE" && (t.removeEventListener("message", n), L(t), D in e && typeof e[D] == "function" && e[D]());
|
|
87
|
+
}).catch((u) => {
|
|
88
|
+
const [w, f] = A({
|
|
89
89
|
value: new TypeError("Unserializable return value"),
|
|
90
|
-
[
|
|
90
|
+
[E]: 0
|
|
91
91
|
});
|
|
92
|
-
|
|
92
|
+
t.postMessage(Object.assign(Object.assign({}, w), { id: a }), f);
|
|
93
93
|
});
|
|
94
|
-
}),
|
|
94
|
+
}), t.start && t.start();
|
|
95
95
|
}
|
|
96
|
-
function G(
|
|
97
|
-
return
|
|
96
|
+
function G(e) {
|
|
97
|
+
return e.constructor.name === "MessagePort";
|
|
98
98
|
}
|
|
99
|
-
function L(
|
|
100
|
-
G(
|
|
99
|
+
function L(e) {
|
|
100
|
+
G(e) && e.close();
|
|
101
101
|
}
|
|
102
|
-
function Y(
|
|
102
|
+
function Y(e, t) {
|
|
103
103
|
const r = /* @__PURE__ */ new Map();
|
|
104
|
-
return
|
|
105
|
-
const { data:
|
|
106
|
-
if (!
|
|
104
|
+
return e.addEventListener("message", function(i) {
|
|
105
|
+
const { data: a } = i;
|
|
106
|
+
if (!a || !a.id)
|
|
107
107
|
return;
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
108
|
+
const s = r.get(a.id);
|
|
109
|
+
if (s)
|
|
110
110
|
try {
|
|
111
|
-
|
|
111
|
+
s(a);
|
|
112
112
|
} finally {
|
|
113
|
-
r.delete(
|
|
113
|
+
r.delete(a.id);
|
|
114
114
|
}
|
|
115
|
-
}),
|
|
115
|
+
}), M(e, r, [], t);
|
|
116
116
|
}
|
|
117
|
-
function
|
|
118
|
-
if (
|
|
117
|
+
function p(e) {
|
|
118
|
+
if (e)
|
|
119
119
|
throw new Error("Proxy has been released and is not useable");
|
|
120
120
|
}
|
|
121
|
-
function
|
|
122
|
-
return d(
|
|
121
|
+
function U(e) {
|
|
122
|
+
return d(e, /* @__PURE__ */ new Map(), {
|
|
123
123
|
type: "RELEASE"
|
|
124
124
|
}).then(() => {
|
|
125
|
-
L(
|
|
125
|
+
L(e);
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
-
const F = /* @__PURE__ */ new WeakMap(), S = "FinalizationRegistry" in globalThis && new FinalizationRegistry((
|
|
129
|
-
const
|
|
130
|
-
F.set(
|
|
128
|
+
const F = /* @__PURE__ */ new WeakMap(), S = "FinalizationRegistry" in globalThis && new FinalizationRegistry((e) => {
|
|
129
|
+
const t = (F.get(e) || 0) - 1;
|
|
130
|
+
F.set(e, t), t === 0 && U(e);
|
|
131
131
|
});
|
|
132
|
-
function X(
|
|
133
|
-
const r = (F.get(
|
|
134
|
-
F.set(
|
|
132
|
+
function X(e, t) {
|
|
133
|
+
const r = (F.get(t) || 0) + 1;
|
|
134
|
+
F.set(t, r), S && S.register(e, t, e);
|
|
135
135
|
}
|
|
136
|
-
function q(
|
|
137
|
-
S && S.unregister(
|
|
136
|
+
function q(e) {
|
|
137
|
+
S && S.unregister(e);
|
|
138
138
|
}
|
|
139
|
-
function
|
|
139
|
+
function M(e, t, r = [], n = function() {
|
|
140
140
|
}) {
|
|
141
|
-
let
|
|
142
|
-
const
|
|
143
|
-
get(
|
|
144
|
-
if (
|
|
141
|
+
let i = !1;
|
|
142
|
+
const a = new Proxy(n, {
|
|
143
|
+
get(s, o) {
|
|
144
|
+
if (p(i), o === B)
|
|
145
145
|
return () => {
|
|
146
|
-
q(
|
|
146
|
+
q(a), U(e), t.clear(), i = !0;
|
|
147
147
|
};
|
|
148
|
-
if (
|
|
148
|
+
if (o === "then") {
|
|
149
149
|
if (r.length === 0)
|
|
150
|
-
return { then: () =>
|
|
151
|
-
const l = d(
|
|
150
|
+
return { then: () => a };
|
|
151
|
+
const l = d(e, t, {
|
|
152
152
|
type: "GET",
|
|
153
|
-
path: r.map((
|
|
153
|
+
path: r.map((h) => h.toString())
|
|
154
154
|
}).then(y);
|
|
155
155
|
return l.then.bind(l);
|
|
156
156
|
}
|
|
157
|
-
return
|
|
157
|
+
return M(e, t, [...r, o]);
|
|
158
158
|
},
|
|
159
|
-
set(
|
|
160
|
-
|
|
161
|
-
const [
|
|
162
|
-
return d(
|
|
159
|
+
set(s, o, l) {
|
|
160
|
+
p(i);
|
|
161
|
+
const [h, u] = A(l);
|
|
162
|
+
return d(e, t, {
|
|
163
163
|
type: "SET",
|
|
164
|
-
path: [...r,
|
|
165
|
-
value:
|
|
166
|
-
},
|
|
164
|
+
path: [...r, o].map((w) => w.toString()),
|
|
165
|
+
value: h
|
|
166
|
+
}, u).then(y);
|
|
167
167
|
},
|
|
168
|
-
apply(
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
return d(
|
|
168
|
+
apply(s, o, l) {
|
|
169
|
+
p(i);
|
|
170
|
+
const h = r[r.length - 1];
|
|
171
|
+
if (h === R)
|
|
172
|
+
return d(e, t, {
|
|
173
173
|
type: "ENDPOINT"
|
|
174
174
|
}).then(y);
|
|
175
|
-
if (
|
|
176
|
-
return
|
|
177
|
-
const [
|
|
178
|
-
return d(
|
|
175
|
+
if (h === "bind")
|
|
176
|
+
return M(e, t, r.slice(0, -1));
|
|
177
|
+
const [u, w] = N(l);
|
|
178
|
+
return d(e, t, {
|
|
179
179
|
type: "APPLY",
|
|
180
|
-
path: r.map((
|
|
181
|
-
argumentList:
|
|
180
|
+
path: r.map((f) => f.toString()),
|
|
181
|
+
argumentList: u
|
|
182
182
|
}, w).then(y);
|
|
183
183
|
},
|
|
184
|
-
construct(
|
|
185
|
-
|
|
186
|
-
const [l,
|
|
187
|
-
return d(
|
|
184
|
+
construct(s, o) {
|
|
185
|
+
p(i);
|
|
186
|
+
const [l, h] = N(o);
|
|
187
|
+
return d(e, t, {
|
|
188
188
|
type: "CONSTRUCT",
|
|
189
|
-
path: r.map((
|
|
189
|
+
path: r.map((u) => u.toString()),
|
|
190
190
|
argumentList: l
|
|
191
|
-
},
|
|
191
|
+
}, h).then(y);
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
|
-
return X(
|
|
194
|
+
return X(a, e), a;
|
|
195
195
|
}
|
|
196
|
-
function K(
|
|
197
|
-
return Array.prototype.concat.apply([],
|
|
196
|
+
function K(e) {
|
|
197
|
+
return Array.prototype.concat.apply([], e);
|
|
198
198
|
}
|
|
199
|
-
function
|
|
200
|
-
const
|
|
201
|
-
return [
|
|
199
|
+
function N(e) {
|
|
200
|
+
const t = e.map(A);
|
|
201
|
+
return [t.map((r) => r[0]), K(t.map((r) => r[1]))];
|
|
202
202
|
}
|
|
203
203
|
const _ = /* @__PURE__ */ new WeakMap();
|
|
204
|
-
function J(
|
|
205
|
-
return _.set(
|
|
204
|
+
function J(e, t) {
|
|
205
|
+
return _.set(e, t), e;
|
|
206
206
|
}
|
|
207
|
-
function Q(
|
|
208
|
-
return Object.assign(
|
|
207
|
+
function Q(e) {
|
|
208
|
+
return Object.assign(e, { [H]: !0 });
|
|
209
209
|
}
|
|
210
|
-
function A(
|
|
211
|
-
for (const [
|
|
212
|
-
if (r.canHandle(
|
|
213
|
-
const [
|
|
210
|
+
function A(e) {
|
|
211
|
+
for (const [t, r] of z)
|
|
212
|
+
if (r.canHandle(e)) {
|
|
213
|
+
const [n, i] = r.serialize(e);
|
|
214
214
|
return [
|
|
215
215
|
{
|
|
216
216
|
type: "HANDLER",
|
|
217
|
-
name:
|
|
218
|
-
value:
|
|
217
|
+
name: t,
|
|
218
|
+
value: n
|
|
219
219
|
},
|
|
220
|
-
|
|
220
|
+
i
|
|
221
221
|
];
|
|
222
222
|
}
|
|
223
223
|
return [
|
|
224
224
|
{
|
|
225
225
|
type: "RAW",
|
|
226
|
-
value:
|
|
226
|
+
value: e
|
|
227
227
|
},
|
|
228
|
-
_.get(
|
|
228
|
+
_.get(e) || []
|
|
229
229
|
];
|
|
230
230
|
}
|
|
231
|
-
function y(
|
|
232
|
-
switch (
|
|
231
|
+
function y(e) {
|
|
232
|
+
switch (e.type) {
|
|
233
233
|
case "HANDLER":
|
|
234
|
-
return
|
|
234
|
+
return z.get(e.name).deserialize(e.value);
|
|
235
235
|
case "RAW":
|
|
236
|
-
return
|
|
236
|
+
return e.value;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
-
function d(
|
|
240
|
-
return new Promise((
|
|
241
|
-
const
|
|
242
|
-
|
|
239
|
+
function d(e, t, r, n) {
|
|
240
|
+
return new Promise((i) => {
|
|
241
|
+
const a = Z();
|
|
242
|
+
t.set(a, i), e.start && e.start(), e.postMessage(Object.assign({ id: a }, r), n);
|
|
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(
|
|
250
|
-
super(
|
|
249
|
+
constructor(t, r, n) {
|
|
250
|
+
super(t), this.code = r, this.path = n, this.name = "OPFSError";
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
|
-
class
|
|
253
|
+
class tt extends c {
|
|
254
254
|
constructor() {
|
|
255
255
|
super("OPFS is not supported in this browser", "OPFS_NOT_SUPPORTED");
|
|
256
256
|
}
|
|
@@ -260,165 +260,163 @@ class T extends c {
|
|
|
260
260
|
super("OPFS is not mounted", "OPFS_NOT_MOUNTED");
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
class
|
|
264
|
-
constructor(
|
|
265
|
-
super(
|
|
263
|
+
class k extends c {
|
|
264
|
+
constructor(t, r) {
|
|
265
|
+
super(t, "INVALID_PATH", r);
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
|
-
class
|
|
269
|
-
constructor(
|
|
270
|
-
super(\`File not found: \${
|
|
268
|
+
class O extends c {
|
|
269
|
+
constructor(t) {
|
|
270
|
+
super(\`File not found: \${t}\`, "FILE_NOT_FOUND", t);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
-
function
|
|
274
|
-
switch (
|
|
273
|
+
function et(e, t = "utf-8") {
|
|
274
|
+
switch (t) {
|
|
275
275
|
case "utf8":
|
|
276
276
|
case "utf-8":
|
|
277
|
-
return new TextEncoder().encode(
|
|
277
|
+
return new TextEncoder().encode(e);
|
|
278
278
|
case "utf16le":
|
|
279
279
|
case "ucs2":
|
|
280
280
|
case "ucs-2":
|
|
281
|
-
return
|
|
281
|
+
return nt(e);
|
|
282
282
|
case "ascii":
|
|
283
|
-
return
|
|
283
|
+
return st(e);
|
|
284
284
|
case "latin1":
|
|
285
|
-
return
|
|
285
|
+
return at(e);
|
|
286
286
|
case "binary":
|
|
287
|
-
return Uint8Array.from(
|
|
287
|
+
return Uint8Array.from(e, (r) => r.charCodeAt(0));
|
|
288
288
|
case "base64":
|
|
289
|
-
return Uint8Array.from(atob(
|
|
289
|
+
return Uint8Array.from(atob(e), (r) => r.charCodeAt(0));
|
|
290
290
|
case "hex":
|
|
291
|
-
if (!/^[\\da-f]+$/i.test(
|
|
291
|
+
if (!/^[\\da-f]+$/i.test(e) || e.length % 2 !== 0)
|
|
292
292
|
throw new c("Invalid hex string", "INVALID_HEX_FORMAT");
|
|
293
|
-
return Uint8Array.from(
|
|
293
|
+
return Uint8Array.from(e.match(/.{1,2}/g).map((r) => parseInt(r, 16)));
|
|
294
294
|
default:
|
|
295
|
-
return console.warn("Encoding not supported, falling back to UTF-8"), new TextEncoder().encode(
|
|
295
|
+
return console.warn("Encoding not supported, falling back to UTF-8"), new TextEncoder().encode(e);
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
-
function
|
|
299
|
-
switch (
|
|
298
|
+
function rt(e, t = "utf-8") {
|
|
299
|
+
switch (t) {
|
|
300
300
|
case "utf8":
|
|
301
301
|
case "utf-8":
|
|
302
|
-
return new TextDecoder().decode(
|
|
302
|
+
return new TextDecoder().decode(e);
|
|
303
303
|
case "utf16le":
|
|
304
304
|
case "ucs2":
|
|
305
305
|
case "ucs-2":
|
|
306
|
-
return
|
|
306
|
+
return it(e);
|
|
307
307
|
case "latin1":
|
|
308
|
-
return String.fromCharCode(...
|
|
308
|
+
return String.fromCharCode(...e);
|
|
309
309
|
case "binary":
|
|
310
|
-
return String.fromCharCode(...
|
|
310
|
+
return String.fromCharCode(...e);
|
|
311
311
|
case "ascii":
|
|
312
|
-
return String.fromCharCode(...
|
|
312
|
+
return String.fromCharCode(...e.map((r) => r & 127));
|
|
313
313
|
case "base64":
|
|
314
|
-
return btoa(String.fromCharCode(...
|
|
314
|
+
return btoa(String.fromCharCode(...e));
|
|
315
315
|
case "hex":
|
|
316
|
-
return Array.from(
|
|
316
|
+
return Array.from(e).map((r) => r.toString(16).padStart(2, "0")).join("");
|
|
317
317
|
default:
|
|
318
|
-
return console.warn("Unsupported encoding, falling back to UTF-8"), new TextDecoder().decode(
|
|
318
|
+
return console.warn("Unsupported encoding, falling back to UTF-8"), new TextDecoder().decode(e);
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
|
-
function
|
|
322
|
-
const
|
|
323
|
-
for (let r = 0; r <
|
|
324
|
-
const
|
|
325
|
-
|
|
321
|
+
function nt(e) {
|
|
322
|
+
const t = new Uint8Array(e.length * 2);
|
|
323
|
+
for (let r = 0; r < e.length; r++) {
|
|
324
|
+
const n = e.charCodeAt(r);
|
|
325
|
+
t[r * 2] = n & 255, t[r * 2 + 1] = n >> 8;
|
|
326
326
|
}
|
|
327
|
-
return
|
|
327
|
+
return t;
|
|
328
328
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
return String.fromCharCode(...
|
|
329
|
+
function it(e) {
|
|
330
|
+
e.length % 2 !== 0 && (console.warn("Invalid UTF-16LE buffer length, truncating last byte"), e = e.slice(0, e.length - 1));
|
|
331
|
+
const t = new Uint16Array(e.buffer, e.byteOffset, e.byteLength / 2);
|
|
332
|
+
return String.fromCharCode(...t);
|
|
333
333
|
}
|
|
334
|
-
function
|
|
335
|
-
const
|
|
336
|
-
for (let r = 0; r <
|
|
337
|
-
|
|
338
|
-
return
|
|
334
|
+
function at(e) {
|
|
335
|
+
const t = new Uint8Array(e.length);
|
|
336
|
+
for (let r = 0; r < e.length; r++)
|
|
337
|
+
t[r] = e.charCodeAt(r) & 255;
|
|
338
|
+
return t;
|
|
339
339
|
}
|
|
340
|
-
function
|
|
341
|
-
const
|
|
342
|
-
for (let r = 0; r <
|
|
343
|
-
|
|
344
|
-
return
|
|
340
|
+
function st(e) {
|
|
341
|
+
const t = new Uint8Array(e.length);
|
|
342
|
+
for (let r = 0; r < e.length; r++)
|
|
343
|
+
t[r] = e.charCodeAt(r) & 127;
|
|
344
|
+
return t;
|
|
345
345
|
}
|
|
346
|
-
function
|
|
346
|
+
function ot() {
|
|
347
347
|
if (!("storage" in navigator) || !("getDirectory" in navigator.storage))
|
|
348
|
-
throw new
|
|
348
|
+
throw new tt();
|
|
349
349
|
}
|
|
350
|
-
function m(
|
|
351
|
-
return Array.isArray(
|
|
350
|
+
function m(e) {
|
|
351
|
+
return Array.isArray(e) ? e : e.split("/").filter(Boolean);
|
|
352
352
|
}
|
|
353
|
-
function
|
|
354
|
-
return typeof
|
|
353
|
+
function P(e) {
|
|
354
|
+
return typeof e == "string" ? e ?? "/" : \`/\${e.join("/")}\`;
|
|
355
355
|
}
|
|
356
|
-
function b(
|
|
357
|
-
const
|
|
358
|
-
return
|
|
356
|
+
function b(e) {
|
|
357
|
+
const t = m(e);
|
|
358
|
+
return t[t.length - 1] || "";
|
|
359
359
|
}
|
|
360
|
-
function
|
|
361
|
-
const
|
|
362
|
-
return
|
|
360
|
+
function x(e) {
|
|
361
|
+
const t = m(e);
|
|
362
|
+
return t.pop(), P(t);
|
|
363
363
|
}
|
|
364
|
-
function C(
|
|
365
|
-
return !
|
|
364
|
+
function C(e) {
|
|
365
|
+
return !e || e === "/" ? "/" : e.startsWith("/") ? e : \`/\${e}\`;
|
|
366
366
|
}
|
|
367
|
-
function
|
|
368
|
-
const
|
|
369
|
-
for (const
|
|
370
|
-
if (!(
|
|
371
|
-
if (
|
|
367
|
+
function ct(e) {
|
|
368
|
+
const t = m(e), r = [];
|
|
369
|
+
for (const n of t)
|
|
370
|
+
if (!(n === "." || n === ""))
|
|
371
|
+
if (n === "..") {
|
|
372
372
|
if (r.length === 0)
|
|
373
373
|
continue;
|
|
374
374
|
r.pop();
|
|
375
375
|
} else
|
|
376
|
-
r.push(
|
|
377
|
-
return
|
|
376
|
+
r.push(n);
|
|
377
|
+
return P(r);
|
|
378
378
|
}
|
|
379
|
-
function
|
|
380
|
-
return typeof
|
|
379
|
+
function lt(e, t = "utf-8") {
|
|
380
|
+
return typeof e == "string" ? et(e, t) : e instanceof Uint8Array ? e : new Uint8Array(e);
|
|
381
381
|
}
|
|
382
|
-
async function
|
|
383
|
-
const
|
|
382
|
+
async function ht(e) {
|
|
383
|
+
const t = await e.createSyncAccessHandle();
|
|
384
384
|
try {
|
|
385
|
-
const r =
|
|
386
|
-
return
|
|
385
|
+
const r = t.getSize(), n = new Uint8Array(r);
|
|
386
|
+
return t.read(n, { at: 0 }), n;
|
|
387
387
|
} finally {
|
|
388
|
-
|
|
388
|
+
t.close();
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
|
-
async function
|
|
392
|
-
let
|
|
391
|
+
async function v(e, t, r, n = {}) {
|
|
392
|
+
let i = null;
|
|
393
393
|
try {
|
|
394
|
-
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
} catch (
|
|
398
|
-
console.error(
|
|
399
|
-
const
|
|
400
|
-
throw new c(\`Failed to \${
|
|
394
|
+
i = await e.createSyncAccessHandle();
|
|
395
|
+
const a = lt(t, r), s = n.append ? i.getSize() : 0;
|
|
396
|
+
i.write(a, { at: s }), n.truncate && !n.append && i.truncate(a.byteLength), i.flush();
|
|
397
|
+
} catch (a) {
|
|
398
|
+
console.error(a);
|
|
399
|
+
const s = n.append ? "append" : "write";
|
|
400
|
+
throw new c(\`Failed to \${s} file\`, \`\${s.toUpperCase()}_FAILED\`);
|
|
401
401
|
} finally {
|
|
402
|
-
if (
|
|
402
|
+
if (i)
|
|
403
403
|
try {
|
|
404
|
-
|
|
404
|
+
i.close();
|
|
405
405
|
} catch {
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
|
-
async function
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
throw console.warn(\`Failed to calculate \${e} hash:\`, r), r;
|
|
415
|
-
}
|
|
409
|
+
async function ut(e, t = "SHA-1", r = 50 * 1024 * 1024) {
|
|
410
|
+
if (e instanceof File && (e = await e.arrayBuffer()), e.byteLength > r)
|
|
411
|
+
throw new Error(\`File size \${e.byteLength} bytes exceeds maximum allowed size \${r} bytes\`);
|
|
412
|
+
const n = new Uint8Array(e), i = await crypto.subtle.digest(t, n);
|
|
413
|
+
return Array.from(new Uint8Array(i)).map((s) => s.toString(16).padStart(2, "0")).join("");
|
|
416
414
|
}
|
|
417
|
-
async function
|
|
418
|
-
const
|
|
419
|
-
return new Uint8Array(
|
|
415
|
+
async function ft(e) {
|
|
416
|
+
const t = await e.arrayBuffer();
|
|
417
|
+
return new Uint8Array(t);
|
|
420
418
|
}
|
|
421
|
-
class
|
|
419
|
+
class wt {
|
|
422
420
|
/** Root directory handle for the file system */
|
|
423
421
|
root = null;
|
|
424
422
|
/** Watch event callback */
|
|
@@ -427,12 +425,16 @@ class we {
|
|
|
427
425
|
watchers = /* @__PURE__ */ new Map();
|
|
428
426
|
/** Interval handle for polling watched paths */
|
|
429
427
|
watchTimer = null;
|
|
430
|
-
/** Polling interval in milliseconds */
|
|
431
|
-
watchInterval = 1e3;
|
|
432
428
|
/** Flag to avoid concurrent scans */
|
|
433
429
|
scanning = !1;
|
|
434
430
|
/** Promise to prevent concurrent mount operations */
|
|
435
431
|
mountingPromise = null;
|
|
432
|
+
/** Configuration options */
|
|
433
|
+
options = {
|
|
434
|
+
watchInterval: 1e3,
|
|
435
|
+
maxFileSize: 50 * 1024 * 1024,
|
|
436
|
+
hashAlgorithm: null
|
|
437
|
+
};
|
|
436
438
|
/**
|
|
437
439
|
* Notify about internal changes to the file system
|
|
438
440
|
*
|
|
@@ -442,21 +444,35 @@ class we {
|
|
|
442
444
|
* @param path - The path that was changed
|
|
443
445
|
* @param type - The type of change (create, change, delete)
|
|
444
446
|
*/
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
447
|
+
async notifyChange(t) {
|
|
448
|
+
if (!this.watchCallback)
|
|
449
|
+
return;
|
|
450
|
+
let r;
|
|
451
|
+
if (this.options.hashAlgorithm && !t.isDirectory && t.type !== "removed")
|
|
452
|
+
try {
|
|
453
|
+
const n = await this.stat(t.path);
|
|
454
|
+
n.isFile && n.hash && (r = n.hash);
|
|
455
|
+
} catch (n) {
|
|
456
|
+
console.warn(\`Failed to calculate hash for \${t.path}:\`, n);
|
|
457
|
+
}
|
|
458
|
+
this.watchCallback({
|
|
459
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
460
|
+
...t,
|
|
461
|
+
...r && { hash: r }
|
|
449
462
|
});
|
|
450
463
|
}
|
|
451
464
|
/**
|
|
452
465
|
* Creates a new OPFSFileSystem instance
|
|
453
466
|
*
|
|
454
467
|
* @param watchCallback - Optional callback for file change events
|
|
455
|
-
* @param
|
|
468
|
+
* @param options - Optional configuration options
|
|
469
|
+
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
470
|
+
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
471
|
+
* @param options.maxFileSize - Maximum file size for hashing in bytes (default: 50MB)
|
|
456
472
|
* @throws {OPFSError} If OPFS is not supported in the current browser
|
|
457
473
|
*/
|
|
458
|
-
constructor(
|
|
459
|
-
|
|
474
|
+
constructor(t, r) {
|
|
475
|
+
ot(), t && (this.watchCallback = t), r && this.setOptions(r), this.mount("/");
|
|
460
476
|
}
|
|
461
477
|
/**
|
|
462
478
|
* Initialize the file system within a given directory
|
|
@@ -479,14 +495,14 @@ class we {
|
|
|
479
495
|
* await fs.mount('/my-app');
|
|
480
496
|
* \`\`\`
|
|
481
497
|
*/
|
|
482
|
-
async mount(
|
|
483
|
-
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (r,
|
|
498
|
+
async mount(t = "/") {
|
|
499
|
+
return this.mountingPromise && await this.mountingPromise, this.mountingPromise = new Promise(async (r, n) => {
|
|
484
500
|
this.root = null;
|
|
485
501
|
try {
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
} catch (
|
|
489
|
-
console.error(
|
|
502
|
+
const i = await navigator.storage.getDirectory();
|
|
503
|
+
t === "/" ? this.root = i : this.root = await this.getDirectoryHandle(t, !0, i), r(!0);
|
|
504
|
+
} catch (i) {
|
|
505
|
+
console.error(i), n(new c("Failed to initialize OPFS", "INIT_FAILED"));
|
|
490
506
|
} finally {
|
|
491
507
|
this.mountingPromise = null;
|
|
492
508
|
}
|
|
@@ -496,10 +512,20 @@ class we {
|
|
|
496
512
|
* Set the watch callback for file change events
|
|
497
513
|
*
|
|
498
514
|
* @param callback - The callback function to invoke when files change
|
|
499
|
-
* @param options - Optional configuration for watching
|
|
500
515
|
*/
|
|
501
|
-
setWatchCallback(
|
|
502
|
-
this.watchCallback =
|
|
516
|
+
setWatchCallback(t) {
|
|
517
|
+
this.watchCallback = t;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Update configuration options
|
|
521
|
+
*
|
|
522
|
+
* @param options - Configuration options to update
|
|
523
|
+
* @param options.watchInterval - Polling interval in milliseconds for file watching
|
|
524
|
+
* @param options.hashAlgorithm - Hash algorithm for file hashing
|
|
525
|
+
* @param options.maxFileSize - Maximum file size for hashing in bytes
|
|
526
|
+
*/
|
|
527
|
+
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);
|
|
503
529
|
}
|
|
504
530
|
/**
|
|
505
531
|
* Automatically mount the OPFS root if not already mounted
|
|
@@ -537,14 +563,14 @@ class we {
|
|
|
537
563
|
* const docsDir2 = await fs.getDirectoryHandle(['users', 'john', 'documents'], true);
|
|
538
564
|
* \`\`\`
|
|
539
565
|
*/
|
|
540
|
-
async getDirectoryHandle(
|
|
541
|
-
if (!
|
|
566
|
+
async getDirectoryHandle(t, r = !1, n = this.root) {
|
|
567
|
+
if (!n)
|
|
542
568
|
throw new T();
|
|
543
|
-
const
|
|
544
|
-
let
|
|
545
|
-
for (const
|
|
546
|
-
|
|
547
|
-
return
|
|
569
|
+
const i = Array.isArray(t) ? t : m(t);
|
|
570
|
+
let a = n;
|
|
571
|
+
for (const s of i)
|
|
572
|
+
a = await a.getDirectoryHandle(s, { create: r });
|
|
573
|
+
return a;
|
|
548
574
|
}
|
|
549
575
|
/**
|
|
550
576
|
* Get a file handle from a path
|
|
@@ -565,45 +591,27 @@ class we {
|
|
|
565
591
|
* const fileHandle2 = await fs.getFileHandle(['config', 'settings.json'], true);
|
|
566
592
|
* \`\`\`
|
|
567
593
|
*/
|
|
568
|
-
async getFileHandle(
|
|
569
|
-
if (!
|
|
594
|
+
async getFileHandle(t, r = !1, n = this.root) {
|
|
595
|
+
if (!n)
|
|
570
596
|
throw new T();
|
|
571
|
-
const
|
|
572
|
-
if (
|
|
573
|
-
throw new
|
|
574
|
-
const
|
|
575
|
-
return (await this.getDirectoryHandle(
|
|
597
|
+
const i = m(t);
|
|
598
|
+
if (i.length === 0)
|
|
599
|
+
throw new k("Path must not be empty", Array.isArray(t) ? t.join("/") : t);
|
|
600
|
+
const a = i.pop();
|
|
601
|
+
return (await this.getDirectoryHandle(i, r, n)).getFileHandle(a, { create: r });
|
|
576
602
|
}
|
|
577
603
|
/**
|
|
578
|
-
*
|
|
604
|
+
* Get a complete index of all files and directories in the file system
|
|
579
605
|
*
|
|
580
|
-
*
|
|
581
|
-
* a Map containing
|
|
606
|
+
* This method recursively traverses the entire file system and returns
|
|
607
|
+
* a Map containing FileStat objects for every file and directory.
|
|
582
608
|
*
|
|
583
|
-
* @
|
|
584
|
-
* @
|
|
585
|
-
* @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
|
|
586
|
-
* @returns Promise that resolves to a Map of path => FileStat
|
|
587
|
-
* @throws {OPFSError} If the indexing operation fails
|
|
609
|
+
* @returns Promise that resolves to a Map of paths to FileStat objects
|
|
610
|
+
* @throws {OPFSError} If the file system is not mounted
|
|
588
611
|
*
|
|
589
612
|
* @example
|
|
590
613
|
* \`\`\`typescript
|
|
591
|
-
* // Basic index without hash
|
|
592
614
|
* const index = await fs.index();
|
|
593
|
-
*
|
|
594
|
-
* // Index with file hash
|
|
595
|
-
* const indexWithHash = await fs.index({
|
|
596
|
-
* includeHash: true,
|
|
597
|
-
* hashAlgorithm: 'SHA-1'
|
|
598
|
-
* });
|
|
599
|
-
*
|
|
600
|
-
* // Iterate through all files and directories
|
|
601
|
-
* for (const [path, stat] of index) {
|
|
602
|
-
* console.log(\`\${path}: \${stat.isFile ? 'file' : 'directory'} (\${stat.size} bytes)\`);
|
|
603
|
-
* if (stat.hash) console.log(\` Hash: \${stat.hash}\`);
|
|
604
|
-
* }
|
|
605
|
-
*
|
|
606
|
-
* // Get specific file stats
|
|
607
615
|
* const fileStats = index.get('/data/config.json');
|
|
608
616
|
* if (fileStats) {
|
|
609
617
|
* console.log(\`File size: \${fileStats.size} bytes\`);
|
|
@@ -611,35 +619,35 @@ class we {
|
|
|
611
619
|
* }
|
|
612
620
|
* \`\`\`
|
|
613
621
|
*/
|
|
614
|
-
async index(
|
|
615
|
-
const
|
|
622
|
+
async index() {
|
|
623
|
+
const t = /* @__PURE__ */ new Map(), r = async (n) => {
|
|
616
624
|
const i = await this.readdir(n, { withFileTypes: !0 });
|
|
617
|
-
for (const
|
|
618
|
-
const s = \`\${n === "/" ? "" : n}/\${
|
|
625
|
+
for (const a of i) {
|
|
626
|
+
const s = \`\${n === "/" ? "" : n}/\${a.name}\`;
|
|
619
627
|
try {
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
} catch (
|
|
623
|
-
console.warn(\`Skipping broken entry: \${s}\`,
|
|
628
|
+
const o = await this.stat(s);
|
|
629
|
+
t.set(s, o), o.isDirectory && await r(s);
|
|
630
|
+
} catch (o) {
|
|
631
|
+
console.warn(\`Skipping broken entry: \${s}\`, o);
|
|
624
632
|
}
|
|
625
633
|
}
|
|
626
634
|
};
|
|
627
|
-
return
|
|
635
|
+
return t.set("/", {
|
|
628
636
|
kind: "directory",
|
|
629
637
|
size: 0,
|
|
630
638
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
631
639
|
ctime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
632
640
|
isFile: !1,
|
|
633
641
|
isDirectory: !0
|
|
634
|
-
}), await
|
|
642
|
+
}), await r("/"), t;
|
|
635
643
|
}
|
|
636
|
-
async readFile(
|
|
644
|
+
async readFile(t, r = "utf-8") {
|
|
637
645
|
await this.ensureMounted();
|
|
638
646
|
try {
|
|
639
|
-
const
|
|
640
|
-
return r === "binary" ?
|
|
641
|
-
} catch (
|
|
642
|
-
throw console.error(
|
|
647
|
+
const n = await this.getFileHandle(t, !1), i = await ht(n);
|
|
648
|
+
return r === "binary" ? i : rt(i, r);
|
|
649
|
+
} catch (n) {
|
|
650
|
+
throw console.error(n), new O(t);
|
|
643
651
|
}
|
|
644
652
|
}
|
|
645
653
|
/**
|
|
@@ -667,10 +675,10 @@ class we {
|
|
|
667
675
|
* await fs.writeFile('/data/utf16.txt', 'Hello World', 'utf-16le');
|
|
668
676
|
* \`\`\`
|
|
669
677
|
*/
|
|
670
|
-
async writeFile(
|
|
678
|
+
async writeFile(t, r, n) {
|
|
671
679
|
await this.ensureMounted();
|
|
672
|
-
const
|
|
673
|
-
await
|
|
680
|
+
const i = await this.getFileHandle(t, !0);
|
|
681
|
+
await v(i, r, n, { truncate: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
674
682
|
}
|
|
675
683
|
/**
|
|
676
684
|
* Append data to a file
|
|
@@ -694,10 +702,10 @@ class we {
|
|
|
694
702
|
* await fs.appendFile('/data/binary.dat', additionalData);
|
|
695
703
|
* \`\`\`
|
|
696
704
|
*/
|
|
697
|
-
async appendFile(
|
|
705
|
+
async appendFile(t, r, n) {
|
|
698
706
|
await this.ensureMounted();
|
|
699
|
-
const
|
|
700
|
-
await
|
|
707
|
+
const i = await this.getFileHandle(t, !0);
|
|
708
|
+
await v(i, r, n, { append: !0 }), await this.notifyChange({ path: t, type: "changed", isDirectory: !1 });
|
|
701
709
|
}
|
|
702
710
|
/**
|
|
703
711
|
* Create a directory
|
|
@@ -720,55 +728,48 @@ class we {
|
|
|
720
728
|
* await fs.mkdir('/users/john/documents/projects', { recursive: true });
|
|
721
729
|
* \`\`\`
|
|
722
730
|
*/
|
|
723
|
-
async mkdir(
|
|
731
|
+
async mkdir(t, r) {
|
|
724
732
|
if (await this.ensureMounted(), !this.root)
|
|
725
733
|
throw new T();
|
|
726
|
-
const
|
|
727
|
-
let
|
|
728
|
-
for (let
|
|
729
|
-
const
|
|
734
|
+
const n = r?.recursive ?? !1, i = m(t);
|
|
735
|
+
let a = this.root;
|
|
736
|
+
for (let s = 0; s < i.length; s++) {
|
|
737
|
+
const o = i[s];
|
|
730
738
|
try {
|
|
731
|
-
|
|
739
|
+
a = await a.getDirectoryHandle(o, { create: n || s === i.length - 1 });
|
|
732
740
|
} catch (l) {
|
|
733
741
|
throw l.name === "NotFoundError" ? new c(
|
|
734
|
-
\`Parent directory does not exist: \${
|
|
742
|
+
\`Parent directory does not exist: \${P(i.slice(0, s + 1))}\`,
|
|
735
743
|
"ENOENT"
|
|
736
|
-
) : l.name === "TypeMismatchError" ? new c(\`Path segment is not a directory: \${
|
|
744
|
+
) : l.name === "TypeMismatchError" ? new c(\`Path segment is not a directory: \${o}\`, "ENOTDIR") : new c("Failed to create directory", "MKDIR_FAILED");
|
|
737
745
|
}
|
|
738
746
|
}
|
|
739
|
-
this.
|
|
747
|
+
await this.notifyChange({ path: t, type: "added", isDirectory: !0 });
|
|
740
748
|
}
|
|
741
749
|
/**
|
|
742
|
-
* Get file or directory
|
|
750
|
+
* Get file or directory statistics
|
|
743
751
|
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
752
|
+
* Returns detailed information about a file or directory, including
|
|
753
|
+
* size, modification time, and optionally a hash of the file content.
|
|
746
754
|
*
|
|
747
755
|
* @param path - The path to the file or directory
|
|
748
|
-
* @
|
|
749
|
-
* @
|
|
750
|
-
* @param options.hashAlgorithm - Hash algorithm to use (default: 'SHA-1', fastest)
|
|
751
|
-
* @returns Promise that resolves to file/directory statistics
|
|
752
|
-
* @throws {OPFSError} If the file or directory does not exist or cannot be accessed
|
|
756
|
+
* @returns Promise that resolves to FileStat object
|
|
757
|
+
* @throws {OPFSError} If the path does not exist or cannot be accessed
|
|
753
758
|
*
|
|
754
759
|
* @example
|
|
755
760
|
* \`\`\`typescript
|
|
756
|
-
*
|
|
757
|
-
* const stats = await fs.stat('/config/settings.json');
|
|
761
|
+
* const stats = await fs.stat('/data/config.json');
|
|
758
762
|
* console.log(\`File size: \${stats.size} bytes\`);
|
|
759
|
-
* console.log(\`
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
* hashAlgorithm: 'SHA-1'
|
|
766
|
-
* });
|
|
767
|
-
* console.log(\`Hash: \${statsWithHash.hash}\`);
|
|
763
|
+
* console.log(\`Last modified: \${stats.mtime}\`);
|
|
764
|
+
*
|
|
765
|
+
* // If hashing is enabled, hash will be included
|
|
766
|
+
* if (stats.hash) {
|
|
767
|
+
* console.log(\`Hash: \${stats.hash}\`);
|
|
768
|
+
* }
|
|
768
769
|
* \`\`\`
|
|
769
770
|
*/
|
|
770
|
-
async stat(
|
|
771
|
-
if (await this.ensureMounted(),
|
|
771
|
+
async stat(t) {
|
|
772
|
+
if (await this.ensureMounted(), t === "/")
|
|
772
773
|
return {
|
|
773
774
|
kind: "directory",
|
|
774
775
|
size: 0,
|
|
@@ -777,30 +778,30 @@ class we {
|
|
|
777
778
|
isFile: !1,
|
|
778
779
|
isDirectory: !0
|
|
779
780
|
};
|
|
780
|
-
const
|
|
781
|
+
const r = b(t), n = await this.getDirectoryHandle(x(t), !1), i = this.options.hashAlgorithm !== null;
|
|
781
782
|
try {
|
|
782
|
-
const
|
|
783
|
+
const s = await (await n.getFileHandle(r, { create: !1 })).getFile(), o = {
|
|
783
784
|
kind: "file",
|
|
784
|
-
size:
|
|
785
|
-
mtime: new Date(
|
|
786
|
-
ctime: new Date(
|
|
785
|
+
size: s.size,
|
|
786
|
+
mtime: new Date(s.lastModified).toISOString(),
|
|
787
|
+
ctime: new Date(s.lastModified).toISOString(),
|
|
787
788
|
isFile: !0,
|
|
788
789
|
isDirectory: !1
|
|
789
790
|
};
|
|
790
|
-
if (i)
|
|
791
|
+
if (i && this.options.hashAlgorithm)
|
|
791
792
|
try {
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
} catch (
|
|
795
|
-
console.warn(\`Failed to calculate hash for \${
|
|
793
|
+
const l = await ut(s, this.options.hashAlgorithm, this.options.maxFileSize);
|
|
794
|
+
o.hash = l;
|
|
795
|
+
} catch (l) {
|
|
796
|
+
console.warn(\`Failed to calculate hash for \${t}:\`, l);
|
|
796
797
|
}
|
|
797
|
-
return
|
|
798
|
-
} catch (
|
|
799
|
-
if (
|
|
798
|
+
return o;
|
|
799
|
+
} catch (a) {
|
|
800
|
+
if (a.name !== "TypeMismatchError" && a.name !== "NotFoundError")
|
|
800
801
|
throw new c("Failed to stat (file)", "STAT_FAILED");
|
|
801
802
|
}
|
|
802
803
|
try {
|
|
803
|
-
return await n.getDirectoryHandle(
|
|
804
|
+
return await n.getDirectoryHandle(r, { create: !1 }), {
|
|
804
805
|
kind: "directory",
|
|
805
806
|
size: 0,
|
|
806
807
|
mtime: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
@@ -808,30 +809,30 @@ class we {
|
|
|
808
809
|
isFile: !1,
|
|
809
810
|
isDirectory: !0
|
|
810
811
|
};
|
|
811
|
-
} catch (
|
|
812
|
-
throw
|
|
812
|
+
} catch (a) {
|
|
813
|
+
throw a.name === "NotFoundError" ? new c(\`No such file or directory: \${t}\`, "ENOENT") : new c("Failed to stat (directory)", "STAT_FAILED");
|
|
813
814
|
}
|
|
814
815
|
}
|
|
815
|
-
async readdir(
|
|
816
|
+
async readdir(t, r) {
|
|
816
817
|
await this.ensureMounted();
|
|
817
|
-
const
|
|
818
|
-
if (
|
|
819
|
-
const
|
|
820
|
-
for await (const [
|
|
821
|
-
const l =
|
|
822
|
-
|
|
823
|
-
name:
|
|
824
|
-
kind:
|
|
818
|
+
const n = r?.withFileTypes ?? !1, i = await this.getDirectoryHandle(t, !1);
|
|
819
|
+
if (n) {
|
|
820
|
+
const a = [];
|
|
821
|
+
for await (const [s, o] of i.entries()) {
|
|
822
|
+
const l = o.kind === "file";
|
|
823
|
+
a.push({
|
|
824
|
+
name: s,
|
|
825
|
+
kind: o.kind,
|
|
825
826
|
isFile: l,
|
|
826
827
|
isDirectory: !l
|
|
827
828
|
});
|
|
828
829
|
}
|
|
829
|
-
return
|
|
830
|
+
return a;
|
|
830
831
|
} else {
|
|
831
|
-
const
|
|
832
|
-
for await (const [
|
|
833
|
-
|
|
834
|
-
return
|
|
832
|
+
const a = [];
|
|
833
|
+
for await (const [s] of i.entries())
|
|
834
|
+
a.push(s);
|
|
835
|
+
return a;
|
|
835
836
|
}
|
|
836
837
|
}
|
|
837
838
|
/**
|
|
@@ -848,29 +849,29 @@ class we {
|
|
|
848
849
|
* console.log(\`File exists: \${exists}\`);
|
|
849
850
|
* \`\`\`
|
|
850
851
|
*/
|
|
851
|
-
async exists(
|
|
852
|
-
if (await this.ensureMounted(),
|
|
852
|
+
async exists(t) {
|
|
853
|
+
if (await this.ensureMounted(), t === "/")
|
|
853
854
|
return !0;
|
|
854
|
-
const r = b(
|
|
855
|
-
let
|
|
855
|
+
const r = b(t);
|
|
856
|
+
let n = null;
|
|
856
857
|
try {
|
|
857
|
-
|
|
858
|
-
} catch (
|
|
859
|
-
throw (
|
|
858
|
+
n = await this.getDirectoryHandle(x(t), !1);
|
|
859
|
+
} catch (i) {
|
|
860
|
+
throw (i.name === "NotFoundError" || i.name === "TypeMismatchError") && (n = null), i;
|
|
860
861
|
}
|
|
861
|
-
if (!
|
|
862
|
+
if (!n || !r)
|
|
862
863
|
return !1;
|
|
863
864
|
try {
|
|
864
|
-
return await
|
|
865
|
-
} catch (
|
|
866
|
-
if (
|
|
867
|
-
throw
|
|
865
|
+
return await n.getFileHandle(r, { create: !1 }), !0;
|
|
866
|
+
} catch (i) {
|
|
867
|
+
if (i.name !== "NotFoundError" && i.name !== "TypeMismatchError")
|
|
868
|
+
throw i;
|
|
868
869
|
}
|
|
869
870
|
try {
|
|
870
|
-
return await
|
|
871
|
-
} catch (
|
|
872
|
-
if (
|
|
873
|
-
throw
|
|
871
|
+
return await n.getDirectoryHandle(r, { create: !1 }), !0;
|
|
872
|
+
} catch (i) {
|
|
873
|
+
if (i.name !== "NotFoundError" && i.name !== "TypeMismatchError")
|
|
874
|
+
throw i;
|
|
874
875
|
}
|
|
875
876
|
return !1;
|
|
876
877
|
}
|
|
@@ -893,17 +894,17 @@ class we {
|
|
|
893
894
|
* await fs.clear('/data');
|
|
894
895
|
* \`\`\`
|
|
895
896
|
*/
|
|
896
|
-
async clear(
|
|
897
|
+
async clear(t = "/") {
|
|
897
898
|
await this.ensureMounted();
|
|
898
899
|
try {
|
|
899
|
-
const r = await this.readdir(
|
|
900
|
-
for (const
|
|
901
|
-
const
|
|
902
|
-
await this.remove(
|
|
900
|
+
const r = await this.readdir(t, { withFileTypes: !0 });
|
|
901
|
+
for (const n of r) {
|
|
902
|
+
const i = \`\${t === "/" ? "" : t}/\${n.name}\`;
|
|
903
|
+
await this.remove(i, { recursive: !0 });
|
|
903
904
|
}
|
|
904
|
-
this.
|
|
905
|
+
await this.notifyChange({ path: t, type: "changed", isDirectory: !0 });
|
|
905
906
|
} catch (r) {
|
|
906
|
-
throw r instanceof c ? r : new c(\`Failed to clear directory: \${
|
|
907
|
+
throw r instanceof c ? r : new c(\`Failed to clear directory: \${t}\`, "CLEAR_FAILED");
|
|
907
908
|
}
|
|
908
909
|
}
|
|
909
910
|
/**
|
|
@@ -930,24 +931,24 @@ class we {
|
|
|
930
931
|
* await fs.rm('/maybe/exists', { force: true });
|
|
931
932
|
* \`\`\`
|
|
932
933
|
*/
|
|
933
|
-
async remove(
|
|
934
|
+
async remove(t, r) {
|
|
934
935
|
await this.ensureMounted();
|
|
935
|
-
const
|
|
936
|
-
if (
|
|
936
|
+
const n = r?.recursive ?? !1, i = r?.force ?? !1;
|
|
937
|
+
if (t === "/")
|
|
937
938
|
throw new c("Cannot remove root directory", "EROOT");
|
|
938
|
-
const
|
|
939
|
-
if (!
|
|
940
|
-
throw new
|
|
941
|
-
const
|
|
939
|
+
const a = b(t);
|
|
940
|
+
if (!a)
|
|
941
|
+
throw new k("Invalid path", t);
|
|
942
|
+
const s = await this.getDirectoryHandle(x(t), !1);
|
|
942
943
|
try {
|
|
943
|
-
await
|
|
944
|
-
} catch (
|
|
945
|
-
if (
|
|
946
|
-
if (!
|
|
947
|
-
throw new c(\`No such file or directory: \${
|
|
948
|
-
} else throw
|
|
944
|
+
await s.removeEntry(a, { recursive: n });
|
|
945
|
+
} catch (o) {
|
|
946
|
+
if (o.name === "NotFoundError") {
|
|
947
|
+
if (!i)
|
|
948
|
+
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" && !n ? new c(\`Cannot remove directory without recursive option: \${t}\`, "EISDIR") : new c(\`Failed to remove path: \${t}\`, "RM_FAILED");
|
|
949
950
|
}
|
|
950
|
-
this.
|
|
951
|
+
await this.notifyChange({ path: t, type: "removed", isDirectory: !1 });
|
|
951
952
|
}
|
|
952
953
|
/**
|
|
953
954
|
* Resolve a path to an absolute path
|
|
@@ -967,15 +968,15 @@ class we {
|
|
|
967
968
|
* console.log(absolute); // '/data/file.txt'
|
|
968
969
|
* \`\`\`
|
|
969
970
|
*/
|
|
970
|
-
async realpath(
|
|
971
|
+
async realpath(t) {
|
|
971
972
|
await this.ensureMounted();
|
|
972
973
|
try {
|
|
973
|
-
const r =
|
|
974
|
+
const r = ct(t);
|
|
974
975
|
if (!await this.exists(r))
|
|
975
|
-
throw new
|
|
976
|
+
throw new O(r);
|
|
976
977
|
return r;
|
|
977
978
|
} catch (r) {
|
|
978
|
-
throw r instanceof c ? r : new c(\`Failed to resolve path: \${
|
|
979
|
+
throw r instanceof c ? r : new c(\`Failed to resolve path: \${t}\`, "REALPATH_FAILED");
|
|
979
980
|
}
|
|
980
981
|
}
|
|
981
982
|
/**
|
|
@@ -994,14 +995,14 @@ class we {
|
|
|
994
995
|
* await fs.rename('/old/path/file.txt', '/new/path/renamed.txt');
|
|
995
996
|
* \`\`\`
|
|
996
997
|
*/
|
|
997
|
-
async rename(
|
|
998
|
+
async rename(t, r) {
|
|
998
999
|
await this.ensureMounted();
|
|
999
1000
|
try {
|
|
1000
|
-
if (!await this.exists(
|
|
1001
|
-
throw new
|
|
1002
|
-
await this.copy(
|
|
1003
|
-
} catch (
|
|
1004
|
-
throw
|
|
1001
|
+
if (!await this.exists(t))
|
|
1002
|
+
throw new O(t);
|
|
1003
|
+
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 (n) {
|
|
1005
|
+
throw n instanceof c ? n : new c(\`Failed to rename from \${t} to \${r}\`, "RENAME_FAILED");
|
|
1005
1006
|
}
|
|
1006
1007
|
}
|
|
1007
1008
|
/**
|
|
@@ -1029,85 +1030,81 @@ class we {
|
|
|
1029
1030
|
* await fs.copy('/source', '/dest', { recursive: true, force: false });
|
|
1030
1031
|
* \`\`\`
|
|
1031
1032
|
*/
|
|
1032
|
-
async copy(
|
|
1033
|
+
async copy(t, r, n) {
|
|
1033
1034
|
await this.ensureMounted();
|
|
1034
1035
|
try {
|
|
1035
|
-
const
|
|
1036
|
-
if (!await this.exists(
|
|
1037
|
-
throw new c(\`Source does not exist: \${
|
|
1038
|
-
if (await this.exists(r) && !
|
|
1036
|
+
const i = n?.recursive ?? !1, a = n?.force ?? !0;
|
|
1037
|
+
if (!await this.exists(t))
|
|
1038
|
+
throw new c(\`Source does not exist: \${t}\`, "ENOENT");
|
|
1039
|
+
if (await this.exists(r) && !a)
|
|
1039
1040
|
throw new c(\`Destination already exists: \${r}\`, "EEXIST");
|
|
1040
|
-
if ((await this.stat(
|
|
1041
|
-
const
|
|
1042
|
-
await this.writeFile(r,
|
|
1041
|
+
if ((await this.stat(t)).isFile) {
|
|
1042
|
+
const h = await this.readFile(t, "binary");
|
|
1043
|
+
await this.writeFile(r, h);
|
|
1043
1044
|
} else {
|
|
1044
|
-
if (!
|
|
1045
|
-
throw new c(\`Cannot copy directory without recursive option: \${
|
|
1045
|
+
if (!i)
|
|
1046
|
+
throw new c(\`Cannot copy directory without recursive option: \${t}\`, "EISDIR");
|
|
1046
1047
|
await this.mkdir(r, { recursive: !0 });
|
|
1047
|
-
const
|
|
1048
|
-
for (const
|
|
1049
|
-
const w = \`\${
|
|
1050
|
-
await this.copy(w,
|
|
1048
|
+
const h = await this.readdir(t, { withFileTypes: !0 });
|
|
1049
|
+
for (const u of h) {
|
|
1050
|
+
const w = \`\${t}/\${u.name}\`, f = \`\${r}/\${u.name}\`;
|
|
1051
|
+
await this.copy(w, f, { recursive: !0, force: a });
|
|
1051
1052
|
}
|
|
1052
1053
|
}
|
|
1053
|
-
this.
|
|
1054
|
-
} catch (
|
|
1055
|
-
throw
|
|
1054
|
+
await this.notifyChange({ path: r, type: "added", isDirectory: !1 });
|
|
1055
|
+
} catch (i) {
|
|
1056
|
+
throw i instanceof c ? i : new c(\`Failed to copy from \${t} to \${r}\`, "CP_FAILED");
|
|
1056
1057
|
}
|
|
1057
1058
|
}
|
|
1058
1059
|
/**
|
|
1059
1060
|
* Start watching a file or directory for changes
|
|
1060
1061
|
*/
|
|
1061
|
-
async watch(
|
|
1062
|
+
async watch(t) {
|
|
1062
1063
|
await this.ensureMounted();
|
|
1063
|
-
const r = C(
|
|
1064
|
-
this.watchers.set(r,
|
|
1064
|
+
const r = C(t), n = await this.buildSnapshot(r);
|
|
1065
|
+
this.watchers.set(r, n), this.watchTimer || (this.watchTimer = setInterval(() => {
|
|
1065
1066
|
this.scanWatches();
|
|
1066
|
-
}, this.watchInterval));
|
|
1067
|
+
}, this.options.watchInterval));
|
|
1067
1068
|
}
|
|
1068
1069
|
/**
|
|
1069
1070
|
* Stop watching a previously watched path
|
|
1070
1071
|
*/
|
|
1071
|
-
unwatch(
|
|
1072
|
-
const r = C(
|
|
1072
|
+
unwatch(t) {
|
|
1073
|
+
const r = C(t);
|
|
1073
1074
|
this.watchers.delete(r), this.watchers.size === 0 && this.watchTimer && (clearInterval(this.watchTimer), this.watchTimer = null);
|
|
1074
1075
|
}
|
|
1075
|
-
async buildSnapshot(
|
|
1076
|
-
const r = /* @__PURE__ */ new Map(),
|
|
1077
|
-
const
|
|
1078
|
-
if (r.set(
|
|
1079
|
-
const
|
|
1080
|
-
for (const
|
|
1081
|
-
const l = \`\${
|
|
1082
|
-
await
|
|
1076
|
+
async buildSnapshot(t) {
|
|
1077
|
+
const r = /* @__PURE__ */ new Map(), n = async (i) => {
|
|
1078
|
+
const a = await this.stat(i);
|
|
1079
|
+
if (r.set(i, a), a.isDirectory) {
|
|
1080
|
+
const s = await this.readdir(i, { withFileTypes: !0 });
|
|
1081
|
+
for (const o of s) {
|
|
1082
|
+
const l = \`\${i === "/" ? "" : i}/\${o.name}\`;
|
|
1083
|
+
await n(l);
|
|
1083
1084
|
}
|
|
1084
1085
|
}
|
|
1085
1086
|
};
|
|
1086
|
-
return await
|
|
1087
|
+
return await n(t), r;
|
|
1087
1088
|
}
|
|
1088
1089
|
async scanWatches() {
|
|
1089
1090
|
if (!this.scanning) {
|
|
1090
1091
|
this.scanning = !0;
|
|
1091
1092
|
try {
|
|
1092
1093
|
await Promise.all(
|
|
1093
|
-
[...this.watchers.entries()].map(async ([
|
|
1094
|
-
let
|
|
1094
|
+
[...this.watchers.entries()].map(async ([t, r]) => {
|
|
1095
|
+
let n;
|
|
1095
1096
|
try {
|
|
1096
|
-
|
|
1097
|
+
n = await this.buildSnapshot(t);
|
|
1097
1098
|
} catch {
|
|
1098
|
-
|
|
1099
|
+
n = /* @__PURE__ */ new Map();
|
|
1099
1100
|
}
|
|
1100
|
-
const n
|
|
1101
|
-
for (const [i, o] of a) {
|
|
1101
|
+
for (const [i, a] of n) {
|
|
1102
1102
|
const s = r.get(i);
|
|
1103
|
-
s ? (s.mtime !==
|
|
1103
|
+
s ? (s.mtime !== a.mtime || s.size !== a.size) && await this.notifyChange({ path: i, type: "changed", isDirectory: !1 }) : await this.notifyChange({ path: i, type: "added", isDirectory: !1 });
|
|
1104
1104
|
}
|
|
1105
1105
|
for (const i of r.keys())
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
for (const i of n)
|
|
1109
|
-
this.watchCallback(i);
|
|
1110
|
-
this.watchers.set(e, a);
|
|
1106
|
+
n.has(i) || await this.notifyChange({ path: i, type: "removed", isDirectory: !1 });
|
|
1107
|
+
this.watchers.set(t, n);
|
|
1111
1108
|
})
|
|
1112
1109
|
);
|
|
1113
1110
|
} finally {
|
|
@@ -1143,22 +1140,22 @@ class we {
|
|
|
1143
1140
|
* await fs.sync(entries, { cleanBefore: true });
|
|
1144
1141
|
* \`\`\`
|
|
1145
1142
|
*/
|
|
1146
|
-
async sync(
|
|
1143
|
+
async sync(t, r) {
|
|
1147
1144
|
await this.ensureMounted();
|
|
1148
1145
|
try {
|
|
1149
1146
|
(r?.cleanBefore ?? !1) && await this.clear("/");
|
|
1150
|
-
for (const [
|
|
1151
|
-
const
|
|
1152
|
-
let
|
|
1153
|
-
|
|
1147
|
+
for (const [i, a] of t) {
|
|
1148
|
+
const s = C(i);
|
|
1149
|
+
let o;
|
|
1150
|
+
a instanceof Blob ? o = await ft(a) : o = a, await this.writeFile(s, o);
|
|
1154
1151
|
}
|
|
1155
|
-
this.
|
|
1156
|
-
} catch (
|
|
1157
|
-
throw
|
|
1152
|
+
await this.notifyChange({ path: "/", type: "changed", isDirectory: !0 });
|
|
1153
|
+
} catch (n) {
|
|
1154
|
+
throw n instanceof c ? n : new c("Failed to sync file system", "SYNC_FAILED");
|
|
1158
1155
|
}
|
|
1159
1156
|
}
|
|
1160
1157
|
}
|
|
1161
|
-
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" &&
|
|
1162
|
-
//# sourceMappingURL=worker-
|
|
1163
|
-
`,i=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",o],{type:"text/javascript;charset=utf-8"});function s(r){let
|
|
1158
|
+
typeof self < "u" && self.constructor.name === "DedicatedWorkerGlobalScope" && I(new wt());
|
|
1159
|
+
//# sourceMappingURL=worker-CHy3JxL1.js.map
|
|
1160
|
+
`,i=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",o],{type:"text/javascript;charset=utf-8"});function s(r){let t;try{if(t=i&&(self.URL||self.webkitURL).createObjectURL(i),!t)throw"";const e=new Worker(t,{type:"module",name:r?.name});return e.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),e}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(o),{type:"module",name:r?.name})}}function c(r,t){const e=a.wrap(new s);return r&&e.setWatchCallback(r?a.proxy(r):()=>{}),t&&e.setOptions(t),e}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;
|
|
1164
1161
|
//# sourceMappingURL=index.cjs.map
|