@ricsam/quickjs-fs 0.2.0 → 0.2.2

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.
@@ -0,0 +1,221 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+
30
+ // packages/fs/src/node-adapter.ts
31
+ var exports_node_adapter = {};
32
+ __export(exports_node_adapter, {
33
+ createNodeDirectoryHandle: () => createNodeDirectoryHandle
34
+ });
35
+ module.exports = __toCommonJS(exports_node_adapter);
36
+
37
+ class NodeFileHandle {
38
+ name;
39
+ fullPath;
40
+ kind = "file";
41
+ constructor(name, fullPath) {
42
+ this.name = name;
43
+ this.fullPath = fullPath;
44
+ }
45
+ async getFile() {
46
+ const file = Bun.file(this.fullPath);
47
+ const buffer = await file.arrayBuffer();
48
+ const stat = await Bun.file(this.fullPath).stat();
49
+ return new File([buffer], this.name, {
50
+ type: file.type,
51
+ lastModified: stat?.mtime?.getTime() ?? Date.now()
52
+ });
53
+ }
54
+ async createWritable(options) {
55
+ return new NodeWritableFileStream(this.fullPath, options?.keepExistingData ?? false);
56
+ }
57
+ }
58
+
59
+ class NodeWritableFileStream {
60
+ path;
61
+ buffer;
62
+ position = 0;
63
+ constructor(path, keepExistingData) {
64
+ this.path = path;
65
+ if (keepExistingData) {
66
+ try {
67
+ const file = Bun.file(this.path);
68
+ this.buffer = new Uint8Array(0);
69
+ file.arrayBuffer().then((ab) => {
70
+ this.buffer = new Uint8Array(ab);
71
+ });
72
+ } catch {
73
+ this.buffer = new Uint8Array(0);
74
+ }
75
+ } else {
76
+ this.buffer = new Uint8Array(0);
77
+ }
78
+ }
79
+ async write(data) {
80
+ let bytes;
81
+ if (typeof data === "string") {
82
+ bytes = new TextEncoder().encode(data);
83
+ } else if (data instanceof ArrayBuffer) {
84
+ bytes = new Uint8Array(data);
85
+ } else if (data instanceof Uint8Array) {
86
+ bytes = data;
87
+ } else if (data instanceof Blob) {
88
+ bytes = new Uint8Array(await data.arrayBuffer());
89
+ } else {
90
+ if (data.type === "seek") {
91
+ this.position = data.position ?? 0;
92
+ return;
93
+ }
94
+ if (data.type === "truncate") {
95
+ this.buffer = this.buffer.slice(0, data.size ?? 0);
96
+ if (this.position > this.buffer.length) {
97
+ this.position = this.buffer.length;
98
+ }
99
+ return;
100
+ }
101
+ if (data.data === undefined)
102
+ return;
103
+ return this.write(data.data);
104
+ }
105
+ const neededSize = this.position + bytes.length;
106
+ if (neededSize > this.buffer.length) {
107
+ const newBuffer = new Uint8Array(neededSize);
108
+ newBuffer.set(this.buffer);
109
+ this.buffer = newBuffer;
110
+ }
111
+ this.buffer.set(bytes, this.position);
112
+ this.position += bytes.length;
113
+ }
114
+ async seek(position) {
115
+ this.position = position;
116
+ }
117
+ async truncate(size) {
118
+ if (size < this.buffer.length) {
119
+ this.buffer = this.buffer.slice(0, size);
120
+ } else if (size > this.buffer.length) {
121
+ const newBuffer = new Uint8Array(size);
122
+ newBuffer.set(this.buffer);
123
+ this.buffer = newBuffer;
124
+ }
125
+ if (this.position > size) {
126
+ this.position = size;
127
+ }
128
+ }
129
+ async close() {
130
+ await Bun.write(this.path, this.buffer);
131
+ }
132
+ async abort(_reason) {
133
+ this.buffer = new Uint8Array(0);
134
+ }
135
+ }
136
+
137
+ class NodeDirectoryHandle {
138
+ name;
139
+ fullPath;
140
+ kind = "directory";
141
+ constructor(name, fullPath) {
142
+ this.name = name;
143
+ this.fullPath = fullPath;
144
+ }
145
+ async getFileHandle(name, options) {
146
+ const path = `${this.fullPath}/${name}`;
147
+ const file = Bun.file(path);
148
+ const exists = await file.exists();
149
+ if (!exists && !options?.create) {
150
+ throw new DOMException(`File not found: ${name}`, "NotFoundError");
151
+ }
152
+ if (!exists && options?.create) {
153
+ await Bun.write(path, "");
154
+ }
155
+ return new NodeFileHandle(name, path);
156
+ }
157
+ async getDirectoryHandle(name, options) {
158
+ const path = `${this.fullPath}/${name}`;
159
+ try {
160
+ const stat = await Bun.file(path).stat();
161
+ if (!stat) {
162
+ throw new Error("Not found");
163
+ }
164
+ } catch {
165
+ if (!options?.create) {
166
+ throw new DOMException(`Directory not found: ${name}`, "NotFoundError");
167
+ }
168
+ await Bun.$`mkdir -p ${path}`;
169
+ }
170
+ return new NodeDirectoryHandle(name, path);
171
+ }
172
+ async removeEntry(name, options) {
173
+ const path = `${this.fullPath}/${name}`;
174
+ if (options?.recursive) {
175
+ await Bun.$`rm -rf ${path}`;
176
+ } else {
177
+ await Bun.$`rm ${path}`;
178
+ }
179
+ }
180
+ async resolve(possibleDescendant) {
181
+ const descendantPath = possibleDescendant instanceof NodeFileHandle || possibleDescendant instanceof NodeDirectoryHandle ? possibleDescendant.fullPath : null;
182
+ if (!descendantPath || !descendantPath.startsWith(this.fullPath)) {
183
+ return null;
184
+ }
185
+ const relativePath = descendantPath.slice(this.fullPath.length);
186
+ return relativePath.split("/").filter(Boolean);
187
+ }
188
+ async* entries() {
189
+ const result = await Bun.$`ls -1 ${this.fullPath}`.text();
190
+ const names = result.trim().split(`
191
+ `).filter(Boolean);
192
+ for (const name of names) {
193
+ const path = `${this.fullPath}/${name}`;
194
+ try {
195
+ const stat = await Bun.file(path).stat();
196
+ if (stat && typeof stat.isDirectory === "function" && stat.isDirectory()) {
197
+ yield [name, new NodeDirectoryHandle(name, path)];
198
+ } else {
199
+ yield [name, new NodeFileHandle(name, path)];
200
+ }
201
+ } catch {}
202
+ }
203
+ }
204
+ async* keys() {
205
+ for await (const [name] of this.entries()) {
206
+ yield name;
207
+ }
208
+ }
209
+ async* values() {
210
+ for await (const [, handle] of this.entries()) {
211
+ yield handle;
212
+ }
213
+ }
214
+ }
215
+ function createNodeDirectoryHandle(rootPath) {
216
+ const name = rootPath.split("/").pop() || "";
217
+ return new NodeDirectoryHandle(name, rootPath);
218
+ }
219
+ })
220
+
221
+ //# debugId=30BC4BE3F0DE509364756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/node-adapter.ts"],
4
+ "sourcesContent": [
5
+ "import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.cjs\";\n\n/**\n * Node/Bun file handle implementation\n */\nclass NodeFileHandle implements HostFileHandle {\n readonly kind = \"file\" as const;\n\n constructor(\n public readonly name: string,\n private readonly fullPath: string\n ) {}\n\n async getFile(): Promise<File> {\n const file = Bun.file(this.fullPath);\n const buffer = await file.arrayBuffer();\n const stat = await Bun.file(this.fullPath).stat();\n\n return new File([buffer], this.name, {\n type: file.type,\n lastModified: stat?.mtime?.getTime() ?? Date.now(),\n });\n }\n\n async createWritable(\n options?: { keepExistingData?: boolean }\n ): Promise<HostWritableFileStream> {\n return new NodeWritableFileStream(\n this.fullPath,\n options?.keepExistingData ?? false\n );\n }\n}\n\n/**\n * Node/Bun writable file stream implementation\n */\nclass NodeWritableFileStream implements HostWritableFileStream {\n private buffer: Uint8Array;\n private position = 0;\n\n constructor(\n private readonly path: string,\n keepExistingData: boolean\n ) {\n if (keepExistingData) {\n // Read existing file synchronously for simplicity\n try {\n const file = Bun.file(this.path);\n // Note: This is simplified; in production you'd want async\n this.buffer = new Uint8Array(0);\n file.arrayBuffer().then((ab) => {\n this.buffer = new Uint8Array(ab);\n });\n } catch {\n this.buffer = new Uint8Array(0);\n }\n } else {\n this.buffer = new Uint8Array(0);\n }\n }\n\n async write(\n data: string | ArrayBuffer | Uint8Array | Blob | WriteParams\n ): Promise<void> {\n let bytes: Uint8Array;\n\n if (typeof data === \"string\") {\n bytes = new TextEncoder().encode(data);\n } else if (data instanceof ArrayBuffer) {\n bytes = new Uint8Array(data);\n } else if (data instanceof Uint8Array) {\n bytes = data;\n } else if (data instanceof Blob) {\n bytes = new Uint8Array(await data.arrayBuffer());\n } else {\n // WriteParams\n if (data.type === \"seek\") {\n this.position = data.position ?? 0;\n return;\n }\n if (data.type === \"truncate\") {\n this.buffer = this.buffer.slice(0, data.size ?? 0);\n if (this.position > this.buffer.length) {\n this.position = this.buffer.length;\n }\n return;\n }\n // type === \"write\"\n if (data.data === undefined) return;\n return this.write(data.data);\n }\n\n // Expand buffer if needed\n const neededSize = this.position + bytes.length;\n if (neededSize > this.buffer.length) {\n const newBuffer = new Uint8Array(neededSize);\n newBuffer.set(this.buffer);\n this.buffer = newBuffer;\n }\n\n this.buffer.set(bytes, this.position);\n this.position += bytes.length;\n }\n\n async seek(position: number): Promise<void> {\n this.position = position;\n }\n\n async truncate(size: number): Promise<void> {\n if (size < this.buffer.length) {\n this.buffer = this.buffer.slice(0, size);\n } else if (size > this.buffer.length) {\n const newBuffer = new Uint8Array(size);\n newBuffer.set(this.buffer);\n this.buffer = newBuffer;\n }\n if (this.position > size) {\n this.position = size;\n }\n }\n\n async close(): Promise<void> {\n await Bun.write(this.path, this.buffer);\n }\n\n async abort(_reason?: unknown): Promise<void> {\n // Don't write, just discard\n this.buffer = new Uint8Array(0);\n }\n}\n\n/**\n * Node/Bun directory handle implementation\n */\nclass NodeDirectoryHandle implements HostDirectoryHandle {\n readonly kind = \"directory\" as const;\n\n constructor(\n public readonly name: string,\n private readonly fullPath: string\n ) {}\n\n async getFileHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostFileHandle> {\n const path = `${this.fullPath}/${name}`;\n const file = Bun.file(path);\n const exists = await file.exists();\n\n if (!exists && !options?.create) {\n throw new DOMException(`File not found: ${name}`, \"NotFoundError\");\n }\n\n if (!exists && options?.create) {\n await Bun.write(path, \"\");\n }\n\n return new NodeFileHandle(name, path);\n }\n\n async getDirectoryHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostDirectoryHandle> {\n const path = `${this.fullPath}/${name}`;\n\n try {\n const stat = await Bun.file(path).stat();\n if (!stat) {\n throw new Error(\"Not found\");\n }\n } catch {\n if (!options?.create) {\n throw new DOMException(`Directory not found: ${name}`, \"NotFoundError\");\n }\n // Create directory\n await Bun.$`mkdir -p ${path}`;\n }\n\n return new NodeDirectoryHandle(name, path);\n }\n\n async removeEntry(\n name: string,\n options?: { recursive?: boolean }\n ): Promise<void> {\n const path = `${this.fullPath}/${name}`;\n\n if (options?.recursive) {\n await Bun.$`rm -rf ${path}`;\n } else {\n await Bun.$`rm ${path}`;\n }\n }\n\n async resolve(\n possibleDescendant: HostFileHandle | HostDirectoryHandle\n ): Promise<string[] | null> {\n // Get the paths and compare\n const descendantPath =\n possibleDescendant instanceof NodeFileHandle ||\n possibleDescendant instanceof NodeDirectoryHandle\n ? (possibleDescendant as unknown as { fullPath: string }).fullPath\n : null;\n\n if (!descendantPath || !descendantPath.startsWith(this.fullPath)) {\n return null;\n }\n\n const relativePath = descendantPath.slice(this.fullPath.length);\n return relativePath.split(\"/\").filter(Boolean);\n }\n\n async *entries(): AsyncIterable<\n [string, HostFileHandle | HostDirectoryHandle]\n > {\n const result = await Bun.$`ls -1 ${this.fullPath}`.text();\n const names = result.trim().split(\"\\n\").filter(Boolean);\n\n for (const name of names) {\n const path = `${this.fullPath}/${name}`;\n try {\n const stat = await Bun.file(path).stat();\n if (stat && typeof stat.isDirectory === 'function' && stat.isDirectory()) {\n yield [name, new NodeDirectoryHandle(name, path)];\n } else {\n yield [name, new NodeFileHandle(name, path)];\n }\n } catch {\n // Skip entries we can't stat\n }\n }\n }\n\n async *keys(): AsyncIterable<string> {\n for await (const [name] of this.entries()) {\n yield name;\n }\n }\n\n async *values(): AsyncIterable<HostFileHandle | HostDirectoryHandle> {\n for await (const [, handle] of this.entries()) {\n yield handle;\n }\n }\n}\n\n/**\n * Create a directory handle backed by Node.js/Bun fs\n * Useful for server-side implementations\n *\n * @param rootPath - Absolute path to the directory on disk\n * @returns A HostDirectoryHandle implementation\n *\n * @example\n * import { createNodeDirectoryHandle } from \"@ricsam/quickjs-fs\";\n *\n * const handle = setupFs(context, {\n * getDirectory: async (path) => {\n * // Only allow access to /sandbox\n * if (!path.startsWith(\"/sandbox\")) {\n * throw new Error(\"Access denied\");\n * }\n * const realPath = path.replace(\"/sandbox\", \"/var/app/sandbox\");\n * return createNodeDirectoryHandle(realPath);\n * }\n * });\n */\nexport function createNodeDirectoryHandle(\n rootPath: string\n): HostDirectoryHandle {\n const name = rootPath.split(\"/\").pop() || \"\";\n return new NodeDirectoryHandle(name, rootPath);\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "30BC4BE3F0DE509364756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fs",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "commonjs"
5
5
  }
