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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class o extends Error {
|
|
2
|
-
constructor(r,
|
|
3
|
-
super(r), this.code =
|
|
2
|
+
constructor(r, t, n) {
|
|
3
|
+
super(r), this.code = t, this.path = n, this.name = "OPFSError";
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
class l extends o {
|
|
@@ -13,12 +13,12 @@ class A extends o {
|
|
|
13
13
|
super("OPFS is not mounted", "OPFS_NOT_MOUNTED");
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
class
|
|
17
|
-
constructor(r,
|
|
18
|
-
super(r, "INVALID_PATH",
|
|
16
|
+
class m extends o {
|
|
17
|
+
constructor(r, t) {
|
|
18
|
+
super(r, "INVALID_PATH", t);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
class
|
|
21
|
+
class S extends o {
|
|
22
22
|
constructor(r) {
|
|
23
23
|
super(`File not found: ${r}`, "FILE_NOT_FOUND", r);
|
|
24
24
|
}
|
|
@@ -29,18 +29,18 @@ class E extends o {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
class O extends o {
|
|
32
|
-
constructor(r,
|
|
33
|
-
super(`Permission denied for ${
|
|
32
|
+
constructor(r, t) {
|
|
33
|
+
super(`Permission denied for ${t} on: ${r}`, "PERMISSION_DENIED", r);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
class F extends o {
|
|
37
|
-
constructor(r,
|
|
38
|
-
super(r, "STORAGE_ERROR",
|
|
37
|
+
constructor(r, t) {
|
|
38
|
+
super(r, "STORAGE_ERROR", t);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
class U extends o {
|
|
42
|
-
constructor(r,
|
|
43
|
-
super(`Operation timed out: ${r}`, "TIMEOUT_ERROR",
|
|
42
|
+
constructor(r, t) {
|
|
43
|
+
super(`Operation timed out: ${r}`, "TIMEOUT_ERROR", t);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function f(e, r = "utf-8") {
|
|
@@ -57,13 +57,13 @@ function f(e, r = "utf-8") {
|
|
|
57
57
|
case "latin1":
|
|
58
58
|
return y(e);
|
|
59
59
|
case "binary":
|
|
60
|
-
return Uint8Array.from(e, (
|
|
60
|
+
return Uint8Array.from(e, (t) => t.charCodeAt(0));
|
|
61
61
|
case "base64":
|
|
62
|
-
return Uint8Array.from(atob(e), (
|
|
62
|
+
return Uint8Array.from(atob(e), (t) => t.charCodeAt(0));
|
|
63
63
|
case "hex":
|
|
64
64
|
if (!/^[\da-f]+$/i.test(e) || e.length % 2 !== 0)
|
|
65
65
|
throw new o("Invalid hex string", "INVALID_HEX_FORMAT");
|
|
66
|
-
return Uint8Array.from(e.match(/.{1,2}/g).map((
|
|
66
|
+
return Uint8Array.from(e.match(/.{1,2}/g).map((t) => parseInt(t, 16)));
|
|
67
67
|
default:
|
|
68
68
|
return console.warn("Encoding not supported, falling back to UTF-8"), new TextEncoder().encode(e);
|
|
69
69
|
}
|
|
@@ -82,20 +82,20 @@ function T(e, r = "utf-8") {
|
|
|
82
82
|
case "binary":
|
|
83
83
|
return String.fromCharCode(...e);
|
|
84
84
|
case "ascii":
|
|
85
|
-
return String.fromCharCode(...e.map((
|
|
85
|
+
return String.fromCharCode(...e.map((t) => t & 127));
|
|
86
86
|
case "base64":
|
|
87
87
|
return btoa(String.fromCharCode(...e));
|
|
88
88
|
case "hex":
|
|
89
|
-
return Array.from(e).map((
|
|
89
|
+
return Array.from(e).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
90
90
|
default:
|
|
91
91
|
return console.warn("Unsupported encoding, falling back to UTF-8"), new TextDecoder().decode(e);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
function d(e) {
|
|
95
95
|
const r = new Uint8Array(e.length * 2);
|
|
96
|
-
for (let
|
|
97
|
-
const
|
|
98
|
-
r[
|
|
96
|
+
for (let t = 0; t < e.length; t++) {
|
|
97
|
+
const n = e.charCodeAt(t);
|
|
98
|
+
r[t * 2] = n & 255, r[t * 2 + 1] = n >> 8;
|
|
99
99
|
}
|
|
100
100
|
return r;
|
|
101
101
|
}
|
|
@@ -106,17 +106,17 @@ function h(e) {
|
|
|
106
106
|
}
|
|
107
107
|
function y(e) {
|
|
108
108
|
const r = new Uint8Array(e.length);
|
|
109
|
-
for (let
|
|
110
|
-
r[
|
|
109
|
+
for (let t = 0; t < e.length; t++)
|
|
110
|
+
r[t] = e.charCodeAt(t) & 255;
|
|
111
111
|
return r;
|
|
112
112
|
}
|
|
113
113
|
function g(e) {
|
|
114
114
|
const r = new Uint8Array(e.length);
|
|
115
|
-
for (let
|
|
116
|
-
r[
|
|
115
|
+
for (let t = 0; t < e.length; t++)
|
|
116
|
+
r[t] = e.charCodeAt(t) & 127;
|
|
117
117
|
return r;
|
|
118
118
|
}
|
|
119
|
-
function
|
|
119
|
+
function x() {
|
|
120
120
|
if (!("storage" in navigator) || !("getDirectory" in navigator.storage))
|
|
121
121
|
throw new l();
|
|
122
122
|
}
|
|
@@ -130,7 +130,7 @@ function p(e) {
|
|
|
130
130
|
const r = i(e);
|
|
131
131
|
return r[r.length - 1] || "";
|
|
132
132
|
}
|
|
133
|
-
function
|
|
133
|
+
function P(e) {
|
|
134
134
|
const r = i(e);
|
|
135
135
|
return r.pop(), u(r);
|
|
136
136
|
}
|
|
@@ -138,20 +138,20 @@ function D(e) {
|
|
|
138
138
|
return !e || e === "/" ? "/" : e.startsWith("/") ? e : `/${e}`;
|
|
139
139
|
}
|
|
140
140
|
function C(e) {
|
|
141
|
-
const r = i(e),
|
|
142
|
-
for (const
|
|
143
|
-
if (!(
|
|
144
|
-
if (
|
|
145
|
-
if (
|
|
141
|
+
const r = i(e), t = [];
|
|
142
|
+
for (const n of r)
|
|
143
|
+
if (!(n === "." || n === ""))
|
|
144
|
+
if (n === "..") {
|
|
145
|
+
if (t.length === 0)
|
|
146
146
|
continue;
|
|
147
|
-
|
|
147
|
+
t.pop();
|
|
148
148
|
} else
|
|
149
|
-
|
|
150
|
-
return u(
|
|
149
|
+
t.push(n);
|
|
150
|
+
return u(t);
|
|
151
151
|
}
|
|
152
152
|
function I(e) {
|
|
153
|
-
const r = p(e),
|
|
154
|
-
return
|
|
153
|
+
const r = p(e), t = r.lastIndexOf(".");
|
|
154
|
+
return t <= 0 || t === r.length - 1 ? "" : r.slice(t);
|
|
155
155
|
}
|
|
156
156
|
function w(e, r = "utf-8") {
|
|
157
157
|
return typeof e == "string" ? f(e, r) : e instanceof Uint8Array ? e : new Uint8Array(e);
|
|
@@ -159,22 +159,22 @@ function w(e, r = "utf-8") {
|
|
|
159
159
|
async function N(e) {
|
|
160
160
|
const r = await e.createSyncAccessHandle();
|
|
161
161
|
try {
|
|
162
|
-
const
|
|
163
|
-
return r.read(
|
|
162
|
+
const t = r.getSize(), n = new Uint8Array(t);
|
|
163
|
+
return r.read(n, { at: 0 }), n;
|
|
164
164
|
} finally {
|
|
165
165
|
r.close();
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
async function _(e, r,
|
|
168
|
+
async function _(e, r, t, n = {}) {
|
|
169
169
|
let s = null;
|
|
170
170
|
try {
|
|
171
171
|
s = await e.createSyncAccessHandle();
|
|
172
|
-
const
|
|
173
|
-
s.write(
|
|
174
|
-
} catch (
|
|
175
|
-
console.error(
|
|
176
|
-
const
|
|
177
|
-
throw new o(`Failed to ${
|
|
172
|
+
const a = w(r, t), c = n.append ? s.getSize() : 0;
|
|
173
|
+
s.write(a, { at: c }), n.truncate && !n.append && s.truncate(a.byteLength), s.flush();
|
|
174
|
+
} catch (a) {
|
|
175
|
+
console.error(a);
|
|
176
|
+
const c = n.append ? "append" : "write";
|
|
177
|
+
throw new o(`Failed to ${c} file`, `${c.toUpperCase()}_FAILED`);
|
|
178
178
|
} finally {
|
|
179
179
|
if (s)
|
|
180
180
|
try {
|
|
@@ -183,13 +183,11 @@ async function _(e, r, n, t = {}) {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
-
async function
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
throw console.warn(`Failed to calculate ${r} hash:`, n), n;
|
|
192
|
-
}
|
|
186
|
+
async function L(e, r = "SHA-1", t = 50 * 1024 * 1024) {
|
|
187
|
+
if (e instanceof File && (e = await e.arrayBuffer()), e.byteLength > t)
|
|
188
|
+
throw new Error(`File size ${e.byteLength} bytes exceeds maximum allowed size ${t} bytes`);
|
|
189
|
+
const n = new Uint8Array(e), s = await crypto.subtle.digest(r, n);
|
|
190
|
+
return Array.from(new Uint8Array(s)).map((c) => c.toString(16).padStart(2, "0")).join("");
|
|
193
191
|
}
|
|
194
192
|
async function R(e) {
|
|
195
193
|
const r = await e.arrayBuffer();
|
|
@@ -197,22 +195,22 @@ async function R(e) {
|
|
|
197
195
|
}
|
|
198
196
|
export {
|
|
199
197
|
E as D,
|
|
200
|
-
|
|
198
|
+
S as F,
|
|
201
199
|
o as O,
|
|
202
|
-
|
|
200
|
+
m as P,
|
|
203
201
|
F as S,
|
|
204
202
|
U as T,
|
|
205
203
|
l as a,
|
|
206
204
|
A as b,
|
|
207
205
|
O as c,
|
|
208
|
-
|
|
206
|
+
x as d,
|
|
209
207
|
p as e,
|
|
210
|
-
|
|
208
|
+
P as f,
|
|
211
209
|
I as g,
|
|
212
210
|
w as h,
|
|
213
211
|
N as i,
|
|
214
212
|
u as j,
|
|
215
|
-
|
|
213
|
+
L as k,
|
|
216
214
|
R as l,
|
|
217
215
|
f as m,
|
|
218
216
|
D as n,
|
|
@@ -221,4 +219,4 @@ export {
|
|
|
221
219
|
i as s,
|
|
222
220
|
_ as w
|
|
223
221
|
};
|
|
224
|
-
//# sourceMappingURL=helpers-
|
|
222
|
+
//# sourceMappingURL=helpers-C0nyU6hv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers-Co-qCBmA.js","sources":["../src/utils/errors.ts","../src/utils/encoder.ts","../src/utils/helpers.ts"],"sourcesContent":["/**\n * Base error class for all OPFS-related errors\n */\nexport class OPFSError extends Error {\n constructor(message: string, public readonly code: string, public readonly path?: string) {\n super(message);\n this.name = 'OPFSError';\n }\n}\n\n/**\n * Error thrown when OPFS is not supported in the current browser\n */\nexport class OPFSNotSupportedError extends OPFSError {\n constructor() {\n super('OPFS is not supported in this browser', 'OPFS_NOT_SUPPORTED');\n }\n}\n\n\n/**\n * Error thrown when OPFS is not mounted\n */\nexport class OPFSNotMountedError extends OPFSError {\n constructor() {\n super('OPFS is not mounted', 'OPFS_NOT_MOUNTED');\n }\n}\n\n/**\n * Error thrown for invalid paths or path traversal attempts\n */\nexport class PathError extends OPFSError {\n constructor(message: string, path: string) {\n super(message, 'INVALID_PATH', path);\n }\n}\n\n/**\n * Error thrown when a requested file doesn't exist\n */\nexport class FileNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`File not found: ${ path }`, 'FILE_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when a requested directory doesn't exist\n */\nexport class DirectoryNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`Directory not found: ${ path }`, 'DIRECTORY_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when permission is denied for an operation\n */\nexport class PermissionError extends OPFSError {\n constructor(path: string, operation: string) {\n super(`Permission denied for ${ operation } on: ${ path }`, 'PERMISSION_DENIED', path);\n }\n}\n\n/**\n * Error thrown when an operation fails due to insufficient storage\n */\nexport class StorageError extends OPFSError {\n constructor(message: string, path?: string) {\n super(message, 'STORAGE_ERROR', path);\n }\n}\n\n/**\n * Error thrown when an operation times out\n */\nexport class TimeoutError extends OPFSError {\n constructor(operation: string, path?: string) {\n super(`Operation timed out: ${ operation }`, 'TIMEOUT_ERROR', path);\n }\n}\n","import { OPFSError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\nexport function encodeString(data: string, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextEncoder().encode(data);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return encodeUtf16LE(data);\n\n case 'ascii':\n return encodeAscii(data);\n\n case 'latin1':\n return encodeLatin1(data);\n\n case 'binary':\n return Uint8Array.from(data, char => char.charCodeAt(0));\n\n case 'base64':\n return Uint8Array.from(atob(data), c => c.charCodeAt(0));\n\n case 'hex':\n if (!/^[\\da-f]+$/i.test(data) || data.length % 2 !== 0) {\n throw new OPFSError('Invalid hex string', 'INVALID_HEX_FORMAT');\n }\n\n return Uint8Array.from(data.match(/.{1,2}/g)!.map(b => parseInt(b, 16)));\n\n default:\n console.warn('Encoding not supported, falling back to UTF-8');\n\n return new TextEncoder().encode(data);\n }\n}\n\nexport function decodeBuffer(buffer: Uint8Array, encoding: BufferEncoding = 'utf-8'): string {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextDecoder().decode(buffer);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return decodeUtf16LE(buffer);\n\n case 'latin1':\n return String.fromCharCode(...buffer);\n\n case 'binary':\n return String.fromCharCode(...buffer);\n\n case 'ascii':\n return String.fromCharCode(...buffer.map(b => b & 0x7F));\n\n case 'base64':\n return btoa(String.fromCharCode(...buffer));\n\n case 'hex':\n return Array.from(buffer).map(b => b.toString(16).padStart(2, '0')).join('');\n\n default:\n console.warn('Unsupported encoding, falling back to UTF-8');\n\n return new TextDecoder().decode(buffer);\n }\n}\n\nfunction encodeUtf16LE(str: string): Uint8Array {\n const buf = new Uint8Array(str.length * 2);\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n buf[(i * 2)] = code & 0xFF;\n buf[(i * 2) + 1] = code >> 8;\n }\n\n return buf;\n}\n\nfunction decodeUtf16LE(buf: Uint8Array): string {\n if (buf.length % 2 !== 0) {\n console.warn('Invalid UTF-16LE buffer length, truncating last byte');\n buf = buf.slice(0, buf.length - 1);\n }\n\n const codeUnits = new Uint16Array(buf.buffer, buf.byteOffset, buf.byteLength / 2);\n\n return String.fromCharCode(...codeUnits);\n}\n\nfunction encodeLatin1(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0xFF;\n }\n\n return buf;\n}\n\nfunction encodeAscii(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0x7F;\n }\n\n return buf;\n}\n","import { encodeString } from './encoder';\nimport { OPFSError, OPFSNotSupportedError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\n/**\n * Check if the browser supports the OPFS API\n * \n * @throws {OPFSNotSupportedError} If the browser does not support the OPFS API\n */\nexport function checkOPFSSupport(): void {\n if (!('storage' in navigator) || !('getDirectory' in (navigator.storage as any))) {\n throw new OPFSNotSupportedError();\n }\n}\n\n/** \n * Split a path into an array of segments\n * \n * @param path - The path to split\n * @returns The array of segments\n */\nexport function splitPath(path: string | string[]): string[] {\n if (Array.isArray(path)) {\n return path;\n }\n\n return path.split('/').filter(Boolean);\n}\n\n\n/**\n * Join an array of path segments into a single path\n * \n * @param segments - The array of path segments\n * @returns The joined path\n */\nexport function joinPath(segments: string[] | string): string {\n return typeof segments === 'string'\n ? (segments ?? '/')\n : `/${ segments.join('/') }`;\n}\n\n/**\n * Extract the filename from a path\n * \n * @param path - The file path\n * @returns The filename without the directory path\n * \n * @example\n * ```typescript\n * basename('/path/to/file.txt'); // 'file.txt'\n * basename('/path/to/directory/'); // ''\n * basename('file.txt'); // 'file.txt'\n * ```\n */\nexport function basename(path: string): string {\n const segments = splitPath(path);\n return segments[segments.length - 1] || '';\n}\n\n/**\n * Extract the directory path from a file path\n * \n * @param path - The file path\n * @returns The directory path without the filename\n * \n * @example\n * ```typescript\n * dirname('/path/to/file.txt'); // '/path/to'\n * dirname('/path/to/directory/'); // '/path/to/directory'\n * dirname('file.txt'); // '/'\n * ```\n */\nexport function dirname(path: string): string {\n const segments = splitPath(path);\n segments.pop();\n return joinPath(segments);\n}\n\n/**\n * Normalize a path to ensure it starts with '/'\n * \n * @param path - The path to normalize\n * @returns The normalized path\n * \n * @example\n * ```typescript\n * normalizePath('path/to/file'); // '/path/to/file'\n * normalizePath('/path/to/file'); // '/path/to/file'\n * normalizePath(''); // '/'\n * ```\n */\nexport function normalizePath(path: string): string {\n if (!path || path === '/') {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Resolve a path to an absolute path, handling relative segments\n * \n * @param path - The path to resolve\n * @returns The resolved absolute path\n * \n * @example\n * ```typescript\n * resolvePath('./config/../data/file.txt'); // '/data/file.txt'\n * resolvePath('/path/to/../file.txt'); // '/path/file.txt'\n * resolvePath('../../file.txt'); // '/file.txt' (truncated to root)\n * ```\n */\nexport function resolvePath(path: string): string {\n const segments = splitPath(path);\n const normalizedSegments: string[] = [];\n\n for (const segment of segments) {\n if (segment === '.' || segment === '') {\n // Skip current directory references and empty segments\n continue;\n }\n else if (segment === '..') {\n if (normalizedSegments.length === 0) {\n // Path escapes root, keep at root level\n continue;\n }\n // Go up one directory\n normalizedSegments.pop();\n }\n else {\n normalizedSegments.push(segment);\n }\n }\n\n return joinPath(normalizedSegments);\n}\n\n/**\n * Get the file extension from a path\n * \n * @param path - The file path\n * @returns The file extension including the dot, or empty string if no extension\n * \n * @example\n * ```typescript\n * extname('/path/to/file.txt'); // '.txt'\n * extname('/path/to/file'); // ''\n * extname('/path/to/file.name.ext'); // '.ext'\n * extname('/path/to/.hidden'); // ''\n * ```\n */\nexport function extname(path: string): string {\n const filename = basename(path);\n const lastDotIndex = filename.lastIndexOf('.');\n \n if (lastDotIndex <= 0 || lastDotIndex === filename.length - 1) {\n return '';\n }\n \n return filename.slice(lastDotIndex);\n}\n\nexport function createBuffer(data: string | Uint8Array | ArrayBuffer, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n if (typeof data === 'string') {\n return encodeString(data, encoding);\n }\n\n return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\n\n/**\n * Read raw binary data from a file using a file handle\n *\n * @param fileHandle - The file handle to read from\n * @returns The raw binary data as Uint8Array\n */\nexport async function readFileData(fileHandle: FileSystemFileHandle): Promise<Uint8Array> {\n const handle = await fileHandle.createSyncAccessHandle();\n\n try {\n const size = handle.getSize();\n const buffer = new Uint8Array(size);\n\n handle.read(buffer, { at: 0 });\n\n return buffer;\n }\n finally {\n handle.close();\n }\n}\n\n/**\n * Write data to a file using a file handle\n *\n * @param fileHandle - The file handle to write to\n * @param data - The data to write to the file\n * @param encoding - The encoding to use\n * @param options - Write options (truncate or append)\n */\nexport async function writeFileData(\n fileHandle: FileSystemFileHandle,\n data: string | Uint8Array | ArrayBuffer,\n encoding?: BufferEncoding,\n options: { truncate?: boolean; append?: boolean } = {}\n): Promise<void> {\n let handle: FileSystemSyncAccessHandle | null = null;\n\n try {\n handle = await fileHandle.createSyncAccessHandle();\n\n const buffer = createBuffer(data, encoding);\n const writeOffset = options.append ? handle.getSize() : 0;\n\n handle.write(buffer, { at: writeOffset });\n\n if (options.truncate && !options.append) {\n handle.truncate(buffer.byteLength);\n }\n\n handle.flush();\n }\n catch (error) {\n console.error(error);\n const operation = options.append ? 'append' : 'write';\n\n throw new OPFSError(`Failed to ${ operation } file`, `${ operation.toUpperCase() }_FAILED`);\n }\n finally {\n if (handle) {\n try {\n handle.close();\n }\n catch { /* ~ */ }\n }\n }\n}\n\n/**\n * Calculate file hash using Web Crypto API\n * \n * @param buffer - The file content as Uint8Array\n * @param algorithm - Hash algorithm to use (default: 'SHA-1')\n * @returns Promise that resolves to the hash string\n */\nexport async function calculateFileHash(buffer: Uint8Array, algorithm: string = 'SHA-1'): Promise<string> {\n try {\n const bufferSource = new Uint8Array(buffer);\n const hashBuffer = await crypto.subtle.digest(algorithm, bufferSource);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n }\n catch (error) {\n console.warn(`Failed to calculate ${ algorithm } hash:`, error);\n\n throw error;\n }\n}\n\n/**\n * Convert a Blob to Uint8Array\n * \n * This function converts a Blob object to a Uint8Array for use with file operations.\n * It's useful when working with file uploads or other Blob data sources.\n * \n * @param blob - The Blob to convert\n * @returns Promise that resolves to the Uint8Array representation of the Blob\n * \n * @example\n * ```typescript\n * const fileInput = document.getElementById('file') as HTMLInputElement;\n * const file = fileInput.files?.[0];\n * if (file) {\n * const data = await convertBlobToUint8Array(file);\n * await fs.writeFile('/uploaded-file', data);\n * }\n * ```\n */\nexport async function convertBlobToUint8Array(blob: Blob): Promise<Uint8Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n}\n"],"names":["OPFSError","message","code","path","OPFSNotSupportedError","OPFSNotMountedError","PathError","FileNotFoundError","DirectoryNotFoundError","PermissionError","operation","StorageError","TimeoutError","encodeString","data","encoding","encodeUtf16LE","encodeAscii","encodeLatin1","char","c","b","decodeBuffer","buffer","decodeUtf16LE","str","buf","i","codeUnits","checkOPFSSupport","splitPath","joinPath","segments","basename","dirname","normalizePath","resolvePath","normalizedSegments","segment","extname","filename","lastDotIndex","createBuffer","readFileData","fileHandle","handle","size","writeFileData","options","writeOffset","error","calculateFileHash","algorithm","bufferSource","hashBuffer","convertBlobToUint8Array","blob","arrayBuffer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers-C0nyU6hv.js","sources":["../src/utils/errors.ts","../src/utils/encoder.ts","../src/utils/helpers.ts"],"sourcesContent":["/**\n * Base error class for all OPFS-related errors\n */\nexport class OPFSError extends Error {\n constructor(message: string, public readonly code: string, public readonly path?: string) {\n super(message);\n this.name = 'OPFSError';\n }\n}\n\n/**\n * Error thrown when OPFS is not supported in the current browser\n */\nexport class OPFSNotSupportedError extends OPFSError {\n constructor() {\n super('OPFS is not supported in this browser', 'OPFS_NOT_SUPPORTED');\n }\n}\n\n\n/**\n * Error thrown when OPFS is not mounted\n */\nexport class OPFSNotMountedError extends OPFSError {\n constructor() {\n super('OPFS is not mounted', 'OPFS_NOT_MOUNTED');\n }\n}\n\n/**\n * Error thrown for invalid paths or path traversal attempts\n */\nexport class PathError extends OPFSError {\n constructor(message: string, path: string) {\n super(message, 'INVALID_PATH', path);\n }\n}\n\n/**\n * Error thrown when a requested file doesn't exist\n */\nexport class FileNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`File not found: ${ path }`, 'FILE_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when a requested directory doesn't exist\n */\nexport class DirectoryNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`Directory not found: ${ path }`, 'DIRECTORY_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when permission is denied for an operation\n */\nexport class PermissionError extends OPFSError {\n constructor(path: string, operation: string) {\n super(`Permission denied for ${ operation } on: ${ path }`, 'PERMISSION_DENIED', path);\n }\n}\n\n/**\n * Error thrown when an operation fails due to insufficient storage\n */\nexport class StorageError extends OPFSError {\n constructor(message: string, path?: string) {\n super(message, 'STORAGE_ERROR', path);\n }\n}\n\n/**\n * Error thrown when an operation times out\n */\nexport class TimeoutError extends OPFSError {\n constructor(operation: string, path?: string) {\n super(`Operation timed out: ${ operation }`, 'TIMEOUT_ERROR', path);\n }\n}\n","import { OPFSError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\nexport function encodeString(data: string, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextEncoder().encode(data);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return encodeUtf16LE(data);\n\n case 'ascii':\n return encodeAscii(data);\n\n case 'latin1':\n return encodeLatin1(data);\n\n case 'binary':\n return Uint8Array.from(data, char => char.charCodeAt(0));\n\n case 'base64':\n return Uint8Array.from(atob(data), c => c.charCodeAt(0));\n\n case 'hex':\n if (!/^[\\da-f]+$/i.test(data) || data.length % 2 !== 0) {\n throw new OPFSError('Invalid hex string', 'INVALID_HEX_FORMAT');\n }\n\n return Uint8Array.from(data.match(/.{1,2}/g)!.map(b => parseInt(b, 16)));\n\n default:\n console.warn('Encoding not supported, falling back to UTF-8');\n\n return new TextEncoder().encode(data);\n }\n}\n\nexport function decodeBuffer(buffer: Uint8Array, encoding: BufferEncoding = 'utf-8'): string {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextDecoder().decode(buffer);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return decodeUtf16LE(buffer);\n\n case 'latin1':\n return String.fromCharCode(...buffer);\n\n case 'binary':\n return String.fromCharCode(...buffer);\n\n case 'ascii':\n return String.fromCharCode(...buffer.map(b => b & 0x7F));\n\n case 'base64':\n return btoa(String.fromCharCode(...buffer));\n\n case 'hex':\n return Array.from(buffer).map(b => b.toString(16).padStart(2, '0')).join('');\n\n default:\n console.warn('Unsupported encoding, falling back to UTF-8');\n\n return new TextDecoder().decode(buffer);\n }\n}\n\nfunction encodeUtf16LE(str: string): Uint8Array {\n const buf = new Uint8Array(str.length * 2);\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n buf[(i * 2)] = code & 0xFF;\n buf[(i * 2) + 1] = code >> 8;\n }\n\n return buf;\n}\n\nfunction decodeUtf16LE(buf: Uint8Array): string {\n if (buf.length % 2 !== 0) {\n console.warn('Invalid UTF-16LE buffer length, truncating last byte');\n buf = buf.slice(0, buf.length - 1);\n }\n\n const codeUnits = new Uint16Array(buf.buffer, buf.byteOffset, buf.byteLength / 2);\n\n return String.fromCharCode(...codeUnits);\n}\n\nfunction encodeLatin1(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0xFF;\n }\n\n return buf;\n}\n\nfunction encodeAscii(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0x7F;\n }\n\n return buf;\n}\n","import { encodeString } from './encoder';\nimport { OPFSError, OPFSNotSupportedError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\n/**\n * Check if the browser supports the OPFS API\n * \n * @throws {OPFSNotSupportedError} If the browser does not support the OPFS API\n */\nexport function checkOPFSSupport(): void {\n if (!('storage' in navigator) || !('getDirectory' in (navigator.storage as any))) {\n throw new OPFSNotSupportedError();\n }\n}\n\n/** \n * Split a path into an array of segments\n * \n * @param path - The path to split\n * @returns The array of segments\n */\nexport function splitPath(path: string | string[]): string[] {\n if (Array.isArray(path)) {\n return path;\n }\n\n return path.split('/').filter(Boolean);\n}\n\n\n/**\n * Join an array of path segments into a single path\n * \n * @param segments - The array of path segments\n * @returns The joined path\n */\nexport function joinPath(segments: string[] | string): string {\n return typeof segments === 'string'\n ? (segments ?? '/')\n : `/${ segments.join('/') }`;\n}\n\n/**\n * Extract the filename from a path\n * \n * @param path - The file path\n * @returns The filename without the directory path\n * \n * @example\n * ```typescript\n * basename('/path/to/file.txt'); // 'file.txt'\n * basename('/path/to/directory/'); // ''\n * basename('file.txt'); // 'file.txt'\n * ```\n */\nexport function basename(path: string): string {\n const segments = splitPath(path);\n return segments[segments.length - 1] || '';\n}\n\n/**\n * Extract the directory path from a file path\n * \n * @param path - The file path\n * @returns The directory path without the filename\n * \n * @example\n * ```typescript\n * dirname('/path/to/file.txt'); // '/path/to'\n * dirname('/path/to/directory/'); // '/path/to/directory'\n * dirname('file.txt'); // '/'\n * ```\n */\nexport function dirname(path: string): string {\n const segments = splitPath(path);\n segments.pop();\n return joinPath(segments);\n}\n\n/**\n * Normalize a path to ensure it starts with '/'\n * \n * @param path - The path to normalize\n * @returns The normalized path\n * \n * @example\n * ```typescript\n * normalizePath('path/to/file'); // '/path/to/file'\n * normalizePath('/path/to/file'); // '/path/to/file'\n * normalizePath(''); // '/'\n * ```\n */\nexport function normalizePath(path: string): string {\n if (!path || path === '/') {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Resolve a path to an absolute path, handling relative segments\n * \n * @param path - The path to resolve\n * @returns The resolved absolute path\n * \n * @example\n * ```typescript\n * resolvePath('./config/../data/file.txt'); // '/data/file.txt'\n * resolvePath('/path/to/../file.txt'); // '/path/file.txt'\n * resolvePath('../../file.txt'); // '/file.txt' (truncated to root)\n * ```\n */\nexport function resolvePath(path: string): string {\n const segments = splitPath(path);\n const normalizedSegments: string[] = [];\n\n for (const segment of segments) {\n if (segment === '.' || segment === '') {\n // Skip current directory references and empty segments\n continue;\n }\n else if (segment === '..') {\n if (normalizedSegments.length === 0) {\n // Path escapes root, keep at root level\n continue;\n }\n // Go up one directory\n normalizedSegments.pop();\n }\n else {\n normalizedSegments.push(segment);\n }\n }\n\n return joinPath(normalizedSegments);\n}\n\n/**\n * Get the file extension from a path\n * \n * @param path - The file path\n * @returns The file extension including the dot, or empty string if no extension\n * \n * @example\n * ```typescript\n * extname('/path/to/file.txt'); // '.txt'\n * extname('/path/to/file'); // ''\n * extname('/path/to/file.name.ext'); // '.ext'\n * extname('/path/to/.hidden'); // ''\n * ```\n */\nexport function extname(path: string): string {\n const filename = basename(path);\n const lastDotIndex = filename.lastIndexOf('.');\n \n if (lastDotIndex <= 0 || lastDotIndex === filename.length - 1) {\n return '';\n }\n \n return filename.slice(lastDotIndex);\n}\n\nexport function createBuffer(data: string | Uint8Array | ArrayBuffer, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n if (typeof data === 'string') {\n return encodeString(data, encoding);\n }\n\n return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\n\n/**\n * Read raw binary data from a file using a file handle\n *\n * @param fileHandle - The file handle to read from\n * @returns The raw binary data as Uint8Array\n */\nexport async function readFileData(fileHandle: FileSystemFileHandle): Promise<Uint8Array> {\n const handle = await fileHandle.createSyncAccessHandle();\n\n try {\n const size = handle.getSize();\n const buffer = new Uint8Array(size);\n\n handle.read(buffer, { at: 0 });\n\n return buffer;\n }\n finally {\n handle.close();\n }\n}\n\n/**\n * Write data to a file using a file handle\n *\n * @param fileHandle - The file handle to write to\n * @param data - The data to write to the file\n * @param encoding - The encoding to use\n * @param options - Write options (truncate or append)\n */\nexport async function writeFileData(\n fileHandle: FileSystemFileHandle,\n data: string | Uint8Array | ArrayBuffer,\n encoding?: BufferEncoding,\n options: { truncate?: boolean; append?: boolean } = {}\n): Promise<void> {\n let handle: FileSystemSyncAccessHandle | null = null;\n\n try {\n handle = await fileHandle.createSyncAccessHandle();\n\n const buffer = createBuffer(data, encoding);\n const writeOffset = options.append ? handle.getSize() : 0;\n\n handle.write(buffer, { at: writeOffset });\n\n if (options.truncate && !options.append) {\n handle.truncate(buffer.byteLength);\n }\n\n handle.flush();\n }\n catch (error) {\n console.error(error);\n const operation = options.append ? 'append' : 'write';\n\n throw new OPFSError(`Failed to ${ operation } file`, `${ operation.toUpperCase() }_FAILED`);\n }\n finally {\n if (handle) {\n try {\n handle.close();\n }\n catch { /* ~ */ }\n }\n }\n}\n\n/**\n * Calculate file hash using Web Crypto API\n * \n * @param buffer - The file content as File, ArrayBuffer, or Uint8Array\n * @param algorithm - Hash algorithm to use (default: 'SHA-1')\n * @param maxSize - Maximum file size in bytes. If file is larger, throws error (default: 50MB)\n * @returns Promise that resolves to the hash string\n * @throws Error if file size exceeds maxSize\n */\nexport async function calculateFileHash(\n buffer: File | ArrayBuffer | Uint8Array, \n algorithm: string = 'SHA-1',\n maxSize: number = 50 * 1024 * 1024 // 50MB default\n): Promise<string> {\n if (buffer instanceof File) {\n buffer = await buffer.arrayBuffer();\n }\n \n // Check file size before processing\n if (buffer.byteLength > maxSize) {\n throw new Error(`File size ${buffer.byteLength} bytes exceeds maximum allowed size ${maxSize} bytes`);\n }\n\n const bufferSource = new Uint8Array(buffer);\n const hashBuffer = await crypto.subtle.digest(algorithm, bufferSource);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Convert a Blob to Uint8Array\n * \n * This function converts a Blob object to a Uint8Array for use with file operations.\n * It's useful when working with file uploads or other Blob data sources.\n * \n * @param blob - The Blob to convert\n * @returns Promise that resolves to the Uint8Array representation of the Blob\n * \n * @example\n * ```typescript\n * const fileInput = document.getElementById('file') as HTMLInputElement;\n * const file = fileInput.files?.[0];\n * if (file) {\n * const data = await convertBlobToUint8Array(file);\n * await fs.writeFile('/uploaded-file', data);\n * }\n * ```\n */\nexport async function convertBlobToUint8Array(blob: Blob): Promise<Uint8Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n}\n"],"names":["OPFSError","message","code","path","OPFSNotSupportedError","OPFSNotMountedError","PathError","FileNotFoundError","DirectoryNotFoundError","PermissionError","operation","StorageError","TimeoutError","encodeString","data","encoding","encodeUtf16LE","encodeAscii","encodeLatin1","char","c","b","decodeBuffer","buffer","decodeUtf16LE","str","buf","i","codeUnits","checkOPFSSupport","splitPath","joinPath","segments","basename","dirname","normalizePath","resolvePath","normalizedSegments","segment","extname","filename","lastDotIndex","createBuffer","readFileData","fileHandle","handle","size","writeFileData","options","writeOffset","error","calculateFileHash","algorithm","maxSize","bufferSource","hashBuffer","convertBlobToUint8Array","blob","arrayBuffer"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";class o extends Error{constructor(r,t,n){super(r),this.code=t,this.path=n,this.name="OPFSError"}}class l extends o{constructor(){super("OPFS is not supported in this browser","OPFS_NOT_SUPPORTED")}}class y extends o{constructor(){super("OPFS is not mounted","OPFS_NOT_MOUNTED")}}class g extends o{constructor(r,t){super(r,"INVALID_PATH",t)}}class p extends o{constructor(r){super(`File not found: ${r}`,"FILE_NOT_FOUND",r)}}class E extends o{constructor(r){super(`Directory not found: ${r}`,"DIRECTORY_NOT_FOUND",r)}}class S extends o{constructor(r,t){super(`Permission denied for ${t} on: ${r}`,"PERMISSION_DENIED",r)}}class m extends o{constructor(r,t){super(r,"STORAGE_ERROR",t)}}class w extends o{constructor(r,t){super(`Operation timed out: ${r}`,"TIMEOUT_ERROR",t)}}function f(e,r="utf-8"){switch(r){case"utf8":case"utf-8":return new TextEncoder().encode(e);case"utf16le":case"ucs2":case"ucs-2":return A(e);case"ascii":return U(e);case"latin1":return P(e);case"binary":return Uint8Array.from(e,t=>t.charCodeAt(0));case"base64":return Uint8Array.from(atob(e),t=>t.charCodeAt(0));case"hex":if(!/^[\da-f]+$/i.test(e)||e.length%2!==0)throw new o("Invalid hex string","INVALID_HEX_FORMAT");return Uint8Array.from(e.match(/.{1,2}/g).map(t=>parseInt(t,16)));default:return console.warn("Encoding not supported, falling back to UTF-8"),new TextEncoder().encode(e)}}function F(e,r="utf-8"){switch(r){case"utf8":case"utf-8":return new TextDecoder().decode(e);case"utf16le":case"ucs2":case"ucs-2":return O(e);case"latin1":return String.fromCharCode(...e);case"binary":return String.fromCharCode(...e);case"ascii":return String.fromCharCode(...e.map(t=>t&127));case"base64":return btoa(String.fromCharCode(...e));case"hex":return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("");default:return console.warn("Unsupported encoding, falling back to UTF-8"),new TextDecoder().decode(e)}}function A(e){const r=new Uint8Array(e.length*2);for(let t=0;t<e.length;t++){const n=e.charCodeAt(t);r[t*2]=n&255,r[t*2+1]=n>>8}return r}function O(e){e.length%2!==0&&(console.warn("Invalid UTF-16LE buffer length, truncating last byte"),e=e.slice(0,e.length-1));const r=new Uint16Array(e.buffer,e.byteOffset,e.byteLength/2);return String.fromCharCode(...r)}function P(e){const r=new Uint8Array(e.length);for(let t=0;t<e.length;t++)r[t]=e.charCodeAt(t)&255;return r}function U(e){const r=new Uint8Array(e.length);for(let t=0;t<e.length;t++)r[t]=e.charCodeAt(t)&127;return r}function T(){if(!("storage"in navigator)||!("getDirectory"in navigator.storage))throw new l}function a(e){return Array.isArray(e)?e:e.split("/").filter(Boolean)}function u(e){return typeof e=="string"?e??"/":`/${e.join("/")}`}function d(e){const r=a(e);return r[r.length-1]||""}function x(e){const r=a(e);return r.pop(),u(r)}function D(e){return!e||e==="/"?"/":e.startsWith("/")?e:`/${e}`}function N(e){const r=a(e),t=[];for(const n of r)if(!(n==="."||n===""))if(n===".."){if(t.length===0)continue;t.pop()}else t.push(n);return u(t)}function C(e){const r=d(e),t=r.lastIndexOf(".");return t<=0||t===r.length-1?"":r.slice(t)}function h(e,r="utf-8"){return typeof e=="string"?f(e,r):e instanceof Uint8Array?e:new Uint8Array(e)}async function I(e){const r=await e.createSyncAccessHandle();try{const t=r.getSize(),n=new Uint8Array(t);return r.read(n,{at:0}),n}finally{r.close()}}async function _(e,r,t,n={}){let c=null;try{c=await e.createSyncAccessHandle();const i=h(r,t),s=n.append?c.getSize():0;c.write(i,{at:s}),n.truncate&&!n.append&&c.truncate(i.byteLength),c.flush()}catch(i){console.error(i);const s=n.append?"append":"write";throw new o(`Failed to ${s} file`,`${s.toUpperCase()}_FAILED`)}finally{if(c)try{c.close()}catch{}}}async function b(e,r="SHA-1",t=50*1024*1024){if(e instanceof File&&(e=await e.arrayBuffer()),e.byteLength>t)throw new Error(`File size ${e.byteLength} bytes exceeds maximum allowed size ${t} bytes`);const n=new Uint8Array(e),c=await crypto.subtle.digest(r,n);return Array.from(new Uint8Array(c)).map(s=>s.toString(16).padStart(2,"0")).join("")}async function L(e){const r=await e.arrayBuffer();return new Uint8Array(r)}exports.DirectoryNotFoundError=E;exports.FileNotFoundError=p;exports.OPFSError=o;exports.OPFSNotMountedError=y;exports.OPFSNotSupportedError=l;exports.PathError=g;exports.PermissionError=S;exports.StorageError=m;exports.TimeoutError=w;exports.basename=d;exports.calculateFileHash=b;exports.checkOPFSSupport=T;exports.convertBlobToUint8Array=L;exports.createBuffer=h;exports.decodeBuffer=F;exports.dirname=x;exports.encodeString=f;exports.extname=C;exports.joinPath=u;exports.normalizePath=D;exports.readFileData=I;exports.resolvePath=N;exports.splitPath=a;exports.writeFileData=_;
|
|
2
|
+
//# sourceMappingURL=helpers-FvdHLObV.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers-hEpet7x7.cjs","sources":["../src/utils/errors.ts","../src/utils/encoder.ts","../src/utils/helpers.ts"],"sourcesContent":["/**\n * Base error class for all OPFS-related errors\n */\nexport class OPFSError extends Error {\n constructor(message: string, public readonly code: string, public readonly path?: string) {\n super(message);\n this.name = 'OPFSError';\n }\n}\n\n/**\n * Error thrown when OPFS is not supported in the current browser\n */\nexport class OPFSNotSupportedError extends OPFSError {\n constructor() {\n super('OPFS is not supported in this browser', 'OPFS_NOT_SUPPORTED');\n }\n}\n\n\n/**\n * Error thrown when OPFS is not mounted\n */\nexport class OPFSNotMountedError extends OPFSError {\n constructor() {\n super('OPFS is not mounted', 'OPFS_NOT_MOUNTED');\n }\n}\n\n/**\n * Error thrown for invalid paths or path traversal attempts\n */\nexport class PathError extends OPFSError {\n constructor(message: string, path: string) {\n super(message, 'INVALID_PATH', path);\n }\n}\n\n/**\n * Error thrown when a requested file doesn't exist\n */\nexport class FileNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`File not found: ${ path }`, 'FILE_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when a requested directory doesn't exist\n */\nexport class DirectoryNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`Directory not found: ${ path }`, 'DIRECTORY_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when permission is denied for an operation\n */\nexport class PermissionError extends OPFSError {\n constructor(path: string, operation: string) {\n super(`Permission denied for ${ operation } on: ${ path }`, 'PERMISSION_DENIED', path);\n }\n}\n\n/**\n * Error thrown when an operation fails due to insufficient storage\n */\nexport class StorageError extends OPFSError {\n constructor(message: string, path?: string) {\n super(message, 'STORAGE_ERROR', path);\n }\n}\n\n/**\n * Error thrown when an operation times out\n */\nexport class TimeoutError extends OPFSError {\n constructor(operation: string, path?: string) {\n super(`Operation timed out: ${ operation }`, 'TIMEOUT_ERROR', path);\n }\n}\n","import { OPFSError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\nexport function encodeString(data: string, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextEncoder().encode(data);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return encodeUtf16LE(data);\n\n case 'ascii':\n return encodeAscii(data);\n\n case 'latin1':\n return encodeLatin1(data);\n\n case 'binary':\n return Uint8Array.from(data, char => char.charCodeAt(0));\n\n case 'base64':\n return Uint8Array.from(atob(data), c => c.charCodeAt(0));\n\n case 'hex':\n if (!/^[\\da-f]+$/i.test(data) || data.length % 2 !== 0) {\n throw new OPFSError('Invalid hex string', 'INVALID_HEX_FORMAT');\n }\n\n return Uint8Array.from(data.match(/.{1,2}/g)!.map(b => parseInt(b, 16)));\n\n default:\n console.warn('Encoding not supported, falling back to UTF-8');\n\n return new TextEncoder().encode(data);\n }\n}\n\nexport function decodeBuffer(buffer: Uint8Array, encoding: BufferEncoding = 'utf-8'): string {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextDecoder().decode(buffer);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return decodeUtf16LE(buffer);\n\n case 'latin1':\n return String.fromCharCode(...buffer);\n\n case 'binary':\n return String.fromCharCode(...buffer);\n\n case 'ascii':\n return String.fromCharCode(...buffer.map(b => b & 0x7F));\n\n case 'base64':\n return btoa(String.fromCharCode(...buffer));\n\n case 'hex':\n return Array.from(buffer).map(b => b.toString(16).padStart(2, '0')).join('');\n\n default:\n console.warn('Unsupported encoding, falling back to UTF-8');\n\n return new TextDecoder().decode(buffer);\n }\n}\n\nfunction encodeUtf16LE(str: string): Uint8Array {\n const buf = new Uint8Array(str.length * 2);\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n buf[(i * 2)] = code & 0xFF;\n buf[(i * 2) + 1] = code >> 8;\n }\n\n return buf;\n}\n\nfunction decodeUtf16LE(buf: Uint8Array): string {\n if (buf.length % 2 !== 0) {\n console.warn('Invalid UTF-16LE buffer length, truncating last byte');\n buf = buf.slice(0, buf.length - 1);\n }\n\n const codeUnits = new Uint16Array(buf.buffer, buf.byteOffset, buf.byteLength / 2);\n\n return String.fromCharCode(...codeUnits);\n}\n\nfunction encodeLatin1(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0xFF;\n }\n\n return buf;\n}\n\nfunction encodeAscii(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0x7F;\n }\n\n return buf;\n}\n","import { encodeString } from './encoder';\nimport { OPFSError, OPFSNotSupportedError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\n/**\n * Check if the browser supports the OPFS API\n * \n * @throws {OPFSNotSupportedError} If the browser does not support the OPFS API\n */\nexport function checkOPFSSupport(): void {\n if (!('storage' in navigator) || !('getDirectory' in (navigator.storage as any))) {\n throw new OPFSNotSupportedError();\n }\n}\n\n/** \n * Split a path into an array of segments\n * \n * @param path - The path to split\n * @returns The array of segments\n */\nexport function splitPath(path: string | string[]): string[] {\n if (Array.isArray(path)) {\n return path;\n }\n\n return path.split('/').filter(Boolean);\n}\n\n\n/**\n * Join an array of path segments into a single path\n * \n * @param segments - The array of path segments\n * @returns The joined path\n */\nexport function joinPath(segments: string[] | string): string {\n return typeof segments === 'string'\n ? (segments ?? '/')\n : `/${ segments.join('/') }`;\n}\n\n/**\n * Extract the filename from a path\n * \n * @param path - The file path\n * @returns The filename without the directory path\n * \n * @example\n * ```typescript\n * basename('/path/to/file.txt'); // 'file.txt'\n * basename('/path/to/directory/'); // ''\n * basename('file.txt'); // 'file.txt'\n * ```\n */\nexport function basename(path: string): string {\n const segments = splitPath(path);\n return segments[segments.length - 1] || '';\n}\n\n/**\n * Extract the directory path from a file path\n * \n * @param path - The file path\n * @returns The directory path without the filename\n * \n * @example\n * ```typescript\n * dirname('/path/to/file.txt'); // '/path/to'\n * dirname('/path/to/directory/'); // '/path/to/directory'\n * dirname('file.txt'); // '/'\n * ```\n */\nexport function dirname(path: string): string {\n const segments = splitPath(path);\n segments.pop();\n return joinPath(segments);\n}\n\n/**\n * Normalize a path to ensure it starts with '/'\n * \n * @param path - The path to normalize\n * @returns The normalized path\n * \n * @example\n * ```typescript\n * normalizePath('path/to/file'); // '/path/to/file'\n * normalizePath('/path/to/file'); // '/path/to/file'\n * normalizePath(''); // '/'\n * ```\n */\nexport function normalizePath(path: string): string {\n if (!path || path === '/') {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Resolve a path to an absolute path, handling relative segments\n * \n * @param path - The path to resolve\n * @returns The resolved absolute path\n * \n * @example\n * ```typescript\n * resolvePath('./config/../data/file.txt'); // '/data/file.txt'\n * resolvePath('/path/to/../file.txt'); // '/path/file.txt'\n * resolvePath('../../file.txt'); // '/file.txt' (truncated to root)\n * ```\n */\nexport function resolvePath(path: string): string {\n const segments = splitPath(path);\n const normalizedSegments: string[] = [];\n\n for (const segment of segments) {\n if (segment === '.' || segment === '') {\n // Skip current directory references and empty segments\n continue;\n }\n else if (segment === '..') {\n if (normalizedSegments.length === 0) {\n // Path escapes root, keep at root level\n continue;\n }\n // Go up one directory\n normalizedSegments.pop();\n }\n else {\n normalizedSegments.push(segment);\n }\n }\n\n return joinPath(normalizedSegments);\n}\n\n/**\n * Get the file extension from a path\n * \n * @param path - The file path\n * @returns The file extension including the dot, or empty string if no extension\n * \n * @example\n * ```typescript\n * extname('/path/to/file.txt'); // '.txt'\n * extname('/path/to/file'); // ''\n * extname('/path/to/file.name.ext'); // '.ext'\n * extname('/path/to/.hidden'); // ''\n * ```\n */\nexport function extname(path: string): string {\n const filename = basename(path);\n const lastDotIndex = filename.lastIndexOf('.');\n \n if (lastDotIndex <= 0 || lastDotIndex === filename.length - 1) {\n return '';\n }\n \n return filename.slice(lastDotIndex);\n}\n\nexport function createBuffer(data: string | Uint8Array | ArrayBuffer, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n if (typeof data === 'string') {\n return encodeString(data, encoding);\n }\n\n return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\n\n/**\n * Read raw binary data from a file using a file handle\n *\n * @param fileHandle - The file handle to read from\n * @returns The raw binary data as Uint8Array\n */\nexport async function readFileData(fileHandle: FileSystemFileHandle): Promise<Uint8Array> {\n const handle = await fileHandle.createSyncAccessHandle();\n\n try {\n const size = handle.getSize();\n const buffer = new Uint8Array(size);\n\n handle.read(buffer, { at: 0 });\n\n return buffer;\n }\n finally {\n handle.close();\n }\n}\n\n/**\n * Write data to a file using a file handle\n *\n * @param fileHandle - The file handle to write to\n * @param data - The data to write to the file\n * @param encoding - The encoding to use\n * @param options - Write options (truncate or append)\n */\nexport async function writeFileData(\n fileHandle: FileSystemFileHandle,\n data: string | Uint8Array | ArrayBuffer,\n encoding?: BufferEncoding,\n options: { truncate?: boolean; append?: boolean } = {}\n): Promise<void> {\n let handle: FileSystemSyncAccessHandle | null = null;\n\n try {\n handle = await fileHandle.createSyncAccessHandle();\n\n const buffer = createBuffer(data, encoding);\n const writeOffset = options.append ? handle.getSize() : 0;\n\n handle.write(buffer, { at: writeOffset });\n\n if (options.truncate && !options.append) {\n handle.truncate(buffer.byteLength);\n }\n\n handle.flush();\n }\n catch (error) {\n console.error(error);\n const operation = options.append ? 'append' : 'write';\n\n throw new OPFSError(`Failed to ${ operation } file`, `${ operation.toUpperCase() }_FAILED`);\n }\n finally {\n if (handle) {\n try {\n handle.close();\n }\n catch { /* ~ */ }\n }\n }\n}\n\n/**\n * Calculate file hash using Web Crypto API\n * \n * @param buffer - The file content as Uint8Array\n * @param algorithm - Hash algorithm to use (default: 'SHA-1')\n * @returns Promise that resolves to the hash string\n */\nexport async function calculateFileHash(buffer: Uint8Array, algorithm: string = 'SHA-1'): Promise<string> {\n try {\n const bufferSource = new Uint8Array(buffer);\n const hashBuffer = await crypto.subtle.digest(algorithm, bufferSource);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n }\n catch (error) {\n console.warn(`Failed to calculate ${ algorithm } hash:`, error);\n\n throw error;\n }\n}\n\n/**\n * Convert a Blob to Uint8Array\n * \n * This function converts a Blob object to a Uint8Array for use with file operations.\n * It's useful when working with file uploads or other Blob data sources.\n * \n * @param blob - The Blob to convert\n * @returns Promise that resolves to the Uint8Array representation of the Blob\n * \n * @example\n * ```typescript\n * const fileInput = document.getElementById('file') as HTMLInputElement;\n * const file = fileInput.files?.[0];\n * if (file) {\n * const data = await convertBlobToUint8Array(file);\n * await fs.writeFile('/uploaded-file', data);\n * }\n * ```\n */\nexport async function convertBlobToUint8Array(blob: Blob): Promise<Uint8Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n}\n"],"names":["OPFSError","message","code","path","OPFSNotSupportedError","OPFSNotMountedError","PathError","FileNotFoundError","DirectoryNotFoundError","PermissionError","operation","StorageError","TimeoutError","encodeString","data","encoding","encodeUtf16LE","encodeAscii","encodeLatin1","char","c","b","decodeBuffer","buffer","decodeUtf16LE","str","buf","i","codeUnits","checkOPFSSupport","splitPath","joinPath","segments","basename","dirname","normalizePath","resolvePath","normalizedSegments","segment","extname","filename","lastDotIndex","createBuffer","readFileData","fileHandle","handle","size","writeFileData","options","writeOffset","error","calculateFileHash","algorithm","bufferSource","hashBuffer","convertBlobToUint8Array","blob","arrayBuffer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers-FvdHLObV.cjs","sources":["../src/utils/errors.ts","../src/utils/encoder.ts","../src/utils/helpers.ts"],"sourcesContent":["/**\n * Base error class for all OPFS-related errors\n */\nexport class OPFSError extends Error {\n constructor(message: string, public readonly code: string, public readonly path?: string) {\n super(message);\n this.name = 'OPFSError';\n }\n}\n\n/**\n * Error thrown when OPFS is not supported in the current browser\n */\nexport class OPFSNotSupportedError extends OPFSError {\n constructor() {\n super('OPFS is not supported in this browser', 'OPFS_NOT_SUPPORTED');\n }\n}\n\n\n/**\n * Error thrown when OPFS is not mounted\n */\nexport class OPFSNotMountedError extends OPFSError {\n constructor() {\n super('OPFS is not mounted', 'OPFS_NOT_MOUNTED');\n }\n}\n\n/**\n * Error thrown for invalid paths or path traversal attempts\n */\nexport class PathError extends OPFSError {\n constructor(message: string, path: string) {\n super(message, 'INVALID_PATH', path);\n }\n}\n\n/**\n * Error thrown when a requested file doesn't exist\n */\nexport class FileNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`File not found: ${ path }`, 'FILE_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when a requested directory doesn't exist\n */\nexport class DirectoryNotFoundError extends OPFSError {\n constructor(path: string) {\n super(`Directory not found: ${ path }`, 'DIRECTORY_NOT_FOUND', path);\n }\n}\n\n/**\n * Error thrown when permission is denied for an operation\n */\nexport class PermissionError extends OPFSError {\n constructor(path: string, operation: string) {\n super(`Permission denied for ${ operation } on: ${ path }`, 'PERMISSION_DENIED', path);\n }\n}\n\n/**\n * Error thrown when an operation fails due to insufficient storage\n */\nexport class StorageError extends OPFSError {\n constructor(message: string, path?: string) {\n super(message, 'STORAGE_ERROR', path);\n }\n}\n\n/**\n * Error thrown when an operation times out\n */\nexport class TimeoutError extends OPFSError {\n constructor(operation: string, path?: string) {\n super(`Operation timed out: ${ operation }`, 'TIMEOUT_ERROR', path);\n }\n}\n","import { OPFSError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\nexport function encodeString(data: string, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextEncoder().encode(data);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return encodeUtf16LE(data);\n\n case 'ascii':\n return encodeAscii(data);\n\n case 'latin1':\n return encodeLatin1(data);\n\n case 'binary':\n return Uint8Array.from(data, char => char.charCodeAt(0));\n\n case 'base64':\n return Uint8Array.from(atob(data), c => c.charCodeAt(0));\n\n case 'hex':\n if (!/^[\\da-f]+$/i.test(data) || data.length % 2 !== 0) {\n throw new OPFSError('Invalid hex string', 'INVALID_HEX_FORMAT');\n }\n\n return Uint8Array.from(data.match(/.{1,2}/g)!.map(b => parseInt(b, 16)));\n\n default:\n console.warn('Encoding not supported, falling back to UTF-8');\n\n return new TextEncoder().encode(data);\n }\n}\n\nexport function decodeBuffer(buffer: Uint8Array, encoding: BufferEncoding = 'utf-8'): string {\n switch (encoding) {\n case 'utf8':\n case 'utf-8':\n return new TextDecoder().decode(buffer);\n\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n return decodeUtf16LE(buffer);\n\n case 'latin1':\n return String.fromCharCode(...buffer);\n\n case 'binary':\n return String.fromCharCode(...buffer);\n\n case 'ascii':\n return String.fromCharCode(...buffer.map(b => b & 0x7F));\n\n case 'base64':\n return btoa(String.fromCharCode(...buffer));\n\n case 'hex':\n return Array.from(buffer).map(b => b.toString(16).padStart(2, '0')).join('');\n\n default:\n console.warn('Unsupported encoding, falling back to UTF-8');\n\n return new TextDecoder().decode(buffer);\n }\n}\n\nfunction encodeUtf16LE(str: string): Uint8Array {\n const buf = new Uint8Array(str.length * 2);\n\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n\n buf[(i * 2)] = code & 0xFF;\n buf[(i * 2) + 1] = code >> 8;\n }\n\n return buf;\n}\n\nfunction decodeUtf16LE(buf: Uint8Array): string {\n if (buf.length % 2 !== 0) {\n console.warn('Invalid UTF-16LE buffer length, truncating last byte');\n buf = buf.slice(0, buf.length - 1);\n }\n\n const codeUnits = new Uint16Array(buf.buffer, buf.byteOffset, buf.byteLength / 2);\n\n return String.fromCharCode(...codeUnits);\n}\n\nfunction encodeLatin1(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0xFF;\n }\n\n return buf;\n}\n\nfunction encodeAscii(str: string): Uint8Array {\n const buf = new Uint8Array(str.length);\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i) & 0x7F;\n }\n\n return buf;\n}\n","import { encodeString } from './encoder';\nimport { OPFSError, OPFSNotSupportedError } from './errors';\n\nimport type { BufferEncoding } from 'typescript';\n\n/**\n * Check if the browser supports the OPFS API\n * \n * @throws {OPFSNotSupportedError} If the browser does not support the OPFS API\n */\nexport function checkOPFSSupport(): void {\n if (!('storage' in navigator) || !('getDirectory' in (navigator.storage as any))) {\n throw new OPFSNotSupportedError();\n }\n}\n\n/** \n * Split a path into an array of segments\n * \n * @param path - The path to split\n * @returns The array of segments\n */\nexport function splitPath(path: string | string[]): string[] {\n if (Array.isArray(path)) {\n return path;\n }\n\n return path.split('/').filter(Boolean);\n}\n\n\n/**\n * Join an array of path segments into a single path\n * \n * @param segments - The array of path segments\n * @returns The joined path\n */\nexport function joinPath(segments: string[] | string): string {\n return typeof segments === 'string'\n ? (segments ?? '/')\n : `/${ segments.join('/') }`;\n}\n\n/**\n * Extract the filename from a path\n * \n * @param path - The file path\n * @returns The filename without the directory path\n * \n * @example\n * ```typescript\n * basename('/path/to/file.txt'); // 'file.txt'\n * basename('/path/to/directory/'); // ''\n * basename('file.txt'); // 'file.txt'\n * ```\n */\nexport function basename(path: string): string {\n const segments = splitPath(path);\n return segments[segments.length - 1] || '';\n}\n\n/**\n * Extract the directory path from a file path\n * \n * @param path - The file path\n * @returns The directory path without the filename\n * \n * @example\n * ```typescript\n * dirname('/path/to/file.txt'); // '/path/to'\n * dirname('/path/to/directory/'); // '/path/to/directory'\n * dirname('file.txt'); // '/'\n * ```\n */\nexport function dirname(path: string): string {\n const segments = splitPath(path);\n segments.pop();\n return joinPath(segments);\n}\n\n/**\n * Normalize a path to ensure it starts with '/'\n * \n * @param path - The path to normalize\n * @returns The normalized path\n * \n * @example\n * ```typescript\n * normalizePath('path/to/file'); // '/path/to/file'\n * normalizePath('/path/to/file'); // '/path/to/file'\n * normalizePath(''); // '/'\n * ```\n */\nexport function normalizePath(path: string): string {\n if (!path || path === '/') {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Resolve a path to an absolute path, handling relative segments\n * \n * @param path - The path to resolve\n * @returns The resolved absolute path\n * \n * @example\n * ```typescript\n * resolvePath('./config/../data/file.txt'); // '/data/file.txt'\n * resolvePath('/path/to/../file.txt'); // '/path/file.txt'\n * resolvePath('../../file.txt'); // '/file.txt' (truncated to root)\n * ```\n */\nexport function resolvePath(path: string): string {\n const segments = splitPath(path);\n const normalizedSegments: string[] = [];\n\n for (const segment of segments) {\n if (segment === '.' || segment === '') {\n // Skip current directory references and empty segments\n continue;\n }\n else if (segment === '..') {\n if (normalizedSegments.length === 0) {\n // Path escapes root, keep at root level\n continue;\n }\n // Go up one directory\n normalizedSegments.pop();\n }\n else {\n normalizedSegments.push(segment);\n }\n }\n\n return joinPath(normalizedSegments);\n}\n\n/**\n * Get the file extension from a path\n * \n * @param path - The file path\n * @returns The file extension including the dot, or empty string if no extension\n * \n * @example\n * ```typescript\n * extname('/path/to/file.txt'); // '.txt'\n * extname('/path/to/file'); // ''\n * extname('/path/to/file.name.ext'); // '.ext'\n * extname('/path/to/.hidden'); // ''\n * ```\n */\nexport function extname(path: string): string {\n const filename = basename(path);\n const lastDotIndex = filename.lastIndexOf('.');\n \n if (lastDotIndex <= 0 || lastDotIndex === filename.length - 1) {\n return '';\n }\n \n return filename.slice(lastDotIndex);\n}\n\nexport function createBuffer(data: string | Uint8Array | ArrayBuffer, encoding: BufferEncoding = 'utf-8'): Uint8Array {\n if (typeof data === 'string') {\n return encodeString(data, encoding);\n }\n\n return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\n\n/**\n * Read raw binary data from a file using a file handle\n *\n * @param fileHandle - The file handle to read from\n * @returns The raw binary data as Uint8Array\n */\nexport async function readFileData(fileHandle: FileSystemFileHandle): Promise<Uint8Array> {\n const handle = await fileHandle.createSyncAccessHandle();\n\n try {\n const size = handle.getSize();\n const buffer = new Uint8Array(size);\n\n handle.read(buffer, { at: 0 });\n\n return buffer;\n }\n finally {\n handle.close();\n }\n}\n\n/**\n * Write data to a file using a file handle\n *\n * @param fileHandle - The file handle to write to\n * @param data - The data to write to the file\n * @param encoding - The encoding to use\n * @param options - Write options (truncate or append)\n */\nexport async function writeFileData(\n fileHandle: FileSystemFileHandle,\n data: string | Uint8Array | ArrayBuffer,\n encoding?: BufferEncoding,\n options: { truncate?: boolean; append?: boolean } = {}\n): Promise<void> {\n let handle: FileSystemSyncAccessHandle | null = null;\n\n try {\n handle = await fileHandle.createSyncAccessHandle();\n\n const buffer = createBuffer(data, encoding);\n const writeOffset = options.append ? handle.getSize() : 0;\n\n handle.write(buffer, { at: writeOffset });\n\n if (options.truncate && !options.append) {\n handle.truncate(buffer.byteLength);\n }\n\n handle.flush();\n }\n catch (error) {\n console.error(error);\n const operation = options.append ? 'append' : 'write';\n\n throw new OPFSError(`Failed to ${ operation } file`, `${ operation.toUpperCase() }_FAILED`);\n }\n finally {\n if (handle) {\n try {\n handle.close();\n }\n catch { /* ~ */ }\n }\n }\n}\n\n/**\n * Calculate file hash using Web Crypto API\n * \n * @param buffer - The file content as File, ArrayBuffer, or Uint8Array\n * @param algorithm - Hash algorithm to use (default: 'SHA-1')\n * @param maxSize - Maximum file size in bytes. If file is larger, throws error (default: 50MB)\n * @returns Promise that resolves to the hash string\n * @throws Error if file size exceeds maxSize\n */\nexport async function calculateFileHash(\n buffer: File | ArrayBuffer | Uint8Array, \n algorithm: string = 'SHA-1',\n maxSize: number = 50 * 1024 * 1024 // 50MB default\n): Promise<string> {\n if (buffer instanceof File) {\n buffer = await buffer.arrayBuffer();\n }\n \n // Check file size before processing\n if (buffer.byteLength > maxSize) {\n throw new Error(`File size ${buffer.byteLength} bytes exceeds maximum allowed size ${maxSize} bytes`);\n }\n\n const bufferSource = new Uint8Array(buffer);\n const hashBuffer = await crypto.subtle.digest(algorithm, bufferSource);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Convert a Blob to Uint8Array\n * \n * This function converts a Blob object to a Uint8Array for use with file operations.\n * It's useful when working with file uploads or other Blob data sources.\n * \n * @param blob - The Blob to convert\n * @returns Promise that resolves to the Uint8Array representation of the Blob\n * \n * @example\n * ```typescript\n * const fileInput = document.getElementById('file') as HTMLInputElement;\n * const file = fileInput.files?.[0];\n * if (file) {\n * const data = await convertBlobToUint8Array(file);\n * await fs.writeFile('/uploaded-file', data);\n * }\n * ```\n */\nexport async function convertBlobToUint8Array(blob: Blob): Promise<Uint8Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n}\n"],"names":["OPFSError","message","code","path","OPFSNotSupportedError","OPFSNotMountedError","PathError","FileNotFoundError","DirectoryNotFoundError","PermissionError","operation","StorageError","TimeoutError","encodeString","data","encoding","encodeUtf16LE","encodeAscii","encodeLatin1","char","c","b","decodeBuffer","buffer","decodeUtf16LE","str","buf","i","codeUnits","checkOPFSSupport","splitPath","joinPath","segments","basename","dirname","normalizePath","resolvePath","normalizedSegments","segment","extname","filename","lastDotIndex","createBuffer","readFileData","fileHandle","handle","size","writeFileData","options","writeOffset","error","calculateFileHash","algorithm","maxSize","bufferSource","hashBuffer","convertBlobToUint8Array","blob","arrayBuffer"],"mappings":"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"}
|