Package Reference
Every package Symmetra ships, every function it exposes, what each parameter does, and what each call returns. All signatures below match the published type definitions exactly.
One important concept before you start: Symmetra packages contain no JavaScript runtime code. They are compile-time type definitions. When you run sym server.ts, the Symmetra engine reads your source, resolves these imports, and generates CUDA C++ for your handlers. Your code never executes in Node.js.
@symmetra/http HTTP server
The GPU-native HTTP server. This is the package every Symmetra application starts with.
import { Router, serve } from '@symmetra/http'
new Router()
Creates a route table. Each route handler you register compiles to a CUDA device function.
| Method | Parameters | Returns | What it does |
|---|---|---|---|
| get(path, handler) | path: string, handler: (ctx) => void | Promise<void> | this | Registers a GET route. Chainable. |
| post(path, handler) | same | this | Registers a POST route. |
| put(path, handler) | same | this | Registers a PUT route. |
| delete(path, handler) | same | this | Registers a DELETE route. |
| patch(path, handler) | same | this | Registers a PATCH route. |
| route(prefix) | prefix: string | RouterGroup | Returns a sub-router whose routes are all prefixed (e.g. /api). |
| use(middleware) | (ctx, next) => Promise<void> | this | Registers middleware that runs before route handlers. |
const app = new Router()
app.get('/health', ctx => {
ctx.json({ status: 'ok' })
})
// Grouped routes — everything under /api
const api = app.route('/api')
api.get('/users', ctx => { /* GET /api/users */ })
api.post('/users', ctx => { /* POST /api/users */ })
serve(app, options?)
The entry point. The Symmetra engine intercepts this call at compile time and uses it to configure the GPU server. Returns nothing — the process stays alive serving requests.
Returns: void (the server runs until the process is stopped)
All options are covered in depth with complete examples on the Server Configuration page. Summary:
| Option | Type | Default | Meaning |
|---|---|---|---|
| port | number | 8080 | TCP port to listen on. |
| hostname | string | '0.0.0.0' | Bind address. |
| streams | number | 32 | CUDA stream pool size (max 64). |
| batch | number | 64 | Requests grouped per GPU dispatch. |
| logLevel | 'debug'|'info'|'warn'|'error' | 'info' | Runtime log verbosity. |
| maxBodyBytes | number | — | Reject request bodies larger than this. |
| scheduler | SchedulerOptions | — | Advanced GPU/IO tuning — see scheduler options. |
The ctx object (SymmCtx)
Every handler receives one argument: the request/response context. This is how you read the request and write the response.
Reading the request:
| Property / Method | Returns | What it gives you |
|---|---|---|
| ctx.method | string | HTTP method ('GET', 'POST', …) |
| ctx.path | string | Request path ('/api/users') |
| ctx.query | Record<string,string> | Parsed query string (?a=1 → { a: '1' }) |
| ctx.params | Record<string,string> | Route parameters |
| ctx.headers | Record<string,string> | All request headers |
| ctx.header(name) | string | undefined | One header value |
| ctx.text() | Promise<string> | Body as a string |
| ctx.json<T>() | Promise<T> | Body parsed as JSON |
| ctx.body<T>() | Promise<GpuBuffer<T>> | Raw body as a VRAM buffer — zero-copy, already on GPU |
Writing the response:
| Method | Returns | What it does |
|---|---|---|
| ctx.status(code) | this | Sets the HTTP status code. Chainable: ctx.status(404).json({...}) |
| ctx.json(data) | void | Serializes data to JSON and sends it with Content-Type: application/json |
| ctx.text(data) | void | Sends a plain-text response |
| ctx.send(data) | void | Sends raw bytes — accepts a GpuBuffer or Uint8Array |
| ctx.header(name, value) | this | Sets a response header. Chainable. |
Utilities on ctx:
| Property | Type | What it gives you |
|---|---|---|
| ctx.gpu | GpuApi | Device info and compute primitives — see gpu API |
| ctx.kv | KvApi | The VRAM key-value store — see @symmetra/kv |
app.post('/echo', async ctx => {
const body = await ctx.json<{ name: string }>()
ctx.status(200)
.header('X-Engine', 'symmetra')
ctx.json({ hello: body.name, device: ctx.gpu.deviceName })
})
@symmetra/core GPU primitives
GPU buffer types, VRAM containers, and compute primitives. Most of these are standard JavaScript shapes (Map, Set, Promise, EventEmitter) that the compiler maps to GPU equivalents — you usually don't import them explicitly.
GpuBuffer<T>
A typed array resident in VRAM. Array operations compile to parallel CUDA kernels — one GPU thread per element instead of a CPU loop.
| Member | Returns | What it does |
|---|---|---|
| length | number | Element count. |
| byteLength | number | Size in bytes. |
| map(fn) | GpuBuffer<U> | Parallel transform — each element processed by its own GPU thread. |
| filter(fn) | GpuBuffer<T> | Parallel filter. |
| reduce(fn, init) | number | Parallel tree reduction. |
| forEach(fn) | void | Parallel iteration (side effects only). |
| slice(start?, end?) | GpuBuffer<T> | Sub-range — zero-copy view when possible. |
| toCpu() | T (the typed array) | Copies data back to CPU memory. Avoid in hot paths — it crosses the PCIe bus. |
| toArray() | number[] | Copies back as a plain JS array. Same cost warning. |
gpu (GpuApi)
Available as ctx.gpu inside handlers or imported as gpu from @symmetra/http.
| Member | Returns | What it does |
|---|---|---|
| fingerprint(data) | Promise<bigint> | Hashes a string or buffer entirely on GPU. |
| alloc<T>(length) | GpuBuffer<T> | Allocates a typed array in VRAM. |
| upload(data) | Promise<GpuBuffer<T>> | Uploads a CPU typed array to VRAM via pinned-memory DMA. |
| parallel(n, fn) | Promise<void> | Runs fn(tid) across n GPU threads — raw parallel kernel. |
| deviceName | string | e.g. "NVIDIA GeForce RTX 5070" |
| computeSm | string | Compute capability, e.g. "sm_120" |
| vramTotal / vramFree | number | VRAM in bytes. |
| streamCount | number | Active CUDA streams. |
GpuMap, GpuSet, GpuRegExp
Standard JavaScript Map, Set, and RegExp literals compile to VRAM-resident equivalents automatically. The interfaces match the standard built-ins — get/set/has/delete/clear/size, iteration, test/exec. RegExp literals compile to a GPU DFA at kernel-compile time, so there is no runtime regex JIT cost. Explicit constructors GpuMapOf(entries?) and GpuSetOf(values?) exist if you want to be explicit.
EventEmitter & Streams
EventEmitter matches the Node.js shape: on / once / off / emit / removeAllListeners / listenerCount. Event dispatch state lives in VRAM.
Streams follow the Node.js model — Readable, Writable, Transform, and pipeline(). Each pipeline stage maps to a VRAM ring buffer; data never leaves GPU memory between stages.
| API | Returns | Notes |
|---|---|---|
| Readable.from(path, opts?) | Readable | Wraps a file in a VRAM-backed readable stream. opts.chunkSize controls chunking. |
| Writable.toFile(path) | Writable | Writable stream that flushes to a file. |
| pipeline(source, ...stages) | Promise<void> | Connects source → transforms → destination; resolves when all data is flushed. |
| highWaterMark | — | Constructor option on all streams: VRAM ring-buffer capacity in chunks. Default 8. |
GpuWorker, MessageChannel, Atomics
GpuWorker maps to the Node.js worker_threads API. Each worker gets its own CUDA stream and an isolated VRAM slab.
| Member | Returns | What it does |
|---|---|---|
| new GpuWorker(path, opts?) | GpuWorker | opts.heapBytes (default 4 MB private VRAM), opts.shareGpuMemory, opts.name. |
| postMessage(data, transfer?) | void | Sends structured data. Transferred GpuBuffers move zero-copy — ownership transfers to the worker. |
| nextMessage<T>() | Promise<T> | Resolves with the next message from the worker. |
| terminate() | void | Stops the worker immediately. |
| sharedBuffer(byteLength) | SharedGpuBuffer | VRAM region visible to both parent and worker streams. |
| Atomics.add / sub / and / or / xor / load / store / exchange / compareExchange | number | Compile to CUDA atomic intrinsics (atomicAdd, atomicCAS, …) on shared VRAM. No CPU involved. |
URL, URLSearchParams, TextEncoder/Decoder, Timers, AbortController
- URL / URLSearchParams — standard WHATWG interfaces. Parsing happens CPU-side (not a hot path); parsed fields upload to the request's VRAM slab.
- TextEncoder.encode(str) returns a
GpuBuffer<Uint8Array>in VRAM — one GPU thread per code point. TextDecoder.decode(buf) reverses it. - setTimeout / setInterval / clearTimeout / clearInterval — standard signatures. A CPU min-heap fires callbacks onto a dedicated GPU timer stream.
- AbortController / AbortSignal — standard shape. The signal compiles to a VRAM flag;
abort()sets it instantly withcuMemsetD8. Kernels check the flag at yield points, and@symmetra/netrequests accept it.
@symmetra/kv VRAM key-value store
A key-value cache that lives in GPU memory. No Redis process, no DRAM round-trip, no serialization between your handler and the store.
import { KvStore } from '@symmetra/kv'
// Instantiate at module scope — maps to a VRAM allocation
const cache = new KvStore({ maxMb: 256, namespace: 'app' })
| Method | Returns | What it does |
|---|---|---|
| get<T>(key) | Promise<T | null> | Reads a value. null when missing or expired. |
| set<T>(key, value, opts?) | Promise<void> | Writes a value. opts.ttlMs sets expiry in milliseconds. |
| del(key) | Promise<void> | Deletes a key. |
| has(key) | Promise<boolean> | Existence check. |
| stats() | Promise<{hits, misses, evictions, sizeBytes}> | Cache statistics. |
Constructor options: maxMb (VRAM budget, default 256) and namespace (key prefix, default empty). The per-request ctx.kv exposes the same API plus keys(pattern?).
Measured behavior (beta, 128 of 6,144 CUDA cores): on our RTX 5070 test rig, a handler doing one KV set + one KV get per request sustained ~3.5K req/s at 6.4ms median — cooperative GPU↔CPU I/O has real cost. Cache-friendly patterns (e.g. memoized Fibonacci) measured ~5.9K req/s at 553µs median.
@symmetra/db Database clients
Typed clients for PostgreSQL, SQLite, and Redis. Database I/O is handled by the CPU side of the runtime (the GPU requests it cooperatively), so treat these as standard async clients.
import { postgres, sqlite, redis } from '@symmetra/db'
postgres(config) → PgClient
| Method | Returns | Notes |
|---|---|---|
| query<T>(sql, params?) | Promise<PgResult<T>> | PgResult = { rows: T[], rowCount, fields } |
| queryOne<T>(sql, params?) | Promise<T | null> | First row or null. |
| prepare<T>(name, sql) | Promise<PreparedStatement<T>> | Statement has execute(), executeOne(), close(). |
| transaction<T>(fn) | Promise<T> | Runs fn inside BEGIN/COMMIT; the passed client adds rollback(). |
| close() | Promise<void> | Closes the pool. |
Config: host, port, database, user, password, ssl?, maxConnections?, idleTimeoutMs?.
sqlite(options) → SqliteClient — options: path, readOnly?, walMode?. Same query/queryOne/execute shape (SqliteResult adds lastInsertRowid and changes), plus one GPU-specific method:
| tableToGpu<T>(sql, params?) | Promise<GpuBuffer<T>> | Runs a query and uploads the numeric result column(s) straight into VRAM — query once, compute many times on GPU. |
redis(config?) → RedisClient — standard command set: get, set (with ex/px/nx/xx options), del, exists, expire, ttl, incr, incrBy, hashes (hset/hget/hgetall), sets (sadd/smembers/sismember), lists (lpush/rpush/lrange), and pipeline() for batched commands ending in exec() → Promise<(string|number|null)[]>.
@symmetra/fs Filesystem
import { fs, jsonFs } from '@symmetra/fs'
| Method | Returns | What it does |
|---|---|---|
| fs.read(path, { encoding: 'utf8' }) | Promise<string> | Reads a text file. |
| fs.read(path) | Promise<GpuBuffer<Uint8Array>> | Binary read — lands directly in VRAM. offset/length options for partial reads. |
| fs.write(path, data, opts?) | Promise<void> | Accepts string | Uint8Array | GpuBuffer. opts.flag: 'w' | 'wx' | 'a' | 'ax'. |
| fs.append(path, data) | Promise<void> | Appends. |
| fs.stat(path) | Promise<FileStat> | { size, isFile, isDirectory, isSymlink, modifiedAt, createdAt } |
| fs.exists(path) | Promise<boolean> | — |
| fs.delete / fs.rename / fs.copy | Promise<void> | — |
| fs.mkdir(path, opts?) / fs.rmdir(path, opts?) | Promise<void> | opts.recursive supported on both. |
| fs.readdir(path) | Promise<{name, type}[]> | type is 'file' | 'dir' | 'symlink' |
| fs.watch(path, opts?) | AsyncIterable<WatchEvent> | for await-able change events: { type: 'create'|'modify'|'delete'|'rename', path }. opts.signal stops it. |
| jsonFs.read<T>(path) | Promise<T> | Read + parse JSON in one call. |
| jsonFs.write(path, value, opts?) | Promise<void> | Stringify + write. opts.pretty formats output. |
@symmetra/crypto Cryptography
import { hash, cipher, kdf, random, jwt, password } from '@symmetra/crypto'
| API | Returns | What it does |
|---|---|---|
| hash.hash(alg, data) | Promise<string> | Hex digest. alg: 'sha256' | 'sha512' | 'blake3'. Accepts strings, bytes, or GpuBuffers. |
| hash.hmac(alg, key, data) | Promise<string> | Keyed HMAC digest. |
| hash.batchHash(alg, items) | Promise<GpuBuffer<Uint8Array>> | Hashes many VRAM buffers in one parallel dispatch. |
| hash.compare(a, b) | boolean | Constant-time comparison — use for digests/tokens, never ===. |
| cipher.encrypt(alg, key, plaintext) | Promise<{ciphertext, iv, tag}> | AEAD encryption. alg: 'aes-256-gcm' | 'chacha20-poly1305'. |
| cipher.decrypt(alg, key, ciphertext, iv, tag) | Promise<Uint8Array> | Throws if the auth tag doesn't verify. |
| cipher.encryptString / decryptString | Promise<string> | Same, but packs iv+tag+ciphertext into one encoded string for easy storage. |
| kdf.pbkdf2(password, salt, opts?) | Promise<string> | opts: iterations, keyLength, algorithm. |
| kdf.argon2id(password, salt?, opts?) | Promise<string> | opts: memoryCost, timeCost, parallelism, keyLength. |
| kdf.hkdf(inputKey, salt, opts?) | Promise<Uint8Array> | Key derivation for protocols. |
| random.bytes(n) / hex(n?) / uuid() / int(min?, max?) | varies | Cryptographically secure randomness. |
| jwt.sign(payload, secret, opts?) | Promise<string> | opts: algorithm (HS256/HS512/RS256/ES256), expiresIn, issuer, audience. |
| jwt.verify<T>(token, secret) | Promise<T> | Throws on invalid signature or expiry. |
| jwt.decode<T>(token) | T | null | Decodes without verifying — never trust this alone. |
| password.hash(pw) / password.verify(pw, hash) | Promise<string> / Promise<boolean> | Opinionated password hashing — use these instead of raw KDFs for login flows. |
@symmetra/env Configuration
import { env, config } from '@symmetra/env'
// Schema-validated, fully typed environment loading
const settings = env.load({
PORT: { type: 'port', default: 8080 },
DATABASE_URL: { type: 'url', required: true },
DEBUG: { type: 'boolean', default: false },
})
// settings.PORT is number, settings.DATABASE_URL is string, settings.DEBUG is boolean
| API | Returns | What it does |
|---|---|---|
| env.load(schema, opts?) | typed object | Validates env vars against a schema. Field types: string, number, boolean, url, email, port. Per-field: required, default, min/max, pattern, choices. Throws with a clear message when validation fails. |
| env.get(key, default?) | string | undefined | Raw read with optional fallback. |
| env.getNumber / env.getBoolean | number/boolean | undefined | Coerced reads. |
| env.require(key) | string | Throws if the variable is missing. |
| env.all() | Record<string,string> | Everything. |
| config.loadJson<T>(path) / loadToml<T>(path) | Promise<T> | Typed config file loading. |
| config.watch<T>(path, cb) | () => void | Calls cb with re-parsed config on file change. Returns an unsubscribe function. |
@symmetra/net Networking
import { http, connect, createUdp, websocket, dns } from '@symmetra/net'
http — outbound HTTP client. All methods return Promise<HttpResponse> where the response has status, ok, headers, and body accessors text(), json<T>(), bytes():
| http.get(url, opts?) | Promise<HttpResponse> | opts: headers, timeout, followRedirects, maxRedirects, body. Outbound requests are dispatched to a dedicated CPU fetch pool so GPU I/O threads stay free. |
| http.post / put / patch(url, body?, opts?) | Promise<HttpResponse> | |
| http.delete(url, opts?) / http.fetch(url, opts?) | Promise<HttpResponse> |
Measured behavior (beta): a handler that performs an outbound fetch back into itself (full GPU → CPU → GPU round trip) measured ~166 req/s at 30ms median on our test rig. Outbound I/O is the most expensive thing a handler can do — cache aggressively.
connect(options) → Promise<TcpSocket> — raw TCP with optional TLS. Socket: write(), read(length?), readLine(), readAll(), close(), plus connected, remoteAddress, remotePort.
createUdp(options?) → Promise<UdpSocket> — send(data, host, port), receive() → { data, remoteAddress, remotePort }, close(). Supports broadcast and multicast groups.
websocket(url, options?) → Promise<WebSocket> — send(), receive() → { type: 'text'|'binary'|'close'|'ping', data }, close(code?, reason?), and a readyState property.
dns — resolve(hostname, type?), lookup(hostname), reverse(ip), records(hostname, type) for A/AAAA/CNAME/MX/TXT/NS records.