diff --git a/Makefile b/Makefile index 3764ed06..f43ca4f5 100644 --- a/Makefile +++ b/Makefile @@ -39,4 +39,4 @@ perf-tester: .PHONY: regenerate_swiftpm_resources regenerate_swiftpm_resources: npm run build - cp Runtime/lib/index.js Runtime/lib/index.mjs Sources/JavaScriptKit/Runtime + cp Runtime/lib/index.js Runtime/lib/index.mjs Runtime/lib/index.d.ts Sources/JavaScriptKit/Runtime diff --git a/Plugins/PackageToJS/Sources/PackageToJS.swift b/Plugins/PackageToJS/Sources/PackageToJS.swift index 0402c745..da29164b 100644 --- a/Plugins/PackageToJS/Sources/PackageToJS.swift +++ b/Plugins/PackageToJS/Sources/PackageToJS.swift @@ -567,6 +567,7 @@ struct PackagingPlanner { ("Plugins/PackageToJS/Templates/platforms/node.js", "platforms/node.js"), ("Plugins/PackageToJS/Templates/platforms/node.d.ts", "platforms/node.d.ts"), ("Sources/JavaScriptKit/Runtime/index.mjs", "runtime.js"), + ("Sources/JavaScriptKit/Runtime/index.d.ts", "runtime.d.ts"), ] { packageInputs.append( planCopyTemplateFile( diff --git a/Plugins/PackageToJS/Templates/instantiate.d.ts b/Plugins/PackageToJS/Templates/instantiate.d.ts index 424d3517..3a88b12d 100644 --- a/Plugins/PackageToJS/Templates/instantiate.d.ts +++ b/Plugins/PackageToJS/Templates/instantiate.d.ts @@ -1,6 +1,4 @@ -/* #if USE_SHARED_MEMORY */ -import type { SwiftRuntimeThreadChannel, SwiftRuntime } from "./runtime.js"; -/* #endif */ +import type { /* #if USE_SHARED_MEMORY */SwiftRuntimeThreadChannel, /* #endif */SwiftRuntime } from "./runtime.js"; export type Import = { // TODO: Generate type from imported .d.ts files diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json index 0b1b2ac8..e525d134 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json @@ -233,6 +233,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -269,7 +286,8 @@ "$OUTPUT\/platforms\/browser.worker.js", "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", - "$OUTPUT\/runtime.js" + "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts" ] } ] \ No newline at end of file diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json index 889789bd..6e3480c5 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json @@ -248,6 +248,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -284,7 +301,8 @@ "$OUTPUT\/platforms\/browser.worker.js", "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", - "$OUTPUT\/runtime.js" + "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts" ] } ] \ No newline at end of file diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json index 0b1b2ac8..e525d134 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json @@ -233,6 +233,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -269,7 +286,8 @@ "$OUTPUT\/platforms\/browser.worker.js", "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", - "$OUTPUT\/runtime.js" + "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts" ] } ] \ No newline at end of file diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json index 889789bd..6e3480c5 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json @@ -248,6 +248,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -284,7 +301,8 @@ "$OUTPUT\/platforms\/browser.worker.js", "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", - "$OUTPUT\/runtime.js" + "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts" ] } ] \ No newline at end of file diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json index 0b1b2ac8..e525d134 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json @@ -233,6 +233,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -269,7 +286,8 @@ "$OUTPUT\/platforms\/browser.worker.js", "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", - "$OUTPUT\/runtime.js" + "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts" ] } ] \ No newline at end of file diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json index 59e5bb4a..2be6ce1d 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json @@ -274,6 +274,23 @@ { "attributes" : [ + ], + "inputs" : [ + "$PLANNER_SOURCE_PATH", + "$SELF_PACKAGE\/Sources\/JavaScriptKit\/Runtime\/index.d.ts", + "$INTERMEDIATES\/wasm-imports.json" + ], + "output" : "$OUTPUT\/runtime.d.ts", + "salt" : "eyJjb25kaXRpb25zIjp7IklTX1dBU0kiOnRydWUsIlVTRV9TSEFSRURfTUVNT1JZIjpmYWxzZSwiVVNFX1dBU0lfQ0ROIjpmYWxzZX0sInN1YnN0aXR1dGlvbnMiOnsiUEFDS0FHRV9UT19KU19NT0RVTEVfUEFUSCI6Im1haW4ud2FzbSIsIlBBQ0tBR0VfVE9fSlNfUEFDS0FHRV9OQU1FIjoidGVzdCJ9fQ==", + "wants" : [ + "$OUTPUT", + "$OUTPUT\/platforms", + "$INTERMEDIATES\/wasm-imports.json" + ] + }, + { + "attributes" : [ + ], "inputs" : [ "$PLANNER_SOURCE_PATH", @@ -356,6 +373,7 @@ "$OUTPUT\/platforms\/node.js", "$OUTPUT\/platforms\/node.d.ts", "$OUTPUT\/runtime.js", + "$OUTPUT\/runtime.d.ts", "$INTERMEDIATES\/npm-install.stamp", "$OUTPUT\/bin", "$OUTPUT\/test.js", diff --git a/Runtime/rollup.config.mjs b/Runtime/rollup.config.mjs index cf9b49b5..15efea49 100644 --- a/Runtime/rollup.config.mjs +++ b/Runtime/rollup.config.mjs @@ -1,20 +1,31 @@ import typescript from "@rollup/plugin-typescript"; +import dts from "rollup-plugin-dts"; /** @type {import('rollup').RollupOptions} */ -const config = { - input: "src/index.ts", - output: [ - { - file: "lib/index.mjs", +const config = [ + { + input: "src/index.ts", + output: [ + { + file: "lib/index.mjs", + format: "esm", + }, + { + file: "lib/index.js", + format: "umd", + name: "JavaScriptKit", + }, + ], + plugins: [typescript()], + }, + { + input: "src/index.ts", + output: { + file: "lib/index.d.ts", format: "esm", }, - { - dir: "lib", - format: "umd", - name: "JavaScriptKit", - }, - ], - plugins: [typescript()], -}; + plugins: [dts()], + }, +]; export default config; diff --git a/Runtime/tsconfig.json b/Runtime/tsconfig.json index 8a53ba2c..bd4f8a1a 100644 --- a/Runtime/tsconfig.json +++ b/Runtime/tsconfig.json @@ -1,7 +1,6 @@ { "compilerOptions": { - "declaration": true, - "declarationDir": "lib", + "declaration": false, "importHelpers": true, "module": "esnext", "noEmit": true, diff --git a/Sources/JavaScriptKit/Runtime/index.d.ts b/Sources/JavaScriptKit/Runtime/index.d.ts new file mode 100644 index 00000000..5bfa4c24 --- /dev/null +++ b/Sources/JavaScriptKit/Runtime/index.d.ts @@ -0,0 +1,262 @@ +declare class Memory { + readonly rawMemory: WebAssembly.Memory; + private readonly heap; + constructor(exports: WebAssembly.Exports); + retain: (value: any) => number; + getObject: (ref: number) => any; + release: (ref: number) => void; + bytes: () => Uint8Array; + dataView: () => DataView; + writeBytes: (ptr: pointer, bytes: Uint8Array) => void; + readUint32: (ptr: pointer) => number; + readUint64: (ptr: pointer) => bigint; + readInt64: (ptr: pointer) => bigint; + readFloat64: (ptr: pointer) => number; + writeUint32: (ptr: pointer, value: number) => void; + writeUint64: (ptr: pointer, value: bigint) => void; + writeInt64: (ptr: pointer, value: bigint) => void; + writeFloat64: (ptr: pointer, value: number) => void; +} + +declare const enum Kind { + Boolean = 0, + String = 1, + Number = 2, + Object = 3, + Null = 4, + Undefined = 5, + Function = 6, + Symbol = 7, + BigInt = 8 +} + +type ref = number; +type pointer = number; +type bool = number; +type JavaScriptValueKind = number; +type JavaScriptValueKindAndFlags = number; +interface ImportedFunctions { + swjs_set_prop(ref: number, name: number, kind: Kind, payload1: number, payload2: number): void; + swjs_get_prop(ref: number, name: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKind; + swjs_set_subscript(ref: number, index: number, kind: Kind, payload1: number, payload2: number): void; + swjs_get_subscript(ref: number, index: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKind; + swjs_encode_string(ref: number, bytes_ptr_result: pointer): number; + swjs_decode_string(bytes_ptr: pointer, length: number): number; + swjs_load_string(ref: number, buffer: pointer): void; + swjs_call_function(ref: number, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags; + swjs_call_function_no_catch(ref: number, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags; + swjs_call_function_with_this(obj_ref: ref, func_ref: ref, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags; + swjs_call_function_with_this_no_catch(obj_ref: ref, func_ref: ref, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags; + swjs_call_new(ref: number, argv: pointer, argc: number): number; + swjs_call_throwing_new(ref: number, argv: pointer, argc: number, exception_kind_ptr: pointer, exception_payload1_ptr: pointer, exception_payload2_ptr: pointer): number; + swjs_instanceof(obj_ref: ref, constructor_ref: ref): boolean; + swjs_create_function(host_func_id: number, line: number, file: ref): number; + swjs_create_typed_array(constructor_ref: ref, elementsPtr: pointer, length: number): number; + swjs_load_typed_array(ref: ref, buffer: pointer): void; + swjs_release(ref: number): void; + swjs_release_remote(tid: number, ref: number): void; + swjs_i64_to_bigint(value: bigint, signed: bool): ref; + swjs_bigint_to_i64(ref: ref, signed: bool): bigint; + swjs_i64_to_bigint_slow(lower: number, upper: number, signed: bool): ref; + swjs_unsafe_event_loop_yield: () => void; + swjs_send_job_to_main_thread: (unowned_job: number) => void; + swjs_listen_message_from_main_thread: () => void; + swjs_wake_up_worker_thread: (tid: number) => void; + swjs_listen_message_from_worker_thread: (tid: number) => void; + swjs_terminate_worker_thread: (tid: number) => void; + swjs_get_worker_thread_id: () => number; + swjs_request_sending_object: (sending_object: ref, transferring_objects: pointer, transferring_objects_count: number, object_source_tid: number, sending_context: pointer) => void; + swjs_request_sending_objects: (sending_objects: pointer, sending_objects_count: number, transferring_objects: pointer, transferring_objects_count: number, object_source_tid: number, sending_context: pointer) => void; +} + +/** + * A thread channel is a set of functions that are used to communicate between + * the main thread and the worker thread. The main thread and the worker thread + * can send messages to each other using these functions. + * + * @example + * ```javascript + * // worker.js + * const runtime = new SwiftRuntime({ + * threadChannel: { + * postMessageToMainThread: postMessage, + * listenMessageFromMainThread: (listener) => { + * self.onmessage = (event) => { + * listener(event.data); + * }; + * } + * } + * }); + * + * // main.js + * const worker = new Worker("worker.js"); + * const runtime = new SwiftRuntime({ + * threadChannel: { + * postMessageToWorkerThread: (tid, data) => { + * worker.postMessage(data); + * }, + * listenMessageFromWorkerThread: (tid, listener) => { + * worker.onmessage = (event) => { + listener(event.data); + * }; + * } + * } + * }); + * ``` + */ +type SwiftRuntimeThreadChannel = { + /** + * This function is used to send messages from the worker thread to the main thread. + * The message submitted by this function is expected to be listened by `listenMessageFromWorkerThread`. + * @param message The message to be sent to the main thread. + * @param transfer The array of objects to be transferred to the main thread. + */ + postMessageToMainThread: (message: WorkerToMainMessage, transfer: any[]) => void; + /** + * This function is expected to be set in the worker thread and should listen + * to messages from the main thread sent by `postMessageToWorkerThread`. + * @param listener The listener function to be called when a message is received from the main thread. + */ + listenMessageFromMainThread: (listener: (message: MainToWorkerMessage) => void) => void; +} | { + /** + * This function is expected to be set in the main thread. + * The message submitted by this function is expected to be listened by `listenMessageFromMainThread`. + * @param tid The thread ID of the worker thread. + * @param message The message to be sent to the worker thread. + * @param transfer The array of objects to be transferred to the worker thread. + */ + postMessageToWorkerThread: (tid: number, message: MainToWorkerMessage, transfer: any[]) => void; + /** + * This function is expected to be set in the main thread and should listen + * to messages sent by `postMessageToMainThread` from the worker thread. + * @param tid The thread ID of the worker thread. + * @param listener The listener function to be called when a message is received from the worker thread. + */ + listenMessageFromWorkerThread: (tid: number, listener: (message: WorkerToMainMessage) => void) => void; + /** + * This function is expected to be set in the main thread and called + * when the worker thread is terminated. + * @param tid The thread ID of the worker thread. + */ + terminateWorkerThread?: (tid: number) => void; +}; +declare class ITCInterface { + private memory; + constructor(memory: Memory); + send(sendingObject: ref, transferringObjects: ref[], sendingContext: pointer): { + object: any; + sendingContext: pointer; + transfer: Transferable[]; + }; + sendObjects(sendingObjects: ref[], transferringObjects: ref[], sendingContext: pointer): { + object: any[]; + sendingContext: pointer; + transfer: Transferable[]; + }; + release(objectRef: ref): { + object: undefined; + transfer: Transferable[]; + }; +} +type AllRequests> = { + [K in keyof Interface]: { + method: K; + parameters: Parameters; + }; +}; +type ITCRequest> = AllRequests[keyof AllRequests]; +type AllResponses> = { + [K in keyof Interface]: ReturnType; +}; +type ITCResponse> = AllResponses[keyof AllResponses]; +type RequestMessage = { + type: "request"; + data: { + /** The TID of the thread that sent the request */ + sourceTid: number; + /** The TID of the thread that should respond to the request */ + targetTid: number; + /** The context pointer of the request */ + context: pointer; + /** The request content */ + request: ITCRequest; + }; +}; +type SerializedError = { + isError: true; + value: Error; +} | { + isError: false; + value: unknown; +}; +type ResponseMessage = { + type: "response"; + data: { + /** The TID of the thread that sent the response */ + sourceTid: number; + /** The context pointer of the request */ + context: pointer; + /** The response content */ + response: { + ok: true; + value: ITCResponse; + } | { + ok: false; + error: SerializedError; + }; + }; +}; +type MainToWorkerMessage = { + type: "wake"; +} | RequestMessage | ResponseMessage; +type WorkerToMainMessage = { + type: "job"; + data: number; +} | RequestMessage | ResponseMessage; + +type SwiftRuntimeOptions = { + /** + * If `true`, the memory space of the WebAssembly instance can be shared + * between the main thread and the worker thread. + */ + sharedMemory?: boolean; + /** + * The thread channel is a set of functions that are used to communicate + * between the main thread and the worker thread. + */ + threadChannel?: SwiftRuntimeThreadChannel; +}; +declare class SwiftRuntime { + private _instance; + private _memory; + private _closureDeallocator; + private options; + private version; + private textDecoder; + private textEncoder; + /** The thread ID of the current thread. */ + private tid; + constructor(options?: SwiftRuntimeOptions); + setInstance(instance: WebAssembly.Instance): void; + main(): void; + /** + * Start a new thread with the given `tid` and `startArg`, which + * is forwarded to the `wasi_thread_start` function. + * This function is expected to be called from the spawned Web Worker thread. + */ + startThread(tid: number, startArg: number): void; + private get instance(); + private get exports(); + private get memory(); + private get closureDeallocator(); + private callHostFunction; + /** @deprecated Use `wasmImports` instead */ + importObjects: () => ImportedFunctions; + get wasmImports(): ImportedFunctions; + private postMessageToMainThread; + private postMessageToWorkerThread; +} + +export { SwiftRuntime }; +export type { SwiftRuntimeOptions }; diff --git a/package-lock.json b/package-lock.json index fe5959f9..ec5bd0a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,9 +13,41 @@ "playwright": "^1.51.0", "prettier": "3.5.3", "rollup": "^4.37.0", + "rollup-plugin-dts": "^6.2.1", "typescript": "^5.8.2" } }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "optional": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, "node_modules/@rollup/plugin-typescript": { "version": "12.1.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", @@ -414,6 +446,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "optional": true + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -421,6 +469,13 @@ "dev": true, "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "optional": true + }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", @@ -543,6 +598,28 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-dts": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.2.1.tgz", + "integrity": "sha512-sR3CxYUl7i2CHa0O7bA45mCrgADyAQ0tVtGSqi3yvH28M+eg1+g5d7kQ9hLvEz5dorK3XVsH5L2jwHLQf72DzA==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.17" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.26.2" + }, + "peerDependencies": { + "rollup": "^3.29.4 || ^4", + "typescript": "^4.5 || ^5.0" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", diff --git a/package.json b/package.json index 35a7661c..0ff2d17a 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "playwright": "^1.51.0", "prettier": "3.5.3", "rollup": "^4.37.0", + "rollup-plugin-dts": "^6.2.1", "typescript": "^5.8.2" } }