@ricsam/quickjs-core 0.0.1 → 0.2.0

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 CHANGED
@@ -1,45 +1,38 @@
1
1
  # @ricsam/quickjs-core
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@ricsam/quickjs-core`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
3
+ Core utilities and Web Streams API.
4
+
5
+ ```typescript
6
+ import { setupCore } from "@ricsam/quickjs-core";
7
+
8
+ const handle = setupCore(context);
9
+ ```
10
+
11
+ **Injected Globals:**
12
+ - `ReadableStream`, `WritableStream`, `TransformStream`
13
+ - `ReadableStreamDefaultReader`, `WritableStreamDefaultWriter`
14
+ - `Blob`, `File`
15
+
16
+ **Usage in QuickJS:**
17
+
18
+ ```javascript
19
+ // Streams
20
+ const stream = new ReadableStream({
21
+ start(controller) {
22
+ controller.enqueue("chunk1");
23
+ controller.enqueue("chunk2");
24
+ controller.close();
25
+ }
26
+ });
27
+
28
+ const reader = stream.getReader();
29
+ const { value, done } = await reader.read();
30
+
31
+ // Blob
32
+ const blob = new Blob(["hello", " ", "world"], { type: "text/plain" });
33
+ const text = await blob.text(); // "hello world"
34
+
35
+ // File
36
+ const file = new File(["content"], "file.txt", { type: "text/plain" });
37
+ console.log(file.name); // "file.txt"
38
+ ```
@@ -0,0 +1,143 @@
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/core/src/index.ts
31
+ var exports_src = {};
32
+ __export(exports_src, {
33
+ withScopeAsync: () => import_scope.withScopeAsync,
34
+ withScope: () => import_scope.withScope,
35
+ unmarshal: () => import_unmarshal.unmarshal,
36
+ setupCore: () => setupCore,
37
+ setState: () => import_class_builder2.setState,
38
+ setInstanceState: () => import_class_builder2.setInstanceState,
39
+ marshal: () => import_marshal.marshal,
40
+ isHandle: () => import_marshal.isHandle,
41
+ getState: () => import_class_builder2.getState,
42
+ getInstanceStateById: () => import_class_builder2.getInstanceStateById,
43
+ getInstanceState: () => import_class_builder2.getInstanceState,
44
+ getHandleType: () => import_marshal.getHandleType,
45
+ defineFunction: () => import_function_builder.defineFunction,
46
+ defineClass: () => import_class_builder2.defineClass,
47
+ defineAsyncFunction: () => import_function_builder.defineAsyncFunction,
48
+ createWritableStream: () => import_writable_stream2.createWritableStream,
49
+ createURLSearchParamsClass: () => import_url_search_params2.createURLSearchParamsClass,
50
+ createURLClass: () => import_url2.createURLClass,
51
+ createStateMap: () => import_class_builder2.createStateMap,
52
+ createReadableStream: () => import_readable_stream2.createReadableStream,
53
+ createFile: () => import_file2.createFile,
54
+ createBlob: () => import_blob2.createBlob,
55
+ consumeReadableStream: () => import_readable_stream2.consumeReadableStream,
56
+ clearAllInstanceState: () => import_class_builder2.clearAllInstanceState,
57
+ cleanupUnmarshaledHandles: () => import_unmarshal.cleanupUnmarshaledHandles,
58
+ cleanupInstanceState: () => import_class_builder2.cleanupInstanceState,
59
+ addURLSearchParamsGetter: () => import_url2.addURLSearchParamsGetter,
60
+ INTERNAL_STATE: () => import_types.INTERNAL_STATE
61
+ });
62
+ module.exports = __toCommonJS(exports_src);
63
+ var import_class_builder = require("./class-builder.ts");
64
+ var import_readable_stream = require("./streams/readable-stream.ts");
65
+ var import_writable_stream = require("./streams/writable-stream.ts");
66
+ var import_transform_stream = require("./streams/transform-stream.ts");
67
+ var import_blob = require("./blob.ts");
68
+ var import_file = require("./file.ts");
69
+ var import_dom_exception = require("./dom-exception.ts");
70
+ var import_url_search_params = require("./url-search-params.ts");
71
+ var import_url = require("./url.ts");
72
+ var import_types = require("./types.ts");
73
+ var import_scope = require("./scope.ts");
74
+ var import_marshal = require("./marshal.ts");
75
+ var import_unmarshal = require("./unmarshal.ts");
76
+ var import_function_builder = require("./function-builder.ts");
77
+ var import_class_builder2 = require("./class-builder.ts");
78
+ var import_readable_stream2 = require("./streams/readable-stream.ts");
79
+ var import_writable_stream2 = require("./streams/writable-stream.ts");
80
+ var import_blob2 = require("./blob.ts");
81
+ var import_file2 = require("./file.ts");
82
+ var import_url_search_params2 = require("./url-search-params.ts");
83
+ var import_url2 = require("./url.ts");
84
+ function setupCore(context, options) {
85
+ const stateMap = options?.stateMap ?? import_class_builder.createStateMap();
86
+ const handles = [];
87
+ const ReadableStreamDefaultReader = import_readable_stream.createReadableStreamDefaultReaderClass(context, stateMap);
88
+ context.setProp(context.global, "ReadableStreamDefaultReader", ReadableStreamDefaultReader);
89
+ ReadableStreamDefaultReader.dispose();
90
+ const readerClassRef = context.getProp(context.global, "ReadableStreamDefaultReader");
91
+ const ReadableStream = import_readable_stream.createReadableStreamClass(context, stateMap, readerClassRef);
92
+ readerClassRef.dispose();
93
+ context.setProp(context.global, "ReadableStream", ReadableStream);
94
+ ReadableStream.dispose();
95
+ const WritableStreamDefaultWriter = import_writable_stream.createWritableStreamDefaultWriterClass(context, stateMap);
96
+ context.setProp(context.global, "WritableStreamDefaultWriter", WritableStreamDefaultWriter);
97
+ WritableStreamDefaultWriter.dispose();
98
+ const writerClassRef = context.getProp(context.global, "WritableStreamDefaultWriter");
99
+ const WritableStream = import_writable_stream.createWritableStreamClass(context, stateMap, writerClassRef);
100
+ writerClassRef.dispose();
101
+ context.setProp(context.global, "WritableStream", WritableStream);
102
+ WritableStream.dispose();
103
+ const TransformStream = import_transform_stream.createTransformStreamClass(context, stateMap);
104
+ context.setProp(context.global, "TransformStream", TransformStream);
105
+ TransformStream.dispose();
106
+ const BlobClass = import_blob.createBlobClass(context, stateMap, (source) => import_readable_stream.createReadableStream(context, stateMap, source));
107
+ context.setProp(context.global, "Blob", BlobClass);
108
+ BlobClass.dispose();
109
+ const blobClassRef = context.getProp(context.global, "Blob");
110
+ const FileClass = import_file.createFileClass(context, stateMap, blobClassRef);
111
+ blobClassRef.dispose();
112
+ context.setProp(context.global, "File", FileClass);
113
+ FileClass.dispose();
114
+ const DOMExceptionClass = import_dom_exception.createDOMExceptionClass(context, stateMap);
115
+ context.setProp(context.global, "DOMException", DOMExceptionClass);
116
+ DOMExceptionClass.dispose();
117
+ const URLSearchParamsClass = import_url_search_params.createURLSearchParamsClass(context, stateMap);
118
+ context.setProp(context.global, "URLSearchParams", URLSearchParamsClass);
119
+ URLSearchParamsClass.dispose();
120
+ const urlSearchParamsIteratorResult = context.evalCode(`
121
+ URLSearchParams.prototype[Symbol.iterator] = function() {
122
+ return this.entries()[Symbol.iterator]();
123
+ };
124
+ `);
125
+ if (urlSearchParamsIteratorResult.error) {
126
+ urlSearchParamsIteratorResult.error.dispose();
127
+ } else {
128
+ urlSearchParamsIteratorResult.value.dispose();
129
+ }
130
+ const URLClass = import_url.createURLClass(context, stateMap);
131
+ context.setProp(context.global, "URL", URLClass);
132
+ URLClass.dispose();
133
+ import_url.addURLSearchParamsGetter(context);
134
+ return {
135
+ stateMap,
136
+ dispose() {
137
+ handles.length = 0;
138
+ }
139
+ };
140
+ }
141
+ })
142
+
143
+ //# debugId=FE2DEE7125C06AA764756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { SetupCoreOptions, CoreHandle, StateMap } from \"./types.ts\";\nimport { createStateMap } from \"./class-builder.ts\";\nimport {\n createReadableStreamClass,\n createReadableStreamDefaultReaderClass,\n createReadableStream,\n} from \"./streams/readable-stream.ts\";\nimport {\n createWritableStreamClass,\n createWritableStreamDefaultWriterClass,\n} from \"./streams/writable-stream.ts\";\nimport { createTransformStreamClass } from \"./streams/transform-stream.ts\";\nimport { createBlobClass } from \"./blob.ts\";\nimport { createFileClass } from \"./file.ts\";\nimport { createDOMExceptionClass } from \"./dom-exception.ts\";\nimport { createURLSearchParamsClass } from \"./url-search-params.ts\";\nimport { createURLClass, addURLSearchParamsGetter } from \"./url.ts\";\n\n/**\n * Setup core APIs in a QuickJS context\n *\n * Injects the following globals:\n * - ReadableStream, WritableStream, TransformStream\n * - ReadableStreamDefaultReader, WritableStreamDefaultWriter\n * - Blob\n * - File\n * - DOMException\n * - URL, URLSearchParams\n *\n * @example\n * const handle = setupCore(context);\n *\n * context.evalCode(`\n * const blob = new Blob([\"hello\", \" \", \"world\"], { type: \"text/plain\" });\n * const text = await blob.text(); // \"hello world\"\n *\n * const stream = new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"chunk1\");\n * controller.enqueue(\"chunk2\");\n * controller.close();\n * }\n * });\n * `);\n */\nexport function setupCore(\n context: QuickJSContext,\n options?: SetupCoreOptions\n): CoreHandle {\n const stateMap = options?.stateMap ?? createStateMap();\n const handles: { name: string; handle: QuickJSHandle }[] = [];\n\n // Create ReadableStreamDefaultReader class first\n const ReadableStreamDefaultReader = createReadableStreamDefaultReaderClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"ReadableStreamDefaultReader\",\n ReadableStreamDefaultReader\n );\n ReadableStreamDefaultReader.dispose();\n\n // Create ReadableStream class\n const readerClassRef = context.getProp(context.global, \"ReadableStreamDefaultReader\");\n const ReadableStream = createReadableStreamClass(\n context,\n stateMap,\n readerClassRef\n );\n readerClassRef.dispose();\n context.setProp(context.global, \"ReadableStream\", ReadableStream);\n ReadableStream.dispose();\n\n // Create WritableStreamDefaultWriter class first\n const WritableStreamDefaultWriter = createWritableStreamDefaultWriterClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"WritableStreamDefaultWriter\",\n WritableStreamDefaultWriter\n );\n WritableStreamDefaultWriter.dispose();\n\n // Create WritableStream class\n const writerClassRef = context.getProp(context.global, \"WritableStreamDefaultWriter\");\n const WritableStream = createWritableStreamClass(\n context,\n stateMap,\n writerClassRef\n );\n writerClassRef.dispose();\n context.setProp(context.global, \"WritableStream\", WritableStream);\n WritableStream.dispose();\n\n // Create TransformStream class\n const TransformStream = createTransformStreamClass(context, stateMap);\n context.setProp(context.global, \"TransformStream\", TransformStream);\n TransformStream.dispose();\n\n // Create Blob class with stream factory\n const BlobClass = createBlobClass(context, stateMap, (source) =>\n createReadableStream(context, stateMap, source)\n );\n context.setProp(context.global, \"Blob\", BlobClass);\n BlobClass.dispose();\n\n // Create File class (extends Blob)\n const blobClassRef = context.getProp(context.global, \"Blob\");\n const FileClass = createFileClass(context, stateMap, blobClassRef);\n blobClassRef.dispose();\n context.setProp(context.global, \"File\", FileClass);\n FileClass.dispose();\n\n // Create DOMException class\n const DOMExceptionClass = createDOMExceptionClass(context, stateMap);\n context.setProp(context.global, \"DOMException\", DOMExceptionClass);\n DOMExceptionClass.dispose();\n\n // Create URLSearchParams class\n const URLSearchParamsClass = createURLSearchParamsClass(context, stateMap);\n context.setProp(context.global, \"URLSearchParams\", URLSearchParamsClass);\n URLSearchParamsClass.dispose();\n\n // Add Symbol.iterator support for URLSearchParams\n const urlSearchParamsIteratorResult = context.evalCode(`\n URLSearchParams.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (urlSearchParamsIteratorResult.error) {\n urlSearchParamsIteratorResult.error.dispose();\n } else {\n urlSearchParamsIteratorResult.value.dispose();\n }\n\n // Create URL class (depends on URLSearchParams)\n const URLClass = createURLClass(context, stateMap);\n context.setProp(context.global, \"URL\", URLClass);\n URLClass.dispose();\n\n // Add searchParams getter to URL that returns URLSearchParams instance\n addURLSearchParamsGetter(context);\n\n /**\n * @returns CoreHandle with shared stateMap and dispose method\n *\n * **dispose() behavior:**\n * - Clears internal handle tracking array\n * - Does NOT dispose globals (ReadableStream, Blob, etc.) - they are owned\n * by context.global and cleaned up by context.dispose()\n * - Call before context.dispose() to release internal references\n *\n * @see PATTERNS.md for implementation patterns\n */\n return {\n stateMap,\n dispose() {\n // Note: handles set on global (ReadableStream, Blob, etc.) are NOT disposed here\n // They are owned by the global object and will be cleaned up by context.dispose()\n // Disposing them before context disposal causes QuickJS GC assertion failures\n handles.length = 0;\n },\n };\n}\n\n// Re-export types\nexport type {\n Scope,\n MarshalOptions,\n UnmarshalOptions,\n PropertyDescriptor,\n ClassDefinition,\n StateMap,\n SetupCoreOptions,\n CoreHandle,\n QuickJSContext,\n QuickJSHandle,\n QuickJSRuntime,\n} from \"./types.ts\";\nexport { INTERNAL_STATE } from \"./types.ts\";\n\n// Re-export utilities\nexport { withScope, withScopeAsync } from \"./scope.ts\";\nexport { marshal, isHandle, getHandleType } from \"./marshal.ts\";\nexport { unmarshal, cleanupUnmarshaledHandles } from \"./unmarshal.ts\";\nexport { defineFunction, defineAsyncFunction } from \"./function-builder.ts\";\nexport {\n defineClass,\n createStateMap,\n getState,\n setState,\n getInstanceState,\n setInstanceState,\n getInstanceStateById,\n cleanupInstanceState,\n clearAllInstanceState,\n} from \"./class-builder.ts\";\n\n// Re-export stream utilities\nexport {\n createReadableStream,\n consumeReadableStream,\n} from \"./streams/readable-stream.ts\";\nexport { createWritableStream } from \"./streams/writable-stream.ts\";\n\n// Re-export Blob/File utilities\nexport { createBlob } from \"./blob.ts\";\nexport { createFile } from \"./file.ts\";\n\n// Re-export URL utilities\nexport { createURLSearchParamsClass } from \"./url-search-params.ts\";\nexport type { URLSearchParamsState } from \"./url-search-params.ts\";\nexport { createURLClass, addURLSearchParamsGetter } from \"./url.ts\";\nexport type { URLState } from \"./url.ts\";\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE+B,IAA/B;AAKO,IAJP;AAQO,IAHP;AAI2C,IAA3C;AACgC,IAAhC;AACgC,IAAhC;AACwC,IAAxC;AAC2C,IAA3C;AACyD,IAAzD;AAuK+B,IAA/B;AAG0C,IAA1C;AACiD,IAAjD;AACqD,IAArD;AACoD,IAApD;AAWO,IAVP;AAgBO,IAHP;AAIqC,IAArC;AAG2B,IAA3B;AAC2B,IAA3B;AAG2C,IAA3C;AAEyD,IAAzD;AA3KO,SAAS,SAAS,CACvB,SACA,SACY;AAAA,EACZ,MAAM,WAAW,SAAS,YAAY,oCAAe;AAAA,EACrD,MAAM,UAAqD,CAAC;AAAA,EAG5D,MAAM,8BAA8B,8DAClC,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,+BACA,2BACF;AAAA,EACA,4BAA4B,QAAQ;AAAA,EAGpC,MAAM,iBAAiB,QAAQ,QAAQ,QAAQ,QAAQ,6BAA6B;AAAA,EACpF,MAAM,iBAAiB,iDACrB,SACA,UACA,cACF;AAAA,EACA,eAAe,QAAQ;AAAA,EACvB,QAAQ,QAAQ,QAAQ,QAAQ,kBAAkB,cAAc;AAAA,EAChE,eAAe,QAAQ;AAAA,EAGvB,MAAM,8BAA8B,8DAClC,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,+BACA,2BACF;AAAA,EACA,4BAA4B,QAAQ;AAAA,EAGpC,MAAM,iBAAiB,QAAQ,QAAQ,QAAQ,QAAQ,6BAA6B;AAAA,EACpF,MAAM,iBAAiB,iDACrB,SACA,UACA,cACF;AAAA,EACA,eAAe,QAAQ;AAAA,EACvB,QAAQ,QAAQ,QAAQ,QAAQ,kBAAkB,cAAc;AAAA,EAChE,eAAe,QAAQ;AAAA,EAGvB,MAAM,kBAAkB,mDAA2B,SAAS,QAAQ;AAAA,EACpE,QAAQ,QAAQ,QAAQ,QAAQ,mBAAmB,eAAe;AAAA,EAClE,gBAAgB,QAAQ;AAAA,EAGxB,MAAM,YAAY,4BAAgB,SAAS,UAAU,CAAC,WACpD,4CAAqB,SAAS,UAAU,MAAM,CAChD;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EACjD,UAAU,QAAQ;AAAA,EAGlB,MAAM,eAAe,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAAA,EAC3D,MAAM,YAAY,4BAAgB,SAAS,UAAU,YAAY;AAAA,EACjE,aAAa,QAAQ;AAAA,EACrB,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EACjD,UAAU,QAAQ;AAAA,EAGlB,MAAM,oBAAoB,6CAAwB,SAAS,QAAQ;AAAA,EACnE,QAAQ,QAAQ,QAAQ,QAAQ,gBAAgB,iBAAiB;AAAA,EACjE,kBAAkB,QAAQ;AAAA,EAG1B,MAAM,uBAAuB,oDAA2B,SAAS,QAAQ;AAAA,EACzE,QAAQ,QAAQ,QAAQ,QAAQ,mBAAmB,oBAAoB;AAAA,EACvE,qBAAqB,QAAQ;AAAA,EAG7B,MAAM,gCAAgC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAItD;AAAA,EACD,IAAI,8BAA8B,OAAO;AAAA,IACvC,8BAA8B,MAAM,QAAQ;AAAA,EAC9C,EAAO;AAAA,IACL,8BAA8B,MAAM,QAAQ;AAAA;AAAA,EAI9C,MAAM,WAAW,0BAAe,SAAS,QAAQ;AAAA,EACjD,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,QAAQ;AAAA,EAC/C,SAAS,QAAQ;AAAA,EAGjB,oCAAyB,OAAO;AAAA,EAahC,OAAO;AAAA,IACL;AAAA,IACA,OAAO,GAAG;AAAA,MAIR,QAAQ,SAAS;AAAA;AAAA,EAErB;AAAA;",
8
+ "debugId": "FE2DEE7125C06AA764756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@ricsam/quickjs-core",
3
+ "version": "0.2.0",
4
+ "type": "commonjs"
5
+ }
@@ -0,0 +1,132 @@
1
+ // @bun
2
+ // packages/core/src/index.ts
3
+ import { createStateMap } from "./class-builder.ts";
4
+ import {
5
+ createReadableStreamClass,
6
+ createReadableStreamDefaultReaderClass,
7
+ createReadableStream
8
+ } from "./streams/readable-stream.ts";
9
+ import {
10
+ createWritableStreamClass,
11
+ createWritableStreamDefaultWriterClass
12
+ } from "./streams/writable-stream.ts";
13
+ import { createTransformStreamClass } from "./streams/transform-stream.ts";
14
+ import { createBlobClass } from "./blob.ts";
15
+ import { createFileClass } from "./file.ts";
16
+ import { createDOMExceptionClass } from "./dom-exception.ts";
17
+ import { createURLSearchParamsClass } from "./url-search-params.ts";
18
+ import { createURLClass, addURLSearchParamsGetter } from "./url.ts";
19
+ import { INTERNAL_STATE } from "./types.ts";
20
+ import { withScope, withScopeAsync } from "./scope.ts";
21
+ import { marshal, isHandle, getHandleType } from "./marshal.ts";
22
+ import { unmarshal, cleanupUnmarshaledHandles } from "./unmarshal.ts";
23
+ import { defineFunction, defineAsyncFunction } from "./function-builder.ts";
24
+ import {
25
+ defineClass,
26
+ createStateMap as createStateMap2,
27
+ getState,
28
+ setState,
29
+ getInstanceState,
30
+ setInstanceState,
31
+ getInstanceStateById,
32
+ cleanupInstanceState,
33
+ clearAllInstanceState
34
+ } from "./class-builder.ts";
35
+ import {
36
+ createReadableStream as createReadableStream2,
37
+ consumeReadableStream
38
+ } from "./streams/readable-stream.ts";
39
+ import { createWritableStream } from "./streams/writable-stream.ts";
40
+ import { createBlob } from "./blob.ts";
41
+ import { createFile } from "./file.ts";
42
+ import { createURLSearchParamsClass as createURLSearchParamsClass2 } from "./url-search-params.ts";
43
+ import { createURLClass as createURLClass2, addURLSearchParamsGetter as addURLSearchParamsGetter2 } from "./url.ts";
44
+ function setupCore(context, options) {
45
+ const stateMap = options?.stateMap ?? createStateMap();
46
+ const handles = [];
47
+ const ReadableStreamDefaultReader = createReadableStreamDefaultReaderClass(context, stateMap);
48
+ context.setProp(context.global, "ReadableStreamDefaultReader", ReadableStreamDefaultReader);
49
+ ReadableStreamDefaultReader.dispose();
50
+ const readerClassRef = context.getProp(context.global, "ReadableStreamDefaultReader");
51
+ const ReadableStream = createReadableStreamClass(context, stateMap, readerClassRef);
52
+ readerClassRef.dispose();
53
+ context.setProp(context.global, "ReadableStream", ReadableStream);
54
+ ReadableStream.dispose();
55
+ const WritableStreamDefaultWriter = createWritableStreamDefaultWriterClass(context, stateMap);
56
+ context.setProp(context.global, "WritableStreamDefaultWriter", WritableStreamDefaultWriter);
57
+ WritableStreamDefaultWriter.dispose();
58
+ const writerClassRef = context.getProp(context.global, "WritableStreamDefaultWriter");
59
+ const WritableStream = createWritableStreamClass(context, stateMap, writerClassRef);
60
+ writerClassRef.dispose();
61
+ context.setProp(context.global, "WritableStream", WritableStream);
62
+ WritableStream.dispose();
63
+ const TransformStream = createTransformStreamClass(context, stateMap);
64
+ context.setProp(context.global, "TransformStream", TransformStream);
65
+ TransformStream.dispose();
66
+ const BlobClass = createBlobClass(context, stateMap, (source) => createReadableStream(context, stateMap, source));
67
+ context.setProp(context.global, "Blob", BlobClass);
68
+ BlobClass.dispose();
69
+ const blobClassRef = context.getProp(context.global, "Blob");
70
+ const FileClass = createFileClass(context, stateMap, blobClassRef);
71
+ blobClassRef.dispose();
72
+ context.setProp(context.global, "File", FileClass);
73
+ FileClass.dispose();
74
+ const DOMExceptionClass = createDOMExceptionClass(context, stateMap);
75
+ context.setProp(context.global, "DOMException", DOMExceptionClass);
76
+ DOMExceptionClass.dispose();
77
+ const URLSearchParamsClass = createURLSearchParamsClass(context, stateMap);
78
+ context.setProp(context.global, "URLSearchParams", URLSearchParamsClass);
79
+ URLSearchParamsClass.dispose();
80
+ const urlSearchParamsIteratorResult = context.evalCode(`
81
+ URLSearchParams.prototype[Symbol.iterator] = function() {
82
+ return this.entries()[Symbol.iterator]();
83
+ };
84
+ `);
85
+ if (urlSearchParamsIteratorResult.error) {
86
+ urlSearchParamsIteratorResult.error.dispose();
87
+ } else {
88
+ urlSearchParamsIteratorResult.value.dispose();
89
+ }
90
+ const URLClass = createURLClass(context, stateMap);
91
+ context.setProp(context.global, "URL", URLClass);
92
+ URLClass.dispose();
93
+ addURLSearchParamsGetter(context);
94
+ return {
95
+ stateMap,
96
+ dispose() {
97
+ handles.length = 0;
98
+ }
99
+ };
100
+ }
101
+ export {
102
+ withScopeAsync,
103
+ withScope,
104
+ unmarshal,
105
+ setupCore,
106
+ setState,
107
+ setInstanceState,
108
+ marshal,
109
+ isHandle,
110
+ getState,
111
+ getInstanceStateById,
112
+ getInstanceState,
113
+ getHandleType,
114
+ defineFunction,
115
+ defineClass,
116
+ defineAsyncFunction,
117
+ createWritableStream,
118
+ createURLSearchParamsClass2 as createURLSearchParamsClass,
119
+ createURLClass2 as createURLClass,
120
+ createStateMap2 as createStateMap,
121
+ createReadableStream2 as createReadableStream,
122
+ createFile,
123
+ createBlob,
124
+ consumeReadableStream,
125
+ clearAllInstanceState,
126
+ cleanupUnmarshaledHandles,
127
+ cleanupInstanceState,
128
+ addURLSearchParamsGetter2 as addURLSearchParamsGetter,
129
+ INTERNAL_STATE
130
+ };
131
+
132
+ //# debugId=E3F9214AFACC87A464756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { SetupCoreOptions, CoreHandle, StateMap } from \"./types.ts\";\nimport { createStateMap } from \"./class-builder.ts\";\nimport {\n createReadableStreamClass,\n createReadableStreamDefaultReaderClass,\n createReadableStream,\n} from \"./streams/readable-stream.ts\";\nimport {\n createWritableStreamClass,\n createWritableStreamDefaultWriterClass,\n} from \"./streams/writable-stream.ts\";\nimport { createTransformStreamClass } from \"./streams/transform-stream.ts\";\nimport { createBlobClass } from \"./blob.ts\";\nimport { createFileClass } from \"./file.ts\";\nimport { createDOMExceptionClass } from \"./dom-exception.ts\";\nimport { createURLSearchParamsClass } from \"./url-search-params.ts\";\nimport { createURLClass, addURLSearchParamsGetter } from \"./url.ts\";\n\n/**\n * Setup core APIs in a QuickJS context\n *\n * Injects the following globals:\n * - ReadableStream, WritableStream, TransformStream\n * - ReadableStreamDefaultReader, WritableStreamDefaultWriter\n * - Blob\n * - File\n * - DOMException\n * - URL, URLSearchParams\n *\n * @example\n * const handle = setupCore(context);\n *\n * context.evalCode(`\n * const blob = new Blob([\"hello\", \" \", \"world\"], { type: \"text/plain\" });\n * const text = await blob.text(); // \"hello world\"\n *\n * const stream = new ReadableStream({\n * start(controller) {\n * controller.enqueue(\"chunk1\");\n * controller.enqueue(\"chunk2\");\n * controller.close();\n * }\n * });\n * `);\n */\nexport function setupCore(\n context: QuickJSContext,\n options?: SetupCoreOptions\n): CoreHandle {\n const stateMap = options?.stateMap ?? createStateMap();\n const handles: { name: string; handle: QuickJSHandle }[] = [];\n\n // Create ReadableStreamDefaultReader class first\n const ReadableStreamDefaultReader = createReadableStreamDefaultReaderClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"ReadableStreamDefaultReader\",\n ReadableStreamDefaultReader\n );\n ReadableStreamDefaultReader.dispose();\n\n // Create ReadableStream class\n const readerClassRef = context.getProp(context.global, \"ReadableStreamDefaultReader\");\n const ReadableStream = createReadableStreamClass(\n context,\n stateMap,\n readerClassRef\n );\n readerClassRef.dispose();\n context.setProp(context.global, \"ReadableStream\", ReadableStream);\n ReadableStream.dispose();\n\n // Create WritableStreamDefaultWriter class first\n const WritableStreamDefaultWriter = createWritableStreamDefaultWriterClass(\n context,\n stateMap\n );\n context.setProp(\n context.global,\n \"WritableStreamDefaultWriter\",\n WritableStreamDefaultWriter\n );\n WritableStreamDefaultWriter.dispose();\n\n // Create WritableStream class\n const writerClassRef = context.getProp(context.global, \"WritableStreamDefaultWriter\");\n const WritableStream = createWritableStreamClass(\n context,\n stateMap,\n writerClassRef\n );\n writerClassRef.dispose();\n context.setProp(context.global, \"WritableStream\", WritableStream);\n WritableStream.dispose();\n\n // Create TransformStream class\n const TransformStream = createTransformStreamClass(context, stateMap);\n context.setProp(context.global, \"TransformStream\", TransformStream);\n TransformStream.dispose();\n\n // Create Blob class with stream factory\n const BlobClass = createBlobClass(context, stateMap, (source) =>\n createReadableStream(context, stateMap, source)\n );\n context.setProp(context.global, \"Blob\", BlobClass);\n BlobClass.dispose();\n\n // Create File class (extends Blob)\n const blobClassRef = context.getProp(context.global, \"Blob\");\n const FileClass = createFileClass(context, stateMap, blobClassRef);\n blobClassRef.dispose();\n context.setProp(context.global, \"File\", FileClass);\n FileClass.dispose();\n\n // Create DOMException class\n const DOMExceptionClass = createDOMExceptionClass(context, stateMap);\n context.setProp(context.global, \"DOMException\", DOMExceptionClass);\n DOMExceptionClass.dispose();\n\n // Create URLSearchParams class\n const URLSearchParamsClass = createURLSearchParamsClass(context, stateMap);\n context.setProp(context.global, \"URLSearchParams\", URLSearchParamsClass);\n URLSearchParamsClass.dispose();\n\n // Add Symbol.iterator support for URLSearchParams\n const urlSearchParamsIteratorResult = context.evalCode(`\n URLSearchParams.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (urlSearchParamsIteratorResult.error) {\n urlSearchParamsIteratorResult.error.dispose();\n } else {\n urlSearchParamsIteratorResult.value.dispose();\n }\n\n // Create URL class (depends on URLSearchParams)\n const URLClass = createURLClass(context, stateMap);\n context.setProp(context.global, \"URL\", URLClass);\n URLClass.dispose();\n\n // Add searchParams getter to URL that returns URLSearchParams instance\n addURLSearchParamsGetter(context);\n\n /**\n * @returns CoreHandle with shared stateMap and dispose method\n *\n * **dispose() behavior:**\n * - Clears internal handle tracking array\n * - Does NOT dispose globals (ReadableStream, Blob, etc.) - they are owned\n * by context.global and cleaned up by context.dispose()\n * - Call before context.dispose() to release internal references\n *\n * @see PATTERNS.md for implementation patterns\n */\n return {\n stateMap,\n dispose() {\n // Note: handles set on global (ReadableStream, Blob, etc.) are NOT disposed here\n // They are owned by the global object and will be cleaned up by context.dispose()\n // Disposing them before context disposal causes QuickJS GC assertion failures\n handles.length = 0;\n },\n };\n}\n\n// Re-export types\nexport type {\n Scope,\n MarshalOptions,\n UnmarshalOptions,\n PropertyDescriptor,\n ClassDefinition,\n StateMap,\n SetupCoreOptions,\n CoreHandle,\n QuickJSContext,\n QuickJSHandle,\n QuickJSRuntime,\n} from \"./types.ts\";\nexport { INTERNAL_STATE } from \"./types.ts\";\n\n// Re-export utilities\nexport { withScope, withScopeAsync } from \"./scope.ts\";\nexport { marshal, isHandle, getHandleType } from \"./marshal.ts\";\nexport { unmarshal, cleanupUnmarshaledHandles } from \"./unmarshal.ts\";\nexport { defineFunction, defineAsyncFunction } from \"./function-builder.ts\";\nexport {\n defineClass,\n createStateMap,\n getState,\n setState,\n getInstanceState,\n setInstanceState,\n getInstanceStateById,\n cleanupInstanceState,\n clearAllInstanceState,\n} from \"./class-builder.ts\";\n\n// Re-export stream utilities\nexport {\n createReadableStream,\n consumeReadableStream,\n} from \"./streams/readable-stream.ts\";\nexport { createWritableStream } from \"./streams/writable-stream.ts\";\n\n// Re-export Blob/File utilities\nexport { createBlob } from \"./blob.ts\";\nexport { createFile } from \"./file.ts\";\n\n// Re-export URL utilities\nexport { createURLSearchParamsClass } from \"./url-search-params.ts\";\nexport type { URLSearchParamsState } from \"./url-search-params.ts\";\nexport { createURLClass, addURLSearchParamsGetter } from \"./url.ts\";\nexport type { URLState } from \"./url.ts\";\n"
6
+ ],
7
+ "mappings": ";;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AAuKA;AAGA;AACA;AACA;AACA;AACA;AAAA;AAAA,oBAEE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWF;AAAA,0BACE;AAAA;AAAA;AAGF;AAGA;AACA;AAGA,uCAAS;AAET,2BAAS,6CAAgB;AA3KlB,SAAS,SAAS,CACvB,SACA,SACY;AAAA,EACZ,MAAM,WAAW,SAAS,YAAY,eAAe;AAAA,EACrD,MAAM,UAAqD,CAAC;AAAA,EAG5D,MAAM,8BAA8B,uCAClC,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,+BACA,2BACF;AAAA,EACA,4BAA4B,QAAQ;AAAA,EAGpC,MAAM,iBAAiB,QAAQ,QAAQ,QAAQ,QAAQ,6BAA6B;AAAA,EACpF,MAAM,iBAAiB,0BACrB,SACA,UACA,cACF;AAAA,EACA,eAAe,QAAQ;AAAA,EACvB,QAAQ,QAAQ,QAAQ,QAAQ,kBAAkB,cAAc;AAAA,EAChE,eAAe,QAAQ;AAAA,EAGvB,MAAM,8BAA8B,uCAClC,SACA,QACF;AAAA,EACA,QAAQ,QACN,QAAQ,QACR,+BACA,2BACF;AAAA,EACA,4BAA4B,QAAQ;AAAA,EAGpC,MAAM,iBAAiB,QAAQ,QAAQ,QAAQ,QAAQ,6BAA6B;AAAA,EACpF,MAAM,iBAAiB,0BACrB,SACA,UACA,cACF;AAAA,EACA,eAAe,QAAQ;AAAA,EACvB,QAAQ,QAAQ,QAAQ,QAAQ,kBAAkB,cAAc;AAAA,EAChE,eAAe,QAAQ;AAAA,EAGvB,MAAM,kBAAkB,2BAA2B,SAAS,QAAQ;AAAA,EACpE,QAAQ,QAAQ,QAAQ,QAAQ,mBAAmB,eAAe;AAAA,EAClE,gBAAgB,QAAQ;AAAA,EAGxB,MAAM,YAAY,gBAAgB,SAAS,UAAU,CAAC,WACpD,qBAAqB,SAAS,UAAU,MAAM,CAChD;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EACjD,UAAU,QAAQ;AAAA,EAGlB,MAAM,eAAe,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAAA,EAC3D,MAAM,YAAY,gBAAgB,SAAS,UAAU,YAAY;AAAA,EACjE,aAAa,QAAQ;AAAA,EACrB,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EACjD,UAAU,QAAQ;AAAA,EAGlB,MAAM,oBAAoB,wBAAwB,SAAS,QAAQ;AAAA,EACnE,QAAQ,QAAQ,QAAQ,QAAQ,gBAAgB,iBAAiB;AAAA,EACjE,kBAAkB,QAAQ;AAAA,EAG1B,MAAM,uBAAuB,2BAA2B,SAAS,QAAQ;AAAA,EACzE,QAAQ,QAAQ,QAAQ,QAAQ,mBAAmB,oBAAoB;AAAA,EACvE,qBAAqB,QAAQ;AAAA,EAG7B,MAAM,gCAAgC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAItD;AAAA,EACD,IAAI,8BAA8B,OAAO;AAAA,IACvC,8BAA8B,MAAM,QAAQ;AAAA,EAC9C,EAAO;AAAA,IACL,8BAA8B,MAAM,QAAQ;AAAA;AAAA,EAI9C,MAAM,WAAW,eAAe,SAAS,QAAQ;AAAA,EACjD,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,QAAQ;AAAA,EAC/C,SAAS,QAAQ;AAAA,EAGjB,yBAAyB,OAAO;AAAA,EAahC,OAAO;AAAA,IACL;AAAA,IACA,OAAO,GAAG;AAAA,MAIR,QAAQ,SAAS;AAAA;AAAA,EAErB;AAAA;",
8
+ "debugId": "E3F9214AFACC87A464756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@ricsam/quickjs-core",
3
+ "version": "0.2.0",
4
+ "type": "module"
5
+ }
@@ -0,0 +1,19 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ /**
4
+ * Type for the stream factory function
5
+ */
6
+ type StreamFactory = (source: UnderlyingSource) => QuickJSHandle;
7
+ /**
8
+ * Create the Blob class for QuickJS
9
+ *
10
+ * @param context - QuickJS context
11
+ * @param stateMap - State map for internal state tracking
12
+ * @param createStream - Factory function to create ReadableStream handles
13
+ */
14
+ export declare function createBlobClass(context: QuickJSContext, stateMap: StateMap, createStream: StreamFactory): QuickJSHandle;
15
+ /**
16
+ * Create a Blob in QuickJS from host data
17
+ */
18
+ export declare function createBlob(context: QuickJSContext, stateMap: StateMap, parts: BlobPart[], options?: BlobPropertyBag): QuickJSHandle;
19
+ export {};
@@ -0,0 +1,62 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { ClassDefinition, StateMap } from "./types.ts";
3
+ /**
4
+ * Create a new StateMap for tracking object internal states
5
+ */
6
+ export declare function createStateMap(): StateMap;
7
+ /**
8
+ * Get the internal state associated with a QuickJS object handle
9
+ */
10
+ export declare function getState<T extends object>(stateMap: StateMap, handle: QuickJSHandle): T | undefined;
11
+ /**
12
+ * Set the internal state associated with a QuickJS object handle
13
+ */
14
+ export declare function setState<T extends object>(stateMap: StateMap, handle: QuickJSHandle, state: T): void;
15
+ /**
16
+ * Define a class in the QuickJS context
17
+ *
18
+ * Uses evalCode to create a proper JavaScript class that can be called with 'new'.
19
+ * Host-side callbacks are registered and invoked by the JavaScript class.
20
+ *
21
+ * @returns Handle to the class constructor (caller must manage disposal)
22
+ *
23
+ * @example
24
+ * const Point = defineClass(context, stateMap, {
25
+ * name: "Point",
26
+ * construct: ([x, y]) => ({ x: Number(x), y: Number(y) }),
27
+ * methods: {
28
+ * distance(this: { x: number; y: number }) {
29
+ * return Math.sqrt(this.x ** 2 + this.y ** 2);
30
+ * }
31
+ * },
32
+ * properties: {
33
+ * x: {
34
+ * get(this: { x: number }) { return this.x; },
35
+ * set(this: { x: number }, v: unknown) { this.x = Number(v); }
36
+ * }
37
+ * }
38
+ * });
39
+ * context.setProp(context.global, "Point", Point);
40
+ */
41
+ export declare function defineClass<TState extends object>(context: QuickJSContext, stateMap: StateMap, definition: ClassDefinition<TState>): QuickJSHandle;
42
+ /**
43
+ * Get internal state for a QuickJS instance by extracting its __instanceId__
44
+ */
45
+ export declare function getInstanceState<T>(context: QuickJSContext, instanceHandle: QuickJSHandle): T | undefined;
46
+ /**
47
+ * Set internal state for a QuickJS instance by extracting its __instanceId__
48
+ */
49
+ export declare function setInstanceState<T>(context: QuickJSContext, instanceHandle: QuickJSHandle, state: T): void;
50
+ /**
51
+ * Get internal state by instance ID directly
52
+ * Useful when you have the instanceId from an unmarshaled object
53
+ */
54
+ export declare function getInstanceStateById<T>(instanceId: number): T | undefined;
55
+ /**
56
+ * Clean up instance state when an instance is no longer needed
57
+ */
58
+ export declare function cleanupInstanceState(instanceId: number): void;
59
+ /**
60
+ * Clear all instance state (useful for context disposal or testing cleanup)
61
+ */
62
+ export declare function clearAllInstanceState(): void;
@@ -0,0 +1,8 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ export interface DOMExceptionState {
4
+ message: string;
5
+ name: string;
6
+ code: number;
7
+ }
8
+ export declare function createDOMExceptionClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
@@ -0,0 +1,10 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ /**
4
+ * Create the File class for QuickJS (extends Blob)
5
+ */
6
+ export declare function createFileClass(context: QuickJSContext, stateMap: StateMap, _blobClass: QuickJSHandle): QuickJSHandle;
7
+ /**
8
+ * Create a File in QuickJS from host data
9
+ */
10
+ export declare function createFile(context: QuickJSContext, stateMap: StateMap, parts: BlobPart[], name: string, options?: FilePropertyBag): QuickJSHandle;
@@ -0,0 +1,23 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ /**
3
+ * Define a global function in the QuickJS context
4
+ *
5
+ * @returns Handle to the function (caller must manage disposal)
6
+ *
7
+ * @example
8
+ * const logFn = defineFunction(context, "log", (...args) => {
9
+ * console.log("[QuickJS]", ...args);
10
+ * });
11
+ * context.setProp(context.global, "log", logFn);
12
+ */
13
+ export declare function defineFunction(context: QuickJSContext, name: string, fn: (...args: unknown[]) => unknown): QuickJSHandle;
14
+ /**
15
+ * Define an async function that returns a promise to QuickJS
16
+ *
17
+ * @example
18
+ * const fetchFn = defineAsyncFunction(context, "fetch", async (url) => {
19
+ * const response = await fetch(String(url));
20
+ * return response.text();
21
+ * });
22
+ */
23
+ export declare function defineAsyncFunction(context: QuickJSContext, name: string, fn: (...args: unknown[]) => Promise<unknown>): QuickJSHandle;
@@ -0,0 +1,45 @@
1
+ import type { QuickJSContext } from "quickjs-emscripten";
2
+ import type { SetupCoreOptions, CoreHandle } from "./types.ts";
3
+ /**
4
+ * Setup core APIs in a QuickJS context
5
+ *
6
+ * Injects the following globals:
7
+ * - ReadableStream, WritableStream, TransformStream
8
+ * - ReadableStreamDefaultReader, WritableStreamDefaultWriter
9
+ * - Blob
10
+ * - File
11
+ * - DOMException
12
+ * - URL, URLSearchParams
13
+ *
14
+ * @example
15
+ * const handle = setupCore(context);
16
+ *
17
+ * context.evalCode(`
18
+ * const blob = new Blob(["hello", " ", "world"], { type: "text/plain" });
19
+ * const text = await blob.text(); // "hello world"
20
+ *
21
+ * const stream = new ReadableStream({
22
+ * start(controller) {
23
+ * controller.enqueue("chunk1");
24
+ * controller.enqueue("chunk2");
25
+ * controller.close();
26
+ * }
27
+ * });
28
+ * `);
29
+ */
30
+ export declare function setupCore(context: QuickJSContext, options?: SetupCoreOptions): CoreHandle;
31
+ export type { Scope, MarshalOptions, UnmarshalOptions, PropertyDescriptor, ClassDefinition, StateMap, SetupCoreOptions, CoreHandle, QuickJSContext, QuickJSHandle, QuickJSRuntime, } from "./types.ts";
32
+ export { INTERNAL_STATE } from "./types.ts";
33
+ export { withScope, withScopeAsync } from "./scope.ts";
34
+ export { marshal, isHandle, getHandleType } from "./marshal.ts";
35
+ export { unmarshal, cleanupUnmarshaledHandles } from "./unmarshal.ts";
36
+ export { defineFunction, defineAsyncFunction } from "./function-builder.ts";
37
+ export { defineClass, createStateMap, getState, setState, getInstanceState, setInstanceState, getInstanceStateById, cleanupInstanceState, clearAllInstanceState, } from "./class-builder.ts";
38
+ export { createReadableStream, consumeReadableStream, } from "./streams/readable-stream.ts";
39
+ export { createWritableStream } from "./streams/writable-stream.ts";
40
+ export { createBlob } from "./blob.ts";
41
+ export { createFile } from "./file.ts";
42
+ export { createURLSearchParamsClass } from "./url-search-params.ts";
43
+ export type { URLSearchParamsState } from "./url-search-params.ts";
44
+ export { createURLClass, addURLSearchParamsGetter } from "./url.ts";
45
+ export type { URLState } from "./url.ts";
@@ -0,0 +1,30 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { MarshalOptions } from "./types.ts";
3
+ /**
4
+ * Check if a value is a QuickJS handle
5
+ */
6
+ export declare function isHandle(value: unknown): value is QuickJSHandle;
7
+ /**
8
+ * Get the type of a QuickJS handle as a string
9
+ */
10
+ export declare function getHandleType(context: QuickJSContext, handle: QuickJSHandle): "undefined" | "null" | "boolean" | "number" | "string" | "symbol" | "object" | "function";
11
+ /**
12
+ * Marshal a JavaScript value to a QuickJS handle
13
+ *
14
+ * Supports:
15
+ * - Primitives (string, number, boolean, null, undefined, bigint)
16
+ * - Arrays
17
+ * - Plain objects
18
+ * - ArrayBuffer / Uint8Array
19
+ * - Date (converted to Date object in QuickJS)
20
+ * - Functions (wrapped as host functions)
21
+ * - Promises (wrapped with context.newPromise)
22
+ *
23
+ * @example
24
+ * const handle = marshal(context, {
25
+ * name: "test",
26
+ * values: [1, 2, 3],
27
+ * callback: (x) => x * 2
28
+ * });
29
+ */
30
+ export declare function marshal(context: QuickJSContext, value: unknown, options?: MarshalOptions): QuickJSHandle;
@@ -0,0 +1,18 @@
1
+ import type { QuickJSContext } from "quickjs-emscripten";
2
+ import type { Scope } from "./types.ts";
3
+ /**
4
+ * Execute a function with automatic handle cleanup
5
+ *
6
+ * @example
7
+ * const result = withScope(context, (scope) => {
8
+ * const obj = scope.manage(context.newObject());
9
+ * const str = scope.manage(context.newString("hello"));
10
+ * context.setProp(obj, "message", str);
11
+ * return context.dump(obj);
12
+ * });
13
+ */
14
+ export declare function withScope<T>(_context: QuickJSContext, fn: (scope: Scope) => T): T;
15
+ /**
16
+ * Async version of withScope for promise-based operations
17
+ */
18
+ export declare function withScopeAsync<T>(_context: QuickJSContext, fn: (scope: Scope) => Promise<T>): Promise<T>;
@@ -0,0 +1,18 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "../types.ts";
3
+ /**
4
+ * Create the ReadableStreamDefaultReader class
5
+ */
6
+ export declare function createReadableStreamDefaultReaderClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
7
+ /**
8
+ * Create the ReadableStream class
9
+ */
10
+ export declare function createReadableStreamClass(context: QuickJSContext, stateMap: StateMap, readerClass: QuickJSHandle): QuickJSHandle;
11
+ /**
12
+ * Create a ReadableStream in QuickJS from a host-side source
13
+ */
14
+ export declare function createReadableStream(context: QuickJSContext, stateMap: StateMap, source: UnderlyingSource): QuickJSHandle;
15
+ /**
16
+ * Consume a ReadableStream from QuickJS in the host
17
+ */
18
+ export declare function consumeReadableStream(context: QuickJSContext, stateMap: StateMap, streamHandle: QuickJSHandle): AsyncIterable<unknown>;
@@ -0,0 +1,6 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "../types.ts";
3
+ /**
4
+ * Create the TransformStream class
5
+ */
6
+ export declare function createTransformStreamClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
@@ -0,0 +1,14 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "../types.ts";
3
+ /**
4
+ * Create the WritableStreamDefaultWriter class
5
+ */
6
+ export declare function createWritableStreamDefaultWriterClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
7
+ /**
8
+ * Create the WritableStream class
9
+ */
10
+ export declare function createWritableStreamClass(context: QuickJSContext, stateMap: StateMap, writerClass: QuickJSHandle): QuickJSHandle;
11
+ /**
12
+ * Create a WritableStream in QuickJS from a host-side sink
13
+ */
14
+ export declare function createWritableStream(context: QuickJSContext, stateMap: StateMap, sink: UnderlyingSink): QuickJSHandle;
@@ -0,0 +1,83 @@
1
+ import type { QuickJSContext, QuickJSHandle, QuickJSRuntime } from "quickjs-emscripten";
2
+ export type { QuickJSContext, QuickJSHandle, QuickJSRuntime };
3
+ /**
4
+ * A scope for automatic handle cleanup
5
+ */
6
+ export interface Scope {
7
+ /** Track a handle for cleanup when scope ends */
8
+ manage<T extends QuickJSHandle>(handle: T): T;
9
+ /** Get all managed handles */
10
+ readonly handles: readonly QuickJSHandle[];
11
+ }
12
+ /**
13
+ * Options for marshalling values
14
+ */
15
+ export interface MarshalOptions {
16
+ /** Maximum depth for nested objects (default: 10) */
17
+ maxDepth?: number;
18
+ /** Custom marshaller for specific types */
19
+ custom?: (value: unknown, context: QuickJSContext) => QuickJSHandle | undefined;
20
+ }
21
+ /**
22
+ * Options for unmarshalling values
23
+ */
24
+ export interface UnmarshalOptions {
25
+ /** Maximum depth for nested objects (default: 10) */
26
+ maxDepth?: number;
27
+ /** Custom unmarshaller for specific handles */
28
+ custom?: (handle: QuickJSHandle, context: QuickJSContext) => unknown | undefined;
29
+ }
30
+ /**
31
+ * Property descriptor for class builder
32
+ */
33
+ export interface PropertyDescriptor<TState = unknown> {
34
+ get?: (this: TState) => any;
35
+ set?: (this: TState, value: any) => void;
36
+ value?: unknown;
37
+ writable?: boolean;
38
+ enumerable?: boolean;
39
+ configurable?: boolean;
40
+ }
41
+ /**
42
+ * Options for defining a class
43
+ */
44
+ export interface ClassDefinition<TState extends object = object> {
45
+ /** Class name */
46
+ name: string;
47
+ /** Constructor function - receives unmarshalled args, returns internal state */
48
+ construct?: (args: unknown[]) => TState;
49
+ /** Prototype methods */
50
+ methods?: Record<string, (this: TState, ...args: unknown[]) => unknown>;
51
+ /** Prototype getters/setters */
52
+ properties?: Record<string, PropertyDescriptor<TState>>;
53
+ /** Static methods */
54
+ staticMethods?: Record<string, (...args: unknown[]) => unknown>;
55
+ /** Static properties */
56
+ staticProperties?: Record<string, unknown>;
57
+ /** Parent class handle (for inheritance) */
58
+ extends?: QuickJSHandle;
59
+ }
60
+ /**
61
+ * Symbol used to store internal state on QuickJS class instances
62
+ */
63
+ export declare const INTERNAL_STATE: unique symbol;
64
+ /**
65
+ * Map to store internal state for QuickJS object handles
66
+ */
67
+ export type StateMap = WeakMap<QuickJSHandle, object>;
68
+ /**
69
+ * Options for setting up core APIs
70
+ */
71
+ export interface SetupCoreOptions {
72
+ /** Existing state map to use (creates new one if not provided) */
73
+ stateMap?: StateMap;
74
+ }
75
+ /**
76
+ * Handle returned from setupCore
77
+ */
78
+ export interface CoreHandle {
79
+ /** State map containing internal states */
80
+ readonly stateMap: StateMap;
81
+ /** Dispose all handles */
82
+ dispose(): void;
83
+ }
@@ -0,0 +1,14 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { UnmarshalOptions } from "./types.ts";
3
+ /**
4
+ * Clean up all duped handles for a context
5
+ * Should be called before disposing the context
6
+ */
7
+ export declare function cleanupUnmarshaledHandles(context: QuickJSContext): void;
8
+ /**
9
+ * Unmarshal a QuickJS handle to a JavaScript value
10
+ *
11
+ * @example
12
+ * const value = unmarshal(context, handle);
13
+ */
14
+ export declare function unmarshal(context: QuickJSContext, handle: QuickJSHandle, options?: UnmarshalOptions): unknown;
@@ -0,0 +1,12 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ /**
4
+ * Internal state for URLSearchParams
5
+ */
6
+ export interface URLSearchParamsState {
7
+ params: [string, string][];
8
+ }
9
+ /**
10
+ * Create the URLSearchParams class for QuickJS
11
+ */
12
+ export declare function createURLSearchParamsClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
@@ -0,0 +1,30 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ /**
4
+ * Internal state for URL
5
+ */
6
+ export interface URLState {
7
+ hash: string;
8
+ host: string;
9
+ hostname: string;
10
+ href: string;
11
+ origin: string;
12
+ password: string;
13
+ pathname: string;
14
+ port: string;
15
+ protocol: string;
16
+ search: string;
17
+ username: string;
18
+ }
19
+ /**
20
+ * Create the URL class for QuickJS
21
+ *
22
+ * Note: The searchParams property is added separately via evalCode
23
+ * after this class is registered, as it needs to return a URLSearchParams instance.
24
+ */
25
+ export declare function createURLClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
26
+ /**
27
+ * Add searchParams getter to URL prototype using evalCode
28
+ * This must be called after both URL and URLSearchParams are registered as globals
29
+ */
30
+ export declare function addURLSearchParamsGetter(context: QuickJSContext): void;
package/package.json CHANGED
@@ -1,10 +1,54 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-core",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @ricsam/quickjs-core",
3
+ "version": "0.2.0",
4
+ "main": "./dist/cjs/index.cjs",
5
+ "types": "./dist/types/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/types/index.d.ts",
9
+ "require": "./dist/cjs/index.cjs",
10
+ "import": "./dist/mjs/index.mjs"
11
+ }
12
+ },
13
+ "scripts": {
14
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun",
15
+ "test": "bun test",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "dependencies": {
19
+ "quickjs-emscripten": "^0.31.0"
20
+ },
21
+ "peerDependencies": {
22
+ "quickjs-emscripten": "^0.31.0"
23
+ },
24
+ "author": "Richard Samuelsson",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/ricsam/richie-qjs.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/ricsam/richie-qjs/issues"
32
+ },
33
+ "homepage": "https://github.com/ricsam/richie-qjs#readme",
5
34
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
35
+ "quickjs",
36
+ "sandbox",
37
+ "javascript",
38
+ "runtime",
39
+ "fetch",
40
+ "filesystem",
41
+ "streams",
42
+ "wasm",
43
+ "emscripten"
44
+ ],
45
+ "description": "Core utilities and class builder for QuickJS runtime bindings",
46
+ "module": "./dist/mjs/index.mjs",
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "files": [
51
+ "dist",
52
+ "README.md"
9
53
  ]
10
- }
54
+ }