@hypen-space/core 0.2.2 → 0.2.4
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/src/app.js +2 -1
- package/dist/src/app.js.map +3 -3
- package/dist/src/engine.browser.js +3 -3
- package/dist/src/engine.browser.js.map +3 -3
- package/dist/src/engine.js +4 -3
- package/dist/src/engine.js.map +3 -3
- package/dist/src/index.js +18 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugin.js +126 -0
- package/dist/src/plugin.js.map +10 -0
- package/dist/src/resolver.js +102 -0
- package/dist/src/resolver.js.map +10 -0
- package/dist/src/router.js +37 -18
- package/dist/src/router.js.map +3 -3
- package/dist/src/state.js +9 -1
- package/dist/src/state.js.map +3 -3
- package/package.json +15 -2
- package/src/app.ts +1 -0
- package/src/engine.browser.ts +9 -3
- package/src/engine.ts +4 -2
- package/src/index.ts +21 -1
- package/src/plugin.ts +219 -0
- package/src/resolver.ts +216 -0
- package/src/router.ts +43 -21
- package/src/state.ts +20 -0
- package/wasm-browser/README.md +425 -0
- package/wasm-browser/hypen_engine.d.ts +151 -0
- package/wasm-browser/hypen_engine.js +811 -0
- package/wasm-browser/hypen_engine_bg.js +736 -0
- package/wasm-browser/hypen_engine_bg.wasm +0 -0
- package/wasm-browser/hypen_engine_bg.wasm.d.ts +30 -0
- package/wasm-browser/package.json +15 -0
- package/wasm-node/README.md +425 -0
- package/wasm-node/hypen_engine.d.ts +97 -0
- package/wasm-node/hypen_engine.js +751 -0
- package/wasm-node/hypen_engine_bg.js +736 -0
- package/wasm-node/hypen_engine_bg.wasm +0 -0
- package/wasm-node/hypen_engine_bg.wasm.d.ts +30 -0
- package/wasm-node/package.json +11 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# Hypen Engine
|
|
2
|
+
|
|
3
|
+
The core reactive rendering engine for Hypen, written in Rust. Compiles to WASM for web/desktop or native binaries with UniFFI for mobile platforms.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Hypen Engine is a platform-agnostic UI engine that:
|
|
8
|
+
- **Expands** Hypen DSL components into an intermediate representation (IR)
|
|
9
|
+
- **Tracks** reactive dependencies between state and UI nodes
|
|
10
|
+
- **Reconciles** UI trees efficiently using keyed diffing
|
|
11
|
+
- **Generates** minimal platform-agnostic patches for renderers
|
|
12
|
+
- **Routes** actions and events between UI and application logic
|
|
13
|
+
- **Serializes** for Remote UI scenarios (client-server streaming)
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────┐
|
|
19
|
+
│ Hypen Engine │
|
|
20
|
+
├─────────────────────────────────────────────────────────┤
|
|
21
|
+
│ Parser → IR → Reactive Graph → Reconciler → Patches │
|
|
22
|
+
│ ↓ ↓ │
|
|
23
|
+
│ Component Registry Platform Renderer│
|
|
24
|
+
│ Dependency Tracking (Web/iOS/Android)│
|
|
25
|
+
│ State Management │
|
|
26
|
+
└─────────────────────────────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Core Systems
|
|
30
|
+
|
|
31
|
+
1. **IR & Component Expansion** (`src/ir/`)
|
|
32
|
+
- Canonical intermediate representation
|
|
33
|
+
- Component registry and resolution
|
|
34
|
+
- Props/slots expansion with defaults
|
|
35
|
+
- Stable NodeId generation
|
|
36
|
+
|
|
37
|
+
2. **Reactive System** (`src/reactive/`)
|
|
38
|
+
- Dependency graph tracking `${state.*}` bindings
|
|
39
|
+
- Dirty marking on state changes
|
|
40
|
+
- Scheduling for efficient updates
|
|
41
|
+
|
|
42
|
+
3. **Reconciliation** (`src/reconcile/`)
|
|
43
|
+
- Virtual instance tree (no platform objects)
|
|
44
|
+
- Keyed children diffing algorithm
|
|
45
|
+
- Minimal patch generation
|
|
46
|
+
|
|
47
|
+
4. **Patch Types** (Platform-agnostic):
|
|
48
|
+
- `Create(id, type, props)` - Create new node
|
|
49
|
+
- `SetProp(id, name, value)` - Update property
|
|
50
|
+
- `SetText(id, text)` - Update text content
|
|
51
|
+
- `Insert(parent, id, before?)` - Insert into tree
|
|
52
|
+
- `Move(parent, id, before?)` - Reorder node
|
|
53
|
+
- `Remove(id)` - Remove from tree
|
|
54
|
+
- `AttachEvent(id, event)` / `DetachEvent(id, event)`
|
|
55
|
+
|
|
56
|
+
5. **Action/Event Routing** (`src/dispatch/`)
|
|
57
|
+
- Map `@actions.*` to module handlers
|
|
58
|
+
- Forward UI events (click, input, etc.)
|
|
59
|
+
- Stable dispatch contract for SDKs
|
|
60
|
+
|
|
61
|
+
6. **Lifecycle Management** (`src/lifecycle/`)
|
|
62
|
+
- Module lifecycle (created/destroyed)
|
|
63
|
+
- Component lifecycle (mount/unmount)
|
|
64
|
+
- Resource cache (images/fonts) with pluggable fetcher
|
|
65
|
+
|
|
66
|
+
7. **Remote UI Serialization** (`src/serialize/`)
|
|
67
|
+
- Initial tree serialization
|
|
68
|
+
- Incremental patch streaming
|
|
69
|
+
- Revision tracking and optional integrity hashes
|
|
70
|
+
- JSON/CBOR format support
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### Basic Example
|
|
75
|
+
|
|
76
|
+
```rust
|
|
77
|
+
use hypen_engine::{Engine, ir::{Element, Value, Component}};
|
|
78
|
+
use serde_json::json;
|
|
79
|
+
|
|
80
|
+
// Create engine
|
|
81
|
+
let mut engine = Engine::new();
|
|
82
|
+
|
|
83
|
+
// Register a custom component
|
|
84
|
+
engine.register_component(Component::new("Greeting", |props| {
|
|
85
|
+
Element::new("Text")
|
|
86
|
+
.with_prop("text", Value::Binding("${state.name}".to_string()))
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
// Set render callback
|
|
90
|
+
engine.set_render_callback(|patches| {
|
|
91
|
+
for patch in patches {
|
|
92
|
+
println!("Patch: {:?}", patch);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Register action handler
|
|
97
|
+
engine.on_action("greet", |action| {
|
|
98
|
+
println!("Hello from action: {:?}", action);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Render UI
|
|
102
|
+
let ui = Element::new("Column")
|
|
103
|
+
.with_child(Element::new("Greeting"));
|
|
104
|
+
|
|
105
|
+
engine.render(&ui);
|
|
106
|
+
|
|
107
|
+
// Update state
|
|
108
|
+
engine.update_state(json!({
|
|
109
|
+
"name": "Alice"
|
|
110
|
+
}));
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### With Module Host
|
|
114
|
+
|
|
115
|
+
```rust
|
|
116
|
+
use hypen_engine::lifecycle::{Module, ModuleInstance};
|
|
117
|
+
|
|
118
|
+
// Create module definition
|
|
119
|
+
let module = Module::new("ProfilePage")
|
|
120
|
+
.with_actions(vec!["signIn".to_string(), "signOut".to_string()])
|
|
121
|
+
.with_state_keys(vec!["user".to_string()])
|
|
122
|
+
.with_persist(true);
|
|
123
|
+
|
|
124
|
+
// Create module instance
|
|
125
|
+
let instance = ModuleInstance::new(
|
|
126
|
+
module,
|
|
127
|
+
json!({ "user": null })
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
engine.set_module(instance);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Compilation Targets
|
|
134
|
+
|
|
135
|
+
### Native (Development)
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
cargo build
|
|
139
|
+
cargo test
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### WASM (Web/Desktop)
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Install wasm-pack (one time)
|
|
146
|
+
cargo install wasm-pack
|
|
147
|
+
|
|
148
|
+
# Build for all WASM targets
|
|
149
|
+
./build-wasm.sh
|
|
150
|
+
|
|
151
|
+
# Or build manually for specific targets:
|
|
152
|
+
wasm-pack build --target bundler # For webpack/vite
|
|
153
|
+
wasm-pack build --target nodejs # For Node.js
|
|
154
|
+
wasm-pack build --target web # For vanilla JS
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Output directories:
|
|
158
|
+
- `pkg/bundler/` - For use with bundlers (webpack, vite, rollup)
|
|
159
|
+
- `pkg/nodejs/` - For Node.js
|
|
160
|
+
- `pkg/web/` - For vanilla HTML/JS (see `example.html`)
|
|
161
|
+
|
|
162
|
+
### JavaScript/TypeScript API
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import init, { WasmEngine } from './pkg/web/hypen_engine.js';
|
|
166
|
+
|
|
167
|
+
// Initialize WASM
|
|
168
|
+
await init();
|
|
169
|
+
|
|
170
|
+
// Create engine
|
|
171
|
+
const engine = new WasmEngine();
|
|
172
|
+
|
|
173
|
+
// Set render callback
|
|
174
|
+
engine.setRenderCallback((patches) => {
|
|
175
|
+
console.log('Patches:', patches);
|
|
176
|
+
// Apply patches to your renderer
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Register action handlers
|
|
180
|
+
engine.onAction('increment', (action) => {
|
|
181
|
+
console.log('Increment action:', action);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Initialize module
|
|
185
|
+
engine.setModule(
|
|
186
|
+
'CounterModule',
|
|
187
|
+
['increment', 'decrement'],
|
|
188
|
+
['count'],
|
|
189
|
+
{ count: 0 }
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
// Render Hypen DSL
|
|
193
|
+
const source = `
|
|
194
|
+
Column {
|
|
195
|
+
Text("Count: \${state.count}")
|
|
196
|
+
Button("@actions.increment") { Text("+1") }
|
|
197
|
+
}
|
|
198
|
+
`;
|
|
199
|
+
engine.renderSource(source);
|
|
200
|
+
|
|
201
|
+
// Update state
|
|
202
|
+
engine.updateState({ count: 42 });
|
|
203
|
+
|
|
204
|
+
// Dispatch action
|
|
205
|
+
engine.dispatchAction('increment', { amount: 1 });
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Testing WASM Build
|
|
209
|
+
|
|
210
|
+
Open `example.html` in a web server:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Using Python
|
|
214
|
+
python3 -m http.server 8000
|
|
215
|
+
|
|
216
|
+
# Using Node.js
|
|
217
|
+
npx serve .
|
|
218
|
+
|
|
219
|
+
# Then visit: http://localhost:8000/example.html
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Mobile (UniFFI)
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
# Generate Swift/Kotlin bindings (coming soon)
|
|
226
|
+
cargo install uniffi_bindgen
|
|
227
|
+
uniffi-bindgen generate src/hypen_engine.udl --language swift
|
|
228
|
+
uniffi-bindgen generate src/hypen_engine.udl --language kotlin
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Project Structure
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
hypen-engine-rs/
|
|
235
|
+
├── src/
|
|
236
|
+
│ ├── lib.rs # Public API
|
|
237
|
+
│ ├── engine.rs # Main orchestrator
|
|
238
|
+
│ ├── wasi.rs # WASI interfaces
|
|
239
|
+
│ ├── ir/ # IR & component expansion
|
|
240
|
+
│ │ ├── node.rs # NodeId, Element, Props, Value
|
|
241
|
+
│ │ ├── component.rs # Component registry
|
|
242
|
+
│ │ └── expand.rs # AST → IR lowering
|
|
243
|
+
│ ├── reactive/ # Reactive system
|
|
244
|
+
│ │ ├── binding.rs # ${state.*} parsing
|
|
245
|
+
│ │ ├── graph.rs # Dependency tracking
|
|
246
|
+
│ │ └── scheduler.rs # Dirty marking
|
|
247
|
+
│ ├── reconcile/ # Reconciliation
|
|
248
|
+
│ │ ├── tree.rs # Instance tree
|
|
249
|
+
│ │ ├── diff.rs # Diffing algorithm
|
|
250
|
+
│ │ └── patch.rs # Patch types
|
|
251
|
+
│ ├── dispatch/ # Events & actions
|
|
252
|
+
│ │ ├── action.rs # Action dispatcher
|
|
253
|
+
│ │ └── event.rs # Event router
|
|
254
|
+
│ ├── lifecycle/ # Lifecycle
|
|
255
|
+
│ │ ├── module.rs # Module lifecycle
|
|
256
|
+
│ │ ├── component.rs # Component lifecycle
|
|
257
|
+
│ │ └── resource.rs # Resource cache
|
|
258
|
+
│ └── serialize/ # Serialization
|
|
259
|
+
│ └── remote.rs # Remote UI protocol
|
|
260
|
+
├── Cargo.toml
|
|
261
|
+
└── README.md
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Key Data Structures
|
|
265
|
+
|
|
266
|
+
### Element (IR Node)
|
|
267
|
+
```rust
|
|
268
|
+
pub struct Element {
|
|
269
|
+
pub element_type: String, // "Column", "Text", etc.
|
|
270
|
+
pub props: IndexMap<String, Value>, // Properties
|
|
271
|
+
pub children: Vec<Element>, // Child elements
|
|
272
|
+
pub key: Option<String>, // For reconciliation
|
|
273
|
+
pub events: IndexMap<String, String>, // event → action
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Value (Props)
|
|
278
|
+
```rust
|
|
279
|
+
pub enum Value {
|
|
280
|
+
Static(serde_json::Value), // Literal values
|
|
281
|
+
Binding(String), // ${state.user.name}
|
|
282
|
+
Action(String), // @actions.signIn
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Patch (Output)
|
|
287
|
+
```rust
|
|
288
|
+
pub enum Patch {
|
|
289
|
+
Create { id, element_type, props },
|
|
290
|
+
SetProp { id, name, value },
|
|
291
|
+
SetText { id, text },
|
|
292
|
+
Insert { parent_id, id, before_id? },
|
|
293
|
+
Move { parent_id, id, before_id? },
|
|
294
|
+
Remove { id },
|
|
295
|
+
AttachEvent { id, event_name },
|
|
296
|
+
DetachEvent { id, event_name },
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Integration with Parser
|
|
301
|
+
|
|
302
|
+
The engine integrates with the Hypen parser from `../parser`:
|
|
303
|
+
|
|
304
|
+
```rust
|
|
305
|
+
use hypen_parser::parse_component;
|
|
306
|
+
use hypen_engine::ast_to_ir;
|
|
307
|
+
|
|
308
|
+
let source = r#"
|
|
309
|
+
Column {
|
|
310
|
+
Text("Hello, ${state.name}")
|
|
311
|
+
Button("@actions.greet") { Text("Greet") }
|
|
312
|
+
}
|
|
313
|
+
"#;
|
|
314
|
+
|
|
315
|
+
let ast = parse_component(source)?;
|
|
316
|
+
let element = ast_to_ir(&ast); // Convert AST → IR
|
|
317
|
+
engine.render(&element);
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Full Example with Parser
|
|
321
|
+
|
|
322
|
+
```rust
|
|
323
|
+
use hypen_engine::{Engine, ast_to_ir};
|
|
324
|
+
use hypen_parser::parse_component;
|
|
325
|
+
use serde_json::json;
|
|
326
|
+
|
|
327
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
328
|
+
let mut engine = Engine::new();
|
|
329
|
+
|
|
330
|
+
// Set render callback
|
|
331
|
+
engine.set_render_callback(|patches| {
|
|
332
|
+
println!("Patches: {:#?}", patches);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// Parse Hypen DSL
|
|
336
|
+
let source = r#"
|
|
337
|
+
Column {
|
|
338
|
+
Text("Count: ${state.count}")
|
|
339
|
+
Button("@actions.increment") { Text("+1") }
|
|
340
|
+
}
|
|
341
|
+
"#;
|
|
342
|
+
|
|
343
|
+
let ast = parse_component(source)?;
|
|
344
|
+
let element = ast_to_ir(&ast);
|
|
345
|
+
|
|
346
|
+
// Render
|
|
347
|
+
engine.render(&element);
|
|
348
|
+
|
|
349
|
+
// Update state
|
|
350
|
+
engine.update_state(json!({"count": 42}));
|
|
351
|
+
|
|
352
|
+
Ok(())
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Performance Considerations
|
|
357
|
+
|
|
358
|
+
- **Keyed reconciliation**: Use `key` props for list items to minimize DOM churn
|
|
359
|
+
- **Dependency tracking**: Only re-render nodes affected by state changes
|
|
360
|
+
- **Lazy evaluation**: Bindings are resolved on-demand during reconciliation
|
|
361
|
+
- **Resource caching**: Images/fonts are cached with configurable eviction
|
|
362
|
+
|
|
363
|
+
## Remote UI Protocol
|
|
364
|
+
|
|
365
|
+
For client-server streaming:
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
// Initial tree (client connects)
|
|
369
|
+
{
|
|
370
|
+
"type": "initialTree",
|
|
371
|
+
"module": "ProfilePage",
|
|
372
|
+
"state": { "user": null },
|
|
373
|
+
"patches": [...],
|
|
374
|
+
"revision": 0
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// State update (server → client)
|
|
378
|
+
{
|
|
379
|
+
"type": "stateUpdate",
|
|
380
|
+
"module": "ProfilePage",
|
|
381
|
+
"state": { "user": { "name": "Alice" } }
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Incremental patches (server → client)
|
|
385
|
+
{
|
|
386
|
+
"type": "patch",
|
|
387
|
+
"module": "ProfilePage",
|
|
388
|
+
"patches": [{ "type": "setProp", ... }],
|
|
389
|
+
"revision": 42
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Action dispatch (client → server)
|
|
393
|
+
{
|
|
394
|
+
"type": "dispatchAction",
|
|
395
|
+
"module": "ProfilePage",
|
|
396
|
+
"action": "signIn",
|
|
397
|
+
"payload": { "provider": "google" }
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Testing
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# Run all tests
|
|
405
|
+
cargo test
|
|
406
|
+
|
|
407
|
+
# Run with output
|
|
408
|
+
cargo test -- --nocapture
|
|
409
|
+
|
|
410
|
+
# Test specific module
|
|
411
|
+
cargo test reactive::
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Contributing
|
|
415
|
+
|
|
416
|
+
This is part of the Hypen project. See the main repository for contribution guidelines.
|
|
417
|
+
|
|
418
|
+
## License
|
|
419
|
+
|
|
420
|
+
See main Hypen project for license information.
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
**Status**: ✅ Core systems implemented, WASM integration in progress
|
|
425
|
+
**Next**: Full keyed reconciliation, UniFFI bindings, platform renderers
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Export patches as JSON string (for debugging)
|
|
5
|
+
*/
|
|
6
|
+
export function patchesToJson(patches: any): string;
|
|
7
|
+
/**
|
|
8
|
+
* Parse Hypen DSL and return AST as JSON
|
|
9
|
+
*/
|
|
10
|
+
export function parseToJson(source: string): string;
|
|
11
|
+
export function main(): void;
|
|
12
|
+
/**
|
|
13
|
+
* WASM-exported engine instance
|
|
14
|
+
* Uses Rc<RefCell<>> instead of Send+Sync for WASM single-threaded environment
|
|
15
|
+
*/
|
|
16
|
+
export class WasmEngine {
|
|
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
|
+
*/
|
|
26
|
+
renderSource(source: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Set the render callback that receives patches
|
|
29
|
+
*/
|
|
30
|
+
setRenderCallback(callback: Function): void;
|
|
31
|
+
/**
|
|
32
|
+
* Set the component resolver callback
|
|
33
|
+
* The resolver receives (componentName, contextPath) and should return
|
|
34
|
+
* { source: string, path: string } or null
|
|
35
|
+
*
|
|
36
|
+
* contextPath is the path of the component that's referencing this component
|
|
37
|
+
* The returned path should be the resolved absolute path to the component file
|
|
38
|
+
*/
|
|
39
|
+
setComponentResolver(resolver: Function): void;
|
|
40
|
+
/**
|
|
41
|
+
* Register a primitive element (like Text, Button, etc.) to skip component resolution
|
|
42
|
+
* This prevents unnecessary resolver calls for built-in DOM elements
|
|
43
|
+
*/
|
|
44
|
+
registerPrimitive(name: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Render a component source (for lazy loading routes)
|
|
47
|
+
* This allows rendering a component on-demand
|
|
48
|
+
*/
|
|
49
|
+
renderLazyComponent(source: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Render a component into a specific parent node (subtree rendering)
|
|
52
|
+
* This is used for lazy routing where components are rendered on-demand into route containers
|
|
53
|
+
*
|
|
54
|
+
* # Arguments
|
|
55
|
+
* * `source` - The Hypen DSL source to parse and render
|
|
56
|
+
* * `parent_node_id_str` - The serialized node ID string of the parent element
|
|
57
|
+
* * `state_js` - The state to use for rendering (as JsValue)
|
|
58
|
+
*/
|
|
59
|
+
renderInto(source: string, parent_node_id_str: string, state_js: any): void;
|
|
60
|
+
/**
|
|
61
|
+
* Update state from JavaScript
|
|
62
|
+
*/
|
|
63
|
+
updateState(state_patch: any): void;
|
|
64
|
+
/**
|
|
65
|
+
* Update state using sparse path-value pairs
|
|
66
|
+
* More efficient than updateState for large state objects when only a few paths changed
|
|
67
|
+
*
|
|
68
|
+
* # Arguments
|
|
69
|
+
* * `paths_js` - Array of changed paths (e.g., ["user.name", "count"])
|
|
70
|
+
* * `values_js` - Object mapping paths to their new values (e.g., { "user.name": "Bob", "count": 42 })
|
|
71
|
+
*/
|
|
72
|
+
updateStateSparse(paths_js: any, values_js: any): void;
|
|
73
|
+
/**
|
|
74
|
+
* Dispatch an action
|
|
75
|
+
*/
|
|
76
|
+
dispatchAction(name: string, payload: any): void;
|
|
77
|
+
/**
|
|
78
|
+
* Register an action handler
|
|
79
|
+
*/
|
|
80
|
+
onAction(action_name: string, handler: Function): void;
|
|
81
|
+
/**
|
|
82
|
+
* Clear the engine tree (useful when switching samples)
|
|
83
|
+
*/
|
|
84
|
+
clearTree(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Debug method to inspect parsed components
|
|
87
|
+
*/
|
|
88
|
+
debugParseComponent(source: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Initialize a module
|
|
91
|
+
*/
|
|
92
|
+
setModule(name: string, actions: string[], state_keys: string[], initial_state: any): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get the current revision number
|
|
95
|
+
*/
|
|
96
|
+
getRevision(): bigint;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
100
|
+
|
|
101
|
+
export interface InitOutput {
|
|
102
|
+
readonly memory: WebAssembly.Memory;
|
|
103
|
+
readonly __wbg_wasmengine_free: (a: number, b: number) => void;
|
|
104
|
+
readonly wasmengine_new: () => number;
|
|
105
|
+
readonly wasmengine_setRenderCallback: (a: number, b: any) => void;
|
|
106
|
+
readonly wasmengine_setComponentResolver: (a: number, b: any) => void;
|
|
107
|
+
readonly wasmengine_registerPrimitive: (a: number, b: number, c: number) => void;
|
|
108
|
+
readonly wasmengine_renderLazyComponent: (a: number, b: number, c: number) => [number, number];
|
|
109
|
+
readonly wasmengine_renderInto: (a: number, b: number, c: number, d: number, e: number, f: any) => [number, number];
|
|
110
|
+
readonly wasmengine_updateState: (a: number, b: any) => [number, number];
|
|
111
|
+
readonly wasmengine_updateStateSparse: (a: number, b: any, c: any) => [number, number];
|
|
112
|
+
readonly wasmengine_dispatchAction: (a: number, b: number, c: number, d: any) => [number, number];
|
|
113
|
+
readonly wasmengine_onAction: (a: number, b: number, c: number, d: any) => void;
|
|
114
|
+
readonly wasmengine_clearTree: (a: number) => void;
|
|
115
|
+
readonly wasmengine_debugParseComponent: (a: number, b: number, c: number) => [number, number, number, number];
|
|
116
|
+
readonly wasmengine_setModule: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any) => [number, number];
|
|
117
|
+
readonly wasmengine_getRevision: (a: number) => bigint;
|
|
118
|
+
readonly patchesToJson: (a: any) => [number, number, number, number];
|
|
119
|
+
readonly parseToJson: (a: number, b: number) => [number, number, number, number];
|
|
120
|
+
readonly main: () => void;
|
|
121
|
+
readonly wasmengine_renderSource: (a: number, b: number, c: number) => [number, number];
|
|
122
|
+
readonly __wbindgen_exn_store: (a: number) => void;
|
|
123
|
+
readonly __externref_table_alloc: () => number;
|
|
124
|
+
readonly __wbindgen_export_2: WebAssembly.Table;
|
|
125
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
126
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
127
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
128
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
129
|
+
readonly __wbindgen_start: () => void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
133
|
+
/**
|
|
134
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
135
|
+
* a precompiled `WebAssembly.Module`.
|
|
136
|
+
*
|
|
137
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
138
|
+
*
|
|
139
|
+
* @returns {InitOutput}
|
|
140
|
+
*/
|
|
141
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
145
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
146
|
+
*
|
|
147
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
148
|
+
*
|
|
149
|
+
* @returns {Promise<InitOutput>}
|
|
150
|
+
*/
|
|
151
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|