API reference

Swift reference

Every declaration undra bindgen generates in Swift 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.

UndraPlaygroundCore

Show the declarations 21 lines
/// The core these bindings belong to, `playground_core` (`[core] namespace` in undra.toml): `load`
/// starts it, and `core` is the core every generated type and function of this module uses
/// unless it is given another one (`ctx:`).
///
/// ```swift
/// let core = try UndraPlaygroundCore.load() // linked into the app
/// let dev = try UndraPlaygroundCore.load(.remote(url: "ws://127.0.0.1:7878")) // `undra dev`
/// ```
public enum UndraPlaygroundCore {
    /// The core's namespace: it exports `playground_core_undra_api` from `libplayground_core.a`.
    public static let namespace = "playground_core"

    /// Loads the core (linked into the app unless `options` say otherwise) and makes it
    /// `core`. Throws `UndraSchemaMismatchError` when the core was built from another schema,
    /// and `UndraLoadError` when it cannot start or is already loaded.
    public static func load(_ options: LoadOptions = .inproc()) throws -> UndraCore

    /// The loaded core, or, while none is loaded (or after it was closed), a closed placeholder
    /// whose calls fail as unavailable.
    public static var core: UndraCore
}

Types#

A struct for each record, an enum for each enum, with the wire codec beside it.

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 476 lines
/// An account of the [`Ledger`] store.
public struct Account: UndraRecord, Sendable, Hashable, Codable {
    /// Its identity; the store's list is patched by it.
    public var id: AccountId
    /// Whose it is.
    public var owner: String

    public init(id: AccountId, owner: String)

    public static func undraDecode(_ r: inout UndraReader) throws -> Account

    public func undraEncode(_ w: inout UndraWriter)
}

/// The identity of an account: a `Uuid` that is not just any `Uuid`.
public struct AccountId: RawRepresentable, UndraRecord, Sendable, Hashable, Codable {
    /// The wrapped value.
    public var rawValue: UUID

    /// Wraps `rawValue`.
    public init(rawValue: UUID)

    /// Wraps `rawValue`.
    public init(_ rawValue: UUID)

    public init(from decoder: any Decoder) throws

    public func encode(to encoder: any Encoder) throws

    public static func undraDecode(_ r: inout UndraReader) throws -> AccountId

    public func undraEncode(_ w: inout UndraWriter)
}

/// An amount in cents: a whole number that is not just any number.
public struct Cents: RawRepresentable, UndraRecord, Sendable, Hashable, Codable, Comparable {
    /// The wrapped value.
    public var rawValue: Int64

    /// Wraps `rawValue`.
    public init(rawValue: Int64)

    /// Wraps `rawValue`.
    public init(_ rawValue: Int64)

    public init(from decoder: any Decoder) throws

    public func encode(to encoder: any Encoder) throws

    public static func < (lhs: Cents, rhs: Cents) -> Bool

    public static func undraDecode(_ r: inout UndraReader) throws -> Cents

    public func undraEncode(_ w: inout UndraWriter)
}

/// A record that nests the other kinds: lists, options, maps, enums with data and a map with
/// integer keys.
public struct Composite: UndraRecord, Sendable, Hashable {
    /// A name.
    public var name: String
    /// Several strings.
    public var tags: [String]
    /// Maybe a figure.
    public var figure: Figure?
    /// Figures, in order.
    public var history: [Figure]
    /// A map keyed by string.
    public var scores: [String: Int32]
    /// A map keyed by integer.
    public var names: [UInt32: String]
    /// Maybe a number.
    public var limit: UInt32?

    public init(
        name: String,
        tags: [String],
        figure: Figure?,
        history: [Figure],
        scores: [String: Int32],
        names: [UInt32: String],
        limit: UInt32?
    )

    public static func undraDecode(_ r: inout UndraReader) throws -> Composite

    public func undraEncode(_ w: inout UndraWriter)
}

/// One value of each SQLite storage class, as [`db_cells`] read it back.
public struct DbCells: UndraRecord, Sendable, Hashable, Codable {
    /// The `INTEGER`.
    public var int: Int64
    /// The `REAL`.
    public var real: Double
    /// The `TEXT`.
    public var text: String
    /// The `BLOB`.
    public var blob: [UInt8]
    /// The column that held `NULL` (or the text given for it).
    public var none: String?
    /// SQLite's `typeof()` of the five columns, in order.
    public var types: [String]

    public init(
        int: Int64,
        real: Double,
        text: String,
        blob: [UInt8],
        none: String?,
        types: [String]
    )

    public static func undraDecode(_ r: inout UndraReader) throws -> DbCells

    public func undraEncode(_ w: inout UndraWriter)
}

/// One line of an account's statement.
public struct Entry: UndraRecord, Sendable, Hashable, Codable {
    /// The account the money went into.
    public var account: AccountId
    /// How much.
    public var amount: Price
    /// What it was for.
    public var memo: String
    /// When the caller says it happened.
    public var at: Date

    public init(account: AccountId, amount: Price, memo: String, at: Date)

    public static func undraDecode(_ r: inout UndraReader) throws -> Entry

    public func undraEncode(_ w: inout UndraWriter)
}

/// A window of [`Entry`] rows.
public struct EntrySlice: UndraRecord, Sendable, Hashable, Codable {
    /// The rows of this window.
    public var items: [Entry]
    /// The offset of the next window, if there is one.
    public var next: UInt32?

    public init(items: [Entry], next: UInt32?)

    public static func undraDecode(_ r: inout UndraReader) throws -> EntrySlice

    public func undraEncode(_ w: inout UndraWriter)
}

/// One row of a list, identified by `id`.
public struct Item: UndraRecord, Sendable, Hashable, Codable, Identifiable {
    /// Identity of the row; lists are patched by it, never by position.
    public var id: UInt32
    /// The text of the row.
    public var label: String
    /// How many times the row was updated.
    public var version: UInt32

    public init(id: UInt32, label: String, version: UInt32)

    public static func undraDecode(_ r: inout UndraReader) throws -> Item

    public func undraEncode(_ w: inout UndraWriter)
}

/// One note, a row of the `notes` table.
public struct Note: UndraRecord, Sendable, Hashable, Codable {
    /// The row id.
    public var id: Int64
    /// The text.
    public var title: String
    /// Whether it is ticked.
    public var done: Bool

    public init(id: Int64, title: String, done: Bool)

    public static func undraDecode(_ r: inout UndraReader) throws -> Note

    public func undraEncode(_ w: inout UndraWriter)
}

/// A price: an exact decimal number of the currency's major unit.
public struct Price: RawRepresentable, UndraRecord, Sendable, Hashable, Codable, Comparable {
    /// The wrapped value.
    public var rawValue: Decimal

    /// Wraps `rawValue`.
    public init(rawValue: Decimal)

    /// Wraps `rawValue`.
    public init(_ rawValue: Decimal)

    public init(from decoder: any Decoder) throws

    public func encode(to encoder: any Encoder) throws

    public static func < (lhs: Price, rhs: Price) -> Bool

    public static func undraDecode(_ r: inout UndraReader) throws -> Price

    public func undraEncode(_ w: inout UndraWriter)
}

/// One value of every primitive the wire has, so a single call covers them all.
public struct Primitives: UndraRecord, Sendable, Hashable {
    /// A boolean.
    public var flag: Bool
    /// An `i8`.
    public var tiny: Int8
    /// An `i16`.
    public var small: Int16
    /// An `i32`.
    public var int: Int32
    /// An `i64`: a `bigint` in TypeScript.
    public var long: Int64
    /// A `u8`.
    public var byte: UInt8
    /// A `u16`.
    public var word: UInt16
    /// A `u32`.
    public var dword: UInt32
    /// A `u64`: a `bigint` in TypeScript.
    public var qword: UInt64
    /// An `f32`.
    public var single: Float
    /// An `f64`.
    public var double: Double
    /// A string, UTF-8 on the wire.
    public var text: String
    /// Raw bytes.
    public var blob: [UInt8]
    /// A span of time, whole nanoseconds on the wire.
    public var span: Duration
    /// A moment, milliseconds since the Unix epoch on the wire.
    public var at: Date
    /// A UUID, sixteen bytes on the wire.
    public var id: UUID

