@microverse.ts/runtime-wasm 0.1.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/LICENSE +21 -0
- package/dist/application/bootstrap/WasmBootstrapOrder.d.ts +2 -0
- package/dist/application/bootstrap/WasmBootstrapOrder.d.ts.map +1 -0
- package/dist/domain/worker/WorkerMicroverseMessages.d.ts +20 -0
- package/dist/domain/worker/WorkerMicroverseMessages.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +420 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/runtime/WasmoonRuntimeAdapter.d.ts +22 -0
- package/dist/infrastructure/runtime/WasmoonRuntimeAdapter.d.ts.map +1 -0
- package/dist/infrastructure/runtime/createWasmMicroverseRuntime.d.ts +11 -0
- package/dist/infrastructure/runtime/createWasmMicroverseRuntime.d.ts.map +1 -0
- package/dist/infrastructure/runtime/luaLongString.d.ts +3 -0
- package/dist/infrastructure/runtime/luaLongString.d.ts.map +1 -0
- package/dist/infrastructure/runtime/microverseLuaSlotVmBootstrap.d.ts +11 -0
- package/dist/infrastructure/runtime/microverseLuaSlotVmBootstrap.d.ts.map +1 -0
- package/dist/infrastructure/runtime/wasmoonExecutePolicy.d.ts +20 -0
- package/dist/infrastructure/runtime/wasmoonExecutePolicy.d.ts.map +1 -0
- package/dist/infrastructure/worker/WorkerMicroverseHost.d.ts +7 -0
- package/dist/infrastructure/worker/WorkerMicroverseHost.d.ts.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 QADRAX
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WasmBootstrapOrder.d.ts","sourceRoot":"","sources":["../../../src/application/bootstrap/WasmBootstrapOrder.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,8BAA+B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type WorkerHostToRuntimeMessage = {
|
|
2
|
+
readonly _tag: 'init';
|
|
3
|
+
readonly wasmEntrypoint: string;
|
|
4
|
+
} | {
|
|
5
|
+
readonly _tag: 'execute';
|
|
6
|
+
readonly requestId: string;
|
|
7
|
+
readonly script: string;
|
|
8
|
+
};
|
|
9
|
+
export type WorkerRuntimeToHostMessage = {
|
|
10
|
+
readonly _tag: 'ready';
|
|
11
|
+
} | {
|
|
12
|
+
readonly _tag: 'result';
|
|
13
|
+
readonly requestId: string;
|
|
14
|
+
readonly output: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly _tag: 'error';
|
|
17
|
+
readonly requestId: string;
|
|
18
|
+
readonly message: string;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=WorkerMicroverseMessages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerMicroverseMessages.d.ts","sourceRoot":"","sources":["../../../src/domain/worker/WorkerMicroverseMessages.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { WorkerHostToRuntimeMessage, WorkerRuntimeToHostMessage, } from './domain/worker/WorkerMicroverseMessages';
|
|
2
|
+
export { createWasmMicroverseRuntime, type WasmMicroverseRuntimeOptions, } from './infrastructure/runtime/createWasmMicroverseRuntime';
|
|
3
|
+
export { MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET, MICROVERSE_LUA_SLOT_VM_BOOTSTRAP, } from './infrastructure/runtime/microverseLuaSlotVmBootstrap';
|
|
4
|
+
export { MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS } from './infrastructure/runtime/wasmoonExecutePolicy';
|
|
5
|
+
export { WasmoonRuntimeAdapter, type WasmoonRuntimeAdapterOptions } from './infrastructure/runtime/WasmoonRuntimeAdapter';
|
|
6
|
+
export { WorkerMicroverseHost } from './infrastructure/worker/WorkerMicroverseHost';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,GAClC,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EACL,yCAAyC,EACzC,gCAAgC,GACjC,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAC;AACxG,OAAO,EAAE,qBAAqB,EAAE,KAAK,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AAC1H,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { ConsoleLogger, createStubMicroverseRuntime } from "@microverse.ts/runtime-core";
|
|
2
|
+
import { err, ok } from "@microverse.ts/shared";
|
|
3
|
+
import { LuaFactory } from "wasmoon";
|
|
4
|
+
//#region src/infrastructure/runtime/microverseLuaSlotVmBootstrap.ts
|
|
5
|
+
/**
|
|
6
|
+
* Lua 5.4 bootstrap for **one Wasmoon VM, many slots**:
|
|
7
|
+
* - Slot `_ENV` uses a **safe global** table (no `debug`, `load`, `io`, `os`, …).
|
|
8
|
+
* - Slot registry and internals are **closure-local** (not on `_G`).
|
|
9
|
+
* - Bridge tables are **read-only** from Lua (`__newindex`); host re-injects via `mergeEnv` each run.
|
|
10
|
+
* - **No auto-await**: async bridges return a handle with `:await()`; optional 2nd-arg callback runs after the current chunk step.
|
|
11
|
+
* - Optional **instruction budget** per chunk via `debug.sethook` when available.
|
|
12
|
+
*/
|
|
13
|
+
var MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET = 5e6;
|
|
14
|
+
var MICROVERSE_LUA_SLOT_VM_BOOTSTRAP = `
|
|
15
|
+
do
|
|
16
|
+
local REAL_G = _G
|
|
17
|
+
local envs = {}
|
|
18
|
+
local pending_async = {}
|
|
19
|
+
|
|
20
|
+
local function copy_functions(lib)
|
|
21
|
+
if type(lib) ~= "table" then return nil end
|
|
22
|
+
local out = {}
|
|
23
|
+
for k, v in pairs(lib) do
|
|
24
|
+
if type(v) == "function" then
|
|
25
|
+
out[k] = v
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
return out
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
local function copy_math()
|
|
32
|
+
local src = REAL_G.math
|
|
33
|
+
if type(src) ~= "table" then return {} end
|
|
34
|
+
local blocked = { random = true, randomseed = true }
|
|
35
|
+
local out = {}
|
|
36
|
+
for k, v in pairs(src) do
|
|
37
|
+
if type(v) == "function" and not blocked[k] then
|
|
38
|
+
out[k] = v
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
return out
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
local SAFE_G = {
|
|
45
|
+
assert = assert,
|
|
46
|
+
error = error,
|
|
47
|
+
getmetatable = getmetatable,
|
|
48
|
+
ipairs = ipairs,
|
|
49
|
+
next = next,
|
|
50
|
+
pairs = pairs,
|
|
51
|
+
pcall = pcall,
|
|
52
|
+
rawequal = rawequal,
|
|
53
|
+
rawget = rawget,
|
|
54
|
+
rawlen = rawlen,
|
|
55
|
+
rawset = rawset,
|
|
56
|
+
select = select,
|
|
57
|
+
setmetatable = setmetatable,
|
|
58
|
+
tonumber = tonumber,
|
|
59
|
+
tostring = tostring,
|
|
60
|
+
type = type,
|
|
61
|
+
xpcall = xpcall,
|
|
62
|
+
table = copy_functions(REAL_G.table),
|
|
63
|
+
string = copy_functions(REAL_G.string),
|
|
64
|
+
math = copy_math(),
|
|
65
|
+
_VERSION = REAL_G._VERSION,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
local ENV_MT = { __index = SAFE_G }
|
|
69
|
+
|
|
70
|
+
local function ensure_env(slot_key)
|
|
71
|
+
local e = envs[slot_key]
|
|
72
|
+
if not e then
|
|
73
|
+
e = {}
|
|
74
|
+
setmetatable(e, ENV_MT)
|
|
75
|
+
envs[slot_key] = e
|
|
76
|
+
end
|
|
77
|
+
return e
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
local debug_lib = REAL_G.debug
|
|
81
|
+
local DEFAULT_BUDGET = ${MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}
|
|
82
|
+
local HOOK_STEP = 10000
|
|
83
|
+
|
|
84
|
+
local function is_awaitable(r)
|
|
85
|
+
if type(r) == "userdata" or type(r) == "table" then
|
|
86
|
+
return type(r.await) == "function"
|
|
87
|
+
end
|
|
88
|
+
return false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
function __microverse_lua_await_value(r)
|
|
92
|
+
if not is_awaitable(r) then
|
|
93
|
+
return r
|
|
94
|
+
end
|
|
95
|
+
local ok, out = pcall(function()
|
|
96
|
+
return r:await()
|
|
97
|
+
end)
|
|
98
|
+
if not ok then
|
|
99
|
+
error(out, 0)
|
|
100
|
+
end
|
|
101
|
+
return out
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
function __microverse_lua_wrap_async_result(r)
|
|
105
|
+
if not is_awaitable(r) then
|
|
106
|
+
return r
|
|
107
|
+
end
|
|
108
|
+
return setmetatable({}, {
|
|
109
|
+
__index = function(_, key)
|
|
110
|
+
if key == "await" then
|
|
111
|
+
return function()
|
|
112
|
+
return __microverse_lua_await_value(r)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
return nil
|
|
116
|
+
end,
|
|
117
|
+
})
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
local function is_lua_callback(v)
|
|
121
|
+
return type(v) == "function"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
local function schedule_on_complete(onComplete, r)
|
|
125
|
+
pending_async[#pending_async + 1] = { cb = onComplete, r = r }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
local function flush_pending_async()
|
|
129
|
+
for i = 1, #pending_async do
|
|
130
|
+
local job = pending_async[i]
|
|
131
|
+
local out = __microverse_lua_await_value(job.r)
|
|
132
|
+
job.cb(out)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
local function proxy_bridge(impl)
|
|
137
|
+
return setmetatable({}, {
|
|
138
|
+
__index = function(_, method)
|
|
139
|
+
local f = impl[method]
|
|
140
|
+
if type(f) ~= "function" then
|
|
141
|
+
return nil
|
|
142
|
+
end
|
|
143
|
+
return function(...)
|
|
144
|
+
local n = select("#", ...)
|
|
145
|
+
local onComplete = nil
|
|
146
|
+
local payload
|
|
147
|
+
if n >= 3 and is_lua_callback(select(3, ...)) then
|
|
148
|
+
onComplete = select(3, ...)
|
|
149
|
+
payload = select(2, ...)
|
|
150
|
+
elseif n >= 2 and is_lua_callback(select(2, ...)) then
|
|
151
|
+
onComplete = select(2, ...)
|
|
152
|
+
payload = select(1, ...)
|
|
153
|
+
elseif n >= 2 then
|
|
154
|
+
payload = select(2, ...)
|
|
155
|
+
elseif n >= 1 then
|
|
156
|
+
payload = select(1, ...)
|
|
157
|
+
end
|
|
158
|
+
local r
|
|
159
|
+
if onComplete ~= nil then
|
|
160
|
+
if payload ~= nil then
|
|
161
|
+
r = f(impl, payload)
|
|
162
|
+
else
|
|
163
|
+
r = f(impl)
|
|
164
|
+
end
|
|
165
|
+
schedule_on_complete(onComplete, r)
|
|
166
|
+
return nil
|
|
167
|
+
end
|
|
168
|
+
if payload ~= nil then
|
|
169
|
+
r = f(impl, payload)
|
|
170
|
+
elseif n == 0 then
|
|
171
|
+
r = f(impl)
|
|
172
|
+
else
|
|
173
|
+
r = f(impl, select(1, ...))
|
|
174
|
+
end
|
|
175
|
+
return __microverse_lua_wrap_async_result(r)
|
|
176
|
+
end
|
|
177
|
+
end,
|
|
178
|
+
__newindex = function(_, key)
|
|
179
|
+
error("microverse: bridge table is read-only (" .. tostring(key) .. ")", 2)
|
|
180
|
+
end,
|
|
181
|
+
})
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
function __microverse_lua_put_bridge_from_global(slot_key, field_name, global_tmp_key)
|
|
185
|
+
local e = ensure_env(slot_key)
|
|
186
|
+
local v = REAL_G[global_tmp_key]
|
|
187
|
+
REAL_G[global_tmp_key] = nil
|
|
188
|
+
if type(v) == "userdata" or type(v) == "table" then
|
|
189
|
+
v = proxy_bridge(v)
|
|
190
|
+
end
|
|
191
|
+
rawset(e, field_name, v)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
function __microverse_lua_execute_in_slot(slot_key, source, instr_budget)
|
|
195
|
+
instr_budget = instr_budget or DEFAULT_BUDGET
|
|
196
|
+
pending_async = {}
|
|
197
|
+
local env = ensure_env(slot_key)
|
|
198
|
+
local f, load_err = load(source, "@" .. tostring(slot_key), "t", env)
|
|
199
|
+
if not f then
|
|
200
|
+
error(load_err or "load failed", 0)
|
|
201
|
+
end
|
|
202
|
+
local count = 0
|
|
203
|
+
if debug_lib and debug_lib.sethook then
|
|
204
|
+
debug_lib.sethook(function()
|
|
205
|
+
count = count + HOOK_STEP
|
|
206
|
+
if count > instr_budget then
|
|
207
|
+
debug_lib.sethook()
|
|
208
|
+
error("microverse: instruction limit exceeded", 0)
|
|
209
|
+
end
|
|
210
|
+
end, "", HOOK_STEP)
|
|
211
|
+
end
|
|
212
|
+
local ok, result = pcall(f)
|
|
213
|
+
if debug_lib and debug_lib.sethook then
|
|
214
|
+
debug_lib.sethook()
|
|
215
|
+
end
|
|
216
|
+
flush_pending_async()
|
|
217
|
+
if not ok then
|
|
218
|
+
error(result, 0)
|
|
219
|
+
end
|
|
220
|
+
return result
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
function __microverse_lua_destroy_slot(slot_key)
|
|
224
|
+
envs[slot_key] = nil
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
`.trim();
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/infrastructure/runtime/luaLongString.ts
|
|
230
|
+
/** Builds a Lua long literal `[=*[ ... ]=*]` so `source` can contain `]`, newlines, etc. */
|
|
231
|
+
function toLuaLongStringLiteral(source) {
|
|
232
|
+
let eq = 0;
|
|
233
|
+
while (true) {
|
|
234
|
+
const close = `]${"=".repeat(eq)}]`;
|
|
235
|
+
if (!source.includes(close)) break;
|
|
236
|
+
eq += 1;
|
|
237
|
+
}
|
|
238
|
+
return `${`[${"=".repeat(eq)}[`}${source}${`]${"=".repeat(eq)}]`}`;
|
|
239
|
+
}
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/infrastructure/runtime/wasmoonExecutePolicy.ts
|
|
242
|
+
var MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS = 512e3;
|
|
243
|
+
var schedulerHost = () => globalThis;
|
|
244
|
+
var scheduleTimeout = (fn, ms) => {
|
|
245
|
+
const host = schedulerHost();
|
|
246
|
+
if (typeof host.setTimeout !== "function") throw new Error("microverse: setTimeout is not available in this runtime");
|
|
247
|
+
return host.setTimeout(fn, ms);
|
|
248
|
+
};
|
|
249
|
+
var cancelTimeout = (handle) => {
|
|
250
|
+
const host = schedulerHost();
|
|
251
|
+
if (typeof host.clearTimeout === "function") host.clearTimeout(handle);
|
|
252
|
+
};
|
|
253
|
+
var MicroverseTimeoutError = class extends Error {
|
|
254
|
+
constructor() {
|
|
255
|
+
super("microverse: execution timed out");
|
|
256
|
+
this.name = "MicroverseTimeoutError";
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
function resolveTimeoutMs(timeout) {
|
|
260
|
+
if (timeout === void 0 || timeout.kind === "none") return;
|
|
261
|
+
return timeout.milliseconds;
|
|
262
|
+
}
|
|
263
|
+
function assertScriptSize(script, maxChars) {
|
|
264
|
+
if (script.length > maxChars) throw new Error(`microverse: script exceeds max size (${script.length} > ${maxChars})`);
|
|
265
|
+
}
|
|
266
|
+
function assertNotCancelled(cancellation) {
|
|
267
|
+
if (cancellation.isCancelled()) throw new Error("microverse: execution cancelled");
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Runs an async Lua invocation with optional wall-clock timeout.
|
|
271
|
+
* Note: synchronous infinite Lua still blocks the thread until the instruction hook fires;
|
|
272
|
+
* callers should combine with {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET} in the bootstrap.
|
|
273
|
+
*/
|
|
274
|
+
async function runWithWallClockTimeout(run, timeoutMs) {
|
|
275
|
+
if (timeoutMs === void 0) {
|
|
276
|
+
await run();
|
|
277
|
+
return "ok";
|
|
278
|
+
}
|
|
279
|
+
let timer;
|
|
280
|
+
try {
|
|
281
|
+
await Promise.race([run(), new Promise((_, reject) => {
|
|
282
|
+
timer = scheduleTimeout(() => reject(new MicroverseTimeoutError()), timeoutMs);
|
|
283
|
+
})]);
|
|
284
|
+
return "ok";
|
|
285
|
+
} catch (e) {
|
|
286
|
+
if (e instanceof MicroverseTimeoutError) return "timeout";
|
|
287
|
+
throw e;
|
|
288
|
+
} finally {
|
|
289
|
+
if (timer !== void 0) cancelTimeout(timer);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function mapExecuteError(e) {
|
|
293
|
+
if (e instanceof MicroverseTimeoutError) return { _tag: "Timeout" };
|
|
294
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
295
|
+
if (message.includes("execution cancelled")) return { _tag: "Cancelled" };
|
|
296
|
+
if (message.includes("instruction limit exceeded") || message.includes("script exceeds max size")) return {
|
|
297
|
+
_tag: "AdapterError",
|
|
298
|
+
message
|
|
299
|
+
};
|
|
300
|
+
return {
|
|
301
|
+
_tag: "AdapterError",
|
|
302
|
+
message
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
//#endregion
|
|
306
|
+
//#region src/infrastructure/runtime/WasmoonRuntimeAdapter.ts
|
|
307
|
+
var WasmoonRuntimeAdapter = class {
|
|
308
|
+
options;
|
|
309
|
+
factory = new LuaFactory();
|
|
310
|
+
maxScriptChars;
|
|
311
|
+
defaultInstructionBudget;
|
|
312
|
+
engineInit;
|
|
313
|
+
constructor(options = {}) {
|
|
314
|
+
this.options = options;
|
|
315
|
+
this.maxScriptChars = options.maxScriptChars ?? 512e3;
|
|
316
|
+
this.defaultInstructionBudget = options.defaultInstructionBudget ?? 5e6;
|
|
317
|
+
}
|
|
318
|
+
getEngine = () => {
|
|
319
|
+
if (this.engineInit === void 0) this.engineInit = (async () => {
|
|
320
|
+
const lua = await this.factory.createEngine({ injectObjects: true });
|
|
321
|
+
await lua.doString(MICROVERSE_LUA_SLOT_VM_BOOTSTRAP);
|
|
322
|
+
return lua;
|
|
323
|
+
})();
|
|
324
|
+
return this.engineInit;
|
|
325
|
+
};
|
|
326
|
+
resetEngine = async () => {
|
|
327
|
+
const current = this.engineInit;
|
|
328
|
+
this.engineInit = void 0;
|
|
329
|
+
if (current === void 0) return;
|
|
330
|
+
const lua = await current.catch(() => void 0);
|
|
331
|
+
if (lua !== void 0) try {
|
|
332
|
+
await Promise.resolve(lua.global.close());
|
|
333
|
+
} catch {}
|
|
334
|
+
};
|
|
335
|
+
runLua = async (lua, chunk) => {
|
|
336
|
+
await lua.doString(chunk);
|
|
337
|
+
};
|
|
338
|
+
execute = async (ctx, input) => {
|
|
339
|
+
try {
|
|
340
|
+
assertNotCancelled(ctx.cancellation);
|
|
341
|
+
assertScriptSize(String(input.script), this.maxScriptChars);
|
|
342
|
+
} catch (e) {
|
|
343
|
+
return err(mapExecuteError(e));
|
|
344
|
+
}
|
|
345
|
+
const timeoutMs = resolveTimeoutMs(input.timeout);
|
|
346
|
+
const budget = this.defaultInstructionBudget;
|
|
347
|
+
const runOnce = async () => {
|
|
348
|
+
const lua = await this.getEngine();
|
|
349
|
+
const slotLit = toLuaLongStringLiteral(String(ctx.microverseId));
|
|
350
|
+
const merge = input.mergeEnv;
|
|
351
|
+
if (merge !== void 0 && Object.keys(merge).length > 0) for (const name of Object.keys(merge)) {
|
|
352
|
+
if (!Object.prototype.hasOwnProperty.call(merge, name)) continue;
|
|
353
|
+
const tmp = `__microverse_lua_one_${randomMicroverseToken()}`;
|
|
354
|
+
lua.global.set(tmp, merge[name]);
|
|
355
|
+
const putChunk = `__microverse_lua_put_bridge_from_global(${slotLit}, ${toLuaLongStringLiteral(name)}, ${toLuaLongStringLiteral(tmp)})`;
|
|
356
|
+
if (await runWithWallClockTimeout(() => this.runLua(lua, putChunk), timeoutMs) === "timeout") {
|
|
357
|
+
await this.resetEngine();
|
|
358
|
+
return err({ _tag: "Timeout" });
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const execChunk = `__microverse_lua_execute_in_slot(${slotLit}, ${toLuaLongStringLiteral(String(input.script))}, ${budget})`;
|
|
362
|
+
if (await runWithWallClockTimeout(() => this.runLua(lua, execChunk), timeoutMs) === "timeout") {
|
|
363
|
+
await this.resetEngine();
|
|
364
|
+
return err({ _tag: "Timeout" });
|
|
365
|
+
}
|
|
366
|
+
return ok({ output: "lua_ok" });
|
|
367
|
+
};
|
|
368
|
+
try {
|
|
369
|
+
return await runOnce();
|
|
370
|
+
} catch (e) {
|
|
371
|
+
const mapped = mapExecuteError(e);
|
|
372
|
+
if (mapped._tag === "AdapterError" && mapped.message.includes("instruction limit exceeded")) await this.resetEngine();
|
|
373
|
+
return err(mapped);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
disposeMicroverse = async (microverseId) => {
|
|
377
|
+
if (this.engineInit === void 0) return;
|
|
378
|
+
const lua = await this.engineInit.catch(() => void 0);
|
|
379
|
+
if (lua === void 0) return;
|
|
380
|
+
const slotLit = toLuaLongStringLiteral(String(microverseId));
|
|
381
|
+
try {
|
|
382
|
+
await lua.doString(`__microverse_lua_destroy_slot(${slotLit})`);
|
|
383
|
+
} catch {}
|
|
384
|
+
};
|
|
385
|
+
};
|
|
386
|
+
function randomMicroverseToken() {
|
|
387
|
+
const g = globalThis;
|
|
388
|
+
if (g.crypto?.randomUUID) return g.crypto.randomUUID();
|
|
389
|
+
return Math.random().toString(16).slice(2);
|
|
390
|
+
}
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/infrastructure/runtime/createWasmMicroverseRuntime.ts
|
|
393
|
+
/**
|
|
394
|
+
* Wasmoon-backed {@link MicroverseRuntime} with hardened slot bootstrap (safe globals, instruction budget).
|
|
395
|
+
*/
|
|
396
|
+
function createWasmMicroverseRuntime(options = {}) {
|
|
397
|
+
const { defaultTimeout, ...adapterOptions } = options;
|
|
398
|
+
return createStubMicroverseRuntime({
|
|
399
|
+
adapter: new WasmoonRuntimeAdapter(adapterOptions),
|
|
400
|
+
logger: new ConsoleLogger(),
|
|
401
|
+
defaultTimeout
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/infrastructure/worker/WorkerMicroverseHost.ts
|
|
406
|
+
var WorkerMicroverseHost = class {
|
|
407
|
+
last = null;
|
|
408
|
+
post = (message) => {
|
|
409
|
+
this.last = { _tag: "ready" };
|
|
410
|
+
};
|
|
411
|
+
drain = () => {
|
|
412
|
+
const v = this.last;
|
|
413
|
+
this.last = null;
|
|
414
|
+
return v === null ? void 0 : v;
|
|
415
|
+
};
|
|
416
|
+
};
|
|
417
|
+
//#endregion
|
|
418
|
+
export { MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET, MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS, MICROVERSE_LUA_SLOT_VM_BOOTSTRAP, WasmoonRuntimeAdapter, WorkerMicroverseHost, createWasmMicroverseRuntime };
|
|
419
|
+
|
|
420
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Result } from '@microverse.ts/shared';
|
|
2
|
+
import { ExecutionContext, ExecutionFailure, RuntimeAdapter, RunScriptInput, RunScriptResult, MicroverseId } from '@microverse.ts/runtime-core';
|
|
3
|
+
export type WasmoonRuntimeAdapterOptions = {
|
|
4
|
+
/** Rejects {@link RunScriptInput.script} larger than this (default {@link MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS}). */
|
|
5
|
+
readonly maxScriptChars?: number | undefined;
|
|
6
|
+
/** Passed to `__microverse_lua_execute_in_slot` when the third argument is omitted (default {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET}). */
|
|
7
|
+
readonly defaultInstructionBudget?: number | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare class WasmoonRuntimeAdapter implements RuntimeAdapter {
|
|
10
|
+
private readonly options;
|
|
11
|
+
private readonly factory;
|
|
12
|
+
private readonly maxScriptChars;
|
|
13
|
+
private readonly defaultInstructionBudget;
|
|
14
|
+
private engineInit;
|
|
15
|
+
constructor(options?: WasmoonRuntimeAdapterOptions);
|
|
16
|
+
private getEngine;
|
|
17
|
+
private resetEngine;
|
|
18
|
+
private runLua;
|
|
19
|
+
readonly execute: (ctx: ExecutionContext, input: RunScriptInput) => Promise<Result<RunScriptResult, ExecutionFailure>>;
|
|
20
|
+
readonly disposeMicroverse: (microverseId: MicroverseId) => Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=WasmoonRuntimeAdapter.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MicroverseRuntime, TimeoutPolicy } from '@microverse.ts/runtime-core';
|
|
2
|
+
import { WasmoonRuntimeAdapterOptions } from './WasmoonRuntimeAdapter';
|
|
3
|
+
export type WasmMicroverseRuntimeOptions = WasmoonRuntimeAdapterOptions & {
|
|
4
|
+
/** Default timeout forwarded to each {@link MicroverseSlot.run} when the call omits `timeout`. */
|
|
5
|
+
readonly defaultTimeout?: TimeoutPolicy | undefined;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Wasmoon-backed {@link MicroverseRuntime} with hardened slot bootstrap (safe globals, instruction budget).
|
|
9
|
+
*/
|
|
10
|
+
export declare function createWasmMicroverseRuntime(options?: WasmMicroverseRuntimeOptions): MicroverseRuntime;
|
|
11
|
+
//# sourceMappingURL=createWasmMicroverseRuntime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createWasmMicroverseRuntime.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/createWasmMicroverseRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAyB,KAAK,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAEnG,MAAM,MAAM,4BAA4B,GAAG,4BAA4B,GAAG;IACxE,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,4BAAiC,GAAG,iBAAiB,CAOzG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"luaLongString.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/luaLongString.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAY7D"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua 5.4 bootstrap for **one Wasmoon VM, many slots**:
|
|
3
|
+
* - Slot `_ENV` uses a **safe global** table (no `debug`, `load`, `io`, `os`, …).
|
|
4
|
+
* - Slot registry and internals are **closure-local** (not on `_G`).
|
|
5
|
+
* - Bridge tables are **read-only** from Lua (`__newindex`); host re-injects via `mergeEnv` each run.
|
|
6
|
+
* - **No auto-await**: async bridges return a handle with `:await()`; optional 2nd-arg callback runs after the current chunk step.
|
|
7
|
+
* - Optional **instruction budget** per chunk via `debug.sethook` when available.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET = 5000000;
|
|
10
|
+
export declare const MICROVERSE_LUA_SLOT_VM_BOOTSTRAP: string;
|
|
11
|
+
//# sourceMappingURL=microverseLuaSlotVmBootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microverseLuaSlotVmBootstrap.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/microverseLuaSlotVmBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,yCAAyC,UAAY,CAAC;AAEnE,eAAO,MAAM,gCAAgC,QAqNrC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CancellationToken, TimeoutPolicy } from '@microverse.ts/runtime-core';
|
|
2
|
+
export declare const MICROVERSE_LUA_DEFAULT_MAX_SCRIPT_CHARS = 512000;
|
|
3
|
+
export declare function resolveTimeoutMs(timeout: TimeoutPolicy | undefined): number | undefined;
|
|
4
|
+
export declare function assertScriptSize(script: string, maxChars: number): void;
|
|
5
|
+
export declare function assertNotCancelled(cancellation: CancellationToken): void;
|
|
6
|
+
/**
|
|
7
|
+
* Runs an async Lua invocation with optional wall-clock timeout.
|
|
8
|
+
* Note: synchronous infinite Lua still blocks the thread until the instruction hook fires;
|
|
9
|
+
* callers should combine with {@link MICROVERSE_LUA_DEFAULT_INSTRUCTION_BUDGET} in the bootstrap.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runWithWallClockTimeout(run: () => Promise<void>, timeoutMs: number | undefined): Promise<'ok' | 'timeout'>;
|
|
12
|
+
export declare function mapExecuteError(e: unknown): {
|
|
13
|
+
readonly _tag: 'Timeout';
|
|
14
|
+
} | {
|
|
15
|
+
readonly _tag: 'Cancelled';
|
|
16
|
+
} | {
|
|
17
|
+
readonly _tag: 'AdapterError';
|
|
18
|
+
readonly message: string;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=wasmoonExecutePolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmoonExecutePolicy.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/runtime/wasmoonExecutePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEpF,eAAO,MAAM,uCAAuC,SAAU,CAAC;AAkC/D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKvF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIvE;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAIxE;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACxB,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CA0B3B;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAYvK"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WorkerHostToRuntimeMessage, WorkerRuntimeToHostMessage } from '../../domain/worker/WorkerMicroverseMessages';
|
|
2
|
+
export declare class WorkerMicroverseHost {
|
|
3
|
+
private last;
|
|
4
|
+
readonly post: (message: WorkerHostToRuntimeMessage) => void;
|
|
5
|
+
readonly drain: () => WorkerRuntimeToHostMessage | undefined;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=WorkerMicroverseHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerMicroverseHost.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/worker/WorkerMicroverseHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,8CAA8C,CAAC;AAEtD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAA2C;IAEvD,QAAQ,CAAC,IAAI,GAAI,SAAS,0BAA0B,KAAG,IAAI,CAGzD;IAEF,QAAQ,CAAC,KAAK,QAAO,0BAA0B,GAAG,SAAS,CAIzD;CACH"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@microverse.ts/runtime-wasm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/QADRAX/Microverse.ts.git",
|
|
10
|
+
"directory": "packages/runtime-wasm"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/QADRAX/Microverse.ts/issues",
|
|
13
|
+
"homepage": "https://github.com/QADRAX/Microverse.ts/tree/main/packages/runtime-wasm",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"provenance": true
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"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"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.8.3",
|
|
35
|
+
"vite": "^8.0.0",
|
|
36
|
+
"vite-plugin-dts": "^4.5.4",
|
|
37
|
+
"vitest": "^3.1.4"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "vite build",
|
|
41
|
+
"lint": "eslint .",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
44
|
+
}
|
|
45
|
+
}
|