Wasm bindings and WIT-facing facade for crater
{
"deps": {
"mizchi/crater-wasm": "*"
}
}moon updatenpm install @aspect-build/jco# Download from wa.dev
curl -O https://wa.dev/mizchi/crater/crater.wasm
# Transpile to JavaScript
npx jco transpile crater.wasm -o ./crater --name craterimport { core } from './crater/crater.js';
// Compute layout from HTML - returns flat node array
const html = '<div style="width: 100px; height: 50px"><span>Hello</span></div>';
const result = JSON.parse(core.computeLayout(html, 800, 600));
console.log(result.rootId); // "body"
console.log(result.nodes);
// [
// { id: "body", parentId: "", index: 0, x: 0, y: 0, width: 800, height: 50, ... },
// { id: "div", parentId: "body", index: 0, x: 0, y: 0, width: 100, height: 50, ... },
// { id: "span", parentId: "div", index: 0, x: 0, y: 0, width: 100, height: 50, text: "Hello", ... }
// ]
// Build tree from flat array if needed
function buildTree(nodes, rootId) {
const nodeMap = new Map(nodes.map(n => [n.id, { ...n, children: [] }]));
for (const node of nodes) {
if (node.parentId) {
nodeMap.get(node.parentId)?.children.push(nodeMap.get(node.id));
}
}
return nodeMap.get(rootId);
}import { renderer } from './crater/crater.js';
// Render HTML to layout JSON (hierarchical tree)
const html = '<div style="width: 100px; display: flex;"><div style="flex: 1;"></div></div>';
const layoutJson = renderer.renderHtmlToJson(html, 800, 600);
const layout = JSON.parse(layoutJson);
console.log(layout);
// { id: 'body', x: 0, y: 0, width: 800, height: 0, children: [...] }
// Render to paint tree with colors
const paintTree = renderer.renderHtmlToPaintTree(html, 800, 600);import { incremental } from './crater/crater.js';
// Create layout tree
incremental.createTree(html, 800, 600);
// Initial layout
const result = incremental.computeIncremental();
console.log(JSON.parse(result));
// Update style and recompute (only affected nodes)
incremental.updateStyle('div#root', 'width: 200px;');
incremental.markDirty('div#root');
const updated = incremental.computeIncremental();
// Check cache statistics
const stats = JSON.parse(incremental.getCacheStats());
console.log(`Cache hit rate: ${stats.hitRate * 100}%`);
// Resize viewport
incremental.resizeViewport(1024, 768);
const resized = incremental.computeIncremental();
// Cleanup
incremental.destroyTree();import { yoga, incremental } from './crater/crater.js';
// Create layout tree first
incremental.createTree('<div id="root"></div>', 800, 600);
// Programmatic layout using Yoga-style API
yoga.setWidth('div#root', 400);
yoga.setHeight('div#root', 300);
yoga.setFlexDirection('div#root', 'column');
yoga.setJustifyContent('div#root', 'center');
yoga.setAlignItems('div#root', 'center');
// Calculate and get layout
const layoutJson = yoga.calculateLayout(800, 600);
const layout = JSON.parse(layoutJson);
// Get computed values
const width = yoga.getComputedWidth('div#root');
const height = yoga.getComputedHeight('div#root');
console.log(`Computed size: ${width}x${height}`);
incremental.destroyTree();import { accessibility } from './crater/crater.js';
const html = '<button>Click me</button><input type="text" placeholder="Name">';
// Get ARIA snapshot (Playwright-compatible YAML format)
console.log(accessibility.getAriaSnapshot(html));
// - document:
// - generic:
// - button "Click me": Click me
// - textbox
// Get ARIA snapshot as JSON
const ariaJson = JSON.parse(accessibility.getAriaSnapshotJson(html));
console.log(ariaJson);
// Get full accessibility tree
const tree = JSON.parse(accessibility.getAccessibilityTree(html));
console.log(tree);npm run build:wasm-componentnpm run jco:transpileinterface LayoutNode {
id: string;
parentId: string; // empty for root
index: number; // child index in parent
x: number;
y: number;
width: number;
height: number;
contentX: number;
contentY: number;
contentWidth: number;
contentHeight: number;
text?: string; // for text nodes
}# Login to wa.dev
wa login
# Publish
cd wasm
wa publishfn extract_main_content_with_layout(html : String, width : Int, height : Int) -> Stringfn render_html_to_json(html : String, width : UInt, height : UInt) -> Stringfn render_html_to_paint_tree(html : String, width : UInt, height : UInt) -> String