    public init(
        flag: Bool,
        tiny: Int8,
        small: Int16,
        int: Int32,
        long: Int64,
        byte: UInt8,
        word: UInt16,
        dword: UInt32,
        qword: UInt64,
        single: Float,
        double: Double,
        text: String,
        blob: [UInt8],
        span: Duration,
        at: Date,
        id: UUID
    )

    public static func undraDecode(_ r: inout UndraReader) throws -> Primitives

    public func undraEncode(_ w: inout UndraWriter)
}

/// What a [`Probe`] has seen.
public struct ProbeCounters: UndraRecord, Sendable, Hashable, Codable {
    /// Calls that started running in the core.
    public var started: UInt32
    /// Calls that ran to the end.
    public var completed: UInt32
    /// Calls the core dropped before they ended, because the platform cancelled them.
    public var cancelled: UInt32
    /// Items the core produced for streams (whether or not the platform has read them yet).
    public var produced: UInt32

    public init(started: UInt32, completed: UInt32, cancelled: UInt32, produced: UInt32)

    public static func undraDecode(_ r: inout UndraReader) throws -> ProbeCounters

    public func undraEncode(_ w: inout UndraWriter)
}

/// A record of types from other crates: every field is a leaf type that crosses as a wire type.
public struct Receipt: UndraRecord, Sendable, Hashable {
    /// A `uuid::Uuid`, which crosses as `Uuid`.
    public var id: UUID
    /// A `chrono::DateTime<Utc>`, which crosses as `Timestamp` (milliseconds).
    public var issued: Date
    /// A `chrono::TimeDelta`, which crosses as `Duration` (nanoseconds).
    public var validFor: Duration
    /// A `rust_decimal::Decimal`, which crosses as `Decimal`.
    public var total: Decimal
    /// A `bytes::Bytes`, which crosses as `Bytes`.
    public var signature: [UInt8]

    public init(id: UUID, issued: Date, validFor: Duration, total: Decimal, signature: [UInt8])

    public static func undraDecode(_ r: inout UndraReader) throws -> Receipt

    public func undraEncode(_ w: inout UndraWriter)
}

/// Where the server is: what an app supplies once, at start-up.
public struct RemoteConfig: UndraRecord, Sendable, Hashable, Codable {
    /// The server's address without a trailing slash, such as `https://api.example.com`.
    public var baseUrl: String

    public init(baseUrl: String)

    public static func undraDecode(_ r: inout UndraReader) throws -> RemoteConfig

    public func undraEncode(_ w: inout UndraWriter)
}

/// One to-do item on the server.
public struct RemoteTodo: UndraRecord, Sendable, Hashable, Codable {
    /// 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`.
    public var id: UInt32
    /// What has to be done.
    public var title: String
    /// Whether it is finished.
    public var done: Bool

    public init(id: UInt32, title: String, done: Bool)

    public static func undraDecode(_ r: inout UndraReader) throws -> RemoteTodo

    public func undraEncode(_ w: inout UndraWriter)
}

/// What [`sse_follow`] read.
public struct SseFollow: UndraRecord, Sendable, Hashable, Codable {
    /// The events, in order.
    public var events: [SseEvent]
    /// Whether the server ended the stream (`SseError::Ended`) before `max` events.
    public var ended: Bool

    public init(events: [SseEvent], ended: Bool)

    public static func undraDecode(_ r: inout UndraReader) throws -> SseFollow

    public func undraEncode(_ w: inout UndraWriter)
}

/// What the query client's persistence did so far: [`storage_status`].
public struct StorageStatus: UndraRecord, Sendable, Hashable, Codable {
    /// Mutations waiting in the offline queue.
    public var pending: UInt32
    /// The dead letters, as `"<mutation>: <reason>"`.
    public var deadLetters: [String]
    /// Whether the stored offline queue has been read (`false` while the store cannot be read:
    /// the queue is then neither replayed nor written).
    public var queueReadable: Bool
    /// Writes to the `Kv` store that failed.
    public var writeFailed: UInt64
    /// Persisted cache entries dropped because they could not be migrated.
    public var dropped: UInt64
    /// Cache entries and queued mutations an older build wrote that were migrated.
    public var migrated: UInt64
    /// Queued mutations moved to the dead-letter queue.
    public var deadLettered: UInt64

    public init(
        pending: UInt32,
        deadLetters: [String],
        queueReadable: Bool,
        writeFailed: UInt64,
        dropped: UInt64,
        migrated: UInt64,
        deadLettered: UInt64
    )

    public static func undraDecode(_ r: inout UndraReader) throws -> StorageStatus

    public func undraEncode(_ w: inout UndraWriter)
}

/// One item of the to-do list.
public struct Todo: UndraRecord, Sendable, Hashable, Codable {
    /// Identity of the item; the list is updated by key, so the UI diffs by it.
    public var id: UUID
    /// What has to be done.
    public var title: String
    /// Whether it is finished.
    public var done: Bool

    public init(id: UUID, title: String, done: Bool)

    public static func undraDecode(_ r: inout UndraReader) throws -> Todo

    public func undraEncode(_ w: inout UndraWriter)
}

/// A shape: an enum with named fields, a tuple variant and a unit variant.
public enum Figure: UndraEnum, Sendable, Hashable {
    /// A circle.
    case circle(radius: Double)
    /// A rectangle.
    case rect(width: Double, height: Double)
    /// A shape that is only a name.
    case label(String)
    /// No shape at all.
    case empty

    public static func undraDecode(_ r: inout UndraReader) throws -> Figure

    public func undraEncode(_ w: inout UndraWriter)
}

/// Which items the list shows.
public enum Filter: UInt16, UndraEnum, CaseIterable, Sendable, Codable {
    /// Every item.
    case all = 0
    /// Items that are not finished.
    case active = 1
    /// Items that are finished.
    case done = 2

    public static func undraDecode(_ r: inout UndraReader) throws -> Filter

    public func undraEncode(_ w: inout UndraWriter)
}

/// A window of entries that may still be loading.
public enum LoadableEntries: UndraEnum, Sendable, Hashable {
    /// Nothing yet.
    case loading
    /// Here it is.
    case loaded(EntrySlice)
    /// It could not be had.
    case failed(String)

    public static func undraDecode(_ r: inout UndraReader) throws -> LoadableEntries

    public func undraEncode(_ w: inout UndraWriter)
}

/// Whether the count is even or odd: a value derived from `count` in the core.
public enum Parity: UInt16, UndraEnum, CaseIterable, Sendable, Codable {
    /// The count is divisible by two.
    case even = 0
    /// The count is not divisible by two.
    case odd = 1

    public static func undraDecode(_ r: inout UndraReader) throws -> Parity

    public func undraEncode(_ w: inout UndraWriter)
}

/// Which signal `burst` and `start` write.
public enum StressMode: UInt16, UndraEnum, CaseIterable, Sendable, Codable {
    /// `value` + 1 per transaction: a firehose the platforms apply once per frame.
    case firehose = 0
    /// `progress` + 1 per transaction: a `no_coalesce` signal the platforms apply step by step.
    case progress = 1

    public static func undraDecode(_ r: inout UndraReader) throws -> StressMode

    public func undraEncode(_ w: inout UndraWriter)
}

/// The fetch state of a query (SPEC section 9).
public enum QueryStatus: UInt16, UndraEnum, CaseIterable, Sendable, Codable {
    /// No fetch has started.
    case idle = 0
    /// A fetch is in flight.
    case fetching = 1
    /// The latest fetch succeeded.
    case success = 2
    /// The latest fetch failed.
    case error = 3

    public static func undraDecode(_ r: inout UndraReader) throws -> QueryStatus

