Skip to content

Builtins & Globals ​

Weld has no importable standard library — the useful primitives are built into the language. This page is the exhaustive reference: every builtin function, every builtin statement, and every builtin type/global the compiler recognises. Signatures are written in Weld type notation (T? optional, [T] list, [K: V] map, T! fallible).

Everything here is checked by the compiler: a wrong argument type or arity is a compile-time error, not a runtime surprise.

String functions ​

All string builtins are pure and total (they never fail).

SignatureReturnsDescription
upper(s: string) -> stringuppercased copyASCII upper-case.
lower(s: string) -> stringlowercased copyASCII lower-case.
trim(s: string) -> stringtrimmed copyStrip leading and trailing ASCII whitespace.
trimPrefix(s: string, prefix: string) -> strings without prefixIf s starts with prefix, drop it; otherwise return s unchanged.
contains(s: string, needle: string) -> boolboolIs needle a substring of s?
startsWith(s: string, prefix: string) -> boolboolDoes s begin with prefix?
endsWith(s: string, suffix: string) -> boolboolDoes s end with suffix?
parseInt(s: string) -> intintParse a base-10 integer (invalid input yields 0).
weld
route GET "/normalize/:raw" (raw: string) -> string {
    let name = trim(lower(raw))
    let tag  = trimPrefix(name, "user-")     # "user-ada" -> "ada"
    respond "name={name} tag={tag} isuser={startsWith(name, "user-")} n={parseInt("42")}"
}

For building strings, use + concatenation and {expr} interpolation — see Expressions & Control Flow. For string → enum, use the enum reinterpreter below.

Conversion functions ​

SignatureReturnsDescription
str(x: int | float | bool | string | Enum) -> stringstringRender any primitive or enum as text. On an enum it yields the variant's string label.
int(e: Enum) -> intintThe enum variant's underlying number. (For string -> int, use parseInt.)
hash(x: int | float | bool | string | Enum) -> intintA stable 64-bit hash (Wyhash). The building block for hash maps written in Weld.
Enum(x: int | string) -> Enumthe enumEnum reinterpreter — turn a number or string back into an enum value; an unknown input becomes the zero Unspecified variant. Enum is the name of any enum you declared.
weld
enum Role { Admin = 1 : "admin", User = 2 : "user" }

route GET "/role/:name" (name: string) -> string {
    let r = Role(name)                       # string -> enum (unknown -> Unspecified)
    respond "label={str(r)} number={int(r)} again={str(Role(int(r)))} hash={hash(r)}"
}

See Enums & Sum Types for the full enum model.

List functions ​

[T] is a mutable list (a Zig slice). Indexing (xs[i]) is bounds-checked — an out-of-range index is a recoverable error that fails the request rather than crashing the server.

SignatureReturnsDescription
len(xs: [T]) -> intintNumber of elements.
push(xs: [T], v: T) -> [T]a new listAppend v, returning the grown list. push returns the result — assign it back: xs = push(xs, v).
filled(n: int, v: T) -> [T][T] of length nPreallocate a list of n copies of v.
slice(xs: [T], start: int, end: int) -> [T][T]The sub-range [start, end), clamped to bounds (a bad range yields an empty list, never a crash).
pop(xs: [T]) -> [T][T]The list without its last element; an empty list stays empty.
concat(a: [T], b: [T]) -> [T][T]The two lists joined; element types must match.
reverse(xs: [T]) -> [T][T]The list reversed.
contains(xs: [T], v: T) -> boolboolIs v an element of xs? For primitive or enum element types (strings compared by value).
sort(xs: [T]) -> [T][T]The list sorted ascending. T must be int, float, or string.
insert(xs: [T], i: int, v: T) -> [T][T]A new list with v inserted at index i (clamped to [0, len]).
removeAt(xs: [T], i: int) -> [T][T]A new list without the element at index i (out-of-range: unchanged).
map(xs: [T], f: x => U) -> [U][U]Each element transformed by the closure f.
filter(xs: [T], p: x => bool) -> [T][T]The elements for which the predicate p is true.
reduce(xs: [T], init: A, f: (acc, x) => A) -> AAFold left: start from init, combine each element into the accumulator.

