@ricsam/quickjs-fs 0.2.1 → 0.2.3
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/dist/cjs/{directory-handle.cjs → handles/directory-handle.cjs} +2 -2
- package/dist/cjs/handles/directory-handle.cjs.map +10 -0
- package/dist/cjs/handles/file-handle.cjs.map +10 -0
- package/dist/cjs/{writable-stream.cjs → handles/writable-stream.cjs} +2 -2
- package/dist/cjs/handles/writable-stream.cjs.map +10 -0
- package/dist/cjs/index.cjs +4 -4
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/cjs/memory-adapter.cjs.map +1 -1
- package/dist/cjs/node-adapter.cjs.map +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/setup.cjs +4 -4
- package/dist/cjs/setup.cjs.map +2 -2
- package/dist/mjs/{directory-handle.mjs → handles/directory-handle.mjs} +2 -2
- package/dist/mjs/handles/directory-handle.mjs.map +10 -0
- package/dist/mjs/handles/file-handle.mjs.map +10 -0
- package/dist/mjs/{writable-stream.mjs → handles/writable-stream.mjs} +2 -2
- package/dist/mjs/handles/writable-stream.mjs.map +10 -0
- package/dist/mjs/index.mjs +4 -4
- package/dist/mjs/index.mjs.map +2 -2
- package/dist/mjs/memory-adapter.mjs.map +1 -1
- package/dist/mjs/node-adapter.mjs.map +1 -1
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/setup.mjs +4 -4
- package/dist/mjs/setup.mjs.map +2 -2
- package/package.json +2 -2
- package/dist/cjs/directory-handle.cjs.map +0 -10
- package/dist/cjs/file-handle.cjs.map +0 -10
- package/dist/cjs/writable-stream.cjs.map +0 -10
- package/dist/mjs/directory-handle.mjs.map +0 -10
- package/dist/mjs/file-handle.mjs.map +0 -10
- package/dist/mjs/writable-stream.mjs.map +0 -10
- /package/dist/cjs/{file-handle.cjs → handles/file-handle.cjs} +0 -0
- /package/dist/mjs/{file-handle.mjs → handles/file-handle.mjs} +0 -0
|
@@ -36,7 +36,7 @@ __export(exports_directory_handle, {
|
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(exports_directory_handle);
|
|
38
38
|
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
39
|
-
var import_file_handle = require("./file-handle.
|
|
39
|
+
var import_file_handle = require("./file-handle.cjs");
|
|
40
40
|
var nextHostHandleId = 0;
|
|
41
41
|
var pendingHostHandles = new Map;
|
|
42
42
|
function registerHostDirectoryHandle(handle) {
|
|
@@ -163,4 +163,4 @@ function createFileSystemDirectoryHandleClass(context, stateMap) {
|
|
|
163
163
|
}
|
|
164
164
|
})
|
|
165
165
|
|
|
166
|
-
//# debugId=
|
|
166
|
+
//# debugId=BB1AC823E8D90E4864756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/handles/directory-handle.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type {\n FileSystemDirectoryHandleState,\n FileSystemFileHandleState,\n HostDirectoryHandle,\n} from \"../types.cjs\";\nimport { registerHostFileHandle } from \"./file-handle.cjs\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextHostHandleId = 0;\nexport const pendingHostHandles = new Map<\n number,\n { handle: HostDirectoryHandle; name: string }\n>();\n\nexport function registerHostDirectoryHandle(\n handle: HostDirectoryHandle\n): number {\n const id = nextHostHandleId++;\n pendingHostHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\n/**\n * Create the FileSystemDirectoryHandle class for QuickJS\n */\nexport function createFileSystemDirectoryHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemDirectoryHandleState>(context, stateMap, {\n name: \"FileSystemDirectoryHandle\",\n construct: (args) => {\n // First argument is the host handle ID\n const hostHandleId = args[0] as number;\n const pending = pendingHostHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending host handle with ID ${hostHandleId}`);\n }\n pendingHostHandles.delete(hostHandleId);\n return {\n kind: \"directory\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemDirectoryHandleState) {\n return \"directory\";\n },\n },\n name: {\n get(this: FileSystemDirectoryHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async _getFileHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __fileHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostFile = await this.hostHandle.getFileHandle(String(name), {\n create: opts?.create,\n });\n\n return { __fileHandleId: registerHostFileHandle(hostFile) };\n },\n async _getDirectoryHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __directoryHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostDir = await this.hostHandle.getDirectoryHandle(String(name), {\n create: opts?.create,\n });\n\n return { __directoryHandleId: registerHostDirectoryHandle(hostDir) };\n },\n async removeEntry(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<void> {\n const opts = options as { recursive?: boolean } | undefined;\n await this.hostHandle.removeEntry(String(name), {\n recursive: opts?.recursive,\n });\n },\n async resolve(\n this: FileSystemDirectoryHandleState,\n possibleDescendant: unknown\n ): Promise<string[] | null> {\n if (!possibleDescendant || typeof possibleDescendant !== \"object\") {\n return null;\n }\n\n const descendant = possibleDescendant as\n | FileSystemFileHandleState\n | FileSystemDirectoryHandleState;\n return this.hostHandle.resolve(descendant.hostHandle);\n },\n async entries(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n >\n > {\n const result: Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n > = [];\n\n for await (const [name, handle] of this.hostHandle.entries()) {\n if (handle.kind === \"file\") {\n result.push([\n name,\n {\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n } else {\n result.push([\n name,\n {\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n }\n }\n\n return result;\n },\n async keys(this: FileSystemDirectoryHandleState): Promise<string[]> {\n const result: string[] = [];\n for await (const name of this.hostHandle.keys()) {\n result.push(name);\n }\n return result;\n },\n async values(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<FileSystemFileHandleState | FileSystemDirectoryHandleState>\n > {\n const result: Array<\n FileSystemFileHandleState | FileSystemDirectoryHandleState\n > = [];\n\n for await (const handle of this.hostHandle.values()) {\n if (handle.kind === \"file\") {\n result.push({\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n });\n } else {\n result.push({\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n });\n }\n }\n\n return result;\n },\n async isSameEntry(\n this: FileSystemDirectoryHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemDirectoryHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "BB1AC823E8D90E4864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/handles/file-handle.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 { FileSystemFileHandleState, HostFileHandle, HostWritableFileStream } from \"../types.cjs\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextFileHandleId = 0;\nexport const pendingFileHandles = new Map<number, { handle: HostFileHandle; name: string }>();\nlet nextWritableStreamId = 0;\nexport const pendingWritableStreams = new Map<number, HostWritableFileStream>();\n\nexport function registerHostFileHandle(handle: HostFileHandle): number {\n const id = nextFileHandleId++;\n pendingFileHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\nexport function registerHostWritableStream(stream: HostWritableFileStream): number {\n const id = nextWritableStreamId++;\n pendingWritableStreams.set(id, stream);\n return id;\n}\n\n/**\n * Create the FileSystemFileHandle class for QuickJS\n */\nexport function createFileSystemFileHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemFileHandleState>(context, stateMap, {\n name: \"FileSystemFileHandle\",\n construct: (args) => {\n const hostHandleId = args[0] as number;\n const pending = pendingFileHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending file handle with ID ${hostHandleId}`);\n }\n pendingFileHandles.delete(hostHandleId);\n return {\n kind: \"file\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemFileHandleState) {\n return \"file\";\n },\n },\n name: {\n get(this: FileSystemFileHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async getFile(this: FileSystemFileHandleState): Promise<object> {\n const file = await this.hostHandle.getFile();\n\n // Convert native File to our internal File representation\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n return {\n parts: [data],\n type: file.type,\n size: file.size,\n name: file.name,\n lastModified: file.lastModified,\n webkitRelativePath: \"\",\n // Include methods that will be recognized\n async text() {\n return new TextDecoder().decode(data);\n },\n async arrayBuffer() {\n return buffer;\n },\n async bytes() {\n return data;\n },\n };\n },\n async _createWritableInternal(\n this: FileSystemFileHandleState,\n options?: unknown\n ): Promise<{ __writableStreamId: number }> {\n const opts = options as { keepExistingData?: boolean } | undefined;\n const hostStream = await this.hostHandle.createWritable({\n keepExistingData: opts?.keepExistingData,\n });\n\n return { __writableStreamId: registerHostWritableStream(hostStream) };\n },\n async isSameEntry(\n this: FileSystemFileHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemFileHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE4B,IAA5B;AAIA,IAAI,mBAAmB;AAChB,IAAM,qBAAqB,IAAI;AACtC,IAAI,uBAAuB;AACpB,IAAM,yBAAyB,IAAI;AAEnC,SAAS,sBAAsB,CAAC,QAAgC;AAAA,EACrE,MAAM,KAAK;AAAA,EACX,mBAAmB,IAAI,IAAI,EAAE,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,EACxD,OAAO;AAAA;AAGF,SAAS,0BAA0B,CAAC,QAAwC;AAAA,EACjF,MAAM,KAAK;AAAA,EACX,uBAAuB,IAAI,IAAI,MAAM;AAAA,EACrC,OAAO;AAAA;AAMF,SAAS,+BAA+B,CAC7C,SACA,UACe;AAAA,EACf,OAAO,gCAAuC,SAAS,UAAU;AAAA,IAC/D,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,eAAe,KAAK;AAAA,MAC1B,MAAM,UAAU,mBAAmB,IAAI,YAAY;AAAA,MACnD,IAAI,CAAC,SAAS;AAAA,QACZ,MAAM,IAAI,MAAM,kCAAkC,cAAc;AAAA,MAClE;AAAA,MACA,mBAAmB,OAAO,YAAY;AAAA,MACtC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO;AAAA;AAAA,MAEX;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,QAAO,GAAmD;AAAA,QAC9D,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ;AAAA,QAG3C,MAAM,SAAS,MAAM,KAAK,YAAY;AAAA,QACtC,MAAM,OAAO,IAAI,WAAW,MAAM;AAAA,QAElC,OAAO;AAAA,UACL,OAAO,CAAC,IAAI;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,cAAc,KAAK;AAAA,UACnB,oBAAoB;AAAA,eAEd,KAAI,GAAG;AAAA,YACX,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA;AAAA,eAEhC,YAAW,GAAG;AAAA,YAClB,OAAO;AAAA;AAAA,eAEH,MAAK,GAAG;AAAA,YACZ,OAAO;AAAA;AAAA,QAEX;AAAA;AAAA,WAEI,wBAAuB,CAE3B,SACyC;AAAA,QACzC,MAAM,OAAO;AAAA,QACb,MAAM,aAAa,MAAM,KAAK,WAAW,eAAe;AAAA,UACtD,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,QAED,OAAO,EAAE,oBAAoB,2BAA2B,UAAU,EAAE;AAAA;AAAA,WAEhE,YAAW,CAEf,OACkB;AAAA,QAClB,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AAAA,UACvC,OAAO;AAAA,QACT;AAAA,QACA,MAAM,cAAc;AAAA,QACpB,OAAO,KAAK,eAAe,YAAY;AAAA;AAAA,IAE3C;AAAA,EACF,CAAC;AAAA;",
|
|
8
|
+
"debugId": "03934374EFF6363C64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -34,7 +34,7 @@ __export(exports_writable_stream, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(exports_writable_stream);
|
|
36
36
|
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
37
|
-
var import_file_handle = require("./file-handle.
|
|
37
|
+
var import_file_handle = require("./file-handle.cjs");
|
|
38
38
|
function createFileSystemWritableFileStreamClass(context, stateMap) {
|
|
39
39
|
return import_quickjs_core.defineClass(context, stateMap, {
|
|
40
40
|
name: "FileSystemWritableFileStream",
|
|
@@ -116,4 +116,4 @@ function createFileSystemWritableFileStreamClass(context, stateMap) {
|
|
|
116
116
|
}
|
|
117
117
|
})
|
|
118
118
|
|
|
119
|
-
//# debugId=
|
|
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
|
+
}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -35,9 +35,9 @@ __export(exports_src, {
|
|
|
35
35
|
createMemoryDirectoryHandle: () => import_memory_adapter.createMemoryDirectoryHandle
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(exports_src);
|
|
38
|
-
var import_setup = require("./setup.
|
|
39
|
-
var import_node_adapter = require("./node-adapter.
|
|
40
|
-
var import_memory_adapter = require("./memory-adapter.
|
|
38
|
+
var import_setup = require("./setup.cjs");
|
|
39
|
+
var import_node_adapter = require("./node-adapter.cjs");
|
|
40
|
+
var import_memory_adapter = require("./memory-adapter.cjs");
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
//# debugId=
|
|
43
|
+
//# debugId=17BC35DC931775ED64756E2164756E21
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export { setupFs } from \"./setup.
|
|
5
|
+
"export { setupFs } from \"./setup.cjs\";\nexport { createNodeDirectoryHandle } from \"./node-adapter.cjs\";\nexport { createMemoryDirectoryHandle } from \"./memory-adapter.cjs\";\n\nexport type {\n SetupFsOptions,\n FsHandle,\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.cjs\";\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAwB,IAAxB;AAC0C,IAA1C;AAC4C,IAA5C;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "17BC35DC931775ED64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/memory-adapter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.
|
|
5
|
+
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.cjs\";\n\ninterface MemoryEntry {\n kind: \"file\" | \"directory\";\n name: string;\n content?: Uint8Array;\n children?: Map<string, MemoryEntry>;\n lastModified: number;\n type?: string;\n}\n\n/**\n * In-memory file handle implementation\n */\nclass MemoryFileHandle implements HostFileHandle {\n readonly kind = \"file\" as const;\n\n constructor(\n public readonly name: string,\n private entry: MemoryEntry\n ) {}\n\n async getFile(): Promise<File> {\n const content = this.entry.content ?? new Uint8Array();\n return new File([content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength) as ArrayBuffer], this.name, {\n type: this.entry.type || \"application/octet-stream\",\n lastModified: this.entry.lastModified,\n });\n }\n\n async createWritable(\n options?: { keepExistingData?: boolean }\n ): Promise<HostWritableFileStream> {\n return new MemoryWritableFileStream(\n this.entry,\n options?.keepExistingData ?? false\n );\n }\n}\n\n/**\n * In-memory writable file stream implementation\n */\nclass MemoryWritableFileStream implements HostWritableFileStream {\n private buffer: Uint8Array;\n private position = 0;\n\n constructor(\n private entry: MemoryEntry,\n keepExistingData: boolean\n ) {\n if (keepExistingData && this.entry.content) {\n this.buffer = new Uint8Array(this.entry.content);\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 this.entry.content = this.buffer;\n this.entry.lastModified = Date.now();\n }\n\n async abort(_reason?: unknown): Promise<void> {\n // Don't save, just discard\n }\n}\n\n/**\n * In-memory directory handle implementation\n */\nclass MemoryDirectoryHandle implements HostDirectoryHandle {\n readonly kind = \"directory\" as const;\n\n constructor(\n public readonly name: string,\n private entry: MemoryEntry\n ) {}\n\n async getFileHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostFileHandle> {\n if (!this.entry.children) {\n this.entry.children = new Map();\n }\n\n let child = this.entry.children.get(name);\n\n if (!child) {\n if (!options?.create) {\n throw new DOMException(`File not found: ${name}`, \"NotFoundError\");\n }\n child = {\n kind: \"file\",\n name,\n content: new Uint8Array(0),\n lastModified: Date.now(),\n };\n this.entry.children.set(name, child);\n }\n\n if (child.kind !== \"file\") {\n throw new DOMException(\n `${name} is not a file`,\n \"TypeMismatchError\"\n );\n }\n\n return new MemoryFileHandle(name, child);\n }\n\n async getDirectoryHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostDirectoryHandle> {\n if (!this.entry.children) {\n this.entry.children = new Map();\n }\n\n let child = this.entry.children.get(name);\n\n if (!child) {\n if (!options?.create) {\n throw new DOMException(\n `Directory not found: ${name}`,\n \"NotFoundError\"\n );\n }\n child = {\n kind: \"directory\",\n name,\n children: new Map(),\n lastModified: Date.now(),\n };\n this.entry.children.set(name, child);\n }\n\n if (child.kind !== \"directory\") {\n throw new DOMException(\n `${name} is not a directory`,\n \"TypeMismatchError\"\n );\n }\n\n return new MemoryDirectoryHandle(name, child);\n }\n\n async removeEntry(\n name: string,\n options?: { recursive?: boolean }\n ): Promise<void> {\n if (!this.entry.children) {\n throw new DOMException(`Entry not found: ${name}`, \"NotFoundError\");\n }\n\n const child = this.entry.children.get(name);\n if (!child) {\n throw new DOMException(`Entry not found: ${name}`, \"NotFoundError\");\n }\n\n if (child.kind === \"directory\" && child.children?.size && !options?.recursive) {\n throw new DOMException(\n `Directory is not empty: ${name}`,\n \"InvalidModificationError\"\n );\n }\n\n this.entry.children.delete(name);\n }\n\n async resolve(\n possibleDescendant: HostFileHandle | HostDirectoryHandle\n ): Promise<string[] | null> {\n // Simplified implementation - just check if it's a direct child\n const descendantName = possibleDescendant.name;\n if (this.entry.children?.has(descendantName)) {\n return [descendantName];\n }\n return null;\n }\n\n async *entries(): AsyncIterable<\n [string, HostFileHandle | HostDirectoryHandle]\n > {\n if (!this.entry.children) {\n return;\n }\n\n for (const [name, child] of this.entry.children) {\n if (child.kind === \"file\") {\n yield [name, new MemoryFileHandle(name, child)];\n } else {\n yield [name, new MemoryDirectoryHandle(name, child)];\n }\n }\n }\n\n async *keys(): AsyncIterable<string> {\n if (!this.entry.children) {\n return;\n }\n for (const name of this.entry.children.keys()) {\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 an in-memory directory handle\n * Useful for testing or fully sandboxed environments\n *\n * @example\n * import { createMemoryDirectoryHandle } from \"@ricsam/quickjs-fs\";\n *\n * const memFs = createMemoryDirectoryHandle({\n * \"config.json\": JSON.stringify({ debug: true }),\n * \"data/users.json\": JSON.stringify([]),\n * });\n *\n * const handle = setupFs(context, {\n * getDirectory: async (path) => memFs\n * });\n */\nexport function createMemoryDirectoryHandle(\n initialFiles?: Record<string, string | Uint8Array>\n): HostDirectoryHandle {\n const root: MemoryEntry = {\n kind: \"directory\",\n name: \"\",\n children: new Map(),\n lastModified: Date.now(),\n };\n\n if (initialFiles) {\n for (const [path, content] of Object.entries(initialFiles)) {\n const segments = path.split(\"/\").filter(Boolean);\n let current = root;\n\n // Create directories as needed\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n if (!current.children) {\n current.children = new Map();\n }\n\n let child = current.children.get(segment);\n if (!child) {\n child = {\n kind: \"directory\",\n name: segment,\n children: new Map(),\n lastModified: Date.now(),\n };\n current.children.set(segment, child);\n }\n current = child;\n }\n\n // Create the file\n const fileName = segments[segments.length - 1]!;\n if (!current.children) {\n current.children = new Map();\n }\n\n const fileContent =\n typeof content === \"string\"\n ? new TextEncoder().encode(content)\n : content;\n\n current.children.set(fileName, {\n kind: \"file\",\n name: fileName,\n content: fileContent,\n lastModified: Date.now(),\n });\n }\n }\n\n return new MemoryDirectoryHandle(\"\", root);\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
8
|
"debugId": "EE454A6223A555BF64756E2164756E21",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/node-adapter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.
|
|
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
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
8
|
"debugId": "30BC4BE3F0DE509364756E2164756E21",
|
package/dist/cjs/package.json
CHANGED
package/dist/cjs/setup.cjs
CHANGED
|
@@ -34,9 +34,9 @@ __export(exports_setup, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(exports_setup);
|
|
36
36
|
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
37
|
-
var import_writable_stream = require("./handles/writable-stream.
|
|
38
|
-
var import_file_handle = require("./handles/file-handle.
|
|
39
|
-
var import_directory_handle = require("./handles/directory-handle.
|
|
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
40
|
function setupFs(context, options) {
|
|
41
41
|
const coreHandle = options.coreHandle ?? import_quickjs_core.setupCore(context, {
|
|
42
42
|
stateMap: options.stateMap
|
|
@@ -137,4 +137,4 @@ function setupFs(context, options) {
|
|
|
137
137
|
}
|
|
138
138
|
})
|
|
139
139
|
|
|
140
|
-
//# debugId=
|
|
140
|
+
//# debugId=66CE72DDAD52011C64756E2164756E21
|
package/dist/cjs/setup.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/setup.ts"],
|
|
4
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.
|
|
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
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,IAJP;AAMwD,IAAxD;AACgD,IAAhD;AACkF,IAAlF;AAuDO,SAAS,OAAO,CACrB,SACA,SACU;AAAA,EAEV,MAAM,aACJ,QAAQ,cACR,8BAAU,SAAS;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB,CAAC;AAAA,EAEH,MAAM,WAAW,QAAQ,YAAY,WAAW;AAAA,EAChD,MAAM,UAA2B,CAAC;AAAA,EAGlC,MAAM,sBAAsB,+DAC1B,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,gCACA,mBACF;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,oCAAoC,mBAAmB;AAAA,EACvF,oBAAoB,QAAQ;AAAA,EAG5B,MAAM,kBAAkB,mDACtB,SACA,QACF;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,wBAAwB,eAAe;AAAA,EACvE,QAAQ,QAAQ,QAAQ,QAAQ,4BAA4B,eAAe;AAAA,EAC3E,gBAAgB,QAAQ;AAAA,EAGxB,MAAM,uBAAuB,6DAC3B,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,6BACA,oBACF;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,iCAAiC,oBAAoB;AAAA,EACrF,qBAAqB,QAAQ;AAAA,EAG7B,MAAM,sBAAsB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAO5C;AAAA,EACD,IAAI,oBAAoB,OAAO;AAAA,IAC7B,oBAAoB,MAAM,QAAQ;AAAA,EACpC,EAAO;AAAA,IACL,oBAAoB,MAAM,QAAQ;AAAA;AAAA,EAIpC,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBpB,MAAM,gBAAgB,QAAQ,SAAS,WAAW;AAAA,EAClD,IAAI,cAAc,OAAO;AAAA,IACvB,MAAM,QAAQ,QAAQ,KAAK,cAAc,KAAK;AAAA,IAC9C,cAAc,MAAM,QAAQ;AAAA,IAC5B,MAAM,IAAI,MAAM,wCAAwC,KAAK,UAAU,KAAK,GAAG;AAAA,EACjF;AAAA,EACA,cAAc,MAAM,QAAQ;AAAA,EAG5B,MAAM,cAAc,QAAQ,UAAU;AAAA,EAGtC,MAAM,iBAAiB,QAAQ,YAAY,gBAAgB,CAAC,eAAe;AAAA,IACzE,MAAM,OAAO,QAAQ,UAAU,UAAU;AAAA,IAEzC,MAAM,WAAW,QAAQ,WAAW;AAAA,IAEpC,QACG,aAAa,IAAI,EACjB,KAAK,CAAC,eAAe;AAAA,MAEpB,MAAM,eAAe,oDAA4B,UAAU;AAAA,MAG3D,MAAM,iBAAiB,QAAQ,SAC7B,qCAAqC,eACvC;AAAA,MAEA,IAAI,eAAe,OAAO;AAAA,QACxB,SAAS,OAAO,eAAe,KAAK;AAAA,QACpC,eAAe,MAAM,QAAQ;AAAA,MAC/B,EAAO;AAAA,QACL,SAAS,QAAQ,eAAe,KAAK;AAAA,QACrC,eAAe,MAAM,QAAQ;AAAA;AAAA,MAE/B,QAAQ,QAAQ,mBAAmB;AAAA,KACpC,EACA,MAAM,CAAC,UAAU;AAAA,MAChB,MAAM,cAAc,4BAAQ,SAAS;AAAA,QACnC,MAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,QAC5C,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAChE,CAAC;AAAA,MACD,SAAS,OAAO,WAAW;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,QAAQ,QAAQ,mBAAmB;AAAA,KACpC;AAAA,IAEH,OAAO,SAAS;AAAA,GACjB;AAAA,EACD,QAAQ,KAAK,cAAc;AAAA,EAC3B,QAAQ,QAAQ,aAAa,gBAAgB,cAAc;AAAA,EAE3D,QAAQ,QAAQ,QAAQ,QAAQ,MAAM,WAAW;AAAA,EACjD,YAAY,QAAQ;AAAA,EAEpB,OAAO;AAAA,IACL;AAAA,IACA,OAAO,GAAG;AAAA,MACR,WAAW,UAAU,SAAS;AAAA,QAC5B,IAAI,OAAO,OAAO;AAAA,UAChB,OAAO,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA;AAAA,EAEJ;AAAA;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "66CE72DDAD52011C64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/fs/src/handles/directory-handle.ts
|
|
3
3
|
import { defineClass } from "@ricsam/quickjs-core";
|
|
4
|
-
import { registerHostFileHandle } from "./file-handle.
|
|
4
|
+
import { registerHostFileHandle } from "./file-handle.mjs";
|
|
5
5
|
var nextHostHandleId = 0;
|
|
6
6
|
var pendingHostHandles = new Map;
|
|
7
7
|
function registerHostDirectoryHandle(handle) {
|
|
@@ -132,4 +132,4 @@ export {
|
|
|
132
132
|
createFileSystemDirectoryHandleClass
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
//# debugId=
|
|
135
|
+
//# debugId=F0BD0146F4CA709E64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/handles/directory-handle.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type {\n FileSystemDirectoryHandleState,\n FileSystemFileHandleState,\n HostDirectoryHandle,\n} from \"../types.mjs\";\nimport { registerHostFileHandle } from \"./file-handle.mjs\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextHostHandleId = 0;\nexport const pendingHostHandles = new Map<\n number,\n { handle: HostDirectoryHandle; name: string }\n>();\n\nexport function registerHostDirectoryHandle(\n handle: HostDirectoryHandle\n): number {\n const id = nextHostHandleId++;\n pendingHostHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\n/**\n * Create the FileSystemDirectoryHandle class for QuickJS\n */\nexport function createFileSystemDirectoryHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemDirectoryHandleState>(context, stateMap, {\n name: \"FileSystemDirectoryHandle\",\n construct: (args) => {\n // First argument is the host handle ID\n const hostHandleId = args[0] as number;\n const pending = pendingHostHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending host handle with ID ${hostHandleId}`);\n }\n pendingHostHandles.delete(hostHandleId);\n return {\n kind: \"directory\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemDirectoryHandleState) {\n return \"directory\";\n },\n },\n name: {\n get(this: FileSystemDirectoryHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async _getFileHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __fileHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostFile = await this.hostHandle.getFileHandle(String(name), {\n create: opts?.create,\n });\n\n return { __fileHandleId: registerHostFileHandle(hostFile) };\n },\n async _getDirectoryHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __directoryHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostDir = await this.hostHandle.getDirectoryHandle(String(name), {\n create: opts?.create,\n });\n\n return { __directoryHandleId: registerHostDirectoryHandle(hostDir) };\n },\n async removeEntry(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<void> {\n const opts = options as { recursive?: boolean } | undefined;\n await this.hostHandle.removeEntry(String(name), {\n recursive: opts?.recursive,\n });\n },\n async resolve(\n this: FileSystemDirectoryHandleState,\n possibleDescendant: unknown\n ): Promise<string[] | null> {\n if (!possibleDescendant || typeof possibleDescendant !== \"object\") {\n return null;\n }\n\n const descendant = possibleDescendant as\n | FileSystemFileHandleState\n | FileSystemDirectoryHandleState;\n return this.hostHandle.resolve(descendant.hostHandle);\n },\n async entries(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n >\n > {\n const result: Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n > = [];\n\n for await (const [name, handle] of this.hostHandle.entries()) {\n if (handle.kind === \"file\") {\n result.push([\n name,\n {\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n } else {\n result.push([\n name,\n {\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n }\n }\n\n return result;\n },\n async keys(this: FileSystemDirectoryHandleState): Promise<string[]> {\n const result: string[] = [];\n for await (const name of this.hostHandle.keys()) {\n result.push(name);\n }\n return result;\n },\n async values(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<FileSystemFileHandleState | FileSystemDirectoryHandleState>\n > {\n const result: Array<\n FileSystemFileHandleState | FileSystemDirectoryHandleState\n > = [];\n\n for await (const handle of this.hostHandle.values()) {\n if (handle.kind === \"file\") {\n result.push({\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n });\n } else {\n result.push({\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n });\n }\n }\n\n return result;\n },\n async isSameEntry(\n this: FileSystemDirectoryHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemDirectoryHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "F0BD0146F4CA709E64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/handles/file-handle.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 { FileSystemFileHandleState, HostFileHandle, HostWritableFileStream } from \"../types.mjs\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextFileHandleId = 0;\nexport const pendingFileHandles = new Map<number, { handle: HostFileHandle; name: string }>();\nlet nextWritableStreamId = 0;\nexport const pendingWritableStreams = new Map<number, HostWritableFileStream>();\n\nexport function registerHostFileHandle(handle: HostFileHandle): number {\n const id = nextFileHandleId++;\n pendingFileHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\nexport function registerHostWritableStream(stream: HostWritableFileStream): number {\n const id = nextWritableStreamId++;\n pendingWritableStreams.set(id, stream);\n return id;\n}\n\n/**\n * Create the FileSystemFileHandle class for QuickJS\n */\nexport function createFileSystemFileHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemFileHandleState>(context, stateMap, {\n name: \"FileSystemFileHandle\",\n construct: (args) => {\n const hostHandleId = args[0] as number;\n const pending = pendingFileHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending file handle with ID ${hostHandleId}`);\n }\n pendingFileHandles.delete(hostHandleId);\n return {\n kind: \"file\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemFileHandleState) {\n return \"file\";\n },\n },\n name: {\n get(this: FileSystemFileHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async getFile(this: FileSystemFileHandleState): Promise<object> {\n const file = await this.hostHandle.getFile();\n\n // Convert native File to our internal File representation\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n return {\n parts: [data],\n type: file.type,\n size: file.size,\n name: file.name,\n lastModified: file.lastModified,\n webkitRelativePath: \"\",\n // Include methods that will be recognized\n async text() {\n return new TextDecoder().decode(data);\n },\n async arrayBuffer() {\n return buffer;\n },\n async bytes() {\n return data;\n },\n };\n },\n async _createWritableInternal(\n this: FileSystemFileHandleState,\n options?: unknown\n ): Promise<{ __writableStreamId: number }> {\n const opts = options as { keepExistingData?: boolean } | undefined;\n const hostStream = await this.hostHandle.createWritable({\n keepExistingData: opts?.keepExistingData,\n });\n\n return { __writableStreamId: registerHostWritableStream(hostStream) };\n },\n async isSameEntry(\n this: FileSystemFileHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemFileHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;AAEA;AAIA,IAAI,mBAAmB;AAChB,IAAM,qBAAqB,IAAI;AACtC,IAAI,uBAAuB;AACpB,IAAM,yBAAyB,IAAI;AAEnC,SAAS,sBAAsB,CAAC,QAAgC;AAAA,EACrE,MAAM,KAAK;AAAA,EACX,mBAAmB,IAAI,IAAI,EAAE,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,EACxD,OAAO;AAAA;AAGF,SAAS,0BAA0B,CAAC,QAAwC;AAAA,EACjF,MAAM,KAAK;AAAA,EACX,uBAAuB,IAAI,IAAI,MAAM;AAAA,EACrC,OAAO;AAAA;AAMF,SAAS,+BAA+B,CAC7C,SACA,UACe;AAAA,EACf,OAAO,YAAuC,SAAS,UAAU;AAAA,IAC/D,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,eAAe,KAAK;AAAA,MAC1B,MAAM,UAAU,mBAAmB,IAAI,YAAY;AAAA,MACnD,IAAI,CAAC,SAAS;AAAA,QACZ,MAAM,IAAI,MAAM,kCAAkC,cAAc;AAAA,MAClE;AAAA,MACA,mBAAmB,OAAO,YAAY;AAAA,MACtC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO;AAAA;AAAA,MAEX;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,QAAO,GAAmD;AAAA,QAC9D,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ;AAAA,QAG3C,MAAM,SAAS,MAAM,KAAK,YAAY;AAAA,QACtC,MAAM,OAAO,IAAI,WAAW,MAAM;AAAA,QAElC,OAAO;AAAA,UACL,OAAO,CAAC,IAAI;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,cAAc,KAAK;AAAA,UACnB,oBAAoB;AAAA,eAEd,KAAI,GAAG;AAAA,YACX,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA;AAAA,eAEhC,YAAW,GAAG;AAAA,YAClB,OAAO;AAAA;AAAA,eAEH,MAAK,GAAG;AAAA,YACZ,OAAO;AAAA;AAAA,QAEX;AAAA;AAAA,WAEI,wBAAuB,CAE3B,SACyC;AAAA,QACzC,MAAM,OAAO;AAAA,QACb,MAAM,aAAa,MAAM,KAAK,WAAW,eAAe;AAAA,UACtD,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,QAED,OAAO,EAAE,oBAAoB,2BAA2B,UAAU,EAAE;AAAA;AAAA,WAEhE,YAAW,CAEf,OACkB;AAAA,QAClB,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AAAA,UACvC,OAAO;AAAA,QACT;AAAA,QACA,MAAM,cAAc;AAAA,QACpB,OAAO,KAAK,eAAe,YAAY;AAAA;AAAA,IAE3C;AAAA,EACF,CAAC;AAAA;",
|
|
8
|
+
"debugId": "F8BEEB6B16C7A8BF64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/fs/src/handles/writable-stream.ts
|
|
3
3
|
import { defineClass } from "@ricsam/quickjs-core";
|
|
4
|
-
import { pendingWritableStreams } from "./file-handle.
|
|
4
|
+
import { pendingWritableStreams } from "./file-handle.mjs";
|
|
5
5
|
function createFileSystemWritableFileStreamClass(context, stateMap) {
|
|
6
6
|
return defineClass(context, stateMap, {
|
|
7
7
|
name: "FileSystemWritableFileStream",
|
|
@@ -85,4 +85,4 @@ export {
|
|
|
85
85
|
createFileSystemWritableFileStreamClass
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
//# debugId=
|
|
88
|
+
//# debugId=B236E2EB6FE3A03F64756E2164756E21
|
|
@@ -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.mjs\";\nimport { pendingWritableStreams } from \"./file-handle.mjs\";\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": ";;AAEA;AAMA;AAKO,SAAS,uCAAuC,CACrD,SACA,UACe;AAAA,EACf,OAAO,YAA+C,SAAS,UAAU;AAAA,IACvE,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,WAAW,KAAK;AAAA,MACtB,MAAM,aAAa,uBAAuB,IAAI,QAAQ;AAAA,MACtD,IAAI,CAAC,YAAY;AAAA,QACf,MAAM,IAAI,MAAM,sCAAsC,UAAU;AAAA,MAClE;AAAA,MACA,uBAAuB,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": "B236E2EB6FE3A03F64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/mjs/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/fs/src/index.ts
|
|
3
|
-
import { setupFs } from "./setup.
|
|
4
|
-
import { createNodeDirectoryHandle } from "./node-adapter.
|
|
5
|
-
import { createMemoryDirectoryHandle } from "./memory-adapter.
|
|
3
|
+
import { setupFs } from "./setup.mjs";
|
|
4
|
+
import { createNodeDirectoryHandle } from "./node-adapter.mjs";
|
|
5
|
+
import { createMemoryDirectoryHandle } from "./memory-adapter.mjs";
|
|
6
6
|
export {
|
|
7
7
|
setupFs,
|
|
8
8
|
createNodeDirectoryHandle,
|
|
9
9
|
createMemoryDirectoryHandle
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
//# debugId=
|
|
12
|
+
//# debugId=17679FAE5ACEB98264756E2164756E21
|
package/dist/mjs/index.mjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export { setupFs } from \"./setup.
|
|
5
|
+
"export { setupFs } from \"./setup.mjs\";\nexport { createNodeDirectoryHandle } from \"./node-adapter.mjs\";\nexport { createMemoryDirectoryHandle } from \"./memory-adapter.mjs\";\n\nexport type {\n SetupFsOptions,\n FsHandle,\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.mjs\";\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;AAAA;AACA;AACA;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "17679FAE5ACEB98264756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/memory-adapter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.
|
|
5
|
+
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.mjs\";\n\ninterface MemoryEntry {\n kind: \"file\" | \"directory\";\n name: string;\n content?: Uint8Array;\n children?: Map<string, MemoryEntry>;\n lastModified: number;\n type?: string;\n}\n\n/**\n * In-memory file handle implementation\n */\nclass MemoryFileHandle implements HostFileHandle {\n readonly kind = \"file\" as const;\n\n constructor(\n public readonly name: string,\n private entry: MemoryEntry\n ) {}\n\n async getFile(): Promise<File> {\n const content = this.entry.content ?? new Uint8Array();\n return new File([content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength) as ArrayBuffer], this.name, {\n type: this.entry.type || \"application/octet-stream\",\n lastModified: this.entry.lastModified,\n });\n }\n\n async createWritable(\n options?: { keepExistingData?: boolean }\n ): Promise<HostWritableFileStream> {\n return new MemoryWritableFileStream(\n this.entry,\n options?.keepExistingData ?? false\n );\n }\n}\n\n/**\n * In-memory writable file stream implementation\n */\nclass MemoryWritableFileStream implements HostWritableFileStream {\n private buffer: Uint8Array;\n private position = 0;\n\n constructor(\n private entry: MemoryEntry,\n keepExistingData: boolean\n ) {\n if (keepExistingData && this.entry.content) {\n this.buffer = new Uint8Array(this.entry.content);\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 this.entry.content = this.buffer;\n this.entry.lastModified = Date.now();\n }\n\n async abort(_reason?: unknown): Promise<void> {\n // Don't save, just discard\n }\n}\n\n/**\n * In-memory directory handle implementation\n */\nclass MemoryDirectoryHandle implements HostDirectoryHandle {\n readonly kind = \"directory\" as const;\n\n constructor(\n public readonly name: string,\n private entry: MemoryEntry\n ) {}\n\n async getFileHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostFileHandle> {\n if (!this.entry.children) {\n this.entry.children = new Map();\n }\n\n let child = this.entry.children.get(name);\n\n if (!child) {\n if (!options?.create) {\n throw new DOMException(`File not found: ${name}`, \"NotFoundError\");\n }\n child = {\n kind: \"file\",\n name,\n content: new Uint8Array(0),\n lastModified: Date.now(),\n };\n this.entry.children.set(name, child);\n }\n\n if (child.kind !== \"file\") {\n throw new DOMException(\n `${name} is not a file`,\n \"TypeMismatchError\"\n );\n }\n\n return new MemoryFileHandle(name, child);\n }\n\n async getDirectoryHandle(\n name: string,\n options?: { create?: boolean }\n ): Promise<HostDirectoryHandle> {\n if (!this.entry.children) {\n this.entry.children = new Map();\n }\n\n let child = this.entry.children.get(name);\n\n if (!child) {\n if (!options?.create) {\n throw new DOMException(\n `Directory not found: ${name}`,\n \"NotFoundError\"\n );\n }\n child = {\n kind: \"directory\",\n name,\n children: new Map(),\n lastModified: Date.now(),\n };\n this.entry.children.set(name, child);\n }\n\n if (child.kind !== \"directory\") {\n throw new DOMException(\n `${name} is not a directory`,\n \"TypeMismatchError\"\n );\n }\n\n return new MemoryDirectoryHandle(name, child);\n }\n\n async removeEntry(\n name: string,\n options?: { recursive?: boolean }\n ): Promise<void> {\n if (!this.entry.children) {\n throw new DOMException(`Entry not found: ${name}`, \"NotFoundError\");\n }\n\n const child = this.entry.children.get(name);\n if (!child) {\n throw new DOMException(`Entry not found: ${name}`, \"NotFoundError\");\n }\n\n if (child.kind === \"directory\" && child.children?.size && !options?.recursive) {\n throw new DOMException(\n `Directory is not empty: ${name}`,\n \"InvalidModificationError\"\n );\n }\n\n this.entry.children.delete(name);\n }\n\n async resolve(\n possibleDescendant: HostFileHandle | HostDirectoryHandle\n ): Promise<string[] | null> {\n // Simplified implementation - just check if it's a direct child\n const descendantName = possibleDescendant.name;\n if (this.entry.children?.has(descendantName)) {\n return [descendantName];\n }\n return null;\n }\n\n async *entries(): AsyncIterable<\n [string, HostFileHandle | HostDirectoryHandle]\n > {\n if (!this.entry.children) {\n return;\n }\n\n for (const [name, child] of this.entry.children) {\n if (child.kind === \"file\") {\n yield [name, new MemoryFileHandle(name, child)];\n } else {\n yield [name, new MemoryDirectoryHandle(name, child)];\n }\n }\n }\n\n async *keys(): AsyncIterable<string> {\n if (!this.entry.children) {\n return;\n }\n for (const name of this.entry.children.keys()) {\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 an in-memory directory handle\n * Useful for testing or fully sandboxed environments\n *\n * @example\n * import { createMemoryDirectoryHandle } from \"@ricsam/quickjs-fs\";\n *\n * const memFs = createMemoryDirectoryHandle({\n * \"config.json\": JSON.stringify({ debug: true }),\n * \"data/users.json\": JSON.stringify([]),\n * });\n *\n * const handle = setupFs(context, {\n * getDirectory: async (path) => memFs\n * });\n */\nexport function createMemoryDirectoryHandle(\n initialFiles?: Record<string, string | Uint8Array>\n): HostDirectoryHandle {\n const root: MemoryEntry = {\n kind: \"directory\",\n name: \"\",\n children: new Map(),\n lastModified: Date.now(),\n };\n\n if (initialFiles) {\n for (const [path, content] of Object.entries(initialFiles)) {\n const segments = path.split(\"/\").filter(Boolean);\n let current = root;\n\n // Create directories as needed\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n if (!current.children) {\n current.children = new Map();\n }\n\n let child = current.children.get(segment);\n if (!child) {\n child = {\n kind: \"directory\",\n name: segment,\n children: new Map(),\n lastModified: Date.now(),\n };\n current.children.set(segment, child);\n }\n current = child;\n }\n\n // Create the file\n const fileName = segments[segments.length - 1]!;\n if (!current.children) {\n current.children = new Map();\n }\n\n const fileContent =\n typeof content === \"string\"\n ? new TextEncoder().encode(content)\n : content;\n\n current.children.set(fileName, {\n kind: \"file\",\n name: fileName,\n content: fileContent,\n lastModified: Date.now(),\n });\n }\n }\n\n return new MemoryDirectoryHandle(\"\", root);\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;AAmBA,MAAM,iBAA2C;AAAA,EAI7B;AAAA,EACR;AAAA,EAJD,OAAO;AAAA,EAEhB,WAAW,CACO,MACR,OACR;AAAA,IAFgB;AAAA,IACR;AAAA;AAAA,OAGJ,QAAO,GAAkB;AAAA,IAC7B,MAAM,UAAU,KAAK,MAAM,WAAW,IAAI;AAAA,IAC1C,OAAO,IAAI,KAAK,CAAC,QAAQ,OAAO,MAAM,QAAQ,YAAY,QAAQ,aAAa,QAAQ,UAAU,CAAgB,GAAG,KAAK,MAAM;AAAA,MAC7H,MAAM,KAAK,MAAM,QAAQ;AAAA,MACzB,cAAc,KAAK,MAAM;AAAA,IAC3B,CAAC;AAAA;AAAA,OAGG,eAAc,CAClB,SACiC;AAAA,IACjC,OAAO,IAAI,yBACT,KAAK,OACL,SAAS,oBAAoB,KAC/B;AAAA;AAEJ;AAAA;AAKA,MAAM,yBAA2D;AAAA,EAKrD;AAAA,EAJF;AAAA,EACA,WAAW;AAAA,EAEnB,WAAW,CACD,OACR,kBACA;AAAA,IAFQ;AAAA,IAGR,IAAI,oBAAoB,KAAK,MAAM,SAAS;AAAA,MAC1C,KAAK,SAAS,IAAI,WAAW,KAAK,MAAM,OAAO;AAAA,IACjD,EAAO;AAAA,MACL,KAAK,SAAS,IAAI,WAAW,CAAC;AAAA;AAAA;AAAA,OAI5B,MAAK,CACT,MACe;AAAA,IACf,IAAI;AAAA,IAEJ,IAAI,OAAO,SAAS,UAAU;AAAA,MAC5B,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA,IACvC,EAAO,SAAI,gBAAgB,aAAa;AAAA,MACtC,QAAQ,IAAI,WAAW,IAAI;AAAA,IAC7B,EAAO,SAAI,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,IACV,EAAO,SAAI,gBAAgB,MAAM;AAAA,MAC/B,QAAQ,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AAAA,IACjD,EAAO;AAAA,MAEL,IAAI,KAAK,SAAS,QAAQ;AAAA,QACxB,KAAK,WAAW,KAAK,YAAY;AAAA,QACjC;AAAA,MACF;AAAA,MACA,IAAI,KAAK,SAAS,YAAY;AAAA,QAC5B,KAAK,SAAS,KAAK,OAAO,MAAM,GAAG,KAAK,QAAQ,CAAC;AAAA,QACjD,IAAI,KAAK,WAAW,KAAK,OAAO,QAAQ;AAAA,UACtC,KAAK,WAAW,KAAK,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,MACF;AAAA,MAEA,IAAI,KAAK,SAAS;AAAA,QAAW;AAAA,MAC7B,OAAO,KAAK,MAAM,KAAK,IAAI;AAAA;AAAA,IAI7B,MAAM,aAAa,KAAK,WAAW,MAAM;AAAA,IACzC,IAAI,aAAa,KAAK,OAAO,QAAQ;AAAA,MACnC,MAAM,YAAY,IAAI,WAAW,UAAU;AAAA,MAC3C,UAAU,IAAI,KAAK,MAAM;AAAA,MACzB,KAAK,SAAS;AAAA,IAChB;AAAA,IAEA,KAAK,OAAO,IAAI,OAAO,KAAK,QAAQ;AAAA,IACpC,KAAK,YAAY,MAAM;AAAA;AAAA,OAGnB,KAAI,CAAC,UAAiC;AAAA,IAC1C,KAAK,WAAW;AAAA;AAAA,OAGZ,SAAQ,CAAC,MAA6B;AAAA,IAC1C,IAAI,OAAO,KAAK,OAAO,QAAQ;AAAA,MAC7B,KAAK,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI;AAAA,IACzC,EAAO,SAAI,OAAO,KAAK,OAAO,QAAQ;AAAA,MACpC,MAAM,YAAY,IAAI,WAAW,IAAI;AAAA,MACrC,UAAU,IAAI,KAAK,MAAM;AAAA,MACzB,KAAK,SAAS;AAAA,IAChB;AAAA,IACA,IAAI,KAAK,WAAW,MAAM;AAAA,MACxB,KAAK,WAAW;AAAA,IAClB;AAAA;AAAA,OAGI,MAAK,GAAkB;AAAA,IAC3B,KAAK,MAAM,UAAU,KAAK;AAAA,IAC1B,KAAK,MAAM,eAAe,KAAK,IAAI;AAAA;AAAA,OAG/B,MAAK,CAAC,SAAkC;AAGhD;AAAA;AAKA,MAAM,sBAAqD;AAAA,EAIvC;AAAA,EACR;AAAA,EAJD,OAAO;AAAA,EAEhB,WAAW,CACO,MACR,OACR;AAAA,IAFgB;AAAA,IACR;AAAA;AAAA,OAGJ,cAAa,CACjB,MACA,SACyB;AAAA,IACzB,IAAI,CAAC,KAAK,MAAM,UAAU;AAAA,MACxB,KAAK,MAAM,WAAW,IAAI;AAAA,IAC5B;AAAA,IAEA,IAAI,QAAQ,KAAK,MAAM,SAAS,IAAI,IAAI;AAAA,IAExC,IAAI,CAAC,OAAO;AAAA,MACV,IAAI,CAAC,SAAS,QAAQ;AAAA,QACpB,MAAM,IAAI,aAAa,mBAAmB,QAAQ,eAAe;AAAA,MACnE;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,SAAS,IAAI,WAAW,CAAC;AAAA,QACzB,cAAc,KAAK,IAAI;AAAA,MACzB;AAAA,MACA,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK;AAAA,IACrC;AAAA,IAEA,IAAI,MAAM,SAAS,QAAQ;AAAA,MACzB,MAAM,IAAI,aACR,GAAG,sBACH,mBACF;AAAA,IACF;AAAA,IAEA,OAAO,IAAI,iBAAiB,MAAM,KAAK;AAAA;AAAA,OAGnC,mBAAkB,CACtB,MACA,SAC8B;AAAA,IAC9B,IAAI,CAAC,KAAK,MAAM,UAAU;AAAA,MACxB,KAAK,MAAM,WAAW,IAAI;AAAA,IAC5B;AAAA,IAEA,IAAI,QAAQ,KAAK,MAAM,SAAS,IAAI,IAAI;AAAA,IAExC,IAAI,CAAC,OAAO;AAAA,MACV,IAAI,CAAC,SAAS,QAAQ;AAAA,QACpB,MAAM,IAAI,aACR,wBAAwB,QACxB,eACF;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,UAAU,IAAI;AAAA,QACd,cAAc,KAAK,IAAI;AAAA,MACzB;AAAA,MACA,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK;AAAA,IACrC;AAAA,IAEA,IAAI,MAAM,SAAS,aAAa;AAAA,MAC9B,MAAM,IAAI,aACR,GAAG,2BACH,mBACF;AAAA,IACF;AAAA,IAEA,OAAO,IAAI,sBAAsB,MAAM,KAAK;AAAA;AAAA,OAGxC,YAAW,CACf,MACA,SACe;AAAA,IACf,IAAI,CAAC,KAAK,MAAM,UAAU;AAAA,MACxB,MAAM,IAAI,aAAa,oBAAoB,QAAQ,eAAe;AAAA,IACpE;AAAA,IAEA,MAAM,QAAQ,KAAK,MAAM,SAAS,IAAI,IAAI;AAAA,IAC1C,IAAI,CAAC,OAAO;AAAA,MACV,MAAM,IAAI,aAAa,oBAAoB,QAAQ,eAAe;AAAA,IACpE;AAAA,IAEA,IAAI,MAAM,SAAS,eAAe,MAAM,UAAU,QAAQ,CAAC,SAAS,WAAW;AAAA,MAC7E,MAAM,IAAI,aACR,2BAA2B,QAC3B,0BACF;AAAA,IACF;AAAA,IAEA,KAAK,MAAM,SAAS,OAAO,IAAI;AAAA;AAAA,OAG3B,QAAO,CACX,oBAC0B;AAAA,IAE1B,MAAM,iBAAiB,mBAAmB;AAAA,IAC1C,IAAI,KAAK,MAAM,UAAU,IAAI,cAAc,GAAG;AAAA,MAC5C,OAAO,CAAC,cAAc;AAAA,IACxB;AAAA,IACA,OAAO;AAAA;AAAA,SAGF,OAAO,GAEZ;AAAA,IACA,IAAI,CAAC,KAAK,MAAM,UAAU;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,YAAY,MAAM,UAAU,KAAK,MAAM,UAAU;AAAA,MAC/C,IAAI,MAAM,SAAS,QAAQ;AAAA,QACzB,MAAM,CAAC,MAAM,IAAI,iBAAiB,MAAM,KAAK,CAAC;AAAA,MAChD,EAAO;AAAA,QACL,MAAM,CAAC,MAAM,IAAI,sBAAsB,MAAM,KAAK,CAAC;AAAA;AAAA,IAEvD;AAAA;AAAA,SAGK,IAAI,GAA0B;AAAA,IACnC,IAAI,CAAC,KAAK,MAAM,UAAU;AAAA,MACxB;AAAA,IACF;AAAA,IACA,WAAW,QAAQ,KAAK,MAAM,SAAS,KAAK,GAAG;AAAA,MAC7C,MAAM;AAAA,IACR;AAAA;AAAA,SAGK,MAAM,GAAwD;AAAA,IACnE,oBAAoB,WAAW,KAAK,QAAQ,GAAG;AAAA,MAC7C,MAAM;AAAA,IACR;AAAA;AAEJ;AAkBO,SAAS,2BAA2B,CACzC,cACqB;AAAA,EACrB,MAAM,OAAoB;AAAA,IACxB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU,IAAI;AAAA,IACd,cAAc,KAAK,IAAI;AAAA,EACzB;AAAA,EAEA,IAAI,cAAc;AAAA,IAChB,YAAY,MAAM,YAAY,OAAO,QAAQ,YAAY,GAAG;AAAA,MAC1D,MAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,MAC/C,IAAI,UAAU;AAAA,MAGd,SAAS,IAAI,EAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAAA,QAC5C,MAAM,UAAU,SAAS;AAAA,QACzB,IAAI,CAAC,QAAQ,UAAU;AAAA,UACrB,QAAQ,WAAW,IAAI;AAAA,QACzB;AAAA,QAEA,IAAI,QAAQ,QAAQ,SAAS,IAAI,OAAO;AAAA,QACxC,IAAI,CAAC,OAAO;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,UAAU,IAAI;AAAA,YACd,cAAc,KAAK,IAAI;AAAA,UACzB;AAAA,UACA,QAAQ,SAAS,IAAI,SAAS,KAAK;AAAA,QACrC;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,MAGA,MAAM,WAAW,SAAS,SAAS,SAAS;AAAA,MAC5C,IAAI,CAAC,QAAQ,UAAU;AAAA,QACrB,QAAQ,WAAW,IAAI;AAAA,MACzB;AAAA,MAEA,MAAM,cACJ,OAAO,YAAY,WACf,IAAI,YAAY,EAAE,OAAO,OAAO,IAChC;AAAA,MAEN,QAAQ,SAAS,IAAI,UAAU;AAAA,QAC7B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,cAAc,KAAK,IAAI;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO,IAAI,sBAAsB,IAAI,IAAI;AAAA;",
|
|
8
8
|
"debugId": "842484F7D90E977364756E2164756E21",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/node-adapter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.
|
|
5
|
+
"import type {\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.mjs\";\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
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
8
|
"debugId": "D92FD9559FCFEFE664756E2164756E21",
|
package/dist/mjs/package.json
CHANGED
package/dist/mjs/setup.mjs
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
setupCore,
|
|
5
5
|
marshal
|
|
6
6
|
} from "@ricsam/quickjs-core";
|
|
7
|
-
import { createFileSystemWritableFileStreamClass } from "./handles/writable-stream.
|
|
8
|
-
import { createFileSystemFileHandleClass } from "./handles/file-handle.
|
|
9
|
-
import { createFileSystemDirectoryHandleClass, registerHostDirectoryHandle } from "./handles/directory-handle.
|
|
7
|
+
import { createFileSystemWritableFileStreamClass } from "./handles/writable-stream.mjs";
|
|
8
|
+
import { createFileSystemFileHandleClass } from "./handles/file-handle.mjs";
|
|
9
|
+
import { createFileSystemDirectoryHandleClass, registerHostDirectoryHandle } from "./handles/directory-handle.mjs";
|
|
10
10
|
function setupFs(context, options) {
|
|
11
11
|
const coreHandle = options.coreHandle ?? setupCore(context, {
|
|
12
12
|
stateMap: options.stateMap
|
|
@@ -109,4 +109,4 @@ export {
|
|
|
109
109
|
setupFs
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
-
//# debugId=
|
|
112
|
+
//# debugId=4F5B9AAC430B117764756E2164756E21
|
package/dist/mjs/setup.mjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/setup.ts"],
|
|
4
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.
|
|
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.mjs\";\nimport { createFileSystemWritableFileStreamClass } from \"./handles/writable-stream.mjs\";\nimport { createFileSystemFileHandleClass } from \"./handles/file-handle.mjs\";\nimport { createFileSystemDirectoryHandleClass, registerHostDirectoryHandle } from \"./handles/directory-handle.mjs\";\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
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "4F5B9AAC430B117764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/quickjs-fs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"main": "./dist/cjs/index.cjs",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"typecheck": "tsc --noEmit"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@ricsam/quickjs-core": "^0.2.
|
|
19
|
+
"@ricsam/quickjs-core": "^0.2.3",
|
|
20
20
|
"quickjs-emscripten": "^0.31.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/handles/directory-handle.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type {\n FileSystemDirectoryHandleState,\n FileSystemFileHandleState,\n HostDirectoryHandle,\n} from \"../types.ts\";\nimport { registerHostFileHandle } from \"./file-handle.ts\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextHostHandleId = 0;\nexport const pendingHostHandles = new Map<\n number,\n { handle: HostDirectoryHandle; name: string }\n>();\n\nexport function registerHostDirectoryHandle(\n handle: HostDirectoryHandle\n): number {\n const id = nextHostHandleId++;\n pendingHostHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\n/**\n * Create the FileSystemDirectoryHandle class for QuickJS\n */\nexport function createFileSystemDirectoryHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemDirectoryHandleState>(context, stateMap, {\n name: \"FileSystemDirectoryHandle\",\n construct: (args) => {\n // First argument is the host handle ID\n const hostHandleId = args[0] as number;\n const pending = pendingHostHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending host handle with ID ${hostHandleId}`);\n }\n pendingHostHandles.delete(hostHandleId);\n return {\n kind: \"directory\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemDirectoryHandleState) {\n return \"directory\";\n },\n },\n name: {\n get(this: FileSystemDirectoryHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async _getFileHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __fileHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostFile = await this.hostHandle.getFileHandle(String(name), {\n create: opts?.create,\n });\n\n return { __fileHandleId: registerHostFileHandle(hostFile) };\n },\n async _getDirectoryHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __directoryHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostDir = await this.hostHandle.getDirectoryHandle(String(name), {\n create: opts?.create,\n });\n\n return { __directoryHandleId: registerHostDirectoryHandle(hostDir) };\n },\n async removeEntry(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<void> {\n const opts = options as { recursive?: boolean } | undefined;\n await this.hostHandle.removeEntry(String(name), {\n recursive: opts?.recursive,\n });\n },\n async resolve(\n this: FileSystemDirectoryHandleState,\n possibleDescendant: unknown\n ): Promise<string[] | null> {\n if (!possibleDescendant || typeof possibleDescendant !== \"object\") {\n return null;\n }\n\n const descendant = possibleDescendant as\n | FileSystemFileHandleState\n | FileSystemDirectoryHandleState;\n return this.hostHandle.resolve(descendant.hostHandle);\n },\n async entries(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n >\n > {\n const result: Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n > = [];\n\n for await (const [name, handle] of this.hostHandle.entries()) {\n if (handle.kind === \"file\") {\n result.push([\n name,\n {\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n } else {\n result.push([\n name,\n {\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n }\n }\n\n return result;\n },\n async keys(this: FileSystemDirectoryHandleState): Promise<string[]> {\n const result: string[] = [];\n for await (const name of this.hostHandle.keys()) {\n result.push(name);\n }\n return result;\n },\n async values(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<FileSystemFileHandleState | FileSystemDirectoryHandleState>\n > {\n const result: Array<\n FileSystemFileHandleState | FileSystemDirectoryHandleState\n > = [];\n\n for await (const handle of this.hostHandle.values()) {\n if (handle.kind === \"file\") {\n result.push({\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n });\n } else {\n result.push({\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n });\n }\n }\n\n return result;\n },\n async isSameEntry(\n this: FileSystemDirectoryHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemDirectoryHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "9FF50EE4CEB5814A64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/handles/file-handle.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 { FileSystemFileHandleState, HostFileHandle, HostWritableFileStream } from \"../types.ts\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextFileHandleId = 0;\nexport const pendingFileHandles = new Map<number, { handle: HostFileHandle; name: string }>();\nlet nextWritableStreamId = 0;\nexport const pendingWritableStreams = new Map<number, HostWritableFileStream>();\n\nexport function registerHostFileHandle(handle: HostFileHandle): number {\n const id = nextFileHandleId++;\n pendingFileHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\nexport function registerHostWritableStream(stream: HostWritableFileStream): number {\n const id = nextWritableStreamId++;\n pendingWritableStreams.set(id, stream);\n return id;\n}\n\n/**\n * Create the FileSystemFileHandle class for QuickJS\n */\nexport function createFileSystemFileHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemFileHandleState>(context, stateMap, {\n name: \"FileSystemFileHandle\",\n construct: (args) => {\n const hostHandleId = args[0] as number;\n const pending = pendingFileHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending file handle with ID ${hostHandleId}`);\n }\n pendingFileHandles.delete(hostHandleId);\n return {\n kind: \"file\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemFileHandleState) {\n return \"file\";\n },\n },\n name: {\n get(this: FileSystemFileHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async getFile(this: FileSystemFileHandleState): Promise<object> {\n const file = await this.hostHandle.getFile();\n\n // Convert native File to our internal File representation\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n return {\n parts: [data],\n type: file.type,\n size: file.size,\n name: file.name,\n lastModified: file.lastModified,\n webkitRelativePath: \"\",\n // Include methods that will be recognized\n async text() {\n return new TextDecoder().decode(data);\n },\n async arrayBuffer() {\n return buffer;\n },\n async bytes() {\n return data;\n },\n };\n },\n async _createWritableInternal(\n this: FileSystemFileHandleState,\n options?: unknown\n ): Promise<{ __writableStreamId: number }> {\n const opts = options as { keepExistingData?: boolean } | undefined;\n const hostStream = await this.hostHandle.createWritable({\n keepExistingData: opts?.keepExistingData,\n });\n\n return { __writableStreamId: registerHostWritableStream(hostStream) };\n },\n async isSameEntry(\n this: FileSystemFileHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemFileHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE4B,IAA5B;AAIA,IAAI,mBAAmB;AAChB,IAAM,qBAAqB,IAAI;AACtC,IAAI,uBAAuB;AACpB,IAAM,yBAAyB,IAAI;AAEnC,SAAS,sBAAsB,CAAC,QAAgC;AAAA,EACrE,MAAM,KAAK;AAAA,EACX,mBAAmB,IAAI,IAAI,EAAE,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,EACxD,OAAO;AAAA;AAGF,SAAS,0BAA0B,CAAC,QAAwC;AAAA,EACjF,MAAM,KAAK;AAAA,EACX,uBAAuB,IAAI,IAAI,MAAM;AAAA,EACrC,OAAO;AAAA;AAMF,SAAS,+BAA+B,CAC7C,SACA,UACe;AAAA,EACf,OAAO,gCAAuC,SAAS,UAAU;AAAA,IAC/D,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,eAAe,KAAK;AAAA,MAC1B,MAAM,UAAU,mBAAmB,IAAI,YAAY;AAAA,MACnD,IAAI,CAAC,SAAS;AAAA,QACZ,MAAM,IAAI,MAAM,kCAAkC,cAAc;AAAA,MAClE;AAAA,MACA,mBAAmB,OAAO,YAAY;AAAA,MACtC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO;AAAA;AAAA,MAEX;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,QAAO,GAAmD;AAAA,QAC9D,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ;AAAA,QAG3C,MAAM,SAAS,MAAM,KAAK,YAAY;AAAA,QACtC,MAAM,OAAO,IAAI,WAAW,MAAM;AAAA,QAElC,OAAO;AAAA,UACL,OAAO,CAAC,IAAI;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,cAAc,KAAK;AAAA,UACnB,oBAAoB;AAAA,eAEd,KAAI,GAAG;AAAA,YACX,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA;AAAA,eAEhC,YAAW,GAAG;AAAA,YAClB,OAAO;AAAA;AAAA,eAEH,MAAK,GAAG;AAAA,YACZ,OAAO;AAAA;AAAA,QAEX;AAAA;AAAA,WAEI,wBAAuB,CAE3B,SACyC;AAAA,QACzC,MAAM,OAAO;AAAA,QACb,MAAM,aAAa,MAAM,KAAK,WAAW,eAAe;AAAA,UACtD,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,QAED,OAAO,EAAE,oBAAoB,2BAA2B,UAAU,EAAE;AAAA;AAAA,WAEhE,YAAW,CAEf,OACkB;AAAA,QAClB,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AAAA,UACvC,OAAO;AAAA,QACT;AAAA,QACA,MAAM,cAAc;AAAA,QACpB,OAAO,KAAK,eAAe,YAAY;AAAA;AAAA,IAE3C;AAAA,EACF,CAAC;AAAA;",
|
|
8
|
-
"debugId": "03934374EFF6363C64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
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.ts\";\nimport { pendingWritableStreams } from \"./file-handle.ts\";\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": "2133667E0EBA9F1F64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/handles/directory-handle.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type {\n FileSystemDirectoryHandleState,\n FileSystemFileHandleState,\n HostDirectoryHandle,\n} from \"../types.ts\";\nimport { registerHostFileHandle } from \"./file-handle.ts\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextHostHandleId = 0;\nexport const pendingHostHandles = new Map<\n number,\n { handle: HostDirectoryHandle; name: string }\n>();\n\nexport function registerHostDirectoryHandle(\n handle: HostDirectoryHandle\n): number {\n const id = nextHostHandleId++;\n pendingHostHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\n/**\n * Create the FileSystemDirectoryHandle class for QuickJS\n */\nexport function createFileSystemDirectoryHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemDirectoryHandleState>(context, stateMap, {\n name: \"FileSystemDirectoryHandle\",\n construct: (args) => {\n // First argument is the host handle ID\n const hostHandleId = args[0] as number;\n const pending = pendingHostHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending host handle with ID ${hostHandleId}`);\n }\n pendingHostHandles.delete(hostHandleId);\n return {\n kind: \"directory\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemDirectoryHandleState) {\n return \"directory\";\n },\n },\n name: {\n get(this: FileSystemDirectoryHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async _getFileHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __fileHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostFile = await this.hostHandle.getFileHandle(String(name), {\n create: opts?.create,\n });\n\n return { __fileHandleId: registerHostFileHandle(hostFile) };\n },\n async _getDirectoryHandleInternal(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<{ __directoryHandleId: number }> {\n const opts = options as { create?: boolean } | undefined;\n const hostDir = await this.hostHandle.getDirectoryHandle(String(name), {\n create: opts?.create,\n });\n\n return { __directoryHandleId: registerHostDirectoryHandle(hostDir) };\n },\n async removeEntry(\n this: FileSystemDirectoryHandleState,\n name: unknown,\n options?: unknown\n ): Promise<void> {\n const opts = options as { recursive?: boolean } | undefined;\n await this.hostHandle.removeEntry(String(name), {\n recursive: opts?.recursive,\n });\n },\n async resolve(\n this: FileSystemDirectoryHandleState,\n possibleDescendant: unknown\n ): Promise<string[] | null> {\n if (!possibleDescendant || typeof possibleDescendant !== \"object\") {\n return null;\n }\n\n const descendant = possibleDescendant as\n | FileSystemFileHandleState\n | FileSystemDirectoryHandleState;\n return this.hostHandle.resolve(descendant.hostHandle);\n },\n async entries(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n >\n > {\n const result: Array<\n [string, FileSystemFileHandleState | FileSystemDirectoryHandleState]\n > = [];\n\n for await (const [name, handle] of this.hostHandle.entries()) {\n if (handle.kind === \"file\") {\n result.push([\n name,\n {\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n } else {\n result.push([\n name,\n {\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n },\n ]);\n }\n }\n\n return result;\n },\n async keys(this: FileSystemDirectoryHandleState): Promise<string[]> {\n const result: string[] = [];\n for await (const name of this.hostHandle.keys()) {\n result.push(name);\n }\n return result;\n },\n async values(\n this: FileSystemDirectoryHandleState\n ): Promise<\n Array<FileSystemFileHandleState | FileSystemDirectoryHandleState>\n > {\n const result: Array<\n FileSystemFileHandleState | FileSystemDirectoryHandleState\n > = [];\n\n for await (const handle of this.hostHandle.values()) {\n if (handle.kind === \"file\") {\n result.push({\n kind: \"file\",\n name: handle.name,\n hostHandle: handle,\n });\n } else {\n result.push({\n kind: \"directory\",\n name: handle.name,\n hostHandle: handle,\n });\n }\n }\n\n return result;\n },\n async isSameEntry(\n this: FileSystemDirectoryHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemDirectoryHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "1ED47E15C544CC8464756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/handles/file-handle.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 { FileSystemFileHandleState, HostFileHandle, HostWritableFileStream } from \"../types.ts\";\n\n// Registry for pending host handles that will be picked up by constructor\nlet nextFileHandleId = 0;\nexport const pendingFileHandles = new Map<number, { handle: HostFileHandle; name: string }>();\nlet nextWritableStreamId = 0;\nexport const pendingWritableStreams = new Map<number, HostWritableFileStream>();\n\nexport function registerHostFileHandle(handle: HostFileHandle): number {\n const id = nextFileHandleId++;\n pendingFileHandles.set(id, { handle, name: handle.name });\n return id;\n}\n\nexport function registerHostWritableStream(stream: HostWritableFileStream): number {\n const id = nextWritableStreamId++;\n pendingWritableStreams.set(id, stream);\n return id;\n}\n\n/**\n * Create the FileSystemFileHandle class for QuickJS\n */\nexport function createFileSystemFileHandleClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FileSystemFileHandleState>(context, stateMap, {\n name: \"FileSystemFileHandle\",\n construct: (args) => {\n const hostHandleId = args[0] as number;\n const pending = pendingFileHandles.get(hostHandleId);\n if (!pending) {\n throw new Error(`No pending file handle with ID ${hostHandleId}`);\n }\n pendingFileHandles.delete(hostHandleId);\n return {\n kind: \"file\" as const,\n name: pending.name,\n hostHandle: pending.handle,\n };\n },\n properties: {\n kind: {\n get(this: FileSystemFileHandleState) {\n return \"file\";\n },\n },\n name: {\n get(this: FileSystemFileHandleState) {\n return this.name;\n },\n },\n },\n methods: {\n async getFile(this: FileSystemFileHandleState): Promise<object> {\n const file = await this.hostHandle.getFile();\n\n // Convert native File to our internal File representation\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n return {\n parts: [data],\n type: file.type,\n size: file.size,\n name: file.name,\n lastModified: file.lastModified,\n webkitRelativePath: \"\",\n // Include methods that will be recognized\n async text() {\n return new TextDecoder().decode(data);\n },\n async arrayBuffer() {\n return buffer;\n },\n async bytes() {\n return data;\n },\n };\n },\n async _createWritableInternal(\n this: FileSystemFileHandleState,\n options?: unknown\n ): Promise<{ __writableStreamId: number }> {\n const opts = options as { keepExistingData?: boolean } | undefined;\n const hostStream = await this.hostHandle.createWritable({\n keepExistingData: opts?.keepExistingData,\n });\n\n return { __writableStreamId: registerHostWritableStream(hostStream) };\n },\n async isSameEntry(\n this: FileSystemFileHandleState,\n other: unknown\n ): Promise<boolean> {\n if (!other || typeof other !== \"object\") {\n return false;\n }\n const otherHandle = other as FileSystemFileHandleState;\n return this.hostHandle === otherHandle.hostHandle;\n },\n },\n });\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";;AAEA;AAIA,IAAI,mBAAmB;AAChB,IAAM,qBAAqB,IAAI;AACtC,IAAI,uBAAuB;AACpB,IAAM,yBAAyB,IAAI;AAEnC,SAAS,sBAAsB,CAAC,QAAgC;AAAA,EACrE,MAAM,KAAK;AAAA,EACX,mBAAmB,IAAI,IAAI,EAAE,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,EACxD,OAAO;AAAA;AAGF,SAAS,0BAA0B,CAAC,QAAwC;AAAA,EACjF,MAAM,KAAK;AAAA,EACX,uBAAuB,IAAI,IAAI,MAAM;AAAA,EACrC,OAAO;AAAA;AAMF,SAAS,+BAA+B,CAC7C,SACA,UACe;AAAA,EACf,OAAO,YAAuC,SAAS,UAAU;AAAA,IAC/D,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,eAAe,KAAK;AAAA,MAC1B,MAAM,UAAU,mBAAmB,IAAI,YAAY;AAAA,MACnD,IAAI,CAAC,SAAS;AAAA,QACZ,MAAM,IAAI,MAAM,kCAAkC,cAAc;AAAA,MAClE;AAAA,MACA,mBAAmB,OAAO,YAAY;AAAA,MACtC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO;AAAA;AAAA,MAEX;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAkC;AAAA,UACnC,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,QAAO,GAAmD;AAAA,QAC9D,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ;AAAA,QAG3C,MAAM,SAAS,MAAM,KAAK,YAAY;AAAA,QACtC,MAAM,OAAO,IAAI,WAAW,MAAM;AAAA,QAElC,OAAO;AAAA,UACL,OAAO,CAAC,IAAI;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,cAAc,KAAK;AAAA,UACnB,oBAAoB;AAAA,eAEd,KAAI,GAAG;AAAA,YACX,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA;AAAA,eAEhC,YAAW,GAAG;AAAA,YAClB,OAAO;AAAA;AAAA,eAEH,MAAK,GAAG;AAAA,YACZ,OAAO;AAAA;AAAA,QAEX;AAAA;AAAA,WAEI,wBAAuB,CAE3B,SACyC;AAAA,QACzC,MAAM,OAAO;AAAA,QACb,MAAM,aAAa,MAAM,KAAK,WAAW,eAAe;AAAA,UACtD,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,QAED,OAAO,EAAE,oBAAoB,2BAA2B,UAAU,EAAE;AAAA;AAAA,WAEhE,YAAW,CAEf,OACkB;AAAA,QAClB,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AAAA,UACvC,OAAO;AAAA,QACT;AAAA,QACA,MAAM,cAAc;AAAA,QACpB,OAAO,KAAK,eAAe,YAAY;AAAA;AAAA,IAE3C;AAAA,EACF,CAAC;AAAA;",
|
|
8
|
-
"debugId": "F8BEEB6B16C7A8BF64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
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.ts\";\nimport { pendingWritableStreams } from \"./file-handle.ts\";\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": ";;AAEA;AAMA;AAKO,SAAS,uCAAuC,CACrD,SACA,UACe;AAAA,EACf,OAAO,YAA+C,SAAS,UAAU;AAAA,IACvE,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,WAAW,KAAK;AAAA,MACtB,MAAM,aAAa,uBAAuB,IAAI,QAAQ;AAAA,MACtD,IAAI,CAAC,YAAY;AAAA,QACf,MAAM,IAAI,MAAM,sCAAsC,UAAU;AAAA,MAClE;AAAA,MACA,uBAAuB,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": "DEDE1A3875D7952464756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
File without changes
|
|
File without changes
|