# Building Hypen Engine for WASM

## ✅ Quick Start

The WASM build is now working! Here's how to build it:

### Basic Build

```bash
# Build for bundler (webpack/vite/rollup)
wasm-pack build --target bundler --out-dir pkg/bundler

# Build for Node.js
wasm-pack build --target nodejs --out-dir pkg/nodejs

# Build for web (no bundler)
wasm-pack build --target web --out-dir pkg/web
```

### Custom Output Directory

To build to a specific directory (e.g., for your renderer project):

```bash
# Absolute path
wasm-pack build --target bundler --out-dir /path/to/hypen-web/packages/web-engine/wasm-browser

# Relative path (e.g. for the browser WASM package)
wasm-pack build --target bundler --out-dir ../hypen-web/packages/web-engine/wasm-browser
```

### Example (Your Use Case)

```bash
cd hypen-engine-rs
cargo clean  # Optional: clean previous builds
wasm-pack build --target bundler --out-dir ../hypen-web/packages/web-engine/wasm-browser
```

## 📦 Output Files

After building, you'll get these files:

- `hypen_engine_bg.wasm` - The WASM binary (~300KB optimized)
- `hypen_engine.js` - JavaScript entry point
- `hypen_engine_bg.js` - Generated bindings
- `hypen_engine.d.ts` - TypeScript definitions
- `package.json` - NPM package metadata
- `README.md` - Auto-generated docs

## 🚀 Using in Your Project

### With a Bundler (Vite/Webpack)

```typescript
import init, { WasmEngine } from './wasm/hypen_engine.js';

// Initialize WASM
await init();

// Create engine
const engine = new WasmEngine();

// Set render callback
engine.setRenderCallback((patches) => {
    console.log('Patches:', patches);
    applyPatches(patches);
});

// Initialize module
engine.setModule(
    'MyApp',
    ['increment', 'greet'],
    ['count', 'username'],
    { count: 0, username: 'Guest' }
);

// Render Hypen DSL
engine.renderSource(`
    Column {
        Text("Count: @{state.count}")
        Button("@actions.increment") { Text("+1") }
    }
`);

// Update state
engine.updateState({ count: 42 });

// Dispatch action
engine.dispatchAction('increment', { amount: 1 });
```

### With Node.js

```javascript
const { WasmEngine } = require('./wasm/hypen_engine.js');

const engine = new WasmEngine();
// ... same API as above
```

## 🛠️ Build Script

Use the provided build script for all targets:

```bash
./build-wasm.sh
```

This builds:
- `pkg/bundler/` - For webpack/vite/rollup
- `pkg/nodejs/` - For Node.js
- `pkg/web/` - For vanilla HTML/JS

## 🔧 Troubleshooting

### Error: `wasm-pack not found`

```bash
cargo install wasm-pack
```

### Error: `Send + Sync` issues

These have been fixed! The WASM module no longer requires `Send + Sync` since WASM is single-threaded.

### Build is slow

First build takes time (~40s) to compile dependencies. Subsequent builds are much faster (~1s).

### TypeScript errors

Make sure to import the types:

```typescript
import type { WasmEngine } from './wasm/hypen_engine';
```

## 📊 Size Optimization

The release build is already optimized:
- LTO enabled
- `opt-level = "z"` (optimize for size)
- Single codegen unit
- wasm-opt applied

Result: ~300KB WASM binary (before gzip)

## 🎯 API Reference

### WasmEngine Class

```typescript
class WasmEngine {
  constructor();

  // Render Hypen DSL source code
  renderSource(source: string): void;

  // Set callback to receive patches
  setRenderCallback(callback: (patches: Patch[]) => void): void;

  // Update state (triggers re-render of affected nodes)
  updateState(patch: object): void;

  // Dispatch an action
  dispatchAction(name: string, payload?: any): void;

  // Register action handler
  onAction(name: string, handler: (action: Action) => void): void;

  // Initialize module
  setModule(
    name: string,
    actions: string[],
    stateKeys: string[],
    initialState: object
  ): void;

  // Get current revision number
  getRevision(): number;
}
```

### Utility Functions

```typescript
// Parse Hypen DSL to JSON AST
parseToJson(source: string): string;

// Convert patches to JSON string
patchesToJson(patches: Patch[]): string;
```

## 🔗 Integration Examples

### Bun

```typescript
import { WasmEngine } from './wasm/hypen_engine.js';

const engine = new WasmEngine();
// ... use as normal
```

### Deno

```typescript
import init, { WasmEngine } from './wasm/hypen_engine.js';

await init();
const engine = new WasmEngine();
```

### Browser (ES Modules)

```html
<script type="module">
  import init, { WasmEngine } from './wasm/hypen_engine.js';

  await init();
  const engine = new WasmEngine();
  // ... use as normal
</script>
```

## 📝 Notes

- WASM build is single-threaded (no Web Workers needed)
- All callbacks are synchronous
- State updates trigger immediate re-renders
- Patches are emitted as JavaScript arrays/objects

---

**Status**: ✅ WASM build working and tested!
**Size**: ~300KB optimized WASM binary
**Targets**: Bundler, Node.js, Web