All of these are also methods — xs.op(…) is the same as op(xs, …), and reads better when chained: xs.filter(x => x > 0).map(x => x * 2).sort(). The higher-order ops take closures: a one-parameter x => … for map/filter, and a two-parameter (acc, x) => … combiner for reduce.

weld
route GET "/build/:n" (n: int) -> string {
    var xs = filled(3, 0)          # [0, 0, 0]
    xs = push(xs, n)               # [0, 0, 0, n]
    xs = concat(xs, [1, 2])        # [0, 0, 0, n, 1, 2]
    xs = slice(xs, 2, len(xs))     # drop the first two
    xs = reverse(pop(xs))          # drop the last, then reverse
    xs[0] = 100                    # index-assign (bounds-checked)
    var total = 0
    for i, x in xs { total = total + x + i }   # indexed iteration
    respond "len={len(xs)} first={xs[0]} has100={contains(xs, 100)} total={total}"
}

The higher-order ops read best as a method chain:

weld
route GET "/stats" -> string {
    let xs = [5, 3, 8, 1, 9, 2]
    let bigs = xs.filter(x => x > 3).map(x => x * 10)   # [50, 80, 90]
    let total = xs.reduce(0, (acc, x) => acc + x)       # 28
    let ranked = xs.sort()                              # [1, 2, 3, 5, 8, 9]
    respond "n_big={len(bigs)} total={total} min={ranked[0]} max={ranked[len(ranked) - 1]}"
}

An empty list literal takes its element type from context — a declared type, a return type, filled, or the left of a ??: let seen = maybe ?? [].

Map functions ​

[K: V] is a hash map with string or int keys. A lookup m[k] yields V? (null when the key is absent); m[k] = v inserts or overwrites.

SignatureReturnsDescription
len(m: [K: V]) -> intintNumber of entries.
has(m: [K: V], k: K) -> boolboolIs k present?
remove(m: [K: V], k: K) -> boolboolRemove k; returns whether it was present.

Iterate with for k, v in m { … }. Maps are commonly stored in state so they persist across requests.

weld
state counts { var hits: [string: int] = [:] }

route GET "/hit/:page" (page: string) -> string {
    let n = (counts.hits[page] ?? 0) + 1     # m[k] -> V?, ?? gives a default
    counts.hits[page] = n
    if has(counts.hits, "admin") { let _ = remove(counts.hits, "admin") }
    respond "{page}={n} total_pages={len(counts.hits)}"
}

Environment & time ​

SignatureReturnsDescription
env(name: string) -> stringstringRead an environment variable (empty string if unset). Used for configuration — database URLs, secrets, upstream bases.
now_ms() -> intintCurrent Unix time in milliseconds. Available anywhere.
ready() -> boolbooltrue normally, false once the server is draining (SIGTERM received). Serve it from a readiness probe so the load balancer stops routing before shutdown — see Graceful shutdown.

env() is the idiomatic way to configure the resource blocks:

weld
database db { url env("DATABASE_URL") }
upstream api { base env("BACKEND_URL") }
grpc Svc { addr env("GRPC_ADDR") }

Request context ​

These read from the in-flight HTTP request, so they are only valid inside a route handler or a decorator (using them elsewhere is a compile-time error).

SignatureReturnsDescription
request_header(name: string) -> string?string?A request header value, or null if absent. Case-insensitive name.
request_cookie(name: string) -> string?string?A cookie value from the request's Cookie header, or null if absent.
client_ip() -> stringstringThe client IP, honouring X-Forwarded-For / X-Real-IP when present.
weld
route GET "/whoami" -> string {
    let ua = request_header("User-Agent") ?? "unknown"
    let sid = request_cookie("session") ?? "anonymous"
    respond "ip={client_ip()} agent={ua} session={sid} at={now_ms()}"
}

These are the primitives that rate limiting and auth are built from — in Weld itself, with no dedicated middleware.

Form bodies & file uploads ​

Read a submitted HTML form or file upload from the request body. All return an optional (null when the field is absent), so pair them with ?? or else.

