@hypen-space/core 0.4.31 → 0.4.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +73 -2
- package/dist/app.js +112 -9
- package/dist/app.js.map +6 -5
- package/dist/components/builtin.js +112 -9
- package/dist/components/builtin.js.map +6 -5
- package/dist/context.d.ts +8 -0
- package/dist/context.js +6 -2
- package/dist/context.js.map +3 -3
- package/dist/datasource.d.ts +168 -0
- package/dist/discovery.js +114 -9
- package/dist/discovery.js.map +7 -6
- package/dist/disposable.js +6 -2
- package/dist/disposable.js.map +2 -2
- package/dist/engine.browser.d.ts +15 -0
- package/dist/engine.browser.js +19 -2
- package/dist/engine.browser.js.map +3 -3
- package/dist/engine.d.ts +22 -0
- package/dist/engine.js +37 -3
- package/dist/engine.js.map +3 -3
- package/dist/events.js +6 -2
- package/dist/events.js.map +2 -2
- package/dist/index.browser.js +295 -179
- package/dist/index.browser.js.map +9 -8
- package/dist/index.d.ts +3 -1
- package/dist/index.js +298 -179
- package/dist/index.js.map +10 -9
- package/dist/loader.js +6 -2
- package/dist/loader.js.map +2 -2
- package/dist/logger.js +6 -2
- package/dist/logger.js.map +2 -2
- package/dist/plugin.js +6 -2
- package/dist/plugin.js.map +2 -2
- package/dist/remote/client.js +6 -2
- package/dist/remote/client.js.map +2 -2
- package/dist/remote/index.js +152 -11
- package/dist/remote/index.js.map +9 -8
- package/dist/remote/server.js +152 -11
- package/dist/remote/server.js.map +9 -8
- package/dist/renderer.js +6 -2
- package/dist/renderer.js.map +2 -2
- package/dist/resolver.js +6 -2
- package/dist/resolver.js.map +2 -2
- package/dist/router.d.ts +9 -0
- package/dist/router.js +186 -18
- package/dist/router.js.map +6 -5
- package/dist/state.js +13 -6
- package/dist/state.js.map +3 -3
- package/package.json +1 -1
- package/src/app.ts +121 -4
- package/src/context.ts +10 -2
- package/src/datasource.ts +252 -0
- package/src/discovery.ts +2 -0
- package/src/engine.browser.ts +30 -0
- package/src/engine.ts +56 -1
- package/src/index.ts +16 -0
- package/src/managed-router.ts +3 -0
- package/src/remote/server.ts +11 -2
- package/src/router.ts +36 -10
- package/src/state.ts +10 -3
- package/wasm-browser/README.md +10 -10
- package/wasm-browser/hypen_engine.d.ts +368 -131
- package/wasm-browser/hypen_engine.js +896 -645
- package/wasm-browser/hypen_engine_bg.wasm +0 -0
- package/wasm-browser/hypen_engine_bg.wasm.d.ts +20 -13
- package/wasm-browser/package.json +1 -1
- package/wasm-node/README.md +10 -10
- package/wasm-node/hypen_engine.d.ts +318 -89
- package/wasm-node/hypen_engine.js +832 -613
- package/wasm-node/hypen_engine_bg.wasm +0 -0
- package/wasm-node/hypen_engine_bg.wasm.d.ts +20 -13
- package/wasm-node/package.json +1 -1
|
Binary file
|
|
@@ -2,29 +2,36 @@
|
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
export const memory: WebAssembly.Memory;
|
|
4
4
|
export const __wbg_wasmengine_free: (a: number, b: number) => void;
|
|
5
|
+
export const main: () => void;
|
|
6
|
+
export const parseToJson: (a: number, b: number) => [number, number, number, number];
|
|
7
|
+
export const patchesToJson: (a: any) => [number, number, number, number];
|
|
8
|
+
export const wasmengine_clearTree: (a: number) => void;
|
|
9
|
+
export const wasmengine_currentState: (a: number) => any;
|
|
10
|
+
export const wasmengine_debugParseComponent: (a: number, b: number, c: number) => [number, number, number, number];
|
|
11
|
+
export const wasmengine_dispatchAction: (a: number, b: number, c: number, d: any) => [number, number];
|
|
12
|
+
export const wasmengine_getRevision: (a: number) => bigint;
|
|
5
13
|
export const wasmengine_new: () => number;
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
14
|
+
export const wasmengine_onAction: (a: number, b: number, c: number, d: any) => void;
|
|
15
|
+
export const wasmengine_onDataSourceAction: (a: number, b: any) => void;
|
|
8
16
|
export const wasmengine_registerPrimitive: (a: number, b: number, c: number) => void;
|
|
9
|
-
export const
|
|
17
|
+
export const wasmengine_removeContext: (a: number, b: number, c: number) => void;
|
|
10
18
|
export const wasmengine_renderInto: (a: number, b: number, c: number, d: number, e: number, f: any) => [number, number];
|
|
19
|
+
export const wasmengine_renderLazyComponent: (a: number, b: number, c: number) => [number, number];
|
|
20
|
+
export const wasmengine_reset: (a: number) => void;
|
|
21
|
+
export const wasmengine_setComponentResolver: (a: number, b: any) => void;
|
|
22
|
+
export const wasmengine_setContext: (a: number, b: number, c: number, d: any) => [number, number];
|
|
23
|
+
export const wasmengine_setModule: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any) => [number, number];
|
|
24
|
+
export const wasmengine_setRenderCallback: (a: number, b: any) => void;
|
|
25
|
+
export const wasmengine_treeSize: (a: number) => number;
|
|
11
26
|
export const wasmengine_updateState: (a: number, b: any) => [number, number];
|
|
12
27
|
export const wasmengine_updateStateSparse: (a: number, b: any, c: any) => [number, number];
|
|
13
|
-
export const
|
|
14
|
-
export const wasmengine_onAction: (a: number, b: number, c: number, d: any) => void;
|
|
15
|
-
export const wasmengine_clearTree: (a: number) => void;
|
|
16
|
-
export const wasmengine_debugParseComponent: (a: number, b: number, c: number) => [number, number, number, number];
|
|
17
|
-
export const wasmengine_setModule: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any) => [number, number];
|
|
18
|
-
export const wasmengine_getRevision: (a: number) => bigint;
|
|
19
|
-
export const patchesToJson: (a: any) => [number, number, number, number];
|
|
20
|
-
export const parseToJson: (a: number, b: number) => [number, number, number, number];
|
|
21
|
-
export const main: () => void;
|
|
28
|
+
export const wasmengine_validate: (a: number) => any;
|
|
22
29
|
export const wasmengine_renderSource: (a: number, b: number, c: number) => [number, number];
|
|
23
30
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
24
31
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
25
32
|
export const __wbindgen_exn_store: (a: number) => void;
|
|
26
33
|
export const __externref_table_alloc: () => number;
|
|
27
|
-
export const
|
|
34
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
28
35
|
export const __externref_table_dealloc: (a: number) => void;
|
|
29
36
|
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
30
37
|
export const __wbindgen_start: () => void;
|
package/wasm-node/README.md
CHANGED
|
@@ -11,7 +11,7 @@ The core reactive rendering engine for Hypen, written in Rust. Compiles to WASM
|
|
|
11
11
|
### Rust
|
|
12
12
|
|
|
13
13
|
```rust
|
|
14
|
-
use hypen_engine::{Engine,
|
|
14
|
+
use hypen_engine::{Engine, ast_to_ir_node};
|
|
15
15
|
use hypen_parser::parse_component;
|
|
16
16
|
use serde_json::json;
|
|
17
17
|
|
|
@@ -21,7 +21,7 @@ engine.set_render_callback(|patches| {
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
let ast = parse_component(r#"Column { Text("Hello") }"#)?;
|
|
24
|
-
engine.
|
|
24
|
+
engine.render_ir_node(&ast_to_ir_node(&ast));
|
|
25
25
|
engine.update_state(json!({ "count": 42 }));
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -120,7 +120,7 @@ use serde_json::json;
|
|
|
120
120
|
let mut engine = Engine::new();
|
|
121
121
|
|
|
122
122
|
// Register a custom component
|
|
123
|
-
// Note: In practice, you'd typically parse Hypen DSL with
|
|
123
|
+
// Note: In practice, you'd typically parse Hypen DSL with ast_to_ir_node
|
|
124
124
|
engine.register_component(Component::new("Greeting", |props: IndexMap<String, serde_json::Value>| {
|
|
125
125
|
Element::new("Text")
|
|
126
126
|
.with_prop("text", Value::Binding(
|
|
@@ -400,7 +400,7 @@ The engine integrates with the Hypen parser from `../parser`:
|
|
|
400
400
|
|
|
401
401
|
```rust
|
|
402
402
|
use hypen_parser::parse_component;
|
|
403
|
-
use hypen_engine::
|
|
403
|
+
use hypen_engine::ast_to_ir_node;
|
|
404
404
|
|
|
405
405
|
let source = r#"
|
|
406
406
|
Column {
|
|
@@ -410,14 +410,14 @@ let source = r#"
|
|
|
410
410
|
"#;
|
|
411
411
|
|
|
412
412
|
let ast = parse_component(source)?;
|
|
413
|
-
let
|
|
414
|
-
engine.
|
|
413
|
+
let ir_node = ast_to_ir_node(&ast); // Convert AST → IR
|
|
414
|
+
engine.render_ir_node(&ir_node);
|
|
415
415
|
```
|
|
416
416
|
|
|
417
417
|
### Full Example with Parser
|
|
418
418
|
|
|
419
419
|
```rust
|
|
420
|
-
use hypen_engine::{Engine,
|
|
420
|
+
use hypen_engine::{Engine, ast_to_ir_node};
|
|
421
421
|
use hypen_parser::parse_component;
|
|
422
422
|
use serde_json::json;
|
|
423
423
|
|
|
@@ -438,10 +438,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
438
438
|
"#;
|
|
439
439
|
|
|
440
440
|
let ast = parse_component(source)?;
|
|
441
|
-
let
|
|
441
|
+
let ir_node = ast_to_ir_node(&ast);
|
|
442
442
|
|
|
443
443
|
// Render
|
|
444
|
-
engine.
|
|
444
|
+
engine.render_ir_node(&ir_node);
|
|
445
445
|
|
|
446
446
|
// Update state
|
|
447
447
|
engine.update_state(json!({"count": 42}));
|
|
@@ -557,7 +557,7 @@ impl Engine {
|
|
|
557
557
|
|
|
558
558
|
```rust
|
|
559
559
|
pub use engine::Engine;
|
|
560
|
-
pub use ir::{
|
|
560
|
+
pub use ir::{ast_to_ir_node, Element, IRNode, Value};
|
|
561
561
|
pub use lifecycle::{Module, ModuleInstance};
|
|
562
562
|
pub use reconcile::Patch;
|
|
563
563
|
pub use state::StateChange;
|
|
@@ -1,98 +1,327 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* The main Hypen engine interface for JavaScript/WASM runtimes.
|
|
6
|
+
*
|
|
7
|
+
* `WasmEngine` manages the full lifecycle of a Hypen UI: parsing DSL source,
|
|
8
|
+
* maintaining the virtual tree, tracking reactive dependencies, and emitting
|
|
9
|
+
* minimal patches when state changes. It runs in a single-threaded WASM
|
|
10
|
+
* environment (browsers, Node.js, Bun, Deno).
|
|
11
|
+
*
|
|
12
|
+
* # Quick Start
|
|
13
|
+
*
|
|
14
|
+
* ```js
|
|
15
|
+
* import { WasmEngine } from "@hypen-space/core";
|
|
16
|
+
*
|
|
17
|
+
* const engine = new WasmEngine();
|
|
18
|
+
*
|
|
19
|
+
* // 1. Register primitives so the engine doesn't try to resolve them as components
|
|
20
|
+
* engine.registerPrimitive("Text");
|
|
21
|
+
* engine.registerPrimitive("Column");
|
|
22
|
+
*
|
|
23
|
+
* // 2. Receive patches via callback
|
|
24
|
+
* engine.setRenderCallback((patches) => {
|
|
25
|
+
* for (const patch of patches) {
|
|
26
|
+
* applyPatch(patch); // Create, SetProp, Insert, Remove, etc.
|
|
27
|
+
* }
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // 3. Optionally set up a module for stateful UI
|
|
31
|
+
* engine.setModule("Counter", ["increment"], ["count"], { count: 0 });
|
|
32
|
+
*
|
|
33
|
+
* // 4. Render DSL source — patches are emitted via the callback
|
|
34
|
+
* engine.renderSource('Column { Text("Count: ${state.count}") }');
|
|
35
|
+
*
|
|
36
|
+
* // 5. Update state — only affected nodes are re-rendered
|
|
37
|
+
* engine.updateState({ count: 1 });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* # Patch Protocol
|
|
41
|
+
*
|
|
42
|
+
* All UI mutations are expressed as [`Patch`] values emitted through the render
|
|
43
|
+
* callback. Patches use camelCase field names for direct JavaScript consumption.
|
|
44
|
+
* See [`Patch`] for the full variant list and field documentation.
|
|
45
|
+
*
|
|
46
|
+
* # Component Resolution
|
|
47
|
+
*
|
|
48
|
+
* Custom components (anything not registered as a primitive) are resolved lazily
|
|
49
|
+
* via the component resolver callback set with [`set_component_resolver`]. The
|
|
50
|
+
* resolver receives `(componentName, contextPath)` and should return
|
|
51
|
+
* `{ source: string, path: string }` or `null`.
|
|
52
|
+
*
|
|
53
|
+
* # Revision Tracking
|
|
54
|
+
*
|
|
55
|
+
* Every render cycle (initial render or state update that produces patches)
|
|
56
|
+
* increments the revision counter. Use [`get_revision`] to detect stale state
|
|
57
|
+
* in async workflows.
|
|
5
58
|
*/
|
|
6
|
-
export
|
|
59
|
+
export class WasmEngine {
|
|
60
|
+
free(): void;
|
|
61
|
+
[Symbol.dispose](): void;
|
|
62
|
+
/**
|
|
63
|
+
* Remove all nodes from the instance tree without emitting Remove patches.
|
|
64
|
+
*
|
|
65
|
+
* Use this when tearing down the UI entirely (e.g. navigating away or
|
|
66
|
+
* switching samples). The renderer is responsible for clearing its own
|
|
67
|
+
* DOM/canvas state separately.
|
|
68
|
+
*/
|
|
69
|
+
clearTree(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Return a JSON snapshot of the active module's current state.
|
|
72
|
+
*
|
|
73
|
+
* Returns `null` (as a `JsValue`) if no module is set.
|
|
74
|
+
* Useful for debugging and DevTools integration.
|
|
75
|
+
*/
|
|
76
|
+
currentState(): any;
|
|
77
|
+
/**
|
|
78
|
+
* Parse a component and return a human-readable debug string.
|
|
79
|
+
*
|
|
80
|
+
* Intended for development tooling only — the output format is not stable.
|
|
81
|
+
*/
|
|
82
|
+
debugParseComponent(source: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* Dispatch a named action, invoking the registered handler (if any).
|
|
85
|
+
*
|
|
86
|
+
* Actions are the primary way UI events flow from the renderer back to
|
|
87
|
+
* application logic. In Hypen DSL, buttons reference actions like
|
|
88
|
+
* `Button("@actions.submit")` — the renderer maps clicks to
|
|
89
|
+
* `engine.dispatchAction("submit", payload)`.
|
|
90
|
+
*
|
|
91
|
+
* # Arguments
|
|
92
|
+
* * `name` — Action name (e.g. `"submit"`, `"increment"`)
|
|
93
|
+
* * `payload` — Optional JS value passed to the handler. `null`/`undefined` are treated as no payload.
|
|
94
|
+
*
|
|
95
|
+
* # Errors
|
|
96
|
+
*
|
|
97
|
+
* Returns an error if the payload cannot be deserialized. Does **not** error
|
|
98
|
+
* if no handler is registered (the action is silently dropped).
|
|
99
|
+
*/
|
|
100
|
+
dispatchAction(name: string, payload: any): void;
|
|
101
|
+
/**
|
|
102
|
+
* Get the current revision number.
|
|
103
|
+
*
|
|
104
|
+
* Starts at 0 and increments by 1 for each render cycle that produces
|
|
105
|
+
* patches. Useful for cache invalidation and detecting stale async results.
|
|
106
|
+
*/
|
|
107
|
+
getRevision(): bigint;
|
|
108
|
+
/**
|
|
109
|
+
* Create a new engine instance with an empty tree and no module.
|
|
110
|
+
*
|
|
111
|
+
* After construction, you typically:
|
|
112
|
+
* 1. Register primitives with [`register_primitive`]
|
|
113
|
+
* 2. Set a render callback with [`set_render_callback`]
|
|
114
|
+
* 3. Optionally set a component resolver with [`set_component_resolver`]
|
|
115
|
+
* 4. Optionally initialize a module with [`set_module`]
|
|
116
|
+
* 5. Render source with [`render_source`]
|
|
117
|
+
*/
|
|
118
|
+
constructor();
|
|
119
|
+
/**
|
|
120
|
+
* Register a JavaScript function as the handler for a named action.
|
|
121
|
+
*
|
|
122
|
+
* When [`dispatch_action`] is called with a matching name, the handler
|
|
123
|
+
* receives a serialized [`Action`] object with `{ name, payload }`.
|
|
124
|
+
*
|
|
125
|
+
* Registering a handler for the same name replaces the previous one.
|
|
126
|
+
*/
|
|
127
|
+
onAction(action_name: string, handler: Function): void;
|
|
128
|
+
/**
|
|
129
|
+
* Register a handler for data source actions.
|
|
130
|
+
*
|
|
131
|
+
* When [`dispatch_action`] is called with a name like `"spacetime.sendMessage"`
|
|
132
|
+
* and no explicit action handler is registered for that name, the engine checks
|
|
133
|
+
* if the prefix (`"spacetime"`) is a registered data source. If so, it calls
|
|
134
|
+
* this handler with `{ provider, method, payload }`.
|
|
135
|
+
*
|
|
136
|
+
* This enables `@actions.spacetime.sendMessage` in DSL to automatically route
|
|
137
|
+
* to the appropriate data source plugin without manual handler registration.
|
|
138
|
+
*/
|
|
139
|
+
onDataSourceAction(handler: Function): void;
|
|
140
|
+
/**
|
|
141
|
+
* Register a primitive element (like Text, Button, etc.) to skip component resolution
|
|
142
|
+
* This prevents unnecessary resolver calls for built-in DOM elements
|
|
143
|
+
*/
|
|
144
|
+
registerPrimitive(name: string): void;
|
|
145
|
+
/**
|
|
146
|
+
* Remove a data source context entirely.
|
|
147
|
+
*
|
|
148
|
+
* Drops the provider's state and re-renders bound nodes (they resolve to `null`).
|
|
149
|
+
*/
|
|
150
|
+
removeContext(name: string): void;
|
|
151
|
+
/**
|
|
152
|
+
* Render a component into a specific parent node (subtree rendering)
|
|
153
|
+
* This is used for lazy routing where components are rendered on-demand into route containers
|
|
154
|
+
*
|
|
155
|
+
* # Arguments
|
|
156
|
+
* * `source` - The Hypen DSL source to parse and render
|
|
157
|
+
* * `parent_node_id_str` - The serialized node ID string of the parent element
|
|
158
|
+
* * `state_js` - The state to use for rendering (as JsValue)
|
|
159
|
+
*/
|
|
160
|
+
renderInto(source: string, parent_node_id_str: string, state_js: any): void;
|
|
161
|
+
/**
|
|
162
|
+
* Render a component source on-demand (for lazy-loaded routes).
|
|
163
|
+
*
|
|
164
|
+
* Equivalent to calling [`render_source`] — the source is parsed as a full
|
|
165
|
+
* document and replaces the current tree.
|
|
166
|
+
*/
|
|
167
|
+
renderLazyComponent(source: string): void;
|
|
168
|
+
/**
|
|
169
|
+
* Parse and render Hypen DSL source code, emitting patches via the render callback.
|
|
170
|
+
*
|
|
171
|
+
* Supports full document syntax including `import` statements. Imports are
|
|
172
|
+
* resolved synchronously through the component resolver callback (if set).
|
|
173
|
+
*
|
|
174
|
+
* This performs a **full reconciliation** — the existing tree is diffed against
|
|
175
|
+
* the new IR and minimal patches are emitted. Calling this multiple times with
|
|
176
|
+
* different source replaces the previous UI.
|
|
177
|
+
*
|
|
178
|
+
* # Errors
|
|
179
|
+
*
|
|
180
|
+
* Returns a `JsValue` string error if the source fails to parse.
|
|
181
|
+
*/
|
|
182
|
+
renderSource(source: string): void;
|
|
183
|
+
/**
|
|
184
|
+
* Fully reset the engine to its initial empty state.
|
|
185
|
+
*
|
|
186
|
+
* Clears the tree, module, dependencies, scheduler, action handlers,
|
|
187
|
+
* component registry, and resets the revision to 0. The render callback
|
|
188
|
+
* and component resolver are preserved.
|
|
189
|
+
*/
|
|
190
|
+
reset(): void;
|
|
191
|
+
/**
|
|
192
|
+
* Set the component resolver callback
|
|
193
|
+
* The resolver receives (componentName, contextPath) and should return
|
|
194
|
+
* { source: string, path: string } or null
|
|
195
|
+
*
|
|
196
|
+
* contextPath is the path of the component that's referencing this component
|
|
197
|
+
* The returned path should be the resolved absolute path to the component file
|
|
198
|
+
*/
|
|
199
|
+
setComponentResolver(resolver: Function): void;
|
|
200
|
+
/**
|
|
201
|
+
* Set (or replace) a named data source context.
|
|
202
|
+
*
|
|
203
|
+
* Registers the provider in the dependency graph (if not already known),
|
|
204
|
+
* stores the data, and re-renders every node bound to `$name.*`.
|
|
205
|
+
* Sparse merging (if needed) should happen at the SDK layer before
|
|
206
|
+
* calling this method with the merged object.
|
|
207
|
+
*
|
|
208
|
+
* # Example (JS)
|
|
209
|
+
* ```js
|
|
210
|
+
* engine.setContext("spacetime", {
|
|
211
|
+
* message: [{ id: 1, text: "Hello" }, { id: 2, text: "World" }],
|
|
212
|
+
* user: [{ id: 1, name: "Alice", online: true }]
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
setContext(name: string, data_js: any): void;
|
|
217
|
+
/**
|
|
218
|
+
* Initialize (or replace) the active module with the given configuration.
|
|
219
|
+
*
|
|
220
|
+
* A module provides stateful context for `${state.xxx}` bindings in the DSL.
|
|
221
|
+
* Only one module is active at a time — calling this again replaces it.
|
|
222
|
+
*
|
|
223
|
+
* # Arguments
|
|
224
|
+
* * `name` — Module identifier (e.g. `"Counter"`, `"ProfilePage"`)
|
|
225
|
+
* * `actions` — List of action names this module handles
|
|
226
|
+
* * `state_keys` — List of top-level state keys (used for validation)
|
|
227
|
+
* * `initial_state` — The starting state as a JS object
|
|
228
|
+
*
|
|
229
|
+
* # Errors
|
|
230
|
+
*
|
|
231
|
+
* Returns an error if `initial_state` cannot be deserialized as JSON.
|
|
232
|
+
*/
|
|
233
|
+
setModule(name: string, actions: string[], state_keys: string[], initial_state: any): void;
|
|
234
|
+
/**
|
|
235
|
+
* Set the callback that receives UI patches after each render cycle.
|
|
236
|
+
*
|
|
237
|
+
* The callback is invoked with a single argument: a JavaScript array of
|
|
238
|
+
* [`Patch`] objects. Each patch describes one atomic DOM operation (Create,
|
|
239
|
+
* SetProp, SetText, Insert, Move, Remove, RemoveProp).
|
|
240
|
+
*
|
|
241
|
+
* The callback is called synchronously during `renderSource()`, `updateState()`,
|
|
242
|
+
* `updateStateSparse()`, and `renderInto()`.
|
|
243
|
+
*
|
|
244
|
+
* # Example (JS)
|
|
245
|
+
* ```js
|
|
246
|
+
* engine.setRenderCallback((patches) => {
|
|
247
|
+
* for (const p of patches) {
|
|
248
|
+
* switch (p.type) {
|
|
249
|
+
* case "create": createElement(p.id, p.elementType, p.props); break;
|
|
250
|
+
* case "setProp": setProperty(p.id, p.name, p.value); break;
|
|
251
|
+
* case "insert": insertChild(p.parentId, p.id, p.beforeId); break;
|
|
252
|
+
* // ...
|
|
253
|
+
* }
|
|
254
|
+
* }
|
|
255
|
+
* });
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
setRenderCallback(callback: Function): void;
|
|
259
|
+
/**
|
|
260
|
+
* Return the total number of nodes currently in the instance tree.
|
|
261
|
+
*
|
|
262
|
+
* Useful for debugging, performance monitoring, and DevTools.
|
|
263
|
+
*/
|
|
264
|
+
treeSize(): number;
|
|
265
|
+
/**
|
|
266
|
+
* Apply a state patch and re-render affected nodes.
|
|
267
|
+
*
|
|
268
|
+
* The `state_patch` is a JavaScript object whose keys are merged into the
|
|
269
|
+
* current module state (deep merge). Only nodes whose bindings reference
|
|
270
|
+
* changed paths are re-rendered, producing minimal patches.
|
|
271
|
+
*
|
|
272
|
+
* # Example (JS)
|
|
273
|
+
* ```js
|
|
274
|
+
* // Updates state.user.name and state.count, re-renders bound nodes
|
|
275
|
+
* engine.updateState({ user: { name: "Bob" }, count: 42 });
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
278
|
+
* # Errors
|
|
279
|
+
*
|
|
280
|
+
* Returns an error if `state_patch` cannot be deserialized as JSON.
|
|
281
|
+
*/
|
|
282
|
+
updateState(state_patch: any): void;
|
|
283
|
+
/**
|
|
284
|
+
* Apply a sparse state update using explicit path-value pairs.
|
|
285
|
+
*
|
|
286
|
+
* More efficient than [`update_state`] for large state objects when only a
|
|
287
|
+
* few deeply-nested paths changed, because it avoids a full deep-merge.
|
|
288
|
+
*
|
|
289
|
+
* # Arguments
|
|
290
|
+
* * `paths_js` — JS array of dot-separated paths that changed (e.g. `["user.name", "count"]`)
|
|
291
|
+
* * `values_js` — JS object mapping each path to its new value (e.g. `{ "user.name": "Bob", "count": 42 }`)
|
|
292
|
+
*
|
|
293
|
+
* # Errors
|
|
294
|
+
*
|
|
295
|
+
* Returns an error if either argument cannot be deserialized.
|
|
296
|
+
*/
|
|
297
|
+
updateStateSparse(paths_js: any, values_js: any): void;
|
|
298
|
+
/**
|
|
299
|
+
* Validate that the engine is in a consistent state.
|
|
300
|
+
*
|
|
301
|
+
* Checks that:
|
|
302
|
+
* - All child references point to existing nodes
|
|
303
|
+
* - All parent back-references are correct
|
|
304
|
+
* - The root node (if any) exists in the tree
|
|
305
|
+
*
|
|
306
|
+
* Returns `null` if valid, or a string describing the first inconsistency found.
|
|
307
|
+
* Intended for testing and debugging only — not for production hot paths.
|
|
308
|
+
*/
|
|
309
|
+
validate(): any;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function main(): void;
|
|
313
|
+
|
|
7
314
|
/**
|
|
8
|
-
* Parse Hypen DSL and return AST as JSON
|
|
315
|
+
* Parse Hypen DSL source and return the AST as a pretty-printed JSON string.
|
|
316
|
+
*
|
|
317
|
+
* Useful for tooling, syntax highlighting, and debugging the parser output.
|
|
9
318
|
*/
|
|
10
319
|
export function parseToJson(source: string): string;
|
|
11
|
-
|
|
320
|
+
|
|
12
321
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
322
|
+
* Serialize a patches array to a pretty-printed JSON string.
|
|
323
|
+
*
|
|
324
|
+
* Intended for debugging and logging — not for production use.
|
|
325
|
+
* Accepts a JS array of patch objects and returns formatted JSON.
|
|
15
326
|
*/
|
|
16
|
-
export
|
|
17
|
-
free(): void;
|
|
18
|
-
[Symbol.dispose](): void;
|
|
19
|
-
/**
|
|
20
|
-
* Create a new engine instance
|
|
21
|
-
*/
|
|
22
|
-
constructor();
|
|
23
|
-
/**
|
|
24
|
-
* Parse and render Hypen DSL source code
|
|
25
|
-
* Supports documents with import statements - imports are resolved via the component resolver
|
|
26
|
-
*/
|
|
27
|
-
renderSource(source: string): void;
|
|
28
|
-
/**
|
|
29
|
-
* Set the render callback that receives patches
|
|
30
|
-
*/
|
|
31
|
-
setRenderCallback(callback: Function): void;
|
|
32
|
-
/**
|
|
33
|
-
* Set the component resolver callback
|
|
34
|
-
* The resolver receives (componentName, contextPath) and should return
|
|
35
|
-
* { source: string, path: string } or null
|
|
36
|
-
*
|
|
37
|
-
* contextPath is the path of the component that's referencing this component
|
|
38
|
-
* The returned path should be the resolved absolute path to the component file
|
|
39
|
-
*/
|
|
40
|
-
setComponentResolver(resolver: Function): void;
|
|
41
|
-
/**
|
|
42
|
-
* Register a primitive element (like Text, Button, etc.) to skip component resolution
|
|
43
|
-
* This prevents unnecessary resolver calls for built-in DOM elements
|
|
44
|
-
*/
|
|
45
|
-
registerPrimitive(name: string): void;
|
|
46
|
-
/**
|
|
47
|
-
* Render a component source (for lazy loading routes)
|
|
48
|
-
* This allows rendering a component on-demand
|
|
49
|
-
*/
|
|
50
|
-
renderLazyComponent(source: string): void;
|
|
51
|
-
/**
|
|
52
|
-
* Render a component into a specific parent node (subtree rendering)
|
|
53
|
-
* This is used for lazy routing where components are rendered on-demand into route containers
|
|
54
|
-
*
|
|
55
|
-
* # Arguments
|
|
56
|
-
* * `source` - The Hypen DSL source to parse and render
|
|
57
|
-
* * `parent_node_id_str` - The serialized node ID string of the parent element
|
|
58
|
-
* * `state_js` - The state to use for rendering (as JsValue)
|
|
59
|
-
*/
|
|
60
|
-
renderInto(source: string, parent_node_id_str: string, state_js: any): void;
|
|
61
|
-
/**
|
|
62
|
-
* Update state from JavaScript
|
|
63
|
-
*/
|
|
64
|
-
updateState(state_patch: any): void;
|
|
65
|
-
/**
|
|
66
|
-
* Update state using sparse path-value pairs
|
|
67
|
-
* More efficient than updateState for large state objects when only a few paths changed
|
|
68
|
-
*
|
|
69
|
-
* # Arguments
|
|
70
|
-
* * `paths_js` - Array of changed paths (e.g., ["user.name", "count"])
|
|
71
|
-
* * `values_js` - Object mapping paths to their new values (e.g., { "user.name": "Bob", "count": 42 })
|
|
72
|
-
*/
|
|
73
|
-
updateStateSparse(paths_js: any, values_js: any): void;
|
|
74
|
-
/**
|
|
75
|
-
* Dispatch an action
|
|
76
|
-
*/
|
|
77
|
-
dispatchAction(name: string, payload: any): void;
|
|
78
|
-
/**
|
|
79
|
-
* Register an action handler
|
|
80
|
-
*/
|
|
81
|
-
onAction(action_name: string, handler: Function): void;
|
|
82
|
-
/**
|
|
83
|
-
* Clear the engine tree (useful when switching samples)
|
|
84
|
-
*/
|
|
85
|
-
clearTree(): void;
|
|
86
|
-
/**
|
|
87
|
-
* Debug method to inspect parsed components
|
|
88
|
-
*/
|
|
89
|
-
debugParseComponent(source: string): string;
|
|
90
|
-
/**
|
|
91
|
-
* Initialize a module
|
|
92
|
-
*/
|
|
93
|
-
setModule(name: string, actions: string[], state_keys: string[], initial_state: any): void;
|
|
94
|
-
/**
|
|
95
|
-
* Get the current revision number
|
|
96
|
-
*/
|
|
97
|
-
getRevision(): bigint;
|
|
98
|
-
}
|
|
327
|
+
export function patchesToJson(patches: any): string;
|