@hypen-space/core 0.2.7 → 0.2.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypen-space/core",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Hypen core engine - Platform-agnostic reactive UI runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -2,6 +2,39 @@
2
2
 
3
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
4
 
5
+ ## Quick Start
6
+
7
+ ### Rust
8
+
9
+ ```rust
10
+ use hypen_engine::{Engine, ast_to_ir};
11
+ use hypen_parser::parse_component;
12
+ use serde_json::json;
13
+
14
+ let mut engine = Engine::new();
15
+ engine.set_render_callback(|patches| {
16
+ // Apply patches to your renderer
17
+ });
18
+
19
+ let ast = parse_component(r#"Column { Text("Hello") }"#)?;
20
+ engine.render(&ast_to_ir(&ast));
21
+ engine.update_state(json!({ "count": 42 }));
22
+ ```
23
+
24
+ ### JavaScript/TypeScript (WASM)
25
+
26
+ ```typescript
27
+ import init, { WasmEngine } from './wasm/hypen_engine.js';
28
+ await init();
29
+
30
+ const engine = new WasmEngine();
31
+ engine.setRenderCallback((patches) => applyPatches(patches));
32
+ engine.setModule('App', ['increment'], ['count'], { count: 0 });
33
+ engine.renderSource(`Column { Text("\${state.count}") }`);
34
+ ```
35
+
36
+ See [BUILD_WASM.md](./BUILD_WASM.md) for detailed WASM build instructions.
37
+
5
38
  ## Overview
6
39
 
7
40
  Hypen Engine is a platform-agnostic UI engine that:
@@ -51,7 +84,7 @@ Hypen Engine is a platform-agnostic UI engine that:
51
84
  - `Insert(parent, id, before?)` - Insert into tree
52
85
  - `Move(parent, id, before?)` - Reorder node
53
86
  - `Remove(id)` - Remove from tree
54
- - `AttachEvent(id, event)` / `DetachEvent(id, event)`
87
+ - Event handling is managed at the renderer level
55
88
 
56
89
  5. **Action/Event Routing** (`src/dispatch/`)
57
90
  - Map `@actions.*` to module handlers
@@ -67,7 +100,7 @@ Hypen Engine is a platform-agnostic UI engine that:
67
100
  - Initial tree serialization
68
101
  - Incremental patch streaming
69
102
  - Revision tracking and optional integrity hashes
70
- - JSON/CBOR format support
103
+ - JSON format support
71
104
 
72
105
  ## Usage
73
106
 
@@ -75,15 +108,20 @@ Hypen Engine is a platform-agnostic UI engine that:
75
108
 
76
109
  ```rust
77
110
  use hypen_engine::{Engine, ir::{Element, Value, Component}};
111
+ use hypen_engine::reactive::parse_binding;
112
+ use indexmap::IndexMap;
78
113
  use serde_json::json;
79
114
 
80
115
  // Create engine
81
116
  let mut engine = Engine::new();
82
117
 
83
118
  // Register a custom component
84
- engine.register_component(Component::new("Greeting", |props| {
119
+ // Note: In practice, you'd typically parse Hypen DSL with ast_to_ir
120
+ engine.register_component(Component::new("Greeting", |props: IndexMap<String, serde_json::Value>| {
85
121
  Element::new("Text")
86
- .with_prop("text", Value::Binding("${state.name}".to_string()))
122
+ .with_prop("text", Value::Binding(
123
+ parse_binding("${state.name}").expect("valid binding")
124
+ ))
87
125
  }));
88
126
 
89
127
  // Set render callback
@@ -141,6 +179,10 @@ cargo test
141
179
 
142
180
  ### WASM (Web/Desktop)
143
181
 
182
+ The WASM build is fully functional and tested. See [BUILD_WASM.md](./BUILD_WASM.md) for detailed build instructions.
183
+
184
+ **Quick Start:**
185
+
144
186
  ```bash
145
187
  # Install wasm-pack (one time)
146
188
  cargo install wasm-pack
@@ -149,47 +191,60 @@ cargo install wasm-pack
149
191
  ./build-wasm.sh
150
192
 
151
193
  # Or build manually for specific targets:
152
- wasm-pack build --target bundler # For webpack/vite
194
+ wasm-pack build --target bundler # For webpack/vite/rollup
153
195
  wasm-pack build --target nodejs # For Node.js
154
196
  wasm-pack build --target web # For vanilla JS