SignatureReturnsDescription
form_field(name: string) -> string?string?A field from a application/x-www-form-urlencoded or multipart/form-data body (auto-detected by Content-Type; urlencoded values are %/+-decoded).
upload(name: string) -> string?string?A multipart file part's raw bytes (binary-safe).
upload_filename(name: string) -> string?string?The filename of a multipart file part.
weld
route POST "/upload" -> string {
    let file = upload("file") else { fail 400 "no file part" }
    let name = upload_filename("file") ?? "upload.bin"
    let note = form_field("note") ?? ""
    respond "stored {name} ({len(file)} bytes), note: {note}"
}

The buffered body (JSON body params, form_field, upload) is capped by MAX_BODY_SIZE (default 8 MB). For larger inputs, stream instead.

Streaming the request body ​

SignatureReturnsDescription
request_body() -> Stream<string>a stream of chunksThe raw request body as a stream of byte chunks, consumed by for chunk in request_body() { … }. Read in constant memory — the whole body is never buffered, so it handles inputs far larger than MAX_BODY_SIZE.
weld
route POST "/measure" -> string {
    var bytes = 0
    for chunk in request_body() {          # each chunk is a slice of raw bytes
        bytes = bytes + len(chunk)
    }
    respond "received {bytes} bytes"
}

A streaming route cannot also declare a JSON body parameter (that needs the whole body); read what you need from the chunks instead.

JWT ​

HS256 JSON Web Tokens. The first argument is a record type naming the claims to decode the payload into; the compiler checks it and produces a value of that type.

SignatureReturnsDescription
jwt_sign(claims: Record, secret: string) -> stringstringSign a claims record as an HS256 token. The record's fields become the payload — include exp/iat/nbf as int fields (Unix seconds) to set the standard claims.
jwt_verify(Type, token: string, secret: string) -> Type!Type! (fallible)Verify the HS256 signature (constant-time) and decode the payload into Type. A bad signature, a malformed token, an expired exp, or a not-yet-valid nbf all fail — combine with try/else.
jwt_decode(Type, token: string) -> Type?Type? (optional)Decode the payload without verifying. null on a malformed token. Use only when another layer already established trust.

When the claims Type carries exp/nbf as plain int fields, jwt_verify enforces them automatically (an expired token becomes a 401).

weld
type Claims = { sub: string, exp: int }

route GET "/login/:user" (user: string) -> string {
    let claims = Claims { sub: user, exp: now_ms() / 1000 + 3600 }
    respond jwt_sign(claims, env("JWT_SECRET"))     # issue a 1-hour token
}

route GET "/me" (query token: string) -> Claims {
    let claims = try jwt_verify(Claims, token, env("JWT_SECRET"))   # rejects expired/tampered
    respond claims
}

Unknown JSON fields in the payload are ignored, so your Claims record only needs the fields you use.

Crypto & encoding ​

Hashing, HMAC, secure randomness, password hashing, and encodings — the building blocks of tokens, sessions, and signatures. Hex/base64 outputs are lowercase; decoders return "" on malformed input (like parseInt returning 0).

