/** * @dotdo/tanstack - TanStack DB Integration for PostgreSQL * * A comprehensive local-first data synchronization library that integrates * TanStack Query patterns with PostgreSQL and PGLite backends. * * @packageDocumentation * * ## Quick Start * * ```typescript * import { createQueryAdapter, createSyncCollection } from '@dotdo/tanstack' * * // Connect to postgres.do * const adapter = createQueryAdapter({ database: 'myapp' }) * const { data } = useQuery(adapter.queryOptions('SELECT * FROM users')) * * // Or use local-first sync * const todos = createSyncCollection({ * id: 'todos', * table: 'todos', * syncUrl: 'https://api.example.com/sync', * }) * await todos.connect() * ``` * * ## Key Features * * - **TanStack Query v5 Integration** - Seamless useQuery/useMutation patterns * - **Local-First Sync** - Offline support with background synchronization * - **Optimistic Updates** - Instant UI updates with automatic rollback * - **Conflict Resolution** - Built-in strategies (local-wins, remote-wins, merge) * - **PGLite Support** - Run PostgreSQL entirely in WebAssembly * - **Framework Agnostic** - Hook factories work with React, Vue, Solid, etc. * * ## Architecture * * The package is organized into several modules: * * - **Collections** - QueryCollection, SyncCollection, PGLiteCollection * - **Adapter** - TanStack Query v5 adapter for postgres.do * - **Optimistic** - Optimistic update management with rollback * - **Conflict** - Conflict detection and resolution strategies * - **Hooks** - React hook factories for TanStack Query integration * * @see https://electric-sql.com/blog/2025/07/29/local-first-sync-with-tanstack-db * @see https://tanstack.com/query/v5 * @see https://postgres.do */ // ============================================================================ // Core Types // ============================================================================ /** * Core types for collections, sync state, and data records. * * @category Core Types */ export type { /** Base interface for all collection records - requires an `id` field */ BaseRecord, /** Common options shared by all collection types */ CollectionOptions, /** Options for QueryCollection (caching, stale time, refetch) */ QueryCollectionOptions, /** Options for SyncCollection (sync URL, polling, shape params) */ SyncCollectionOptions, /** Options for reactive live queries with filtering/sorting */ LiveQueryOptions, /** Options for mutation operations */ MutationOptions, /** State tracking for optimistic updates */ OptimisticState, /** A mutation waiting to be sent to the server */ PendingMutation, /** A mutation that has been applied locally, awaiting confirmation */ AppliedMutation, /** Types of conflicts that can occur during sync */ ConflictType, /** Full conflict information for resolution */ Conflict, /** Built-in conflict resolution strategy names */ ConflictStrategy, /** Custom conflict resolver function signature */ ConflictResolver, /** Current synchronization state for a collection */ SyncState, /** Options for PGLiteCollection (local database) */ PGLiteCollectionOptions, /** Minimal PGLite interface for type safety */ PGLiteInterface, /** Standard collection interface with CRUD operations */ Collection, /** Multi-collection store interface */ TanStackStore, } from './types' // ============================================================================ // Collections // ============================================================================ /** * QueryCollection - TanStack Query-style data fetching with caching. * * Use when you need: * - Server-side data with automatic caching * - Stale-while-revalidate patterns * - Auto-refetch at intervals * * @category Collections */ export { createQueryCollection, QueryCollection, } from './query/index' /** * SyncCollection - Local-first sync with background synchronization. * * Use when you need: * - Offline support with sync on reconnect * - Real-time updates via polling * - Optimistic mutations with pending tracking * * @category Collections */ export { createSyncCollection, SyncCollection, SyncEngine, } from './sync/index' /** * PGLiteCollection - Collections backed by local PGLite database. * * Use when you need: * - Full PostgreSQL locally in WebAssembly * - Complex queries and joins * - No network dependency * * @category Collections */ export { createPGLiteCollection, PGLiteCollection, PGLiteStore, } from './pglite/index' // ============================================================================ // Optimistic Updates // ============================================================================ /** * Optimistic update utilities for instant UI feedback. * * Apply changes immediately, then rollback if the server rejects them. * * @category Optimistic Updates */ export { /** Create a new optimistic store for a collection */ createOptimisticStore, /** OptimisticStore class for managing optimistic state */ OptimisticStore, /** Apply an optimistic update to a data map (immutably) */ applyOptimisticUpdate, /** Rollback an optimistic update (immutably) */ rollbackOptimisticUpdate, } from './optimistic/index' // ============================================================================ // Conflict Resolution // ============================================================================ /** * Conflict detection and resolution for sync operations. * * Built-in strategies: local-wins, remote-wins, latest-wins, merge, manual. * * @category Conflict Resolution */ export { /** Detect if a conflict exists between local and remote changes */ detectConflict, /** Resolve a conflict using a strategy or custom resolver */ resolveConflict, /** Create a conflict resolver function from a strategy */ createConflictResolver, /** Builder for creating custom conflict resolvers with multiple rules */ ConflictResolverBuilder, /** Built-in conflict resolution strategy functions */ strategies, } from './conflict/index' // ============================================================================ // Store Factory // ============================================================================ /** * Create a unified store managing multiple collections. * * @category Store */ export { createTanStackStore } from './store' // ============================================================================ // TanStack Query v5 Adapter // ============================================================================ /** * TanStack Query v5 adapter for postgres.do integration. * * Provides query/mutation options factories that work directly with * TanStack Query's useQuery and useMutation hooks. * * @category TanStack Query Adapter */ export { /** TanStack Query adapter for postgres.do */ QueryAdapter, /** Factory to create a query adapter */ createQueryAdapter, /** Generate a query key from database, SQL, and params */ createQueryKey, /** Normalize SQL for consistent query key generation */ normalizeSQL, /** Normalize query params (string or object) into a QueryParams object */ normalizeQueryParams, /** Extract table names from SQL for invalidation */ extractTablesFromSQL, /** Determine mutation type (insert/update/delete) from SQL */ getMutationType, /** Check if SQL is a read-only query (SELECT/WITH) */ isReadOnlyQuery, /** Filter collection items by partial object match */ filterByPartialMatch, /** Sort collection items by a field and direction */ sortByField, /** Apply offset/limit pagination to an array */ applyPagination, /** Create TanStack Query options from a collection */ createCollectionQueryOptions, /** Create TanStack mutation options from a collection */ createCollectionMutationOptions, } from './adapter' /** * Types for the TanStack Query adapter. * * @category TanStack Query Adapter */ export type { /** Query key structure: ['postgres', database, sql, ...params] */ PostgresQueryKey, /** Configuration for creating a query adapter */ QueryAdapterConfig, /** Parameters for SELECT queries */ QueryParams, /** Parameters for INSERT/UPDATE/DELETE mutations */ MutationParams, /** Context passed through mutation lifecycle */ MutationContext, /** Result from a postgres.do query */ QueryResult, /** Query options compatible with TanStack Query v5 */ PostgresQueryOptions, /** Mutation options compatible with TanStack Query v5 */ PostgresMutationOptions, /** Pattern for cache invalidation after mutations */ InvalidationPattern, /** Options for creating collection query options */ CollectionQueryOptions, } from './adapter' // ============================================================================ // React Hook Factories // ============================================================================ /** * Hook factories for creating framework-specific hooks. * * These factories accept TanStack Query hooks and return postgres.do-specific * hooks. This pattern enables framework-agnostic code. * * @example * ```typescript * // Create hooks (do this once at app initialization) * import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' * import { useSyncExternalStore } from 'react' * * const usePostgresQuery = createUsePostgresQuery(useQuery) * const usePostgresMutation = createUsePostgresMutation(useMutation, useQueryClient) * const useLiveQuery = createUseLiveQuery(useSyncExternalStore) * ``` * * @category React Hooks */ export { /** Create a usePostgresQuery hook for SQL queries */ createUsePostgresQuery, /** Create a usePostgresMutation hook for SQL mutations */ createUsePostgresMutation, /** Create a useLiveQuery hook for reactive collection queries */ createUseLiveQuery, /** Create a useCollectionInsert hook for insert operations */ createUseCollectionInsert, /** Create a useCollectionUpdate hook for update operations */ createUseCollectionUpdate, /** Create a useCollectionDelete hook for delete operations */ createUseCollectionDelete, /** Create a usePrefetchQuery hook for prefetching */ createUsePrefetchQuery, /** Create a useInvalidateQueries hook for cache invalidation */ createUseInvalidateQueries, } from './hooks' /** * Types for React hooks. * * @category React Hooks */ export type { /** Query state returned by usePostgresQuery */ PostgresQueryState, /** Mutation state returned by usePostgresMutation */ PostgresMutationState, /** Options for usePostgresQuery hook */ UsePostgresQueryOptions, /** Options for usePostgresMutation hook */ UsePostgresMutationOptions, /** Options for useLiveQuery hook */ UseLiveQueryOptions, /** State returned by useLiveQuery */ LiveQueryState, /** Full result type for usePostgresQuery */ UsePostgresQueryResult, /** Full result type for usePostgresMutation */ UsePostgresMutationResult, } from './hooks'