155
197
  ```
156
198
 
157
- Output directories:
199
+ **Output directories:**
158
200
  - `pkg/bundler/` - For use with bundlers (webpack, vite, rollup)
159
201
  - `pkg/nodejs/` - For Node.js
160
202
  - `pkg/web/` - For vanilla HTML/JS (see `example.html`)
161
203
 
204
+ **Build to custom directory:**
205
+ ```bash
206
+ # Build directly to your renderer project
207
+ wasm-pack build --target bundler --out-dir ../hypen-render-bun/wasm
208
+ ```
209
+
210
+ The WASM binary is optimized for size (~300KB) with LTO and size optimizations enabled.
211
+
162
212
  ### JavaScript/TypeScript API
163
213
 
214
+ The WASM build provides a `WasmEngine` class with a complete API:
215
+
164
216
  ```typescript
165
217
  import init, { WasmEngine } from './pkg/web/hypen_engine.js';
166
218
 
167
- // Initialize WASM
219
+ // Initialize WASM (required before creating engine)
168
220
  await init();
169
221
 
170
- // Create engine
222
+ // Create engine instance
171
223
  const engine = new WasmEngine();
172
224
 
173
- // Set render callback
225
+ // Set render callback to receive patches
174
226
  engine.setRenderCallback((patches) => {
175
227
  console.log('Patches:', patches);
176
- // Apply patches to your renderer
228
+ // Apply patches to your platform renderer
229
+ applyPatchesToDOM(patches);
177
230
  });
178
231
 
179
232
  // Register action handlers
180
233
  engine.onAction('increment', (action) => {
181
- console.log('Increment action:', action);
234
+ console.log('Action received:', action.name, action.payload);
235
+ // Handle action (e.g., update state)
236
+ engine.updateState({ count: action.payload.count + 1 });
182
237
  });
183
238
 
184
- // Initialize module
239
+ // Initialize module with state and actions
185
240
  engine.setModule(
186
- 'CounterModule',
187
- ['increment', 'decrement'],
188
- ['count'],
189
- { count: 0 }
241
+ 'CounterModule', // Module name
242
+ ['increment', 'decrement'], // Available actions
243
+ ['count'], // State keys
244
+ { count: 0 } // Initial state
190
245
  );
191
246
 
192
- // Render Hypen DSL
247
+ // Render Hypen DSL source code
193
248
  const source = `
194
249
  Column {
195
250
  Text("Count: \${state.count}")
@@ -198,13 +253,30 @@ const source = `
198
253
  `;
199
254
  engine.renderSource(source);
200
255
 
201
- // Update state
256
+ // Update state (triggers reactive re-render)
202
257
  engine.updateState({ count: 42 });
203
258
 
204
- // Dispatch action
259
+ // Dispatch action programmatically
205
260
  engine.dispatchAction('increment', { amount: 1 });
261
+
262
+ // Get current revision number (for remote UI)
263
+ const revision = engine.getRevision();
206
264
  ```
207
265
 
266
+ **WasmEngine API Reference:**
267
+
268
+ - `constructor()` - Create a new engine instance
269
+ - `renderSource(source: string)` - Render Hypen DSL source code
270
+ - `setRenderCallback(callback: (patches: Patch[]) => void)` - Set patch callback
271
+ - `setModule(name, actions, stateKeys, initialState)` - Initialize module
272
+ - `updateState(patch: object)` - Update state and trigger re-render
273
+ - `dispatchAction(name: string, payload?: any)` - Dispatch an action
274
+ - `onAction(name: string, handler: (action: Action) => void)` - Register action handler
275
+ - `getRevision(): number` - Get current revision number
276
+ - `setComponentResolver(resolver: (name: string, context?: string) => ResolvedComponent | null)` - Set dynamic component resolver
277
+
278
+ See [BUILD_WASM.md](./BUILD_WASM.md) for more details and examples.
279
+
208
280
  ### Testing WASM Build
209
281
 
210
282
  Open `example.html` in a web server:
@@ -221,44 +293,62 @@ npx serve .
221
293
 
222
294
  ### Mobile (UniFFI)
223
295
 
296
+ UniFFI bindings for native mobile platforms are planned but not yet implemented.
297
+
224
298
  ```bash
225
- # Generate Swift/Kotlin bindings (coming soon)
299
+ # Future: Generate Swift/Kotlin bindings
226
300
  cargo install uniffi_bindgen
227
301
  uniffi-bindgen generate src/hypen_engine.udl --language swift
228
302
  uniffi-bindgen generate src/hypen_engine.udl --language kotlin
229
303
  ```
230
304
 
305
+ For now, mobile platforms can use the WASM build via WebView or native WASM runtimes.
306
+
231
307
  ## Project Structure
232
308
 
