Signatures below describe checked types. Builtins are reserved names. Argument count/type failures occur at compile time. Runtime conversion failures unwind; HTTP handlers return 500 unless the failure is explicitly a client-body error.
Pure functions
| Function | Return | Behavior |
|---|---|---|
json(value) |
Json | Encode a serializable primitive, struct, enum or supported container |
println(value) |
void | Print serializable values and newline; app output goes to stderr |
assert(condition: bool) |
void | Unwind if false; language tests report failure |
len(value: String) |
i64 | Unicode scalar count, not bytes or graphemes |
len(value: Json) |
i64 | Array/object length or JSON string scalar count; other kinds fail |
json_get(value: Json, key: String) |
Json | Object field; missing/wrong container returns null |
json_at(value: Json, index: i64) |
Json | Zero-based array value; invalid index/container returns null |
json_kind(value: Json) |
String | null, number, bool, string, array, or object |
as_string(value: Json) |
String | Checked string conversion |
as_i64(value: Json) |
i64 | Checked integer conversion within i64 range |
as_bool(value: Json) |
bool | Checked boolean conversion |
json_parse(value: String) |
Json | Parse valid JSON; invalid JSON fails |
secure_eq(a: String, b: String) |
bool | Constant-time content comparison using subtle; differing lengths may be distinguished |
response(status: i64, body: Json) |
Response | JSON response; status must be 200..599 |
text_response(status: i64, body: String) |
Response | Text response; same status bounds |
JSON strings escape control characters correctly. Parsed numbers preserve
their JSON numeric spelling with the backend’s arbitrary-precision JSON parser;
arithmetic in the language still requires i64. Serializable structs support strict codecs. Use response_header for custom headers. Cookie/session authentication is an application responsibility.
Request and environment APIs
These are permitted only inside apps and their private helpers. Each handler has a thread-local request context; it cannot read another request’s context.
| Function | Return | Behavior |
|---|---|---|
request_text() |
String | Entire bounded body; invalid UTF-8 gives 400 |
request_json() |
Json | Parse body as JSON; invalid JSON gives 400 |
header(name: String) |
String | Case-insensitive header lookup; absent/non-text value gives empty string |
param(name: String) |
String | Decoded route parameter; absent gives empty string |
query(name: String) |
String | Form-decoded query value; last duplicate wins; absent gives empty string |
env("LITERAL_NAME") |
String | Read a declared environment capability |
request_json parses the body independently of Content-Type; application code
can inspect header("content-type") if it needs to reject another media type.
Startup refuses missing or empty declared environment variables. The compiler
requires a literal name and matching permit env. It does not embed secret
values into the binary. RYFT_WORKER_* names are reserved for supervisor IPC
and cannot be declared as language capabilities. Do not log authorization
headers or environment values.
SQLite APIs
storage db: sqlite("catalog.db");
let written = db_exec(db, "INSERT INTO products (name) VALUES (?1)", [name]);
let found = db_query(db, "SELECT id, name FROM products WHERE id = ?1", [id]);
db_exec(handle, sql: String, params: Json) -> Json executes one statement.
Success: {"ok":true,"affected":N,"last_insert_id":N}.
db_query(handle, sql: String, params: Json) -> Json executes a read-only
statement. Success: {"ok":true,"rows":[{"column":value}]}. Give result
columns unique names, using aliases when joining tables.
Both return {"ok":false,"error":"..."} on database/parameter errors.
SQL must be a source string literal; dynamic SQL strings are rejected during
compilation. Choose among literal templates in branches and bind data values.
Check ok before reading result fields; do not expose internal database error
details from public endpoints. The first argument is an app-local declared
handle, not an arbitrary filename or value.
Parameters must be a JSON array of scalar values: null, i64, bool (stored as
0/1), String, or finite numeric JSON. Integer spellings must fit i64; decimal
and exponent spellings convert to finite SQLite REAL. Nonfinite parameters or
query results return an error. Bind
values with ?1 placeholders; never concatenate request input into SQL.
Identifiers and SQL syntax cannot be bound as parameters. Floating point
database values have SQLite/IEEE precision, not arbitrary-precision arithmetic.
Databases open at server startup inside separate app directories, use WAL and foreign keys, and have a five-second SQLite busy timeout. A per-database mutex serializes access; other databases/apps can progress independently. Statements check the handler deadline through a SQLite progress callback. ATTACH, DETACH, application PRAGMAs, unknown authorization actions, and extension loading are denied. Multi-statement execution and BLOB result decoding are unsupported. Queries are capped at 10,000 rows and 16 MiB of encoded row data. Paginate.
Explicit transaction/savepoint statements are rejected to prevent requests
from sharing an open transaction on the same connection. Use db_transaction for a bounded, atomic batch of literal SQL templates. Connection pools and general schema migration tracking,
PostgreSQL, Redis and ORM features are not implemented. Each normal statement
uses SQLite’s statement-level atomicity; separate API calls are not one
transaction. Protect the data directory with OS permissions and back it up
using SQLite-aware procedures.
Strings and parsing
| Function | Return | Behavior |
|---|---|---|
trim(value: String) |
String | Remove surrounding Unicode whitespace |
lowercase(value: String) / uppercase(value: String) |
String | Unicode case conversion |
contains(value: String, needle: String) |
bool | Literal substring check |
starts_with(value: String, prefix: String) / ends_with(value: String, suffix: String) |
bool | Literal boundary checks |
split(value: String, separator: String) |
List |
Split into owned strings |
is_hex(value: String) / is_digits(value: String) |
bool | Nonempty ASCII hex/decimal spelling checks |
regex_escape(value: String) |
String | Escape literal text for regular-expression use |
parse_i64(value: String) |
Result<i64,String> | Fallible signed integer parsing |
parse_json(value: String) |
Result<Json,String> | Fallible JSON parsing |
to_string(value: i64) |
String | Decimal integer spelling |
now_millis() |
i64 | Unix epoch milliseconds |
uuid() |
String | OS-random UUID v4; app-only |
Typed collections and codecs
| Function | Return | Behavior |
|---|---|---|
list(values...) |
List |
Nonempty homogeneous typed list |
list_push(values: List<T>, value: T) |
List |
Return an extended list |
list_at(values: List<T>, index: i64) |
Option |
Safe zero-based lookup |
map_put(values: Map<String,T>, key: String, value: T) |
Map<String,T> | Return an updated map |
map_get(values: Map<String,T>, key: String) |
Option |
Safe key lookup |
len(value: List<T> or Map<String,T>) |
i64 | Element count |
List<T>.new() and Map<String,T>.new() create empty containers. Keep the updated value returned by push/put. Serializable values support .to_json() and json(value); supported types expose .from_json(Json) -> Result<T,String>. Struct decoding rejects missing/unknown fields and invalid types. See types and errors.
Request metadata and headers
| Function | Return | Behavior |
|---|---|---|
request_path() |
String | Path without query string |
request_method() |
String | Request method |
request_id() |
String | Runtime request identifier |
response_header(value: Response, name: String, content: String) |
Response | Add a validated header; framing and hop-by-hop headers are rejected |
Request APIs require a request context and cannot be used in startup/shutdown hooks or pure global helpers. RYFT_CONTROL_TOKEN and RYFT_WORKER_* names are reserved for the runtime.
SQLite transaction batches
db_transaction(handle, steps: Json) -> Json accepts 1..100 source-literal objects with literal sql and a params value. Success returns {"ok":true,"results":[{"affected":1,"last_insert_id":1}]}. A failed step rolls back and returns ok: false. User SQL cannot issue its own transaction controls. See HTTP and storage for an executable example.
MongoDB APIs
Declare storage db: mongodb("MONGODB_URI", "database"); and permit env "MONGODB_URI"; in an app. Supply the URI at runtime. The first argument below must be the app-local handle; collection arguments must be source literals. All functions return Json.
| Function | Success envelope fields besides ok |
|---|---|
mongo_ping(handle) |
ok: true |
mongo_find(handle, collection: String, filter: Json, limit: i64, skip: i64, sort: Json) |
rows array |
mongo_insert(handle, collection: String, document: Json) |
inserted_id |
mongo_update(handle, collection: String, filter: Json, update: Json) |
matched, modified |
mongo_delete(handle, collection: String, filter: Json) |
deleted count |
mongo_index(handle, collection: String, keys: Json, unique: bool) |
ok: true |
mongo_drop(handle, collection: String) |
ok: true; deletes the entire collection |
mongo_transaction(handle, steps: Json) |
results array |
Errors return {"ok":false,"error":"..."} with redacted driver messages. Find limit is 1..1000, skip is 0..100000, and encoded rows are limited to 16 MiB. Update supports $set, $inc and $unset; executable filter operators are blocked. Update and delete each affect one matching document. ObjectIds encode as strings, with Extended JSON $oid available in filters.
Transactions use literal collection and operation (insert, update or delete) plus document or filter/update. A failed operation aborts the batch. Unknown commit outcomes can return uncertain: true after bounded commit retries; reconcile before replaying writes. Compatible deployment topology and permissions are required. HTTP deadlines do not forcibly cancel synchronous driver operations.