API reference

TypeScript reference

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

Entry point#

The package entry: it re-exports every file below.

Show the declarations 9 lines
export * from "./types.js";
export * from "./errors.js";
export * from "./objects.js";
export * from "./stores.js";
export * from "./ports.js";
export * from "./queries.js";
export * from "./callbacks.js";
export * from "./ids.js";
export * from "./core.js";

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 42 lines
/**
 * The core these bindings belong to, `playground_core` (`[core] namespace` in undra.toml): `load` starts it,
 * and `core` is the core every generated class and function of this package uses unless it is given
 * another one.
 *
 * ```ts
 * await UndraPlaygroundCore.load({ mode: "wasm-main", wasm: new URL("playground_core.wasm", import.meta.url) });
 * ```
 */
export const UndraPlaygroundCore = {
  /** The core's namespace: its wasm module is `playground_core.wasm`, its native library `libplayground_core`. */
  namespace: "playground_core",
  /** The schema hash these bindings were generated for. */
  schemaHash: UndraIds.schemaHash,

  /**
   * Loads the core (`UndraCore.load` with this package's schema hash and namespace) and makes it `core`. Rejects
   * with `UndraSchemaMismatchError` when the core was built from another schema, and with `UndraError` while
   * this core is already loaded. The default stores are kept under the namespace (`undra.<namespace>.kv`, ...).
   */
  async load(options: Omit<LoadOptions, "expectedSchemaHash" | "namespace" | "features">): Promise<UndraCore> {
    claim();
    return started(UndraCore.load({ ...options, expectedSchemaHash: UndraIds.schemaHash, namespace: UndraIds.namespace, features: [streams] }));
  },

  /**
   * Attaches the core over a transport you provide (React Native's `NativeTransport`, a test double),
   * with this package's schema hash and namespace, and makes it `core`.
   */
  async attach(transport: Transport, options: Omit<AttachOptions, "expectedSchemaHash" | "namespace" | "features"> = {}): Promise<UndraCore> {
    claim();
    return started(UndraCore.attach(transport, { ...options, expectedSchemaHash: UndraIds.schemaHash, namespace: UndraIds.namespace, features: [streams] }));
  },

  /**
   * The loaded core, or, while none is loaded (or after it was closed), the closed placeholder
   * `UndraCore.unloaded`, whose calls reject with `UndraCallError.Unavailable`.
   */
  get core(): UndraCore {
    return loaded !== null && !loaded.closed ? loaded : UndraCore.unloaded;
  },
};

Types#

An interface for each record, a union for each enum, each with a codec.

Account AccountId Cents Composite DbCells Entry EntrySlice Item Note Price Primitives ProbeCounters Receipt RemoteConfig RemoteTodo SseFollow StorageStatus Todo Figure Filter LoadableEntries Parity StressMode QueryStatus

Show the declarations 324 lines
/** An account of the [`Ledger`] store. */
export interface Account {
  /** Its identity; the store's list is patched by it. */
  id: AccountId;
  /** Whose it is. */
  owner: string;
}

export const AccountCodec: Codec<Account>;

/** The identity of an account: a `Uuid` that is not just any `Uuid`. */
export type AccountId = string & { readonly __brand: "AccountId" };

/** Brands `value` as `AccountId`; no check is made. */
export function AccountId(value: string): AccountId;

export const AccountIdCodec: Codec<AccountId>;

/** An amount in cents: a whole number that is not just any number. */
export type Cents = bigint & { readonly __brand: "Cents" };

/** Brands `value` as `Cents`; no check is made. */
export function Cents(value: bigint): Cents;

export const CentsCodec: Codec<Cents>;

/**
 * A record that nests the other kinds: lists, options, maps, enums with data and a map with
 * integer keys.
 */
export interface Composite {
  /** A name. */
  name: string;
  /** Several strings. */
  tags: string[];
  /** Maybe a figure. */
  figure: Figure | null;
  /** Figures, in order. */
  history: Figure[];
  /** A map keyed by string. */
  scores: Map<string, number>;
  /** A map keyed by integer. */
  names: Map<number, string>;
  /** Maybe a number. */
  limit: number | null;
}

export const CompositeCodec: Codec<Composite>;

/** One value of each SQLite storage class, as [`db_cells`] read it back. */
export interface DbCells {
  /** The `INTEGER`. */
  int: bigint;
  /** The `REAL`. */
  real: number;
  /** The `TEXT`. */
  text: string;
  /** The `BLOB`. */
  blob: Uint8Array;
  /** The column that held `NULL` (or the text given for it). */
  none: string | null;
  /** SQLite's `typeof()` of the five columns, in order. */
  types: string[];
}

export const DbCellsCodec: Codec<DbCells>;

/** One line of an account's statement. */
export interface Entry {
  /** The account the money went into. */
  account: AccountId;
  /** How much. */
  amount: Price;
  /** What it was for. */
  memo: string;
  /** When the caller says it happened. */
  at: Timestamp;
}

export const EntryCodec: Codec<Entry>;

/** A window of [`Entry`] rows. */
export interface EntrySlice {
  /** The rows of this window. */
  items: Entry[];
  /** The offset of the next window, if there is one. */
  next: number | null;
}

export const EntrySliceCodec: Codec<EntrySlice>;

/** One row of a list, identified by `id`. */
export interface Item {
  /** Identity of the row; lists are patched by it, never by position. */
  id: number;
  /** The text of the row. */
  label: string;
  /** How many times the row was updated. */
  version: number;
}

export const ItemCodec: Codec<Item>;

/** One note, a row of the `notes` table. */
export interface Note {
  /** The row id. */
  id: bigint;
  /** The text. */
  title: string;
  /** Whether it is ticked. */
  done: boolean;
}

export const NoteCodec: Codec<Note>;

/** A price: an exact decimal number of the currency's major unit. */
export type Price = Decimal & { readonly __brand: "Price" };

/** Brands `value` as `Price`; no check is made. */
export function Price(value: Decimal): Price;

export const PriceCodec: Codec<Price>;

/** One value of every primitive the wire has, so a single call covers them all. */
export interface Primitives {
  /** A boolean. */
  flag: boolean;
  /** An `i8`. */
  tiny: number;
  /** An `i16`. */
  small: number;
  /** An `i32`. */
  int: number;
  /** An `i64`: a `bigint` in TypeScript. */
  long: bigint;
  /** A `u8`. */
  byte: number;
  /** A `u16`. */
  word: number;
  /** A `u32`. */
  dword: number;
  /** A `u64`: a `bigint` in TypeScript. */
  qword: bigint;
  /** An `f32`. */
  single: number;
  /** An `f64`. */
  double: number;
  /** A string, UTF-8 on the wire. */
  text: string;
  /** Raw bytes. */
  blob: Uint8Array;
  /** A span of time, whole nanoseconds on the wire. */
  span: Duration;
  /** A moment, milliseconds since the Unix epoch on the wire. */
  at: Timestamp;
  /** A UUID, sixteen bytes on the wire. */
  id: string;
}

export const PrimitivesCodec: Codec<Primitives>;

/** What a [`Probe`] has seen. */
export interface ProbeCounters {
  /** Calls that started running in the core. */
  started: number;
  /** Calls that ran to the end. */
  completed: number;
  /** Calls the core dropped before they ended, because the platform cancelled them. */
  cancelled: number;
  /** Items the core produced for streams (whether or not the platform has read them yet). */
  produced: number;
}

export const ProbeCountersCodec: Codec<ProbeCounters>;

/** A record of types from other crates: every field is a leaf type that crosses as a wire type. */
export interface Receipt {
  /** A `uuid::Uuid`, which crosses as `Uuid`. */
  id: string;
  /** A `chrono::DateTime<Utc>`, which crosses as `Timestamp` (milliseconds). */
  issued: Timestamp;
  /** A `chrono::TimeDelta`, which crosses as `Duration` (nanoseconds). */
  validFor: Duration;
  /** A `rust_decimal::Decimal`, which crosses as `Decimal`. */
  total: Decimal;
  /** A `bytes::Bytes`, which crosses as `Bytes`. */
  signature: Uint8Array;
}

