@microverse.ts/microverse-lua 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  **Lua microverse** facade for TypeScript applications: `MicroverseLua.create`, Wasm VM, script slots, and the fluent host surface builder.
4
4
 
5
- Monorepo overview: [root README](../../README.md).
5
+ Monorepo overview (protocol vision): [root README](../../README.md).
6
6
 
7
7
  ## What is a Lua microverse?
8
8
 
9
9
  One logical scripting universe in your process:
10
10
 
11
11
  - **One** Wasm-backed Lua VM (Wasmoon), shared for efficiency.
12
- - **Many** isolated **environment slots** — one per registered script.
13
- - **One** host **surface** (declarative bridges + optional workflow hooks).
12
+ - **Many** isolated **environment slots** — one per mounted script instance.
13
+ - **One** host **surface** (declarative bridges + optional component hooks).
14
14
  - **One** host **object** (your TypeScript services).
15
- - **Per-script capability allowlists** at registration.
15
+ - **Typed component profiles** bridges on `self.bridges` are narrowed by `YourType:extend()` in each script.
16
16
 
17
17
  ```
18
18
  ┌─────────────────────────────────────────────────────────────┐
@@ -21,10 +21,10 @@ One logical scripting universe in your process:
21
21
  │ │ Shared Wasm Lua VM │ │
22
22
  │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
23
23
  │ │ │ slot: a │ │ slot: b │ │ slot: c │ │ │
24
- │ │ │ caps: […] │ │ caps: […] │ │ caps: […] │ │ │
24
+ │ │ │ OrderEcho │ │ AuditOnly │ │ Promotions │ │ │
25
25
  │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
26
26
  │ └───────────────────────────────────────────────────────┘ │
27
- │ ▲ bridges from host surface + host services
27
+ │ ▲ self.bridges after Type:extend() (per profile)
28
28
  └─────────────────────────────────────────────────────────────┘
29
29
  ```
30
30
 
@@ -36,7 +36,69 @@ pnpm add @microverse.ts/microverse-lua
36
36
 
37
37
  Workspace: `"@microverse.ts/microverse-lua": "workspace:*"`.
38
38
 
39
- ## Quick start
39
+ ## Concepts
40
+
41
+ | Term | Meaning |
42
+ |------|---------|
43
+ | **Microverse** | One shared Wasm Lua VM + catalog of script definitions + N mounted instances ([`LuaMicroverse`](src/infrastructure/facade/luaMicroverse.ts)). |
44
+ | **Host** | Your typed services object passed to `MicroverseLua.create({ host })`. Handlers on the surface receive it; Lua never sees the raw host table. |
45
+ | **Surface** | Result of `defineHostSurfaceFor<THost>().componentType(…).bridge(…).method(…).componentHooks(…).build()` — component types, bridges, capability ids, and a manifest for `.d.lua`. |
46
+ | **Component type** | Declared profile: props/state Zod schemas, capability set, hook subset. Lua fixes the type with `OrderEcho:extend()` → `OrderEchoComponent`. |
47
+ | **Bridge** | A named group of host methods exposed in Lua as `self.bridges.<name>:<method>(payload)` when the active type’s capabilities include that method. **Not** a global in the script slot. |
48
+ | **Capability** | A `domain:action` string on each bridge method (`requires`) and on each `.componentType(…)` profile. Runtime includes only matching bridges on `self.bridges`. |
49
+ | **Script definition** | Catalog entry: `scriptId`, Lua source, optional `injectLuaChunks`, optional `profileId`, optional props schema / defaults. |
50
+ | **Script instance** | A mounted slot: `instanceId`, `scriptId`, props, and the component table from `YourType:extend()` in the script chunk. |
51
+ | **Component** | Lua table from `YourType:extend()` with typed `properties`, `state`, narrowed `bridges`, lifecycle (`init`, `onDestroy`, `onPropsChanged`), and domain `on*` hooks. |
52
+
53
+ ## Engine lifecycle
54
+
55
+ When you mount an instance, the runtime runs this pipeline (see [`mountScriptInstance`](src/infrastructure/facade/luaMicroverse.ts)):
56
+
57
+ ```mermaid
58
+ sequenceDiagram
59
+ participant App
60
+ participant MV as LuaMicroverse
61
+ participant Session as HostScriptSession
62
+ participant VM as Wasm Lua
63
+
64
+ App->>MV: registerScriptDefinition
65
+ App->>MV: mountScriptInstance
66
+ MV->>Session: openSession
67
+ Session->>VM: run shared + inject prelude chunks
68
+ Session->>VM: run main chunk (Type:extend())
69
+ Session->>VM: setProps
70
+ Session->>VM: invoke init
71
+ App->>MV: emitToAllInstances
72
+ MV->>Session: invoke on* hooks
73
+ App->>MV: unmountScriptInstance
74
+ MV->>Session: onDestroy + dispose
75
+ ```
76
+
77
+ 1. **`registerScriptDefinition`** — Add source to the catalog (does not allocate a slot).
78
+ 2. **`mountScriptInstance`** — Open a slot, run preludes + main chunk, merge props, call `init`.
79
+ 3. **`emitToAllInstances`** — Broadcast a component hook (`OrderPlaced`, …) to every mounted instance.
80
+ 4. **`unmountScriptInstance`** — Call `onDestroy`, tear down the slot.
81
+ 5. **`dispose`** — Unmount all instances.
82
+
83
+ ## API
84
+
85
+ | Export / method | Purpose |
86
+ |-----------------|--------|
87
+ | `MicroverseLua.create` | Create a Lua microverse (Wasm VM included). |
88
+ | `registerScriptDefinition` | Catalog entry (source, optional preludes, props schema). |
89
+ | `mountScriptInstance` | New Wasm slot for one instance (props, audit). Script must call `Type:extend()`. |
90
+ | `unmountScriptInstance` | Tear down one instance. |
91
+ | `emitToAllInstances` | Call `on{Kind}` on every mounted instance (component hooks). |
92
+ | `setInstanceProps` / `patchInstanceProps` | Update host-synced props; may invoke `onPropsChanged`. |
93
+ | `getInstanceProps` / `flushInstanceProps` | Read or flush props proxy state. |
94
+ | `getSurfaceCapabilities` | All capability ids declared on the surface. |
95
+ | `surface.getComponentType(name)` | Resolved profile (props, state, capabilities, hooks) for codegen/runtime. |
96
+ | `dispose` | Unmount all instances. |
97
+ | `defineHostSurfaceFor`, `defineHostSurface` | Fluent surface builder (`componentType` → `bridge` → `method` → `build`). |
98
+
99
+ Re-exported from this package for convenience; lower-level session API lives in `@microverse.ts/host-surface`.
100
+
101
+ ## Quick start (minimal)
40
102
 
41
103
  ```ts
42
104
  import { MicroverseLua, defineHostSurfaceFor } from '@microverse.ts/microverse-lua';
@@ -60,38 +122,269 @@ const microverse = MicroverseLua.create({
60
122
  defaultTimeoutMs: 30_000,
61
123
  });
62
124
 
63
- await microverse.registerScript({
125
+ microverse.registerScriptDefinition({
126
+ scriptId: 'welcome',
127
+ source: `local msg = greet:hello({ name = "world" })`,
128
+ });
129
+ await microverse.mountScriptInstance({
130
+ instanceId: 'welcome',
64
131
  scriptId: 'welcome',
65
- script: `local msg = greet:hello({ name = "world" })`,
66
- capabilities: surface.pickCapabilities('demo:greet'),
67
132
  });
68
133
 
69
134
  await microverse.dispose();
70
135
  ```
71
136
 
