/** * @module Firestore Query Watcher * * This module provides functionality for watching changes to Firestore query results over time. * It tracks document additions, modifications, and removals, and provides an event-based * system for reacting to these changes in real-time. */ import { type Milliseconds } from '@dereekb/util'; import { type Observable } from 'rxjs'; import { type DocumentChange, type QuerySnapshot } from '../types'; import { type FirestoreItemPageIteration } from './iterator'; /** * Default delay in milliseconds before a query change watcher begins processing events. * * A value of 0 means the watcher will start immediately after the first successful page result. */ export declare const DEFAULT_QUERY_CHANGE_WATCHER_DELAY = 0; /** * Configuration for creating a query document change watcher. * * @template T - The document data type */ export interface IterationQueryDocChangeWatcherConfig { /** * The iteration instance that will be watched for changes. * * This instance provides access to the underlying Firestore query and its results, * which the watcher will monitor for document changes. */ readonly instance: FirestoreItemPageIteration; /** * Optional delay in milliseconds before the watcher begins processing events. * * This delay is applied after the first successful page result is received. * Default is 0 (start immediately). */ readonly delay?: Milliseconds; } /** * Interface for watching query result changes events. * * Provides observables for monitoring changes to Firestore query results over time, * including document additions, modifications, and removals. * * @template T - The document data type */ export interface IterationQueryDocChangeWatcher { /** * Streams all subsequent query snapshots after the initial result. * * This observable emits the raw QuerySnapshot objects from Firestore, * allowing direct access to all query results and their changes. */ readonly stream$: Observable>; /** * Streams processed change events derived from the query snapshots. * * This observable transforms the raw query snapshots into structured event * objects that categorize document changes into added, removed, and modified * groups, making it easier to respond to specific types of changes. */ readonly event$: Observable>; } /** * Event representing a set of changes to a Firestore query result. * * This event captures all document changes that occurred in a single update, * categorized by their type (added, removed, modified) along with metadata * about when the changes occurred and an overall classification of the event. * * @template T - The document data type */ export interface IterationQueryDocChangeWatcherEvent extends IterationQueryDocChangeWatcherChangeGroup { /** * Timestamp when this change event was processed. */ readonly time: Date; /** * Array of all document changes in this event. * * Contains the complete set of changes, regardless of their type. */ readonly changes: DocumentChange[]; /** * Classification of this change event based on the types of changes it contains. * * This provides a quick way to determine the nature of the changes without * examining the individual document changes. */ readonly type: IterationQueryDocChangeWatcherChangeType; } /** * Group of document changes categorized by their change type. * * This interface organizes document changes into three distinct categories: * added, removed, and modified, making it easier to process changes based * on their type. * * @template T - The document data type */ export interface IterationQueryDocChangeWatcherChangeGroup { /** * Documents that were newly added to the query results. */ readonly added: DocumentChange[]; /** * Documents that were removed from the query results. */ readonly removed: DocumentChange[]; /** * Documents that remained in the query results but had their data modified. */ readonly modified: DocumentChange[]; } /** * Classification of a change event based on the types of document changes it contains. * * - 'addedAndRemoved': Both additions and removals occurred * - 'added': Only additions occurred * - 'removed': Only removals occurred * - 'modified': Only modifications occurred * - 'none': No changes occurred */ export type IterationQueryDocChangeWatcherChangeType = 'addedAndRemoved' | 'added' | 'removed' | 'modified' | 'none'; /** * Creates a watcher for monitoring changes to Firestore query results. * * This function sets up observables that track document changes (additions, removals, * and modifications) in the results of a Firestore query over time. It provides both * raw query snapshots and processed change events, making it easier to react to * specific types of changes. * * @template T - The document data type * @param config - Configuration for the watcher, including the iteration instance to watch * and an optional delay before starting to monitor changes * @returns A watcher object with observables for streaming changes * * @example * // Create a watcher for changes to active users * const usersIterator = firestoreItemPageIterator({ * queryFactory: () => collection(firestore, 'users').where('status', '==', 'active'), * pageSize: 10 * }); * * const watcher = iterationQueryDocChangeWatcher({ * instance: usersIterator, * delay: 1000 // wait 1 second after first results before watching for changes * }); * * // React to specific change types * watcher.event$.subscribe(event => { * if (event.type === 'added') { * console.log('New users added:', event.added.map(change => change.doc.data())); * } * }); */ export declare function iterationQueryDocChangeWatcher(config: IterationQueryDocChangeWatcherConfig): IterationQueryDocChangeWatcher; /** * Determines the overall change type for a group of document changes. * * This function analyzes a change group to classify it based on the types of changes * it contains. It follows a priority order for classification: * 1. If both additions and removals are present, classify as 'addedAndRemoved'. * 2. If only additions are present, classify as 'added'. * 3. If only removals are present, classify as 'removed'. * 4. If only modifications are present, classify as 'modified'. * 5. If no changes are present, classify as 'none'. * * @template T - The document data type * @param group - The change group to classify * @returns The overall change type classification */ export declare function iterationQueryDocChangeWatcherChangeTypeForGroup(group: IterationQueryDocChangeWatcherChangeGroup): IterationQueryDocChangeWatcherChangeType;