donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
62 lines • 2.85 kB
TypeScript
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