Rindle

API index and search · Build metadata

Supporting declarations

packages/room/src/mutation-tx.ts. These declarations explain referenced types. Only package-page symbols are package exports.

Exact source

WireValue

/** A bare wire cell (the client stack's `WireValue`). */
export type WireValue = number | string | boolean | null;

KeyedRow

/** A row keyed by column name. */
export type KeyedRow = Record<string, WireValue>;

MutationTx

/** The §4.2 write handle. Keyed methods are schema-checked; positional methods are the
 *  raw wire shape (cells in schema column order, pk cells in `primaryKey` order).
 *  `query` is not available in room mutators yet (it throws) — typed so a client
 *  registry that uses it still registers, and fails loudly at run time. */
export interface MutationTx {
    /** Read one row by primary key (e.g. `tx.row("issue", { id: 1 })`). */
    row(table: string, pk: KeyedRow): KeyedRow | undefined;
    /** Insert a FULL row (every column named; missing or unknown columns throw). */
    insert(table: string, row: KeyedRow): void;
    /** Update the row identified by the pk columns; only the named non-pk columns
     *  change. A missing row is a NO-OP (rebase-friendly). */
    update(table: string, row: KeyedRow): void;
    /** Insert, or fully replace when the pk already exists (a FULL row, like insert). */
    upsert(table: string, row: KeyedRow): void;
    /** Delete the row identified by the pk columns. A missing row is a NO-OP. */
    delete(table: string, pk: KeyedRow): void;
    /** NOT SUPPORTED in room mutators yet — throws. (Typed to accept the client
     *  builder's queries so shared registries typecheck.) */
    query(query: {
        ast(): unknown;
    }): never;
    get(table: string, pk: WireValue[]): WireValue[] | undefined;
    add(table: string, row: WireValue[]): void;
    remove(table: string, row: WireValue[]): void;
    edit(table: string, oldRow: WireValue[], newRow: (WireValue | undefined)[]): void;
}

RoomMutatorCtx

/** The ambient authorization context a room mutator runs under (managed-writes design
 *  §3.2). Shell-stamped from the connection's DO-verified lease token — NEVER
 *  client-supplied — so per-row/per-field rules checked against it are trustworthy.
 *  The shape deliberately matches the shared-generator drivers' `ctx.user`, so one
 *  registry body runs identically in all three homes (client / api-server / room). */
export interface RoomMutatorCtx {
    /** The authenticated subject (the lease token's `sub`). `""` on replay of an entry
     *  journaled before the identity plane — treat as unauthenticated. */
    user: string;
}

RoomMutator

/** A room mutator: deterministic, replayable — re-invoked on journal replay against
 *  the freshly re-subscribed base (§3.3), so the same purity rules as a client
 *  mutator apply (no clock, no randomness, a pure function of `(base, args, ctx)`).
 *  An auth check against `ctx` re-runs on replay against the freshly rebuilt base —
 *  a mutation that passed before a crash can replay as rejected if the permission
 *  row changed in between; that is §3.3's intended rebase behavior. */
export type RoomMutator = (tx: MutationTx, args: never, ctx: RoomMutatorCtx) => void;

environmentShortfall

/**
 * Tag an error as an ENVIRONMENT shortfall (H-iv-b): the room lacks a capability the
 * mutation needs (today: `tx.query`), which is a verdict about the ROOM, not the
 * mutation — the shell classifies it as a DEOPT (the client re-routes the mutation to
 * the daemon stream, where the capability exists) instead of a FINAL rejection (which
 * would drop the mutation). Contrast a validation/authz throw: re-routing can't help
 * those, so they stay `rejected`.
 */
export declare function environmentShortfall(message: string): Error;

isEnvironmentShortfall

/** Whether `e` was tagged by {@link environmentShortfall}. */
export declare function isEnvironmentShortfall(e: unknown): boolean;

assertSyncMutatorReturn

/**
 * Guard against the two mutator shapes that would corrupt silently instead of failing loudly.
 * A `shared(...)` GENERATOR registered verbatim returns an un-iterated generator — zero writes,
 * acked as applied (data loss); an ASYNC mutator runs synchronously only to its first `await`,
 * so later writes land OUTSIDE the committed transaction. Both shells call this on the
 * mutator's return value inside their try/reject path, so either shape becomes an explicit
 * rejection with a pointed message. (An adapter that DRIVES a shared generator registry against
 * the room tx is future work — managed-writes design §8.)
 */
export declare function assertSyncMutatorReturn(returned: unknown, name: string): void;

TableShape

/** One table's positional shape, parsed from the upstream hello. */
export interface TableShape {
    columns: string[];
    /** Indices into `columns`. */
    primaryKey: number[];
}

mutationTx

/** Build the MutationTx for one open wasm transaction. Valid only while that
 *  transaction is open — the shell creates one per mutation and never retains it. */
export declare function mutationTx(room: WasmRoom, shapes: Map<string, TableShape>): MutationTx;