import type { PaginatedResult } from '../models/PaginatedResult';
/**
 * Per-layer pagination state, carried across pages inside the composite
 * page token. `cursor` is the layer's own opaque page token; `resumeAfterId`
 * is the id of the last item from this layer kept on the previous page (in
 * the layer's own order). `exhausted` becomes true once a layer has nothing
 * more to give and we've already returned everything it contributed.
 */
interface SourceState {
    cursor?: string;
    resumeAfterId?: string;
    exhausted: boolean;
}
/**
 * Internal state tracked across pages when federating results from multiple
 * persistence layers. Serialized as base64(JSON(...)) into the composite
 * page token.
 */
interface FederatedPaginationState {
    sources: SourceState[];
}
export declare function createCompositePageToken(state: FederatedPaginationState): string;
export declare function parseCompositePageToken(token?: string): FederatedPaginationState;
/**
 * Federate a paginated listing across multiple persistence layers
 * (resume-by-id).
 *
 * Each layer holds an opaque cursor and an optional `resumeAfterId`. On
 * each page request, federation fetches from each non-exhausted layer
 * (advancing through batches as needed until it has at least `limit`
 * candidates per layer), stable-sorts the merged contributions with the
 * caller's `comparator`, and trims to `limit`. For each layer, the
 * **last kept item in that layer's order** becomes the new
 * `resumeAfterId`, with `cursor` set to the layer-token used to fetch
 * that item's batch. Layers whose contribution is wholly dropped by the
 * trim retain their pre-call state so their items remain reachable on
 * later pages.
 *
 * **Critical contract: the comparator must NOT tiebreak by id.** Ties
 * on the sort key must return 0 from `comparator`. `Array.sort` is
 * stable since ES2019, and federation feeds the merge in
 * `[layer0..., layer1..., ...]` insertion order, so ties resolve by
 * `(layerIndex, layer-internal position)` — exactly the property that
 * keeps each layer's kept items as a *prefix* of its own order, which
 * is what makes a single `resumeAfterId` representable. An id
 * tiebreaker would silently break this and lose items.
 *
 * **Layer contract.** Layers must return the same items in the same
 * order for the same `(query, pageToken)` pair across calls. Their
 * internal ordering does not need to match federation's tiebreaker —
 * just be deterministic.
 */
export declare function federatedList<TQuery extends {
    limit?: number;
    pageToken?: string;
}, TItem extends {
    id: string;
}>(layers: {
    getItems: (query: TQuery) => Promise<PaginatedResult<TItem>>;
}[], query: TQuery, comparator: (a: TItem, b: TItem) => number): Promise<PaginatedResult<TItem>>;
export {};
//# sourceMappingURL=FederatedPagination.d.ts.map