@microverse.ts/runtime-wasm 0.1.0 → 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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/infrastructure/runtime/microverseLuaSlotVmBootstrap.ts","../src/infrastructure/runtime/luaLongString.ts","../src/infrastructure/runtime/wasmoonExecutePolicy.ts","../src/infrastructure/runtime/WasmoonRuntimeAdapter.ts","../src/infrastructure/runtime/createWasmMicroverseRuntime.ts","../src/infrastructure/worker/WorkerMicroverseHost.ts"],"sourcesContent":["/**\n * Lua 5.4 bootstrap for **one Wasmoon VM, many slots**:\n * - Slot `_ENV` uses a **safe global** table (no `debug`, `load`, `io`, `os`, …).\n * - Slot registry and internals are **closure-local** (not on `_G`).\n * - Bridge tables are **read-only** from Lua (`__newindex`); host re-injects via `mergeEnv` each run.\n * - **No auto-await**: async bridges return a handle with `:await()`; optional 2nd-arg callback runs after the current chunk step.\n * - Optional **instruction budget** per chunk via `debug.sethook` when available.\n */\nexport const MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET = 5_000_000;\n\nexport const MICROVERSE_LUA_SLOT_VM_BOOTSTRAP = `\ndo\n local REAL_G = _G\n local envs = {}\n local pending_async = {}\n\n local function copy_functions(lib)\n if type(lib) ~= \"table\" then return nil end\n local out = {}\n for k, v in pairs(lib) do\n if type(v) == \"function\" then\n out[k] = v\n end\n end\n return out\n end\n\n local function copy_math()\n local src = REAL_G.math\n if type(src) ~= \"table\" then return {} end\n local blocked = { random = true, randomseed = true }\n local out = {}\n for k, v in pairs(src) do\n if type(v) == \"function\" and not blocked[k] then\n out[k] = v\n end\n end\n return out\n end\n\n local SAFE_G = {\n assert = assert,\n error = error,\n getmetatable = getmetatable,\n ipairs = ipairs,\n next = next,\n pairs = pairs,\n pcall = pcall,\n rawequal = rawequal,\n rawget = rawget,\n rawlen = rawlen,\n rawset = rawset,\n select = select,\n setmetatable = setmetatable,\n tonumber = tonumber,\n tostring = tostring,\n type = type,\n xpcall = xpcall,\n table = copy_functions(REAL_G.table),\n string = copy_functions(REAL_G.string),\n math = copy_math(),\n _VERSION = REAL_G._VERSION,\n }\n\n local ENV_MT = { __index = SAFE_G }\n\n local function ensure_env(slot_key)\n local e = envs[slot_key]\n if not e then\n e = {}\n setmetatable(e, ENV_MT)\n envs[slot_key] = e\n end\n return e\n end\n\n local debug_lib = REAL_G.debug\n local DEFAULT_BUDGET = ${MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}\n local HOOK_STEP = 10000\n\n local function is_awaitable(r)\n if type(r) == \"userdata\" or type(r) == \"table\" then\n return type(r.await) == \"function\"\n end\n return false\n end\n\n function __microverse_lua_await_value(r)\n if not is_awaitable(r) then\n return r\n end\n local ok, out = pcall(function()\n return r:await()\n end)\n if not ok then\n error(out, 0)\n end\n return out\n end\n\n function __microverse_lua_wrap_async_result(r)\n if not is_awaitable(r) then\n return r\n end\n return setmetatable({}, {\n __index = function(_, key)\n if key == \"await\" then\n return function()\n return __microverse_lua_await_value(r)\n end\n end\n return nil\n end,\n })\n end\n\n local function is_lua_callback(v)\n return type(v) == \"function\"\n end\n\n local function schedule_on_complete(onComplete, r)\n pending_async[#pending_async + 1] = { cb = onComplete, r = r }\n end\n\n local function flush_pending_async()\n for i = 1, #pending_async do\n local job = pending_async[i]\n local out = __microverse_lua_await_value(job.r)\n job.cb(out)\n end\n end\n\n local function proxy_bridge(impl)\n return setmetatable({}, {\n __index = function(_, method)\n local f = impl[method]\n if type(f) ~= \"function\" then\n return nil\n end\n return function(...)\n local n = select(\"#\", ...)\n local onComplete = nil\n local payload\n if n >= 3 and is_lua_callback(select(3, ...)) then\n onComplete = select(3, ...)\n payload = select(2, ...)\n elseif n >= 2 and is_lua_callback(select(2, ...)) then\n onComplete = select(2, ...)\n payload = select(1, ...)\n elseif n >= 2 then\n payload = select(2, ...)\n elseif n >= 1 then\n payload = select(1, ...)\n end\n local r\n if onComplete ~= nil then\n if payload ~= nil then\n r = f(impl, payload)\n else\n r = f(impl)\n end\n schedule_on_complete(onComplete, r)\n return nil\n end\n if payload ~= nil then\n r = f(impl, payload)\n elseif n == 0 then\n r = f(impl)\n else\n r = f(impl, select(1, ...))\n end\n return __microverse_lua_wrap_async_result(r)\n end\n end,\n __newindex = function(_, key)\n error(\"microverse: bridge table is read-only (\" .. tostring(key) .. \")\", 2)\n end,\n })\n end\n\n function __microverse_lua_put_bridge_from_global(slot_key, field_name, global_tmp_key)\n local e = ensure_env(slot_key)\n local v = REAL_G[global_tmp_key]\n REAL_G[global_tmp_key] = nil\n if type(v) == \"userdata\" or type(v) == \"table\" then\n v = proxy_bridge(v)\n end\n rawset(e, field_name, v)\n end\n\n function __microverse_lua_execute_in_slot(slot_key, source, instr_budget)\n instr_budget = instr_budget or DEFAULT_BUDGET\n pending_async = {}\n local env = ensure_env(slot_key)\n local f, load_err = load(source, \"@\" .. tostring(slot_key), \"t\", env)\n if not f then\n error(load_err or \"load failed\", 0)\n end\n local count = 0\n if debug_lib and debug_lib.sethook then\n debug_lib.sethook(function()\n count = count + HOOK_STEP\n if count > instr_budget then\n debug_lib.sethook()\n error(\"microverse: instruction limit exceeded\", 0)\n end\n end, \"\", HOOK_STEP)\n end\n local ok, result = pcall(f)\n if debug_lib and debug_lib.sethook then\n debug_lib.sethook()\n end\n flush_pending_async()\n if not ok then\n error(result, 0)\n end\n return result\n end\n\n function __microverse_lua_destroy_slot(slot_key)\n envs[slot_key] = nil\n end\nend\n`.trim();\n","/** Builds a Lua long literal `[=*[ ... ]=*]` so `source` can contain `]`, newlines, etc. */\nexport function toLuaLongStringLiteral(source: string): string {\n let eq = 0;\n while (true) {\n const close = `]${'='.repeat(eq)}]`;\n if (!source.includes(close)) {\n break;\n }\n eq += 1;\n }\n const open = `[${'='.repeat(eq)}[`;\n const shut = `]${'='.repeat(eq)}]`;\n return `${open}${source}${shut}`;\n}\n","import type { CancellationToken, TimeoutPolicy } from '@microverse.ts/runtime-core';\n\nexport const MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS = 512_000;\n\ntype SchedulerHost = {\n setTimeout(callback: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n};\n\ntype TimerHandle = unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- globalThis lacks SchedulerHost in lib.dom\nconst schedulerHost = (): SchedulerHost => globalThis as unknown as SchedulerHost;\n\nconst scheduleTimeout = (fn: () => void, ms: number): TimerHandle => {\n const host = schedulerHost();\n if (typeof host.setTimeout !== 'function') {\n throw new Error('microverse: setTimeout is not available in this runtime');\n }\n return host.setTimeout(fn, ms);\n};\n\nconst cancelTimeout = (handle: TimerHandle): void => {\n const host = schedulerHost();\n if (typeof host.clearTimeout === 'function') {\n host.clearTimeout(handle);\n }\n};\n\nclass MicroverseTimeoutError extends Error {\n constructor() {\n super('microverse: execution timed out');\n this.name = 'MicroverseTimeoutError';\n }\n}\n\nexport function resolveTimeoutMs(timeout: TimeoutPolicy | undefined): number | undefined {\n if (timeout === undefined || timeout.kind === 'none') {\n return undefined;\n }\n return timeout.milliseconds;\n}\n\nexport function assertScriptSize(script: string, maxChars: number): void {\n if (script.length > maxChars) {\n throw new Error(`microverse: script exceeds max size (${script.length} > ${maxChars})`);\n }\n}\n\nexport function assertNotCancelled(cancellation: CancellationToken): void {\n if (cancellation.isCancelled()) {\n throw new Error('microverse: execution cancelled');\n }\n}\n\n/**\n * Runs an async Lua invocation with optional wall-clock timeout.\n * Note: synchronous infinite Lua still blocks the thread until the instruction hook fires;\n * callers should combine with {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET} in the bootstrap.\n */\nexport async function runWithWallClockTimeout(\n run: () => Promise<void>,\n timeoutMs: number | undefined,\n): Promise<'ok' | 'timeout'> {\n if (timeoutMs === undefined) {\n await run();\n return 'ok';\n }\n // TimerHandle is intentionally opaque (`unknown`).\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- explicit optional slot\n let timer: TimerHandle | undefined;\n try {\n await Promise.race([\n run(),\n new Promise<never>((_, reject) => {\n timer = scheduleTimeout(() => reject(new MicroverseTimeoutError()), timeoutMs);\n }),\n ]);\n return 'ok';\n } catch (e) {\n if (e instanceof MicroverseTimeoutError) {\n return 'timeout';\n }\n throw e;\n } finally {\n if (timer !== undefined) {\n cancelTimeout(timer);\n }\n }\n}\n\nexport function mapExecuteError(e: unknown): { readonly _tag: 'Timeout' } | { readonly _tag: 'Cancelled' } | { readonly _tag: 'AdapterError'; readonly message: string } {\n if (e instanceof MicroverseTimeoutError) {\n return { _tag: 'Timeout' };\n }\n const message = e instanceof Error ? e.message : String(e);\n if (message.includes('execution cancelled')) {\n return { _tag: 'Cancelled' };\n }\n if (message.includes('instruction limit exceeded') || message.includes('script exceeds max size')) {\n return { _tag: 'AdapterError', message };\n }\n return { _tag: 'AdapterError', message };\n}\n","import { err, ok, type Result } from '@microverse.ts/shared';\nimport { LuaFactory } from 'wasmoon';\n\nimport type {\n ExecutionContext,\n ExecutionFailure,\n RuntimeAdapter,\n RunScriptInput,\n RunScriptResult,\n MicroverseId,\n} from '@microverse.ts/runtime-core';\n\nimport {\n MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET,\n MICROVERSE_LUA_SLOT_VM_BOOTSTRAP,\n} from './microverseLuaSlotVmBootstrap';\nimport { toLuaLongStringLiteral } from './luaLongString';\nimport {\n assertNotCancelled,\n assertScriptSize,\n MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS,\n mapExecuteError,\n resolveTimeoutMs,\n runWithWallClockTimeout,\n} from './wasmoonExecutePolicy';\n\ntype WasmoonLuaEngine = Awaited<ReturnType<LuaFactory['createEngine']>>;\n\nexport type WasmoonRuntimeAdapterOptions = {\n /** Rejects {@link RunScriptInput.script} larger than this (default {@link MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS}). */\n readonly maxScriptChars?: number | undefined;\n /** Passed to `__microverse_lua_execute_in_slot` when the third argument is omitted (default {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}). */\n readonly defaultInstructionBudget?: number | undefined;\n};\n\nexport class WasmoonRuntimeAdapter implements RuntimeAdapter {\n private readonly factory = new LuaFactory();\n\n private readonly maxScriptChars: number;\n\n private readonly defaultInstructionBudget: number;\n\n private engineInit: Promise<WasmoonLuaEngine> | undefined;\n\n constructor(private readonly options: WasmoonRuntimeAdapterOptions = {}) {\n this.maxScriptChars = options.maxScriptChars ?? MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS;\n this.defaultInstructionBudget =\n options.defaultInstructionBudget ?? MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET;\n }\n\n private getEngine = (): Promise<WasmoonLuaEngine> => {\n if (this.engineInit === undefined) {\n this.engineInit = (async () => {\n const lua = await this.factory.createEngine({ injectObjects: true });\n await lua.doString(MICROVERSE_LUA_SLOT_VM_BOOTSTRAP);\n return lua;\n })();\n }\n return this.engineInit;\n };\n\n private resetEngine = async (): Promise<void> => {\n const current = this.engineInit;\n this.engineInit = undefined;\n if (current === undefined) {\n return;\n }\n const lua = await current.catch(() => undefined);\n if (lua !== undefined) {\n try {\n await Promise.resolve(lua.global.close());\n } catch {\n // ignore\n }\n }\n };\n\n private runLua = async (lua: WasmoonLuaEngine, chunk: string): Promise<void> => {\n await lua.doString(chunk);\n };\n\n readonly execute = async (\n ctx: ExecutionContext,\n input: RunScriptInput,\n ): Promise<Result<RunScriptResult, ExecutionFailure>> => {\n try {\n assertNotCancelled(ctx.cancellation);\n assertScriptSize(String(input.script), this.maxScriptChars);\n } catch (e) {\n return err(mapExecuteError(e));\n }\n\n const timeoutMs = resolveTimeoutMs(input.timeout);\n const budget = this.defaultInstructionBudget;\n\n const runOnce = async (): Promise<Result<RunScriptResult, ExecutionFailure>> => {\n const lua = await this.getEngine();\n const slotLit = toLuaLongStringLiteral(String(ctx.microverseId));\n const merge = input.mergeEnv;\n if (merge !== undefined && Object.keys(merge).length > 0) {\n for (const name of Object.keys(merge)) {\n if (!Object.prototype.hasOwnProperty.call(merge, name)) {\n continue;\n }\n const tmp = `__microverse_lua_one_${randomMicroverseToken()}`;\n lua.global.set(tmp, merge[name]);\n const nameLit = toLuaLongStringLiteral(name);\n const tmpLit = toLuaLongStringLiteral(tmp);\n const putChunk = `__microverse_lua_put_bridge_from_global(${slotLit}, ${nameLit}, ${tmpLit})`;\n const putOutcome = await runWithWallClockTimeout(() => this.runLua(lua, putChunk), timeoutMs);\n if (putOutcome === 'timeout') {\n await this.resetEngine();\n return err({ _tag: 'Timeout' });\n }\n }\n }\n const srcLit = toLuaLongStringLiteral(String(input.script));\n const execChunk = `__microverse_lua_execute_in_slot(${slotLit}, ${srcLit}, ${budget})`;\n const execOutcome = await runWithWallClockTimeout(() => this.runLua(lua, execChunk), timeoutMs);\n if (execOutcome === 'timeout') {\n await this.resetEngine();\n return err({ _tag: 'Timeout' });\n }\n return ok({ output: 'lua_ok' });\n };\n\n try {\n return await runOnce();\n } catch (e) {\n const mapped = mapExecuteError(e);\n if (mapped._tag === 'AdapterError' && mapped.message.includes('instruction limit exceeded')) {\n await this.resetEngine();\n }\n return err(mapped);\n }\n };\n\n readonly disposeMicroverse = async (microverseId: MicroverseId): Promise<void> => {\n if (this.engineInit === undefined) {\n return;\n }\n const lua = await this.engineInit.catch(() => undefined);\n if (lua === undefined) {\n return;\n }\n const slotLit = toLuaLongStringLiteral(String(microverseId));\n try {\n await lua.doString(`__microverse_lua_destroy_slot(${slotLit})`);\n } catch {\n // ignore\n }\n };\n}\n\nfunction randomMicroverseToken(): string {\n const g = globalThis as typeof globalThis & { crypto?: { randomUUID?: () => string } };\n if (g.crypto?.randomUUID) {\n return g.crypto.randomUUID();\n }\n return Math.random().toString(16).slice(2);\n}\n","import {\n ConsoleLogger,\n createStubMicroverseRuntime,\n type MicroverseRuntime,\n type TimeoutPolicy,\n} from '@microverse.ts/runtime-core';\n\nimport { WasmoonRuntimeAdapter, type WasmoonRuntimeAdapterOptions } from './WasmoonRuntimeAdapter';\n\nexport type WasmMicroverseRuntimeOptions = WasmoonRuntimeAdapterOptions & {\n /** Default timeout forwarded to each {@link MicroverseSlot.run} when the call omits `timeout`. */\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n};\n\n/**\n * Wasmoon-backed {@link MicroverseRuntime} with hardened slot bootstrap (safe globals, instruction budget).\n */\nexport function createWasmMicroverseRuntime(options: WasmMicroverseRuntimeOptions = {}): MicroverseRuntime {\n const { defaultTimeout, ...adapterOptions } = options;\n return createStubMicroverseRuntime({\n adapter: new WasmoonRuntimeAdapter(adapterOptions),\n logger: new ConsoleLogger(),\n defaultTimeout,\n });\n}\n","import type {\n WorkerHostToRuntimeMessage,\n WorkerRuntimeToHostMessage,\n} from '../../domain/worker/WorkerMicroverseMessages';\n\nexport class WorkerMicroverseHost {\n private last: WorkerRuntimeToHostMessage | null = null;\n\n readonly post = (message: WorkerHostToRuntimeMessage): void => {\n void message;\n this.last = { _tag: 'ready' };\n };\n\n readonly drain = (): WorkerRuntimeToHostMessage | undefined => {\n const v = this.last;\n this.last = null;\n return v === null ? undefined : v;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/infrastructure/runtime/microverseLuaSlotVmBootstrap.ts","../src/infrastructure/runtime/luaLongString.ts","../src/infrastructure/runtime/wasmoonExecutePolicy.ts","../src/infrastructure/runtime/WasmoonRuntimeAdapter.ts","../src/infrastructure/runtime/createWasmMicroverseRuntime.ts","../src/infrastructure/worker/WorkerMicroverseHost.ts"],"sourcesContent":["/**\n * Lua 5.4 bootstrap for **one Wasmoon VM, many slots**:\n * - Slot `_ENV` uses a **safe global** table (no `debug`, `load`, `io`, `os`, …).\n * - Slot registry and internals are **closure-local** (not on `_G`).\n * - Bridge tables are **read-only** from Lua (`__newindex`); host re-injects via `mergeEnv` each run.\n * - **No auto-await**: async bridges return a handle with `:await()`; optional 2nd-arg callback runs after the current chunk step.\n * - Optional **instruction budget** per chunk via `debug.sethook` when available.\n */\nexport const MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET = 5_000_000;\n\nexport const MICROVERSE_LUA_SLOT_VM_BOOTSTRAP = `\ndo\n local REAL_G = _G\n local envs = {}\n local pending_async = {}\n\n local function copy_functions(lib)\n if type(lib) ~= \"table\" then return nil end\n local out = {}\n for k, v in pairs(lib) do\n if type(v) == \"function\" then\n out[k] = v\n end\n end\n return out\n end\n\n local function copy_math()\n local src = REAL_G.math\n if type(src) ~= \"table\" then return {} end\n local blocked = { random = true, randomseed = true }\n local out = {}\n for k, v in pairs(src) do\n if type(v) == \"function\" and not blocked[k] then\n out[k] = v\n end\n end\n return out\n end\n\n local SAFE_G = {\n assert = assert,\n error = error,\n getmetatable = getmetatable,\n ipairs = ipairs,\n next = next,\n pairs = pairs,\n pcall = pcall,\n rawequal = rawequal,\n rawget = rawget,\n rawlen = rawlen,\n rawset = rawset,\n select = select,\n setmetatable = setmetatable,\n tonumber = tonumber,\n tostring = tostring,\n type = type,\n xpcall = xpcall,\n table = copy_functions(REAL_G.table),\n string = copy_functions(REAL_G.string),\n math = copy_math(),\n _VERSION = REAL_G._VERSION,\n }\n\n local ENV_MT = { __index = SAFE_G }\n\n local function ensure_env(slot_key)\n local e = envs[slot_key]\n if not e then\n e = {}\n setmetatable(e, ENV_MT)\n envs[slot_key] = e\n end\n return e\n end\n\n local debug_lib = REAL_G.debug\n local DEFAULT_BUDGET = ${MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}\n local HOOK_STEP = 10000\n\n local function is_awaitable(r)\n if type(r) == \"userdata\" or type(r) == \"table\" then\n return type(r.await) == \"function\"\n end\n return false\n end\n\n function __microverse_lua_await_value(r)\n if not is_awaitable(r) then\n return r\n end\n local ok, out = pcall(function()\n return r:await()\n end)\n if not ok then\n error(out, 0)\n end\n return out\n end\n\n function __microverse_lua_wrap_async_result(r)\n if not is_awaitable(r) then\n return r\n end\n return setmetatable({}, {\n __index = function(_, key)\n if key == \"await\" then\n return function()\n return __microverse_lua_await_value(r)\n end\n end\n return nil\n end,\n })\n end\n\n local function is_lua_callback(v)\n return type(v) == \"function\"\n end\n\n local function schedule_on_complete(onComplete, r)\n pending_async[#pending_async + 1] = { cb = onComplete, r = r }\n end\n\n local function flush_pending_async()\n for i = 1, #pending_async do\n local job = pending_async[i]\n local out = __microverse_lua_await_value(job.r)\n job.cb(out)\n end\n end\n\n local function proxy_bridge(impl)\n return setmetatable({}, {\n __index = function(_, method)\n local f = impl[method]\n if type(f) ~= \"function\" then\n return nil\n end\n return function(...)\n local n = select(\"#\", ...)\n local onComplete = nil\n local payload\n if n >= 3 and is_lua_callback(select(3, ...)) then\n onComplete = select(3, ...)\n payload = select(2, ...)\n elseif n >= 2 and is_lua_callback(select(2, ...)) then\n onComplete = select(2, ...)\n payload = select(1, ...)\n elseif n >= 2 then\n payload = select(2, ...)\n elseif n >= 1 then\n payload = select(1, ...)\n end\n local r\n if onComplete ~= nil then\n if payload ~= nil then\n r = f(impl, payload)\n else\n r = f(impl)\n end\n schedule_on_complete(onComplete, r)\n return nil\n end\n if payload ~= nil then\n r = f(impl, payload)\n elseif n == 0 then\n r = f(impl)\n else\n r = f(impl, select(1, ...))\n end\n return __microverse_lua_wrap_async_result(r)\n end\n end,\n __newindex = function(_, key)\n error(\"microverse: bridge table is read-only (\" .. tostring(key) .. \")\", 2)\n end,\n })\n end\n\n function __microverse_lua_put_bridge_from_global(slot_key, field_name, global_tmp_key)\n local e = ensure_env(slot_key)\n local v = REAL_G[global_tmp_key]\n REAL_G[global_tmp_key] = nil\n if type(v) == \"userdata\" or type(v) == \"table\" then\n v = proxy_bridge(v)\n end\n rawset(e, field_name, v)\n end\n\n function __microverse_lua_execute_in_slot(slot_key, source, instr_budget)\n instr_budget = instr_budget or DEFAULT_BUDGET\n pending_async = {}\n local env = ensure_env(slot_key)\n local f, load_err = load(source, \"@\" .. tostring(slot_key), \"t\", env)\n if not f then\n error(load_err or \"load failed\", 0)\n end\n local count = 0\n if debug_lib and debug_lib.sethook then\n debug_lib.sethook(function()\n count = count + HOOK_STEP\n if count > instr_budget then\n debug_lib.sethook()\n error(\"microverse: instruction limit exceeded\", 0)\n end\n end, \"\", HOOK_STEP)\n end\n local ok, result = pcall(f)\n if debug_lib and debug_lib.sethook then\n debug_lib.sethook()\n end\n flush_pending_async()\n if not ok then\n error(result, 0)\n end\n return result\n end\n\n function __microverse_lua_destroy_slot(slot_key)\n envs[slot_key] = nil\n end\nend\n`.trim();\n","/** Builds a Lua long literal `[=*[ ... ]=*]` so `source` can contain `]`, newlines, etc. */\nexport function toLuaLongStringLiteral(source: string): string {\n let eq = 0;\n while (true) {\n const close = `]${'='.repeat(eq)}]`;\n if (!source.includes(close)) {\n break;\n }\n eq += 1;\n }\n const open = `[${'='.repeat(eq)}[`;\n const shut = `]${'='.repeat(eq)}]`;\n return `${open}${source}${shut}`;\n}\n","import type { CancellationToken, TimeoutPolicy } from '@microverse.ts/runtime-core';\n\nexport const MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS = 512_000;\n\ntype SchedulerHost = {\n setTimeout(callback: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n};\n\ntype TimerHandle = unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- globalThis lacks SchedulerHost in lib.dom\nconst schedulerHost = (): SchedulerHost => globalThis as unknown as SchedulerHost;\n\nconst scheduleTimeout = (fn: () => void, ms: number): TimerHandle => {\n const host = schedulerHost();\n if (typeof host.setTimeout !== 'function') {\n throw new Error('microverse: setTimeout is not available in this runtime');\n }\n return host.setTimeout(fn, ms);\n};\n\nconst cancelTimeout = (handle: TimerHandle): void => {\n const host = schedulerHost();\n if (typeof host.clearTimeout === 'function') {\n host.clearTimeout(handle);\n }\n};\n\nclass MicroverseTimeoutError extends Error {\n constructor() {\n super('microverse: execution timed out');\n this.name = 'MicroverseTimeoutError';\n }\n}\n\nexport function resolveTimeoutMs(timeout: TimeoutPolicy | undefined): number | undefined {\n if (timeout === undefined || timeout.kind === 'none') {\n return undefined;\n }\n return timeout.milliseconds;\n}\n\nexport function assertScriptSize(script: string, maxChars: number): void {\n if (script.length > maxChars) {\n throw new Error(`microverse: script exceeds max size (${script.length} > ${maxChars})`);\n }\n}\n\nexport function assertNotCancelled(cancellation: CancellationToken): void {\n if (cancellation.isCancelled()) {\n throw new Error('microverse: execution cancelled');\n }\n}\n\n/**\n * Runs an async Lua invocation with optional wall-clock timeout.\n * Note: synchronous infinite Lua still blocks the thread until the instruction hook fires;\n * callers should combine with {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET} in the bootstrap.\n */\nexport async function runWithWallClockTimeout(\n run: () => Promise<void>,\n timeoutMs: number | undefined,\n): Promise<'ok' | 'timeout'> {\n if (timeoutMs === undefined) {\n await run();\n return 'ok';\n }\n // TimerHandle is intentionally opaque (`unknown`).\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- explicit optional slot\n let timer: TimerHandle | undefined;\n try {\n await Promise.race([\n run(),\n new Promise<never>((_, reject) => {\n timer = scheduleTimeout(() => reject(new MicroverseTimeoutError()), timeoutMs);\n }),\n ]);\n return 'ok';\n } catch (e) {\n if (e instanceof MicroverseTimeoutError) {\n return 'timeout';\n }\n throw e;\n } finally {\n if (timer !== undefined) {\n cancelTimeout(timer);\n }\n }\n}\n\nexport function mapExecuteError(e: unknown): { readonly _tag: 'Timeout' } | { readonly _tag: 'Cancelled' } | { readonly _tag: 'AdapterError'; readonly message: string } {\n if (e instanceof MicroverseTimeoutError) {\n return { _tag: 'Timeout' };\n }\n const message = e instanceof Error ? e.message : String(e);\n if (message.includes('execution cancelled')) {\n return { _tag: 'Cancelled' };\n }\n if (message.includes('instruction limit exceeded') || message.includes('script exceeds max size')) {\n return { _tag: 'AdapterError', message };\n }\n return { _tag: 'AdapterError', message };\n}\n","import { err, ok, type Result } from '@microverse.ts/shared';\nimport { LuaFactory } from 'wasmoon';\n\nimport type {\n ExecutionContext,\n ExecutionFailure,\n RuntimeAdapter,\n RunScriptInput,\n RunScriptResult,\n MicroverseId,\n} from '@microverse.ts/runtime-core';\n\nimport {\n MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET,\n MICROVERSE_LUA_SLOT_VM_BOOTSTRAP,\n} from './microverseLuaSlotVmBootstrap';\nimport { toLuaLongStringLiteral } from './luaLongString';\nimport {\n assertNotCancelled,\n assertScriptSize,\n MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS,\n mapExecuteError,\n resolveTimeoutMs,\n runWithWallClockTimeout,\n} from './wasmoonExecutePolicy';\n\ntype WasmoonLuaEngine = Awaited<ReturnType<LuaFactory['createEngine']>>;\n\nexport type WasmoonRuntimeAdapterOptions = {\n /** Rejects {@link RunScriptInput.script} larger than this (default {@link MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS}). */\n readonly maxScriptChars?: number | undefined;\n /** Passed to `__microverse_lua_execute_in_slot` when the third argument is omitted (default {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}). */\n readonly defaultInstructionBudget?: number | undefined;\n};\n\nexport class WasmoonRuntimeAdapter implements RuntimeAdapter {\n private readonly factory = new LuaFactory();\n\n private readonly maxScriptChars: number;\n\n private readonly defaultInstructionBudget: number;\n\n private engineInit: Promise<WasmoonLuaEngine> | undefined;\n\n constructor(private readonly options: WasmoonRuntimeAdapterOptions = {}) {\n this.maxScriptChars = options.maxScriptChars ?? MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS;\n this.defaultInstructionBudget =\n options.defaultInstructionBudget ?? MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET;\n }\n\n private getEngine = (): Promise<WasmoonLuaEngine> => {\n if (this.engineInit === undefined) {\n this.engineInit = (async () => {\n const lua = await this.factory.createEngine({ injectObjects: true });\n await lua.doString(MICROVERSE_LUA_SLOT_VM_BOOTSTRAP);\n return lua;\n })();\n }\n return this.engineInit;\n };\n\n private resetEngine = async (): Promise<void> => {\n const current = this.engineInit;\n this.engineInit = undefined;\n if (current === undefined) {\n return;\n }\n const lua = await current.catch(() => undefined);\n if (lua !== undefined) {\n try {\n await Promise.resolve(lua.global.close());\n } catch {\n // ignore\n }\n }\n };\n\n private runLua = async (lua: WasmoonLuaEngine, chunk: string): Promise<void> => {\n await lua.doString(chunk);\n };\n\n readonly execute = async (\n ctx: ExecutionContext,\n input: RunScriptInput,\n ): Promise<Result<RunScriptResult, ExecutionFailure>> => {\n try {\n assertNotCancelled(ctx.cancellation);\n assertScriptSize(String(input.script), this.maxScriptChars);\n } catch (e) {\n return err(mapExecuteError(e));\n }\n\n const timeoutMs = resolveTimeoutMs(input.timeout);\n const budget = this.defaultInstructionBudget;\n\n const runOnce = async (): Promise<Result<RunScriptResult, ExecutionFailure>> => {\n const lua = await this.getEngine();\n const slotLit = toLuaLongStringLiteral(String(ctx.microverseId));\n const merge = input.mergeEnv;\n if (merge !== undefined && Object.keys(merge).length > 0) {\n for (const name of Object.keys(merge)) {\n if (!Object.prototype.hasOwnProperty.call(merge, name)) {\n continue;\n }\n const tmp = `__microverse_lua_one_${randomMicroverseToken()}`;\n lua.global.set(tmp, merge[name]);\n const nameLit = toLuaLongStringLiteral(name);\n const tmpLit = toLuaLongStringLiteral(tmp);\n const putChunk = `__microverse_lua_put_bridge_from_global(${slotLit}, ${nameLit}, ${tmpLit})`;\n const putOutcome = await runWithWallClockTimeout(() => this.runLua(lua, putChunk), timeoutMs);\n if (putOutcome === 'timeout') {\n await this.resetEngine();\n return err({ _tag: 'Timeout' });\n }\n }\n }\n const srcLit = toLuaLongStringLiteral(String(input.script));\n const execChunk = `__microverse_lua_execute_in_slot(${slotLit}, ${srcLit}, ${budget})`;\n const execOutcome = await runWithWallClockTimeout(() => this.runLua(lua, execChunk), timeoutMs);\n if (execOutcome === 'timeout') {\n await this.resetEngine();\n return err({ _tag: 'Timeout' });\n }\n return ok({ output: 'lua_ok' });\n };\n\n try {\n return await runOnce();\n } catch (e) {\n const mapped = mapExecuteError(e);\n if (mapped._tag === 'AdapterError' && mapped.message.includes('instruction limit exceeded')) {\n await this.resetEngine();\n }\n return err(mapped);\n }\n };\n\n readonly disposeMicroverse = async (microverseId: MicroverseId): Promise<void> => {\n if (this.engineInit === undefined) {\n return;\n }\n const lua = await this.engineInit.catch(() => undefined);\n if (lua === undefined) {\n return;\n }\n const slotLit = toLuaLongStringLiteral(String(microverseId));\n try {\n await lua.doString(`__microverse_lua_destroy_slot(${slotLit})`);\n } catch {\n // ignore\n }\n };\n\n}\n\nfunction randomMicroverseToken(): string {\n const g = globalThis as typeof globalThis & { crypto?: { randomUUID?: () => string } };\n if (g.crypto?.randomUUID) {\n return g.crypto.randomUUID();\n }\n return Math.random().toString(16).slice(2);\n}\n","import {\n ConsoleLogger,\n createStubMicroverseRuntime,\n type MicroverseRuntime,\n type TimeoutPolicy,\n} from '@microverse.ts/runtime-core';\n\nimport { WasmoonRuntimeAdapter, type WasmoonRuntimeAdapterOptions } from './WasmoonRuntimeAdapter';\n\nexport type WasmMicroverseRuntimeOptions = WasmoonRuntimeAdapterOptions & {\n /** Default timeout forwarded to each {@link MicroverseSlot.run} when the call omits `timeout`. */\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n};\n\n/**\n * Wasmoon-backed {@link MicroverseRuntime} with hardened slot bootstrap (safe globals, instruction budget).\n */\nexport function createWasmMicroverseRuntime(options: WasmMicroverseRuntimeOptions = {}): MicroverseRuntime {\n const { defaultTimeout, ...adapterOptions } = options;\n return createStubMicroverseRuntime({\n adapter: new WasmoonRuntimeAdapter(adapterOptions),\n logger: new ConsoleLogger(),\n defaultTimeout,\n });\n}\n","import type {\n WorkerHostToRuntimeMessage,\n WorkerRuntimeToHostMessage,\n} from '../../domain/worker/WorkerMicroverseMessages';\n\nexport class WorkerMicroverseHost {\n private last: WorkerRuntimeToHostMessage | null = null;\n\n readonly post = (message: WorkerHostToRuntimeMessage): void => {\n void message;\n this.last = { _tag: 'ready' };\n };\n\n readonly drain = (): WorkerRuntimeToHostMessage | undefined => {\n const v = this.last;\n this.last = null;\n return v === null ? undefined : v;\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WasmoonRuntimeAdapter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/WasmoonRuntimeAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,EACb,MAAM,6BAA6B,CAAC;AAkBrC,MAAM,MAAM,4BAA4B,GAAG;IACzC,wHAAwH;IACxH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,mJAAmJ;IACnJ,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxD,CAAC;AAEF,qBAAa,qBAAsB,YAAW,cAAc;IAS9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAE5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAElD,OAAO,CAAC,UAAU,CAAwC;gBAE7B,OAAO,GAAE,4BAAiC;IAMvE,OAAO,CAAC,SAAS,CASf;IAEF,OAAO,CAAC,WAAW,CAcjB;IAEF,OAAO,CAAC,MAAM,CAEZ;IAEF,QAAQ,CAAC,OAAO,GACd,KAAK,gBAAgB,EACrB,OAAO,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAmDnD;IAEF,QAAQ,CAAC,iBAAiB,GAAU,cAAc,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CAc5E;CACH"}
1
+ {"version":3,"file":"WasmoonRuntimeAdapter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/WasmoonRuntimeAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,EACb,MAAM,6BAA6B,CAAC;AAkBrC,MAAM,MAAM,4BAA4B,GAAG;IACzC,wHAAwH;IACxH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,mJAAmJ;IACnJ,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxD,CAAC;AAEF,qBAAa,qBAAsB,YAAW,cAAc;IAS9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAE5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAElD,OAAO,CAAC,UAAU,CAAwC;gBAE7B,OAAO,GAAE,4BAAiC;IAMvE,OAAO,CAAC,SAAS,CASf;IAEF,OAAO,CAAC,WAAW,CAcjB;IAEF,OAAO,CAAC,MAAM,CAEZ;IAEF,QAAQ,CAAC,OAAO,GACd,KAAK,gBAAgB,EACrB,OAAO,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAmDnD;IAEF,QAAQ,CAAC,iBAAiB,GAAU,cAAc,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CAc5E;CAEH"}
@@ -0,0 +1,3 @@
1
+ /** @deprecated Slot prelude is {@link MICROVERSE_LUA_COMPONENT_SLOT_PRELUDE}; kept for engine bootstrap compatibility. */
2
+ export declare const MICROVERSE_LUA_COMPONENT_RUNTIME = "-- component runtime uses per-slot prelude";
3
+ //# sourceMappingURL=microverseLuaComponentRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microverseLuaComponentRuntime.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/microverseLuaComponentRuntime.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,eAAO,MAAM,gCAAgC,+CAA+C,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@microverse.ts/runtime-wasm",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
7
+ "description": "Wasmoon Wasm Lua VM for Microverse: shared VM, per-slot sandboxes, execution limits, and optional Web Worker host.",
7
8
  "repository": {
8
9
  "type": "git",
9
10
  "url": "git+https://github.com/QADRAX/Microverse.ts.git",
@@ -26,9 +27,9 @@
26
27
  ],
27
28
  "dependencies": {
28
29
  "wasmoon": "^1.15.0",
29
- "@microverse.ts/runtime-core": "0.1.0",
30
- "@microverse.ts/runtime-lua": "0.1.0",
31
- "@microverse.ts/shared": "0.1.0"
30
+ "@microverse.ts/runtime-core": "0.2.0",
31
+ "@microverse.ts/runtime-lua": "0.2.0",
32
+ "@microverse.ts/shared": "0.2.0"
32
33
  },
33
34
  "devDependencies": {
34
35
  "typescript": "^5.8.3",