Rindle

API index and search · Build metadata

Supporting declarations

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

Exact source

WS_SUBPROTOCOL

/** The base ws subprotocol the browser offers alongside its `aff.*` ticket; the fleet follower
 *  echoes it on the 101 (a strict browser closes a socket whose selected subprotocol it never
 *  offered, so the base is always offered in affinity mode). Inlined — NOT imported from
 *  `@rindle/affinity`'s `WS_SUBPROTOCOL` — to keep that crate's `node:crypto` out of the browser
 *  bundle (the same duplicate-to-stay-bundle-clean discipline the lease wire types use). Keep the
 *  two spellings in lock-step. */
export declare const WS_SUBPROTOCOL = "rindle.v1";

AffinityTicketStore

/** A mutable holder for the current opaque affinity ticket, shared by the transport, the source,
 *  and the lease POST (see the module header). */
export interface AffinityTicketStore {
    /** The ticket to offer on the next ws handshake, or undefined — ticketless, so the edge
     *  anycasts + mints a fresh one. A persisted/previous-connection ticket may be returned here
     *  even while it is NOT yet safe for a lease; see {@link leaseTicket}. */
    get(): string | undefined;
    /** Record a freshly minted/refreshed ticket (from a connection's `{t:"affinity"}` frame). */
    set(ticket: string): void;
    /** Drop the ticket so the next connect goes ticketless (the pinned follower is gone, §8). */
    clear(): void;
    /** Mark the held ticket handshake-only until this connection emits a fresh mint frame. Called
     *  before the first connection and every reconnect, after the held ticket was already selected
     *  for the ws subprotocol offer. This prevents a restored/rotated/expired persisted ticket from
     *  racing an HTTP lease onto an independently-anycast follower. */
    connectionPending(): void;
    /** Resolve with a ticket minted/refreshed on the CURRENT connection, or the next one
     *  {@link set}. A persisted ticket deliberately does not resolve this wait. */
    waitForTicket(): Promise<string>;
    /** Obtain the current connection's ticket for an HTTP lease. The first missing-ticket wait is
     *  bounded; its timeout removes the waiter and latches ticketless fallback, so later leases
     *  return immediately until a mint frame arrives. Concurrent callers share the one timer.
     *  `timedOut` is true only for that transition, allowing one warning per fallback episode. */
    leaseTicket(timeoutMs: number): Promise<{
        ticket?: string;
        timedOut: boolean;
    }>;
}

TicketPersistence

/** Where a store persists the ticket across reloads. The browser backs this with sessionStorage
 *  (per-TAB, so two tabs can pin two regions — design §13); tests pass none (pure in-memory). */
export interface TicketPersistence {
    load(): string | undefined;
    save(ticket: string): void;
    clear(): void;
}

createAffinityTicketStore

/** Build an {@link AffinityTicketStore}, optionally persisted. Pure/in-memory when `persist` is
 *  omitted. */
export declare function createAffinityTicketStore(persist?: TicketPersistence): AffinityTicketStore;

offerSubprotocols

/** The subprotocol list to offer for one connection: the base protocol always, plus the held ticket
 *  (already an `aff.<…>` token) when one exists. */
export declare function offerSubprotocols(store: AffinityTicketStore): string[];