export const ReceiptCodec: Codec<Receipt>;

/** Where the server is: what an app supplies once, at start-up. */
export interface RemoteConfig {
  /** The server's address without a trailing slash, such as `https://api.example.com`. */
  baseUrl: string;
}

export const RemoteConfigCodec: Codec<RemoteConfig>;

/** One to-do item on the server. */
export interface RemoteTodo {
  /**
   * The server's identity of the item. An item that is only shown optimistically, and that the
   * server has not answered for yet, has an identity counting down from `u32::MAX`.
   */
  id: number;
  /** What has to be done. */
  title: string;
  /** Whether it is finished. */
  done: boolean;
}

export const RemoteTodoCodec: Codec<RemoteTodo>;

/** What [`sse_follow`] read. */
export interface SseFollow {
  /** The events, in order. */
  events: SseEvent[];
  /** Whether the server ended the stream (`SseError::Ended`) before `max` events. */
  ended: boolean;
}

export const SseFollowCodec: Codec<SseFollow>;

/** What the query client's persistence did so far: [`storage_status`]. */
export interface StorageStatus {
  /** Mutations waiting in the offline queue. */
  pending: number;
  /** The dead letters, as `"<mutation>: <reason>"`. */
  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).
   */
  queueReadable: boolean;
  /** Writes to the `Kv` store that failed. */
  writeFailed: bigint;
  /** Persisted cache entries dropped because they could not be migrated. */
  dropped: bigint;
  /** Cache entries and queued mutations an older build wrote that were migrated. */
  migrated: bigint;
  /** Queued mutations moved to the dead-letter queue. */
  deadLettered: bigint;
}

export const StorageStatusCodec: Codec<StorageStatus>;

/** One item of the to-do list. */
export interface Todo {
  /** Identity of the item; the list is updated by key, so the UI diffs by it. */
  id: string;
  /** What has to be done. */
  title: string;
  /** Whether it is finished. */
  done: boolean;
}

export const TodoCodec: Codec<Todo>;

/** A shape: an enum with named fields, a tuple variant and a unit variant. */
export type Figure =
  /** A circle. */
  | { kind: "circle"; radius: number }
  /** A rectangle. */
  | { kind: "rect"; width: number; height: number }
  /** A shape that is only a name. */
  | { kind: "label"; value: string }
  /** No shape at all. */
  | { kind: "empty" };

export const FigureCodec: Codec<Figure>;

/** Which items the list shows. */
export type Filter =
  /** Every item. */
  | "all"
  /** Items that are not finished. */
  | "active"
  /** Items that are finished. */
  | "done";

export const FilterCodec: Codec<Filter>;

/** A window of entries that may still be loading. */
export type LoadableEntries =
  /** Nothing yet. */
  | { kind: "loading" }
  /** Here it is. */
  | { kind: "loaded"; value: EntrySlice }
  /** It could not be had. */
  | { kind: "failed"; value: string };

export const LoadableEntriesCodec: Codec<LoadableEntries>;

/** Whether the count is even or odd: a value derived from `count` in the core. */
export type Parity =
  /** The count is divisible by two. */
  | "even"
  /** The count is not divisible by two. */
  | "odd";

export const ParityCodec: Codec<Parity>;

/** Which signal `burst` and `start` write. */
export type StressMode =
  /** `value` + 1 per transaction: a firehose the platforms apply once per frame. */
  | "firehose"
  /** `progress` + 1 per transaction: a `no_coalesce` signal the platforms apply step by step. */
  | "progress";

export const StressModeCodec: Codec<StressMode>;

/** The fetch state of a query (SPEC section 9). */
export type QueryStatus =
  /** No fetch has started. */
  | "idle"
  /** A fetch is in flight. */
  | "fetching"
  /** The latest fetch succeeded. */
  | "success"
  /** The latest fetch failed. */
  | "error";

export const QueryStatusCodec: Codec<QueryStatus>;

Errors#

An abstract class for each #[undra::error], one subclass per variant.

LabErrorKind LabError LedgerErrorKind LedgerError ListErrorKind ListError RemoteErrorKind RemoteError ReportErrorKind ReportError StressErrorKind StressError TickErrorKind TickError TodoErrorKind TodoError WorkshopErrorKind WorkshopError

Show the declarations 218 lines
export type LabErrorKind = "empty" | "tooLong" | "notANumber" | "rejected";

/** Why a lab call failed. */
export abstract class LabError extends UndraError {
  declare readonly kind: LabErrorKind;
}

export namespace LabError {
  /** Nothing was given. */
  export class Empty extends LabError {
    declare readonly kind: "empty";

    constructor();
  }

  /** The text is longer than `max` characters. */
  export class TooLong extends LabError {
    declare readonly kind: "tooLong";

    constructor(readonly max: number);
  }

  /** The text is not a number. */
  export class NotANumber extends LabError {
    declare readonly kind: "notANumber";

    constructor(readonly value: string);
  }

  /** A failure chosen by the caller. */
  export class Rejected extends LabError {
    declare readonly kind: "rejected";

    constructor(readonly code: number, readonly reason: string);
  }
}

export const LabErrorCodec: Codec<LabError>;

export type LedgerErrorKind = "noSuchAccount" | "outOfRange";

/** Why a ledger operation failed. */
export abstract class LedgerError extends UndraError {
  declare readonly kind: LedgerErrorKind;
}

export namespace LedgerError {
  /** No account has this identity. */
  export class NoSuchAccount extends LedgerError {
    declare readonly kind: "noSuchAccount";

    constructor();
  }

  /** The amount cannot be added (it is not a number `rust_decimal` holds). */
  export class OutOfRange extends LedgerError {
    declare readonly kind: "outOfRange";

    constructor();
  }
}

export const LedgerErrorCodec: Codec<LedgerError>;

export type ListErrorKind = "outOfRange";

/** Why an operation on a list was refused. */
export abstract class ListError extends UndraError {
  declare readonly kind: ListErrorKind;
}

export namespace ListError {
  /** A position is not in the list. */
  export class OutOfRange extends ListError {
    declare readonly kind: "outOfRange";

    constructor(readonly index: number, readonly len: number);
  }
}

export const ListErrorCodec: Codec<ListError>;

export type RemoteErrorKind = "notConfigured" | "http" | "status" | "badBody";

/** Why a request to the server failed. */
export abstract class RemoteError extends UndraError {
  declare readonly kind: RemoteErrorKind;
}

export namespace RemoteError {
  /** [`configure_remote`] was not called. */
  export class NotConfigured extends RemoteError {
    declare readonly kind: "notConfigured";

    constructor();
  }

  /** The `Http` port failed: no network, a timeout, a bad URL, or a cancelled request. */
  export class Http extends RemoteError {
    declare readonly kind: "http";
    declare readonly cause: HttpError;

    constructor(cause: HttpError);
  }

  /** The server answered with a status that is not a success. */
  export class Status extends RemoteError {
    declare readonly kind: "status";

    constructor(readonly code: number);
  }

  /** The server's answer is not the JSON this core expects. */
  export class BadBody extends RemoteError {
    declare readonly kind: "badBody";

    constructor(readonly value: string);
  }
}

export const RemoteErrorCodec: Codec<RemoteError>;

export type ReportErrorKind = "declined" | "unavailable";

/** What a reporter's `confirm` can fail with. */
export abstract class ReportError extends UndraError {
  declare readonly kind: ReportErrorKind;
}

export namespace ReportError {
  /** The user answered no. */
  export class Declined extends ReportError {
    declare readonly kind: "declined";

    constructor();
  }

  /** The app's reporter is not there or failed. */
  export class Unavailable extends ReportError {
    declare readonly kind: "unavailable";

    constructor(readonly value: string);
  }
}

export const ReportErrorCodec: Codec<ReportError>;

export type StressErrorKind = "rateOutOfRange";

/** Why `start` refused to start. */
export abstract class StressError extends UndraError {
  declare readonly kind: StressErrorKind;
}

