Browser Glue Architecture

The browser-glue package provides TypeScript implementations of the tairitsu-browser:full WIT interfaces, enabling WebAssembly components to interact with browser APIs through the Component Model.

Architecture Overview

mermaid

Key Components

TypeScript Glue (src/*.ts)

Auto-generated TypeScript implementations of WIT interfaces:

DomainFileInterfacesFunctions
DOMdomGlue.ts34~300
HTMLhtmlGlue.ts182~1500
CSScssGlue.ts44~400
CanvascanvasGlue.ts20~200
FetchfetchGlue.ts25~150
EventseventsGlue.ts15~100
............

Type Declarations (dist/*.d.ts)

TypeScript declaration files for IDE support and type checking.

Interface Wrappers (dist/browser-glue/*.js)

Minimal adapter files for jco transpiled imports:

jco Integration

Import Map Configuration

html
1
2
3
4
5
6
7
8
<script type="importmap">
{
  "imports": {
    "@bytecodealliance/preview2-shim/": "https://esm.sh/@bytecodealliance/preview2-shim/",
    "tairitsu-browser:full/": "./browser-glue/"
  }
}
</script>

Transpile Process

  1. 1
    Build WASM component: cargo build --target wasm32-wasip2 --lib --release
  2. 2
    Transpile with jco: jco transpile component.wasm -o output/
  3. 3
    jco generates wrapper with imports from tairitsu-browser:full/*
  4. 4
    Import map resolves to ./browser-glue/* adapters

Handle System

Browser objects are represented as opaque u64 handles:

typescript
1
2
3
4
5
6
// TypeScript side
const element = document.createElement('div');
const handle = registerHandle(element); // Returns bigint

// Rust side receives u64
let handle: u64 = bindings::document::create_element("div", None);

Handle Table (handles.ts)

typescript
1
2
3
4
5
6
7
8
9
10
11
12
const _handles = new Map<bigint, object>();
let _nextHandle = 1n;

export function registerHandle(obj: object): bigint {
  const handle = BigInt(_nextHandle++);
  _handles.set(handle, obj);
  return handle;
}

export function lookupHandle<T>(handle: bigint): T | null {
  return _handles.get(handle) as T ?? null;
}

Timer System

The platformHelpers.ts module provides timer functions that bridge WIT callbacks to browser APIs:

FunctionJS APICallback typeWIT export
setTimeoutwindow.setTimeoutOne-shot (FnOnce)timer-callbacks.on-timeout
setIntervalwindow.setIntervalRecurring (FnMut)timer-callbacks.on-interval
requestAnimationFramewindow.requestAnimationFramePer-frameanimation-callbacks.on-frame

Interval callbacks fire repeatedly until cancelled via clearInterval. All timer state is stored on globalThis.__tairitsuTimerState.

Build Process

bash
1
2
3
4
5
6
7
8
# Regenerate glue from WIT
python3 scripts/generate_browser_glue.py

# Build with declarations
cd packages/browser-glue && npm run build

# Production build with minification
npm run build:production

Package Layout

mermaid