233
309
  ```
234
310
  hypen-engine-rs/
235
311
  ├── src/
236
- │ ├── lib.rs # Public API
237
- │ ├── engine.rs # Main orchestrator
238
- │ ├── wasi.rs # WASI interfaces
312
+ │ ├── lib.rs # Public API exports
313
+ │ ├── engine.rs # Main Engine orchestrator
314
+ │ ├── wasm.rs # WASM bindings (wasm-bindgen)
315
+ │ ├── state.rs # State change tracking
316
+ │ ├── render.rs # Dirty node rendering
317
+ │ ├── logger.rs # Logging utilities
239
318
  │ ├── ir/ # IR & component expansion
319
+ │ │ ├── mod.rs # Module exports
240
320
  │ │ ├── node.rs # NodeId, Element, Props, Value
241
- │ │ ├── component.rs # Component registry
242
- │ │ └── expand.rs # AST → IR lowering
321
+ │ │ ├── component.rs # Component registry & resolution
322
+ │ │ ├── expand.rs # AST → IR lowering
323
+ │ │ └── children_slots_test.rs
243
324
  │ ├── reactive/ # Reactive system
325
+ │ │ ├── mod.rs # Module exports
244
326
  │ │ ├── binding.rs # ${state.*} parsing
245
327
  │ │ ├── graph.rs # Dependency tracking
246
- │ │ └── scheduler.rs # Dirty marking
328
+ │ │ └── scheduler.rs # Dirty marking & scheduling
247
329
  │ ├── reconcile/ # Reconciliation
248
- │ │ ├── tree.rs # Instance tree
249
- │ │ ├── diff.rs # Diffing algorithm
330
+ │ │ ├── mod.rs # Module exports
331
+ │ │ ├── tree.rs # Instance tree (virtual DOM)
332
+ │ │ ├── diff.rs # Keyed diffing algorithm
250
333
  │ │ └── patch.rs # Patch types
251
334
  │ ├── dispatch/ # Events & actions
335
+ │ │ ├── mod.rs # Module exports
252
336
  │ │ ├── action.rs # Action dispatcher
253
337
  │ │ └── event.rs # Event router
254
- │ ├── lifecycle/ # Lifecycle
338
+ │ ├── lifecycle/ # Lifecycle management
339
+ │ │ ├── mod.rs # Module exports
255
340
  │ │ ├── module.rs # Module lifecycle
256
341
  │ │ ├── component.rs # Component lifecycle
257
342
  │ │ └── resource.rs # Resource cache
258
343
  │ └── serialize/ # Serialization
344
+ │ ├── mod.rs # Module exports
259
345
  │ └── remote.rs # Remote UI protocol
260
- ├── Cargo.toml
261
- └── README.md
346
+ ├── tests/ # Integration tests
347
+ ├── Cargo.toml # Rust dependencies
348
+ ├── build-wasm.sh # WASM build script
349
+ ├── BUILD_WASM.md # Detailed WASM build docs
350
+ ├── example.html # WASM demo page
351
+ └── README.md # This file
262
352
  ```
263
353
 
264
354
  ## Key Data Structures
@@ -270,7 +360,7 @@ pub struct Element {
270
360
  pub props: IndexMap<String, Value>, // Properties
271
361
  pub children: Vec<Element>, // Child elements
272
362
  pub key: Option<String>, // For reconciliation
273
- pub events: IndexMap<String, String>, // event action
363
+ // Note: Event handling is done at the renderer level, not in IR
274
364
  }
275
365
  ```
276
366
 
@@ -278,7 +368,11 @@ pub struct Element {
278
368
  ```rust
279
369
  pub enum Value {
280
370
  Static(serde_json::Value), // Literal values
281
- Binding(String), // ${state.user.name}
371
+ Binding(Binding), // Parsed ${state.user.name} binding
372
+ TemplateString { // Template with embedded bindings
373
+ template: String,
374
+ bindings: Vec<Binding>,
375
+ },
282
376
  Action(String), // @actions.signIn
283
377
  }
284
378
  ```
@@ -292,8 +386,7 @@ pub enum Patch {
292
386
  Insert { parent_id, id, before_id? },
293
387
  Move { parent_id, id, before_id? },
294
388
  Remove { id },
295
- AttachEvent { id, event_name },
296
- DetachEvent { id, event_name },
389
+ // Note: Event handling is done at the renderer level
297
390
  }
298
391
  ```
299
392
 
@@ -404,13 +497,26 @@ For client-server streaming:
404
497
  # Run all tests
405
498
  cargo test
406
499
 
407
- # Run with output
500
+ # Run with output (useful for debugging)
408
501
  cargo test -- --nocapture
409
502
 
410
503
  # Test specific module
411
504
  cargo test reactive::