export namespace StressError {
  /** The rate is zero or above the fastest generator there is (1,000,000 updates a second). */
  export class RateOutOfRange extends StressError {
    declare readonly kind: "rateOutOfRange";

    constructor(readonly rate: number, readonly max: number);
  }
}

export const StressErrorCodec: Codec<StressError>;

export type TickErrorKind = "failing";

/** Why the ticker could not tick. */
export abstract class TickError extends UndraError {
  declare readonly kind: TickErrorKind;
}

export namespace TickError {
  /** [`set_ticker_failing`] made it fail. */
  export class Failing extends TickError {
    declare readonly kind: "failing";

    constructor();
  }
}

export const TickErrorCodec: Codec<TickError>;

export type TodoErrorKind = "emptyTitle";

/** Why an item could not be added. */
export abstract class TodoError extends UndraError {
  declare readonly kind: TodoErrorKind;
}

export namespace TodoError {
  /** The title is empty once spaces are trimmed. */
  export class EmptyTitle extends TodoError {
    declare readonly kind: "emptyTitle";

    constructor();
  }
}

export const TodoErrorCodec: Codec<TodoError>;

export type WorkshopErrorKind = "noName";

/** What can go wrong opening a shelf. */
export abstract class WorkshopError extends UndraError {
  declare readonly kind: WorkshopErrorKind;
}

export namespace WorkshopError {
  /** The name is empty. */
  export class NoName extends WorkshopError {
    declare readonly kind: "noName";

    constructor();
  }
}

export const WorkshopErrorCodec: Codec<WorkshopError>;

Objects#

A class for each object, and an async 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 768 lines
export class Live extends UndraObject {
  /**
   * No connection yet.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Live>;

  /**
   * Forgets the connection without closing it: the port closes it going away (1001).
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  abandon(): Promise<void>;

  /**
   * Connects to `url`, offering `protocols` and sending `headers`; a connection already open is
   * closed first (1000). Returns the subprotocol the server chose (`""` for none).
   * @throws {WsError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  connect(
    url: string,
    protocols: string[],
    headers: Header[],
    signal?: AbortSignal,
  ): Promise<string>;

  /**
   * Closes the connection with `code` and `reason` (`close` is every object's own: it releases
   * the handle).
   * @throws {WsError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  disconnect(code: number, reason: string, signal?: AbortSignal): Promise<void>;

  /**
   * How many pulls the inbound stream has made (each asks the platform for up to 16).
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  pulls(): Promise<bigint>;

  /**
   * Reads exactly `count` messages. The connection's end before that is the error (its
   * close code, a network failure); a stream that ended cleanly (after [`disconnect`](Live::disconnect))
   * returns the messages it had.
   * @throws {WsError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  read(count: number, signal?: AbortSignal): Promise<WsMessage[]>;

  /**
   * Sends `message` on the open connection.
   * @throws {WsError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  send(message: WsMessage, signal?: AbortSignal): Promise<void>;
}

export class Probe extends UndraObject {
  /**
   * A probe with every counter at zero.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Probe>;

  /**
   * What the probe has seen so far.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  counters(): Promise<ProbeCounters>;

  /**
   * Waits forever. The only way it ends is cancellation, which the `cancelled` counter shows.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  hang(signal?: AbortSignal): Promise<number>;

  /**
   * Sets every counter back to zero.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  reset(): Promise<void>;

  /**
   * 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.
   * Iterating throws UndraCallError; leaving the loop early ends the stream quietly.
   */
  ticks(count: number): AsyncIterable<number>;

  /**
   * 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.
   * Iterating throws LabError or UndraCallError; leaving the loop early ends the stream quietly.
   */
  ticksThenFail(count: number, failAt: number, code: number): AsyncIterable<number>;

