/** * Runtime-composed mailbox publication, query, and stream coordination. * * KERIpy correspondence: * - gathers responsibilities that KERIpy spreads across `Mailboxer`, * mailbox iterables, and indirect-mode query handling * * Boundary rule: * - this module is mailbox storage/query infrastructure, not the general * responder path * - non-`stream` cue delivery such as `reply`, `replay`, `receipt`, and * `witness` belongs in `Respondant` * * Current `keri-ts` difference: * - one runtime host receives an explicit mailbox sidecar instead of * discovering mailbox storage through `Habery` */ import type { StreamCue } from "../core/cues.js"; import { Deck } from "../core/deck.js"; import type { MbxTopicCursor } from "../core/mailbox-topics.js"; import type { Mailboxer } from "../db/mailboxing.js"; import type { Habery } from "./habbing.js"; /** * Mailbox topic director for one runtime host. * * Responsibilities: * - retain mailbox stream requests so protocol hosts can answer `mbx` queries * - expose ordered topic iteration backed by the dedicated `Mailboxer` and * durable remote cursor state in `tops.` * - publish only explicitly forwarded mailbox payloads such as authorized * `/fwd` deliveries * * Non-responsibilities: * - do not absorb generic non-`stream` cue emissions as implicit local mailbox * side effects * - do not replace `Respondant` / `Poster` endpoint delivery * * KERIpy correspondence: * - coordinates the storage/query slice around `Mailboxer` and * `MailboxIterable` */ export declare class MailboxDirector { readonly hby: Habery; readonly mailboxer: Mailboxer | null; readonly queryCues: Deck; readonly topics: Set; private activeMailboxAid; constructor(hby: Habery, { mailboxer, queryCues, topics, }?: { mailboxer?: Mailboxer; queryCues?: Deck; topics?: readonly string[]; }); /** Return true when provider-side mailbox storage is available. */ hasMailboxStore(): boolean; /** Register one mailbox topic this runtime should poll/stream. */ registerTopic(topic: string): void; /** * Run one request-scoped block with the addressed hosted mailbox AID set. * * `/fwd` handling needs this so it can verify mailbox authorization against * the mailbox AID that actually received the request instead of guessing from * payload contents alone. */ withActiveMailboxAid(aid: string | null, fn: () => T): T; /** * Return the mailbox AID currently associated with the in-flight request, if * any. */ currentMailboxAid(): string | null; /** Snapshot the currently configured mailbox topic set. */ registeredTopics(): string[]; /** Retain one mailbox-query `stream` cue for later HTTP/SSE correlation. */ retainQueryCue(cue: StreamCue): void; /** * Persist one outbound mailbox payload under the ordered topic bucket for * `pre/topic`. * * The returned index is the newly assigned mailbox event id for that topic. */ publish(pre: string, topic: string, msg: Uint8Array): number; /** Return the latest stored publication index for one topic, or `-1`. */ lastIndex(pre: string, topic: string): number; /** * Return ordered topic payloads starting at the provided insertion index. * * The returned index is the mailbox event id that should be reflected in the * SSE `id:` field for the emitted message. */ topicIter(pre: string, topic: string, from?: number): Generator<{ idx: number; msg: Uint8Array; }>; /** * Return a server-sent-event stream over mailbox topics until the idle window * expires. * * SSE policy: * - emit one initial `retry:` hint * - stream ordered mailbox payloads as `id/event/data` * - close once the idle window expires without new mailbox traffic */ streamMailbox(pre: string, topicCursor: MbxTopicCursor, { retryMs, pollIntervalMs, idleTimeoutMs, emitRetryHeader, }?: { retryMs?: number; pollIntervalMs?: number; idleTimeoutMs?: number | null; emitRetryHeader?: boolean; }): ReadableStream; /** * Return a KERIpy-style long-lived SSE response for one posted `qry`. * * Correlation rule: * - emit the initial `retry:` hint immediately * - wait until a matching `stream` cue for the query SAID appears * - once matched, proxy the normal mailbox iterable for that cue * * This mirrors KERIpy `QryRpyMailboxIterable` ownership closely: the HTTP * route does not guess mailbox topics itself; it waits for mailbox query * correlation to tell it what to stream. */ streamQueryResponse(said: string, { retryMs, pollIntervalMs, }?: { retryMs?: number; pollIntervalMs?: number; }): ReadableStream; /** * Build the next `mbx` query cursor map for one `(pre, witness)` pair. * * Stored cursor rows track the last seen index, while the wire query asks for * the next wanted index. */ remoteQueryCursor(pre: string, witness: string): Record; /** Persist one consumed remote mailbox index for one `(pre, witness, topic)`. */ updateRemoteCursor(pre: string, witness: string, topic: string, idx: number): void; /** * Check whether the runtime has seen a matching `stream` cue for one query * SAID without discarding other pending query cues. * * This keeps query correlation observable without consuming cues that later * host work still needs. */ hasQueryCue(said: string): boolean; /** Remove and return the next queued `stream` cue for one query SAID. */ private takeQueryCue; /** Require provider mailbox storage for publication or mailbox serving. */ private requireMailboxer; } //# sourceMappingURL=mailbox-director.d.ts.map