import * as RbAbi from "./bindgen/rb-abi-guest"; import { JsAbiValue } from "./bindgen/rb-js-abi-host"; /** * A Ruby VM instance * * @example * * const wasi = new WASI(); * const vm = new RubyVM(); * const imports = { * wasi_snapshot_preview1: wasi.wasiImport, * }; * * vm.addToImports(imports); * * const instance = await WebAssembly.instantiate(rubyModule, imports); * await vm.setInstance(instance); * wasi.initialize(instance); * vm.initialize(); * */ export declare class RubyVM { guest: RbAbi.RbAbiGuest; private instance; private transport; private exceptionFormatter; private interfaceState; constructor(); /** * Initialize the Ruby VM with the given command line arguments * @param args The command line arguments to pass to Ruby. Must be * an array of strings starting with the Ruby program name. */ initialize(args?: string[]): void; /** * Set a given instance to interact JavaScript and Ruby's * WebAssembly instance. This method must be called before calling * Ruby API. * * @param instance The WebAssembly instance to interact with. Must * be instantiated from a Ruby built with JS extension, and built * with Reactor ABI instead of command line. */ setInstance(instance: WebAssembly.Instance): Promise; /** * Add intrinsic import entries, which is necessary to interact JavaScript * and Ruby's WebAssembly instance. * @param imports The import object to add to the WebAssembly instance */ addToImports(imports: WebAssembly.Imports): void; /** * Print the Ruby version to stdout */ printVersion(): void; /** * Runs a string of Ruby code from JavaScript * @param code The Ruby code to run * @returns the result of the last expression * * @example * vm.eval("puts 'hello world'"); * const result = vm.eval("1 + 2"); * console.log(result.toString()); // 3 * */ eval(code: string): RbValue; /** * Runs a string of Ruby code with top-level `JS::Object#await` * Returns a promise that resolves when execution completes. * @param code The Ruby code to run * @returns a promise that resolves to the result of the last expression * * @example * const text = await vm.evalAsync(` * require 'js' * response = JS.global.fetch('https://example.com').await * response.text.await * `); * console.log(text.toString()); // ... */ evalAsync(code: string): Promise; /** * Wrap a JavaScript value into a Ruby JS::Object * @param value The value to convert to RbValue * @returns the RbValue object representing the given JS value * * @example * const hash = vm.eval(`Hash.new`) * hash.call("store", vm.eval(`"key1"`), vm.wrap(new Object())); */ wrap(value: any): RbValue; private privateObject; private rbValueOfPointer; } /** * Export a JS value held by the Ruby VM to the JS environment. * This is implemented in a dirty way since wit cannot reference resources * defined in other interfaces. * In our case, we can't express `function(v: rb-abi-value) -> js-abi-value` * because `rb-js-abi-host.wit`, that defines `js-abi-value`, is implemented * by embedder side (JS) but `rb-abi-guest.wit`, that defines `rb-abi-value` * is implemented by guest side (Wasm). * * This class is a helper to export by: * 1. Call `function __export_to_js(v: rb-abi-value)` defined in guest from embedder side. * 2. Call `function takeJsValue(v: js-abi-value)` defined in embedder from guest side with * underlying JS value of given `rb-abi-value`. * 3. Then `takeJsValue` implementation escapes the given JS value to the `_takenJsValues` * stored in embedder side. * 4. Finally, embedder side can take `_takenJsValues`. * * Note that `exportJsValue` is not reentrant. * * @private */ declare class JsValueTransport { private _takenJsValue; takeJsValue(value: JsAbiValue): void; consumeJsValue(): JsAbiValue; exportJsValue(value: RbValue): JsAbiValue; importJsValue(value: JsAbiValue, vm: RubyVM): RbValue; } /** * A RbValue is an object that represents a value in Ruby */ export declare class RbValue { private inner; private vm; private privateObject; /** * @hideconstructor */ constructor(inner: RbAbi.RbAbiValue, vm: RubyVM, privateObject: RubyVMPrivate); /** * Call a given method with given arguments * * @param callee name of the Ruby method to call * @param args arguments to pass to the method. Must be an array of RbValue * * @example * const ary = vm.eval("[1, 2, 3]"); * ary.call("push", 4); * console.log(ary.call("sample").toString()); * */ call(callee: string, ...args: RbValue[]): RbValue; /** * @see {@link https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive} * @param hint Preferred type of the result primitive value. `"number"`, `"string"`, or `"default"`. */ [Symbol.toPrimitive](hint: string): string; /** * Returns a string representation of the value by calling `to_s` */ toString(): string; /** * Returns a JavaScript object representation of the value * by calling `to_js`. * * Returns null if the value is not convertible to a JavaScript object. */ toJS(): any; } type RubyVMPrivate = { transport: JsValueTransport; exceptionFormatter: RbExceptionFormatter; }; declare class RbExceptionFormatter { private literalsCache; format(error: RbValue, vm: RubyVM, privateObject: RubyVMPrivate): string; formatString(klass: string, message: string, backtrace?: [string, string]): string; } /** * Error class thrown by Ruby execution */ export declare class RbError extends Error { /** * @hideconstructor */ constructor(message: string); } /** * Error class thrown by Ruby execution when it is not possible to recover. * This is usually caused when Ruby VM is in an inconsistent state. */ export declare class RbFatalError extends RbError { /** * @hideconstructor */ constructor(message: string); } export {};