Rindle

API index and search · Build metadata

Supporting declarations

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

Exact source

Salience

export type Salience = "alert" | "info" | "ambient";

NarrateContext

/** Context a template may interpolate — e.g. a human label for the subscription's subject. */
export interface NarrateContext {
    /** A human name for what the query is scoped to ("the Smith wedding"). */
    subject?: string;
    [k: string]: unknown;
}

TemplateCtx

export interface TemplateCtx {
    row: NamedRow;
    old?: NamedRow;
    /** The parent row, for an aggregate/nested change (e.g. the `ticket_type` behind a `sold` count). */
    parent?: NamedRow;
    /** Resolve a named sub-row of the change (only populated on `add`). */
    sub: (alias: string) => NamedRow | null;
    aggregate?: ResolvedChange["aggregate"];
    context: NarrateContext;
}

Template

export type Template = (ctx: TemplateCtx) => string | null;

RelatedNarrator

/** Handlers for changes to ONE nested relationship (keyed by its alias in {@link QueryNarrator.related}),
 *  by op — plus an optional salience override for that relationship's events. A nested template reads
 *  `row` (the nested row), `old`, and `parent` (its immediate container — the deck for a slide, the
 *  slide for a component). */
export interface RelatedNarrator {
    /** Override the query's default salience for events on this relationship (else inherits it). */
    salience?: Salience;
    add?: Template;
    remove?: Template;
    edit?: Template;
}

QueryNarrator

export interface QueryNarrator {
    /** Default importance of this query's events; an op handler may override via the return tuple. */
    salience: Salience;
    /** Handlers for changes at the ROOT level, by op. */
    root?: Partial<Record<"add" | "remove" | "edit", Template>>;
    /** Handlers for changes to a NESTED relationship, keyed by op — so ONE materialized view narrates
     *  its whole tree: e.g. a deck's title at the root, slide edits under `slides`, component adds under
     *  `components`. Key by the relationship's LEAF alias (`components`) for the common case, or by the
     *  FULL dotted alias-chain from the root (`slides.components`) to disambiguate two relationships that
     *  share a leaf alias at different tree positions (e.g. `slides.components` vs `appendix.components`).
     *  A dotted key wins over a leaf key when both match; a bare leaf key still matches at any depth. */
    related?: Record<string, RelatedNarrator>;
    /** Handlers for an aggregate slot (`countAs`), keyed by the count's alias. */
    counts?: Record<string, Template>;
}

NarratorRegistry

/** A registry of {@link QueryNarrator}s, keyed by `defineQuery` name. Supplied by the app. */
export type NarratorRegistry = Record<string, QueryNarrator>;

SemanticEvent

/** One rendered semantic event. `text === null` was suppressed by its template (too ambient). */
export interface SemanticEvent {
    query: string;
    phase: "snapshot" | "batch";
    salience: Salience;
    resolved: ResolvedChange;
    text: string | null;
}

Narrator

export interface Narrator {
    /** Resolve + render a `FlatChange[]` for a named query into semantic events. `schema` is the
     *  query's `WireSchema`, captured from its `hello` frame (or read off `view.schema`) — the
     *  position→name source. */
    narrate(query: string, schema: WireSchema, changes: FlatChange[], phase: "snapshot" | "batch", ctx?: NarrateContext): SemanticEvent[];
    /** Format a batch of rendered events for an agent prompt (salience-marked, suppressions dropped). */
    digest(events: SemanticEvent[]): string;
}

SALIENCE_MARK

/** Per-salience glyph for a rendered line. */
export declare const SALIENCE_MARK: Record<Salience, string>;

salienceRank

/** Order salience high→low. */
export declare const salienceRank: (s: Salience) => number;

createNarrator

/** Build a narrator over an app-supplied {@link NarratorRegistry}. Resolution is driven entirely by
 *  the per-query `WireSchema` passed to {@link Narrator.narrate}, so the narrator holds no schema
 *  state of its own. */
export declare function createNarrator(narrators: NarratorRegistry): Narrator;