WebAssembly
Draft compiles to WebAssembly (WASM) for portable, sandboxed execution.
Overview
Section titled “Overview”WebAssembly allows Draft code to run in browsers, edge runtimes, and any WASM runtime.
Compiling to WASM
Section titled “Compiling to WASM”Basic Compilation
Section titled “Basic Compilation”draft build main.draft --target wasm -o output.wasmWith Optimization
Section titled “With Optimization”draft build main.draft --target wasm --release -o output.wasmWASI Target
Section titled “WASI Target”For server-side WASM with system access:
draft build main.draft --target wasi -o output.wasmBrowser Usage
Section titled “Browser Usage”Loading WASM in JavaScript
Section titled “Loading WASM in JavaScript”const module = await WebAssembly.instantiateStreaming(fetch('output.wasm'));const { greet } = module.instance.exports;console.log(greet());Draft JavaScript Glue
Section titled “Draft JavaScript Glue”<!DOCTYPE html><html><head> <title>Draft WASM Demo</title></head><body> <script type="module"> import { Draft } from './draft.js'; const app = await Draft.load('output.wasm'); app.main(); </script></body></html>Exporting Functions
Section titled “Exporting Functions”@// lib.draftpub action add(@a: Int, @b: Int) -> Int return @a + @bfin action.
pub action greet(@name: String) -> String return "Hello, " + @namefin action.Compile as a library:
draft build lib.draft --target wasm --lib -o lib.wasmImporting Functions
Section titled “Importing Functions”Import JavaScript functions into Draft:
@// Import external functionsextern action log(@message: String)extern action now() -> Int
action main() @log("Hello from Draft!") @timestamp = @now() @log("Timestamp: " + string(@timestamp))fin action.JavaScript side:
const imports = { env: { log: (ptr, len) => { const message = getString(ptr, len); console.log(message); }, now: () => Date.now() }};const module = await WebAssembly.instantiate(wasm, imports);Memory Management
Section titled “Memory Management”WASM uses linear memory. Draft manages this automatically:
@// Allocate memory@ptr = @wasm#malloc(1024)
@// Free memory@wasm#free(@ptr)WASI (WebAssembly System Interface)
Section titled “WASI (WebAssembly System Interface)”WASI provides file system and network access:
import fs
action main() @content = @fs#read_file("/input.txt") @fs#write_file("/output.txt", @content)fin action.Run with a WASI runtime:
wasmtime output.wasmwasmtime output.wasm --dir=.Edge Computing
Section titled “Edge Computing”Deploy to edge platforms:
Cloudflare Workers
Section titled “Cloudflare Workers”draft build main.draft --target wasm --edge -o worker.wasmimport http
action handle_request(@request: Request) -> Response return @http#Response::text("Hello from the edge!")fin action.Deno Deploy
Section titled “Deno Deploy”draft build main.draft --target wasm -o module.wasmFastly Compute
Section titled “Fastly Compute”draft build main.draft --target wasm --edge -o compute.wasmPerformance
Section titled “Performance”WASM performance characteristics:
| Operation | Native | WASM | Slowdown |
|---|---|---|---|
| Integer math | 1x | 1.0-1.2x | ~10% |
| Float math | 1x | 1.0-1.1x | ~5% |
| Memory access | 1x | 1.0-1.5x | ~20% |
| Function calls | 1x | 1.0-1.3x | ~15% |
Debugging
Section titled “Debugging”Source Maps
Section titled “Source Maps”draft build main.draft --target wasm --source-map -o output.wasmDebug Output
Section titled “Debug Output”draft build main.draft --target wasm --debug -o output.wasmInterop with JavaScript
Section titled “Interop with JavaScript”Passing Strings
Section titled “Passing Strings”pub action process_string(@input: String) -> String return @input#upper()fin action.Passing Arrays
Section titled “Passing Arrays”pub action sum_array(@data: Array<Int>) -> Int mut @total = 0 for @value in @data @total = @total + @value fin for. return @totalfin action.Passing Objects
Section titled “Passing Objects”record Point x: Float y: Floatfin record.
pub action distance(@a: Point, @b: Point) -> Float @dx = @a#x - @b#x @dy = @a#y - @b#y return @math#sqrt(@dx * @dx + @dy * @dy)fin action.Streaming Compilation
Section titled “Streaming Compilation”Compile WASM modules in the browser:
const response = await fetch('source.draft');const source = await response.text();const wasm = await Draft.compile(source, { target: 'wasm' });const module = await WebAssembly.instantiate(wasm);Size Optimization
Section titled “Size Optimization”Minify
Section titled “Minify”draft build main.draft --target wasm --minify -o output.wasmCompress
Section titled “Compress”draft build main.draft --target wasm --compress -o output.wasm.gzSize Comparison
Section titled “Size Comparison”| Build | Size |
|---|---|
| Debug | ~500 KB |
| Release | ~50 KB |
| Minified | ~30 KB |
| Compressed | ~10 KB |
Testing WASM
Section titled “Testing WASM”@testaction test_add() @result = add(2, 3) assert @result == 5fin action.
@testaction test_greet() @result = greet("World") assert @result == "Hello, World"fin action.Run tests in WASM:
draft test --target wasm