/** * Shared mailbox utility helpers. * * This module keeps the mailbox ownership and routing rules that multiple * higher-level components rely on: * - `MailboxDirector` needs topic keys and cursor helpers * - `Poster` and mailbox pollers need endpoint selection rules * - the HTTP server needs hosted-endpoint and base-path resolution * * KERIpy correspondence: * - these helpers gather logic that is split across mailbox, forwarding, and * indirect-mode support in KERIpy * * Current `keri-ts` difference: * - endpoint base-path resolution is explicit here because the Fetch/Node host * layer serves both root and non-root mailbox/OOBI paths */ import type { Operation } from "effection"; import { type Mailboxer, type MailboxerOptions } from "../db/mailboxing.js"; import type { OutboxerLike } from "../db/outboxing.js"; import type { Hab, Habery } from "./habbing.js"; /** * Derive mailbox open options from one existing habery. * * This is the supported bridge from core habery state to the additive * provider-side mailbox store lifecycle. */ export declare function mailboxerOptionsForHabery(hby: Habery, options?: Partial): MailboxerOptions; /** * Open the provider-side mailbox sidecar corresponding to one habery. * * Ownership rule: * - this helper only derives open settings from habery state * - the caller that opens the mailboxer owns its lifecycle */ export declare function openMailboxerForHabery(hby: Habery, options?: Partial): Operation; /** Return the habery-owned sender retry sidecar when enabled. */ export declare function getOutboxer(hby: Habery): OutboxerLike; /** * Build the stored mailbox topic key used by KERIpy-style mailbox storage. * * Topic buckets are normalized as `pre/topic`, with `topic` already carrying * the leading slash when it is a protocol mailbox topic like `/challenge`. */ export declare function mailboxTopicKey(pre: string, topic: string): string; /** * Build the next `mbx` query cursor map for one `(pre, eid)` remote mailbox. * * Cursor records store the last seen ordinal, while mailbox queries ask for * the next ordinal wanted. */ export declare function mailboxQueryTopics(hby: Habery, pre: string, witness: string, topics: Iterable): Record; /** * Persist one consumed remote mailbox index for one `(pre, eid, topic)` tuple. * * These cursors live in `Baser.tops` because they describe the consumer's * remote poll progress, not the provider's stored inbox contents. */ export declare function updateMailboxRemoteCursor(hby: Habery, pre: string, witness: string, topic: string, idx: number): void; /** * Return the remote mailbox or witness endpoints a local habitat should poll. * * KERIpy parity rule: * - mailbox role endpoints take precedence when authorized * - otherwise poll one witness mailbox endpoint * * The result is intentionally already flattened to one preferred URL per * endpoint identifier so runtime pollers can stay focused on mailbox protocol * work instead of URL selection policy. */ export declare function mailboxPollEndpoints(hby: Habery, hab: Hab): Array<{ key: string; eid: string; url: string; }>; /** * Return the currently authorized mailbox endpoints for one remote recipient. * * `Poster` treats this as the mailbox-first broadcast target set. */ export declare function mailboxDeliveryEndpoints(hab: Hab, recipient: string): Array<{ eid: string; url: string; }>; /** * Return the direct controller and agent endpoints for one remote recipient. * * These are fallback transport targets only when no mailbox endpoints are * configured or when the caller explicitly forces direct delivery. */ export declare function directDeliveryEndpoints(hab: Hab, recipient: string): Array<{ eid: string; url: string; }>; /** * Read one endpoint's currently stored URLs directly from shared DB state. * * This stays DB-oriented on purpose so CLI, server, and forwarding code can * inspect authoritative location state without carrying a second cache. */ export declare function fetchEndpointUrls(hby: Habery, eid: string, scheme?: string): Record; /** One locally hosted endpoint plus its advertised preferred URL and base path. */ export interface HostedEndpoint { eid: string; url: string; basePath: string; } /** * One hosted endpoint match plus the request path relative to its base path. * * The relative path always starts with `/`, so callers can route mailbox admin * and OOBI resources without reparsing the original absolute request path. */ export interface HostedEndpointPathMatch extends HostedEndpoint { relativePath: string; } /** * One hosted-route lookup result used by HTTP route classifiers. * * Resolution policy: * - no matching hosted endpoint returns `kind: "none"` * - one longest-base-path match returns `kind: "one"` * - ties on the longest base path stay explicit as `kind: "ambiguous"` * * The route layer depends on ambiguity staying first-class. Returning `null` * here would force later code to guess whether "not found" and "matched more * than one hosted AID" mean the same thing. They do not. */ export interface HostedRouteResolution { kind: "none" | "one" | "ambiguous"; endpoint: HostedEndpointPathMatch | null; relativePath: string | null; } /** * Resolve which locally hosted endpoint URL a request path targets. * * Matching rule: * - compare the request path against each local prefix's preferred endpoint URL * - optionally append a resource suffix like `/mailboxes` * - when more than one local endpoint matches, the caller must treat that as * ambiguous instead of guessing */ export declare function hostedEndpointMatches(hby: Habery, pathname: string, resourceSuffix?: string, eids?: Iterable): HostedEndpoint[]; /** * Resolve one hosted endpoint or return `null` when missing or ambiguous. * * Callers that need ambiguity details should use `hostedEndpointPathMatches()` * directly. */ export declare function hostedEndpointForPath(hby: Habery, pathname: string, resourceSuffix?: string, eids?: Iterable): HostedEndpoint | null; /** * Resolve all locally hosted endpoints whose advertised base path prefixes the * current request path. * * Matching policy: * - root-hosted endpoints match every absolute request path * - non-root endpoints match their exact base path or any subpath beneath it * - callers should prefer the longest matching base path and treat ties as * ambiguous instead of guessing */ export declare function hostedEndpointPathMatches(hby: Habery, pathname: string, eids?: Iterable): HostedEndpointPathMatch[]; /** * Resolve one hosted route using longest-base-path semantics. * * Callers may optionally require an exact relative resource suffix such as * `/mailboxes` or `/` while still preserving ambiguity as an explicit result. * * This is the shared answer to "which hosted local AID did this request path * hit?" Keeping it here means `protocol-handler.ts` can reason in terms of * explicit route matches while `server.ts` stays out of endpoint-selection * policy entirely. */ export declare function resolveHostedEndpointPath(hby: Habery, pathname: string, resourceSuffix?: string, eids?: Iterable): HostedRouteResolution; /** * Flatten role endpoint maps to one preferred URL per endpoint identifier. * * This converts stored end-role location shape into the transport-ready tuples * used by forwarding and polling logic. */ export declare function flattenRoleUrls(roleUrls?: Record>): Array<{ eid: string; url: string; }>; /** * Return the deterministic first preferred endpoint from one role map. * * Witness polling intentionally uses a stable choice instead of a randomized * one so local cursor progression is deterministic. */ export declare function firstSortedEndpoint(roleUrls?: Record>): { eid: string; url: string; } | null; /** * Return the preferred URL for one endpoint location set. * * HTTPS wins when present because mailbox and admin URLs are externally * advertised endpoints. */ export declare function preferredUrl(urls: Record): string | null; /** * Extract the normalized base path from one endpoint URL. * * Mailbox and OOBI hosts serve routes relative to this base path, not only * from `/`. */ export declare function endpointBasePath(url: string): string; //# sourceMappingURL=mailboxing.d.ts.map