72
- ## API
137
+ > The minimal sample uses a global `greet` table for brevity. In production, declare **`.componentType(…)`** on the surface, call **`YourType:extend()`** in Lua, and use **`self.bridges`** (see [Lua authoring](#lua-authoring) and [Integrating in your app](#integrating-in-your-app)).
73
138
 
74
- | Export | Purpose |
75
- |--------|---------|
76
- | `MicroverseLua.create` | Create a Lua microverse (Wasm VM included). |
77
- | `registerScript` | New slot + optional preludes + main chunk. |
78
- | `emitToAllScripts` | Call `on{Kind}` on every script (workflow hooks). |
79
- | `defineHostSurfaceFor`, `defineHostSurface` | Fluent surface builder (`bridge` → `method` → `build`). |
139
+ ## Integrating in your app
140
+
141
+ The reference layout is [`examples/sorting-lab`](../../examples/sorting-lab). File tour: [example README](../../examples/sorting-lab/README.md).
142
+
143
+ ### 1. Define the host
144
+
145
+ Aggregate your real services into one object the surface handlers receive:
146
+
147
+ ```ts
148
+ // examples/sorting-lab/src/engine/sortingLabHost.ts
149
+ export type SortingLabHost = {
150
+ arrayA: number[];
151
+ arrayB: number[];
152
+ vizA: SortingVizSnapshot;
153
+ vizB: SortingVizSnapshot;
154
+ // …
155
+ };
156
+ ```
157
+
158
+ Construct it in your app and pass it to `MicroverseLua.create({ host, surface })`.
159
+
160
+ ### 2. Define the surface
80
161
 
81
- ## IDE stubs
162
+ Declare bridges (Lua → host), Zod payloads, capabilities, and optional component hooks (host → Lua):
163
+
164
+ ```ts
165
+ // examples/sorting-lab/src/engine/sortingSurface.ts
166
+ import { defineHostSurfaceFor } from '@microverse.ts/microverse-lua';
167
+ import { sortingComponentHooks } from './sortingHooks';
168
+
169
+ export default defineHostSurfaceFor<SortingLabHost>()
170
+ .componentType('SortingAlgorithm', SORTING_ALGORITHM_PROFILE)
171
+ .bridge('array')
172
+ .method('length', { requires: 'array:read', /* … */ })
173
+ // … viz, sort bridges …
174
+ .componentHooks(sortingComponentHooks)
175
+ .build();
176
+ ```
177
+
178
+ - **`componentType`** — Props/state schemas, capability set, and hook subset for `Name:extend()`.
179
+ - **`requires`** — Capability id; only methods whose capability is in the active type appear on `self.bridges`.
180
+ - **`handler`** — Runs in TypeScript with `{ host, script }` context.
181
+ - **`componentHooks`** — Map of event kind → Zod object; generates `onOrderPlaced`, `MicroverseEvt_OrderPlaced`, etc. in `.d.lua`.
182
+
183
+ Default-export the built surface for `microverse generate-lua-defs --surface …`.
184
+
185
+ ### 3. Wrap the engine (optional)
186
+
187
+ A thin façade keeps app code free of microverse details:
188
+
189
+ ```ts
190
+ // examples/sorting-lab/src/engine/sortingLabEngine.ts
191
+ this.microverse = MicroverseLua.create({ host, surface, defaultTimeoutMs: 30_000 });
192
+
193
+ await this.microverse.mountScriptInstance({
194
+ instanceId: 'A',
195
+ scriptId: 'bubble_sort',
196
+ profileId: 'SortingAlgorithm',
197
+ props: { label: 'Bubble sort', slotSide: 'A' },
198
+ });
199
+
200
+ await session.invokeComponentHook(luaGlobalHookName('Tick'), { step: 1 });
201
+ ```
202
+
203
+ Map your domain events to `emitToAllInstances` (see `dispatch` in the example).
204
+
205
+ ### 4. Load Lua sources
206
+
207
+ Keep scripts in `.lua` files and register by `scriptId`:
208
+
209
+ ```ts
210
+ import { readComponentLua } from './services/components/loadComponentScript';
211
+
212
+ engine.registerScriptDefinition('order_echo', readComponentLua('components/order_echo.lua'));
213
+ ```
214
+
215
+ Or inline strings for tests. Use **`sharedLuaChunks`** on `create` for libraries shared by every instance (e.g. `lua/lib/math_helpers.lua`), and **`injectLuaChunks`** per definition or mount for one-off preludes.
216
+
217
+ ### 5. Mount instances
218
+
219
+ Each Lua script chooses its profile with **`YourType:extend()`** at load time. `self.bridges` only contains bridges/methods allowed by that type’s capabilities:
220
+
221
+ ```ts
222
+ await engine.mountScriptInstance({
223
+ scriptId: 'billing_denied',
224
+ props: { maxCents: 1000 },
225
+ });
226
+ ```
227
+
228
+ ```lua
229
+ -- billing_denied.lua — AuditOnly type has no billing bridge
230
+ local C = AuditOnly:extend()
231
+ ```
232
+
233
+ Optional **`audit`** metadata is passed to script audit callbacks for observability.
234
+
235
+ ### 6. Dispatch events and shut down
236
+
237
+ ```ts
238
+ await engine.emitHook('OrderPlaced', payload);
239
+ // or engine.dispatch(domainEvent)
240
+
241
+ await engine.dispose();
242
+ ```
243
+
244
+ ## Lua authoring
245
+
246
+ ### Component pattern
247
+
248
+ Scripts call the **type singleton** declared on the surface (e.g. `OrderEcho:extend()`) and implement hooks on the returned table:
249
+
250
+ ```lua
251
+ -- examples/sorting-lab/lua/bubble_sort.lua
252
+ local C = SortingAlgorithm:extend()
253
+
254
+ function C:onTick(_evt)
255
+ self.bridges.viz:markComparing({ a = j, b = j + 1 })
256
+ -- one compare/swap per tick …
257
+ end
258
+ ```
259
+
260
+ - **`OrderEcho:extend()`** — Builds the instance with typed `properties`, `state`, and narrowed `bridges` for that profile.
261
+ - **Domain events** — Implement `onOrderPlaced`, … listed in the type’s `hooks` (and in `OrderEchoComponent` in `.d.lua`).
262
+ - **Lifecycle** — `init`, `onDestroy`, `onPropsChanged` (see `props_demo.lua`).
263
+
264
+ ### Bridges (scoped, not global)
265
+
266
+ Call host APIs through **`self.bridges.<bridgeName>:<method>(payload)`**:
267
+
268
+ ```lua
269
+ local order = self.bridges.orders:get({ orderId = evt.orderId })
270
+ self.bridges.audit:record({ line = "seen:" .. evt.orderId })
271
+ ```
272
+
273
+ Bridge names match `.bridge('orders')` in TypeScript (camelCase field on `OrderEchoBridges` / your type’s bridges class in `.d.lua`).
274
+
275
+ ### Props and state
276
+
277
+ ```lua
278
+ -- examples/business-scripting-engine/lua/components/props_demo.lua
279
+ function C:init()
280
+ self.state = { hits = 0 }
281
+ end
282
+
283
+ function C:onPropsChanged(key, newValue)
284
+ self.state.lastKey = key
285
+ end
286
+
287
+ function C:onOrderPlaced(evt)
288
+ local label = self.properties.label or "?"
289
+ self.state.hits = (self.state.hits or 0) + 1
290
+ end
291
+ ```
292
+
293
+ Host patches props via `setInstanceProps` / `patchInstanceProps` on the microverse.
294
+
295
+ ### Shared Lua libraries
296
+
297
+ | Mechanism | Scope |
298
+ |-----------|--------|
299
+ | `sharedLuaChunks` on `MicroverseLua.create` | Every instance, every mount |
300
+ | `injectLuaChunks` on `registerScriptDefinition` | All mounts of that `scriptId` |
301
+ | `injectLuaChunks` on `mountScriptInstance` | Single instance |
302
+
303
+ Run order: shared → definition → mount preludes → main script chunk.
304
+
305
+ ### Async bridges
306
+
307
+ Mark a handler `async` in TypeScript; Lua may use a completion callback or `:await()` on the returned handle:
308
+
309
+ ```lua
310
+ -- examples/business-scripting-engine/lua/components/order_asyncio_tick.lua
311
+ self.bridges.asyncio:tick({ delayMs = 5, seed = evt.amountCents }, function(r)
312
+ self.bridges.audit:record({ line = "asyncio-value:" .. tostring(r.value) })
313
+ end)
314
+ ```
315
+
316
+ Generated stubs document `AsyncioTickHandle` and `AsyncioTickResult` for LuaLS.
317
+
318
+ ## IDE typing (LuaCATS)
319
+
320
+ Generate stubs from the same surface module that drives runtime:
82
321
 
83
322
  ```bash
84
323
  pnpm add -D @microverse.ts/cli
85
- pnpm exec microverse generate-lua-defs --surface src/mySurface.ts
324
+ pnpm exec microverse generate-lua-defs --surface src/engine/sortingSurface.ts
86
325
  ```
87
326
 
88
- Requires `export default` on the surface module (typically the result of `.build()`). Details: [`@microverse.ts/cli`](../cli/README.md).
327
+ The manifest emits **type-only** bridge classes (`---@class Orders` + `---@field get fun()`) so LuaLS does not treat `Orders` as a runtime global. Use:
89
328
 
90
- ## Reference example
329
+ - `self.bridges.orders` — field name (camelCase) on `OrderEchoBridges` (per component type)
330
+ - Types like `Orders`, `OrderDto` — PascalCase classes in the stub file
331
+ - `OrderEcho:extend()` — singleton stub per `.componentType('OrderEcho', …)`
332
+
333
+ Point LuaLS at the generated folder and list your type singletons as globals:
334
+
335
+ ```json
336
+ {
337
+ "workspace.library": ["./generated"],
338
+ "diagnostics.globals": ["OrderEcho", "AuditOnly", "Promotions"]
339
+ }
340
+ ```
341
+
342
+ Include both `sortingSurface.d.lua` (bridges + `*Component`) and `sortingScriptCatalog.d.lua` (per-`scriptId` aliases) when using a script catalog.
343
+
344
+ See [`examples/sorting-lab/.luarc.json`](../../examples/sorting-lab/.luarc.json) and [`generated/sortingSurface.d.lua`](../../examples/sorting-lab/generated/sortingSurface.d.lua).
91
345
 
92
- [`examples/business-scripting-engine`](../../examples/business-scripting-engine) — rules engine with orders, billing, workflow Lua, and `BusinessScriptingEngine` wrapping this package.
346
+ **Chess duel (shared board, turn-based):** [`examples/chess-lab`](../examples/chess-lab/README.md) — two `ChessEngine` scripts compete on one `chess.js` board.
93
347
 
94
- ## Related
348
+ Details: [`@microverse.ts/cli`](../cli/README.md), [`@microverse.ts/lua-defs`](../lua-defs/README.md).
95
349
 
96
- - Async bridges: [`host-surface/docs/async-subroutines-components.md`](../host-surface/docs/async-subroutines-components.md)
97
- - Component-style Lua: [`examples/.../COMPONENT_PATTERN.md`](../../examples/business-scripting-engine/docs/COMPONENT_PATTERN.md)
350
+ ## Integrating a game engine (script profiles)
351
+
352
+ For ECS-style hosts (many entities, many scripts, YAML-driven props), use **script profiles** instead of declaring every script on the surface:
353
+
354
+ | Primitive | Role |
355
+ |-----------|------|
356
+ | `LuaScriptDefinition.profileId` | Names a profile (usually matches a `.componentType()` on the surface for bridges/codegen). |
357
+ | `mountScriptInstance({ profileId })` | Host applies the profile at `openSession` — Lua chunks can omit `Type:extend()` for runtime (keep `---@type XxxComponent` for LuaLS). |
358
+ | `HostScriptSession` + `createLuaEnvSlotKey('entity::script')` | One slot per entity+script; your subsystem owns reconcile/lifecycle. |
359
+ | `ScriptReferenceResolver` | Implement `self.references.*` wrappers (entity handles) without ECS types in microverse. |
360
+ | `buildScriptCatalogLuaDefManifest` | Emit per-`scriptId` aliases for `lua/` (see business example). |
361
+
362
+ Reference layout: [`examples/sorting-lab/src/engine/sortingScriptCatalog.ts`](../../examples/sorting-lab/src/engine/sortingScriptCatalog.ts).
363
+
364
+ ## Security model
365
+
366
+ | Layer | Behavior |
367
+ |-------|----------|
368
+ | **Component types** | Each `.componentType(…)` declares a capability set. `Type:extend()` mounts only matching bridges on `self.bridges`; other bridges are absent (`nil`). |
369
+ | **Bridge methods** | Each method declares `requires`; filtering happens at extend time, not per call (no `capability denied` throws). |
370
+ | **Host isolation** | The TypeScript `host` object is not injected into Lua; only bridge tables built from the surface are visible (via `self.bridges`). |
371
+ | **Timeouts** | `defaultTimeoutMs` or `defaultTimeout` on `create`; Wasm instruction budget in `@microverse.ts/runtime-wasm`. |
372
+ | **Validation** | Zod validates bridge inputs/outputs and instance props (per active type) at the TS boundary (`@microverse.ts/runtime-zod`). |
373
+
374
+ ## Related packages
375
+
376
+ | Package | Use when |
377
+ |---------|----------|
378
+ | [`@microverse.ts/host-surface`](../host-surface/README.md) | Surface builder details, `HostScriptSession`, custom slot wiring. |
379
+ | [`@microverse.ts/lua-defs`](../lua-defs/README.md) | Manifest → LuaCATS document (library use). |
380
+ | [`@microverse.ts/cli`](../cli/README.md) | `microverse generate-lua-defs` in CI or locally. |
381
+ | `runtime-wasm`, `runtime-bridge`, `runtime-capabilities` | Advanced runtime customization (usually via host-surface). |
382
+
383
+ ## Reference example
384
+
385
+ [`examples/sorting-lab`](../../examples/sorting-lab) — browser sorting comparator: Wasm Lua, tick-by-tick `onTick`, dual panels, and `SortingLabEngine` wrapping this package.
386
+
387
+ ```bash
388
+ pnpm --filter @microverse.ts/sorting-lab test
389
+ pnpm --filter @microverse.ts/sorting-lab dev
390
+ ```
package/dist/index.d.ts CHANGED
@@ -4,14 +4,17 @@
4
4
  * Plug-and-play Lua scripting: **{@link MicroverseLua.create}** (built-in Wasm VM) and the fluent
5
5
  * **{@link defineHostSurfaceFor}** builder (`bridge` → `method` → `build`).
6
6
  */
7
- export { augmentHostWithCapabilityRegistry, BridgeBuilder, buildBridgeMergeEnvForHost, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, defineHostSurface, defineHostSurfaceFor, HostScriptSession, luaGlobalHookName, luaType, MICROVERSE_CAPABILITY_REGISTRY, pickSurfaceCapabilities, SurfaceBuilder, zodToLuaTypeRef, type AnyHostSurfaceMethod, type HostFnContext, type HostScriptSessionOptions, type HostSurface, type HostSurfaceCore, type HostSurfaceMethodEntry, type HostSurfaceSpec, type HostSurfaceSpecForHost, type HostWorkflowHooksSpec, type InferSurfaceCapabilities, type LuaDefManifestGeneratorOpts, type LuaGlobalHookName, type SchemaValidationPort, type SurfaceCapabilityString, type SurfaceMethodDef, type WithMicroverseCapabilityRegistry, type WorkflowHookInvokeArgs, type ZodToLuaTypeRefOptions, } from '@microverse.ts/host-surface';
7
+ export { augmentHostWithCapabilityRegistry, BridgeBuilder, buildBridgeMergeEnvForProfile, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, defineHostSurface, defineHostSurfaceFor, HostScriptSession, luaGlobalHookName, luaType, MICROVERSE_CAPABILITY_REGISTRY, pickSurfaceCapabilities, SurfaceBuilder, zodToLuaTypeRef, type AnyHostSurfaceMethod, type HostFnContext, type HostScriptSessionOptions, type HostSurface, type HostSurfaceCore, type HostSurfaceMethodEntry, type HostSurfaceSpec, type HostSurfaceSpecForHost, type HostComponentHooksSpec, type InferSurfaceCapabilities, type LuaDefManifestGeneratorOpts, type LuaGlobalHookName, type SchemaValidationPort, type SurfaceCapabilityString, type SurfaceMethodDef, type WithMicroverseCapabilityRegistry, type ComponentEventHookInvokeArgs, type ZodToLuaTypeRefOptions, buildScriptCatalogLuaDefManifest, scriptCatalogComponentAlias, } from '@microverse.ts/host-surface';
8
8
  export * from '@microverse.ts/shared';
9
9
  export * from '@microverse.ts/runtime-core';
10
+ /** Commonly used script/catalog types (also available via `export *` from runtime-core). */
11
+ export type { LuaScriptDefinition, LuaScriptSource, ScriptInstanceContext, ScriptInstanceId, ScriptProfileDefInput, } from '@microverse.ts/runtime-core';
12
+ export { formatExecutionFailure } from '@microverse.ts/runtime-core';
10
13
  export * from '@microverse.ts/runtime-lua';
11
14
  export * from '@microverse.ts/runtime-wasm';
12
15
  export * from '@microverse.ts/runtime-bridge';
13
16
  export * from '@microverse.ts/runtime-capabilities';
14
17
  export * from '@microverse.ts/runtime-zod';
15
- export { MicroverseLua } from './infrastructure/facade/microverseLuaNamespace.js';
16
- export { createLuaMicroverse, LuaMicroverse, type LuaMicroverseConfig, type InferScriptHooksFromHost, type InferScriptHooksFromSurface, type InferSurfaceCapabilitiesFromSurface, type TaggedLuaMicroverseHost, } from './infrastructure/facade/luaMicroverse.js';
18
+ export { MicroverseLua } from './infrastructure/facade/microverseLuaNamespace';
19
+ export { createLuaMicroverse, LuaMicroverse, type LuaMicroverseConfig, type InferScriptHooksFromHost, type InferScriptHooksFromSurface, type InferSurfaceCapabilitiesFromSurface, type TaggedLuaMicroverseHost, } from './infrastructure/facade/luaMicroverse';
17
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,iCAAiC,EACjC,aAAa,EACb,0BAA0B,EAC1B,sCAAsC,EACtC,kBAAkB,EAClB,qBAAqB,EACrB,2CAA2C,EAC3C,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,OAAO,EACP,8BAA8B,EAC9B,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,6BAA6B,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,uBAAuB,GAC7B,MAAM,0CAA0C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,iCAAiC,EACjC,aAAa,EACb,6BAA6B,EAC7B,sCAAsC,EACtC,kBAAkB,EAClB,qBAAqB,EACrB,2CAA2C,EAC3C,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,OAAO,EACP,8BAA8B,EAC9B,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,gCAAgC,EACrC,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC3B,gCAAgC,EAChC,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,4FAA4F;AAC5F,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4BAA4B,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,uBAAuB,GAC7B,MAAM,uCAAuC,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { BridgeBuilder, HostScriptSession, HostScriptSession as HostScriptSession$1, MICROVERSE_CAPABILITY_REGISTRY, SurfaceBuilder, augmentHostWithCapabilityRegistry, buildBridgeMergeEnvForHost, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, defineHostSurface, defineHostSurfaceFor, luaGlobalHookName, luaGlobalHookName as luaGlobalHookName$1, luaType, pickSurfaceCapabilities, zodToLuaTypeRef } from "@microverse.ts/host-surface";
2
- import { createLuaEnvSlotKey, fixedTimeout } from "@microverse.ts/runtime-core";
1
+ import { BridgeBuilder, HostScriptSession, HostScriptSession as HostScriptSession$1, MICROVERSE_CAPABILITY_REGISTRY, SurfaceBuilder, augmentHostWithCapabilityRegistry, buildBridgeMergeEnvForProfile, buildScriptCatalogLuaDefManifest, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, defineHostSurface, defineHostSurfaceFor, luaGlobalHookName, luaGlobalHookName as luaGlobalHookName$1, luaType, pickSurfaceCapabilities, resolveScriptProfile, scriptCatalogComponentAlias, zodToLuaTypeRef } from "@microverse.ts/host-surface";
2
+ import { createLuaEnvSlotKey, createScriptInstanceContext, fixedTimeout, formatExecutionFailure, formatExecutionFailure as formatExecutionFailure$1, mergeScriptPropertyBags, resolveLuaScriptProfileId, resolveLuaScriptSource } from "@microverse.ts/runtime-core";
3
3
  import { createWasmMicroverseRuntime } from "@microverse.ts/runtime-wasm";
4
4
  export * from "@microverse.ts/shared";
5
5
  export * from "@microverse.ts/runtime-core";
@@ -13,87 +13,159 @@ function resolveDefaultTimeout(config) {
13
13
  if (config.defaultTimeout !== void 0) return config.defaultTimeout;
14
14
  if (config.defaultTimeoutMs !== void 0) return fixedTimeout(config.defaultTimeoutMs);
15
15
  }
16
- /**
17
- * One **Lua microverse**: a shared built-in Wasm Lua VM, {@link HostScriptSession}s keyed by `scriptId`, and helpers to
18
- * register scripts and broadcast hook events. Capabilities per script come from the host surface
19
- * ({@link HostSurfaceCore.pickCapabilities} / {@link HostSurfaceCore.capabilities}). Created via {@link MicroverseLua.create}
20
- * or {@link createLuaMicroverse}.
21
- */
22
16
  var LuaMicroverse = class {
23
17
  config;
24
18
  runtime;
25
- sessions = /* @__PURE__ */ new Map();
19
+ definitions = /* @__PURE__ */ new Map();
20
+ instances = /* @__PURE__ */ new Map();
26
21
  host;
27
22
  surface;
28
23
  envSlotScope;
29
24
  defaultTimeout;
30
25
  sharedLuaChunks;
26
+ onScriptAudit;
31
27
  constructor(config) {
32
28
  this.config = config;
33
29
  this.host = config.host;
34
30
  this.surface = config.surface;
35
31
  this.defaultTimeout = resolveDefaultTimeout(config);
36
32
  this.sharedLuaChunks = config.sharedLuaChunks ?? [];
33
+ this.onScriptAudit = config.onScriptAudit;
37
34
  this.runtime = createWasmMicroverseRuntime(this.defaultTimeout !== void 0 ? { defaultTimeout: this.defaultTimeout } : {});
38
35
  this.envSlotScope = config.envSlotScope ?? "script";
39
36
  }
40
- /** Capability ids declared on the bound host surface. */
41
37
  getSurfaceCapabilities = () => this.surface.capabilities;
42
- /**
43
- * Loads one Lua chunk in an isolated env slot; `scriptId` must be unique within this microverse.
44
- *
45
- * @param args.capabilities - Subset of {@link getSurfaceCapabilities}; use `surface.pickCapabilities(…)` at the call site.
46
- */
47
- registerScript = async (args) => {
48
- const { scriptId, script, capabilities, injectLuaChunks } = args;
49
- const preludeChunks = [...this.sharedLuaChunks, ...injectLuaChunks ?? []];
50
- if (this.sessions.has(scriptId)) throw new Error(`script already registered: ${scriptId}`);
38
+ registerScriptDefinition = (def) => {
39
+ if (this.definitions.has(def.scriptId)) throw new Error(`script definition already registered: ${def.scriptId}`);
40
+ this.definitions.set(def.scriptId, def);
41
+ };
42
+ hasScriptDefinition = (scriptId) => this.definitions.has(scriptId);
43
+ getScriptDefinition = (scriptId) => this.definitions.get(scriptId);
44
+ mountScriptInstance = async (args) => {
45
+ const { instanceId, scriptId, audit, injectLuaChunks } = args;
46
+ if (this.instances.has(instanceId)) throw new Error(`script instance already mounted: ${instanceId}`);
47
+ let def = this.definitions.get(scriptId);
48
+ if (def === void 0) {
49
+ if (args.script === void 0) throw new Error(`unknown scriptId "${scriptId}" and no inline script provided`);
50
+ def = {
51
+ scriptId,
52
+ source: args.script
53
+ };
54
+ this.definitions.set(scriptId, def);
55
+ } else if (args.script !== void 0) def = {
56
+ ...def,
57
+ source: args.script
58
+ };
59
+ const profileId = args.profileId ?? resolveLuaScriptProfileId(def);
60
+ let resolvedProfile;
61
+ if (def.profile !== void 0) {
62
+ const profileName = profileId ?? args.profileSingleton ?? scriptId;
63
+ resolvedProfile = resolveScriptProfile({ [profileName]: def.profile }, profileName, this.surface.getHostSurfaceSpec());
64
+ } else if (profileId !== void 0) this.surface.getComponentType(profileId);
65
+ const profileSingleton = args.profileSingleton ?? (def.profile !== void 0 && profileId !== void 0 ? profileId : void 0);
66
+ const slotKey = createLuaEnvSlotKey(`${this.envSlotScope}:${instanceId}`);
67
+ const scriptContext = createScriptInstanceContext({
68
+ instanceId,
69
+ scriptId,
70
+ slotKey: String(slotKey),
71
+ audit
72
+ });
51
73
  const session = new HostScriptSession$1({
52
74
  runtime: this.runtime,
53
75
  surface: this.surface,
54
76
  host: this.host,
55
- slotKey: createLuaEnvSlotKey(`${this.envSlotScope}:${scriptId}`),
56
- allowedCapabilities: capabilities,
57
- defaultTimeout: this.defaultTimeout
77
+ slotKey,
78
+ defaultTimeout: this.defaultTimeout,
79
+ script: scriptContext,
80
+ profileId: resolvedProfile?.name ?? profileId,
81
+ resolvedProfile,
82
+ profileSingleton,
83
+ onScriptAudit: this.onScriptAudit
58
84
  });
59
- await session.openSession();
60
- for (const [index, chunk] of preludeChunks.entries()) {
61
- const injected = await session.runChunk(chunk);
62
- if (injected._tag !== "ok") {
63
- await session.dispose();
64
- const detail = injected._tag === "err" && injected.error._tag === "AdapterError" ? injected.error.message : JSON.stringify(injected.error);
65
- const which = index < this.sharedLuaChunks.length ? `shared Lua prelude [${index}]` : `script injectLuaChunks [${index - this.sharedLuaChunks.length}]`;
66
- throw new Error(`script "${scriptId}" failed injecting ${which}: ${detail}`);
85
+ try {
86
+ await session.openSession();
87
+ const preludeChunks = [
88
+ ...this.sharedLuaChunks,
89
+ ...def.injectLuaChunks ?? [],
90
+ ...injectLuaChunks ?? []
91
+ ];
92
+ for (const [index, chunk] of preludeChunks.entries()) {
93
+ const injected = await session.runChunk(chunk);
94
+ if (injected._tag !== "ok") throw new Error(formatRunError(instanceId, `prelude [${index}]`, injected));
67
95
  }
68
- }
69
- const loaded = await session.runChunk(script);
70
- if (loaded._tag !== "ok") {
96
+ const source = await resolveLuaScriptSource(def.source);
97
+ const loaded = await session.runChunk(source);
98
+ if (loaded._tag !== "ok") throw new Error(formatRunError(instanceId, "main chunk", loaded));
99
+ const mergedProps = mergeScriptPropertyBags(def.defaultProps ?? {}, args.props ?? {});
100
+ await session.setProps(mergedProps);
101
+ const initResult = await session.invokeComponentHook("init");
102
+ if (initResult._tag !== "ok") throw new Error(formatRunError(instanceId, "init hook", initResult));
103
+ this.instances.set(instanceId, { session });
104
+ this.onScriptAudit?.({
105
+ kind: "mounted",
106
+ context: scriptContext
107
+ });
108
+ } catch (e) {
71
109
  await session.dispose();
72
- const detail = loaded._tag === "err" && loaded.error._tag === "AdapterError" ? loaded.error.message : JSON.stringify(loaded.error);
73
- throw new Error(`script "${scriptId}" failed to load: ${detail}`);
110
+ const message = e instanceof Error ? e.message : String(e);
111
+ this.onScriptAudit?.({
112
+ kind: "scriptError",
113
+ context: scriptContext,
114
+ phase: "mount",
115
+ message
116
+ });
117
+ throw e;
74
118
  }
75
- this.sessions.set(scriptId, session);
76
119
  };
77
- /** Invokes `on{Kind}` on every registered script with the same payload table (Lua literals only). */
78
- emitToAllScripts = (async (kind, payload) => {
120
+ unmountScriptInstance = async (instanceId) => {
121
+ const mounted = this.instances.get(instanceId);
122
+ if (mounted === void 0) throw new Error(`script instance not mounted: ${instanceId}`);
123
+ const ctx = mounted.session.context;
124
+ await mounted.session.dispose();
125
+ this.instances.delete(instanceId);
126
+ this.onScriptAudit?.({
127
+ kind: "unmounted",
128
+ context: ctx
129
+ });
130
+ };
131
+ setInstanceProps = async (instanceId, bag) => {
132
+ await this.requireInstance(instanceId).setProps(bag);
133
+ };
134
+ patchInstanceProps = async (instanceId, partial) => {
135
+ await this.requireInstance(instanceId).patchProps(partial);
136
+ };
137
+ getInstanceProps = (instanceId) => {
138
+ return this.requireInstance(instanceId).getProps();
139
+ };
140
+ flushInstanceProps = async (instanceId) => {
141
+ return this.requireInstance(instanceId).flushDirtyProps();
142
+ };
143
+ getInstance = (instanceId) => {
144
+ return this.instances.get(instanceId)?.session;
145
+ };
146
+ emitToAllInstances = (async (kind, payload) => {
79
147
  const hook = luaGlobalHookName$1(kind);
80
- for (const [id, session] of this.sessions) {
81
- const r = await session.invokeGlobalHookIfPresent(hook, payload);
148
+ for (const [id, { session }] of this.instances) {
149
+ const r = await session.invokeComponentEventHook(hook, payload);
82
150
  if (r._tag !== "ok") {
83
151
  const detail = r._tag === "err" && r.error._tag === "AdapterError" ? r.error.message : JSON.stringify(r.error);
84
- throw new Error(`script "${id}" failed on emit: ${detail}`);
152
+ throw new Error(`instance "${id}" failed on emit: ${detail}`);
85
153
  }
86
154
  }
87
155
  });
88
156
  dispose = async () => {
89
- for (const s of this.sessions.values()) await s.dispose();
90
- this.sessions.clear();
157
+ for (const id of [...this.instances.keys()]) await this.unmountScriptInstance(id);
158
+ this.instances.clear();
91
159
  };
160
+ requireInstance(instanceId) {
161
+ const mounted = this.instances.get(instanceId);
162
+ if (mounted === void 0) throw new Error(`script instance not mounted: ${instanceId}`);
163
+ return mounted.session;
164
+ }
92
165
  };
93
- /**
94
- * Creates a {@link LuaMicroverse} with a **built-in** Wasm Lua VM (Wasmoon). Type `host` with
95
- * {@link TaggedLuaMicroverseHost} so hook emits narrow correctly.
96
- */
166
+ function formatRunError(instanceId, phase, result) {
167
+ return `instance "${instanceId}" failed ${phase}: ${formatExecutionFailure$1(result.error)}`;
168
+ }
97
169
  function createLuaMicroverse(config) {
98
170
  return new LuaMicroverse({
99
171
  host: config.host,
@@ -101,7 +173,8 @@ function createLuaMicroverse(config) {
101
173
  envSlotScope: config.envSlotScope,
102
174
  defaultTimeout: config.defaultTimeout,
103
175
  defaultTimeoutMs: config.defaultTimeoutMs,
104
- sharedLuaChunks: config.sharedLuaChunks
176
+ sharedLuaChunks: config.sharedLuaChunks,
177
+ onScriptAudit: config.onScriptAudit
105
178
  });
106
179
  }
107
180
  //#endregion
@@ -119,13 +192,15 @@ function createLuaMicroverse(config) {
119
192
  * surface: mySurface,
120
193
  * defaultTimeoutMs: 30_000,
121
194
  * });
122
- * await microverse.registerScript({ scriptId: 'ai', script: lua, capabilities: surface.pickCapabilities('demo:tick') });
195
+ * microverse.registerScriptDefinition({ scriptId: 'ai', source: lua });
196
+ * await microverse.mountScriptInstance({ instanceId: 'ai', scriptId: 'ai' });
197
+ * // Lua: local C = MyType:extend()
123
198
  * ```
124
199
  */
125
200
  var MicroverseLua = {
126
201
  /** Creates a {@link LuaMicroverse} with a built-in Wasm Lua runtime. */
127
202
  create: createLuaMicroverse };
128
203
  //#endregion
129
- export { BridgeBuilder, HostScriptSession, LuaMicroverse, MICROVERSE_CAPABILITY_REGISTRY, MicroverseLua, SurfaceBuilder, augmentHostWithCapabilityRegistry, buildBridgeMergeEnvForHost, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, createLuaMicroverse, defineHostSurface, defineHostSurfaceFor, luaGlobalHookName, luaType, pickSurfaceCapabilities, zodToLuaTypeRef };
204
+ export { BridgeBuilder, HostScriptSession, LuaMicroverse, MICROVERSE_CAPABILITY_REGISTRY, MicroverseLua, SurfaceBuilder, augmentHostWithCapabilityRegistry, buildBridgeMergeEnvForProfile, buildScriptCatalogLuaDefManifest, collectCapabilitiesFromHostSurfaceSpec, compileHostSurface, compileHostSurfaceFor, createBridgeDeclarationsFromHostSurfaceSpec, createLuaMicroverse, defineHostSurface, defineHostSurfaceFor, formatExecutionFailure, luaGlobalHookName, luaType, pickSurfaceCapabilities, scriptCatalogComponentAlias, zodToLuaTypeRef };
130
205
 
131
206
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/infrastructure/facade/luaMicroverse.ts","../src/infrastructure/facade/microverseLuaNamespace.ts"],"sourcesContent":["import type { z } from 'zod';\n\nimport {\n HostScriptSession,\n luaGlobalHookName,\n type HostSurface,\n type HostSurfaceCore,\n type HostWorkflowHooksSpec,\n} from '@microverse.ts/host-surface';\nimport type { CapabilityId } from '@microverse.ts/runtime-capabilities';\nimport {\n createLuaEnvSlotKey,\n fixedTimeout,\n type MicroverseRuntime,\n type TimeoutPolicy,\n} from '@microverse.ts/runtime-core';\nimport { createWasmMicroverseRuntime } from '@microverse.ts/runtime-wasm';\n\n/** Phantom key: optional on the host **type** so {@link InferScriptHooksFromHost} can recover hook Zod map typing. Never set at runtime. */\ndeclare const SCRIPT_HOOKS_TYPE: unique symbol;\n\n/**\n * Intersects `TBase` with an optional phantom field carrying `THooks` for {@link LuaMicroverse} / {@link createLuaMicroverse} inference.\n */\nexport type TaggedLuaMicroverseHost<\n THooks extends HostWorkflowHooksSpec,\n TBase = unknown,\n> = TBase & { readonly [SCRIPT_HOOKS_TYPE]?: THooks };\n\nexport type InferScriptHooksFromHost<THost> = THost extends TaggedLuaMicroverseHost<infer H, unknown>\n ? H extends HostWorkflowHooksSpec\n ? H\n : undefined\n : undefined;\n\nexport type InferScriptHooksFromSurface<S extends HostSurfaceCore> =\n S extends HostSurfaceCore<CapabilityId> & { readonly workflowHooks: infer H extends HostWorkflowHooksSpec }\n ? H\n : S extends HostSurface<infer H extends HostWorkflowHooksSpec, CapabilityId>\n ? H\n : undefined;\n\nexport type InferSurfaceCapabilitiesFromSurface<S extends HostSurfaceCore> = S extends HostSurfaceCore<\n infer C extends CapabilityId\n>\n ? C\n : CapabilityId;\n\ntype EffectiveScriptHooks<THost extends object, TSurface extends HostSurfaceCore> = [InferScriptHooksFromHost<THost>] extends [\n undefined,\n]\n ? InferScriptHooksFromSurface<TSurface>\n : InferScriptHooksFromHost<THost>;\n\nexport type LuaMicroverseConfig<\n THost extends object = object,\n THooks extends HostWorkflowHooksSpec | undefined = InferScriptHooksFromHost<THost>,\n TCapabilities extends CapabilityId = CapabilityId,\n> = {\n readonly host: THost;\n /** From {@link defineHostSurface} / {@link defineHostSurfaceFor}; hooks live on `surface.workflowHooks` when present. */\n readonly surface: HostSurface<THooks, TCapabilities>;\n /** Prefix for internal Lua env slot ids, default `script` (ids look like `script:my-id`). */\n readonly envSlotScope?: string | undefined;\n /** Wall-clock limit per `runChunk` / hook invocation (Wasm adapter + session forwarding). */\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n /**\n * Shorthand for {@link defaultTimeout} as `fixedTimeout(ms)`. Ignored when `defaultTimeout` is set.\n */\n readonly defaultTimeoutMs?: number | undefined;\n /**\n * Lua sources run in **every** script slot after {@link HostScriptSession.openSession} and before that\n * script's main chunk. Define shared helpers/libraries here once instead of per {@link registerScript}.\n */\n readonly sharedLuaChunks?: readonly string[] | undefined;\n};\n\nfunction resolveDefaultTimeout<\n THost extends object,\n THooks extends HostWorkflowHooksSpec | undefined,\n TCapabilities extends CapabilityId,\n>(config: LuaMicroverseConfig<THost, THooks, TCapabilities>): TimeoutPolicy | undefined {\n if (config.defaultTimeout !== undefined) {\n return config.defaultTimeout;\n }\n if (config.defaultTimeoutMs !== undefined) {\n return fixedTimeout(config.defaultTimeoutMs);\n }\n return undefined;\n}\n\ntype EmitToAllScriptsFn<THooks extends HostWorkflowHooksSpec | undefined> = THooks extends HostWorkflowHooksSpec\n ? <const K extends keyof THooks & string>(kind: K, payload: Readonly<z.infer<THooks[K]>>) => Promise<void>\n : (\n kind: string,\n payload: Readonly<Record<string, string | number | boolean>>,\n ) => Promise<void>;\n\n/**\n * One **Lua microverse**: a shared built-in Wasm Lua VM, {@link HostScriptSession}s keyed by `scriptId`, and helpers to\n * register scripts and broadcast hook events. Capabilities per script come from the host surface\n * ({@link HostSurfaceCore.pickCapabilities} / {@link HostSurfaceCore.capabilities}). Created via {@link MicroverseLua.create}\n * or {@link createLuaMicroverse}.\n */\nexport class LuaMicroverse<\n THost extends object = object,\n THooks extends HostWorkflowHooksSpec | undefined = InferScriptHooksFromHost<THost>,\n TCapabilities extends CapabilityId = CapabilityId,\n> {\n private readonly runtime: MicroverseRuntime;\n\n private readonly sessions = new Map<string, HostScriptSession<THost, THooks>>();\n\n private readonly host: THost;\n\n private readonly surface: HostSurface<THooks, TCapabilities>;\n\n private readonly envSlotScope: string;\n\n private readonly defaultTimeout: TimeoutPolicy | undefined;\n\n private readonly sharedLuaChunks: readonly string[];\n\n constructor(private readonly config: LuaMicroverseConfig<THost, THooks, TCapabilities>) {\n this.host = config.host;\n this.surface = config.surface;\n this.defaultTimeout = resolveDefaultTimeout(config);\n this.sharedLuaChunks = config.sharedLuaChunks ?? [];\n this.runtime = createWasmMicroverseRuntime(\n this.defaultTimeout !== undefined ? { defaultTimeout: this.defaultTimeout } : {},\n );\n this.envSlotScope = config.envSlotScope ?? 'script';\n }\n\n /** Capability ids declared on the bound host surface. */\n readonly getSurfaceCapabilities = (): readonly TCapabilities[] => this.surface.capabilities;\n\n /**\n * Loads one Lua chunk in an isolated env slot; `scriptId` must be unique within this microverse.\n *\n * @param args.capabilities - Subset of {@link getSurfaceCapabilities}; use `surface.pickCapabilities(…)` at the call site.\n */\n readonly registerScript = async (args: {\n readonly scriptId: string;\n readonly script: string;\n readonly capabilities: readonly TCapabilities[];\n readonly injectLuaChunks?: readonly string[] | undefined;\n }): Promise<void> => {\n const { scriptId, script, capabilities, injectLuaChunks } = args;\n const preludeChunks = [...this.sharedLuaChunks, ...(injectLuaChunks ?? [])];\n if (this.sessions.has(scriptId)) {\n throw new Error(`script already registered: ${scriptId}`);\n }\n const session = new HostScriptSession<THost, THooks>({\n runtime: this.runtime,\n surface: this.surface,\n host: this.host,\n slotKey: createLuaEnvSlotKey(`${this.envSlotScope}:${scriptId}`),\n allowedCapabilities: capabilities,\n defaultTimeout: this.defaultTimeout,\n });\n await session.openSession();\n for (const [index, chunk] of preludeChunks.entries()) {\n const injected = await session.runChunk(chunk);\n if (injected._tag !== 'ok') {\n await session.dispose();\n const detail =\n injected._tag === 'err' && injected.error._tag === 'AdapterError'\n ? injected.error.message\n : JSON.stringify(injected.error);\n const which =\n index < this.sharedLuaChunks.length\n ? `shared Lua prelude [${index}]`\n : `script injectLuaChunks [${index - this.sharedLuaChunks.length}]`;\n throw new Error(`script \"${scriptId}\" failed injecting ${which}: ${detail}`);\n }\n }\n const loaded = await session.runChunk(script);\n if (loaded._tag !== 'ok') {\n await session.dispose();\n const detail =\n loaded._tag === 'err' && loaded.error._tag === 'AdapterError'\n ? loaded.error.message\n : JSON.stringify(loaded.error);\n throw new Error(`script \"${scriptId}\" failed to load: ${detail}`);\n }\n this.sessions.set(scriptId, session);\n };\n\n /** Invokes `on{Kind}` on every registered script with the same payload table (Lua literals only). */\n readonly emitToAllScripts = (async (\n kind: string,\n payload: Readonly<Record<string, string | number | boolean>>,\n ) => {\n const hook = luaGlobalHookName(kind);\n for (const [id, session] of this.sessions) {\n const r = await session.invokeGlobalHookIfPresent(hook, payload);\n if (r._tag !== 'ok') {\n const detail =\n r._tag === 'err' && r.error._tag === 'AdapterError' ? r.error.message : JSON.stringify(r.error);\n throw new Error(`script \"${id}\" failed on emit: ${detail}`);\n }\n }\n }) as EmitToAllScriptsFn<THooks>;\n\n readonly dispose = async (): Promise<void> => {\n for (const s of this.sessions.values()) {\n await s.dispose();\n }\n this.sessions.clear();\n };\n}\n\n/**\n * Creates a {@link LuaMicroverse} with a **built-in** Wasm Lua VM (Wasmoon). Type `host` with\n * {@link TaggedLuaMicroverseHost} so hook emits narrow correctly.\n */\nexport function createLuaMicroverse<\n THost extends object,\n const TSurface extends HostSurfaceCore<CapabilityId>,\n>(config: {\n readonly host: THost;\n readonly surface: TSurface;\n readonly envSlotScope?: string | undefined;\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n readonly defaultTimeoutMs?: number | undefined;\n readonly sharedLuaChunks?: readonly string[] | undefined;\n}): LuaMicroverse<THost, EffectiveScriptHooks<THost, TSurface>, InferSurfaceCapabilitiesFromSurface<TSurface>> {\n type H = EffectiveScriptHooks<THost, TSurface>;\n type C = InferSurfaceCapabilitiesFromSurface<TSurface>;\n return new LuaMicroverse<THost, H, C>({\n host: config.host,\n surface: config.surface as unknown as HostSurface<H, C>,\n envSlotScope: config.envSlotScope,\n defaultTimeout: config.defaultTimeout,\n defaultTimeoutMs: config.defaultTimeoutMs,\n sharedLuaChunks: config.sharedLuaChunks,\n });\n}\n","import { createLuaMicroverse } from './luaMicroverse.js';\n\n/**\n * Plug-and-play **Lua microverse** entry point.\n *\n * A Wasmoon-backed VM is always created for you — pass only `host`, `surface`, and optional timeouts /\n * shared Lua preludes. Define bridges with {@link defineHostSurfaceFor} (`bridge` → `method` → `build`).\n *\n * @example\n * ```ts\n * const microverse = MicroverseLua.create({\n * host: myHost,\n * surface: mySurface,\n * defaultTimeoutMs: 30_000,\n * });\n * await microverse.registerScript({ scriptId: 'ai', script: lua, capabilities: surface.pickCapabilities('demo:tick') });\n * ```\n */\nexport const MicroverseLua = {\n /** Creates a {@link LuaMicroverse} with a built-in Wasm Lua runtime. */\n create: createLuaMicroverse,\n} as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/infrastructure/facade/luaMicroverse.ts","../src/infrastructure/facade/microverseLuaNamespace.ts"],"sourcesContent":["import type { z } from 'zod';\n\nimport {\n HostScriptSession,\n luaGlobalHookName,\n resolveScriptProfile,\n type HostSurface,\n type HostSurfaceCore,\n type HostComponentHooksSpec,\n type ResolvedScriptProfile,\n} from '@microverse.ts/host-surface';\nimport type { CapabilityId } from '@microverse.ts/runtime-capabilities';\nimport {\n createLuaEnvSlotKey,\n createScriptInstanceContext,\n fixedTimeout,\n mergeScriptPropertyBags,\n formatExecutionFailure,\n resolveLuaScriptProfileId,\n resolveLuaScriptSource,\n type ExecutionFailure,\n type LuaScriptDefinition,\n type MicroverseRuntime,\n type ScriptAuditEvent,\n type ScriptPropertyBag,\n type TimeoutPolicy,\n} from '@microverse.ts/runtime-core';\nimport { createWasmMicroverseRuntime } from '@microverse.ts/runtime-wasm';\n\n/** Phantom key: optional on the host **type** so {@link InferScriptHooksFromHost} can recover hook Zod map typing. Never set at runtime. */\ndeclare const SCRIPT_HOOKS_TYPE: unique symbol;\n\nexport type TaggedLuaMicroverseHost<\n THooks extends HostComponentHooksSpec,\n TBase = unknown,\n> = TBase & { readonly [SCRIPT_HOOKS_TYPE]?: THooks };\n\nexport type InferScriptHooksFromHost<THost> = THost extends TaggedLuaMicroverseHost<infer H, unknown>\n ? H extends HostComponentHooksSpec\n ? H\n : undefined\n : undefined;\n\nexport type InferScriptHooksFromSurface<S extends HostSurfaceCore> =\n S extends HostSurfaceCore<CapabilityId> & { readonly componentHooks: infer H extends HostComponentHooksSpec }\n ? H\n : S extends HostSurface<infer H extends HostComponentHooksSpec, CapabilityId>\n ? H\n : undefined;\n\nexport type InferSurfaceCapabilitiesFromSurface<S extends HostSurfaceCore> = S extends HostSurfaceCore<\n infer C extends CapabilityId\n>\n ? C\n : CapabilityId;\n\ntype EffectiveScriptHooks<THost extends object, TSurface extends HostSurfaceCore> = [InferScriptHooksFromHost<THost>] extends [\n undefined,\n]\n ? InferScriptHooksFromSurface<TSurface>\n : InferScriptHooksFromHost<THost>;\n\nexport type LuaMicroverseConfig<\n THost extends object = object,\n THooks extends HostComponentHooksSpec | undefined = InferScriptHooksFromHost<THost>,\n TCapabilities extends CapabilityId = CapabilityId,\n> = {\n readonly host: THost;\n readonly surface: HostSurface<THooks, TCapabilities>;\n readonly envSlotScope?: string | undefined;\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n readonly defaultTimeoutMs?: number | undefined;\n readonly sharedLuaChunks?: readonly string[] | undefined;\n readonly onScriptAudit?: ((event: ScriptAuditEvent) => void) | undefined;\n};\n\nfunction resolveDefaultTimeout<\n THost extends object,\n THooks extends HostComponentHooksSpec | undefined,\n TCapabilities extends CapabilityId,\n>(config: LuaMicroverseConfig<THost, THooks, TCapabilities>): TimeoutPolicy | undefined {\n if (config.defaultTimeout !== undefined) {\n return config.defaultTimeout;\n }\n if (config.defaultTimeoutMs !== undefined) {\n return fixedTimeout(config.defaultTimeoutMs);\n }\n return undefined;\n}\n\ntype EmitToAllInstancesFn<THooks extends HostComponentHooksSpec | undefined> = THooks extends HostComponentHooksSpec\n ? <const K extends keyof THooks & string>(kind: K, payload: Readonly<z.infer<THooks[K]>>) => Promise<void>\n : (\n kind: string,\n payload: Readonly<Record<string, string | number | boolean>>,\n ) => Promise<void>;\n\ntype MountedInstance = {\n readonly session: HostScriptSession<unknown, HostComponentHooksSpec | undefined>;\n};\n\nexport class LuaMicroverse<\n THost extends object = object,\n THooks extends HostComponentHooksSpec | undefined = InferScriptHooksFromHost<THost>,\n TCapabilities extends CapabilityId = CapabilityId,\n> {\n private readonly runtime: MicroverseRuntime;\n\n private readonly definitions = new Map<string, LuaScriptDefinition>();\n\n private readonly instances = new Map<string, MountedInstance>();\n\n private readonly host: THost;\n\n private readonly surface: HostSurface<THooks, TCapabilities>;\n\n private readonly envSlotScope: string;\n\n private readonly defaultTimeout: TimeoutPolicy | undefined;\n\n private readonly sharedLuaChunks: readonly string[];\n\n private readonly onScriptAudit: ((event: ScriptAuditEvent) => void) | undefined;\n\n constructor(private readonly config: LuaMicroverseConfig<THost, THooks, TCapabilities>) {\n this.host = config.host;\n this.surface = config.surface;\n this.defaultTimeout = resolveDefaultTimeout(config);\n this.sharedLuaChunks = config.sharedLuaChunks ?? [];\n this.onScriptAudit = config.onScriptAudit;\n this.runtime = createWasmMicroverseRuntime(\n this.defaultTimeout !== undefined ? { defaultTimeout: this.defaultTimeout } : {},\n );\n this.envSlotScope = config.envSlotScope ?? 'script';\n }\n\n readonly getSurfaceCapabilities = (): readonly TCapabilities[] => this.surface.capabilities;\n\n readonly registerScriptDefinition = (def: LuaScriptDefinition): void => {\n if (this.definitions.has(def.scriptId)) {\n throw new Error(`script definition already registered: ${def.scriptId}`);\n }\n this.definitions.set(def.scriptId, def);\n };\n\n readonly hasScriptDefinition = (scriptId: string): boolean => this.definitions.has(scriptId);\n\n readonly getScriptDefinition = (scriptId: string): LuaScriptDefinition | undefined =>\n this.definitions.get(scriptId);\n\n readonly mountScriptInstance = async (args: {\n readonly instanceId: string;\n readonly scriptId: string;\n readonly script?: string | undefined;\n readonly props?: ScriptPropertyBag | undefined;\n readonly audit?: Readonly<Record<string, string | number | boolean>> | undefined;\n readonly injectLuaChunks?: readonly string[] | undefined;\n /** Overrides {@link LuaScriptDefinition.profileId} for this mount. */\n readonly profileId?: string | undefined;\n /** Lua global for `Type:extend()` when using an inline {@link LuaScriptDefinition.profile}. */\n readonly profileSingleton?: string | undefined;\n }): Promise<void> => {\n const { instanceId, scriptId, audit, injectLuaChunks } = args;\n if (this.instances.has(instanceId)) {\n throw new Error(`script instance already mounted: ${instanceId}`);\n }\n\n let def = this.definitions.get(scriptId);\n if (def === undefined) {\n if (args.script === undefined) {\n throw new Error(`unknown scriptId \"${scriptId}\" and no inline script provided`);\n }\n def = {\n scriptId,\n source: args.script,\n };\n this.definitions.set(scriptId, def);\n } else if (args.script !== undefined) {\n def = { ...def, source: args.script };\n }\n\n const profileId = args.profileId ?? resolveLuaScriptProfileId(def);\n let resolvedProfile: ResolvedScriptProfile | undefined;\n if (def.profile !== undefined) {\n const profileName = profileId ?? args.profileSingleton ?? scriptId;\n resolvedProfile = resolveScriptProfile(\n { [profileName]: def.profile },\n profileName,\n this.surface.getHostSurfaceSpec(),\n );\n } else if (profileId !== undefined) {\n this.surface.getComponentType(profileId);\n }\n\n const profileSingleton =\n args.profileSingleton ??\n (def.profile !== undefined && profileId !== undefined ? profileId : undefined);\n\n const slotKey = createLuaEnvSlotKey(`${this.envSlotScope}:${instanceId}`);\n const scriptContext = createScriptInstanceContext({\n instanceId,\n scriptId,\n slotKey: String(slotKey),\n audit,\n });\n\n const session = new HostScriptSession<THost, THooks>({\n runtime: this.runtime,\n surface: this.surface,\n host: this.host,\n slotKey,\n defaultTimeout: this.defaultTimeout,\n script: scriptContext,\n profileId: resolvedProfile?.name ?? profileId,\n resolvedProfile,\n profileSingleton,\n onScriptAudit: this.onScriptAudit,\n });\n\n try {\n await session.openSession();\n const preludeChunks = [\n ...this.sharedLuaChunks,\n ...(def.injectLuaChunks ?? []),\n ...(injectLuaChunks ?? []),\n ];\n for (const [index, chunk] of preludeChunks.entries()) {\n const injected = await session.runChunk(chunk);\n if (injected._tag !== 'ok') {\n throw new Error(formatRunError(instanceId, `prelude [${index}]`, injected));\n }\n }\n\n const source = await resolveLuaScriptSource(def.source);\n const loaded = await session.runChunk(source);\n if (loaded._tag !== 'ok') {\n throw new Error(formatRunError(instanceId, 'main chunk', loaded));\n }\n\n const mergedProps = mergeScriptPropertyBags(def.defaultProps ?? {}, args.props ?? {});\n await session.setProps(mergedProps);\n const initResult = await session.invokeComponentHook('init');\n if (initResult._tag !== 'ok') {\n throw new Error(formatRunError(instanceId, 'init hook', initResult));\n }\n\n this.instances.set(instanceId, { session });\n this.onScriptAudit?.({ kind: 'mounted', context: scriptContext });\n } catch (e) {\n await session.dispose();\n const message = e instanceof Error ? e.message : String(e);\n this.onScriptAudit?.({\n kind: 'scriptError',\n context: scriptContext,\n phase: 'mount',\n message,\n });\n throw e;\n }\n };\n\n readonly unmountScriptInstance = async (instanceId: string): Promise<void> => {\n const mounted = this.instances.get(instanceId);\n if (mounted === undefined) {\n throw new Error(`script instance not mounted: ${instanceId}`);\n }\n const ctx = mounted.session.context;\n await mounted.session.dispose();\n this.instances.delete(instanceId);\n this.onScriptAudit?.({ kind: 'unmounted', context: ctx });\n };\n\n readonly setInstanceProps = async (instanceId: string, bag: ScriptPropertyBag): Promise<void> => {\n const session = this.requireInstance(instanceId);\n await session.setProps(bag);\n };\n\n readonly patchInstanceProps = async (\n instanceId: string,\n partial: ScriptPropertyBag,\n ): Promise<void> => {\n const session = this.requireInstance(instanceId);\n await session.patchProps(partial);\n };\n\n readonly getInstanceProps = (instanceId: string): Readonly<ScriptPropertyBag> => {\n return this.requireInstance(instanceId).getProps();\n };\n\n readonly flushInstanceProps = async (instanceId: string): Promise<ScriptPropertyBag | null> => {\n return this.requireInstance(instanceId).flushDirtyProps();\n };\n\n readonly getInstance = (instanceId: string): HostScriptSession<THost, THooks> | undefined => {\n return this.instances.get(instanceId)?.session as HostScriptSession<THost, THooks> | undefined;\n };\n\n readonly emitToAllInstances = (async (\n kind: string,\n payload: Readonly<Record<string, string | number | boolean>>,\n ) => {\n const hook = luaGlobalHookName(kind);\n for (const [id, { session }] of this.instances) {\n const r = await session.invokeComponentEventHook(hook, payload);\n if (r._tag !== 'ok') {\n const detail =\n r._tag === 'err' && r.error._tag === 'AdapterError' ? r.error.message : JSON.stringify(r.error);\n throw new Error(`instance \"${id}\" failed on emit: ${detail}`);\n }\n }\n }) as EmitToAllInstancesFn<THooks>;\n\n readonly dispose = async (): Promise<void> => {\n for (const id of [...this.instances.keys()]) {\n await this.unmountScriptInstance(id);\n }\n this.instances.clear();\n };\n\n private requireInstance(instanceId: string): HostScriptSession<THost, THooks> {\n const mounted = this.instances.get(instanceId);\n if (mounted === undefined) {\n throw new Error(`script instance not mounted: ${instanceId}`);\n }\n return mounted.session as HostScriptSession<THost, THooks>;\n }\n}\n\nfunction formatRunError(\n instanceId: string,\n phase: string,\n result: { readonly _tag: 'err'; readonly error: ExecutionFailure },\n): string {\n return `instance \"${instanceId}\" failed ${phase}: ${formatExecutionFailure(result.error)}`;\n}\n\nexport function createLuaMicroverse<\n THost extends object,\n const TSurface extends HostSurfaceCore<CapabilityId>,\n>(config: {\n readonly host: THost;\n readonly surface: TSurface;\n readonly envSlotScope?: string | undefined;\n readonly defaultTimeout?: TimeoutPolicy | undefined;\n readonly defaultTimeoutMs?: number | undefined;\n readonly sharedLuaChunks?: readonly string[] | undefined;\n readonly onScriptAudit?: ((event: ScriptAuditEvent) => void) | undefined;\n}): LuaMicroverse<THost, EffectiveScriptHooks<THost, TSurface>, InferSurfaceCapabilitiesFromSurface<TSurface>> {\n type H = EffectiveScriptHooks<THost, TSurface>;\n type C = InferSurfaceCapabilitiesFromSurface<TSurface>;\n return new LuaMicroverse<THost, H, C>({\n host: config.host,\n surface: config.surface as unknown as HostSurface<H, C>,\n envSlotScope: config.envSlotScope,\n defaultTimeout: config.defaultTimeout,\n defaultTimeoutMs: config.defaultTimeoutMs,\n sharedLuaChunks: config.sharedLuaChunks,\n onScriptAudit: config.onScriptAudit,\n });\n}\n","import { createLuaMicroverse } from './luaMicroverse';\n\n/**\n * Plug-and-play **Lua microverse** entry point.\n *\n * A Wasmoon-backed VM is always created for you — pass only `host`, `surface`, and optional timeouts /\n * shared Lua preludes. Define bridges with {@link defineHostSurfaceFor} (`bridge` → `method` → `build`).\n *\n * @example\n * ```ts\n * const microverse = MicroverseLua.create({\n * host: myHost,\n * surface: mySurface,\n * defaultTimeoutMs: 30_000,\n * });\n * microverse.registerScriptDefinition({ scriptId: 'ai', source: lua });\n * await microverse.mountScriptInstance({ instanceId: 'ai', scriptId: 'ai' });\n * // Lua: local C = MyType:extend()\n * ```\n */\nexport const MicroverseLua = {\n /** Creates a {@link LuaMicroverse} with a built-in Wasm Lua runtime. */\n create: createLuaMicroverse,\n} as const;\n"],"mappings":"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"}
@@ -1,79 +1,68 @@
1
1
  import { z } from 'zod';
2
- import { HostSurface, HostSurfaceCore, HostWorkflowHooksSpec } from '@microverse.ts/host-surface';
2
+ import { HostScriptSession, HostSurface, HostSurfaceCore, HostComponentHooksSpec } from '@microverse.ts/host-surface';
3
3
  import { CapabilityId } from '@microverse.ts/runtime-capabilities';
4
- import { TimeoutPolicy } from '@microverse.ts/runtime-core';
4
+ import { LuaScriptDefinition, ScriptAuditEvent, ScriptPropertyBag, TimeoutPolicy } from '@microverse.ts/runtime-core';
5
5
  /** Phantom key: optional on the host **type** so {@link InferScriptHooksFromHost} can recover hook Zod map typing. Never set at runtime. */
6
6
  declare const SCRIPT_HOOKS_TYPE: unique symbol;
7
- /**
8
- * Intersects `TBase` with an optional phantom field carrying `THooks` for {@link LuaMicroverse} / {@link createLuaMicroverse} inference.
9
- */
10
- export type TaggedLuaMicroverseHost<THooks extends HostWorkflowHooksSpec, TBase = unknown> = TBase & {
7
+ export type TaggedLuaMicroverseHost<THooks extends HostComponentHooksSpec, TBase = unknown> = TBase & {
11
8
  readonly [SCRIPT_HOOKS_TYPE]?: THooks;
12
9
  };
13
- export type InferScriptHooksFromHost<THost> = THost extends TaggedLuaMicroverseHost<infer H, unknown> ? H extends HostWorkflowHooksSpec ? H : undefined : undefined;
10
+ export type InferScriptHooksFromHost<THost> = THost extends TaggedLuaMicroverseHost<infer H, unknown> ? H extends HostComponentHooksSpec ? H : undefined : undefined;
14
11
  export type InferScriptHooksFromSurface<S extends HostSurfaceCore> = S extends HostSurfaceCore<CapabilityId> & {
15
- readonly workflowHooks: infer H extends HostWorkflowHooksSpec;
16
- } ? H : S extends HostSurface<infer H extends HostWorkflowHooksSpec, CapabilityId> ? H : undefined;
12
+ readonly componentHooks: infer H extends HostComponentHooksSpec;
13
+ } ? H : S extends HostSurface<infer H extends HostComponentHooksSpec, CapabilityId> ? H : undefined;
17
14
  export type InferSurfaceCapabilitiesFromSurface<S extends HostSurfaceCore> = S extends HostSurfaceCore<infer C extends CapabilityId> ? C : CapabilityId;
18
15
  type EffectiveScriptHooks<THost extends object, TSurface extends HostSurfaceCore> = [InferScriptHooksFromHost<THost>] extends [
19
16
  undefined
20
17
  ] ? InferScriptHooksFromSurface<TSurface> : InferScriptHooksFromHost<THost>;
21
- export type LuaMicroverseConfig<THost extends object = object, THooks extends HostWorkflowHooksSpec | undefined = InferScriptHooksFromHost<THost>, TCapabilities extends CapabilityId = CapabilityId> = {
18
+ export type LuaMicroverseConfig<THost extends object = object, THooks extends HostComponentHooksSpec | undefined = InferScriptHooksFromHost<THost>, TCapabilities extends CapabilityId = CapabilityId> = {
22
19
  readonly host: THost;
23
- /** From {@link defineHostSurface} / {@link defineHostSurfaceFor}; hooks live on `surface.workflowHooks` when present. */
24
20
  readonly surface: HostSurface<THooks, TCapabilities>;
25
- /** Prefix for internal Lua env slot ids, default `script` (ids look like `script:my-id`). */
26
21
  readonly envSlotScope?: string | undefined;
27
- /** Wall-clock limit per `runChunk` / hook invocation (Wasm adapter + session forwarding). */
28
22
  readonly defaultTimeout?: TimeoutPolicy | undefined;
29
- /**
30
- * Shorthand for {@link defaultTimeout} as `fixedTimeout(ms)`. Ignored when `defaultTimeout` is set.
31
- */
32
23
  readonly defaultTimeoutMs?: number | undefined;
33
- /**
34
- * Lua sources run in **every** script slot after {@link HostScriptSession.openSession} and before that
35
- * script's main chunk. Define shared helpers/libraries here once instead of per {@link registerScript}.
36
- */
37
24
  readonly sharedLuaChunks?: readonly string[] | undefined;
25
+ readonly onScriptAudit?: ((event: ScriptAuditEvent) => void) | undefined;
38
26
  };
39
- type EmitToAllScriptsFn<THooks extends HostWorkflowHooksSpec | undefined> = THooks extends HostWorkflowHooksSpec ? <const K extends keyof THooks & string>(kind: K, payload: Readonly<z.infer<THooks[K]>>) => Promise<void> : (kind: string, payload: Readonly<Record<string, string | number | boolean>>) => Promise<void>;
40
- /**
41
- * One **Lua microverse**: a shared built-in Wasm Lua VM, {@link HostScriptSession}s keyed by `scriptId`, and helpers to
42
- * register scripts and broadcast hook events. Capabilities per script come from the host surface
43
- * ({@link HostSurfaceCore.pickCapabilities} / {@link HostSurfaceCore.capabilities}). Created via {@link MicroverseLua.create}
44
- * or {@link createLuaMicroverse}.
45
- */
46
- export declare class LuaMicroverse<THost extends object = object, THooks extends HostWorkflowHooksSpec | undefined = InferScriptHooksFromHost<THost>, TCapabilities extends CapabilityId = CapabilityId> {
27
+ type EmitToAllInstancesFn<THooks extends HostComponentHooksSpec | undefined> = THooks extends HostComponentHooksSpec ? <const K extends keyof THooks & string>(kind: K, payload: Readonly<z.infer<THooks[K]>>) => Promise<void> : (kind: string, payload: Readonly<Record<string, string | number | boolean>>) => Promise<void>;
28
+ export declare class LuaMicroverse<THost extends object = object, THooks extends HostComponentHooksSpec | undefined = InferScriptHooksFromHost<THost>, TCapabilities extends CapabilityId = CapabilityId> {
47
29
  private readonly config;
48
30
  private readonly runtime;
49
- private readonly sessions;
31
+ private readonly definitions;
32
+ private readonly instances;
50
33
  private readonly host;
51
34
  private readonly surface;
52
35
  private readonly envSlotScope;
53
36
  private readonly defaultTimeout;
54
37
  private readonly sharedLuaChunks;
38
+ private readonly onScriptAudit;
55
39
  constructor(config: LuaMicroverseConfig<THost, THooks, TCapabilities>);
56
- /** Capability ids declared on the bound host surface. */
57
40
  readonly getSurfaceCapabilities: () => readonly TCapabilities[];
58
- /**
59
- * Loads one Lua chunk in an isolated env slot; `scriptId` must be unique within this microverse.
60
- *
61
- * @param args.capabilities - Subset of {@link getSurfaceCapabilities}; use `surface.pickCapabilities(…)` at the call site.
62
- */
63
- readonly registerScript: (args: {
41
+ readonly registerScriptDefinition: (def: LuaScriptDefinition) => void;
42
+ readonly hasScriptDefinition: (scriptId: string) => boolean;
43
+ readonly getScriptDefinition: (scriptId: string) => LuaScriptDefinition | undefined;
44
+ readonly mountScriptInstance: (args: {
45
+ readonly instanceId: string;
64
46
  readonly scriptId: string;
65
- readonly script: string;
66
- readonly capabilities: readonly TCapabilities[];
47
+ readonly script?: string | undefined;
48
+ readonly props?: ScriptPropertyBag | undefined;
49
+ readonly audit?: Readonly<Record<string, string | number | boolean>> | undefined;
67
50
  readonly injectLuaChunks?: readonly string[] | undefined;
51
+ /** Overrides {@link LuaScriptDefinition.profileId} for this mount. */
52
+ readonly profileId?: string | undefined;
53
+ /** Lua global for `Type:extend()` when using an inline {@link LuaScriptDefinition.profile}. */
54
+ readonly profileSingleton?: string | undefined;
68
55
  }) => Promise<void>;
69
- /** Invokes `on{Kind}` on every registered script with the same payload table (Lua literals only). */
70
- readonly emitToAllScripts: EmitToAllScriptsFn<THooks>;
56
+ readonly unmountScriptInstance: (instanceId: string) => Promise<void>;
57
+ readonly setInstanceProps: (instanceId: string, bag: ScriptPropertyBag) => Promise<void>;
58
+ readonly patchInstanceProps: (instanceId: string, partial: ScriptPropertyBag) => Promise<void>;
59
+ readonly getInstanceProps: (instanceId: string) => Readonly<ScriptPropertyBag>;
60
+ readonly flushInstanceProps: (instanceId: string) => Promise<ScriptPropertyBag | null>;
61
+ readonly getInstance: (instanceId: string) => HostScriptSession<THost, THooks> | undefined;
62
+ readonly emitToAllInstances: EmitToAllInstancesFn<THooks>;
71
63
  readonly dispose: () => Promise<void>;
64
+ private requireInstance;
72
65
  }
73
- /**
74
- * Creates a {@link LuaMicroverse} with a **built-in** Wasm Lua VM (Wasmoon). Type `host` with
75
- * {@link TaggedLuaMicroverseHost} so hook emits narrow correctly.
76
- */
77
66
  export declare function createLuaMicroverse<THost extends object, const TSurface extends HostSurfaceCore<CapabilityId>>(config: {
78
67
  readonly host: THost;
79
68
  readonly surface: TSurface;
@@ -81,6 +70,7 @@ export declare function createLuaMicroverse<THost extends object, const TSurface
81
70
  readonly defaultTimeout?: TimeoutPolicy | undefined;
82
71
  readonly defaultTimeoutMs?: number | undefined;
83
72
  readonly sharedLuaChunks?: readonly string[] | undefined;
73
+ readonly onScriptAudit?: ((event: ScriptAuditEvent) => void) | undefined;
84
74
  }): LuaMicroverse<THost, EffectiveScriptHooks<THost, TSurface>, InferSurfaceCapabilitiesFromSurface<TSurface>>;
85
75
  export {};
86
76
  //# sourceMappingURL=luaMicroverse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"luaMicroverse.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/facade/luaMicroverse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"luaMicroverse.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/facade/luaMicroverse.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { createLuaMicroverse } from './luaMicroverse.js';
1
+ import { createLuaMicroverse } from './luaMicroverse';
2
2
  /**
3
3
  * Plug-and-play **Lua microverse** entry point.
4
4
  *
@@ -12,7 +12,9 @@ import { createLuaMicroverse } from './luaMicroverse.js';
12
12
  * surface: mySurface,
13
13
  * defaultTimeoutMs: 30_000,
14
14
  * });
15
- * await microverse.registerScript({ scriptId: 'ai', script: lua, capabilities: surface.pickCapabilities('demo:tick') });
15
+ * microverse.registerScriptDefinition({ scriptId: 'ai', source: lua });
16
+ * await microverse.mountScriptInstance({ instanceId: 'ai', scriptId: 'ai' });
17
+ * // Lua: local C = MyType:extend()
16
18
  * ```
17
19
  */
18
20
  export declare const MicroverseLua: {
@@ -1 +1 @@
1
- {"version":3,"file":"microverseLuaNamespace.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/facade/microverseLuaNamespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa;IACxB,wEAAwE;;CAEhE,CAAC"}
1
+ {"version":3,"file":"microverseLuaNamespace.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/facade/microverseLuaNamespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa;IACxB,wEAAwE;;CAEhE,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@microverse.ts/microverse-lua",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
7
- "description": "Plug-and-play Lua microverse facade: Wasm VM, MicroverseLua, and re-exports for host surfaces and bridges.",
7
+ "description": "Main entry for Microverse Lua: MicroverseLua.create (Wasm sandbox, mounts, events) and defineHostSurfaceFor—re-exports the stack.",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/QADRAX/Microverse.ts.git",
@@ -30,14 +30,14 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "zod": "^3.24.0",
33
- "@microverse.ts/host-surface": "0.1.0",
34
- "@microverse.ts/runtime-bridge": "0.1.0",
35
- "@microverse.ts/runtime-capabilities": "0.1.0",
36
- "@microverse.ts/runtime-core": "0.1.0",
37
- "@microverse.ts/runtime-lua": "0.1.0",
38
- "@microverse.ts/runtime-wasm": "0.1.0",
39
- "@microverse.ts/runtime-zod": "0.1.0",
40
- "@microverse.ts/shared": "0.1.0"
33
+ "@microverse.ts/host-surface": "0.3.0",
34
+ "@microverse.ts/runtime-bridge": "0.3.0",
35
+ "@microverse.ts/runtime-capabilities": "0.3.0",
36
+ "@microverse.ts/runtime-core": "0.3.0",
37
+ "@microverse.ts/runtime-lua": "0.3.0",
38
+ "@microverse.ts/runtime-wasm": "0.3.0",
39
+ "@microverse.ts/runtime-zod": "0.3.0",
40
+ "@microverse.ts/shared": "0.3.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "typescript": "^5.8.3",