  /**
   * Waits `ms` milliseconds and returns it. Cancelled before that, it counts as cancelled.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  wait(ms: number, signal?: AbortSignal): Promise<number>;
}

/** The to-dos opened last. */
export class RecentTodos extends UndraObject {
  /**
   * A list that keeps the last `limit` rows opened.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(
    limit: number,
    core: UndraCore = UndraPlaygroundCore.core,
  ): Promise<RecentTodos>;

  /**
   * The row opened last, if any was.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  latest(): Promise<Todo | null>;

  /**
   * Records that `row` was opened: it moves to the front, and the oldest falls off the end.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  open(row: Todo): Promise<void>;

  /**
   * The rows opened last, newest first.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  rows(): Promise<Todo[]>;
}

export class Watch extends UndraObject {
  /**
   * The subscription's number, in the order they were made.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  id(): Promise<number>;
}

/**
 * Adds two numbers, wrapping on overflow: a synchronous call with primitive arguments.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function add(
  a: number,
  b: number,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<number>;

/**
 * Adds two numbers after `delay_ms` milliseconds: an asynchronous call that waits on the `Timer`
 * port.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function addLater(
  a: number,
  b: number,
  delayMs: number,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<number>;

/**
 * The area of a circle or a rectangle. A label and an empty figure have none.
 * @throws {LabError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function area(
  figure: Figure,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<number>;

/**
 * The balance of every account: a map keyed by a newtype.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function balances(
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Map<AccountId, Price>>;

/**
 * Tells the core where the server is. Call it at start-up, before anything observes
 * [`remote_todos`], and again whenever the core is a new one that kept its stores (after a dev
 * reload or a web crash restart): the address lives in the core outside any store, so a snapshot
 * does not carry it. Calling it again points the core elsewhere (cached data stays until it goes
 * stale).
 * A failure is logged and passed to `onError`; the returned promise never rejects.
 */
export function configureRemote(
  config: RemoteConfig,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<void>;

/**
 * Adds an item to `list` the way a UI wants it: the list shows it at once (an optimistic placeholder), the
 * server is asked, and the placeholder is taken back if the server refuses. On success the cached
 * list is refetched, so the placeholder gives way to the server's item.
 *
 * While the device is offline the request is queued (the mutation is idempotent) and the call
 * keeps waiting; the placeholder stays visible until the network returns and the request is
 * replayed.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function createRemoteTodo(
  list: string,
  title: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<RemoteTodo>;

/**
 * Writes one value of each storage class to an in-memory database and reads them back.
 * @throws {DbError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function dbCells(
  int: bigint,
  real: number,
  text: string,
  blob: Uint8Array,
  none: string | null,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<DbCells>;

/**
 * Opens database `name` with two migrations, the second broken when `broken`: the adapter runs
 * them in one transaction, so a broken second one leaves the database at the version it had.
 * Returns the version reached.
 * @throws {DbError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function dbMigrate(
  name: string,
  broken: boolean,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<number>;

/**
 * Runs one statement (SQL given at run time, no parameters) on database `name` and returns the
 * rows it changed: how a platform's adapter reports SQL and constraint errors.
 * @throws {DbError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function dbRun(
  name: string,
  sql: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<bigint>;

/**
 * Adds `amount` to the balance of `account` and returns the new balance. Exact: `0.1` and `0.2`
 * make `0.3`.
 * @throws {LedgerError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function deposit(
  account: AccountId,
  amount: Price,
  memo: string,
  at: Timestamp,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Price>;

/**
 * A new row of the type the caller names, titled `title`, with an identity of its own that no
 * stored row has.
 *
 * No argument tells which type is wanted, so the caller names it: the type itself in Swift and
 * Kotlin, its name in TypeScript.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function draft(type: "Note", title: string, core?: UndraCore): Promise<Note>;
export function draft(type: "Todo", title: string, core?: UndraCore): Promise<Todo>;
export function draft(
  type: "Note" | "Todo",
  title: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<unknown>;

/**
 * Returns `id`: a newtype of `Uuid` comes back as itself.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoAccount(
  id: AccountId,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<AccountId>;

/**
 * Returns `cents`: a newtype of `i64`.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoCents(
  cents: Cents,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Cents>;

/**
 * Returns `value` unchanged.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoComposite(
  value: Composite,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Composite>;

/**
 * Returns `value` exactly: mantissa, scale and all (`1.10` stays `1.10`).
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoDecimal(
  value: Decimal,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Decimal>;

/**
 * Returns `value` unchanged.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoFigure(
  value: Figure,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Figure>;

/**
 * Returns `price`: a newtype of `Decimal`.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoPrice(
  price: Price,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Price>;

/**
 * Returns `value` unchanged.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoPrimitives(
  value: Primitives,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Primitives>;

/**
 * Returns `receipt`: every leaf type of another crate, through the core and back.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function echoReceipt(
  receipt: Receipt,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<Receipt>;

/**
 * Panics with `reason`. The boundary turns the panic into a reply (status 2), never into a
 * crash, on the platforms that can unwind (R6).
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function explode(
  reason: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<number>;

/**
 * Returns at once and panics with `reason` in a task of its own (ADR-046: a contained panic that
 * no call is waiting on still reaches `onPanic`).
 * A failure is logged and passed to `onError`; the returned promise never rejects.
 */
export function explodeDetached(
  reason: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<void>;

/**
 * Panics with `reason` after `delay_ms` milliseconds, inside an asynchronous call.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function explodeLater(
  delayMs: number,
  reason: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<number>;

/**
 * Fails with `LabError::Rejected { code, .. }` after `delay_ms` milliseconds: an asynchronous
 * call with a typed error.
 * @throws {LabError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function failLater(
  delayMs: number,
  code: number,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<number>;

/**
 * Deletes the file or directory `path` of the `Fs` port.
 * @throws {FsError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function fileDelete(
  path: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * The names in the directory `dir` of the `Fs` port, sorted.
 * @throws {FsError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function fileList(
  dir: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<string[]>;

/**
 * The contents of the file `path` of the `Fs` port.
 * @throws {FsError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function fileRead(
  path: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<Uint8Array>;

/**
 * Writes `data` to the file `path` of the `Fs` port, creating its directories.
 * @throws {FsError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function fileWrite(
  path: string,
  data: Uint8Array,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * A greeting.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function greet(
  name: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<string>;

/**
 * `GET url` through the `Http` port, with an optional timeout in milliseconds. Any status is a
 * response; only a failure to get one is an [`HttpError`].
 * @throws {HttpError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function httpGet(
  url: string,
  timeoutMs: number | null,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<HttpResponse>;

/**
 * The value the `Kv` port has under `key`, if any.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function kvGet(
  key: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<Uint8Array | null>;

/**
 * The keys of the `Kv` port that start with `prefix`, in ascending order.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function kvKeys(
  prefix: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<string[]>;

/**
 * Stores `value` under `key` in the `Kv` port.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function kvPut(
  key: string,
  value: Uint8Array,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * Removes `key` from the `Kv` port; a missing key is not an error.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function kvRemove(
  key: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * The statement of `account` as a [`Loadable`]: `Loading` when `ready` is false, the first
 * `limit` entries when it is true, `Failed` for an unknown account.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function loadableStatement(
  account: AccountId,
  ready: boolean,
  limit: number,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<LoadableEntries>;

/**
 * Greets `name` in the user's language, through the [`Locale`] port.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function localizedGreeting(
  name: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<string>;

/**
 * The newest of `rows`, the one whose identity counts highest, or nothing for an empty list.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function newest(type: "Note", rows: Note[], core?: UndraCore): Promise<Note | null>;
export function newest(type: "Todo", rows: Todo[], core?: UndraCore): Promise<Todo | null>;
export function newest(
  type: "Note" | "Todo",
  rows: Note[] | Todo[],
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<unknown>;

/**
 * A new account for `owner`, with an identity from the ledger's counter.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function openAccount(
  owner: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<AccountId>;

/**
 * Who owns `account`, or an empty string for an unknown one.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function ownerOf(
  account: AccountId,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<string>;

/**
 * Reads an unsigned number of at most nine digits.
 * @throws {LabError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function parseCount(
  text: string,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<number>;

/**
 * Does nothing and returns nothing: a call with neither arguments nor a result.
 * A failure is logged and passed to `onError`; the returned promise never rejects.
 */
export function ping(core: UndraCore = UndraPlaygroundCore.core): Promise<void>;

/**
 * A list of recently opened to-dos that already holds `rows`, the last of them opened last,
 * and keeps `limit` of them.
 *
 * An object is returned from a function like any value: the platform gets one wrapper for it.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function recentTodos(
  rows: Todo[],
  limit: number,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<RecentTodos>;

/**
 * A receipt made of fixed values (what a platform checks it decodes), so a platform can read
 * what the leaf types look like on its side without building one.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function sampleReceipt(core: UndraCore = UndraPlaygroundCore.core): Promise<Receipt>;

/**
 * The value the `SecureStore` port has under `key`, if any.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function secretGet(
  key: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<Uint8Array | null>;

/**
 * The keys of the `SecureStore` port that start with `prefix`, in ascending order.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function secretKeys(
  prefix: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<string[]>;

/**
 * Stores `value` under `key` in the `SecureStore` port (the Keychain, the Android Keystore).
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function secretPut(
  key: string,
  value: Uint8Array,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * Removes `key` from the `SecureStore` port; a missing key is not an error.
 * @throws {StorageError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function secretRemove(
  key: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<void>;

/**
 * Marks an item of `list` finished or not, showing the change at once and taking it back if the server
 * refuses.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function setRemoteDone(
  list: string,
  id: number,
  done: boolean,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<RemoteTodo>;

/**
 * Makes the ticker fail (or succeed again) from its next fetch on.
 * A failure is logged and passed to `onError`; the returned promise never rejects.
 */
export function setTickerFailing(
  failing: boolean,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<void>;

/**
 * Subscribes to `url` (resuming after `last_event_id`) and reads up to `max` events, or until
 * the server ends the stream. Reconnecting is the caller's: call again with the last id read.
 * @throws {SseError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function sseFollow(
  url: string,
  lastEventId: string | null,
  max: number,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<SseFollow>;

/**
 * `limit` entries of the statement of `account` from `offset`: a named instantiation of [`Slice`].
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function statement(
  account: AccountId,
  offset: number,
  limit: number,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<EntrySlice>;

/**
 * What the query client's persistence did: the offline queue, its dead letters and the
 * persistence counters.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function storageStatus(
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<StorageStatus>;

/**
 * How many times the ticker fetched, for a test that wants the number the core sees.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function tickerFetches(core: UndraCore = UndraPlaygroundCore.core): Promise<number>;

/**
 * Makes the feed's even rows show revision `revision` the next time they are fetched.
 * A failure is logged and passed to `onError`; the returned promise never rejects.
 */
export function touchFeed(
  revision: number,
  core: UndraCore = UndraPlaygroundCore.core,
): Promise<void>;

/**
 * The name and version of the core.
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 */
export function version(core: UndraCore = UndraPlaygroundCore.core): Promise<string>;

/**
 * Connects to `url`, sends `messages` in order, reads as many back and closes (1000).
 *
 * Against an echo server the replies are the messages; any end of the connection before that is
 * the error (a refusal, `Closed` with the server's code, `Network`).
 * @throws {WsError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function wsEcho(
  url: string,
  messages: WsMessage[],
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<WsMessage[]>;

Stores#

A class for each #[undra::store]: its signals as Signal, then its methods.

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

Show the declarations 675 lines
/**
 * The benchmark store: 128 counters, a 10,000-row keyed list and three methods that
 * exercise the boundary.
 */
export class Bench extends UndraStore {
  readonly rows: Signal<Item[]>;
  readonly s000: Signal<number>;
  // … 126 more with the same shape …
  readonly s127: Signal<number>;

  /**
   * A store with every counter at zero and [`ROWS`] rows numbered from 1.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Bench>;

  /**
   * Adds two numbers: the cheapest call there is, for the handle-call row.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  benchAdd(a: number, b: number): Promise<number>;

  /**
   * Returns `data` unchanged: a payload of `data.len()` bytes crosses the boundary
   * twice.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  benchEchoBytes(data: Uint8Array): Promise<Uint8Array>;

  /**
   * Inserts one new row so that it ends at position `i` (a position past the end
   * appends): one keyed `Insert` on a list of about 10,000 rows. The list grows by
   * one row per call; `bench_list_reset` starts over.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  benchListInsert(i: number): Promise<void>;

  /**
   * Puts the list back to its [`ROWS`] starting rows and writes zero to every counter,
   * in one transaction: one change-set with the list and all [`SIGNALS`] counters.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  benchListReset(): Promise<void>;

  /**
   * Updates `n` rows of the list, **one transaction each**: `n` change-sets, each a
   * keyed patch of a single `Update` (the row's `version` goes up by one), the way a
   * socket or a sensor feed that writes a row at a time reaches the platform. The rows
   * are spread over the list (consecutive updates are far apart) and the same
   * positions come out for the same list length, so a run is repeatable. This is what
   * the device benchmarks drain (ADR-031: 100,000 patches a second is 1,667 a frame).
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  benchListUpdateBurst(n: number): Promise<void>;

  /**
   * Adds one to the first `k` counters (at most [`SIGNALS`]) inside one transaction:
   * `k` dirty signals, one change-set.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  benchTouchSignals(k: number): Promise<void>;
}

/** A list of [`LIST_LEN`] items with operations that change one item at a time. */
export class BigList extends UndraStore {
  readonly items: Signal<Item[]>;
  /** Computed by the core; read-only. */
  readonly count: Signal<number>;

  /**
   * A list of [`LIST_LEN`] items numbered from 1.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<BigList>;

  /**
   * Inserts a new row with `label` so that it ends at `index` (`index == len` appends), and
   * returns its identity. One keyed `Insert`.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  insertAt(index: number, label: string): Promise<number>;

  /**
   * Moves the row at `from` so that it ends at `to`. One keyed `Move`.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  moveItem(from: number, to: number): Promise<void>;

  /**
   * Removes the row at `index`. One keyed `Remove`.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  removeAt(index: number): Promise<void>;

  /**
   * Replaces the list with a fresh one of [`LIST_LEN`] items. The platform receives the keyed
   * patch that turns the old list into the new one (a full value if they have little in
   * common).
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  reset(): Promise<void>;

  /**
   * Changes the label of the row at `index` and bumps its version. One keyed `Update`.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  updateAt(index: number, label: string): Promise<void>;
}

/** A counter with a change tally and a computed parity. */
export class Counter extends UndraStore {
  readonly count: Signal<number>;
  readonly changes: Signal<number>;
  /** Computed by the core; read-only. */
  readonly parity: Signal<Parity>;

  /**
   * A counter at zero with no changes made.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Counter>;

  /**
   * Adds `amount` (which may be negative) and counts the change: one transaction, so one
   * change-set for `count`, `changes` and `parity` together. The count saturates instead of
   * overflowing.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  add(amount: number): Promise<void>;

  /**
   * Subtracts one.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  decrement(): Promise<void>;

  /**
   * Adds one.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  increment(): Promise<void>;

  /**
   * Sets the count back to zero and forgets the changes, in one transaction.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  reset(): Promise<void>;
}

/**
 * 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.
 */
export class Device extends UndraStore {
  readonly online: Signal<boolean>;
  readonly netKind: Signal<NetKind>;
  readonly appState: Signal<AppState>;
  readonly connectivityReports: Signal<number>;
  readonly lifecycleReports: Signal<number>;

  /**
   * The store, showing every report received so far and following the next ones.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Device>;
}

/** The accounts the app lists: a list keyed by a newtype. */
export class Ledger extends UndraStore {
  readonly accounts: Signal<Account[]>;

  /**
   * A ledger with no accounts.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Ledger>;

  /**
   * Closes the account `id`; one keyed `Remove`.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  closeAccount(id: AccountId): Promise<void>;

  /**
   * Opens an account for `owner`; one keyed `Insert` whose key is a newtype.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  open(owner: string): Promise<AccountId>;

  /**
   * Changes the owner of the account `id`; one keyed `Update`.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  rename(id: AccountId, owner: string): Promise<void>;
}

/** A store whose one signal build B changes incompatibly. */
export class Legacy extends UndraStore {
  readonly score: Signal<number>;

  /**
   * A score of `score`.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(score: number, core: UndraCore = UndraPlaygroundCore.core): Promise<Legacy>;

  /**
   * `score=..`.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  describe(): Promise<string>;
}

/** A library of books the host pages through. */
export class Library extends UndraStore {
  /** 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. */
  readonly books: LazyList<Item>;
  readonly source: Signal<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. */
  readonly evens: LazyList<Item>;

  /**
   * A library with [`LIBRARY_LEN`] books and a source of 20 rows.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Library>;

  /**
   * Appends `count` books and, in the same transaction, as many rows to `source`. Each is one
   * recorded push, and the host is told one new length and version.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  addRows(count: number): Promise<void>;

  /**
   * How many books there are.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  count(): Promise<number>;

  /**
   * Removes `count` rows from the start of `source` (the lazy view follows).
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  dropSource(count: number): Promise<void>;

  /**
   * Removes the book at `index`.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  removeAt(index: number): Promise<void>;

  /**
   * Changes the label of the book at `index` and bumps its version.
   * @throws {ListError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  rename(index: number, label: string): Promise<void>;

  /**
   * Replaces the books with `count` fresh ones numbered from 1.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  reset(count: number): Promise<void>;
}

/** The ticked notes. */
export class NoteSelection extends UndraStore {
  readonly rows: Signal<Note[]>;
  /** Computed by the core; read-only. */
  readonly count: Signal<number>;

  /**
   * Nothing ticked.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<NoteSelection>;

  /**
   * Unticks everything.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  clear(): Promise<void>;

  /**
   * Ticks every row of `rows` that is not ticked yet, in one transaction.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  selectAll(rows: Note[]): Promise<void>;

  /**
   * Ticks `row`, or unticks it if it is ticked.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  toggle(row: Note): Promise<void>;
}

/** The notes of one database, mirrored: `notes` changes only after the database did. */
export class Notes extends UndraStore {
  readonly notes: Signal<Note[]>;
  readonly version: Signal<number>;

  /**
   * No database open yet: call [`open`](Notes::open).
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Notes>;

  /**
   * Adds a note at the end.
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  add(title: string, signal?: AbortSignal): Promise<Note>;

  /**
   * Adds every title in one transaction: all or none. A `None` title breaks `NOT NULL` and
   * rolls the whole batch back. Returns how many were added.
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  addAll(titles: (string | null)[], signal?: AbortSignal): Promise<number>;

  /**
   * Adds a note with a chosen id (an id in use is `Constraint { kind: Unique }`).
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  addWithId(id: bigint, title: string, signal?: AbortSignal): Promise<Note>;

  /**
   * Closes the database; the list keeps what it showed (`close` is every store's own: it
   * releases the handle).
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  closeDatabase(signal?: AbortSignal): Promise<void>;

  /**
   * How many notes the database holds (read from it, not from the mirror).
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  count(signal?: AbortSignal): Promise<number>;

  /**
   * Opens (creating it if needed) database `name`, migrates it and loads every note.
   * Returns its version.
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  open(name: string, signal?: AbortSignal): Promise<number>;

  /**
   * Removes note `id`.
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  remove(id: bigint, signal?: AbortSignal): Promise<void>;

  /**
   * Ticks or unticks note `id`.
   * @throws {DbError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  toggle(id: bigint, signal?: AbortSignal): Promise<void>;
}

/** A user profile: build A's signals are `name`, then `visits`. */
export class Profile extends UndraStore {
  readonly name: Signal<string>;
  readonly visits: Signal<number>;

  /**
   * A profile called `name`, never visited.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(name: string, core: UndraCore = UndraPlaygroundCore.core): Promise<Profile>;

  /**
   * `name=..;visits=..`: what both builds can be compared by.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  describe(): Promise<string>;

  /**
   * Counts one visit.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  visit(): Promise<void>;
}

/** A shelf: a child store of the [`Workshop`], with a label and a count of the items on it. */
export class Shelf extends UndraStore {
  readonly label: Signal<string>;
  readonly items: Signal<number>;

  /**
   * An empty shelf with no label. A platform gets shelves from [`Workshop::shelf`], not from
   * here, so that one name is one shelf.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Shelf>;

  /**
   * Takes every item off the shelf.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  clear(): Promise<void>;

  /**
   * Puts `count` more items on the shelf.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  stock(count: number): Promise<void>;
}

/**
 * A store that commits many transactions, for the coalesced-delivery scenarios and the
 * playground's stress screen.
 */
export class Stress extends UndraStore {
  readonly value: Signal<bigint>;
  readonly progress: Signal<number>;
  readonly generated: Signal<bigint>;
  readonly running: Signal<boolean>;

  /**
   * A store with every signal at its start: zeros, and no generator running.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Stress>;

  /**
   * Commits `transactions` transactions now, each one write of the signal `mode` names: one
   * change-set per transaction, the way data that arrives in the core on its own does.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  burst(mode: StressMode, transactions: number): Promise<void>;

  /**
   * Starts generating updates of the signal the mode names, at the given number a second,
   * each its own transaction, until `stop`. Called while a generator runs, it retunes that
   * generator (new mode, new rate) instead of starting a second one. Fails, starting
   * nothing, when the rate is zero or above 1,000,000.
   * @throws {StressError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  start(mode: StressMode, perSecond: number): Promise<void>;

  /**
   * Stops the generator: no update is committed after this returns. `generated` keeps its
   * count. Does nothing when no generator runs.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  stop(): Promise<void>;
}

/** The ticked to-dos. */
export class TodoSelection extends UndraStore {
  readonly rows: Signal<Todo[]>;
  /** Computed by the core; read-only. */
  readonly count: Signal<number>;

  /**
   * Nothing ticked.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<TodoSelection>;

  /**
   * Unticks everything.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  clear(): Promise<void>;

  /**
   * Ticks every row of `rows` that is not ticked yet, in one transaction.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  selectAll(rows: Todo[]): Promise<void>;

  /**
   * Ticks `row`, or unticks it if it is ticked.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  toggle(row: Todo): Promise<void>;
}

/** The to-do list: what the UI observes (`todos`, `filter`, `visible`, `remaining`) and calls. */
export class Todos extends UndraStore {
  readonly todos: Signal<Todo[]>;
  readonly filter: Signal<Filter>;
  /** Derived by the core from another list; read-only. Changes arrive as keyed patches. */
  readonly visible: Signal<Todo[]>;
  /** Computed by the core; read-only. */
  readonly remaining: Signal<number>;

  /**
   * An empty list showing every item.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Todos>;

  /**
   * Adds an item at the end of the list.
   * @throws {TodoError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  add(title: string, signal?: AbortSignal): Promise<Todo>;

  /**
   * Removes every finished item.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  clearDone(): Promise<void>;

  /**
   * Appends `count` items titled `Item 1`, `Item 2`, .. with every fourth one finished, in one
   * transaction (a demo and test helper: the big-list screen of the docs, contract scenario S19).
   * A bulk load is a raw write, so `todos` and `visible` are sent as full values this once; the
   * writes after it are patches again.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  fill(count: number): Promise<void>;

  /**
   * Removes the item with `id`; unknown ids are ignored.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  remove(id: string): Promise<void>;

  /**
   * Chooses which items `visible` holds.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  setFilter(filter: Filter): Promise<void>;

  /**
   * Flips the `done` flag of the item with `id`; unknown ids are ignored.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  toggle(id: string): Promise<void>;
}

/**
 * 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.
 */
export class Workshop extends UndraStore {
  readonly jobs: Signal<number>;
  readonly notes: Signal<number>;

  /**
   * An empty workshop.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<Workshop>;

  /**
   * Counts a note (a signal commit, which reaches the platform first) and tells every
   * subscribed reporter `line`: the platform sees the new count before it hears the note.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  announce(line: string): Promise<number>;

  /**
   * Reports `steps` times in a row without waiting: a burst, of which the app that is slow to
   * react gets only the newest `progress` (the others are coalesced), but every `note`.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  burst(steps: number, reporter: Reporter): Promise<void>;

  /**
   * The label of `shelf`, or `none` for no shelf at all.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  describe(shelf: Shelf | null): Promise<string>;

  /**
   * The shelf called `name`, if there is one.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  find(name: string): Promise<Shelf | null>;

  /**
   * Moves every item of `from` onto `onto`, in one transaction (a method that takes two
   * stores).
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  merge(from: Shelf, onto: Shelf): Promise<void>;

  /**
   * Opens a shelf after `delay_ms` milliseconds (a call a platform can cancel while it
   * waits: then no shelf was handed out and nothing is owed).
   * @throws {WorkshopError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  open(name: string, delayMs: number, signal?: AbortSignal): Promise<Shelf>;

  /**
   * Runs a job of `steps` steps, reporting to the app: one progress report and one note per
   * step, then a question whose answer is the result (`steps` if the app says go on, else
   * `Declined`). The job counts as run whatever the answer.
   * @throws {ReportError}
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
   */
  run(steps: number, reporter: Reporter, signal?: AbortSignal): Promise<number>;

  /**
   * The shelf called `name`, made on first use: the same shelf every time, so a platform that
   * asks twice gets one object (and one reference to give back, not two).
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  shelf(name: string): Promise<Shelf>;

  /**
   * Every shelf, in name order.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  shelves(): Promise<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.
   * Iterating throws UndraCallError; leaving the loop early ends the stream quietly.
   */
  tally(shelf: Shelf, steps: number): AsyncIterable<number>;

  /**
   * How many items there are on the shelves given.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  total(shelves: Shelf[]): Promise<number>;

  /**
   * 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.
   * Iterating throws UndraCallError; leaving the loop early ends the stream quietly.
   */
  walk(steps: number, reporter: Reporter): AsyncIterable<number>;

  /**
   * Keeps `reporter` until the returned subscription is closed; [`Workshop::announce`] tells it.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  watch(reporter: Reporter): Promise<Watch>;

  /**
   * How many reporters are subscribed.
   * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
   */
  watching(): Promise<number>;
}

Ports#

An interface for each port the core declares, and an adapter that registers your implementation.

Locale localePortImpl

Show the declarations 12 lines
/**
 * The app's own synchronous port (ADR-049 decision 2): how the platform says hello in the
 * user's language. In the TypeScript `wasm-worker` mode a synchronous port is answered in the
 * worker, so the web app registers it in `worker.ports`.
 */
export interface Locale extends UndraPort {
  /** "Hello" in the user's language. */
  hello(): string;
}

/** Adapts an implementation of `Locale` to `UndraCore.registerPort(UndraIds.Ports.Locale.portId, ..)`. */
export function localePortImpl(impl: Locale): PortImpl;

Callbacks#

An interface for each #[undra::callback] trait, which your app implements so the core can call it, with weak<Name>(target) to hand over instead of the object itself.

Reporter weakReporter

Show the declarations 30 lines
/** What the app implements to hear from the core. */
export interface Reporter {
  /**
   * Asks whether to go on; the app may answer later, or not at all.
   * Reject with `ReportError` to fail with it; any other failure is reported to `onError`
   * and the core hears "unavailable".
   * @param signal Aborted when the core stops waiting for the answer.
   */
  confirm(question: string, signal: AbortSignal): Promise<boolean>;
  /** A line to show. */
  note(line: string): void;
  /**
   * 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.
   */
  progress(done: number, total: number): void;
}

/**
 * A `Reporter` that holds `target` weakly (ADR-041): it forwards while `target` is alive; once `target` was
 * garbage-collected its methods do nothing (`confirm` answers the core "unavailable").
 * Pass it instead of `target` when the core must not keep `target` alive.
 */
export function weakReporter(target: Reporter): Reporter;

/**
 * How the core's calls reach a `Reporter` the app passed in (ADR-041), for the runtime: the ids and the
 * decoding of each method. Generated calls lend through it; an app does not use it.
 */
export const ReporterCallback: CallbackInterface<Reporter>;

Queries#

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

FeedQueryHandle RemoteTodosQueryHandle RosterQueryHandle TickerQueryHandle patchRemoteTodo postRemoteTodo saveNote tagNote

Show the declarations 232 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.
 */
export class FeedQueryHandle extends UndraStore {
  /** Every row loaded so far, in order: the first page, then each page `fetchNextPage()` loaded. Empty until the first page arrives. */
  readonly data: Signal<Item[]>;
  /** Where the query is in its fetch lifecycle. */
  readonly status: Signal<QueryStatus>;
  /** The error of the latest failed fetch, cleared by the next success. */
  readonly error: Signal<ListError | null>;
  /** Whether a fetch is in flight (also true while refetching stale data). */
  readonly fetching: Signal<boolean>;
  /** When `data` was last updated. */
  readonly updatedAt: Signal<Timestamp | null>;
  /** Whether another page can be fetched: the last page loaded named a next cursor. */
  readonly hasNextPage: Signal<boolean>;
  /** Whether the fetch of the next page is in flight. */
  readonly fetchingNextPage: Signal<boolean>;

  /** @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached. */
  static create(
    evenOnly: boolean,
    core: UndraCore = UndraPlaygroundCore.core,
  ): Promise<FeedQueryHandle>;

  /**
   * Fetches the next page and appends its rows to `data`; nothing happens while a page is loading or when there is no next page.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  fetchNextPage(): Promise<void>;

  /**
   * Fetches again now, even if the data is fresh.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  refetch(): Promise<void>;

  /**
   * Marks the cached entry stale; it refetches while observed.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  invalidate(): Promise<void>;

  /**
   * Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
   * The entry polls at the smallest interval among its observers; no interval clears this handle's override.
   * An interval below 1 second or above 7 days is clamped to that range.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  setPollInterval(ms: Duration | null): Promise<void>;
}

/**
 * Observes the `remote_todos` query (cache key `remote-todos:{list}`).
 * Constructing it registers an observer and fetches when the data is stale or missing.
 */
export class RemoteTodosQueryHandle extends UndraStore {
  /** The latest successful result, if any. */
  readonly data: Signal<RemoteTodo[] | null>;
  /** Where the query is in its fetch lifecycle. */
  readonly status: Signal<QueryStatus>;
  /** The error of the latest failed fetch, cleared by the next success. */
  readonly error: Signal<RemoteError | null>;
  /** Whether a fetch is in flight (also true while refetching stale data). */
  readonly fetching: Signal<boolean>;
  /** When `data` was last updated. */
  readonly updatedAt: Signal<Timestamp | null>;

  /** @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached. */
  static create(
    list: string,
    core: UndraCore = UndraPlaygroundCore.core,
  ): Promise<RemoteTodosQueryHandle>;

  /**
   * Fetches again now, even if the data is fresh.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  refetch(): Promise<void>;

  /**
   * Marks the cached entry stale; it refetches while observed.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  invalidate(): Promise<void>;

  /**
   * Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
   * The entry polls at the smallest interval among its observers; no interval clears this handle's override.
   * An interval below 1 second or above 7 days is clamped to that range.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  setPollInterval(ms: Duration | null): Promise<void>;
}

/**
 * Observes the `roster` query (cache key `roster:{team}`).
 * Constructing it registers an observer and fetches when the data is stale or missing.
 */
export class RosterQueryHandle extends UndraStore {
  /** The latest successful result, if any. */
  readonly data: Signal<string[] | null>;
  /** Where the query is in its fetch lifecycle. */
  readonly status: Signal<QueryStatus>;
  /** The error of the latest failed fetch, cleared by the next success. */
  readonly error: Signal<RemoteError | null>;
  /** Whether a fetch is in flight (also true while refetching stale data). */
  readonly fetching: Signal<boolean>;
  /** When `data` was last updated. */
  readonly updatedAt: Signal<Timestamp | null>;

  /** @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached. */
  static create(
    team: number,
    core: UndraCore = UndraPlaygroundCore.core,
  ): Promise<RosterQueryHandle>;

  /**
   * Fetches again now, even if the data is fresh.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  refetch(): Promise<void>;

  /**
   * Marks the cached entry stale; it refetches while observed.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  invalidate(): Promise<void>;

  /**
   * Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
   * The entry polls at the smallest interval among its observers; no interval clears this handle's override.
   * An interval below 1 second or above 7 days is clamped to that range.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  setPollInterval(ms: Duration | null): Promise<void>;
}

/**
 * Observes the `ticker` query (cache key `ticker`).
 * Constructing it registers an observer and fetches when the data is stale or missing.
 */
export class TickerQueryHandle extends UndraStore {
  /** The latest successful result, if any. */
  readonly data: Signal<number | null>;
  /** Where the query is in its fetch lifecycle. */
  readonly status: Signal<QueryStatus>;
  /** The error of the latest failed fetch, cleared by the next success. */
  readonly error: Signal<TickError | null>;
  /** Whether a fetch is in flight (also true while refetching stale data). */
  readonly fetching: Signal<boolean>;
  /** When `data` was last updated. */
  readonly updatedAt: Signal<Timestamp | null>;

  /** @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached. */
  static create(core: UndraCore = UndraPlaygroundCore.core): Promise<TickerQueryHandle>;

  /**
   * Fetches again now, even if the data is fresh.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  refetch(): Promise<void>;

  /**
   * Marks the cached entry stale; it refetches while observed.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  invalidate(): Promise<void>;

  /**
   * Overrides how often the query polls while this handle observes it, counted from the end of a fetch.
   * The entry polls at the smallest interval among its observers; no interval clears this handle's override.
   * An interval below 1 second or above 7 days is clamped to that range.
   * A failure is logged and passed to `onError`; the returned promise never rejects.
   */
  setPollInterval(ms: Duration | null): Promise<void>;
}

/**
 * Runs the `patch_remote_todo` mutation.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function patchRemoteTodo(
  list: string,
  id: number,
  done: boolean,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<RemoteTodo>;

/**
 * Runs the `post_remote_todo` mutation.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function postRemoteTodo(
  list: string,
  title: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<RemoteTodo>;

/**
 * Runs the `save_note` mutation.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function saveNote(
  list: string,
  text: string,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<boolean>;

/**
 * Runs the `tag_note` mutation.
 * @throws {RemoteError}
 * @throws {UndraCallError} If the core panics, refuses or cancels the call, or cannot be reached.
 * @throws The `signal`'s reason (an `AbortError` by default) if it aborts the call.
 */
export function tagNote(
  list: string,
  id: number,
  core: UndraCore = UndraPlaygroundCore.core,
  signal?: AbortSignal,
): Promise<boolean>;

Wire ids#

The stable identifiers of every call, the core's namespace and the schema hash its entry checks at load.

UndraIds

Show the declarations 281 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.
 */
export const UndraIds = {
  schemaHash: 0x3c17cd5f59bb6f68n,
  namespace: "playground_core",
  Objects: {
    Live: {
      typeId: 0x881c63cf,
      new: 0xff026383,
      abandon: 0x1a6729e8,
      connect: 0xa8ddf747,
      disconnect: 0xb47c6859,
      pulls: 0x1649f03d,
      read: 0xc853d487,
      send: 0xbb31ff25,
    },
    Probe: {
      typeId: 0x4fdd3051,
      new: 0xb843ab99,
      counters: 0xc3958518,
      hang: 0x98f10ca1,
      reset: 0xce3a32f8,
      ticks: 0x9ea5858d,
      ticksThenFail: 0xa48a6ac2,
      wait: 0x6bab3fb8,
    },
    RecentTodos: {
      typeId: 0xf3574157,
      new: 0xf0a9e00b,
      latest: 0xdabb2338,
      open: 0x4addedc7,
      rows: 0x77753b96,
    },
    Watch: {
      typeId: 0xec266ec8,
      id: 0x2075bd1f,
    },
    Bench: {
      typeId: 0x346ad459,
      new: 0x36809c61,
      benchAdd: 0xe6f91ad9,
      benchEchoBytes: 0x677eb967,
      benchListInsert: 0x914b8e82,
      benchListReset: 0x0c07aab2,
      benchListUpdateBurst: 0x7411fd03,
      benchTouchSignals: 0x3fc0389f,
    },
    BigList: {
      typeId: 0x3b9271c5,
      new: 0xf5e4a11d,
      insertAt: 0x8f234904,
      moveItem: 0x58a6cbde,
      removeAt: 0x1237d7af,
      reset: 0x65063b1c,
      updateAt: 0x0e5ff480,
    },
    Counter: {
      typeId: 0xfc0f33c3,
      new: 0xcff00e37,
      add: 0x8adcbf02,
      decrement: 0xe6593ac4,
      increment: 0x0584c6ac,
      reset: 0x0c5ad256,
    },
    Device: {
      typeId: 0xbdcbb413,
      new: 0x3f6646a7,
    },
    Ledger: {
      typeId: 0x348f96ac,
      new: 0x134c88d0,
      closeAccount: 0x06f7c642,
      open: 0x2dd4faa6,
      rename: 0x12958000,
    },
    Legacy: {
      typeId: 0x055b887e,
      new: 0x14d6ac0e,
      describe: 0x642670b9,
    },
    Library: {
      typeId: 0xa8532270,
      new: 0xf94159c4,
      addRows: 0x4cf117af,
      count: 0x4503ed51,
      dropSource: 0x56f49125,
      removeAt: 0xe4a7c326,
      rename: 0x5fcbc4c4,
      reset: 0x41bc20dd,
    },
    NoteSelection: {
      typeId: 0x5f5e349d,
      new: 0xa0602cd5,
      clear: 0xb304c15e,
      selectAll: 0xbb722df1,
      toggle: 0xce377229,
    },
    Notes: {
      typeId: 0x0ff01b6a,
      new: 0x5981902a,
      add: 0xf7a61617,
      addAll: 0xd4384f5b,
      addWithId: 0x20b4cbe8,
      closeDatabase: 0x11647c30,
      count: 0x39cf3133,
      open: 0x5d8df10c,
      remove: 0x6e4b1cdc,
      toggle: 0xe1983278,
    },
    Profile: {
      typeId: 0xcd17328e,
      new: 0xed94ae7e,
      describe: 0xa05219a9,
      visit: 0xa008fdab,
    },
    Shelf: {
      typeId: 0xb01959e3,
      new: 0x4e9d4957,
      clear: 0x8cb02b88,
      stock: 0xbd0e77fb,
    },
    Stress: {
      typeId: 0xafa58985,
      new: 0x6799185d,
      burst: 0xf4b7ad05,
      start: 0xb710bb83,
      stop: 0xb5c8e111,
    },
    TodoSelection: {
      typeId: 0xd88b75dd,
      new: 0xfb065295,
      clear: 0x1658621e,
      selectAll: 0x916e69b1,
      toggle: 0x5a64c3e9,
    },
    Todos: {
      typeId: 0xf5e31faa,
      new: 0x35935dea,
      add: 0xd13d7ad7,
      clearDone: 0x27ffa842,
      fill: 0x1ce95af5,
      remove: 0xa977479c,
      setFilter: 0x07781993,
      toggle: 0x1cc45d38,
    },
    Workshop: {
      typeId: 0xe22bcc2c,
      new: 0x3dd69650,
      announce: 0xed2adfb5,
      burst: 0x7d3f02b4,
      describe: 0xcec7da2f,
      find: 0x84e1ab01,
      merge: 0x9d9f7396,
      open: 0xa5283b26,
      run: 0x5208d85f,
      shelf: 0xfaed29c6,
      shelves: 0x952fdfee,
      tally: 0x56a6b8e4,
      total: 0xce8e1708,
      walk: 0x0c0539af,
      watch: 0x19e462e5,
      watching: 0x76b9e49b,
    },
    FeedQueryHandle: {
      typeId: 0x015a66a3,
      new: 0x015a66a3,
      fetchNextPage: 0x84920501,
      refetch: 0x21d1b9e2,
      invalidate: 0x44cec2fa,
      setPollInterval: 0xe327e53b,
    },
    RemoteTodosQueryHandle: {
      typeId: 0x2a794167,
      new: 0x2a794167,
      refetch: 0x21d1b9e2,
      invalidate: 0x44cec2fa,
      setPollInterval: 0xe327e53b,
    },
    RosterQueryHandle: {
      typeId: 0xaa41fecc,
      new: 0xaa41fecc,
      refetch: 0x21d1b9e2,
      invalidate: 0x44cec2fa,
      setPollInterval: 0xe327e53b,
    },
    TickerQueryHandle: {
      typeId: 0x38de4411,
      new: 0x38de4411,
      refetch: 0x21d1b9e2,
      invalidate: 0x44cec2fa,
      setPollInterval: 0xe327e53b,
    },
  },
  Functions: {
    add: 0x65b4cd58,
    addLater: 0xc5ca16e9,
    area: 0x293fbad8,
    balances: 0x2f156bcc,
    configureRemote: 0xa991dd26,
    createRemoteTodo: 0x3f635105,
    dbCells: 0x31c92fa5,
    dbMigrate: 0x2f1b2165,
    dbRun: 0x8c3edc9d,
    deposit: 0x1301c349,
    draftNote: 0x1ee40222,
    draftTodo: 0x0c13e0ee,
    echoAccount: 0x730b1c74,
    echoCents: 0x8cdc6e3c,
    echoComposite: 0x769db4ec,
    echoDecimal: 0x7a8022d4,
    echoFigure: 0xeeb27e01,
    echoPrice: 0xbcbc2c72,
    echoPrimitives: 0x59ba77e7,
    echoReceipt: 0x05b7b46b,
    explode: 0x4b8e88d2,
    explodeDetached: 0x5388e4d9,
    explodeLater: 0xe5a63d4b,
    failLater: 0x977e4974,
    fileDelete: 0x3ea41ab3,
    fileList: 0x97b9c870,
    fileRead: 0x2103879c,
    fileWrite: 0x2c0e4e77,
    greet: 0x0594d9ae,
    httpGet: 0xbce1d1e6,
    kvGet: 0x05cd83d7,
    kvKeys: 0x4be5264d,
    kvPut: 0x1b33766e,
    kvRemove: 0xe4402f7d,
    loadableStatement: 0x74183f5f,
    localizedGreeting: 0x247f9a6c,
    newestNote: 0x4835685d,
    newestTodo: 0xb9743b7d,
    openAccount: 0x30922a29,
    ownerOf: 0xacfd7ad8,
    parseCount: 0x1c438944,
    ping: 0x60e670d5,
    recentTodos: 0x69a43bf4,
    sampleReceipt: 0xe6449400,
    secretGet: 0x3f96f35a,
    secretKeys: 0x98a56bd2,
    secretPut: 0x2c60b7cb,
    secretRemove: 0x83a7330a,
    setRemoteDone: 0xa1e08a5f,
    setTickerFailing: 0x26f08a91,
    sseFollow: 0x237de656,
    statement: 0xadc39bc2,
    storageStatus: 0x79205099,
    tickerFetches: 0xb3a3511c,
    touchFeed: 0x27176f81,
    version: 0xceb9168b,
    wsEcho: 0x2b49a875,
  },
  Ports: {
    Locale: {
      portId: 0xcc469822,
      hello: 0x9e2a48e9,
    },
  },
  Queries: {
    feed: 0x015a66a3,
    patchRemoteTodo: 0x77fe653e,
    postRemoteTodo: 0x5c84eed2,
    remoteTodos: 0x2a794167,
    roster: 0xaa41fecc,
    saveNote: 0xaef633c6,
    tagNote: 0xb9224861,
    ticker: 0x38de4411,
  },
  Callbacks: {
    Reporter: {
      portId: 0x10e8b455,
      confirm: 0x1ea2905a,
      note: 0x8720eafe,
      progress: 0x3a77cbcd,
      releaseInstance: 0x47e657b5,
      cancelCall: 0x9a8ca032,
    },
  },
} as const;

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