SignatureReturnsDescription
password_hash(pw: string) -> stringstringA bcrypt hash (cost 10) with a random salt — the $2b$… string to store.
password_verify(pw: string, hash: string) -> boolboolCheck a password against a stored bcrypt hash (constant-time).
random_bytes(n: int) -> bytesbytesn cryptographically-secure random bytes. Encode (hex/base64) before storing or sending as text.
uuid() -> stringstringA random v4 UUID, e.g. 2f1f4051-1790-443d-bc97-86daac32cbec.
sha256(data) -> stringstringLowercase-hex SHA-256 digest (64 chars). data is a string or bytes.
hmac_sha256(msg, key) -> stringstringLowercase-hex HMAC-SHA-256 (64 chars). Args are string or bytes.
base64_encode(data) -> string / base64_decode(s: string) -> bytes—Standard Base64 (with padding). Encoders take string/bytes; decoders yield bytes.
base64url_encode(data) -> string / base64url_decode(s) -> bytes—URL-safe Base64, no padding (as used in JWTs).
hex_encode(data) -> string / hex_decode(s) -> bytes—Lowercase hex.
base32_encode(data) -> string / base32_decode(s) -> bytes—RFC 4648 Base32 (for TOTP secrets, authenticator apps).
encrypt(key, data) -> bytesbytesAES-256-GCM authenticated encryption. key is hashed to 32 bytes; output is nonce ‖ ciphertext ‖ tag.
decrypt(key, data) -> bytes?bytes?Decrypt & authenticate; null on a wrong key or tampered data.
seal(key, data) -> string / unseal(key, token) -> bytes?—Like encrypt/decrypt but the token is compact base64url — handy for signed+encrypted cookies.
totp(secret) -> stringstringCurrent 6-digit TOTP code (RFC 6238, 30 s window, HMAC-SHA1).
totp_verify(secret, code) -> boolboolCheck a code against the current window ±1 (clock-skew tolerant).
es256_keygen() -> string / es256_public(priv) -> stringstringGenerate an ECDSA P-256 private key (hex), and derive its SEC1 public key (hex).
jwt_sign_es256(claims, priv) -> stringstringSign a claims record as an ES256 (asymmetric) JWT with a hex private key.
jwt_verify_es256(T, token, pub) -> T!T!Verify an ES256 JWT with the hex public key and decode into T (enforces exp/nbf).
pem_key(pem) -> stringstringExtract a P-256 key from PEM (SEC1/PKCS#8 private, or SPKI public) into the hex the es256_*/jwt_*_es256 builtins accept; "" on a malformed PEM.
to_bytes(s: string) -> bytes / to_string(b: bytes) -> string—Reinterpret text ⇄ raw bytes (no copy).
read_file(path: string) -> bytes?bytes?Read a file's contents (up to 16 MiB) as bytes; null if it can't be read. Serve a file with respond read_file(...) else { … } plus type/header. Beware path traversal — never pass unvalidated request input as the path.
read_file_stream(path: string) -> Stream<bytes>a stream of chunksStream a file's bytes chunk-by-chunk (constant memory, any size), consumed by for chunk in read_file_stream(path) { emit chunk } — for chunked file downloads. No chunks if the file can't open. Same path-traversal caveat as read_file.
ice_servers(id: string, ttl: int) -> stringstring (JSON)Browser-ready RTCConfiguration JSON with a short-lived TURN-REST credential (valid ttl seconds) for the turn relay. Requires a turn { } block.
weld
type Creds = { username: string, password: string }

state accounts { var hashes: [string: string] = [:] }

route POST "/register" (body creds: Creds) -> string {
    accounts.hashes[creds.username] = password_hash(creds.password)   # bcrypt
    respond "token={hex_encode(random_bytes(24))} id={uuid()}"        # opaque token + id
}

route POST "/login" (body creds: Creds) -> string {
    let stored = accounts.hashes[creds.username] ?? ""
    if !password_verify(creds.password, stored) { fail 401 "invalid credentials" }
    respond "signature={hmac_sha256(creds.username, env("HMAC_KEY"))}"
}

hash() (above, under Conversion) is Wyhash — fast but not cryptographic; never use it for passwords or signatures. Reach for password_hash or hmac_sha256/sha256 instead.

Files & directories (std) ​

Low-level file I/O and filesystem queries, namespaced under std. Paths are resolved relative to the server process's working directory. File descriptors are plain ints (< 0 means the open failed). Reads and writes stream, so you can move files of any size in constant memory. For a self-contained whole-file download, read_file/read_file_stream (above) are simpler; these are the building blocks when you manage the descriptor yourself (e.g. writing an upload straight to disk).

SignatureReturnsDescription
std.open_file_write(path: string) -> intfd, or -1Create/truncate path for writing and return its descriptor.
std.open_file_read(path: string) -> intfd, or -1Open path for reading and return its descriptor.
std.write(fd: int, data: bytes) -> intbytes written, or -1Write data (a string or bytes) to the descriptor.
std.read_stream(fd: int) -> Stream<bytes>a stream of chunksRead the descriptor chunk-by-chunk, consumed by for chunk in std.read_stream(fd) { … }. Closes fd when the stream is exhausted.
std.close(fd: int)—Close a descriptor (a no-op for fd < 0).
std.file_exists(path: string) -> boolboolDoes path exist and is it reachable?
std.is_file(path: string) -> boolboolIs path a regular file?
std.is_dir(path: string) -> boolboolIs path a directory?
std.make_dir(path: string) -> boolboolCreate a directory and any missing parents (like mkdir -p); true on success or if it already exists.
std.delete_file(path: string) -> boolboolDelete a file; true if it was removed, false if it was missing or couldn't be deleted.
std.list_dir(path: string) -> [string][string]The entry names in a directory (empty if it can't be read).

Stream an upload straight to disk, then stream it back — constant memory in both directions:

weld
route POST "/files/:name" (name: string) -> string {
    let fd = std.open_file_write("uploads/{name}")
    if fd < 0 { fail 500 "cannot open file" }
    for chunk in request_body() {                 # raw body, chunk by chunk
        if std.write(fd, chunk) < 0 { std.close(fd)  fail 500 "write failed" }
    }
    std.close(fd)
    respond "stored {name}"
}

route GET "/files/:name" (name: string) -> bytes {
    let path = "uploads/{name}"
    if !std.file_exists(path) { fail 404 "no such file" }
    let fd = std.open_file_read(path)
    type "application/octet-stream"
    for chunk in std.read_stream(fd) { emit chunk }   # closes fd at EOF
}

WARNING

path is used verbatim — never pass unvalidated request input (a caller could send ../etc/passwd). Confine writes to a directory you control and validate or replace the name, as the upload route does by only using the :name segment inside uploads/.

Statements ​

Weld handlers are made of statements. These keywords are the statement vocabulary.

Response statements ​

Valid inside a route handler.

StatementEffect
respond ExprSend the value and finish the handler. A record/list/sum encodes as JSON (application/json); a string is sent as text; a number/bool is rendered.
status <int | HttpStatus>Set the HTTP status code (default 200). Takes an int (status 404) or a value of the built-in std.HttpStatus enum (status std.HttpStatus.NotFound).
type <string | MimeType>Set the Content-Type header (default text/plain). Takes a literal string (type "application/json") or a value of the built-in std.MimeType enum (type std.MimeType.Json) to avoid mis-spelling common types.
header Name ValueAdd an arbitrary response header (both strings), e.g. header "Cache-Control" "no-store". Use for CORS, caching, or a raw Set-Cookie. Also valid in a decorator.
cookie Name ValueSet a Set-Cookie with secure session defaults (Path=/; HttpOnly; SameSite=Lax). For full control (Max-Age, Secure) use header "Set-Cookie" "…".
emit ExprStream one chunk (a string or bytes) via HTTP chunked transfer; the body is never fully buffered. Repeatable — e.g. for chunk in read_file_stream(path) { emit chunk } for a chunked download. Any type/header/cookie (and configured CORS headers) set before the first emit are carried in the chunked reply's head; a respond before the first emit is a terminal early bail-out (sends a normal buffered reply and returns).
serve BASE SUBSend the file at BASE/SUB; content type inferred from the extension, 404 if missing, 403 on a .. traversal.
fail STATUS MESSAGEShort-circuit with an error response. STATUS is any int expression (a literal, a variable, or a std.HttpStatus value like std.HttpStatus.NotFound); MESSAGE is any string expression. Also usable in decorators, hubs, and transactions. In a typed-error function, fail Variant(…) raises a typed value instead.
weld
route GET "/report" {
    type std.MimeType.Text   # or: type "text/plain; charset=utf-8"
    status 200
    emit "line 1\n"
    emit "line 2\n"          # each emit is flushed immediately
}

route GET "/assets/*path" (path: string) {
    serve "public" path       # ./public/<path>
}

The std namespace ​

std is the built-in standard-library namespace. Its members are ordinary proto-style enums, referenced with the std. prefix (there is no bare MimeType — only std.MimeType). They need no import, work with str() / int() / Mime(s)-style reinterpretation like any enum, and only appear in the generated code when you reference them.

std.MimeType — well-known content types, so you write type std.MimeType.Json instead of a mis-spellable "application/json". Each variant's string is the MIME type (str(std.MimeType.Html) → "text/html; charset=utf-8"). std.MimeType.Bytes (application/octet-stream) is the zero/fallback.

VariantContent typeVariantContent type
.Jsonapplication/json.Bytesapplication/octet-stream
.Htmltext/html; charset=utf-8.Texttext/plain; charset=utf-8
.Csstext/css; charset=utf-8.Jstext/javascript; charset=utf-8
.Xmlapplication/xml.Yamlapplication/yaml
.Csvtext/csv; charset=utf-8.EventStreamtext/event-stream
.Formapplication/x-www-form-urlencoded.Multipartmultipart/form-data
.Pngimage/png.Jpegimage/jpeg
.Gifimage/gif.Webpimage/webp
.Svgimage/svg+xml.Icoimage/x-icon
.Pdfapplication/pdf.Wasmapplication/wasm
.Zipapplication/zip.Gzipapplication/gzip
.Woff2font/woff2.Mp4video/mp4
.Mpegaudio/mpeg

std.HttpStatus — named status codes, so you write status std.HttpStatus.NotFound instead of 404. Each variant's number is the code (used by status) and its string is the reason phrase (str(std.HttpStatus.NotFound) → "Not Found"). Covers the common 1xx–5xx codes: .Continue, .SwitchingProtocols, .Ok, .Created, .Accepted, .NoContent, .PartialContent, .MovedPermanently, .Found, .SeeOther, .NotModified, .TemporaryRedirect, .PermanentRedirect, .BadRequest, .Unauthorized, .Forbidden, .NotFound, .MethodNotAllowed, .NotAcceptable, .RequestTimeout, .Conflict, .Gone, .PayloadTooLarge, .UnsupportedMediaType, .UnprocessableEntity, .TooManyRequests, .InternalServerError, .NotImplemented, .BadGateway, .ServiceUnavailable, .GatewayTimeout.

Bindings & assignment ​

StatementEffect
let name [: T] = ExprImmutable binding. Optional explicit type.
var name [: T] = ExprMutable binding.
name = ExprReassign a var.
obj.field = ExprAssign a record field (through a mut self or a state field).
xs[i] = ExprList index-assign (bounds-checked).
m[k] = ExprMap insert / overwrite.
let _ = ExprEvaluate for effect and discard (e.g. an ignored fallible result).

Control flow ​

StatementEffect
if C { … } else if C2 { … } else { … }Conditional. else if / else are optional.
for x in Iterable { … }Iterate a list, a stream, or any type with a next(mut self) -> T? method.
for i, x in List { … }Iterate a list with a 0-based int index i and the element x.
for k, v in Map { … }Iterate a map's key/value pairs.
return [Expr]Return from a fn (bare return in a void fn).
assert CondIn a test block, assert a boolean; a failing assert fails the test run.
transaction db { … }Run the body inside a Postgres BEGIN/COMMIT, rolling back on any failure.

match is an expression, not a statement — see below.

Fallible & optional handling ​

FormEffect
try ExprEvaluate a fallible T!; on failure, propagate (auto error response in a route, .err in a fallible fn). Yields the unwrapped T.
let x = Expr else e { … }Handle a fallible failure: e is bound to the error (Error, or the declared typed error) and the block must diverge (respond/fail/return).
let x = Expr else { … }Unwrap an optional T?; the block runs (and must diverge) when the value is null.
weld
route GET "/u/:id" (id: int) -> User {
    let u = db.findUser(id) else e {         # fallible: bind the Error
        status 404
        respond "not found: {e.message}"
    }
    let email = u.email else { fail 400 "no email on file" }   # optional: unwrap or fail
    respond User { id: u.id, name: u.name, email: email }
}

See Error Handling for the full model.

Hub surface ​

These are only meaningful inside a WebSocket hub. They manage a connection's identity/membership and let you push server-initiated events.

Per-connection operations ​

Valid inside a hub's connect block or a method. Each acts on the current connection.

SignatureEffect
identify(id: string)Tag this connection with an identity (e.g. a user id) so it can be targeted by c.identity.
join(group: string)Add this connection to a named listener group.
leave(group: string)Remove this connection from a group.

Broadcasting to clients ​

Hub.clients (where Hub is your hub's name) is a queryable set of live connections. Filter it, then push an event to the survivors.

ExpressionMeaning
Hub.clientsThe set of all connected clients.
.filter(c => Bool)Keep connections matching a predicate. Chainable.
.send(Record)Push a record to each connection as {"event":"<TypeName>","data":{…}}.
.count() -> intThe number of live connections (after any .filter). Also valid in a plain route handler.

A hub may also declare a disconnect { … } block that runs when a socket drops — the connect-time injected bindings stay in scope, so it can broadcast a departure, but it has no client to reply to. See WebSocket Hubs.

Inside a filter predicate the parameter (c) is a connection handle:

Field / methodTypeMeaning
c.identitystringThe connection's identify(…) tag.
c.idintA stable per-connection id.
c.subscribed(group: string) -> boolboolIs the connection in group?
c.<injected>injected typeAny binding from the hub's connect (…) injects (x: T) clause, e.g. c.user.
weld
type Notice = { text: string }

hub Chat {
    connect (query token: string, query room: string) injects (user: Claims) {
        user = try jwt_verify(Claims, token, env("JWT_SECRET"))
        identify(user.sub)                    # target by user id later
        join(room)                            # add to the room group
        Chat.clients.filter(c => c.subscribed(room))
            .send(Notice { text: "{user.sub} joined" })
    }

    method dm(to: string, text: string) {
        Chat.clients.filter(c => c.identity == to)   # a direct message
            .send(Notice { text: text })
    }
}

Builtin types & globals ​

NameKindDescription
intprimitive64-bit signed integer. Arithmetic wraps on overflow.
floatprimitive64-bit floating point.
boolprimitivetrue / false.
stringprimitiveUTF-8 text (a byte slice).
T?type formerOptional — the value or null.
[T]type formerMutable list.
[K: V]type formerMap (K is string or int).
T!type formerFallible result (carries Error or a declared typed error).
Errorbuiltin record{ status: int, message: string }. The error a bare else e { … } binds, and the shape of the automatic error response. You can construct and read it like any record.
Selfbuiltin typeInside an interface method signature or a generic method, refers to the implementing type.
nullliteralThe absent value of any T?.
injected bindingsvalueNames introduced by a decorator's or hub's injects (…) clause (e.g. user), typed and in scope in the handler/method body.

Sum-type variants are constructed qualified — Shape.Circle(2.0), Role.Admin — and matched unqualified. Sum types and the Error type together power typed errors.

Quick index ​

  • Strings: upper · lower · trim · trimPrefix · contains · startsWith · endsWith · parseInt
  • Conversion: str · int · hash · Enum(x)
  • Lists: len · push · filled · slice · pop · concat · reverse · contains · sort · insert · removeAt · map · filter · reduce (all callable as xs.op(…))
  • Maps: len · has · remove
  • Env & time: env · now_ms
  • Request: request_header · request_cookie · client_ip · form_field · upload · upload_filename · request_body
  • JWT: jwt_sign · jwt_verify · jwt_decode (HS256) · jwt_sign_es256 · jwt_verify_es256 · es256_keygen · es256_public · pem_key (ES256)
  • Crypto & encoding: password_hash · password_verify · random_bytes · uuid · sha256 · hmac_sha256 · encrypt · decrypt · seal · unseal · totp · totp_verify · base64_encode · base64_decode · base64url_encode · base64url_decode · hex_encode · hex_decode · base32_encode · base32_decode
  • Bytes & files: to_bytes · to_string · read_file · read_file_stream (see the bytes type)
  • Files & dirs (std): std.open_file_write · std.open_file_read · std.write · std.read_stream · std.close · std.file_exists · std.is_file · std.is_dir · std.make_dir · std.delete_file · std.list_dir
  • Hub: identify · join · leave · Hub.clients.filter(…).send(…) · .count()
  • WebRTC: ice_servers (with a turn { } block)
  • Statements: respond · status · type · header · cookie · emit · serve · fail · let · var · if · for · match · return · assert · transaction · try · else