505
+
506
+ # Test specific file
507
+ cargo test --test test_reactive_graph
508
+
509
+ # Run tests in parallel (default)
510
+ cargo test --jobs 4
412
511
  ```
413
512
 
513
+ The test suite includes:
514
+ - Unit tests for each module
515
+ - Integration tests for engine workflows
516
+ - WASM integration tests
517
+ - Reactive dependency tracking tests
518
+ - Reconciliation algorithm tests
519
+
414
520
  ## Contributing
415
521
 
416
522
  This is part of the Hypen project. See the main repository for contribution guidelines.
@@ -419,7 +525,60 @@ This is part of the Hypen project. See the main repository for contribution guid
419
525
 
420
526
  See main Hypen project for license information.
421
527
 
528
+ ## API Reference
529
+
530
+ ### Engine (Rust)
531
+
532
+ The main `Engine` struct provides the core functionality:
533
+
534
+ ```rust
535
+ impl Engine {
536
+ pub fn new() -> Self;
537
+ pub fn register_component(&mut self, component: Component);
538
+ pub fn set_component_resolver<F>(&mut self, resolver: F);
539
+ pub fn set_module(&mut self, module: ModuleInstance);
540
+ pub fn set_render_callback<F>(&mut self, callback: F);
541
+ pub fn on_action<F>(&mut self, action_name: impl Into<String>, handler: F);
542
+ pub fn render(&mut self, element: &Element);
543
+ pub fn update_state(&mut self, state_patch: serde_json::Value);
544
+ pub fn notify_state_change(&mut self, change: &StateChange);
545
+ pub fn dispatch_action(&mut self, action: Action) -> Result<(), String>;
546
+ pub fn revision(&self) -> u64;
547
+ pub fn component_registry(&self) -> &ComponentRegistry;
548
+ pub fn resources(&self) -> &ResourceCache;
549
+ }
550
+ ```
551
+
552
+ ### Key Exports
553
+
554
+ ```rust
555
+ pub use engine::Engine;
556
+ pub use ir::{ast_to_ir, Element, Value};
557
+ pub use lifecycle::{Module, ModuleInstance};
558
+ pub use reconcile::Patch;
559
+ pub use state::StateChange;
560
+ ```
561
+
422
562
  ---
423
563
 
424
- **Status**: ✅ Core systems implemented, WASM integration in progress
425
- **Next**: Full keyed reconciliation, UniFFI bindings, platform renderers
564
+ ## Status
565
+
566
+ **✅ Implemented:**
567
+ - Core reactive rendering engine
568
+ - Component expansion and registry
569
+ - Dependency tracking and dirty marking
570
+ - Keyed reconciliation algorithm
571
+ - Patch generation
572
+ - Action/event dispatch system
573
+ - Module lifecycle management
574
+ - Resource caching
575
+ - WASM bindings (fully functional)
576
+ - Remote UI serialization
577
+
578
+ ---
579
+
580
+ ## Related Documentation
581
+
582
+ - [BUILD_WASM.md](./BUILD_WASM.md) - Detailed WASM build instructions
583
+ - [../parser/README.md](../parser/README.md) - Hypen parser documentation
584
+ - [../hypen-render-bun/README.md](../hypen-render-bun/README.md) - Bun renderer implementation
@@ -10,7 +10,7 @@ export function patchesToJson(patches: any): string;
10
10
  export function parseToJson(source: string): string;
11
11
  export function main(): void;
12
12
  /**
13
- * WASM-exported engine instance
13
+ * WASM-exported engine instance for JavaScript runtimes
14
14
  * Uses Rc<RefCell<>> instead of Send+Sync for WASM single-threaded environment
15
15
  */
16
16
  export class WasmEngine {
@@ -255,7 +255,7 @@ const WasmEngineFinalization = (typeof FinalizationRegistry === 'undefined')
255
255
  ? { register: () => {}, unregister: () => {} }
256
256
  : new FinalizationRegistry(ptr => wasm.__wbg_wasmengine_free(ptr >>> 0, 1));
257
257
  /**
258
- * WASM-exported engine instance
258
+ * WASM-exported engine instance for JavaScript runtimes
259
259
  * Uses Rc<RefCell<>> instead of Send+Sync for WASM single-threaded environment
260
260
  */
261
261
  export class WasmEngine {
Binary file
@@ -1,7 +1,16 @@
1
1
  {
2
2
  "name": "hypen-engine",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "collaborators": [
5
+ "Hypen Contributors"
6
+ ],
7
+ "description": "A Rust implementation of the Hypen engine",
8
+ "version": "0.1.2",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/hypen-lang/hypen-engine-rs"
13
+ },
5
14
  "files": [
6
15
  "hypen_engine_bg.wasm",
7
16
  "hypen_engine.js",
@@ -2,6 +2,39 @@
2
2
 
3
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
4
 
5
+ ## Quick Start
6
+
7
+ ### Rust
8
+
9
+ ```rust
10
+ use hypen_engine::{Engine, ast_to_ir};
11
+ use hypen_parser::parse_component;
12
+ use serde_json::json;
13
+
14
+ let mut engine = Engine::new();
15
+ engine.set_render_callback(|patches| {
16
+ // Apply patches to your renderer
17
+ });
18
+
19
+ let ast = parse_component(r#"Column { Text("Hello") }"#)?;
20
+ engine.render(&ast_to_ir(&ast));
21
+ engine.update_state(json!({ "count": 42 }));
22
+ ```
23
+
24
+ ### JavaScript/TypeScript (WASM)
25
+
26
+ ```typescript
27
+ import init, { WasmEngine } from './wasm/hypen_engine.js';
28
+ await init();
29
+
30
+ const engine = new WasmEngine();
31
+ engine.setRenderCallback((patches) => applyPatches(patches));
32
+ engine.setModule('App', ['increment'], ['count'], { count: 0 });
33
+ engine.renderSource(`Column { Text("\${state.count}") }`);
34
+ ```
35
+
36
+ See [BUILD_WASM.md](./BUILD_WASM.md) for detailed WASM build instructions.
37
+
5
38
  ## Overview
6
39
 
7
40
  Hypen Engine is a platform-agnostic UI engine that:
@@ -51,7 +84,7 @@ Hypen Engine is a platform-agnostic UI engine that:
51
84
  - `Insert(parent, id, before?)` - Insert into tree
52
85
  - `Move(parent, id, before?)` - Reorder node
53
86
  - `Remove(id)` - Remove from tree
54
- - `AttachEvent(id, event)` / `DetachEvent(id, event)`
87
+ - Event handling is managed at the renderer level
55
88
 
56
89
  5. **Action/Event Routing** (`src/dispatch/`)
57
90
  - Map `@actions.*` to module handlers
@@ -67,7 +100,7 @@ Hypen Engine is a platform-agnostic UI engine that:
67
100
  - Initial tree serialization
68
101
  - Incremental patch streaming
69
102
  - Revision tracking and optional integrity hashes
70
- - JSON/CBOR format support
103
+ - JSON format support
71
104
 
72
105
  ## Usage
73
106
 
@@ -75,15 +108,20 @@ Hypen Engine is a platform-agnostic UI engine that:
75
108
 
76
109
  ```rust
77
110
  use hypen_engine::{Engine, ir::{Element, Value, Component}};
111
+ use hypen_engine::reactive::parse_binding;
112
+ use indexmap::IndexMap;
78
113
  use serde_json::json;
79
114
 
80
115
  // Create engine
81
116
  let mut engine = Engine::new();
82
117
 
83
118
  // Register a custom component
84
- engine.register_component(Component::new("Greeting", |props| {
119
+ // Note: In practice, you'd typically parse Hypen DSL with ast_to_ir
120
+ engine.register_component(Component::new("Greeting", |props: IndexMap<String, serde_json::Value>| {
85
121
  Element::new("Text")
86
- .with_prop("text", Value::Binding("${state.name}".to_string()))
122
+ .with_prop("text", Value::Binding(
123
+ parse_binding("${state.name}").expect("valid binding")
124
+ ))
87
125
  }));
88
126
 
89
127
  // Set render callback
@@ -141,6 +179,10 @@ cargo test
141
179
 
142
180
  ### WASM (Web/Desktop)
143
181
 
182
+ The WASM build is fully functional and tested. See [BUILD_WASM.md](./BUILD_WASM.md) for detailed build instructions.
183
+
184
+ **Quick Start:**
185
+
144
186
  ```bash
145
187
  # Install wasm-pack (one time)
146
188
  cargo install wasm-pack
@@ -149,47 +191,60 @@ cargo install wasm-pack
149
191
  ./build-wasm.sh
150
192
 
151
193
  # Or build manually for specific targets:
152
- wasm-pack build --target bundler # For webpack/vite
194
+ wasm-pack build --target bundler # For webpack/vite/rollup
153
195
  wasm-pack build --target nodejs # For Node.js
154
196
  wasm-pack build --target web # For vanilla JS
155
197
  ```
156
198
 
157
- Output directories:
199
+ **Output directories:**
158
200
  - `pkg/bundler/` - For use with bundlers (webpack, vite, rollup)
159
201
  - `pkg/nodejs/` - For Node.js
160
202
  - `pkg/web/` - For vanilla HTML/JS (see `example.html`)
161
203
 
204
+ **Build to custom directory:**
205
+ ```bash
206
+ # Build directly to your renderer project
207
+ wasm-pack build --target bundler --out-dir ../hypen-render-bun/wasm
208
+ ```
209
+
210
+ The WASM binary is optimized for size (~300KB) with LTO and size optimizations enabled.
211
+
162
212
  ### JavaScript/TypeScript API
163
213
 
214
+ The WASM build provides a `WasmEngine` class with a complete API:
215
+
164
216
  ```typescript
165
217
  import init, { WasmEngine } from './pkg/web/hypen_engine.js';
166
218
 
167
- // Initialize WASM
219
+ // Initialize WASM (required before creating engine)
168
220
  await init();
169
221
 
170
- // Create engine
222
+ // Create engine instance
171
223
  const engine = new WasmEngine();
172
224
 
173
- // Set render callback
225
+ // Set render callback to receive patches
174
226
  engine.setRenderCallback((patches) => {
175
227
  console.log('Patches:', patches);
176
- // Apply patches to your renderer
228
+ // Apply patches to your platform renderer
229
+ applyPatchesToDOM(patches);
177
230
  });
178
231
 
179
232
  // Register action handlers
180
233
  engine.onAction('increment', (action) => {
181
- console.log('Increment action:', action);
234
+ console.log('Action received:', action.name, action.payload);
235
+ // Handle action (e.g., update state)
236
+ engine.updateState({ count: action.payload.count + 1 });
182
237
  });
183
238
 
184
- // Initialize module
239
+ // Initialize module with state and actions
185
240
  engine.setModule(
186
- 'CounterModule',
187
- ['increment', 'decrement'],
188
- ['count'],
189
- { count: 0 }
241
+ 'CounterModule', // Module name
242
+ ['increment', 'decrement'], // Available actions
243
+ ['count'], // State keys
244
+ { count: 0 } // Initial state
190
245
  );
191
246
 
192
- // Render Hypen DSL
247
+ // Render Hypen DSL source code
193
248
  const source = `
194
249
  Column {
195
250
  Text("Count: \${state.count}")
@@ -198,13 +253,30 @@ const source = `
198
253
  `;
199
254
  engine.renderSource(source);
200
255
 
201
- // Update state
256
+ // Update state (triggers reactive re-render)
202
257
  engine.updateState({ count: 42 });
203
258
 
204
- // Dispatch action
259
+ // Dispatch action programmatically
205
260
  engine.dispatchAction('increment', { amount: 1 });
261
+
262
+ // Get current revision number (for remote UI)
263
+ const revision = engine.getRevision();
206
264
  ```
207
265
 
266
+ **WasmEngine API Reference:**
267
+
268
+ - `constructor()` - Create a new engine instance
269
+ - `renderSource(source: string)` - Render Hypen DSL source code
270
+ - `setRenderCallback(callback: (patches: Patch[]) => void)` - Set patch callback
271
+ - `setModule(name, actions, stateKeys, initialState)` - Initialize module
272
+ - `updateState(patch: object)` - Update state and trigger re-render
273
+ - `dispatchAction(name: string, payload?: any)` - Dispatch an action
274
+ - `onAction(name: string, handler: (action: Action) => void)` - Register action handler
275
+ - `getRevision(): number` - Get current revision number
276
+ - `setComponentResolver(resolver: (name: string, context?: string) => ResolvedComponent | null)` - Set dynamic component resolver
277
+
278
+ See [BUILD_WASM.md](./BUILD_WASM.md) for more details and examples.
279
+
208
280
  ### Testing WASM Build
209
281
 
210
282
  Open `example.html` in a web server:
@@ -221,44 +293,62 @@ npx serve .
221
293
 
222
294
  ### Mobile (UniFFI)
223
295
 
296
+ UniFFI bindings for native mobile platforms are planned but not yet implemented.
297
+
224
298
  ```bash
225
- # Generate Swift/Kotlin bindings (coming soon)
299
+ # Future: Generate Swift/Kotlin bindings
226
300
  cargo install uniffi_bindgen
227
301
  uniffi-bindgen generate src/hypen_engine.udl --language swift
228
302
  uniffi-bindgen generate src/hypen_engine.udl --language kotlin
229
303
  ```
230
304
 
305
+ For now, mobile platforms can use the WASM build via WebView or native WASM runtimes.
306
+
231
307
  ## Project Structure
232
308
 
233
309
  ```
234
310
  hypen-engine-rs/
235
311
  ├── src/
236
- │ ├── lib.rs # Public API
237
- │ ├── engine.rs # Main orchestrator
238
- │ ├── wasi.rs # WASI interfaces
312
+ │ ├── lib.rs # Public API exports
313
+ │ ├── engine.rs # Main Engine orchestrator
314
+ │ ├── wasm.rs # WASM bindings (wasm-bindgen)
315
+ │ ├── state.rs # State change tracking
316
+ │ ├── render.rs # Dirty node rendering
317
+ │ ├── logger.rs # Logging utilities
239
318
  │ ├── ir/ # IR & component expansion
319
+ │ │ ├── mod.rs # Module exports
240
320
  │ │ ├── node.rs # NodeId, Element, Props, Value
241
- │ │ ├── component.rs # Component registry
242
- │ │ └── expand.rs # AST → IR lowering
321
+ │ │ ├── component.rs # Component registry & resolution
322
+ │ │ ├── expand.rs # AST → IR lowering
323
+ │ │ └── children_slots_test.rs
243
324
  │ ├── reactive/ # Reactive system
325
+ │ │ ├── mod.rs # Module exports
244
326
  │ │ ├── binding.rs # ${state.*} parsing
245
327
  │ │ ├── graph.rs # Dependency tracking
246
- │ │ └── scheduler.rs # Dirty marking
328
+ │ │ └── scheduler.rs # Dirty marking & scheduling
247
329
  │ ├── reconcile/ # Reconciliation
248
- │ │ ├── tree.rs # Instance tree
249
- │ │ ├── diff.rs # Diffing algorithm
330
+ │ │ ├── mod.rs # Module exports
331
+ │ │ ├── tree.rs # Instance tree (virtual DOM)
332
+ │ │ ├── diff.rs # Keyed diffing algorithm
250
333
  │ │ └── patch.rs # Patch types
251
334
  │ ├── dispatch/ # Events & actions
335
+ │ │ ├── mod.rs # Module exports
252
336
  │ │ ├── action.rs # Action dispatcher
253
337
  │ │ └── event.rs # Event router
254
- │ ├── lifecycle/ # Lifecycle
338
+ │ ├── lifecycle/ # Lifecycle management
339
+ │ │ ├── mod.rs # Module exports
255
340
  │ │ ├── module.rs # Module lifecycle
256
341
  │ │ ├── component.rs # Component lifecycle
257
342
  │ │ └── resource.rs # Resource cache
258
343
  │ └── serialize/ # Serialization
344
+ │ ├── mod.rs # Module exports
259
345
  │ └── remote.rs # Remote UI protocol
260
- ├── Cargo.toml
261
- └── README.md
346
+ ├── tests/ # Integration tests
347
+ ├── Cargo.toml # Rust dependencies
348
+ ├── build-wasm.sh # WASM build script
349
+ ├── BUILD_WASM.md # Detailed WASM build docs
350
+ ├── example.html # WASM demo page
351
+ └── README.md # This file
262
352
  ```
263
353
 
264
354
  ## Key Data Structures
@@ -270,7 +360,7 @@ pub struct Element {
270
360
  pub props: IndexMap<String, Value>, // Properties
271
361
  pub children: Vec<Element>, // Child elements
272
362
  pub key: Option<String>, // For reconciliation
273
- pub events: IndexMap<String, String>, // event action
363
+ // Note: Event handling is done at the renderer level, not in IR
274
364
  }
275
365
  ```
276
366
 
@@ -278,7 +368,11 @@ pub struct Element {
278
368
  ```rust
279
369
  pub enum Value {
280
370
  Static(serde_json::Value), // Literal values
281
- Binding(String), // ${state.user.name}
371
+ Binding(Binding), // Parsed ${state.user.name} binding
372
+ TemplateString { // Template with embedded bindings
373
+ template: String,
374
+ bindings: Vec<Binding>,
375
+ },
282
376
  Action(String), // @actions.signIn
283
377
  }
284
378
  ```
@@ -292,8 +386,7 @@ pub enum Patch {
292
386
  Insert { parent_id, id, before_id? },
293
387
  Move { parent_id, id, before_id? },
294
388
  Remove { id },
295
- AttachEvent { id, event_name },
296
- DetachEvent { id, event_name },
389
+ // Note: Event handling is done at the renderer level
297
390
  }
298
391
  ```
299
392
 
@@ -404,13 +497,26 @@ For client-server streaming:
404
497
  # Run all tests
405
498
  cargo test
406
499
 
407
- # Run with output
500
+ # Run with output (useful for debugging)
408
501
  cargo test -- --nocapture
409
502
 
410
503
  # Test specific module
411
504
  cargo test reactive::
505
+
506
+ # Test specific file
507
+ cargo test --test test_reactive_graph
508
+
509
+ # Run tests in parallel (default)
510
+ cargo test --jobs 4
412
511
  ```
413
512
 
513
+ The test suite includes:
514
+ - Unit tests for each module
515
+ - Integration tests for engine workflows
516
+ - WASM integration tests
517
+ - Reactive dependency tracking tests
518
+ - Reconciliation algorithm tests
519
+
414
520
  ## Contributing
415
521
 
416
522
  This is part of the Hypen project. See the main repository for contribution guidelines.
@@ -419,7 +525,60 @@ This is part of the Hypen project. See the main repository for contribution guid
419
525
 
420
526
  See main Hypen project for license information.
421
527
 
528
+ ## API Reference
529
+
530
+ ### Engine (Rust)
531
+
532
+ The main `Engine` struct provides the core functionality:
533
+
534
+ ```rust
535
+ impl Engine {
536
+ pub fn new() -> Self;
537
+ pub fn register_component(&mut self, component: Component);
538
+ pub fn set_component_resolver<F>(&mut self, resolver: F);
539
+ pub fn set_module(&mut self, module: ModuleInstance);
540
+ pub fn set_render_callback<F>(&mut self, callback: F);
541
+ pub fn on_action<F>(&mut self, action_name: impl Into<String>, handler: F);
542
+ pub fn render(&mut self, element: &Element);
543
+ pub fn update_state(&mut self, state_patch: serde_json::Value);
544
+ pub fn notify_state_change(&mut self, change: &StateChange);
545
+ pub fn dispatch_action(&mut self, action: Action) -> Result<(), String>;
546
+ pub fn revision(&self) -> u64;
547
+ pub fn component_registry(&self) -> &ComponentRegistry;
548
+ pub fn resources(&self) -> &ResourceCache;
549
+ }
550
+ ```
551
+
552
+ ### Key Exports
553
+
554
+ ```rust
555
+ pub use engine::Engine;
556
+ pub use ir::{ast_to_ir, Element, Value};
557
+ pub use lifecycle::{Module, ModuleInstance};
558
+ pub use reconcile::Patch;
559
+ pub use state::StateChange;
560
+ ```
561
+
422
562
  ---
423
563
 
424
- **Status**: ✅ Core systems implemented, WASM integration in progress
425
- **Next**: Full keyed reconciliation, UniFFI bindings, platform renderers
564
+ ## Status
565
+
566
+ **✅ Implemented:**
567
+ - Core reactive rendering engine
568
+ - Component expansion and registry
569
+ - Dependency tracking and dirty marking
570
+ - Keyed reconciliation algorithm
571
+ - Patch generation
572
+ - Action/event dispatch system
573
+ - Module lifecycle management
574
+ - Resource caching
575
+ - WASM bindings (fully functional)
576
+ - Remote UI serialization
577
+
578
+ ---
579
+
580
+ ## Related Documentation
581
+
582
+ - [BUILD_WASM.md](./BUILD_WASM.md) - Detailed WASM build instructions
583
+ - [../parser/README.md](../parser/README.md) - Hypen parser documentation
584
+ - [../hypen-render-bun/README.md](../hypen-render-bun/README.md) - Bun renderer implementation
@@ -10,7 +10,7 @@ export function patchesToJson(patches: any): string;
10
10
  export function parseToJson(source: string): string;
11
11
  export function main(): void;
12
12
  /**
13
- * WASM-exported engine instance
13
+ * WASM-exported engine instance for JavaScript runtimes
14
14
  * Uses Rc<RefCell<>> instead of Send+Sync for WASM single-threaded environment
15
15
  */
16
16
  export class WasmEngine {
@@ -249,7 +249,7 @@ const WasmEngineFinalization = (typeof FinalizationRegistry === 'undefined')
249
249
  ? { register: () => {}, unregister: () => {} }
250
250
  : new FinalizationRegistry(ptr => wasm.__wbg_wasmengine_free(ptr >>> 0, 1));
251
251
  /**
252
- * WASM-exported engine instance
252
+ * WASM-exported engine instance for JavaScript runtimes
253
253
  * Uses Rc<RefCell<>> instead of Send+Sync for WASM single-threaded environment
254
254
  */
255
255
  class WasmEngine {
Binary file
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "name": "hypen-engine",
3
- "version": "0.1.0",
3
+ "collaborators": [
4
+ "Hypen Contributors"
5
+ ],
6
+ "description": "A Rust implementation of the Hypen engine",
7
+ "version": "0.1.2",
8
+ "license": "MIT",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/hypen-lang/hypen-engine-rs"
12
+ },
4
13
  "files": [
5
14
  "hypen_engine_bg.wasm",
6
15
  "hypen_engine.js",