    public func undraEncode(_ w: inout UndraWriter)
}

Errors#

An enum for each #[undra::error], conforming to Error.

LabError LedgerError ListError RemoteError ReportError StressError TickError TodoError WorkshopError

Show the declarations 159 lines
/// Why a lab call failed.
public enum LabError: UndraError, Error, Sendable, Hashable {
    /// Nothing was given.
    case empty
    /// The text is longer than `max` characters.
    case tooLong(max: UInt32)
    /// The text is not a number.
    case notANumber(String)
    /// A failure chosen by the caller.
    case rejected(code: Int32, reason: String)

    public static func undraDecode(_ r: inout UndraReader) throws -> LabError

    public func undraEncode(_ w: inout UndraWriter)
}

extension LabError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why a ledger operation failed.
public enum LedgerError: UndraError, Error, Sendable, Hashable {
    /// No account has this identity.
    case noSuchAccount
    /// The amount cannot be added (it is not a number `rust_decimal` holds).
    case outOfRange

    public static func undraDecode(_ r: inout UndraReader) throws -> LedgerError

    public func undraEncode(_ w: inout UndraWriter)
}

extension LedgerError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why an operation on a list was refused.
public enum ListError: UndraError, Error, Sendable, Hashable {
    /// A position is not in the list.
    case outOfRange(index: UInt32, len: UInt32)

    public static func undraDecode(_ r: inout UndraReader) throws -> ListError

    public func undraEncode(_ w: inout UndraWriter)
}

extension ListError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why a request to the server failed.
public enum RemoteError: UndraError, Error, Sendable, Hashable {
    /// [`configure_remote`] was not called.
    case notConfigured
    /// The `Http` port failed: no network, a timeout, a bad URL, or a cancelled request.
    case http(HttpError)
    /// The server answered with a status that is not a success.
    case status(code: UInt16)
    /// The server's answer is not the JSON this core expects.
    case badBody(String)

    public static func undraDecode(_ r: inout UndraReader) throws -> RemoteError

    public func undraEncode(_ w: inout UndraWriter)
}

extension RemoteError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// What a reporter's `confirm` can fail with.
public enum ReportError: UndraError, Error, Sendable, Hashable {
    /// The user answered no.
    case declined
    /// The app's reporter is not there or failed.
    case unavailable(String)

    public static func undraDecode(_ r: inout UndraReader) throws -> ReportError

    public func undraEncode(_ w: inout UndraWriter)
}

extension ReportError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why `start` refused to start.
public enum StressError: UndraError, Error, Sendable, Hashable {
    /// The rate is zero or above the fastest generator there is (1,000,000 updates a second).
    case rateOutOfRange(rate: UInt32, max: UInt32)

    public static func undraDecode(_ r: inout UndraReader) throws -> StressError

    public func undraEncode(_ w: inout UndraWriter)
}

extension StressError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why the ticker could not tick.
public enum TickError: UndraError, Error, Sendable, Hashable {
    /// [`set_ticker_failing`] made it fail.
    case failing

    public static func undraDecode(_ r: inout UndraReader) throws -> TickError

    public func undraEncode(_ w: inout UndraWriter)
}

extension TickError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// Why an item could not be added.
public enum TodoError: UndraError, Error, Sendable, Hashable {
    /// The title is empty once spaces are trimmed.
    case emptyTitle

    public static func undraDecode(_ r: inout UndraReader) throws -> TodoError

    public func undraEncode(_ w: inout UndraWriter)
}

extension TodoError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

/// What can go wrong opening a shelf.
public enum WorkshopError: UndraError, Error, Sendable, Hashable {
    /// The name is empty.
    case noName

    public static func undraDecode(_ r: inout UndraReader) throws -> WorkshopError

    public func undraEncode(_ w: inout UndraWriter)
}

extension WorkshopError: CustomStringConvertible, LocalizedError {
    public var description: String

    public var errorDescription: String?
}

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 498 lines
public final class Live: UndraObject, @unchecked Sendable {
    /// No connection yet.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Forgets the connection without closing it: the port closes it going away (1001).
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func connect(
        url: String,
        protocols: [String],
        headers: [Header]
    ) async throws -> String

    /// Closes the connection with `code` and `reason` (`close` is every object's own: it releases
    /// the handle).
    /// - Throws: ``WsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func disconnect(code: UInt16, reason: String) async throws

    /// How many pulls the inbound stream has made (each asks the platform for up to 16).
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func pulls() throws -> UInt64

    /// 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func read(count: UInt32) async throws -> [WsMessage]

    /// Sends `message` on the open connection.
    /// - Throws: ``WsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func send(_ message: WsMessage) async throws
}

public final class Probe: UndraObject, @unchecked Sendable {
    /// A probe with every counter at zero.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// What the probe has seen so far.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func counters() throws -> ProbeCounters

    /// Waits forever. The only way it ends is cancellation, which the `cancelled` counter shows.
    /// - Throws: `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func hang() async throws -> UInt32

    /// Sets every counter back to zero.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: Iterating throws ``UndraCallError`` if the call fails in the core or cannot reach it; cancelling the iterating task ends the loop quietly.
    public func ticks(count: UInt32) -> AsyncThrowingStream<UInt32, Error>

    /// 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.
    /// - Note: Iterating throws ``LabError``, or ``UndraCallError`` if the call fails in the core or cannot reach it; cancelling the iterating task ends the loop quietly.
    public func ticksThenFail(
        count: UInt32,
        failAt: UInt32,
        code: Int32
    ) -> AsyncThrowingStream<UInt32, Error>

    /// Waits `ms` milliseconds and returns it. Cancelled before that, it counts as cancelled.
    /// - Throws: `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func wait(ms: UInt32) async throws -> UInt32
}

/// The to-dos opened last.
public final class RecentTodos: UndraObject, @unchecked Sendable {
    /// A list that keeps the last `limit` rows opened.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(limit: UInt32, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// The row opened last, if any was.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func latest() throws -> Todo?

    /// Records that `row` was opened: it moves to the front, and the oldest falls off the end.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func `open`(_ row: Todo)

    /// The rows opened last, newest first.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func rows() throws -> [Todo]
}

public final class Watch: UndraObject, @unchecked Sendable {
    /// The subscription's number, in the order they were made.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func id() throws -> UInt32
}

/// Adds two numbers, wrapping on overflow: a synchronous call with primitive arguments.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func add(a: Int32, b: Int32, ctx: UndraCore = UndraPlaygroundCore.core) throws -> Int32

/// Adds two numbers after `delay_ms` milliseconds: an asynchronous call that waits on the `Timer`
/// port.
/// - Throws: `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func addLater(
    a: Int32,
    b: Int32,
    delayMs: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> Int32

/// The area of a circle or a rectangle. A label and an empty figure have none.
/// - Throws: ``LabError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
public func area(_ figure: Figure, ctx: UndraCore = UndraPlaygroundCore.core) throws -> Double