@@ -0,0 +1,140 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+
30
+ // packages/fs/src/setup.ts
31
+ var exports_setup = {};
32
+ __export(exports_setup, {
33
+ setupFs: () => setupFs
34
+ });
35
+ module.exports = __toCommonJS(exports_setup);
36
+ var import_quickjs_core = require("@ricsam/quickjs-core");
37
+ var import_writable_stream = require("./handles/writable-stream.cjs");
38
+ var import_file_handle = require("./handles/file-handle.cjs");
39
+ var import_directory_handle = require("./handles/directory-handle.cjs");
40
+ function setupFs(context, options) {
41
+ const coreHandle = options.coreHandle ?? import_quickjs_core.setupCore(context, {
42
+ stateMap: options.stateMap
43
+ });
44
+ const stateMap = options.stateMap ?? coreHandle.stateMap;
45
+ const handles = [];
46
+ const WritableStreamClass = import_writable_stream.createFileSystemWritableFileStreamClass(context, stateMap);
47
+ context.setProp(context.global, "FileSystemWritableFileStream", WritableStreamClass);
48
+ context.setProp(context.global, "__FileSystemWritableFileStream__", WritableStreamClass);
49
+ WritableStreamClass.dispose();
50
+ const FileHandleClass = import_file_handle.createFileSystemFileHandleClass(context, stateMap);
51
+ context.setProp(context.global, "FileSystemFileHandle", FileHandleClass);
52
+ context.setProp(context.global, "__FileSystemFileHandle__", FileHandleClass);
53
+ FileHandleClass.dispose();
54
+ const DirectoryHandleClass = import_directory_handle.createFileSystemDirectoryHandleClass(context, stateMap);
55
+ context.setProp(context.global, "FileSystemDirectoryHandle", DirectoryHandleClass);
56
+ context.setProp(context.global, "__FileSystemDirectoryHandle__", DirectoryHandleClass);
57
+ DirectoryHandleClass.dispose();
58
+ const asyncIteratorResult = context.evalCode(`
59
+ FileSystemDirectoryHandle.prototype[Symbol.asyncIterator] = async function*() {
60
+ const entries = await this.entries();
61
+ for (const entry of entries) {
62
+ yield entry;
63
+ }
64
+ };
65
+ `);
66
+ if (asyncIteratorResult.error) {
67
+ asyncIteratorResult.error.dispose();
68
+ } else {
69
+ asyncIteratorResult.value.dispose();
70
+ }
71
+ const wrapperCode = `
72
+ // Wrapper for getFileHandle
73
+ FileSystemDirectoryHandle.prototype.getFileHandle = async function(name, options) {
74
+ const result = await this._getFileHandleInternal(name, options);
75
+ return new __FileSystemFileHandle__(result.__fileHandleId);
76
+ };
77
+
78
+ // Wrapper for getDirectoryHandle
79
+ FileSystemDirectoryHandle.prototype.getDirectoryHandle = async function(name, options) {
80
+ const result = await this._getDirectoryHandleInternal(name, options);
81
+ return new __FileSystemDirectoryHandle__(result.__directoryHandleId);
82
+ };
83
+
84
+ // Wrapper for createWritable
85
+ FileSystemFileHandle.prototype.createWritable = async function(options) {
86
+ const result = await this._createWritableInternal(options);
87
+ return new __FileSystemWritableFileStream__(result.__writableStreamId);
88
+ };
89
+ `;
90
+ const wrapperResult = context.evalCode(wrapperCode);
91
+ if (wrapperResult.error) {
92
+ const error = context.dump(wrapperResult.error);
93
+ wrapperResult.error.dispose();
94
+ throw new Error(`Failed to set up FS wrapper methods: ${JSON.stringify(error)}`);
95
+ }
96
+ wrapperResult.value.dispose();
97
+ const fsNamespace = context.newObject();
98
+ const getDirectoryFn = context.newFunction("getDirectory", (pathHandle) => {
99
+ const path = context.getString(pathHandle);
100
+ const deferred = context.newPromise();
101
+ options.getDirectory(path).then((hostHandle) => {
102
+ const hostHandleId = import_directory_handle.registerHostDirectoryHandle(hostHandle);
103
+ const instanceResult = context.evalCode(`new __FileSystemDirectoryHandle__(${hostHandleId})`);
104
+ if (instanceResult.error) {
105
+ deferred.reject(instanceResult.error);
106
+ instanceResult.error.dispose();
107
+ } else {
108
+ deferred.resolve(instanceResult.value);
109
+ instanceResult.value.dispose();
110
+ }
111
+ context.runtime.executePendingJobs();
112
+ }).catch((error) => {
113
+ const errorHandle = import_quickjs_core.marshal(context, {
114
+ name: error instanceof Error ? error.name : "Error",
115
+ message: error instanceof Error ? error.message : String(error)
116
+ });
117
+ deferred.reject(errorHandle);
118
+ errorHandle.dispose();
119
+ context.runtime.executePendingJobs();
120
+ });
121
+ return deferred.handle;
122
+ });
123
+ handles.push(getDirectoryFn);
124
+ context.setProp(fsNamespace, "getDirectory", getDirectoryFn);
125
+ context.setProp(context.global, "fs", fsNamespace);
126
+ fsNamespace.dispose();
127
+ return {
128
+ stateMap,
129
+ dispose() {
130
+ for (const handle of handles) {
131
+ if (handle.alive) {
132
+ handle.dispose();
133
+ }
134
+ }
135
+ }
136
+ };
137
+ }
138
+ })
139
+
140
+ //# debugId=66CE72DDAD52011C64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/setup.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport {\n setupCore,\n createStateMap,\n marshal,\n} from \"@ricsam/quickjs-core\";\nimport type { SetupFsOptions, FsHandle } from \"./types.cjs\";\nimport { createFileSystemWritableFileStreamClass } from \"./handles/writable-stream.cjs\";\nimport { createFileSystemFileHandleClass } from \"./handles/file-handle.cjs\";\nimport { createFileSystemDirectoryHandleClass, registerHostDirectoryHandle } from \"./handles/directory-handle.cjs\";\n\n/**\n * Setup File System API in a QuickJS context\n *\n * Injects the following globals:\n * - fs.getDirectory(path) - Server-compatible entry point\n * - FileSystemFileHandle\n * - FileSystemDirectoryHandle\n * - FileSystemWritableFileStream\n *\n * **Private globals (internal use):**\n * - `__FileSystemFileHandle__` - For creating file handle instances from wrapper code\n * - `__FileSystemDirectoryHandle__` - For creating directory handle instances\n * - `__FileSystemWritableFileStream__` - For creating writable stream instances\n *\n * These private globals follow the `__Name__` convention and are required for the\n * wrapper pattern: public methods call internal methods that return IDs, then use\n * evalCode with private constructors to create properly-typed class instances.\n * See PATTERNS.md sections 2 and 5 for details.\n *\n * **Wrapper pattern example:**\n * ```typescript\n * // Public method (added via evalCode)\n * FileSystemFileHandle.prototype.createWritable = async function(options) {\n * const result = await this._createWritableInternal(options);\n * return new __FileSystemWritableFileStream__(result.__writableStreamId);\n * };\n * ```\n *\n * @example\n * import { setupFs, createNodeDirectoryHandle } from \"@ricsam/quickjs-fs\";\n *\n * const handle = setupFs(context, {\n * getDirectory: async (path) => {\n * // Validate and resolve path\n * const resolvedPath = resolveSandboxPath(path);\n * return createNodeDirectoryHandle(resolvedPath);\n * }\n * });\n *\n * context.evalCode(`\n * const root = await fs.getDirectory(\"/data\");\n * const configHandle = await root.getFileHandle(\"config.json\");\n * const file = await configHandle.getFile();\n * const text = await file.text();\n * console.log(JSON.parse(text));\n *\n * // Write a new file\n * const outputHandle = await root.getFileHandle(\"output.txt\", { create: true });\n * const writable = await outputHandle.createWritable();\n * await writable.write(\"Hello, World!\");\n * await writable.close();\n * `);\n */\nexport function setupFs(\n context: QuickJSContext,\n options: SetupFsOptions\n): FsHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n const handles: QuickJSHandle[] = [];\n\n // Create FileSystemWritableFileStream class\n const WritableStreamClass = createFileSystemWritableFileStreamClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"FileSystemWritableFileStream\",\n WritableStreamClass\n );\n context.setProp(context.global, \"__FileSystemWritableFileStream__\", WritableStreamClass);\n WritableStreamClass.dispose();\n\n // Create FileSystemFileHandle class\n const FileHandleClass = createFileSystemFileHandleClass(\n context,\n stateMap\n );\n context.setProp(context.global, \"FileSystemFileHandle\", FileHandleClass);\n context.setProp(context.global, \"__FileSystemFileHandle__\", FileHandleClass);\n FileHandleClass.dispose();\n\n // Create FileSystemDirectoryHandle class\n const DirectoryHandleClass = createFileSystemDirectoryHandleClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"FileSystemDirectoryHandle\",\n DirectoryHandleClass\n );\n context.setProp(context.global, \"__FileSystemDirectoryHandle__\", DirectoryHandleClass);\n DirectoryHandleClass.dispose();\n\n // Add Symbol.asyncIterator support for FileSystemDirectoryHandle (for await...of)\n const asyncIteratorResult = context.evalCode(`\n FileSystemDirectoryHandle.prototype[Symbol.asyncIterator] = async function*() {\n const entries = await this.entries();\n for (const entry of entries) {\n yield entry;\n }\n };\n `);\n if (asyncIteratorResult.error) {\n asyncIteratorResult.error.dispose();\n } else {\n asyncIteratorResult.value.dispose();\n }\n\n // Add wrapper methods that convert IDs to class instances\n const wrapperCode = `\n // Wrapper for getFileHandle\n FileSystemDirectoryHandle.prototype.getFileHandle = async function(name, options) {\n const result = await this._getFileHandleInternal(name, options);\n return new __FileSystemFileHandle__(result.__fileHandleId);\n };\n\n // Wrapper for getDirectoryHandle\n FileSystemDirectoryHandle.prototype.getDirectoryHandle = async function(name, options) {\n const result = await this._getDirectoryHandleInternal(name, options);\n return new __FileSystemDirectoryHandle__(result.__directoryHandleId);\n };\n\n // Wrapper for createWritable\n FileSystemFileHandle.prototype.createWritable = async function(options) {\n const result = await this._createWritableInternal(options);\n return new __FileSystemWritableFileStream__(result.__writableStreamId);\n };\n `;\n const wrapperResult = context.evalCode(wrapperCode);\n if (wrapperResult.error) {\n const error = context.dump(wrapperResult.error);\n wrapperResult.error.dispose();\n throw new Error(`Failed to set up FS wrapper methods: ${JSON.stringify(error)}`);\n }\n wrapperResult.value.dispose();\n\n // Create fs namespace with getDirectory\n const fsNamespace = context.newObject();\n\n // Create getDirectory function that returns proper class instances\n const getDirectoryFn = context.newFunction(\"getDirectory\", (pathHandle) => {\n const path = context.getString(pathHandle);\n\n const deferred = context.newPromise();\n\n options\n .getDirectory(path)\n .then((hostHandle) => {\n // Register the host handle and get an ID\n const hostHandleId = registerHostDirectoryHandle(hostHandle);\n\n // Create instance using evalCode with the ID\n const instanceResult = context.evalCode(\n `new __FileSystemDirectoryHandle__(${hostHandleId})`\n );\n\n if (instanceResult.error) {\n deferred.reject(instanceResult.error);\n instanceResult.error.dispose();\n } else {\n deferred.resolve(instanceResult.value);\n instanceResult.value.dispose();\n }\n context.runtime.executePendingJobs();\n })\n .catch((error) => {\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n handles.push(getDirectoryFn);\n context.setProp(fsNamespace, \"getDirectory\", getDirectoryFn);\n\n context.setProp(context.global, \"fs\", fsNamespace);\n fsNamespace.dispose();\n\n return {\n stateMap,\n dispose() {\n for (const handle of handles) {\n if (handle.alive) {\n handle.dispose();\n }\n }\n },\n };\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "66CE72DDAD52011C64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,26 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+
21
+ // packages/fs/src/types.ts
22
+ var exports_types = {};
23
+ module.exports = __toCommonJS(exports_types);
24
+ })
25
+
26
+ //# debugId=C67E7147CA95AE3264756E2164756E21
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "C67E7147CA95AE3264756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,119 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+
30
+ // packages/fs/src/handles/writable-stream.ts
31
+ var exports_writable_stream = {};
32
+ __export(exports_writable_stream, {
33
+ createFileSystemWritableFileStreamClass: () => createFileSystemWritableFileStreamClass
34
+ });
35
+ module.exports = __toCommonJS(exports_writable_stream);
36
+ var import_quickjs_core = require("@ricsam/quickjs-core");
37
+ var import_file_handle = require("./file-handle.cjs");
38
+ function createFileSystemWritableFileStreamClass(context, stateMap) {
39
+ return import_quickjs_core.defineClass(context, stateMap, {
40
+ name: "FileSystemWritableFileStream",
41
+ construct: (args) => {
42
+ const streamId = args[0];
43
+ const hostStream = import_file_handle.pendingWritableStreams.get(streamId);
44
+ if (!hostStream) {
45
+ throw new Error(`No pending writable stream with ID ${streamId}`);
46
+ }
47
+ import_file_handle.pendingWritableStreams.delete(streamId);
48
+ return {
49
+ hostStream,
50
+ closed: false
51
+ };
52
+ },
53
+ methods: {
54
+ async write(data) {
55
+ if (this.closed) {
56
+ throw new Error("Stream is closed");
57
+ }
58
+ if (data && typeof data === "object" && "type" in data) {
59
+ const params = data;
60
+ if (params.type === "seek" && params.position !== undefined) {
61
+ await this.hostStream.seek(params.position);
62
+ return;
63
+ }
64
+ if (params.type === "truncate" && params.size !== undefined) {
65
+ await this.hostStream.truncate(params.size);
66
+ return;
67
+ }
68
+ if (params.type === "write" && params.data !== undefined) {
69
+ await this.hostStream.write(params.data);
70
+ return;
71
+ }
72
+ }
73
+ if (typeof data === "string") {
74
+ await this.hostStream.write(data);
75
+ } else if (data instanceof ArrayBuffer) {
76
+ await this.hostStream.write(data);
77
+ } else if (data instanceof Uint8Array) {
78
+ await this.hostStream.write(data);
79
+ } else if (data && typeof data === "object" && "parts" in data) {
80
+ const parts = data.parts;
81
+ for (const part of parts) {
82
+ await this.hostStream.write(part);
83
+ }
84
+ } else {
85
+ await this.hostStream.write(String(data));
86
+ }
87
+ },
88
+ async seek(position) {
89
+ if (this.closed) {
90
+ throw new Error("Stream is closed");
91
+ }
92
+ await this.hostStream.seek(Number(position));
93
+ },
94
+ async truncate(size) {
95
+ if (this.closed) {
96
+ throw new Error("Stream is closed");
97
+ }
98
+ await this.hostStream.truncate(Number(size));
99
+ },
100
+ async close() {
101
+ if (this.closed) {
102
+ return;
103
+ }
104
+ this.closed = true;
105
+ await this.hostStream.close();
106
+ },
107
+ async abort(reason) {
108
+ if (this.closed) {
109
+ return;
110
+ }
111
+ this.closed = true;
112
+ await this.hostStream.abort(reason);
113
+ }
114
+ }
115
+ });
116
+ }
117
+ })
118
+
119
+ //# debugId=007DC4CA7D28991D64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/handles/writable-stream.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type {\n FileSystemWritableFileStreamState,\n WriteParams,\n HostWritableFileStream,\n} from \"../types.cjs\";\nimport { pendingWritableStreams } from \"./file-handle.cjs\";\n\n/**\n * Create the FileSystemWritableFileStream class for QuickJS\n */\nexport function createFileSystemWritableFileStreamClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemWritableFileStreamState>(context, stateMap, {\n name: \"FileSystemWritableFileStream\",\n construct: (args) => {\n const streamId = args[0] as number;\n const hostStream = pendingWritableStreams.get(streamId);\n if (!hostStream) {\n throw new Error(`No pending writable stream with ID ${streamId}`);\n }\n pendingWritableStreams.delete(streamId);\n return {\n hostStream,\n closed: false,\n };\n },\n methods: {\n async write(\n this: FileSystemWritableFileStreamState,\n data: unknown\n ): Promise<void> {\n if (this.closed) {\n throw new Error(\"Stream is closed\");\n }\n\n // Handle WriteParams\n if (data && typeof data === \"object\" && \"type\" in data) {\n const params = data as WriteParams;\n if (params.type === \"seek\" && params.position !== undefined) {\n await this.hostStream.seek(params.position);\n return;\n }\n if (params.type === \"truncate\" && params.size !== undefined) {\n await this.hostStream.truncate(params.size);\n return;\n }\n if (params.type === \"write\" && params.data !== undefined) {\n await this.hostStream.write(params.data);\n return;\n }\n }\n\n // Direct data write\n if (typeof data === \"string\") {\n await this.hostStream.write(data);\n } else if (data instanceof ArrayBuffer) {\n await this.hostStream.write(data);\n } else if (data instanceof Uint8Array) {\n await this.hostStream.write(data);\n } else if (data && typeof data === \"object\" && \"parts\" in data) {\n // Blob-like\n const parts = (data as { parts: Uint8Array[] }).parts;\n for (const part of parts) {\n await this.hostStream.write(part);\n }\n } else {\n await this.hostStream.write(String(data));\n }\n },\n async seek(\n this: FileSystemWritableFileStreamState,\n position: unknown\n ): Promise<void> {\n if (this.closed) {\n throw new Error(\"Stream is closed\");\n }\n await this.hostStream.seek(Number(position));\n },\n async truncate(\n this: FileSystemWritableFileStreamState,\n size: unknown\n ): Promise<void> {\n if (this.closed) {\n throw new Error(\"Stream is closed\");\n }\n await this.hostStream.truncate(Number(size));\n },\n async close(this: FileSystemWritableFileStreamState): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n await this.hostStream.close();\n },\n async abort(\n this: FileSystemWritableFileStreamState,\n reason?: unknown\n ): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n await this.hostStream.abort(reason);\n },\n },\n });\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE4B,IAA5B;AAMuC,IAAvC;AAKO,SAAS,uCAAuC,CACrD,SACA,UACe;AAAA,EACf,OAAO,gCAA+C,SAAS,UAAU;AAAA,IACvE,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,WAAW,KAAK;AAAA,MACtB,MAAM,aAAa,0CAAuB,IAAI,QAAQ;AAAA,MACtD,IAAI,CAAC,YAAY;AAAA,QACf,MAAM,IAAI,MAAM,sCAAsC,UAAU;AAAA,MAClE;AAAA,MACA,0CAAuB,OAAO,QAAQ;AAAA,MACtC,OAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,MACV;AAAA;AAAA,IAEF,SAAS;AAAA,WACD,MAAK,CAET,MACe;AAAA,QACf,IAAI,KAAK,QAAQ;AAAA,UACf,MAAM,IAAI,MAAM,kBAAkB;AAAA,QACpC;AAAA,QAGA,IAAI,QAAQ,OAAO,SAAS,YAAY,UAAU,MAAM;AAAA,UACtD,MAAM,SAAS;AAAA,UACf,IAAI,OAAO,SAAS,UAAU,OAAO,aAAa,WAAW;AAAA,YAC3D,MAAM,KAAK,WAAW,KAAK,OAAO,QAAQ;AAAA,YAC1C;AAAA,UACF;AAAA,UACA,IAAI,OAAO,SAAS,cAAc,OAAO,SAAS,WAAW;AAAA,YAC3D,MAAM,KAAK,WAAW,SAAS,OAAO,IAAI;AAAA,YAC1C;AAAA,UACF;AAAA,UACA,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW;AAAA,YACxD,MAAM,KAAK,WAAW,MAAM,OAAO,IAAI;AAAA,YACvC;AAAA,UACF;AAAA,QACF;AAAA,QAGA,IAAI,OAAO,SAAS,UAAU;AAAA,UAC5B,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,QAClC,EAAO,SAAI,gBAAgB,aAAa;AAAA,UACtC,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,QAClC,EAAO,SAAI,gBAAgB,YAAY;AAAA,UACrC,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,QAClC,EAAO,SAAI,QAAQ,OAAO,SAAS,YAAY,WAAW,MAAM;AAAA,UAE9D,MAAM,QAAS,KAAiC;AAAA,UAChD,WAAW,QAAQ,OAAO;AAAA,YACxB,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,UAClC;AAAA,QACF,EAAO;AAAA,UACL,MAAM,KAAK,WAAW,MAAM,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA,WAGtC,KAAI,CAER,UACe;AAAA,QACf,IAAI,KAAK,QAAQ;AAAA,UACf,MAAM,IAAI,MAAM,kBAAkB;AAAA,QACpC;AAAA,QACA,MAAM,KAAK,WAAW,KAAK,OAAO,QAAQ,CAAC;AAAA;AAAA,WAEvC,SAAQ,CAEZ,MACe;AAAA,QACf,IAAI,KAAK,QAAQ;AAAA,UACf,MAAM,IAAI,MAAM,kBAAkB;AAAA,QACpC;AAAA,QACA,MAAM,KAAK,WAAW,SAAS,OAAO,IAAI,CAAC;AAAA;AAAA,WAEvC,MAAK,GAAyD;AAAA,QAClE,IAAI,KAAK,QAAQ;AAAA,UACf;AAAA,QACF;AAAA,QACA,KAAK,SAAS;AAAA,QACd,MAAM,KAAK,WAAW,MAAM;AAAA;AAAA,WAExB,MAAK,CAET,QACe;AAAA,QACf,IAAI,KAAK,QAAQ;AAAA,UACf;AAAA,QACF;AAAA,QACA,KAAK,SAAS;AAAA,QACd,MAAM,KAAK,WAAW,MAAM,MAAM;AAAA;AAAA,IAEtC;AAAA,EACF,CAAC;AAAA;",
8
+ "debugId": "007DC4CA7D28991D64756E2164756E21",
9
+ "names": []
10
+ }