API reference
Kotlin reference
Every declaration undra bindgen generates in Kotlin for the playground (schema hash 0x3c17cd5f59bb6f68). The API overview explains how it is shaped.
Bodies, initializers, private and override members are left out, and a run of declarations that differ only by a number is folded to its ends. Each file name links to its complete source.
The core#
The core's entry, named after its namespace: load starts the core and checks its schema hash, and core is the one every generated call uses unless it is given another. The internal UndraCoreNative holds the natives the core's library registers over JNI.
UndraPlaygroundCore
Show the declarations 28 lines
/**
* The core these bindings belong to, `playground_core` (`[core] namespace` in undra.toml): [load]
* starts it, and [core] is the core every generated class and function of this package uses
* unless it is given another one (`ctx`).
*
* ```kotlin
* val core = UndraPlaygroundCore.load() // in this process
* val dev = UndraPlaygroundCore.load(LoadOptions(Mode.REMOTE, remoteUrl = "ws://10.0.2.2:7878")) // `undra dev`
* ```
*/
object UndraPlaygroundCore {
/** The core's namespace: its library is `libplayground_core.so`. */
const val NAMESPACE: String = "playground_core"
/**
* Loads the core (in this process unless [options] say otherwise) and makes it [core].
*
* @throws UndraSchemaMismatchException if the core was built from another schema.
* @throws UndraException if it cannot start, or this core is already loaded.
*/
fun load(options: LoadOptions = LoadOptions()): UndraCore
/**
* The loaded core, or, while none is loaded (or after it was closed), a closed placeholder
* whose calls fail with `UndraCallError.Unavailable`.
*/
val core: UndraCore get()
}
Types#
A data class for each record, an enum or sealed interface for each enum, each with its codec.
Account AccountId Cents Composite DbCells Entry EntrySlice Item Note Price Primitives ProbeCounters Receipt RemoteConfig RemoteTodo SseFollow StorageStatus Todo Figure Filter LoadableEntries Parity StressMode QueryStatus
Show the declarations 324 lines
/** An account of the [`Ledger`] store. */
data class Account(
/** Its identity; the store's list is patched by it. */
val id: AccountId,
/** Whose it is. */
val owner: String,
) : UndraRecord {
companion object : UndraCodec<Account> { … }
}
/** The identity of an account: a `Uuid` that is not just any `Uuid`. */
@JvmInline
value class AccountId(val value: UUID) : UndraRecord {
companion object : UndraCodec<AccountId> { … }
}
/** An amount in cents: a whole number that is not just any number. */
@JvmInline
value class Cents(val value: Long) : UndraRecord, Comparable<Cents> {
companion object : UndraCodec<Cents> { … }
}
/**
* A record that nests the other kinds: lists, options, maps, enums with data and a map with
* integer keys.
*/
data class Composite(
/** A name. */
val name: String,
/** Several strings. */
val tags: List<String>,
/** Maybe a figure. */
val figure: Figure?,
/** Figures, in order. */
val history: List<Figure>,
/** A map keyed by string. */
val scores: Map<String, Int>,
/** A map keyed by integer. */
val names: Map<UInt, String>,
/** Maybe a number. */
val limit: UInt?,
) : UndraRecord {
companion object : UndraCodec<Composite> { … }
}
/** One value of each SQLite storage class, as [`db_cells`] read it back. */
data class DbCells(
/** The `INTEGER`. */
val int: Long,
/** The `REAL`. */
val real: Double,
/** The `TEXT`. */
val text: String,
/** The `BLOB`. */
val blob: ByteArray,
/** The column that held `NULL` (or the text given for it). */
val none: String?,
/** SQLite's `typeof()` of the five columns, in order. */
val types: List<String>,
) : UndraRecord {
companion object : UndraCodec<DbCells> { … }
}
/** One line of an account's statement. */
data class Entry(
/** The account the money went into. */
val account: AccountId,
/** How much. */
val amount: Price,
/** What it was for. */
val memo: String,
/** When the caller says it happened. */
val at: Timestamp,
) : UndraRecord {
companion object : UndraCodec<Entry> { … }
}
/** A window of [`Entry`] rows. */
data class EntrySlice(
/** The rows of this window. */
val items: List<Entry>,
/** The offset of the next window, if there is one. */
val next: UInt?,
) : UndraRecord {
companion object : UndraCodec<EntrySlice> { … }
}
/** One row of a list, identified by `id`. */
data class Item(
/** Identity of the row; lists are patched by it, never by position. */
val id: UInt,
/** The text of the row. */
val label: String,
/** How many times the row was updated. */
val version: UInt,
) : UndraRecord {
companion object : UndraCodec<Item> { … }
}
/** One note, a row of the `notes` table. */
data class Note(
/** The row id. */
val id: Long,
/** The text. */
val title: String,
/** Whether it is ticked. */
val done: Boolean,
) : UndraRecord {
companion object : UndraCodec<Note> { … }
}
/** A price: an exact decimal number of the currency's major unit. */
@JvmInline
value class Price(val value: BigDecimal) : UndraRecord, Comparable<Price> {
companion object : UndraCodec<Price> { … }
}
/** One value of every primitive the wire has, so a single call covers them all. */
data class Primitives(
/** A boolean. */
val flag: Boolean,
/** An `i8`. */
val tiny: Byte,
/** An `i16`. */
val small: Short,
/** An `i32`. */
val int: Int,
/** An `i64`: a `bigint` in TypeScript. */
val long: Long,
/** A `u8`. */
val byte: UByte,
/** A `u16`. */
val word: UShort,
/** A `u32`. */
val dword: UInt,
/** A `u64`: a `bigint` in TypeScript. */
val qword: ULong,
/** An `f32`. */
val single: Float,
/** An `f64`. */
val double: Double,
/** A string, UTF-8 on the wire. */
val text: String,
/** Raw bytes. */
val blob: ByteArray,
/** A span of time, whole nanoseconds on the wire. */
val span: Duration,
/** A moment, milliseconds since the Unix epoch on the wire. */
val at: Timestamp,
/** A UUID, sixteen bytes on the wire. */
val id: UUID,
) : UndraRecord {
companion object : UndraCodec<Primitives> { … }
}
/** What a [`Probe`] has seen. */
data class ProbeCounters(
/** Calls that started running in the core. */
val started: UInt,
/** Calls that ran to the end. */
val completed: UInt,
/** Calls the core dropped before they ended, because the platform cancelled them. */
val cancelled: UInt,
/** Items the core produced for streams (whether or not the platform has read them yet). */
val produced: UInt,
) : UndraRecord {
companion object : UndraCodec<ProbeCounters> { … }
}
/** A record of types from other crates: every field is a leaf type that crosses as a wire type. */
data class Receipt(
/** A `uuid::Uuid`, which crosses as `Uuid`. */
val id: UUID,
/** A `chrono::DateTime<Utc>`, which crosses as `Timestamp` (milliseconds). */
val issued: Timestamp,
/** A `chrono::TimeDelta`, which crosses as `Duration` (nanoseconds). */
val validFor: Duration,
/** A `rust_decimal::Decimal`, which crosses as `Decimal`. */
val total: BigDecimal,
/** A `bytes::Bytes`, which crosses as `Bytes`. */
val signature: ByteArray,
) : UndraRecord {
companion object : UndraCodec<Receipt> { … }
}
/** Where the server is: what an app supplies once, at start-up. */
data class RemoteConfig(
/** The server's address without a trailing slash, such as `https://api.example.com`. */
val baseUrl: String,
) : UndraRecord {
companion object : UndraCodec<RemoteConfig> { … }
}
/** One to-do item on the server. */
data class RemoteTodo(
/**
* The server's identity of the item. An item that is only shown optimistically, and that the
* server has not answered for yet, has an identity counting down from `u32::MAX`.
*/
val id: UInt,
/** What has to be done. */
val title: String,
/** Whether it is finished. */
val done: Boolean,
) : UndraRecord {
companion object : UndraCodec<RemoteTodo> { … }
}
/** What [`sse_follow`] read. */
data class SseFollow(
/** The events, in order. */
val events: List<SseEvent>,
/** Whether the server ended the stream (`SseError::Ended`) before `max` events. */
val ended: Boolean,
) : UndraRecord {
companion object : UndraCodec<SseFollow> { … }
}
/** What the query client's persistence did so far: [`storage_status`]. */
data class StorageStatus(
/** Mutations waiting in the offline queue. */
val pending: UInt,
/** The dead letters, as `"<mutation>: <reason>"`. */
val deadLetters: List<String>,
/**
* Whether the stored offline queue has been read (`false` while the store cannot be read:
* the queue is then neither replayed nor written).
*/
val queueReadable: Boolean,
/** Writes to the `Kv` store that failed. */
val writeFailed: ULong,
/** Persisted cache entries dropped because they could not be migrated. */
val dropped: ULong,
/** Cache entries and queued mutations an older build wrote that were migrated. */
val migrated: ULong,
/** Queued mutations moved to the dead-letter queue. */
val deadLettered: ULong,
) : UndraRecord {
companion object : UndraCodec<StorageStatus> { … }
}
/** One item of the to-do list. */
data class Todo(
/** Identity of the item; the list is updated by key, so the UI diffs by it. */
val id: UUID,
/** What has to be done. */
val title: String,
/** Whether it is finished. */
val done: Boolean,
) : UndraRecord {
companion object : UndraCodec<Todo> { … }
}
/** A shape: an enum with named fields, a tuple variant and a unit variant. */
sealed interface Figure : UndraEnum {
/** A circle. */
data class Circle(val radius: Double) : Figure
/** A rectangle. */
data class Rect(val width: Double, val height: Double) : Figure
/** A shape that is only a name. */
data class Label(val value: String) : Figure
/** No shape at all. */
data object Empty : Figure
companion object : UndraCodec<Figure> { … }
}
/** Which items the list shows. */
enum class Filter(val index: UShort) : UndraEnum {
/** Every item. */
ALL(0u),
/** Items that are not finished. */
ACTIVE(1u),
/** Items that are finished. */
DONE(2u);
companion object : UndraCodec<Filter> { … }
}
/** A window of entries that may still be loading. */
sealed interface LoadableEntries : UndraEnum {
/** Nothing yet. */
data object Loading : LoadableEntries
/** Here it is. */
data class Loaded(val value: EntrySlice) : LoadableEntries
/** It could not be had. */
data class Failed(val value: String) : LoadableEntries
companion object : UndraCodec<LoadableEntries> { … }
}
/** Whether the count is even or odd: a value derived from `count` in the core. */
enum class Parity(val index: UShort) : UndraEnum {
/** The count is divisible by two. */
EVEN(0u),
/** The count is not divisible by two. */
ODD(1u);
companion object : UndraCodec<Parity> { … }
}
/** Which signal `burst` and `start` write. */
enum class StressMode(val index: UShort) : UndraEnum {
/** `value` + 1 per transaction: a firehose the platforms apply once per frame. */
FIREHOSE(0u),
/** `progress` + 1 per transaction: a `no_coalesce` signal the platforms apply step by step. */
PROGRESS(1u);
companion object : UndraCodec<StressMode> { … }
}
/** The fetch state of a query (SPEC section 9). */
enum class QueryStatus(val index: UShort) : UndraEnum {
/** No fetch has started. */
IDLE(0u),
/** A fetch is in flight. */
FETCHING(1u),
/** The latest fetch succeeded. */
SUCCESS(2u),
/** The latest fetch failed. */
ERROR(3u);
companion object : UndraCodec<QueryStatus> { … }
}
Errors#
A sealed class for each #[undra::error], one subclass per variant.
LabError LedgerError ListError RemoteError ReportError StressError TickError TodoError WorkshopError
Show the declarations 87 lines
/** Why a lab call failed. */
sealed class LabError(message: String) : UndraException(message) {
/** Nothing was given. */
data object Empty : LabError("nothing was given")
/** The text is longer than `max` characters. */
data class TooLong(val max: UInt) : LabError("longer than ${max} characters")
/** The text is not a number. */
data class NotANumber(val value: String) : LabError("`${value}` is not a number")
/** A failure chosen by the caller. */
data class Rejected(val code: Int, val reason: String) : LabError("rejected with code ${code}: ${reason}")
companion object : UndraCodec<LabError> { … }
}
/** Why a ledger operation failed. */
sealed class LedgerError(message: String) : UndraException(message) {
/** No account has this identity. */
data object NoSuchAccount : LedgerError("no such account")
/** The amount cannot be added (it is not a number `rust_decimal` holds). */
data object OutOfRange : LedgerError("the amount is out of range")
companion object : UndraCodec<LedgerError> { … }
}
/** Why an operation on a list was refused. */
sealed class ListError(message: String) : UndraException(message) {
/** A position is not in the list. */
data class OutOfRange(val index: UInt, val len: UInt) : ListError("position ${index} is outside a list of ${len} items")
companion object : UndraCodec<ListError> { … }
}
/** Why a request to the server failed. */
sealed class RemoteError(message: String) : UndraException(message) {
/** [`configure_remote`] was not called. */
data object NotConfigured : RemoteError("the remote server is not configured")
/** The `Http` port failed: no network, a timeout, a bad URL, or a cancelled request. */
data class Http(override val cause: HttpError) : RemoteError("network: ${cause.message}")
/** The server answered with a status that is not a success. */
data class Status(val code: UShort) : RemoteError("the server answered ${code}")
/** The server's answer is not the JSON this core expects. */
data class BadBody(val value: String) : RemoteError("the response is not what was expected: ${value}")
companion object : UndraCodec<RemoteError> { … }
}
/** What a reporter's `confirm` can fail with. */
sealed class ReportError(message: String) : UndraException(message) {
/** The user answered no. */
data object Declined : ReportError("the user declined")
/** The app's reporter is not there or failed. */
data class Unavailable(val value: String) : ReportError("the reporter is not available: ${value}")
companion object : UndraCodec<ReportError> { … }
}
/** Why `start` refused to start. */
sealed class StressError(message: String) : UndraException(message) {
/** The rate is zero or above the fastest generator there is (1,000,000 updates a second). */
data class RateOutOfRange(val rate: UInt, val max: UInt) : StressError("${rate} updates per second is outside 1..=${max}")
companion object : UndraCodec<StressError> { … }
}
/** Why the ticker could not tick. */
sealed class TickError(message: String) : UndraException(message) {
/** [`set_ticker_failing`] made it fail. */
data object Failing : TickError("the ticker is failing on purpose")
companion object : UndraCodec<TickError> { … }
}
/** Why an item could not be added. */
sealed class TodoError(message: String) : UndraException(message) {
/** The title is empty once spaces are trimmed. */
data object EmptyTitle : TodoError("the title cannot be empty")
companion object : UndraCodec<TodoError> { … }
}
/** What can go wrong opening a shelf. */
sealed class WorkshopError(message: String) : UndraException(message) {
/** The name is empty. */
data object NoName : WorkshopError("a shelf needs a name")
companion object : UndraCodec<WorkshopError> { … }
}
Objects#
A class for each object, and a function for each free Rust function.
Live Probe RecentTodos Watch add addLater area balances configureRemote createRemoteTodo dbCells dbMigrate dbRun deposit draft echoAccount echoCents echoComposite echoDecimal echoFigure echoPrice echoPrimitives echoReceipt explode explodeDetached explodeLater failLater fileDelete fileList fileRead fileWrite greet httpGet kvGet kvKeys kvPut kvRemove loadableStatement localizedGreeting newest openAccount ownerOf parseCount ping recentTodos sampleReceipt secretGet secretKeys secretPut secretRemove setRemoteDone setTickerFailing sseFollow statement storageStatus tickerFetches touchFeed version wsEcho
Show the declarations 660 lines
class Live internal constructor(core: UndraCore, handle: Long) : UndraObject(core, handle) {
/**
* Forgets the connection without closing it: the port closes it going away (1001).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun abandon()
/**
* Connects to `url`, offering `protocols` and sending `headers`; a connection already open is
* closed first (1000). Returns the subprotocol the server chose (`""` for none).
* @throws WsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun connect(url: String, protocols: List<String>, headers: List<Header>): String
/**
* Closes the connection with `code` and `reason` (`close` is every object's own: it releases
* the handle).
* @throws WsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun disconnect(code: UShort, reason: String)
/**
* How many pulls the inbound stream has made (each asks the platform for up to 16).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun pulls(): ULong
/**
* Reads exactly `count` messages. The connection's end before that is the error (its
* close code, a network failure); a stream that ended cleanly (after [`disconnect`](Live::disconnect))
* returns the messages it had.
* @throws WsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun read(count: UInt): List<WsMessage>
/**
* Sends `message` on the open connection.
* @throws WsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun send(message: WsMessage)
companion object {
/**
* No connection yet.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Live
/**
* No connection yet.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Live
}
}
class Probe internal constructor(core: UndraCore, handle: Long) : UndraObject(core, handle) {
/**
* What the probe has seen so far.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun counters(): ProbeCounters
/**
* Waits forever. The only way it ends is cancellation, which the `cancelled` counter shows.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun hang(): UInt
/**
* Sets every counter back to zero.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun reset()
/**
* A stream of the numbers `0..count`, produced one per poll. The runtime sends an item only
* against credit the platform granted and polls at most one item ahead of it, so `produced`
* stays within one of what the platform has asked for, however large `count` is.
* Collecting throws UndraCallError; cancelling the collector ends it quietly.
*/
fun ticks(count: UInt): Flow<UInt>
/**
* The numbers `0..count` like `ticks`, except that it ends with the error `Rejected` (with
* `code`) where the number `fail_at` would come, when `fail_at < count`: a stream that ends
* with its typed error part-way (ADR-036). The items before it arrive first.
* Collecting throws LabError or UndraCallError; cancelling the collector ends it quietly.
*/
fun ticksThenFail(count: UInt, failAt: UInt, code: Int): Flow<UInt>
/**
* Waits `ms` milliseconds and returns it. Cancelled before that, it counts as cancelled.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun wait(ms: UInt): UInt
companion object {
/**
* A probe with every counter at zero.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Probe
/**
* A probe with every counter at zero.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Probe
}
}
/** The to-dos opened last. */
class RecentTodos internal constructor(core: UndraCore, handle: Long) : UndraObject(core, handle) {
/**
* The row opened last, if any was.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun latest(): Todo?
/**
* Records that `row` was opened: it moves to the front, and the oldest falls off the end.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun open(row: Todo)
/**
* The rows opened last, newest first.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun rows(): List<Todo>
companion object {
/**
* A list that keeps the last `limit` rows opened.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(
limit: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): RecentTodos
/**
* A list that keeps the last `limit` rows opened.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(limit: UInt, ctx: UndraCore = UndraPlaygroundCore.core): RecentTodos
}
}
class Watch internal constructor(core: UndraCore, handle: Long) : UndraObject(core, handle) {
/**
* The subscription's number, in the order they were made.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun id(): UInt
}
/**
* Adds two numbers, wrapping on overflow: a synchronous call with primitive arguments.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun add(a: Int, b: Int, ctx: UndraCore = UndraPlaygroundCore.core): Int
/**
* Adds two numbers after `delay_ms` milliseconds: an asynchronous call that waits on the `Timer`
* port.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun addLater(
a: Int,
b: Int,
delayMs: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): Int
/**
* The area of a circle or a rectangle. A label and an empty figure have none.
* @throws LabError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun area(figure: Figure, ctx: UndraCore = UndraPlaygroundCore.core): Double
/**
* The balance of every account: a map keyed by a newtype.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun balances(ctx: UndraCore = UndraPlaygroundCore.core): Map<AccountId, Price>
/**
* Tells the core where the server is. Call it at start-up, before anything observes
* [`remote_todos`], and again whenever the core is a new one that kept its stores (after a dev
* reload or a web crash restart): the address lives in the core outside any store, so a snapshot
* does not carry it. Calling it again points the core elsewhere (cached data stays until it goes
* stale).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun configureRemote(config: RemoteConfig, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Adds an item to `list` the way a UI wants it: the list shows it at once (an optimistic placeholder), the
* server is asked, and the placeholder is taken back if the server refuses. On success the cached
* list is refetched, so the placeholder gives way to the server's item.
*
* While the device is offline the request is queued (the mutation is idempotent) and the call
* keeps waiting; the placeholder stays visible until the network returns and the request is
* replayed.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun createRemoteTodo(
list: String,
title: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodo
/**
* Writes one value of each storage class to an in-memory database and reads them back.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun dbCells(
int: Long,
real: Double,
text: String,
blob: ByteArray,
none: String?,
ctx: UndraCore = UndraPlaygroundCore.core,
): DbCells
/**
* Opens database `name` with two migrations, the second broken when `broken`: the adapter runs
* them in one transaction, so a broken second one leaves the database at the version it had.
* Returns the version reached.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun dbMigrate(
name: String,
broken: Boolean,
ctx: UndraCore = UndraPlaygroundCore.core,
): UInt
/**
* Runs one statement (SQL given at run time, no parameters) on database `name` and returns the
* rows it changed: how a platform's adapter reports SQL and constraint errors.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun dbRun(name: String, sql: String, ctx: UndraCore = UndraPlaygroundCore.core): ULong
/**
* Adds `amount` to the balance of `account` and returns the new balance. Exact: `0.1` and `0.2`
* make `0.3`.
* @throws LedgerError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun deposit(
account: AccountId,
amount: Price,
memo: String,
at: Timestamp,
ctx: UndraCore = UndraPlaygroundCore.core,
): Price
/**
* A new row of the type the caller names, titled `title`, with an identity of its own that no
* stored row has.
*
* No argument tells which type is wanted, so the caller names it: the type itself in Swift and
* Kotlin, its name in TypeScript.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
@JvmName("draftNote")
fun draft(type: KClass<Note>, title: String, ctx: UndraCore = UndraPlaygroundCore.core): Note
/**
* A new row of the type the caller names, titled `title`, with an identity of its own that no
* stored row has.
*
* No argument tells which type is wanted, so the caller names it: the type itself in Swift and
* Kotlin, its name in TypeScript.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
@JvmName("draftTodo")
fun draft(type: KClass<Todo>, title: String, ctx: UndraCore = UndraPlaygroundCore.core): Todo
/**
* Returns `id`: a newtype of `Uuid` comes back as itself.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoAccount(id: AccountId, ctx: UndraCore = UndraPlaygroundCore.core): AccountId
/**
* Returns `cents`: a newtype of `i64`.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoCents(cents: Cents, ctx: UndraCore = UndraPlaygroundCore.core): Cents
/**
* Returns `value` unchanged.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoComposite(value: Composite, ctx: UndraCore = UndraPlaygroundCore.core): Composite
/**
* Returns `value` exactly: mantissa, scale and all (`1.10` stays `1.10`).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoDecimal(value: BigDecimal, ctx: UndraCore = UndraPlaygroundCore.core): BigDecimal
/**
* Returns `value` unchanged.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoFigure(value: Figure, ctx: UndraCore = UndraPlaygroundCore.core): Figure
/**
* Returns `price`: a newtype of `Decimal`.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoPrice(price: Price, ctx: UndraCore = UndraPlaygroundCore.core): Price
/**
* Returns `value` unchanged.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoPrimitives(value: Primitives, ctx: UndraCore = UndraPlaygroundCore.core): Primitives
/**
* Returns `receipt`: every leaf type of another crate, through the core and back.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun echoReceipt(receipt: Receipt, ctx: UndraCore = UndraPlaygroundCore.core): Receipt
/**
* Panics with `reason`. The boundary turns the panic into a reply (status 2), never into a
* crash, on the platforms that can unwind (R6).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun explode(reason: String, ctx: UndraCore = UndraPlaygroundCore.core): UInt
/**
* Returns at once and panics with `reason` in a task of its own (ADR-046: a contained panic that
* no call is waiting on still reaches `onPanic`).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun explodeDetached(reason: String, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Panics with `reason` after `delay_ms` milliseconds, inside an asynchronous call.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun explodeLater(
delayMs: UInt,
reason: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): UInt
/**
* Fails with `LabError::Rejected { code, .. }` after `delay_ms` milliseconds: an asynchronous
* call with a typed error.
* @throws LabError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun failLater(delayMs: UInt, code: Int, ctx: UndraCore = UndraPlaygroundCore.core): UInt
/**
* Deletes the file or directory `path` of the `Fs` port.
* @throws FsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun fileDelete(path: String, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* The names in the directory `dir` of the `Fs` port, sorted.
* @throws FsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun fileList(dir: String, ctx: UndraCore = UndraPlaygroundCore.core): List<String>
/**
* The contents of the file `path` of the `Fs` port.
* @throws FsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun fileRead(path: String, ctx: UndraCore = UndraPlaygroundCore.core): ByteArray
/**
* Writes `data` to the file `path` of the `Fs` port, creating its directories.
* @throws FsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun fileWrite(path: String, data: ByteArray, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* A greeting.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun greet(name: String, ctx: UndraCore = UndraPlaygroundCore.core): String
/**
* `GET url` through the `Http` port, with an optional timeout in milliseconds. Any status is a
* response; only a failure to get one is an [`HttpError`].
* @throws HttpError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun httpGet(
url: String,
timeoutMs: UInt?,
ctx: UndraCore = UndraPlaygroundCore.core,
): HttpResponse
/**
* The value the `Kv` port has under `key`, if any.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun kvGet(key: String, ctx: UndraCore = UndraPlaygroundCore.core): ByteArray?
/**
* The keys of the `Kv` port that start with `prefix`, in ascending order.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun kvKeys(prefix: String, ctx: UndraCore = UndraPlaygroundCore.core): List<String>
/**
* Stores `value` under `key` in the `Kv` port.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun kvPut(key: String, value: ByteArray, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Removes `key` from the `Kv` port; a missing key is not an error.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun kvRemove(key: String, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* The statement of `account` as a [`Loadable`]: `Loading` when `ready` is false, the first
* `limit` entries when it is true, `Failed` for an unknown account.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun loadableStatement(
account: AccountId,
ready: Boolean,
limit: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): LoadableEntries
/**
* Greets `name` in the user's language, through the [`Locale`] port.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun localizedGreeting(name: String, ctx: UndraCore = UndraPlaygroundCore.core): String
/**
* The newest of `rows`, the one whose identity counts highest, or nothing for an empty list.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
@JvmName("newestNote")
fun newest(rows: List<Note>, ctx: UndraCore = UndraPlaygroundCore.core): Note?
/**
* The newest of `rows`, the one whose identity counts highest, or nothing for an empty list.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
@JvmName("newestTodo")
fun newest(rows: List<Todo>, ctx: UndraCore = UndraPlaygroundCore.core): Todo?
/**
* A new account for `owner`, with an identity from the ledger's counter.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun openAccount(owner: String, ctx: UndraCore = UndraPlaygroundCore.core): AccountId
/**
* Who owns `account`, or an empty string for an unknown one.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun ownerOf(account: AccountId, ctx: UndraCore = UndraPlaygroundCore.core): String
/**
* Reads an unsigned number of at most nine digits.
* @throws LabError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun parseCount(text: String, ctx: UndraCore = UndraPlaygroundCore.core): UInt
/**
* Does nothing and returns nothing: a call with neither arguments nor a result.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun ping(ctx: UndraCore = UndraPlaygroundCore.core)
/**
* A list of recently opened to-dos that already holds `rows`, the last of them opened last,
* and keeps `limit` of them.
*
* An object is returned from a function like any value: the platform gets one wrapper for it.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun recentTodos(
rows: List<Todo>,
limit: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): RecentTodos
/**
* A receipt made of fixed values (what a platform checks it decodes), so a platform can read
* what the leaf types look like on its side without building one.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun sampleReceipt(ctx: UndraCore = UndraPlaygroundCore.core): Receipt
/**
* The value the `SecureStore` port has under `key`, if any.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun secretGet(key: String, ctx: UndraCore = UndraPlaygroundCore.core): ByteArray?
/**
* The keys of the `SecureStore` port that start with `prefix`, in ascending order.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun secretKeys(prefix: String, ctx: UndraCore = UndraPlaygroundCore.core): List<String>
/**
* Stores `value` under `key` in the `SecureStore` port (the Keychain, the Android Keystore).
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun secretPut(key: String, value: ByteArray, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Removes `key` from the `SecureStore` port; a missing key is not an error.
* @throws StorageError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun secretRemove(key: String, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Marks an item of `list` finished or not, showing the change at once and taking it back if the server
* refuses.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun setRemoteDone(
list: String,
id: UInt,
done: Boolean,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodo
/**
* Makes the ticker fail (or succeed again) from its next fetch on.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setTickerFailing(failing: Boolean, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* Subscribes to `url` (resuming after `last_event_id`) and reads up to `max` events, or until
* the server ends the stream. Reconnecting is the caller's: call again with the last id read.
* @throws SseError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun sseFollow(
url: String,
lastEventId: String?,
max: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): SseFollow
/**
* `limit` entries of the statement of `account` from `offset`: a named instantiation of [`Slice`].
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun statement(
account: AccountId,
offset: UInt,
limit: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): EntrySlice
/**
* What the query client's persistence did: the offline queue, its dead letters and the
* persistence counters.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun storageStatus(ctx: UndraCore = UndraPlaygroundCore.core): StorageStatus
/**
* How many times the ticker fetched, for a test that wants the number the core sees.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun tickerFetches(ctx: UndraCore = UndraPlaygroundCore.core): UInt
/**
* Makes the feed's even rows show revision `revision` the next time they are fetched.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun touchFeed(revision: UInt, ctx: UndraCore = UndraPlaygroundCore.core)
/**
* The name and version of the core.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun version(ctx: UndraCore = UndraPlaygroundCore.core): String
/**
* Connects to `url`, sends `messages` in order, reads as many back and closes (1000).
*
* Against an echo server the replies are the messages; any end of the connection before that is
* the error (a refusal, `Closed` with the server's code, `Network`).
* @throws WsError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun wsEcho(
url: String,
messages: List<WsMessage>,
ctx: UndraCore = UndraPlaygroundCore.core,
): List<WsMessage>
Stores#
A class for each #[undra::store]: its signals as StateFlow, then its methods.
Bench BigList Counter Device Ledger Legacy Library NoteSelection Notes Profile Shelf Stress TodoSelection Todos Workshop
Show the declarations 802 lines
/**
* The benchmark store: 128 counters, a 10,000-row keyed list and three methods that
* exercise the boundary.
*/
class Bench internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val rows: StateFlow<List<Item>>
val s000: StateFlow<UInt>
// … 126 more with the same shape …
val s127: StateFlow<UInt>
/**
* Adds two numbers: the cheapest call there is, for the handle-call row.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun benchAdd(a: UInt, b: UInt): UInt
/**
* Returns `data` unchanged: a payload of `data.len()` bytes crosses the boundary
* twice.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun benchEchoBytes(data: ByteArray): ByteArray
/**
* Inserts one new row so that it ends at position `i` (a position past the end
* appends): one keyed `Insert` on a list of about 10,000 rows. The list grows by
* one row per call; `bench_list_reset` starts over.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun benchListInsert(i: UInt)
/**
* Puts the list back to its [`ROWS`] starting rows and writes zero to every counter,
* in one transaction: one change-set with the list and all [`SIGNALS`] counters.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun benchListReset()
/**
* Updates `n` rows of the list, **one transaction each**: `n` change-sets, each a
* keyed patch of a single `Update` (the row's `version` goes up by one), the way a
* socket or a sensor feed that writes a row at a time reaches the platform. The rows
* are spread over the list (consecutive updates are far apart) and the same
* positions come out for the same list length, so a run is repeatable. This is what
* the device benchmarks drain (ADR-031: 100,000 patches a second is 1,667 a frame).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun benchListUpdateBurst(n: UInt)
/**
* Adds one to the first `k` counters (at most [`SIGNALS`]) inside one transaction:
* `k` dirty signals, one change-set.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun benchTouchSignals(k: UInt)
companion object {
/**
* A store with every counter at zero and [`ROWS`] rows numbered from 1.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Bench
/**
* A store with every counter at zero and [`ROWS`] rows numbered from 1.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Bench
}
}
/** A list of [`LIST_LEN`] items with operations that change one item at a time. */
class BigList internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val items: StateFlow<List<Item>>
/** Computed by the core; read-only. */
val count: StateFlow<UInt>
/**
* Inserts a new row with `label` so that it ends at `index` (`index == len` appends), and
* returns its identity. One keyed `Insert`.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun insertAt(index: UInt, label: String): UInt
/**
* Moves the row at `from` so that it ends at `to`. One keyed `Move`.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun moveItem(from: UInt, to: UInt)
/**
* Removes the row at `index`. One keyed `Remove`.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun removeAt(index: UInt)
/**
* Replaces the list with a fresh one of [`LIST_LEN`] items. The platform receives the keyed
* patch that turns the old list into the new one (a full value if they have little in
* common).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun reset()
/**
* Changes the label of the row at `index` and bumps its version. One keyed `Update`.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun updateAt(index: UInt, label: String)
companion object {
/**
* A list of [`LIST_LEN`] items numbered from 1.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): BigList
/**
* A list of [`LIST_LEN`] items numbered from 1.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): BigList
}
}
/** A counter with a change tally and a computed parity. */
class Counter internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val count: StateFlow<Int>
val changes: StateFlow<UInt>
/** Computed by the core; read-only. */
val parity: StateFlow<Parity>
/**
* Adds `amount` (which may be negative) and counts the change: one transaction, so one
* change-set for `count`, `changes` and `parity` together. The count saturates instead of
* overflowing.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun add(amount: Int)
/**
* Subtracts one.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun decrement()
/**
* Adds one.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun increment()
/**
* Sets the count back to zero and forgets the changes, in one transaction.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun reset()
companion object {
/**
* A counter at zero with no changes made.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Counter
/**
* A counter at zero with no changes made.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Counter
}
}
/**
* The `Connectivity` and `Lifecycle` reports as the core received them: the last of each and how
* many there were since the core started. Every report moves the signals in one transaction, and
* every signal is `no_coalesce`: a platform's mirror applies each report, even several that arrive
* in one frame (or while the app is in the background, where React Native on Android pauses the
* timers that drain it), so a UI or a check sees `background` even when `active` follows at once.
*/
class Device internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle, noCoalesce = setOf(0u, 1u, 2u, 3u, 4u)) {
val online: StateFlow<Boolean>
val netKind: StateFlow<NetKind>
val appState: StateFlow<AppState>
val connectivityReports: StateFlow<UInt>
val lifecycleReports: StateFlow<UInt>
companion object {
/**
* The store, showing every report received so far and following the next ones.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Device
/**
* The store, showing every report received so far and following the next ones.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Device
}
}
/** The accounts the app lists: a list keyed by a newtype. */
class Ledger internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val accounts: StateFlow<List<Account>>
/**
* Closes the account `id`; one keyed `Remove`.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun closeAccount(id: AccountId)
/**
* Opens an account for `owner`; one keyed `Insert` whose key is a newtype.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun open(owner: String): AccountId
/**
* Changes the owner of the account `id`; one keyed `Update`.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun rename(id: AccountId, owner: String)
companion object {
/**
* A ledger with no accounts.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Ledger
/**
* A ledger with no accounts.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Ledger
}
}
/** A store whose one signal build B changes incompatibly. */
class Legacy internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val score: StateFlow<Int>
/**
* `score=..`.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun describe(): String
companion object {
/**
* A score of `score`.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(
score: Int,
ctx: UndraCore = UndraPlaygroundCore.core,
): Legacy
/**
* A score of `score`.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(score: Int, ctx: UndraCore = UndraPlaygroundCore.core): Legacy
}
}
/** A library of books the host pages through. */
class Library internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
/** A list the core holds and this mirror pages through: a row is missing until its page has arrived, and reading it asks for the page. */
val books: UndraLazyList<Item>
val source: StateFlow<List<Item>>
/** A list the core holds and this mirror pages through: a row is missing until its page has arrived, and reading it asks for the page. */
val evens: UndraLazyList<Item>
/**
* Appends `count` books and, in the same transaction, as many rows to `source`. Each is one
* recorded push, and the host is told one new length and version.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun addRows(count: UInt)
/**
* How many books there are.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun count(): UInt
/**
* Removes `count` rows from the start of `source` (the lazy view follows).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun dropSource(count: UInt)
/**
* Removes the book at `index`.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun removeAt(index: UInt)
/**
* Changes the label of the book at `index` and bumps its version.
* @throws ListError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun rename(index: UInt, label: String)
/**
* Replaces the books with `count` fresh ones numbered from 1.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun reset(count: UInt)
companion object {
/**
* A library with [`LIBRARY_LEN`] books and a source of 20 rows.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Library
/**
* A library with [`LIBRARY_LEN`] books and a source of 20 rows.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Library
}
}
/** The ticked notes. */
class NoteSelection internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val rows: StateFlow<List<Note>>
/** Computed by the core; read-only. */
val count: StateFlow<UInt>
/**
* Unticks everything.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun clear()
/**
* Ticks every row of `rows` that is not ticked yet, in one transaction.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun selectAll(rows: List<Note>)
/**
* Ticks `row`, or unticks it if it is ticked.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun toggle(row: Note)
companion object {
/**
* Nothing ticked.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): NoteSelection
/**
* Nothing ticked.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): NoteSelection
}
}
/** The notes of one database, mirrored: `notes` changes only after the database did. */
class Notes internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val notes: StateFlow<List<Note>>
val version: StateFlow<UInt>
/**
* Adds a note at the end.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun add(title: String): Note
/**
* Adds every title in one transaction: all or none. A `None` title breaks `NOT NULL` and
* rolls the whole batch back. Returns how many were added.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun addAll(titles: List<String?>): UInt
/**
* Adds a note with a chosen id (an id in use is `Constraint { kind: Unique }`).
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun addWithId(id: Long, title: String): Note
/**
* Closes the database; the list keeps what it showed (`close` is every store's own: it
* releases the handle).
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun closeDatabase()
/**
* How many notes the database holds (read from it, not from the mirror).
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun count(): UInt
/**
* Opens (creating it if needed) database `name`, migrates it and loads every note.
* Returns its version.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun open(name: String): UInt
/**
* Removes note `id`.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun remove(id: Long)
/**
* Ticks or unticks note `id`.
* @throws DbError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun toggle(id: Long)
companion object {
/**
* No database open yet: call [`open`](Notes::open).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Notes
/**
* No database open yet: call [`open`](Notes::open).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Notes
}
}
/** A user profile: build A's signals are `name`, then `visits`. */
class Profile internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val name: StateFlow<String>
val visits: StateFlow<UInt>
/**
* `name=..;visits=..`: what both builds can be compared by.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun describe(): String
/**
* Counts one visit.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun visit()
companion object {
/**
* A profile called `name`, never visited.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(
name: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): Profile
/**
* A profile called `name`, never visited.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(name: String, ctx: UndraCore = UndraPlaygroundCore.core): Profile
}
}
/** A shelf: a child store of the [`Workshop`], with a label and a count of the items on it. */
class Shelf internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val label: StateFlow<String>
val items: StateFlow<UInt>
/**
* Takes every item off the shelf.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun clear()
/**
* Puts `count` more items on the shelf.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun stock(count: UInt)
companion object {
/**
* An empty shelf with no label. A platform gets shelves from [`Workshop::shelf`], not from
* here, so that one name is one shelf.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Shelf
/**
* An empty shelf with no label. A platform gets shelves from [`Workshop::shelf`], not from
* here, so that one name is one shelf.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Shelf
}
}
/**
* A store that commits many transactions, for the coalesced-delivery scenarios and the
* playground's stress screen.
*/
class Stress internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle, noCoalesce = setOf(1u)) {
val value: StateFlow<ULong>
val progress: StateFlow<UInt>
val generated: StateFlow<ULong>
val running: StateFlow<Boolean>
/**
* Commits `transactions` transactions now, each one write of the signal `mode` names: one
* change-set per transaction, the way data that arrives in the core on its own does.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun burst(mode: StressMode, transactions: UInt)
/**
* Starts generating updates of the signal the mode names, at the given number a second,
* each its own transaction, until `stop`. Called while a generator runs, it retunes that
* generator (new mode, new rate) instead of starting a second one. Fails, starting
* nothing, when the rate is zero or above 1,000,000.
* @throws StressError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun start(mode: StressMode, perSecond: UInt)
/**
* Stops the generator: no update is committed after this returns. `generated` keeps its
* count. Does nothing when no generator runs.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun stop()
companion object {
/**
* A store with every signal at its start: zeros, and no generator running.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Stress
/**
* A store with every signal at its start: zeros, and no generator running.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Stress
}
}
/** The ticked to-dos. */
class TodoSelection internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val rows: StateFlow<List<Todo>>
/** Computed by the core; read-only. */
val count: StateFlow<UInt>
/**
* Unticks everything.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun clear()
/**
* Ticks every row of `rows` that is not ticked yet, in one transaction.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun selectAll(rows: List<Todo>)
/**
* Ticks `row`, or unticks it if it is ticked.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun toggle(row: Todo)
companion object {
/**
* Nothing ticked.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): TodoSelection
/**
* Nothing ticked.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): TodoSelection
}
}
/** The to-do list: what the UI observes (`todos`, `filter`, `visible`, `remaining`) and calls. */
class Todos internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val todos: StateFlow<List<Todo>>
val filter: StateFlow<Filter>
/** Derived by the core from another list; read-only. Changes arrive as keyed patches. */
val visible: StateFlow<List<Todo>>
/** Computed by the core; read-only. */
val remaining: StateFlow<UInt>
/**
* Adds an item at the end of the list.
* @throws TodoError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun add(title: String): Todo
/**
* Removes every finished item.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun clearDone()
/**
* Appends `count` items titled `Item 1`, `Item 2`, .. with every fourth one finished, in one
* transaction (a demo and test helper: the big-list screen of the docs, contract scenario S19).
* A bulk load is a raw write, so `todos` and `visible` are sent as full values this once; the
* writes after it are patches again.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun fill(count: UInt)
/**
* Removes the item with `id`; unknown ids are ignored.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun remove(id: UUID)
/**
* Chooses which items `visible` holds.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setFilter(filter: Filter)
/**
* Flips the `done` flag of the item with `id`; unknown ids are ignored.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun toggle(id: UUID)
companion object {
/**
* An empty list showing every item.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Todos
/**
* An empty list showing every item.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Todos
}
}
/**
* A workshop that owns shelves and tells subscribers what happens in it.
*
* The state a restore cannot rebuild is empty after one: the shelves and subscribers of the old
* workshop are gone with it (ADR-040 decision 8), and `shelf` makes them again.
*/
class Workshop internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
val jobs: StateFlow<UInt>
val notes: StateFlow<UInt>
/**
* Counts a note (a signal commit, which reaches the platform first) and tells every
* subscribed reporter `line`: the platform sees the new count before it hears the note.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun announce(line: String): UInt
/**
* Reports `steps` times in a row without waiting: a burst, of which the app that is slow to
* react gets only the newest `progress` (the others are coalesced), but every `note`.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun burst(steps: UInt, reporter: Reporter)
/**
* The label of `shelf`, or `none` for no shelf at all.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun describe(shelf: Shelf?): String
/**
* The shelf called `name`, if there is one.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun find(name: String): Shelf?
/**
* Moves every item of `from` onto `onto`, in one transaction (a method that takes two
* stores).
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun merge(from: Shelf, onto: Shelf)
/**
* Opens a shelf after `delay_ms` milliseconds (a call a platform can cancel while it
* waits: then no shelf was handed out and nothing is owed).
* @throws WorkshopError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun open(name: String, delayMs: UInt): Shelf
/**
* Runs a job of `steps` steps, reporting to the app: one progress report and one note per
* step, then a question whose answer is the result (`steps` if the app says go on, else
* `Declined`). The job counts as run whatever the answer.
* @throws ReportError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun run(steps: UInt, reporter: Reporter): UInt
/**
* The shelf called `name`, made on first use: the same shelf every time, so a platform that
* asks twice gets one object (and one reference to give back, not two).
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun shelf(name: String): Shelf
/**
* Every shelf, in name order.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun shelves(): List<Shelf>
/**
* Reads how many items `shelf` holds, once per step for `steps` steps: a stream that takes an
* object, which the core holds (borrowed from the platform) while the stream runs.
* Collecting throws UndraCallError; cancelling the collector ends it quietly.
*/
fun tally(shelf: Shelf, steps: UInt): Flow<UInt>
/**
* How many items there are on the shelves given.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun total(shelves: List<Shelf>): UInt
/**
* Walks `steps` steps, telling `reporter` a note at each one and yielding the step number: a
* stream that takes a callback, whose reference is the core's until the stream ends or is dropped.
* Collecting throws UndraCallError; cancelling the collector ends it quietly.
*/
fun walk(steps: UInt, reporter: Reporter): Flow<UInt>
/**
* Keeps `reporter` until the returned subscription is closed; [`Workshop::announce`] tells it.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun watch(reporter: Reporter): Watch
/**
* How many reporters are subscribed.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun watching(): UInt
companion object {
/**
* An empty workshop.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
operator fun invoke(ctx: UndraCore = UndraPlaygroundCore.core): Workshop
/**
* An empty workshop.
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
*/
fun create(ctx: UndraCore = UndraPlaygroundCore.core): Workshop
}
}
Ports#
An interface for each port the core declares, and an adapter that registers your implementation.
Locale localePortImpl
Show the declarations 12 lines
/**
* The app's own synchronous port (ADR-049 decision 2): how the platform says hello in the
* user's language. In the TypeScript `wasm-worker` mode a synchronous port is answered in the
* worker, so the web app registers it in `worker.ports`.
*/
interface Locale : UndraPort {
/** "Hello" in the user's language. */
fun hello(): String
}
/** Adapts an implementation of `Locale` to `UndraCore.registerPort(UndraIds.Ports.Locale.PORT_ID, ..)`. */
fun localePortImpl(impl: Locale): PortImpl
Callbacks#
An interface for each #[undra::callback] trait, which your app implements so the core can call it, with weak(target) to hand over instead of the object itself.
Reporter
Show the declarations 35 lines
/**
* What the app implements to hear from the core.
*
* The app implements it and passes it to the core, which keeps it until it lets go of it.
* The core calls it on the main thread, in order with the stores' changes: a method sees
* the stores as they were when the core called it.
* [weak] wraps an implementation without keeping it alive.
*/
interface Reporter {
/**
* Asks whether to go on; the app may answer later, or not at all.
* @throws ReportError to answer the core with an error; anything else it throws is
* reported (`LoadOptions.onError`) and the core is answered unavailable.
*/
suspend fun confirm(question: String): Boolean
/** A line to show. */
fun note(line: String)
/**
* How far a job is: `done` of `total`. Only the newest report of a burst matters, so the
* platforms deliver just that one to a listener that has fallen behind.
*/
fun progress(done: UInt, total: UInt)
companion object {
/**
* Forwards to [target] while something else keeps it alive, and holds it only weakly: once it
* is collected, the methods that return nothing do nothing and the `suspend` ones answer the
* core unavailable. For an implementation that holds, directly or not, the object it is passed
* to (a view model that owns the store it listens to), which would otherwise keep itself alive.
*/
fun weak(target: Reporter): Reporter
}
}
Queries#
A handle for each #[undra::query], a function for each #[undra::mutation].
FeedQueryHandle RemoteTodosQueryHandle RosterQueryHandle TickerQueryHandle patchRemoteTodo postRemoteTodo saveNote tagNote
Show the declarations 239 lines
/**
* Observes the `feed` query (cache key `feed/{even_only}`).
* Constructing it registers an observer and fetches when the data is stale or missing.
* The query is paged: `data` grows by one page each time `fetchNextPage()` completes.
*/
class FeedQueryHandle internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle), InfiniteQuery {
/** Every row loaded so far, in order: the first page, then each page `fetchNextPage()` loaded. Empty until the first page arrives. */
val data: StateFlow<List<Item>>
/** Where the query is in its fetch lifecycle. */
val status: StateFlow<QueryStatus>
/** The error of the latest failed fetch, cleared by the next success. */
val error: StateFlow<ListError?>
/** Whether a fetch is in flight (also true while refetching stale data). */
val fetching: StateFlow<Boolean>
/** When `data` was last updated. */
val updatedAt: StateFlow<Timestamp?>
/**
* Fetches again now, even if the data is fresh.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun refetch()
/**
* Marks the cached entry stale; it refetches while observed.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun invalidate()
/**
* Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
* The entry polls at the smallest interval among its observers; no interval clears this handle's override.
* An interval below 1 second or above 7 days is clamped to that range.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setPollInterval(interval: Duration?)
companion object {
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
operator fun invoke(
evenOnly: Boolean,
ctx: UndraCore = UndraPlaygroundCore.core,
): FeedQueryHandle
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
fun create(evenOnly: Boolean, ctx: UndraCore = UndraPlaygroundCore.core): FeedQueryHandle
}
}
/**
* Observes the `remote_todos` query (cache key `remote-todos:{list}`).
* Constructing it registers an observer and fetches when the data is stale or missing.
*/
class RemoteTodosQueryHandle internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
/** The latest successful result, if any. */
val data: StateFlow<List<RemoteTodo>?>
/** Where the query is in its fetch lifecycle. */
val status: StateFlow<QueryStatus>
/** The error of the latest failed fetch, cleared by the next success. */
val error: StateFlow<RemoteError?>
/** Whether a fetch is in flight (also true while refetching stale data). */
val fetching: StateFlow<Boolean>
/** When `data` was last updated. */
val updatedAt: StateFlow<Timestamp?>
/**
* Fetches again now, even if the data is fresh.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun refetch()
/**
* Marks the cached entry stale; it refetches while observed.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun invalidate()
/**
* Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
* The entry polls at the smallest interval among its observers; no interval clears this handle's override.
* An interval below 1 second or above 7 days is clamped to that range.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setPollInterval(interval: Duration?)
companion object {
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
operator fun invoke(
list: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodosQueryHandle
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
fun create(
list: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodosQueryHandle
}
}
/**
* Observes the `roster` query (cache key `roster:{team}`).
* Constructing it registers an observer and fetches when the data is stale or missing.
*/
class RosterQueryHandle internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
/** The latest successful result, if any. */
val data: StateFlow<List<String>?>
/** Where the query is in its fetch lifecycle. */
val status: StateFlow<QueryStatus>
/** The error of the latest failed fetch, cleared by the next success. */
val error: StateFlow<RemoteError?>
/** Whether a fetch is in flight (also true while refetching stale data). */
val fetching: StateFlow<Boolean>
/** When `data` was last updated. */
val updatedAt: StateFlow<Timestamp?>
/**
* Fetches again now, even if the data is fresh.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun refetch()
/**
* Marks the cached entry stale; it refetches while observed.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun invalidate()
/**
* Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
* The entry polls at the smallest interval among its observers; no interval clears this handle's override.
* An interval below 1 second or above 7 days is clamped to that range.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setPollInterval(interval: Duration?)
companion object {
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
operator fun invoke(
team: UInt,
ctx: UndraCore = UndraPlaygroundCore.core,
): RosterQueryHandle
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
fun create(team: UInt, ctx: UndraCore = UndraPlaygroundCore.core): RosterQueryHandle
}
}
/**
* Observes the `ticker` query (cache key `ticker`).
* Constructing it registers an observer and fetches when the data is stale or missing.
*/
class TickerQueryHandle internal constructor(core: UndraCore, handle: Long) : UndraStore(core, handle) {
/** The latest successful result, if any. */
val data: StateFlow<UInt?>
/** Where the query is in its fetch lifecycle. */
val status: StateFlow<QueryStatus>
/** The error of the latest failed fetch, cleared by the next success. */
val error: StateFlow<TickError?>
/** Whether a fetch is in flight (also true while refetching stale data). */
val fetching: StateFlow<Boolean>
/** When `data` was last updated. */
val updatedAt: StateFlow<Timestamp?>
/**
* Fetches again now, even if the data is fresh.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun refetch()
/**
* Marks the cached entry stale; it refetches while observed.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun invalidate()
/**
* Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
* The entry polls at the smallest interval among its observers; no interval clears this handle's override.
* An interval below 1 second or above 7 days is clamped to that range.
* A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
*/
fun setPollInterval(interval: Duration?)
companion object {
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
operator fun invoke(
ctx: UndraCore = UndraPlaygroundCore.core,
): TickerQueryHandle
/** @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached. */
fun create(ctx: UndraCore = UndraPlaygroundCore.core): TickerQueryHandle
}
}
/**
* Runs the `patch_remote_todo` mutation.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun patchRemoteTodo(
list: String,
id: UInt,
done: Boolean,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodo
/**
* Runs the `post_remote_todo` mutation.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun postRemoteTodo(
list: String,
title: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): RemoteTodo
/**
* Runs the `save_note` mutation.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun saveNote(
list: String,
text: String,
ctx: UndraCore = UndraPlaygroundCore.core,
): Boolean
/**
* Runs the `tag_note` mutation.
* @throws RemoteError
* @throws UndraCallError if the core panics, refuses or cancels the call, or cannot be reached.
* @throws CancellationException if the calling coroutine is cancelled.
*/
suspend fun tagNote(list: String, id: UInt, ctx: UndraCore = UndraPlaygroundCore.core): Boolean
Wire ids#
The stable identifiers of every call, the core's namespace and the schema hash its entry checks at load.
UndraIds
Show the declarations 286 lines
/**
* Stable wire identifiers (SPEC section 1.1), for logs and debugging, plus the schema
* hash and the namespace of the core these bindings belong to.
*/
object UndraIds {
const val SCHEMA_HASH: ULong = 0x3c17cd5f59bb6f68uL
const val NAMESPACE: String = "playground_core"
object Objects {
object Live {
const val TYPE_ID: UInt = 0x881c63cfu
const val NEW: UInt = 0xff026383u
const val ABANDON: UInt = 0x1a6729e8u
const val CONNECT: UInt = 0xa8ddf747u
const val DISCONNECT: UInt = 0xb47c6859u
const val PULLS: UInt = 0x1649f03du
const val READ: UInt = 0xc853d487u
const val SEND: UInt = 0xbb31ff25u
}
object Probe {
const val TYPE_ID: UInt = 0x4fdd3051u
const val NEW: UInt = 0xb843ab99u
const val COUNTERS: UInt = 0xc3958518u
const val HANG: UInt = 0x98f10ca1u
const val RESET: UInt = 0xce3a32f8u
const val TICKS: UInt = 0x9ea5858du
const val TICKS_THEN_FAIL: UInt = 0xa48a6ac2u
const val WAIT: UInt = 0x6bab3fb8u
}
object RecentTodos {
const val TYPE_ID: UInt = 0xf3574157u
const val NEW: UInt = 0xf0a9e00bu
const val LATEST: UInt = 0xdabb2338u
const val OPEN: UInt = 0x4addedc7u
const val ROWS: UInt = 0x77753b96u
}
object Watch {
const val TYPE_ID: UInt = 0xec266ec8u
const val ID: UInt = 0x2075bd1fu
}
object Bench {
const val TYPE_ID: UInt = 0x346ad459u
const val NEW: UInt = 0x36809c61u
const val BENCH_ADD: UInt = 0xe6f91ad9u
const val BENCH_ECHO_BYTES: UInt = 0x677eb967u
const val BENCH_LIST_INSERT: UInt = 0x914b8e82u
const val BENCH_LIST_RESET: UInt = 0x0c07aab2u
const val BENCH_LIST_UPDATE_BURST: UInt = 0x7411fd03u
const val BENCH_TOUCH_SIGNALS: UInt = 0x3fc0389fu
}
object BigList {
const val TYPE_ID: UInt = 0x3b9271c5u
const val NEW: UInt = 0xf5e4a11du
const val INSERT_AT: UInt = 0x8f234904u
const val MOVE_ITEM: UInt = 0x58a6cbdeu
const val REMOVE_AT: UInt = 0x1237d7afu
const val RESET: UInt = 0x65063b1cu
const val UPDATE_AT: UInt = 0x0e5ff480u
}
object Counter {
const val TYPE_ID: UInt = 0xfc0f33c3u
const val NEW: UInt = 0xcff00e37u
const val ADD: UInt = 0x8adcbf02u
const val DECREMENT: UInt = 0xe6593ac4u
const val INCREMENT: UInt = 0x0584c6acu
const val RESET: UInt = 0x0c5ad256u
}
object Device {
const val TYPE_ID: UInt = 0xbdcbb413u
const val NEW: UInt = 0x3f6646a7u
}
object Ledger {
const val TYPE_ID: UInt = 0x348f96acu
const val NEW: UInt = 0x134c88d0u
const val CLOSE_ACCOUNT: UInt = 0x06f7c642u
const val OPEN: UInt = 0x2dd4faa6u
const val RENAME: UInt = 0x12958000u
}
object Legacy {
const val TYPE_ID: UInt = 0x055b887eu
const val NEW: UInt = 0x14d6ac0eu
const val DESCRIBE: UInt = 0x642670b9u
}
object Library {
const val TYPE_ID: UInt = 0xa8532270u
const val NEW: UInt = 0xf94159c4u
const val ADD_ROWS: UInt = 0x4cf117afu
const val COUNT: UInt = 0x4503ed51u
const val DROP_SOURCE: UInt = 0x56f49125u
const val REMOVE_AT: UInt = 0xe4a7c326u
const val RENAME: UInt = 0x5fcbc4c4u
const val RESET: UInt = 0x41bc20ddu
}
object NoteSelection {
const val TYPE_ID: UInt = 0x5f5e349du
const val NEW: UInt = 0xa0602cd5u
const val CLEAR: UInt = 0xb304c15eu
const val SELECT_ALL: UInt = 0xbb722df1u
const val TOGGLE: UInt = 0xce377229u
}
object Notes {
const val TYPE_ID: UInt = 0x0ff01b6au
const val NEW: UInt = 0x5981902au
const val ADD: UInt = 0xf7a61617u
const val ADD_ALL: UInt = 0xd4384f5bu
const val ADD_WITH_ID: UInt = 0x20b4cbe8u
const val CLOSE_DATABASE: UInt = 0x11647c30u
const val COUNT: UInt = 0x39cf3133u
const val OPEN: UInt = 0x5d8df10cu
const val REMOVE: UInt = 0x6e4b1cdcu
const val TOGGLE: UInt = 0xe1983278u
}
object Profile {
const val TYPE_ID: UInt = 0xcd17328eu
const val NEW: UInt = 0xed94ae7eu
const val DESCRIBE: UInt = 0xa05219a9u
const val VISIT: UInt = 0xa008fdabu
}
object Shelf {
const val TYPE_ID: UInt = 0xb01959e3u
const val NEW: UInt = 0x4e9d4957u
const val CLEAR: UInt = 0x8cb02b88u
const val STOCK: UInt = 0xbd0e77fbu
}
object Stress {
const val TYPE_ID: UInt = 0xafa58985u
const val NEW: UInt = 0x6799185du
const val BURST: UInt = 0xf4b7ad05u
const val START: UInt = 0xb710bb83u
const val STOP: UInt = 0xb5c8e111u
}
object TodoSelection {
const val TYPE_ID: UInt = 0xd88b75ddu
const val NEW: UInt = 0xfb065295u
const val CLEAR: UInt = 0x1658621eu
const val SELECT_ALL: UInt = 0x916e69b1u
const val TOGGLE: UInt = 0x5a64c3e9u
}
object Todos {
const val TYPE_ID: UInt = 0xf5e31faau
const val NEW: UInt = 0x35935deau
const val ADD: UInt = 0xd13d7ad7u
const val CLEAR_DONE: UInt = 0x27ffa842u
const val FILL: UInt = 0x1ce95af5u
const val REMOVE: UInt = 0xa977479cu
const val SET_FILTER: UInt = 0x07781993u
const val TOGGLE: UInt = 0x1cc45d38u
}
object Workshop {
const val TYPE_ID: UInt = 0xe22bcc2cu
const val NEW: UInt = 0x3dd69650u
const val ANNOUNCE: UInt = 0xed2adfb5u
const val BURST: UInt = 0x7d3f02b4u
const val DESCRIBE: UInt = 0xcec7da2fu
const val FIND: UInt = 0x84e1ab01u
const val MERGE: UInt = 0x9d9f7396u
const val OPEN: UInt = 0xa5283b26u
const val RUN: UInt = 0x5208d85fu
const val SHELF: UInt = 0xfaed29c6u
const val SHELVES: UInt = 0x952fdfeeu
const val TALLY: UInt = 0x56a6b8e4u
const val TOTAL: UInt = 0xce8e1708u
const val WALK: UInt = 0x0c0539afu
const val WATCH: UInt = 0x19e462e5u
const val WATCHING: UInt = 0x76b9e49bu
}
object FeedQueryHandle {
const val TYPE_ID: UInt = 0x015a66a3u
const val NEW: UInt = 0x015a66a3u
const val FETCH_NEXT_PAGE: UInt = 0x84920501u
const val REFETCH: UInt = 0x21d1b9e2u
const val INVALIDATE: UInt = 0x44cec2fau
const val SET_POLL_INTERVAL: UInt = 0xe327e53bu
}
object RemoteTodosQueryHandle {
const val TYPE_ID: UInt = 0x2a794167u
const val NEW: UInt = 0x2a794167u
const val REFETCH: UInt = 0x21d1b9e2u
const val INVALIDATE: UInt = 0x44cec2fau
const val SET_POLL_INTERVAL: UInt = 0xe327e53bu
}
object RosterQueryHandle {
const val TYPE_ID: UInt = 0xaa41feccu
const val NEW: UInt = 0xaa41feccu
const val REFETCH: UInt = 0x21d1b9e2u
const val INVALIDATE: UInt = 0x44cec2fau
const val SET_POLL_INTERVAL: UInt = 0xe327e53bu
}
object TickerQueryHandle {
const val TYPE_ID: UInt = 0x38de4411u
const val NEW: UInt = 0x38de4411u
const val REFETCH: UInt = 0x21d1b9e2u
const val INVALIDATE: UInt = 0x44cec2fau
const val SET_POLL_INTERVAL: UInt = 0xe327e53bu
}
}
object Functions {
const val ADD: UInt = 0x65b4cd58u
const val ADD_LATER: UInt = 0xc5ca16e9u
const val AREA: UInt = 0x293fbad8u
const val BALANCES: UInt = 0x2f156bccu
const val CONFIGURE_REMOTE: UInt = 0xa991dd26u
const val CREATE_REMOTE_TODO: UInt = 0x3f635105u
const val DB_CELLS: UInt = 0x31c92fa5u
const val DB_MIGRATE: UInt = 0x2f1b2165u
const val DB_RUN: UInt = 0x8c3edc9du
const val DEPOSIT: UInt = 0x1301c349u
const val DRAFT_NOTE: UInt = 0x1ee40222u
const val DRAFT_TODO: UInt = 0x0c13e0eeu
const val ECHO_ACCOUNT: UInt = 0x730b1c74u
const val ECHO_CENTS: UInt = 0x8cdc6e3cu
const val ECHO_COMPOSITE: UInt = 0x769db4ecu
const val ECHO_DECIMAL: UInt = 0x7a8022d4u
const val ECHO_FIGURE: UInt = 0xeeb27e01u
const val ECHO_PRICE: UInt = 0xbcbc2c72u
const val ECHO_PRIMITIVES: UInt = 0x59ba77e7u
const val ECHO_RECEIPT: UInt = 0x05b7b46bu
const val EXPLODE: UInt = 0x4b8e88d2u
const val EXPLODE_DETACHED: UInt = 0x5388e4d9u
const val EXPLODE_LATER: UInt = 0xe5a63d4bu
const val FAIL_LATER: UInt = 0x977e4974u
const val FILE_DELETE: UInt = 0x3ea41ab3u
const val FILE_LIST: UInt = 0x97b9c870u
const val FILE_READ: UInt = 0x2103879cu
const val FILE_WRITE: UInt = 0x2c0e4e77u
const val GREET: UInt = 0x0594d9aeu
const val HTTP_GET: UInt = 0xbce1d1e6u
const val KV_GET: UInt = 0x05cd83d7u
const val KV_KEYS: UInt = 0x4be5264du
const val KV_PUT: UInt = 0x1b33766eu
const val KV_REMOVE: UInt = 0xe4402f7du
const val LOADABLE_STATEMENT: UInt = 0x74183f5fu
const val LOCALIZED_GREETING: UInt = 0x247f9a6cu
const val NEWEST_NOTE: UInt = 0x4835685du
const val NEWEST_TODO: UInt = 0xb9743b7du
const val OPEN_ACCOUNT: UInt = 0x30922a29u
const val OWNER_OF: UInt = 0xacfd7ad8u
const val PARSE_COUNT: UInt = 0x1c438944u
const val PING: UInt = 0x60e670d5u
const val RECENT_TODOS: UInt = 0x69a43bf4u
const val SAMPLE_RECEIPT: UInt = 0xe6449400u
const val SECRET_GET: UInt = 0x3f96f35au
const val SECRET_KEYS: UInt = 0x98a56bd2u
const val SECRET_PUT: UInt = 0x2c60b7cbu
const val SECRET_REMOVE: UInt = 0x83a7330au
const val SET_REMOTE_DONE: UInt = 0xa1e08a5fu
const val SET_TICKER_FAILING: UInt = 0x26f08a91u
const val SSE_FOLLOW: UInt = 0x237de656u
const val STATEMENT: UInt = 0xadc39bc2u
const val STORAGE_STATUS: UInt = 0x79205099u
const val TICKER_FETCHES: UInt = 0xb3a3511cu
const val TOUCH_FEED: UInt = 0x27176f81u
const val VERSION: UInt = 0xceb9168bu
const val WS_ECHO: UInt = 0x2b49a875u
}
object Ports {
object Locale {
const val PORT_ID: UInt = 0xcc469822u
const val HELLO: UInt = 0x9e2a48e9u
}
}
object Callbacks {
object Reporter {
const val PORT_ID: UInt = 0x10e8b455u
const val CONFIRM: UInt = 0x1ea2905au
const val NOTE: UInt = 0x8720eafeu
const val PROGRESS: UInt = 0x3a77cbcdu
const val RELEASE_INSTANCE: UInt = 0x47e657b5u
const val CANCEL_CALL: UInt = 0x9a8ca032u
}
}
object Queries {
const val FEED: UInt = 0x015a66a3u
const val PATCH_REMOTE_TODO: UInt = 0x77fe653eu
const val POST_REMOTE_TODO: UInt = 0x5c84eed2u
const val REMOTE_TODOS: UInt = 0x2a794167u
const val ROSTER: UInt = 0xaa41feccu
const val SAVE_NOTE: UInt = 0xaef633c6u
const val TAG_NOTE: UInt = 0xb9224861u
const val TICKER: UInt = 0x38de4411u
}
}
Generated by site/scripts/build-reference.mjs from examples/playground/generated/kotlin, with the declarations read by site/scripts/decls.mjs. To change this page, change the core's code or comments and run undra bindgen -C examples/playground --docs.