import { type PageLoadingState, ItemPageIterator, type ItemPageIterationInstance, type ItemPageIterationConfig, type ItemPageIteratorDelegate, type MappedPageItemIterationInstance, type ItemPageLimit } from '@dereekb/rxjs'; import { type DocumentReference, type QueryDocumentSnapshotArray, type QuerySnapshot, type SnapshotListenOptions } from '../types'; import { type Maybe, type ArrayOrValue } from '@dereekb/util'; import { type Observable } from 'rxjs'; import { type FirestoreQueryDriverRef } from '../driver/query'; import { type FirestoreQueryConstraint } from './constraint'; import { type QueryLikeReferenceRef } from '../reference'; import { type LimitedFirestoreDocumentAccessor } from '../accessor/document'; /** * Filter configuration for Firestore query pagination. * * This interface defines how to filter and limit paginated Firestore queries. * It allows specifying both a query limit and additional query constraints. */ export interface FirestoreItemPageIteratorFilter extends ItemPageLimit { /** * Overrides the default limit of items per page, if specified. * * This allows dynamically changing the number of items retrieved in each query * without changing the base configuration. */ readonly limit?: Maybe; /** * Query constraints to apply to the paginated query. * * These can include filtering conditions (where), sorting (orderBy), etc. * Note that some constraints like 'limit' will be handled automatically * and should not be included here. */ readonly constraints?: Maybe>; /** * Whether to infer the end of results when a page returns fewer items than * the requested page size (limit). * * When enabled, if a query returns fewer documents than the limit, the iterator * marks the result as the final page — avoiding an unnecessary extra fetch that * would return zero results. * * Defaults to true. */ readonly inferEndOfResultsFromPageSize?: Maybe; } /** * Base configuration for Firestore query pagination. * * This interface defines the core settings needed for paginated Firestore queries, * including the query reference, driver, and pagination settings. * * @template T - The document data type in the query results */ export interface FirestoreItemPageIterationBaseConfig extends QueryLikeReferenceRef, FirestoreQueryDriverRef, ItemPageLimit { /** * Number of items to retrieve per page in each query. * * This controls the size of each "page" of results. Larger values mean * fewer total queries but more data transferred per query. * * @default 50 */ readonly itemsPerPage?: number; } /** * Complete configuration for Firestore query pagination. * * Combines the base Firestore configuration with the generic pagination configuration, * providing all settings needed for paginated Firestore queries. * * @template T - The document data type in the query results */ export interface FirestoreItemPageIterationConfig extends FirestoreItemPageIterationBaseConfig, ItemPageIterationConfig { } /** * Results from a paginated Firestore query. * * This interface encapsulates the results of a single "page" query in a paginated * Firestore query sequence. It includes both the raw query snapshot and convenient * accessors for the document data, along with methods to reload or stream the results. * * @template T - The document data type in the query results */ export interface FirestoreItemPageQueryResult { /** * Timestamp when the result was retrieved. * * Useful for tracking when data was last fetched or for implementing * time-based caching strategies. */ readonly time: Date; /** * Document snapshots for this page of results. * * This array contains the document snapshots returned by the query, * excluding any cursor document used for pagination. */ readonly docs: QueryDocumentSnapshotArray; /** * The complete query snapshot returned by Firestore. * * This provides access to all metadata and methods of the raw query * snapshot, including size, query information, and document changes. */ readonly snapshot: QuerySnapshot; /** * Reloads the current page of results. * * This method re-executes the exact same query that produced these results, * fetching the latest data from Firestore. Useful for refreshing data * without changing pagination position. * * @returns A promise that resolves with the fresh query snapshot */ reload(): Promise>; /** * Creates an Observable that streams updates to this query. * * This method establishes a real-time listener for the current page query, * emitting new snapshots whenever the underlying data changes. * * @param options - Optional configuration for the snapshot listener * @returns An Observable of query snapshots that updates in real-time */ stream(options?: FirestoreItemPageQueryResultStreamOptions): Observable>; } /** * Options for streaming real-time updates to a Firestore query page. * * This interface allows configuring how the real-time listener behaves * when streaming updates to a page of Firestore query results. */ export interface FirestoreItemPageQueryResultStreamOptions { /** * Optional Firestore snapshot listener options. * * These options control aspects of the snapshot listener like whether to include metadata * changes or wait for a server snapshot. */ readonly options?: Maybe; } /** * Delegate that implements the page loading logic for Firestore pagination. * * Responsible for translating pagination requests into Firestore queries, * managing cursors between pages, and producing {@link FirestoreItemPageQueryResult} values. */ export type FirestoreItemPageIteratorDelegate = ItemPageIteratorDelegate, FirestoreItemPageIteratorFilter, FirestoreItemPageIterationConfig>; /** * Internal pagination instance that works directly with {@link FirestoreItemPageQueryResult}. * * This is the raw iteration instance before mapping to document arrays. It provides * access to snapshot-level data and metadata. Exposed via * {@link FirestoreItemPageIteration.snapshotIteration} for advanced use cases. */ export type InternalFirestoreItemPageIterationInstance = ItemPageIterationInstance, FirestoreItemPageIteratorFilter, FirestoreItemPageIterationConfig>; /** * Filters out constraints that should not be directly specified in pagination queries. * * This utility function removes constraints that would conflict with the pagination * mechanics, such as 'limit' constraints which are automatically added by the paginator. * * @param constraints - Array of query constraints to filter * @returns Filtered array with disallowed constraints removed */ export declare function filterDisallowedFirestoreItemPageIteratorInputConstraints(constraints: FirestoreQueryConstraint[]): FirestoreQueryConstraint[]; /** * Default number of items to retrieve per page in paginated Firestore queries. * * This value is used when no itemsPerPage is explicitly specified in the configuration. */ export declare const DEFAULT_FIRESTORE_ITEM_PAGE_ITERATOR_ITEMS_PER_PAGE = 50; /** * Creates a {@link FirestoreItemPageIteratorDelegate} that handles cursor-based Firestore pagination. * * The delegate implements `loadItemsForPage` by: * 1. Retrieving the cursor document from the previous page's results * 2. Building a query with the configured constraints, `startAfter` cursor, and `limit` * 3. Executing the query and wrapping the results in a {@link FirestoreItemPageQueryResult} * with `reload()` and `stream()` capabilities * * @returns A delegate instance for use with {@link ItemPageIterator} */ export declare function makeFirestoreItemPageIteratorDelegate(): FirestoreItemPageIteratorDelegate; export interface FirestoreItemPageIteration extends MappedPageItemIterationInstance, FirestoreItemPageQueryResult, PageLoadingState>, PageLoadingState>, InternalFirestoreItemPageIterationInstance> { /** * The underlying iteration instance that works with raw query snapshots. * * This provides access to the snapshot-level pagination when needed, which is useful * for accessing metadata or other snapshot-specific features not available in the * mapped document arrays. */ readonly snapshotIteration: InternalFirestoreItemPageIterationInstance; } /** * Instance for paginated iteration over Firestore documents. * * This interface represents a configured paginator for Firestore documents. It extends the * generic mapped page iteration system to work specifically with Firestore documents, * providing both the document arrays and access to the underlying snapshot iteration. * * @template T - The document data type in the query results */ export interface FirestoreItemPageIterationInstance extends FirestoreItemPageIteration { readonly snapshotIteration: InternalFirestoreItemPageIterationInstance; } /** * Factory for creating Firestore pagination instances. * * This interface provides a standardized way to create pagination instances * for Firestore queries with consistent configuration. * * @template T - The document data type in the query results */ export interface FirestoreItemPageIterationFactory { /** * Function that creates pagination instances with consistent base configuration. * * This factory function allows creating multiple pagination instances that share * the same base configuration but can have different filters applied. */ readonly firestoreIteration: FirestoreItemPageIterationFactoryFunction; /** * Function that creates fixed pagination instances with consistent base configuration. */ readonly firestoreFixedIteration: FirestoreFixedItemPageIterationFactoryFunction; } /** * Function that creates a Firestore pagination instance using the specified filter. * * This type represents a factory function that creates pagination instances with * predefined base configuration. The only parameter needed is the filter that specifies * what constraints to apply and how many items to load per page. * * @template T - The document data type in the query results */ export type FirestoreItemPageIterationFactoryFunction = (filter?: FirestoreItemPageIteratorFilter) => FirestoreItemPageIterationInstance; /** * Creates a factory function for generating Firestore pagination instances with consistent base configuration. * * This higher-order function takes a base configuration and returns a specialized factory function * that can create properly configured pagination instances. This is useful when you need to create * multiple pagination instances for the same collection but with different filters. * * @template T - The document data type in the query results * @param baseConfig - The base configuration shared by all created pagination instances * @returns A factory function that creates pagination instances with the specified base configuration * * @example * // Create a factory for paginating users collection * const usersQuery = collection(firestore, 'users'); * const usersPaginator = firestoreItemPageIterationFactory({ * queryLike: usersQuery, * itemsPerPage: 20, * firestoreQueryDriver: driver * }); * * // Create specific pagination instances with different filters * const activePaginator = usersPaginator({ * constraints: [where('status', '==', 'active')] * }); * const adminPaginator = usersPaginator({ * constraints: [where('role', '==', 'admin')] * }); */ export declare function firestoreItemPageIterationFactory(baseConfig: FirestoreItemPageIterationBaseConfig): FirestoreItemPageIterationFactoryFunction; /** * Default delegate that implements Firestore pagination logic. * * This singleton instance handles the core logic of paginated Firestore queries, * including cursor management and document fetching. */ export declare const FIRESTORE_ITEM_PAGE_ITERATOR_DELEGATE: FirestoreItemPageIteratorDelegate; /** * Default iterator that provides Firestore pagination functionality. * * This singleton instance is the core pagination iterator used by the library. * It uses the default delegate to implement paginated Firestore queries. */ export declare const FIRESTORE_ITEM_PAGE_ITERATOR: ItemPageIterator, FirestoreItemPageIteratorFilter, FirestoreItemPageIterationConfig>; /** * Creates a Firestore pagination instance that handles loading documents in pages. * * This function creates a pagination instance that loads Firestore documents in pages, * automatically handling cursor-based pagination. It returns a mapped iteration instance * that directly provides document arrays while also exposing access to the underlying * snapshot iteration. * * @template T - The document data type in the query results * @param config - The configuration for the pagination * @returns A Firestore pagination instance that loads documents in pages * * @example * // Create a pagination instance for a users collection * const usersPagination = firestoreItemPageIteration({ * queryLike: collection(firestore, 'users'), * itemsPerPage: 10, * firestoreQueryDriver: driver, * filter: { * constraints: [where('status', '==', 'active'), orderBy('createdAt', 'desc')] * } * }); * * // Load the first page of results * const firstPage = await usersPagination.loadNextPage().toPromise(); * console.log('First 10 users:', firstPage); * * // Load the next page when needed * const secondPage = await usersPagination.loadNextPage().toPromise(); * console.log('Next 10 users:', secondPage); */ export declare function firestoreItemPageIteration(config: FirestoreItemPageIterationConfig): FirestoreItemPageIterationInstance; /** * Function that creates a Firestore pagination instance using the input items and optional filter. * * This type represents a factory function that creates pagination instances with * predefined base configuration. The only parameter needed is the filter that specifies * what constraints to apply and how many items to load per page. * * @template T - The document data type in the query results */ export type FirestoreFixedItemPageIterationFactoryFunction = (items: DocumentReference[], filter?: FirestoreItemPageIteratorFilter) => FirestoreItemPageIterationInstance; /** * Creates a factory function for generating fixed-set Firestore pagination instances. * * The returned factory takes an array of document references and an optional filter, * producing a pagination instance that iterates over those specific documents in pages. * * @param baseConfig - Base pagination configuration (query reference, driver, page size) * @param documentAccessor - Accessor used to load document snapshots from the references * @returns A factory function that creates fixed-set pagination instances */ export declare function firestoreFixedItemPageIterationFactory(baseConfig: FirestoreItemPageIterationConfig, documentAccessor: LimitedFirestoreDocumentAccessor): FirestoreFixedItemPageIterationFactoryFunction; /** * Configuration for {@link firestoreFixedItemPageIteration}. * * Extends the standard pagination config with a fixed set of document references * and a document accessor to load their snapshots. Instead of querying Firestore, * pagination is simulated by slicing through the provided references array. */ export interface FirestoreFixedItemPageIterationConfig extends FirestoreItemPageIterationConfig { /** * The fixed set of document references to paginate through. * * Documents are loaded in order, sliced into pages of `itemsPerPage` size. */ readonly items: DocumentReference[]; /** * Accessor used to load document snapshots from the references. */ readonly documentAccessor: LimitedFirestoreDocumentAccessor; } /** * Creates a pagination instance that iterates over a fixed set of document references. * * Unlike {@link firestoreItemPageIteration} which queries Firestore dynamically, this function * paginates through a pre-determined list of document references. Each page loads the next * slice of references via the document accessor and produces a synthetic {@link QuerySnapshot}. * * This is useful for paginating over known document sets (e.g., from a pre-computed list * of references) without executing Firestore queries. * * @param config - Configuration including the document references, accessor, and pagination settings * @returns A pagination instance that pages through the fixed reference set */ export declare function firestoreFixedItemPageIteration(config: FirestoreFixedItemPageIterationConfig): FirestoreItemPageIterationInstance;