@flaron-cdn/flare-as
v1.0.1
Published
AssemblyScript SDK for building Flaron flares: small, fast, type-safe WebAssembly modules for the Flaron edge runtime
Maintainers
Readme
@flaron-cdn/flare-as
AssemblyScript SDK for building Flaron flares: small, fast, type-safe WebAssembly modules that run on the Flaron edge runtime.
AssemblyScript compiles a strict subset of TypeScript directly to WebAssembly, producing tiny binaries (typically 3-10 KB per flare) without dragging in a runtime, garbage collector, or JavaScript engine. Your flares start in microseconds and execute at native speed.
Why AssemblyScript?
- Familiar syntax: looks like TypeScript, behaves like Wasm
- Tiny output: examples in this repo compile to 2.6-7.2 KB
- Strict types:
i32,i64,f32,f64,string,Uint8Array - No closures: class methods replace callbacks (host limitation)
- Single-pass compile: no
tscstep, no bundler, nonode_modulesat runtime
Installation
npm install @flaron-cdn/flare-asYou'll also need AssemblyScript itself in your project:
npm install --save-dev assemblyscriptQuick start: HTTP echo flare
Create assembly/index.ts:
import { alloc, resetArena, Request, Response } from "@flaron-cdn/flare-as";
// alloc must be re-exported so the host can write data into your linear memory.
export { alloc };
export function handle_request(): i64 {
resetArena();
const method = Request.method();
const url = Request.url();
Response.setStatus(200);
Response.setHeader("content-type", "text/plain");
Response.setBodyString(method + " " + url + "\n");
return Response.respond();
}Create asconfig.json:
{
"targets": {
"release": {
"outFile": "build/flare.wasm",
"optimizeLevel": 3,
"shrinkLevel": 1,
"runtime": "stub",
"exportRuntime": true
}
}
}Build:
npx asc assembly/index.ts --target releaseThat's it. build/flare.wasm is your deployable artefact.
API surface
| Class | What it does |
|---|---|
| Request | Read inbound HTTP method, URL, headers, body |
| Response | Write outbound status, headers, body, and return action |
| Spark | Per-edge KV store with TTL (NOT replicated) |
| Plasma | Cross-edge replicated KV with PN-counter semantics |
| Secret | Read per-domain secrets (allowlist gated) |
| Snowflake | Generate sortable distributed IDs |
| Beam | Outbound HTTP fetches with FetchOptions |
| WS | WebSocket open/message/close handlers and send |
| Log | Structured logging into the host slog stream |
| Crypto | Hash, HMAC, JWT signing, AES, random bytes |
| Encoding | base64, hex, URL encode/decode |
| ID | UUID v4/v7, ULID, NanoID, KSUID, snowflake |
| Time | Wall-clock timestamps in 6 formats |
Every class uses static methods, since there is no instance state when
only one inbound request exists per invocation.
Required exports
Every flare must export at minimum:
alloc(size: i32) -> i32: re-exported from this SDK; the host calls it to write request data and host-function results into your linear memoryhandle_request() -> i64(HTTP) orws_open()/ws_message()/ws_close()(WebSocket)
The return value of handle_request is an action enum encoded in the upper
32 bits of an i64:
Response.respond(): emit yourResponse.set*writes back to the clientResponse.transform(): pass the (modified) request through to the originResponse.passThrough(): pass the request through unchanged
Memory model
The flaron host calls your exported alloc(size) whenever it needs to write
a value into your linear memory (every header read, every Spark.get(),
every WebSocket event). To prevent unbounded memory growth across requests,
this SDK uses a 256 KiB static bump arena that you reset at the top of
every export with resetArena(). Forgetting to call resetArena() will
exhaust the arena after a few hundred requests and crash the flare.
export function handle_request(): i64 {
resetArena(); // ALWAYS call this first
// …
}Examples
Seven worked examples live in examples/:
| Example | What it shows |
|---|---|
| hello | Minimal HTTP responder |
| spark-counter | Per-edge KV with TTL |
| plasma-counter | Cross-edge atomic counter |
| secret-jwt | Domain secrets and JWT signing |
| websocket-echo | WebSocket event handlers |
| beam-fetch | Outbound HTTP with FetchOptions |
| edge-ops | All edge ops in one flare |
Build them all:
npm run examplesOr build one:
npm run example:helloTesting
The SDK has a self-contained test suite that compiles a guest wasm module, loads it with mock flaron/v1 host imports, and asserts on every public method:
npm test50 tests cover every class and host-function binding. Add new tests by
extending tests/guest/test.ts and tests/runner.mjs together.
Building
npm run asbuild # debug + release
npm run asbuild:debug # build/debug.wasm with source maps
npm run asbuild:release # build/release.wasm optimizedThe release build uses optimizeLevel: 3, shrinkLevel: 1 for the smallest
output. The SDK itself contributes ~2 KB; your code is most of the rest.
AssemblyScript notes
- AS does NOT support closures. Use class static methods or pass typed arrays / structured args.
- AS does NOT support
any. Explicit type annotations everywhere. - AS strings are UTF-16 internally; the SDK transcodes to UTF-8 at every host boundary so this is invisible to you.
- AS does NOT have
async/await. Host functions are synchronous from the guest's perspective, and the host runtime handles concurrency.
Documentation
Full documentation lives at flaron.dev.
License
MIT. See LICENSE.