/// The balance of every account: a map keyed by a newtype.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func balances(ctx: UndraCore = UndraPlaygroundCore.core) throws -> [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).
/// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
public func 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func createRemoteTodo(
    list: String,
    title: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> RemoteTodo

/// Writes one value of each storage class to an in-memory database and reads them back.
/// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func dbCells(
    int: Int64,
    real: Double,
    text: String,
    blob: [UInt8],
    none: String?,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func dbMigrate(
    name: String,
    broken: Bool,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> UInt32

/// 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func dbRun(
    name: String,
    sql: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> UInt64

/// Adds `amount` to the balance of `account` and returns the new balance. Exact: `0.1` and `0.2`
/// make `0.3`.
/// - Throws: ``LedgerError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
public func deposit(
    account: AccountId,
    amount: Price,
    memo: String,
    at: Date,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> 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 call fails in the core or cannot reach it.
public func draft(
    _ type: Note.Type,
    title: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> 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 call fails in the core or cannot reach it.
public func draft(
    _ type: Todo.Type,
    title: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> Todo

/// Returns `id`: a newtype of `Uuid` comes back as itself.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoAccount(
    _ id: AccountId,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> AccountId

/// Returns `cents`: a newtype of `i64`.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoCents(_ cents: Cents, ctx: UndraCore = UndraPlaygroundCore.core) throws -> Cents

/// Returns `value` unchanged.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoComposite(
    _ value: Composite,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> Composite

/// Returns `value` exactly: mantissa, scale and all (`1.10` stays `1.10`).
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoDecimal(
    value: Decimal,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> Decimal

/// Returns `value` unchanged.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoFigure(
    _ value: Figure,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> Figure

/// Returns `price`: a newtype of `Decimal`.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoPrice(_ price: Price, ctx: UndraCore = UndraPlaygroundCore.core) throws -> Price

/// Returns `value` unchanged.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoPrimitives(
    _ value: Primitives,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> Primitives

/// Returns `receipt`: every leaf type of another crate, through the core and back.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func echoReceipt(
    _ receipt: Receipt,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> 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 call fails in the core or cannot reach it.
public func explode(reason: String, ctx: UndraCore = UndraPlaygroundCore.core) throws -> UInt32

/// 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`).
/// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
public func explodeDetached(reason: String, ctx: UndraCore = UndraPlaygroundCore.core)

/// Panics with `reason` after `delay_ms` milliseconds, inside an asynchronous call.
/// - Throws: `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func explodeLater(
    delayMs: UInt32,
    reason: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> UInt32

/// Fails with `LabError::Rejected { code, .. }` after `delay_ms` milliseconds: an asynchronous
/// call with a typed error.
/// - Throws: ``LabError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func failLater(
    delayMs: UInt32,
    code: Int32,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> UInt32

/// Deletes the file or directory `path` of the `Fs` port.
/// - Throws: ``FsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func fileDelete(path: String, ctx: UndraCore = UndraPlaygroundCore.core) async throws

/// The names in the directory `dir` of the `Fs` port, sorted.
/// - Throws: ``FsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func fileList(
    dir: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [String]

/// The contents of the file `path` of the `Fs` port.
/// - Throws: ``FsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func fileRead(
    path: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [UInt8]

/// Writes `data` to the file `path` of the `Fs` port, creating its directories.
/// - Throws: ``FsError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func fileWrite(
    path: String,
    data: [UInt8],
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws

/// A greeting.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func greet(name: String, ctx: UndraCore = UndraPlaygroundCore.core) throws -> 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func httpGet(
    url: String,
    timeoutMs: UInt32?,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> HttpResponse

/// The value the `Kv` port has under `key`, if any.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func kvGet(key: String, ctx: UndraCore = UndraPlaygroundCore.core) async throws -> [UInt8]?

/// The keys of the `Kv` port that start with `prefix`, in ascending order.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func kvKeys(
    prefix: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [String]

/// Stores `value` under `key` in the `Kv` port.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func kvPut(
    key: String,
    value: [UInt8],
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws

/// Removes `key` from the `Kv` port; a missing key is not an error.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func kvRemove(key: String, ctx: UndraCore = UndraPlaygroundCore.core) async throws

/// 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 call fails in the core or cannot reach it.
public func loadableStatement(
    account: AccountId,
    ready: Bool,
    limit: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> LoadableEntries

/// Greets `name` in the user's language, through the [`Locale`] port.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func localizedGreeting(
    name: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> String

/// The newest of `rows`, the one whose identity counts highest, or nothing for an empty list.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func newest(rows: [Note], ctx: UndraCore = UndraPlaygroundCore.core) throws -> Note?

/// The newest of `rows`, the one whose identity counts highest, or nothing for an empty list.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func newest(rows: [Todo], ctx: UndraCore = UndraPlaygroundCore.core) throws -> Todo?

/// A new account for `owner`, with an identity from the ledger's counter.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func openAccount(
    owner: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> AccountId

/// Who owns `account`, or an empty string for an unknown one.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func ownerOf(
    _ account: AccountId,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> String

/// Reads an unsigned number of at most nine digits.
/// - Throws: ``LabError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
public func parseCount(text: String, ctx: UndraCore = UndraPlaygroundCore.core) throws -> UInt32

/// Does nothing and returns nothing: a call with neither arguments nor a result.
/// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
public func 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 call fails in the core or cannot reach it.
public func recentTodos(
    rows: [Todo],
    limit: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> 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 call fails in the core or cannot reach it.
public func sampleReceipt(ctx: UndraCore = UndraPlaygroundCore.core) throws -> Receipt

/// The value the `SecureStore` port has under `key`, if any.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func secretGet(
    key: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [UInt8]?

/// The keys of the `SecureStore` port that start with `prefix`, in ascending order.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func secretKeys(
    prefix: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [String]

/// Stores `value` under `key` in the `SecureStore` port (the Keychain, the Android Keystore).
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func secretPut(
    key: String,
    value: [UInt8],
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws

/// Removes `key` from the `SecureStore` port; a missing key is not an error.
/// - Throws: ``StorageError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func secretRemove(key: String, ctx: UndraCore = UndraPlaygroundCore.core) async throws

/// Marks an item of `list` finished or not, showing the change at once and taking it back if the server
/// refuses.
/// - Throws: ``RemoteError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func setRemoteDone(
    list: String,
    id: UInt32,
    done: Bool,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> RemoteTodo

/// Makes the ticker fail (or succeed again) from its next fetch on.
/// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
public func setTickerFailing(failing: Bool, 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func sseFollow(
    url: String,
    lastEventId: String?,
    max: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> SseFollow

/// `limit` entries of the statement of `account` from `offset`: a named instantiation of [`Slice`].
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func statement(
    account: AccountId,
    offset: UInt32,
    limit: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) throws -> EntrySlice

/// What the query client's persistence did: the offline queue, its dead letters and the
/// persistence counters.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func storageStatus(ctx: UndraCore = UndraPlaygroundCore.core) throws -> StorageStatus

/// How many times the ticker fetched, for a test that wants the number the core sees.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func tickerFetches(ctx: UndraCore = UndraPlaygroundCore.core) throws -> UInt32

/// Makes the feed's even rows show revision `revision` the next time they are fetched.
/// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
public func touchFeed(revision: UInt32, ctx: UndraCore = UndraPlaygroundCore.core)

/// The name and version of the core.
/// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
public func version(ctx: UndraCore = UndraPlaygroundCore.core) throws -> 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func wsEcho(
    url: String,
    messages: [WsMessage],
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> [WsMessage]

Stores#

An @Observable class for each #[undra::store]: its signals, then its methods.

Bench BigList Counter Device Ledger Legacy Library NoteSelection Notes Profile Shelf Stress TodoSelection Todos Workshop

Show the declarations 491 lines
/// The benchmark store: 128 counters, a 10,000-row keyed list and three methods that
/// exercise the boundary.
@MainActor @Observable
public final class Bench: UndraStore, @unchecked Sendable {
    public private(set) var rows: [Item]
    public private(set) var s000: UInt32
    // … 126 more with the same shape …
    public private(set) var s127: UInt32

    /// A store with every counter at zero and [`ROWS`] rows numbered from 1.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Adds two numbers: the cheapest call there is, for the handle-call row.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func benchAdd(a: UInt32, b: UInt32) throws -> UInt32

    /// Returns `data` unchanged: a payload of `data.len()` bytes crosses the boundary
    /// twice.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func benchEchoBytes(data: [UInt8]) throws -> [UInt8]

    /// 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func benchListInsert(i: UInt32)

    /// 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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).
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func benchListUpdateBurst(n: UInt32)

    /// Adds one to the first `k` counters (at most [`SIGNALS`]) inside one transaction:
    /// `k` dirty signals, one change-set.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func benchTouchSignals(k: UInt32)
}

/// A list of [`LIST_LEN`] items with operations that change one item at a time.
@MainActor @Observable
public final class BigList: UndraStore, @unchecked Sendable {
    public private(set) var items: [Item]
    /// Computed by the core; read-only.
    public private(set) var count: UInt32

    /// A list of [`LIST_LEN`] items numbered from 1.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Inserts a new row with `label` so that it ends at `index` (`index == len` appends), and
    /// returns its identity. One keyed `Insert`.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func insertAt(index: UInt32, label: String) throws -> UInt32

    /// Moves the row at `from` so that it ends at `to`. One keyed `Move`.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func moveItem(from: UInt32, to: UInt32) throws

    /// Removes the row at `index`. One keyed `Remove`.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func removeAt(index: UInt32) throws

    /// 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).
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func reset()

    /// Changes the label of the row at `index` and bumps its version. One keyed `Update`.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func updateAt(index: UInt32, label: String) throws
}

/// A counter with a change tally and a computed parity.
@MainActor @Observable
public final class Counter: UndraStore, @unchecked Sendable {
    public private(set) var count: Int32
    public private(set) var changes: UInt32
    /// Computed by the core; read-only.
    public private(set) var parity: Parity

    /// A counter at zero with no changes made.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func add(amount: Int32)

    /// Subtracts one.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func decrement()

    /// Adds one.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func increment()

    /// Sets the count back to zero and forgets the changes, in one transaction.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func reset()
}

/// 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.
@MainActor @Observable
public final class Device: UndraStore, @unchecked Sendable {
    public private(set) var online: Bool
    public private(set) var netKind: NetKind
    public private(set) var appState: UndraAppState
    public private(set) var connectivityReports: UInt32
    public private(set) var lifecycleReports: UInt32

    /// The store, showing every report received so far and following the next ones.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws
}

/// The accounts the app lists: a list keyed by a newtype.
@MainActor @Observable
public final class Ledger: UndraStore, @unchecked Sendable {
    public private(set) var accounts: [Account]

    /// A ledger with no accounts.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Closes the account `id`; one keyed `Remove`.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func closeAccount(_ id: AccountId)

    /// Opens an account for `owner`; one keyed `Insert` whose key is a newtype.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func `open`(owner: String) throws -> AccountId

    /// Changes the owner of the account `id`; one keyed `Update`.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func rename(id: AccountId, owner: String)
}

/// A store whose one signal build B changes incompatibly.
@MainActor @Observable
public final class Legacy: UndraStore, @unchecked Sendable {
    public private(set) var score: Int32

    /// A score of `score`.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(score: Int32, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// `score=..`.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func describe() throws -> String
}

/// A library of books the host pages through.
@MainActor @Observable
public final class Library: UndraStore, @unchecked Sendable {
    /// 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.
    public let books: UndraLazyList<Item>
    public private(set) var source: [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.
    public let evens: UndraLazyList<Item>

    /// A library with [`LIBRARY_LEN`] books and a source of 20 rows.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func addRows(count: UInt32)

    /// How many books there are.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func count() throws -> UInt32

    /// Removes `count` rows from the start of `source` (the lazy view follows).
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func dropSource(count: UInt32)

    /// Removes the book at `index`.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func removeAt(index: UInt32) throws

    /// Changes the label of the book at `index` and bumps its version.
    /// - Throws: ``ListError``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func rename(index: UInt32, label: String) throws

    /// Replaces the books with `count` fresh ones numbered from 1.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func reset(count: UInt32)
}

/// The ticked notes.
@MainActor @Observable
public final class NoteSelection: UndraStore, @unchecked Sendable {
    public private(set) var rows: [Note]
    /// Computed by the core; read-only.
    public private(set) var count: UInt32

    /// Nothing ticked.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Unticks everything.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func clear()

    /// Ticks every row of `rows` that is not ticked yet, in one transaction.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func selectAll(rows: [Note])

    /// Ticks `row`, or unticks it if it is ticked.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func toggle(_ row: Note)
}

/// The notes of one database, mirrored: `notes` changes only after the database did.
@MainActor @Observable
public final class Notes: UndraStore, @unchecked Sendable {
    public private(set) var notes: [Note]
    public private(set) var version: UInt32

    /// No database open yet: call [`open`](Notes::open).
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Adds a note at the end.
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func add(title: String) async throws -> 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func addAll(titles: [String?]) async throws -> UInt32

    /// Adds a note with a chosen id (an id in use is `Constraint { kind: Unique }`).
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func addWithId(id: Int64, title: String) async throws -> Note

    /// Closes the database; the list keeps what it showed (`close` is every store's own: it
    /// releases the handle).
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func closeDatabase() async throws

    /// How many notes the database holds (read from it, not from the mirror).
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func count() async throws -> UInt32

    /// Opens (creating it if needed) database `name`, migrates it and loads every note.
    /// Returns its version.
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func `open`(name: String) async throws -> UInt32

    /// Removes note `id`.
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func remove(id: Int64) async throws

    /// Ticks or unticks note `id`.
    /// - Throws: ``DbError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func toggle(id: Int64) async throws
}

/// A user profile: build A's signals are `name`, then `visits`.
@MainActor @Observable
public final class Profile: UndraStore, @unchecked Sendable {
    public private(set) var name: String
    public private(set) var visits: UInt32

    /// A profile called `name`, never visited.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(name: String, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// `name=..;visits=..`: what both builds can be compared by.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func describe() throws -> String

    /// Counts one visit.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func visit()
}

/// A shelf: a child store of the [`Workshop`], with a label and a count of the items on it.
@MainActor @Observable
public final class Shelf: UndraStore, @unchecked Sendable {
    public private(set) var label: String
    public private(set) var items: UInt32

    /// 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 call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Takes every item off the shelf.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func clear()

    /// Puts `count` more items on the shelf.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func stock(count: UInt32)
}

/// A store that commits many transactions, for the coalesced-delivery scenarios and the
/// playground's stress screen.
@MainActor @Observable
public final class Stress: UndraStore, @unchecked Sendable {
    public private(set) var value: UInt64
    public private(set) var progress: UInt32
    public private(set) var generated: UInt64
    public private(set) var running: Bool

    /// A store with every signal at its start: zeros, and no generator running.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func burst(mode: StressMode, transactions: UInt32)

    /// 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``, or ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func start(mode: StressMode, perSecond: UInt32) throws

    /// Stops the generator: no update is committed after this returns. `generated` keeps its
    /// count. Does nothing when no generator runs.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func stop()
}

/// The ticked to-dos.
@MainActor @Observable
public final class TodoSelection: UndraStore, @unchecked Sendable {
    public private(set) var rows: [Todo]
    /// Computed by the core; read-only.
    public private(set) var count: UInt32

    /// Nothing ticked.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Unticks everything.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func clear()

    /// Ticks every row of `rows` that is not ticked yet, in one transaction.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func selectAll(rows: [Todo])

    /// Ticks `row`, or unticks it if it is ticked.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func toggle(_ row: Todo)
}

/// The to-do list: what the UI observes (`todos`, `filter`, `visible`, `remaining`) and calls.
@MainActor @Observable
public final class Todos: UndraStore, @unchecked Sendable {
    public private(set) var todos: [Todo]
    public private(set) var filter: Filter
    /// Derived by the core from another list; read-only. Changes arrive as keyed patches.
    public private(set) var visible: [Todo]
    /// Computed by the core; read-only.
    public private(set) var remaining: UInt32

    /// An empty list showing every item.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Adds an item at the end of the list.
    /// - Throws: ``TodoError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func add(title: String) async throws -> Todo

    /// Removes every finished item.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func fill(count: UInt32)

    /// Removes the item with `id`; unknown ids are ignored.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func remove(id: UUID)

    /// Chooses which items `visible` holds.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func setFilter(_ filter: Filter)

    /// Flips the `done` flag of the item with `id`; unknown ids are ignored.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func toggle(id: UUID)
}

/// 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.
@MainActor @Observable
public final class Workshop: UndraStore, @unchecked Sendable {
    public private(set) var jobs: UInt32
    public private(set) var notes: UInt32

    /// An empty workshop.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// 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 call fails in the core or cannot reach it.
    public func announce(line: String) throws -> UInt32

    /// 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`.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func burst(steps: UInt32, reporter: any Reporter)

    /// The label of `shelf`, or `none` for no shelf at all.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func describe(shelf: Shelf?) throws -> String

    /// The shelf called `name`, if there is one.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func find(name: String) throws -> Shelf?

    /// Moves every item of `from` onto `onto`, in one transaction (a method that takes two
    /// stores).
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func `open`(name: String, delayMs: UInt32) async throws -> 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``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
    public func run(steps: UInt32, reporter: any Reporter) async throws -> UInt32

    /// 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 call fails in the core or cannot reach it.
    public func shelf(name: String) throws -> Shelf

    /// Every shelf, in name order.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func shelves() throws -> [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.
    /// - Note: Iterating throws ``UndraCallError`` if the call fails in the core or cannot reach it; cancelling the iterating task ends the loop quietly.
    public func tally(shelf: Shelf, steps: UInt32) -> AsyncThrowingStream<UInt32, Error>

    /// How many items there are on the shelves given.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func total(shelves: [Shelf]) throws -> UInt32

    /// 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.
    /// - Note: Iterating throws ``UndraCallError`` if the call fails in the core or cannot reach it; cancelling the iterating task ends the loop quietly.
    public func walk(steps: UInt32, reporter: any Reporter) -> AsyncThrowingStream<UInt32, Error>

    /// Keeps `reporter` until the returned subscription is closed; [`Workshop::announce`] tells it.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func watch(reporter: any Reporter) throws -> Watch

    /// How many reporters are subscribed.
    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public func watching() throws -> UInt32
}

Ports#

A protocol for each port the core declares, and an adapter that registers your implementation.

Locale localePortImpl

Show the declarations 21 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`.
///
/// The core calls these methods from its own thread, so a conforming class is nonisolated and
/// `Sendable`: under default main-actor isolation (Xcode 26) it cannot keep mutable state without
/// a lock or read main-actor state in a synchronous method. ``localePortImpl(hello:)``
/// takes closures instead, so nothing has to conform. Registering either needs `import UndraRuntime`.
public protocol Locale: UndraPort, Sendable {
    /// "Hello" in the user's language.
    nonisolated func hello() -> String
}

/// Adapts an implementation of ``Locale`` to `UndraCore.registerPort(UndraIds.Ports.Locale.portId, _:)`.
public func localePortImpl(_ impl: any Locale) -> PortImpl

/// ``localePortImpl(_:)`` from closures, one per method in the protocol's order, for an app that has no
/// class to conform: under default main-actor isolation a closure literal passed here is nonisolated, so
/// this form compiles unchanged. The closures run on the core's thread: read main-actor state in an
/// async one with `await MainActor.run { .. }`, never in a synchronous one.
public func localePortImpl(hello: @escaping @Sendable () -> String) -> PortImpl

Callbacks#

A protocol for each #[undra::callback] trait, which your app implements so the core can call it, and a weak wrapper to hand over instead of the object itself.

Reporter WeakReporter

Show the declarations 38 lines
/// What the app implements to hear from the core.
///
/// The core calls an implementation on the main actor, after the store changes it made
/// before the call are applied. Pass an implementation to a method that takes one; the core
/// keeps it until it lets go of what it gave it to (``WeakReporter`` keeps it weakly).
@MainActor
public protocol Reporter: AnyObject, Sendable {
    /// Asks whether to go on; the app may answer later, or not at all.
    /// - Throws: ``ReportError``.
    func confirm(question: String) async throws(ReportError) -> Bool
    /// A line to show.
    func 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.
    func progress(done: UInt32, total: UInt32)
}

/// A ``Reporter`` that forwards to `target` while it lives, without keeping it alive: what to
/// pass when the implementation holds (directly or not) the object it is passed to. Once
/// `target` is gone the core's calls do nothing, and its questions are answered as
/// unavailable.
@MainActor
public final class WeakReporter: Reporter, UndraWeakMainCallback {
    /// The ``Reporter`` the calls go to, while it lives.
    public private(set) weak var target: (any Reporter)?

    /// Forwards to `target` without keeping it alive.
    public init(_ target: any Reporter)

    /// `target`, for the runtime, which calls it directly.
    public var undraTarget: AnyObject?

    public func confirm(question: String) async throws(ReportError) -> Bool

    public func note(line: String)

    public func progress(done: UInt32, total: UInt32)
}

Queries#

A handle for each #[undra::query], a function for each #[undra::mutation].

FeedQueryHandle RemoteTodosQueryHandle RosterQueryHandle TickerQueryHandle patchRemoteTodo postRemoteTodo saveNote tagNote

Show the declarations 179 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.
@MainActor @Observable
public final class FeedQueryHandle: UndraStore, @unchecked Sendable {
    /// Every row loaded so far, in order: the first page, then each page `fetchNextPage()` loaded. Empty until the first page arrives.
    public private(set) var data: [Item]
    /// Where the query is in its fetch lifecycle.
    public private(set) var status: QueryStatus
    /// The error of the latest failed fetch, cleared by the next success.
    public private(set) var error: ListError?
    /// Whether a fetch is in flight (also true while refetching stale data).
    public private(set) var fetching: Bool
    /// When `data` was last updated.
    public private(set) var updatedAt: Date?
    /// Whether another page can be fetched: the last page loaded named a next cursor.
    public private(set) var hasNextPage: Bool
    /// Whether the fetch of the next page is in flight.
    public private(set) var fetchingNextPage: Bool

    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(evenOnly: Bool, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Fetches the next page and appends its rows to `data`; nothing happens while a page is loading or when there is no next page.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func fetchNextPage()

    /// Fetches again now, even if the data is fresh.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func refetch()

    /// Marks the cached entry stale; it refetches while observed.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func setPollInterval(_ interval: Duration?)

    /// Fetches the next page when `item` is within `threshold` rows of the end of `data`.
    ///
    /// Call it from each row's `onAppear`: it does nothing while a page is loading or when there is no
    /// next page.
    public func loadMore(ifNeededFor item: Item, threshold: Int = 5)
}

/// Observes the `remote_todos` query (cache key `remote-todos:{list}`).
/// Constructing it registers an observer and fetches when the data is stale or missing.
@MainActor @Observable
public final class RemoteTodosQueryHandle: UndraStore, @unchecked Sendable {
    /// The latest successful result, if any.
    public private(set) var data: [RemoteTodo]?
    /// Where the query is in its fetch lifecycle.
    public private(set) var status: QueryStatus
    /// The error of the latest failed fetch, cleared by the next success.
    public private(set) var error: RemoteError?
    /// Whether a fetch is in flight (also true while refetching stale data).
    public private(set) var fetching: Bool
    /// When `data` was last updated.
    public private(set) var updatedAt: Date?

    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(list: String, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Fetches again now, even if the data is fresh.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func refetch()

    /// Marks the cached entry stale; it refetches while observed.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func setPollInterval(_ interval: Duration?)
}

/// Observes the `roster` query (cache key `roster:{team}`).
/// Constructing it registers an observer and fetches when the data is stale or missing.
@MainActor @Observable
public final class RosterQueryHandle: UndraStore, @unchecked Sendable {
    /// The latest successful result, if any.
    public private(set) var data: [String]?
    /// Where the query is in its fetch lifecycle.
    public private(set) var status: QueryStatus
    /// The error of the latest failed fetch, cleared by the next success.
    public private(set) var error: RemoteError?
    /// Whether a fetch is in flight (also true while refetching stale data).
    public private(set) var fetching: Bool
    /// When `data` was last updated.
    public private(set) var updatedAt: Date?

    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(team: UInt32, ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Fetches again now, even if the data is fresh.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func refetch()

    /// Marks the cached entry stale; it refetches while observed.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func setPollInterval(_ interval: Duration?)
}

/// Observes the `ticker` query (cache key `ticker`).
/// Constructing it registers an observer and fetches when the data is stale or missing.
@MainActor @Observable
public final class TickerQueryHandle: UndraStore, @unchecked Sendable {
    /// The latest successful result, if any.
    public private(set) var data: UInt32?
    /// Where the query is in its fetch lifecycle.
    public private(set) var status: QueryStatus
    /// The error of the latest failed fetch, cleared by the next success.
    public private(set) var error: TickError?
    /// Whether a fetch is in flight (also true while refetching stale data).
    public private(set) var fetching: Bool
    /// When `data` was last updated.
    public private(set) var updatedAt: Date?

    /// - Throws: ``UndraCallError`` if the call fails in the core or cannot reach it.
    public convenience init(ctx: UndraCore = UndraPlaygroundCore.core) throws

    /// Fetches again now, even if the data is fresh.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func refetch()

    /// Marks the cached entry stale; it refetches while observed.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func 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.
    /// - Note: A failure is logged and passed to `LoadOptions.onError`; the method does not throw.
    public func setPollInterval(_ interval: Duration?)
}

/// Runs the `patch_remote_todo` mutation.
/// - Throws: ``RemoteError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func patchRemoteTodo(
    list: String,
    id: UInt32,
    done: Bool,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> RemoteTodo

/// Runs the `post_remote_todo` mutation.
/// - Throws: ``RemoteError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func postRemoteTodo(
    list: String,
    title: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> RemoteTodo

/// Runs the `save_note` mutation.
/// - Throws: ``RemoteError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func saveNote(
    list: String,
    text: String,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> Bool

/// Runs the `tag_note` mutation.
/// - Throws: ``RemoteError``, `CancellationError` if the task is cancelled, or ``UndraCallError``.
public func tagNote(
    list: String,
    id: UInt32,
    ctx: UndraCore = UndraPlaygroundCore.core
) async throws -> Bool

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 284 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.
public enum UndraIds {
    public static let schemaHash: UInt64 = 0x3c17cd5f59bb6f68
    public static let namespace = "playground_core"

    public enum Objects {
        public enum Live {
            public static let typeId: UInt32 = 0x881c63cf
            public static let new: UInt32 = 0xff026383
            public static let abandon: UInt32 = 0x1a6729e8
            public static let connect: UInt32 = 0xa8ddf747
            public static let disconnect: UInt32 = 0xb47c6859
            public static let pulls: UInt32 = 0x1649f03d
            public static let read: UInt32 = 0xc853d487
            public static let send: UInt32 = 0xbb31ff25
        }
        public enum Probe {
            public static let typeId: UInt32 = 0x4fdd3051
            public static let new: UInt32 = 0xb843ab99
            public static let counters: UInt32 = 0xc3958518
            public static let hang: UInt32 = 0x98f10ca1
            public static let reset: UInt32 = 0xce3a32f8
            public static let ticks: UInt32 = 0x9ea5858d
            public static let ticksThenFail: UInt32 = 0xa48a6ac2
            public static let wait: UInt32 = 0x6bab3fb8
        }
        public enum RecentTodos {
            public static let typeId: UInt32 = 0xf3574157
            public static let new: UInt32 = 0xf0a9e00b
            public static let latest: UInt32 = 0xdabb2338
            public static let `open`: UInt32 = 0x4addedc7
            public static let rows: UInt32 = 0x77753b96
        }
        public enum Watch {
            public static let typeId: UInt32 = 0xec266ec8
            public static let id: UInt32 = 0x2075bd1f
        }
        public enum Bench {
            public static let typeId: UInt32 = 0x346ad459
            public static let new: UInt32 = 0x36809c61
            public static let benchAdd: UInt32 = 0xe6f91ad9
            public static let benchEchoBytes: UInt32 = 0x677eb967
            public static let benchListInsert: UInt32 = 0x914b8e82
            public static let benchListReset: UInt32 = 0x0c07aab2
            public static let benchListUpdateBurst: UInt32 = 0x7411fd03
            public static let benchTouchSignals: UInt32 = 0x3fc0389f
        }
        public enum BigList {
            public static let typeId: UInt32 = 0x3b9271c5
            public static let new: UInt32 = 0xf5e4a11d
            public static let insertAt: UInt32 = 0x8f234904
            public static let moveItem: UInt32 = 0x58a6cbde
            public static let removeAt: UInt32 = 0x1237d7af
            public static let reset: UInt32 = 0x65063b1c
            public static let updateAt: UInt32 = 0x0e5ff480
        }
        public enum Counter {
            public static let typeId: UInt32 = 0xfc0f33c3
            public static let new: UInt32 = 0xcff00e37
            public static let add: UInt32 = 0x8adcbf02
            public static let decrement: UInt32 = 0xe6593ac4
            public static let increment: UInt32 = 0x0584c6ac
            public static let reset: UInt32 = 0x0c5ad256
        }
        public enum Device {
            public static let typeId: UInt32 = 0xbdcbb413
            public static let new: UInt32 = 0x3f6646a7
        }
        public enum Ledger {
            public static let typeId: UInt32 = 0x348f96ac
            public static let new: UInt32 = 0x134c88d0
            public static let closeAccount: UInt32 = 0x06f7c642
            public static let `open`: UInt32 = 0x2dd4faa6
            public static let rename: UInt32 = 0x12958000
        }
        public enum Legacy {
            public static let typeId: UInt32 = 0x055b887e
            public static let new: UInt32 = 0x14d6ac0e
            public static let describe: UInt32 = 0x642670b9
        }
        public enum Library {
            public static let typeId: UInt32 = 0xa8532270
            public static let new: UInt32 = 0xf94159c4
            public static let addRows: UInt32 = 0x4cf117af
            public static let count: UInt32 = 0x4503ed51
            public static let dropSource: UInt32 = 0x56f49125
            public static let removeAt: UInt32 = 0xe4a7c326
            public static let rename: UInt32 = 0x5fcbc4c4
            public static let reset: UInt32 = 0x41bc20dd
        }
        public enum NoteSelection {
            public static let typeId: UInt32 = 0x5f5e349d
            public static let new: UInt32 = 0xa0602cd5
            public static let clear: UInt32 = 0xb304c15e
            public static let selectAll: UInt32 = 0xbb722df1
            public static let toggle: UInt32 = 0xce377229
        }
        public enum Notes {
            public static let typeId: UInt32 = 0x0ff01b6a
            public static let new: UInt32 = 0x5981902a
            public static let add: UInt32 = 0xf7a61617
            public static let addAll: UInt32 = 0xd4384f5b
            public static let addWithId: UInt32 = 0x20b4cbe8
            public static let closeDatabase: UInt32 = 0x11647c30
            public static let count: UInt32 = 0x39cf3133
            public static let `open`: UInt32 = 0x5d8df10c
            public static let remove: UInt32 = 0x6e4b1cdc
            public static let toggle: UInt32 = 0xe1983278
        }
        public enum Profile {
            public static let typeId: UInt32 = 0xcd17328e
            public static let new: UInt32 = 0xed94ae7e
            public static let describe: UInt32 = 0xa05219a9
            public static let visit: UInt32 = 0xa008fdab
        }
        public enum Shelf {
            public static let typeId: UInt32 = 0xb01959e3
            public static let new: UInt32 = 0x4e9d4957
            public static let clear: UInt32 = 0x8cb02b88
            public static let stock: UInt32 = 0xbd0e77fb
        }
        public enum Stress {
            public static let typeId: UInt32 = 0xafa58985
            public static let new: UInt32 = 0x6799185d
            public static let burst: UInt32 = 0xf4b7ad05
            public static let start: UInt32 = 0xb710bb83
            public static let stop: UInt32 = 0xb5c8e111
        }
        public enum TodoSelection {
            public static let typeId: UInt32 = 0xd88b75dd
            public static let new: UInt32 = 0xfb065295
            public static let clear: UInt32 = 0x1658621e
            public static let selectAll: UInt32 = 0x916e69b1
            public static let toggle: UInt32 = 0x5a64c3e9
        }
        public enum Todos {
            public static let typeId: UInt32 = 0xf5e31faa
            public static let new: UInt32 = 0x35935dea
            public static let add: UInt32 = 0xd13d7ad7
            public static let clearDone: UInt32 = 0x27ffa842
            public static let fill: UInt32 = 0x1ce95af5
            public static let remove: UInt32 = 0xa977479c
            public static let setFilter: UInt32 = 0x07781993
            public static let toggle: UInt32 = 0x1cc45d38
        }
        public enum Workshop {
            public static let typeId: UInt32 = 0xe22bcc2c
            public static let new: UInt32 = 0x3dd69650
            public static let announce: UInt32 = 0xed2adfb5
            public static let burst: UInt32 = 0x7d3f02b4
            public static let describe: UInt32 = 0xcec7da2f
            public static let find: UInt32 = 0x84e1ab01
            public static let merge: UInt32 = 0x9d9f7396
            public static let `open`: UInt32 = 0xa5283b26
            public static let run: UInt32 = 0x5208d85f
            public static let shelf: UInt32 = 0xfaed29c6
            public static let shelves: UInt32 = 0x952fdfee
            public static let tally: UInt32 = 0x56a6b8e4
            public static let total: UInt32 = 0xce8e1708
            public static let walk: UInt32 = 0x0c0539af
            public static let watch: UInt32 = 0x19e462e5
            public static let watching: UInt32 = 0x76b9e49b
        }
        public enum FeedQueryHandle {
            public static let typeId: UInt32 = 0x015a66a3
            public static let new: UInt32 = 0x015a66a3
            public static let fetchNextPage: UInt32 = 0x84920501
            public static let refetch: UInt32 = 0x21d1b9e2
            public static let invalidate: UInt32 = 0x44cec2fa
            public static let setPollInterval: UInt32 = 0xe327e53b
        }
        public enum RemoteTodosQueryHandle {
            public static let typeId: UInt32 = 0x2a794167
            public static let new: UInt32 = 0x2a794167
            public static let refetch: UInt32 = 0x21d1b9e2
            public static let invalidate: UInt32 = 0x44cec2fa
            public static let setPollInterval: UInt32 = 0xe327e53b
        }
        public enum RosterQueryHandle {
            public static let typeId: UInt32 = 0xaa41fecc
            public static let new: UInt32 = 0xaa41fecc
            public static let refetch: UInt32 = 0x21d1b9e2
            public static let invalidate: UInt32 = 0x44cec2fa
            public static let setPollInterval: UInt32 = 0xe327e53b
        }
        public enum TickerQueryHandle {
            public static let typeId: UInt32 = 0x38de4411
            public static let new: UInt32 = 0x38de4411
            public static let refetch: UInt32 = 0x21d1b9e2
            public static let invalidate: UInt32 = 0x44cec2fa
            public static let setPollInterval: UInt32 = 0xe327e53b
        }
    }

    public enum Functions {
        public static let add: UInt32 = 0x65b4cd58
        public static let addLater: UInt32 = 0xc5ca16e9
        public static let area: UInt32 = 0x293fbad8
        public static let balances: UInt32 = 0x2f156bcc
        public static let configureRemote: UInt32 = 0xa991dd26
        public static let createRemoteTodo: UInt32 = 0x3f635105
        public static let dbCells: UInt32 = 0x31c92fa5
        public static let dbMigrate: UInt32 = 0x2f1b2165
        public static let dbRun: UInt32 = 0x8c3edc9d
        public static let deposit: UInt32 = 0x1301c349
        public static let draftNote: UInt32 = 0x1ee40222
        public static let draftTodo: UInt32 = 0x0c13e0ee
        public static let echoAccount: UInt32 = 0x730b1c74
        public static let echoCents: UInt32 = 0x8cdc6e3c
        public static let echoComposite: UInt32 = 0x769db4ec
        public static let echoDecimal: UInt32 = 0x7a8022d4
        public static let echoFigure: UInt32 = 0xeeb27e01
        public static let echoPrice: UInt32 = 0xbcbc2c72
        public static let echoPrimitives: UInt32 = 0x59ba77e7
        public static let echoReceipt: UInt32 = 0x05b7b46b
        public static let explode: UInt32 = 0x4b8e88d2
        public static let explodeDetached: UInt32 = 0x5388e4d9
        public static let explodeLater: UInt32 = 0xe5a63d4b
        public static let failLater: UInt32 = 0x977e4974
        public static let fileDelete: UInt32 = 0x3ea41ab3
        public static let fileList: UInt32 = 0x97b9c870
        public static let fileRead: UInt32 = 0x2103879c
        public static let fileWrite: UInt32 = 0x2c0e4e77
        public static let greet: UInt32 = 0x0594d9ae
        public static let httpGet: UInt32 = 0xbce1d1e6
        public static let kvGet: UInt32 = 0x05cd83d7
        public static let kvKeys: UInt32 = 0x4be5264d
        public static let kvPut: UInt32 = 0x1b33766e
        public static let kvRemove: UInt32 = 0xe4402f7d
        public static let loadableStatement: UInt32 = 0x74183f5f
        public static let localizedGreeting: UInt32 = 0x247f9a6c
        public static let newestNote: UInt32 = 0x4835685d
        public static let newestTodo: UInt32 = 0xb9743b7d
        public static let openAccount: UInt32 = 0x30922a29
        public static let ownerOf: UInt32 = 0xacfd7ad8
        public static let parseCount: UInt32 = 0x1c438944
        public static let ping: UInt32 = 0x60e670d5
        public static let recentTodos: UInt32 = 0x69a43bf4
        public static let sampleReceipt: UInt32 = 0xe6449400
        public static let secretGet: UInt32 = 0x3f96f35a
        public static let secretKeys: UInt32 = 0x98a56bd2
        public static let secretPut: UInt32 = 0x2c60b7cb
        public static let secretRemove: UInt32 = 0x83a7330a
        public static let setRemoteDone: UInt32 = 0xa1e08a5f
        public static let setTickerFailing: UInt32 = 0x26f08a91
        public static let sseFollow: UInt32 = 0x237de656
        public static let statement: UInt32 = 0xadc39bc2
        public static let storageStatus: UInt32 = 0x79205099
        public static let tickerFetches: UInt32 = 0xb3a3511c
        public static let touchFeed: UInt32 = 0x27176f81
        public static let version: UInt32 = 0xceb9168b
        public static let wsEcho: UInt32 = 0x2b49a875
    }

    public enum Ports {
        public enum Locale {
            public static let portId: UInt32 = 0xcc469822
            public static let hello: UInt32 = 0x9e2a48e9
        }
    }

    public enum Callbacks {
        public enum Reporter {
            public static let portId: UInt32 = 0x10e8b455
            public static let confirm: UInt32 = 0x1ea2905a
            public static let note: UInt32 = 0x8720eafe
            public static let progress: UInt32 = 0x3a77cbcd
            public static let releaseInstance: UInt32 = 0x47e657b5
            public static let cancelCall: UInt32 = 0x9a8ca032
        }
    }

    public enum Queries {
        public static let feed: UInt32 = 0x015a66a3
        public static let patchRemoteTodo: UInt32 = 0x77fe653e
        public static let postRemoteTodo: UInt32 = 0x5c84eed2
        public static let remoteTodos: UInt32 = 0x2a794167
        public static let roster: UInt32 = 0xaa41fecc
        public static let saveNote: UInt32 = 0xaef633c6
        public static let tagNote: UInt32 = 0xb9224861
        public static let ticker: UInt32 = 0x38de4411
    }
}

Generated by site/scripts/build-reference.mjs from examples/playground/generated/swift, 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.