Rindle

API index and search · Build metadata

Supporting declarations

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

Exact source

OneShotResult

/** An authorized one-shot read result, as far as the server Store needs it: the
 *  assembled rows plus the `cvMin` baseline they reflect. (Matches `@rindle/daemon-client`'s
 *  `QueryOnceOutput`, but `@rindle/client` stays dependency-free — inject the call.) */
export interface OneShotResult {
    rows: AssembledNode[];
    cvMin?: number;
}

OneShotQueryFn

/** The one-shot read the server Store calls to preload a query. Two topologies inject different
 *  fns (SSR-DESIGN.md §6):
 *
 *   - **Direct to the daemon** (the trusted tier holds the daemon token): use `ast` —
 *     `(i) => daemon.query(i)`.
 *   - **Through the application's API tier** (the authority resolves names → ASTs, the loader never
 *     sends a raw AST): use `name`/`args` — `(i) => fetch('/api/rindle/read', {name: i.name, args: i.args})`.
 *
 *  `ast` is always present (the Store seeds the local view by its `viewKey`); `name`/`args` are
 *  present when the preloaded query came from `defineQuery`. This Store does not authenticate
 *  users or filter rows. The injected function must enforce access: either call the authenticated
 *  API route, or authorize and construct the AST before a privileged direct daemon read. */
export type OneShotQueryFn = (input: {
    ast: unknown;
    name?: string;
    args?: unknown;
    visibilityKey?: string;
    ttlMs?: number;
}) => Promise<OneShotResult>;

OneShotBackend

/**
 * A no-op live backend for SSR (SSR-DESIGN.md §6.1): it opens no transport and never streams.
 * `registerQuery` is inert, `mutate` rejects, and no `ChangeEvent` is pushed. Every view stays
 * PENDING — reading its SSR {@link Store.seedAssembled seed} — and, lacking `onResultType`,
 * reports `complete` (a backend with no server lifecycle leaves every view authoritative).
 */
export declare class OneShotBackend implements Backend {
    registerQuery(_qid: QueryId, _ast: unknown, _remote?: RemoteQuery): void;
    unregisterQuery(_qid: QueryId): void;
    mutate(_mutations: Mutation[]): Promise<void>;
    onEvent(_handler: (queryId: QueryId, event: ChangeEvent) => void): void;
}

ServerStoreOptions

export interface ServerStoreOptions {
    /** Performs an authorized one-shot read. See {@link OneShotQueryFn} for access ownership. */
    query: OneShotQueryFn;
    /** Optional namespace for query deduplication, forwarded to every preload. Different keys
     *  prevent pipeline sharing for the same AST. This key does not authorize access or filter rows;
     *  the query must already contain the required visibility predicates. */
    visibilityKey?: string;
    /** Optional idle TTL (ms) the warm pipeline is left at, forwarded to every preload (SSR-DESIGN.md
     *  §3.4). The TTL is NOT part of the dedup key, so a shared materialization keeps the LONGEST TTL
     *  any caller requested (max-wins) — `ttlMs` can extend a query's warm-handoff window, never
     *  shrink it; absent ⇒ the daemon's default idle TTL. */
    ttlMs?: number;
}

ServerStore

/**
 * The server-side Store wrapper (SSR-DESIGN.md §6.2). Wraps a {@link Store} over a
 * {@link OneShotBackend} and adds the loader-phase `preload` plus `dehydrate`. Pass `.store` to
 * the React `<Rindle>` provider for the synchronous render; return `.dehydrate()` from the loader.
 * Create one instance per request, with an authorized read function for that request's principal.
 * Its snapshots seed views; they do not persist synced rows in the browser database.
 */
export declare class ServerStore<S extends ColsMap> {
    readonly store: Store<S>;
    private readonly schema;
    private readonly opts;
    constructor(schema: Schema<S>, opts: ServerStoreOptions);
    /** Run the one-shot read for `query` and seed its first-paint snapshot (SSR-DESIGN.md §6.2).
     *  Call once per query in the route loader, before the synchronous render. */
    preload(query: Query<any, any, any>): Promise<void>;
    /** The dehydrated first-paint cache for every preloaded query — embed in the HTML, then
     *  `store.hydrate(...)` it in the browser. */
    dehydrate(): DehydratedState;
    /**
     * Loader-phase convenience over {@link preload} + {@link dehydrate}: preload EVERY query (reads run
     * concurrently) and return the dehydrated first-paint cache. Composition keeps this to one read per
     * composed root query — no request waterfall (SSR-DESIGN.md §6.2).
     *
     * A failed read produces no seed for that query and calls `onError`, if provided. Other reads
     * can still supply seeds. The browser must establish its own successful live subscription to
     * obtain the missing data; hydration alone does not retry this read. Without `onError`, the
     * preload failure is silent. An `onError` callback that throws rejects the batch.
     */
    preloadAll(queries: Array<Query<any, any, any>>, opts?: {
        onError?: (query: Query<any, any, any>, err: unknown) => void;
    }): Promise<DehydratedState>;
}

createServerStore

/** Construct a {@link ServerStore} — the one-shot REST Store for server-side rendering. */
export declare function createServerStore<S extends ColsMap>(schema: Schema<S>, opts: ServerStoreOptions): ServerStore<S>;