search for standard sites
pub-search.waow.tech/
search
zig
blog
atproto
turso and hrana#
leaflet-search uses Turso (hosted libsql) via the HTTP API.
what is hrana?#
hrana (czech for "edge") is the protocol for connecting to libsql/sqlite over the network. designed for edge functions where low latency matters.
the HTTP API (/v2/pipeline) is "hrana over HTTP" - stateless version of the websocket protocol.
request format#
{
"requests": [
{
"type": "execute",
"stmt": {
"sql": "SELECT * FROM users WHERE id = ?",
"args": [
{ "type": "text", "value": "123" }
]
}
},
{ "type": "close" }
]
}
stmt fields#
| field | type | required | notes |
|---|---|---|---|
| sql | string | yes | single SQL statement |
| args | array | no | positional parameters, omit if empty |
| named_args | array | no | named parameters (:name, @name, $name) |
| want_rows | bool | no | default true, set false to skip row data |
value types#
type Value =
| { "type": "null" }
| { "type": "integer", "value": string } // string to avoid precision loss
| { "type": "float", "value": number }
| { "type": "text", "value": string }
| { "type": "blob", "base64": string }
response format#
{
"baton": null,
"base_url": null,
"results": [
{
"type": "ok",
"response": {
"type": "execute",
"result": {
"cols": [{"name": "id", "decltype": "TEXT"}],
"rows": [["123"]],
"affected_row_count": 0,
"last_insert_rowid": null
}
}
},
{ "type": "ok", "response": { "type": "close" } }
]
}
gotchas#
- args must be omitted, not null -
"args": nullis invalid, omit the field entirely when no args - integers as strings - large integers are strings in JSON to preserve precision
- always close - include
{"type": "close"}at the end of requests array