@ricsam/quickjs-fs 0.0.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -43
- package/dist/cjs/directory-handle.cjs +166 -0
- package/dist/cjs/directory-handle.cjs.map +10 -0
- package/dist/cjs/file-handle.cjs +125 -0
- package/dist/cjs/file-handle.cjs.map +10 -0
- package/dist/cjs/index.cjs +43 -0
- package/dist/cjs/index.cjs.map +10 -0
- package/dist/cjs/memory-adapter.cjs +269 -0
- package/dist/cjs/memory-adapter.cjs.map +10 -0
- package/dist/cjs/node-adapter.cjs +221 -0
- package/dist/cjs/node-adapter.cjs.map +10 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/setup.cjs +140 -0
- package/dist/cjs/setup.cjs.map +10 -0
- package/dist/cjs/types.cjs +26 -0
- package/dist/cjs/types.cjs.map +9 -0
- package/dist/cjs/writable-stream.cjs +119 -0
- package/dist/cjs/writable-stream.cjs.map +10 -0
- package/dist/mjs/directory-handle.mjs +135 -0
- package/dist/mjs/directory-handle.mjs.map +10 -0
- package/dist/mjs/file-handle.mjs +94 -0
- package/dist/mjs/file-handle.mjs.map +10 -0
- package/dist/mjs/index.mjs +12 -0
- package/dist/mjs/index.mjs.map +10 -0
- package/dist/mjs/memory-adapter.mjs +237 -0
- package/dist/mjs/memory-adapter.mjs.map +10 -0
- package/dist/mjs/node-adapter.mjs +189 -0
- package/dist/mjs/node-adapter.mjs.map +10 -0
- package/dist/mjs/package.json +5 -0
- package/dist/mjs/setup.mjs +112 -0
- package/dist/mjs/setup.mjs.map +10 -0
- package/dist/mjs/types.mjs +3 -0
- package/dist/mjs/types.mjs.map +9 -0
- package/dist/mjs/writable-stream.mjs +88 -0
- package/dist/mjs/writable-stream.mjs.map +10 -0
- package/dist/types/handles/directory-handle.d.ts +12 -0
- package/dist/types/handles/file-handle.d.ts +14 -0
- package/dist/types/handles/writable-stream.d.ts +6 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/memory-adapter.d.ts +18 -0
- package/dist/types/node-adapter.d.ts +23 -0
- package/dist/types/setup.d.ts +56 -0
- package/dist/types/types.d.ts +85 -0
- package/package.json +51 -6
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// @bun @bun-cjs
|
|
2
|
+
(function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
+
var __toCommonJS = (from) => {
|
|
8
|
+
var entry = __moduleCache.get(from), desc;
|
|
9
|
+
if (entry)
|
|
10
|
+
return entry;
|
|
11
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
+
get: () => from[key],
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
}));
|
|
17
|
+
__moduleCache.set(from, entry);
|
|
18
|
+
return entry;
|
|
19
|
+
};
|
|
20
|
+
var __export = (target, all) => {
|
|
21
|
+
for (var name in all)
|
|
22
|
+
__defProp(target, name, {
|
|
23
|
+
get: all[name],
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// packages/fs/src/setup.ts
|
|
31
|
+
var exports_setup = {};
|
|
32
|
+
__export(exports_setup, {
|
|
33
|
+
setupFs: () => setupFs
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(exports_setup);
|
|
36
|
+
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
37
|
+
var import_writable_stream = require("./handles/writable-stream.ts");
|
|
38
|
+
var import_file_handle = require("./handles/file-handle.ts");
|
|
39
|
+
var import_directory_handle = require("./handles/directory-handle.ts");
|
|
40
|
+
function setupFs(context, options) {
|
|
41
|
+
const coreHandle = options.coreHandle ?? import_quickjs_core.setupCore(context, {
|
|
42
|
+
stateMap: options.stateMap
|
|
43
|
+
});
|
|
44
|
+
const stateMap = options.stateMap ?? coreHandle.stateMap;
|
|
45
|
+
const handles = [];
|
|
46
|
+
const WritableStreamClass = import_writable_stream.createFileSystemWritableFileStreamClass(context, stateMap);
|
|
47
|
+
context.setProp(context.global, "FileSystemWritableFileStream", WritableStreamClass);
|
|
48
|
+
context.setProp(context.global, "__FileSystemWritableFileStream__", WritableStreamClass);
|
|
49
|
+
WritableStreamClass.dispose();
|
|
50
|
+
const FileHandleClass = import_file_handle.createFileSystemFileHandleClass(context, stateMap);
|
|
51
|
+
context.setProp(context.global, "FileSystemFileHandle", FileHandleClass);
|
|
52
|
+
context.setProp(context.global, "__FileSystemFileHandle__", FileHandleClass);
|
|
53
|
+
FileHandleClass.dispose();
|
|
54
|
+
const DirectoryHandleClass = import_directory_handle.createFileSystemDirectoryHandleClass(context, stateMap);
|
|
55
|
+
context.setProp(context.global, "FileSystemDirectoryHandle", DirectoryHandleClass);
|
|
56
|
+
context.setProp(context.global, "__FileSystemDirectoryHandle__", DirectoryHandleClass);
|
|
57
|
+
DirectoryHandleClass.dispose();
|
|
58
|
+
const asyncIteratorResult = context.evalCode(`
|
|
59
|
+
FileSystemDirectoryHandle.prototype[Symbol.asyncIterator] = async function*() {
|
|
60
|
+
const entries = await this.entries();
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
yield entry;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
`);
|
|
66
|
+
if (asyncIteratorResult.error) {
|
|
67
|
+
asyncIteratorResult.error.dispose();
|
|
68
|
+
} else {
|
|
69
|
+
asyncIteratorResult.value.dispose();
|
|
70
|
+
}
|
|
71
|
+
const wrapperCode = `
|
|
72
|
+
// Wrapper for getFileHandle
|
|
73
|
+
FileSystemDirectoryHandle.prototype.getFileHandle = async function(name, options) {
|
|
74
|
+
const result = await this._getFileHandleInternal(name, options);
|
|
75
|
+
return new __FileSystemFileHandle__(result.__fileHandleId);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Wrapper for getDirectoryHandle
|
|
79
|
+
FileSystemDirectoryHandle.prototype.getDirectoryHandle = async function(name, options) {
|
|
80
|
+
const result = await this._getDirectoryHandleInternal(name, options);
|
|
81
|
+
return new __FileSystemDirectoryHandle__(result.__directoryHandleId);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Wrapper for createWritable
|
|
85
|
+
FileSystemFileHandle.prototype.createWritable = async function(options) {
|
|
86
|
+
const result = await this._createWritableInternal(options);
|
|
87
|
+
return new __FileSystemWritableFileStream__(result.__writableStreamId);
|
|
88
|
+
};
|
|
89
|
+
`;
|
|
90
|
+
const wrapperResult = context.evalCode(wrapperCode);
|
|
91
|
+
if (wrapperResult.error) {
|
|
92
|
+
const error = context.dump(wrapperResult.error);
|
|
93
|
+
wrapperResult.error.dispose();
|
|
94
|
+
throw new Error(`Failed to set up FS wrapper methods: ${JSON.stringify(error)}`);
|
|
95
|
+
}
|
|
96
|
+
wrapperResult.value.dispose();
|
|
97
|
+
const fsNamespace = context.newObject();
|
|
98
|
+
const getDirectoryFn = context.newFunction("getDirectory", (pathHandle) => {
|
|
99
|
+
const path = context.getString(pathHandle);
|
|
100
|
+
const deferred = context.newPromise();
|
|
101
|
+
options.getDirectory(path).then((hostHandle) => {
|
|
102
|
+
const hostHandleId = import_directory_handle.registerHostDirectoryHandle(hostHandle);
|
|
103
|
+
const instanceResult = context.evalCode(`new __FileSystemDirectoryHandle__(${hostHandleId})`);
|
|
104
|
+
if (instanceResult.error) {
|
|
105
|
+
deferred.reject(instanceResult.error);
|
|
106
|
+
instanceResult.error.dispose();
|
|
107
|
+
} else {
|
|
108
|
+
deferred.resolve(instanceResult.value);
|
|
109
|
+
instanceResult.value.dispose();
|
|
110
|
+
}
|
|
111
|
+
context.runtime.executePendingJobs();
|
|
112
|
+
}).catch((error) => {
|
|
113
|
+
const errorHandle = import_quickjs_core.marshal(context, {
|
|
114
|
+
name: error instanceof Error ? error.name : "Error",
|
|
115
|
+
message: error instanceof Error ? error.message : String(error)
|
|
116
|
+
});
|
|
117
|
+
deferred.reject(errorHandle);
|
|
118
|
+
errorHandle.dispose();
|
|
119
|
+
context.runtime.executePendingJobs();
|
|
120
|
+
});
|
|
121
|
+
return deferred.handle;
|
|
122
|
+
});
|
|
123
|
+
handles.push(getDirectoryFn);
|
|
124
|
+
context.setProp(fsNamespace, "getDirectory", getDirectoryFn);
|
|
125
|
+
context.setProp(context.global, "fs", fsNamespace);
|
|
126
|
+
fsNamespace.dispose();
|
|
127
|
+
return {
|
|
128
|
+
stateMap,
|
|
129
|
+
dispose() {
|
|
130
|
+
for (const handle of handles) {
|
|
131
|
+
if (handle.alive) {
|
|
132
|
+
handle.dispose();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
//# debugId=D350061A381CE07E64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/setup.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport {\n setupCore,\n createStateMap,\n marshal,\n} from \"@ricsam/quickjs-core\";\nimport type { SetupFsOptions, FsHandle } from \"./types.ts\";\nimport { createFileSystemWritableFileStreamClass } from \"./handles/writable-stream.ts\";\nimport { createFileSystemFileHandleClass } from \"./handles/file-handle.ts\";\nimport { createFileSystemDirectoryHandleClass, registerHostDirectoryHandle } from \"./handles/directory-handle.ts\";\n\n/**\n * Setup File System API in a QuickJS context\n *\n * Injects the following globals:\n * - fs.getDirectory(path) - Server-compatible entry point\n * - FileSystemFileHandle\n * - FileSystemDirectoryHandle\n * - FileSystemWritableFileStream\n *\n * **Private globals (internal use):**\n * - `__FileSystemFileHandle__` - For creating file handle instances from wrapper code\n * - `__FileSystemDirectoryHandle__` - For creating directory handle instances\n * - `__FileSystemWritableFileStream__` - For creating writable stream instances\n *\n * These private globals follow the `__Name__` convention and are required for the\n * wrapper pattern: public methods call internal methods that return IDs, then use\n * evalCode with private constructors to create properly-typed class instances.\n * See PATTERNS.md sections 2 and 5 for details.\n *\n * **Wrapper pattern example:**\n * ```typescript\n * // Public method (added via evalCode)\n * FileSystemFileHandle.prototype.createWritable = async function(options) {\n * const result = await this._createWritableInternal(options);\n * return new __FileSystemWritableFileStream__(result.__writableStreamId);\n * };\n * ```\n *\n * @example\n * import { setupFs, createNodeDirectoryHandle } from \"@ricsam/quickjs-fs\";\n *\n * const handle = setupFs(context, {\n * getDirectory: async (path) => {\n * // Validate and resolve path\n * const resolvedPath = resolveSandboxPath(path);\n * return createNodeDirectoryHandle(resolvedPath);\n * }\n * });\n *\n * context.evalCode(`\n * const root = await fs.getDirectory(\"/data\");\n * const configHandle = await root.getFileHandle(\"config.json\");\n * const file = await configHandle.getFile();\n * const text = await file.text();\n * console.log(JSON.parse(text));\n *\n * // Write a new file\n * const outputHandle = await root.getFileHandle(\"output.txt\", { create: true });\n * const writable = await outputHandle.createWritable();\n * await writable.write(\"Hello, World!\");\n * await writable.close();\n * `);\n */\nexport function setupFs(\n context: QuickJSContext,\n options: SetupFsOptions\n): FsHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n const handles: QuickJSHandle[] = [];\n\n // Create FileSystemWritableFileStream class\n const WritableStreamClass = createFileSystemWritableFileStreamClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"FileSystemWritableFileStream\",\n WritableStreamClass\n );\n context.setProp(context.global, \"__FileSystemWritableFileStream__\", WritableStreamClass);\n WritableStreamClass.dispose();\n\n // Create FileSystemFileHandle class\n const FileHandleClass = createFileSystemFileHandleClass(\n context,\n stateMap\n );\n context.setProp(context.global, \"FileSystemFileHandle\", FileHandleClass);\n context.setProp(context.global, \"__FileSystemFileHandle__\", FileHandleClass);\n FileHandleClass.dispose();\n\n // Create FileSystemDirectoryHandle class\n const DirectoryHandleClass = createFileSystemDirectoryHandleClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"FileSystemDirectoryHandle\",\n DirectoryHandleClass\n );\n context.setProp(context.global, \"__FileSystemDirectoryHandle__\", DirectoryHandleClass);\n DirectoryHandleClass.dispose();\n\n // Add Symbol.asyncIterator support for FileSystemDirectoryHandle (for await...of)\n const asyncIteratorResult = context.evalCode(`\n FileSystemDirectoryHandle.prototype[Symbol.asyncIterator] = async function*() {\n const entries = await this.entries();\n for (const entry of entries) {\n yield entry;\n }\n };\n `);\n if (asyncIteratorResult.error) {\n asyncIteratorResult.error.dispose();\n } else {\n asyncIteratorResult.value.dispose();\n }\n\n // Add wrapper methods that convert IDs to class instances\n const wrapperCode = `\n // Wrapper for getFileHandle\n FileSystemDirectoryHandle.prototype.getFileHandle = async function(name, options) {\n const result = await this._getFileHandleInternal(name, options);\n return new __FileSystemFileHandle__(result.__fileHandleId);\n };\n\n // Wrapper for getDirectoryHandle\n FileSystemDirectoryHandle.prototype.getDirectoryHandle = async function(name, options) {\n const result = await this._getDirectoryHandleInternal(name, options);\n return new __FileSystemDirectoryHandle__(result.__directoryHandleId);\n };\n\n // Wrapper for createWritable\n FileSystemFileHandle.prototype.createWritable = async function(options) {\n const result = await this._createWritableInternal(options);\n return new __FileSystemWritableFileStream__(result.__writableStreamId);\n };\n `;\n const wrapperResult = context.evalCode(wrapperCode);\n if (wrapperResult.error) {\n const error = context.dump(wrapperResult.error);\n wrapperResult.error.dispose();\n throw new Error(`Failed to set up FS wrapper methods: ${JSON.stringify(error)}`);\n }\n wrapperResult.value.dispose();\n\n // Create fs namespace with getDirectory\n const fsNamespace = context.newObject();\n\n // Create getDirectory function that returns proper class instances\n const getDirectoryFn = context.newFunction(\"getDirectory\", (pathHandle) => {\n const path = context.getString(pathHandle);\n\n const deferred = context.newPromise();\n\n options\n .getDirectory(path)\n .then((hostHandle) => {\n // Register the host handle and get an ID\n const hostHandleId = registerHostDirectoryHandle(hostHandle);\n\n // Create instance using evalCode with the ID\n const instanceResult = context.evalCode(\n `new __FileSystemDirectoryHandle__(${hostHandleId})`\n );\n\n if (instanceResult.error) {\n deferred.reject(instanceResult.error);\n instanceResult.error.dispose();\n } else {\n deferred.resolve(instanceResult.value);\n instanceResult.value.dispose();\n }\n context.runtime.executePendingJobs();\n })\n .catch((error) => {\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n handles.push(getDirectoryFn);\n context.setProp(fsNamespace, \"getDirectory\", getDirectoryFn);\n\n context.setProp(context.global, \"fs\", fsNamespace);\n fsNamespace.dispose();\n\n return {\n stateMap,\n dispose() {\n for (const handle of handles) {\n if (handle.alive) {\n handle.dispose();\n }\n }\n },\n };\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "D350061A381CE07E64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @bun @bun-cjs
|
|
2
|
+
(function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
+
var __toCommonJS = (from) => {
|
|
8
|
+
var entry = __moduleCache.get(from), desc;
|
|
9
|
+
if (entry)
|
|
10
|
+
return entry;
|
|
11
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
+
get: () => from[key],
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
}));
|
|
17
|
+
__moduleCache.set(from, entry);
|
|
18
|
+
return entry;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// packages/fs/src/types.ts
|
|
22
|
+
var exports_types = {};
|
|
23
|
+
module.exports = __toCommonJS(exports_types);
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
//# debugId=C67E7147CA95AE3264756E2164756E21
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// @bun @bun-cjs
|
|
2
|
+
(function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
+
var __toCommonJS = (from) => {
|
|
8
|
+
var entry = __moduleCache.get(from), desc;
|
|
9
|
+
if (entry)
|
|
10
|
+
return entry;
|
|
11
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
+
get: () => from[key],
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
}));
|
|
17
|
+
__moduleCache.set(from, entry);
|
|
18
|
+
return entry;
|
|
19
|
+
};
|
|
20
|
+
var __export = (target, all) => {
|
|
21
|
+
for (var name in all)
|
|
22
|
+
__defProp(target, name, {
|
|
23
|
+
get: all[name],
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// packages/fs/src/handles/writable-stream.ts
|
|
31
|
+
var exports_writable_stream = {};
|
|
32
|
+
__export(exports_writable_stream, {
|
|
33
|
+
createFileSystemWritableFileStreamClass: () => createFileSystemWritableFileStreamClass
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(exports_writable_stream);
|
|
36
|
+
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
37
|
+
var import_file_handle = require("./file-handle.ts");
|
|
38
|
+
function createFileSystemWritableFileStreamClass(context, stateMap) {
|
|
39
|
+
return import_quickjs_core.defineClass(context, stateMap, {
|
|
40
|
+
name: "FileSystemWritableFileStream",
|
|
41
|
+
construct: (args) => {
|
|
42
|
+
const streamId = args[0];
|
|
43
|
+
const hostStream = import_file_handle.pendingWritableStreams.get(streamId);
|
|
44
|
+
if (!hostStream) {
|
|
45
|
+
throw new Error(`No pending writable stream with ID ${streamId}`);
|
|
46
|
+
}
|
|
47
|
+
import_file_handle.pendingWritableStreams.delete(streamId);
|
|
48
|
+
return {
|
|
49
|
+
hostStream,
|
|
50
|
+
closed: false
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
methods: {
|
|
54
|
+
async write(data) {
|
|
55
|
+
if (this.closed) {
|
|
56
|
+
throw new Error("Stream is closed");
|
|
57
|
+
}
|
|
58
|
+
if (data && typeof data === "object" && "type" in data) {
|
|
59
|
+
const params = data;
|
|
60
|
+
if (params.type === "seek" && params.position !== undefined) {
|
|
61
|
+
await this.hostStream.seek(params.position);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (params.type === "truncate" && params.size !== undefined) {
|
|
65
|
+
await this.hostStream.truncate(params.size);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (params.type === "write" && params.data !== undefined) {
|
|
69
|
+
await this.hostStream.write(params.data);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (typeof data === "string") {
|
|
74
|
+
await this.hostStream.write(data);
|
|
75
|
+
} else if (data instanceof ArrayBuffer) {
|
|
76
|
+
await this.hostStream.write(data);
|
|
77
|
+
} else if (data instanceof Uint8Array) {
|
|
78
|
+
await this.hostStream.write(data);
|
|
79
|
+
} else if (data && typeof data === "object" && "parts" in data) {
|
|
80
|
+
const parts = data.parts;
|
|
81
|
+
for (const part of parts) {
|
|
82
|
+
await this.hostStream.write(part);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
await this.hostStream.write(String(data));
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
async seek(position) {
|
|
89
|
+
if (this.closed) {
|
|
90
|
+
throw new Error("Stream is closed");
|
|
91
|
+
}
|
|
92
|
+
await this.hostStream.seek(Number(position));
|
|
93
|
+
},
|
|
94
|
+
async truncate(size) {
|
|
95
|
+
if (this.closed) {
|
|
96
|
+
throw new Error("Stream is closed");
|
|
97
|
+
}
|
|
98
|
+
await this.hostStream.truncate(Number(size));
|
|
99
|
+
},
|
|
100
|
+
async close() {
|
|
101
|
+
if (this.closed) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.closed = true;
|
|
105
|
+
await this.hostStream.close();
|
|
106
|
+
},
|
|
107
|
+
async abort(reason) {
|
|
108
|
+
if (this.closed) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.closed = true;
|
|
112
|
+
await this.hostStream.abort(reason);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
//# debugId=2133667E0EBA9F1F64756E2164756E21
|
|
@@ -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.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
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/fs/src/handles/directory-handle.ts
|
|
3
|
+
import { defineClass } from "@ricsam/quickjs-core";
|
|
4
|
+
import { registerHostFileHandle } from "./file-handle.ts";
|
|
5
|
+
var nextHostHandleId = 0;
|
|
6
|
+
var pendingHostHandles = new Map;
|
|
7
|
+
function registerHostDirectoryHandle(handle) {
|
|
8
|
+
const id = nextHostHandleId++;
|
|
9
|
+
pendingHostHandles.set(id, { handle, name: handle.name });
|
|
10
|
+
return id;
|
|
11
|
+
}
|
|
12
|
+
function createFileSystemDirectoryHandleClass(context, stateMap) {
|
|
13
|
+
return defineClass(context, stateMap, {
|
|
14
|
+
name: "FileSystemDirectoryHandle",
|
|
15
|
+
construct: (args) => {
|
|
16
|
+
const hostHandleId = args[0];
|
|
17
|
+
const pending = pendingHostHandles.get(hostHandleId);
|
|
18
|
+
if (!pending) {
|
|
19
|
+
throw new Error(`No pending host handle with ID ${hostHandleId}`);
|
|
20
|
+
}
|
|
21
|
+
pendingHostHandles.delete(hostHandleId);
|
|
22
|
+
return {
|
|
23
|
+
kind: "directory",
|
|
24
|
+
name: pending.name,
|
|
25
|
+
hostHandle: pending.handle
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
properties: {
|
|
29
|
+
kind: {
|
|
30
|
+
get() {
|
|
31
|
+
return "directory";
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
name: {
|
|
35
|
+
get() {
|
|
36
|
+
return this.name;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
methods: {
|
|
41
|
+
async _getFileHandleInternal(name, options) {
|
|
42
|
+
const opts = options;
|
|
43
|
+
const hostFile = await this.hostHandle.getFileHandle(String(name), {
|
|
44
|
+
create: opts?.create
|
|
45
|
+
});
|
|
46
|
+
return { __fileHandleId: registerHostFileHandle(hostFile) };
|
|
47
|
+
},
|
|
48
|
+
async _getDirectoryHandleInternal(name, options) {
|
|
49
|
+
const opts = options;
|
|
50
|
+
const hostDir = await this.hostHandle.getDirectoryHandle(String(name), {
|
|
51
|
+
create: opts?.create
|
|
52
|
+
});
|
|
53
|
+
return { __directoryHandleId: registerHostDirectoryHandle(hostDir) };
|
|
54
|
+
},
|
|
55
|
+
async removeEntry(name, options) {
|
|
56
|
+
const opts = options;
|
|
57
|
+
await this.hostHandle.removeEntry(String(name), {
|
|
58
|
+
recursive: opts?.recursive
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
async resolve(possibleDescendant) {
|
|
62
|
+
if (!possibleDescendant || typeof possibleDescendant !== "object") {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const descendant = possibleDescendant;
|
|
66
|
+
return this.hostHandle.resolve(descendant.hostHandle);
|
|
67
|
+
},
|
|
68
|
+
async entries() {
|
|
69
|
+
const result = [];
|
|
70
|
+
for await (const [name, handle] of this.hostHandle.entries()) {
|
|
71
|
+
if (handle.kind === "file") {
|
|
72
|
+
result.push([
|
|
73
|
+
name,
|
|
74
|
+
{
|
|
75
|
+
kind: "file",
|
|
76
|
+
name: handle.name,
|
|
77
|
+
hostHandle: handle
|
|
78
|
+
}
|
|
79
|
+
]);
|
|
80
|
+
} else {
|
|
81
|
+
result.push([
|
|
82
|
+
name,
|
|
83
|
+
{
|
|
84
|
+
kind: "directory",
|
|
85
|
+
name: handle.name,
|
|
86
|
+
hostHandle: handle
|
|
87
|
+
}
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
},
|
|
93
|
+
async keys() {
|
|
94
|
+
const result = [];
|
|
95
|
+
for await (const name of this.hostHandle.keys()) {
|
|
96
|
+
result.push(name);
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
},
|
|
100
|
+
async values() {
|
|
101
|
+
const result = [];
|
|
102
|
+
for await (const handle of this.hostHandle.values()) {
|
|
103
|
+
if (handle.kind === "file") {
|
|
104
|
+
result.push({
|
|
105
|
+
kind: "file",
|
|
106
|
+
name: handle.name,
|
|
107
|
+
hostHandle: handle
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
result.push({
|
|
111
|
+
kind: "directory",
|
|
112
|
+
name: handle.name,
|
|
113
|
+
hostHandle: handle
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
},
|
|
119
|
+
async isSameEntry(other) {
|
|
120
|
+
if (!other || typeof other !== "object") {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
const otherHandle = other;
|
|
124
|
+
return this.hostHandle === otherHandle.hostHandle;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
registerHostDirectoryHandle,
|
|
131
|
+
pendingHostHandles,
|
|
132
|
+
createFileSystemDirectoryHandleClass
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
//# debugId=1ED47E15C544CC8464756E2164756E21
|
|
@@ -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.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
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/fs/src/handles/file-handle.ts
|
|
3
|
+
import { defineClass } from "@ricsam/quickjs-core";
|
|
4
|
+
var nextFileHandleId = 0;
|
|
5
|
+
var pendingFileHandles = new Map;
|
|
6
|
+
var nextWritableStreamId = 0;
|
|
7
|
+
var pendingWritableStreams = new Map;
|
|
8
|
+
function registerHostFileHandle(handle) {
|
|
9
|
+
const id = nextFileHandleId++;
|
|
10
|
+
pendingFileHandles.set(id, { handle, name: handle.name });
|
|
11
|
+
return id;
|
|
12
|
+
}
|
|
13
|
+
function registerHostWritableStream(stream) {
|
|
14
|
+
const id = nextWritableStreamId++;
|
|
15
|
+
pendingWritableStreams.set(id, stream);
|
|
16
|
+
return id;
|
|
17
|
+
}
|
|
18
|
+
function createFileSystemFileHandleClass(context, stateMap) {
|
|
19
|
+
return defineClass(context, stateMap, {
|
|
20
|
+
name: "FileSystemFileHandle",
|
|
21
|
+
construct: (args) => {
|
|
22
|
+
const hostHandleId = args[0];
|
|
23
|
+
const pending = pendingFileHandles.get(hostHandleId);
|
|
24
|
+
if (!pending) {
|
|
25
|
+
throw new Error(`No pending file handle with ID ${hostHandleId}`);
|
|
26
|
+
}
|
|
27
|
+
pendingFileHandles.delete(hostHandleId);
|
|
28
|
+
return {
|
|
29
|
+
kind: "file",
|
|
30
|
+
name: pending.name,
|
|
31
|
+
hostHandle: pending.handle
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
properties: {
|
|
35
|
+
kind: {
|
|
36
|
+
get() {
|
|
37
|
+
return "file";
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
name: {
|
|
41
|
+
get() {
|
|
42
|
+
return this.name;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
methods: {
|
|
47
|
+
async getFile() {
|
|
48
|
+
const file = await this.hostHandle.getFile();
|
|
49
|
+
const buffer = await file.arrayBuffer();
|
|
50
|
+
const data = new Uint8Array(buffer);
|
|
51
|
+
return {
|
|
52
|
+
parts: [data],
|
|
53
|
+
type: file.type,
|
|
54
|
+
size: file.size,
|
|
55
|
+
name: file.name,
|
|
56
|
+
lastModified: file.lastModified,
|
|
57
|
+
webkitRelativePath: "",
|
|
58
|
+
async text() {
|
|
59
|
+
return new TextDecoder().decode(data);
|
|
60
|
+
},
|
|
61
|
+
async arrayBuffer() {
|
|
62
|
+
return buffer;
|
|
63
|
+
},
|
|
64
|
+
async bytes() {
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
async _createWritableInternal(options) {
|
|
70
|
+
const opts = options;
|
|
71
|
+
const hostStream = await this.hostHandle.createWritable({
|
|
72
|
+
keepExistingData: opts?.keepExistingData
|
|
73
|
+
});
|
|
74
|
+
return { __writableStreamId: registerHostWritableStream(hostStream) };
|
|
75
|
+
},
|
|
76
|
+
async isSameEntry(other) {
|
|
77
|
+
if (!other || typeof other !== "object") {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const otherHandle = other;
|
|
81
|
+
return this.hostHandle === otherHandle.hostHandle;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
registerHostWritableStream,
|
|
88
|
+
registerHostFileHandle,
|
|
89
|
+
pendingWritableStreams,
|
|
90
|
+
pendingFileHandles,
|
|
91
|
+
createFileSystemFileHandleClass
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
//# debugId=F8BEEB6B16C7A8BF64756E2164756E21
|
|
@@ -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.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
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/fs/src/index.ts
|
|
3
|
+
import { setupFs } from "./setup.ts";
|
|
4
|
+
import { createNodeDirectoryHandle } from "./node-adapter.ts";
|
|
5
|
+
import { createMemoryDirectoryHandle } from "./memory-adapter.ts";
|
|
6
|
+
export {
|
|
7
|
+
setupFs,
|
|
8
|
+
createNodeDirectoryHandle,
|
|
9
|
+
createMemoryDirectoryHandle
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# debugId=DF39C017335E76D064756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export { setupFs } from \"./setup.ts\";\nexport { createNodeDirectoryHandle } from \"./node-adapter.ts\";\nexport { createMemoryDirectoryHandle } from \"./memory-adapter.ts\";\n\nexport type {\n SetupFsOptions,\n FsHandle,\n HostDirectoryHandle,\n HostFileHandle,\n HostWritableFileStream,\n WriteParams,\n} from \"./types.ts\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;AAAA;AACA;AACA;",
|
|
8
|
+
"debugId": "DF39C017335E76D064756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|