pbtsdb 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger.ts","../src/subscription-manager.ts","../src/provider.tsx","../src/collection.ts"],"names":["collectionPromises"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Logger interface for subscription events and internal operations.\n * Users can provide their own implementation to integrate with external logging services.\n */\nexport interface Logger {\n /**\n * Log debug-level messages (typically only shown in development).\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n debug: (msg: string, context?: object) => void;\n\n /**\n * Log warning-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n warn: (msg: string, context?: object) => void;\n\n /**\n * Log error-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n error: (msg: string, context?: object) => void;\n}\n\n/**\n * Default console-based logger implementation.\n * Only logs debug messages in development mode.\n */\nconst defaultLogger: Logger = {\n debug: (msg: string, context?: object) => {\n // Only log debug in development\n if (process.env.NODE_ENV === 'development') {\n // biome-ignore lint/suspicious/noConsoleLog: Debug logging is acceptable in development\n console.log(`[pbtsdb] ${msg}`, context || '');\n }\n },\n warn: (msg: string, context?: object) => {\n // biome-ignore lint/suspicious/noConsoleLog: Warning logging is acceptable\n console.warn(`[pbtsdb] ${msg}`, context || '');\n },\n error: (msg: string, context?: object) => {\n // biome-ignore lint/suspicious/noConsoleLog: Error logging is acceptable\n console.error(`[pbtsdb] ${msg}`, context || '');\n },\n};\n\n/**\n * Current logger instance (can be replaced by users).\n */\nlet currentLogger: Logger = defaultLogger;\n\n/**\n * Internal logger instance used by the library.\n */\nexport const logger: Logger = {\n debug: (msg: string, context?: object) => currentLogger.debug(msg, context),\n warn: (msg: string, context?: object) => currentLogger.warn(msg, context),\n error: (msg: string, context?: object) => currentLogger.error(msg, context),\n};\n\n/**\n * Set a custom logger implementation.\n * This allows users to integrate with their own logging services (e.g., Sentry, LogRocket, etc.).\n *\n * @param customLogger - The custom logger implementation\n *\n * @example\n * ```ts\n * import { setLogger } from 'pocketbase-tanstack-db';\n *\n * // Example: Integration with a custom logging service\n * setLogger({\n * debug: (msg, context) => {\n * myLogger.debug(msg, context);\n * },\n * warn: (msg, context) => {\n * myLogger.warn(msg, context);\n * },\n * error: (msg, context) => {\n * myLogger.error(msg, context);\n * // Also send to error tracking service\n * Sentry.captureMessage(msg, { level: 'error', extra: context });\n * },\n * });\n * ```\n *\n * @example\n * ```ts\n * // Example: Disable all logging\n * setLogger({\n * debug: () => {},\n * warn: () => {},\n * error: () => {},\n * });\n * ```\n */\nexport function setLogger(customLogger: Logger): void {\n currentLogger = customLogger;\n}\n\n/**\n * Reset the logger to the default implementation.\n */\nexport function resetLogger(): void {\n currentLogger = defaultLogger;\n}\n","import PocketBase from 'pocketbase';\nimport type { UnsubscribeFunc } from 'pocketbase';\nimport type { Collection } from \"@tanstack/db\"\nimport type { RealtimeEvent, SubscriptionState } from './types';\nimport { logger } from './logger';\n\nexport const SUBSCRIPTION_CONFIG = {\n MAX_RECONNECT_ATTEMPTS: 5,\n BASE_RECONNECT_DELAY_MS: 1000,\n DEFAULT_WAIT_TIMEOUT_MS: 5000,\n CLEANUP_DELAY_MS: 5000,\n} as const;\n\nfunction hasId(record: unknown): record is { id: string } {\n return typeof record === 'object'\n && record !== null\n && 'id' in record\n && typeof (record as { id: unknown }).id === 'string';\n}\n\nfunction createPendingSubscriptionState(recordId?: string): SubscriptionState {\n return {\n unsubscribe: async () => {},\n recordId,\n reconnectAttempts: 0,\n isReconnecting: false,\n };\n}\n\nfunction getSubscriptionKey(recordId?: string): string {\n return recordId || '*';\n}\n\n\n/**\n * Manages real-time subscriptions to PocketBase collections.\n * Handles subscription lifecycle, reconnection with exponential backoff,\n * and automatic synchronization with TanStack DB collections.\n *\n * Subscriptions are automatically managed based on TanStack DB's subscriber count:\n * - Start subscribing when first query becomes active\n * - Stop subscribing when last query becomes inactive (with cleanup delay)\n */\nexport class SubscriptionManager {\n private subscriptions: Map<string, Map<string, SubscriptionState>> = new Map();\n private subscriptionPromises: Map<string, Map<string, Promise<void>>> = new Map();\n private cleanupTimers: Map<string, NodeJS.Timeout> = new Map();\n private subscriberCounts: Map<string, number> = new Map();\n\n constructor(private pocketbase: PocketBase) {}\n\n // ============================================================================\n // Internal Helpers\n // ============================================================================\n\n private async setupSubscription<T extends object>(\n collectionName: string,\n collection: Collection<T>,\n recordId?: string\n ): Promise<UnsubscribeFunc> {\n const subscriptionKey = getSubscriptionKey(recordId);\n\n const eventHandler = (event: RealtimeEvent<T>) => {\n collection.utils.writeBatch(() => {\n switch (event.action) {\n case 'create':\n collection.utils.writeInsert(event.record);\n break;\n case 'update':\n collection.utils.writeUpdate(event.record);\n break;\n case 'delete':\n if (!hasId(event.record)) {\n logger.error('Delete event record missing id field', {\n collectionName,\n record: event.record\n });\n return;\n }\n collection.utils.writeDelete(event.record.id);\n break;\n }\n });\n };\n\n const unsubscribe = await this.pocketbase\n .collection(collectionName)\n .subscribe(subscriptionKey, eventHandler);\n\n logger.debug('Subscription established', { collectionName, subscriptionKey });\n\n return unsubscribe;\n }\n\n private async handleReconnection<T extends object>(\n collectionName: string,\n collection: Collection<T>,\n recordId?: string\n ): Promise<void> {\n const collectionSubs = this.subscriptions.get(collectionName);\n if (!collectionSubs) return;\n\n const subscriptionKey = getSubscriptionKey(recordId);\n const state = collectionSubs.get(subscriptionKey);\n if (!state || state.isReconnecting) return;\n\n state.isReconnecting = true;\n logger.warn('Starting reconnection attempts', { collectionName, subscriptionKey });\n\n while (state.reconnectAttempts < SUBSCRIPTION_CONFIG.MAX_RECONNECT_ATTEMPTS) {\n const delay = SUBSCRIPTION_CONFIG.BASE_RECONNECT_DELAY_MS * Math.pow(2, state.reconnectAttempts);\n logger.debug(`Reconnection attempt ${state.reconnectAttempts + 1}, waiting ${delay}ms`, {\n collectionName,\n subscriptionKey\n });\n await new Promise(resolve => setTimeout(resolve, delay));\n\n try {\n const newUnsubscribe = await this.setupSubscription(\n collectionName,\n collection,\n recordId\n );\n\n state.unsubscribe = newUnsubscribe;\n state.reconnectAttempts = 0;\n state.isReconnecting = false;\n logger.debug('Reconnection successful', { collectionName, subscriptionKey });\n return;\n } catch (error) {\n state.reconnectAttempts++;\n logger.warn(`Reconnection attempt ${state.reconnectAttempts} failed`, {\n collectionName,\n subscriptionKey,\n error\n });\n }\n }\n\n logger.error('Max reconnection attempts reached', {\n collectionName,\n subscriptionKey,\n attempts: state.reconnectAttempts\n });\n state.isReconnecting = false;\n collectionSubs.delete(subscriptionKey);\n }\n\n // ============================================================================\n // Core Subscription Methods\n // ============================================================================\n\n /**\n * Subscribe to real-time updates for a collection.\n * Returns a promise that resolves when the subscription is fully established.\n *\n * @param collectionName - The PocketBase collection name\n * @param collection - The TanStack DB collection to sync with\n * @param recordId - Optional: Subscribe to specific record, or omit for collection-wide updates\n */\n async subscribe<T extends object>(\n collectionName: string,\n collection: Collection<T>,\n recordId?: string\n ): Promise<void> {\n if (!this.subscriptions.has(collectionName)) {\n this.subscriptions.set(collectionName, new Map());\n }\n if (!this.subscriptionPromises.has(collectionName)) {\n this.subscriptionPromises.set(collectionName, new Map());\n }\n\n const collectionSubs = this.subscriptions.get(collectionName)!;\n const collectionPromises = this.subscriptionPromises.get(collectionName)!;\n const subscriptionKey = getSubscriptionKey(recordId);\n\n if (collectionSubs.has(subscriptionKey)) {\n logger.debug('Already subscribed, skipping', { collectionName, subscriptionKey });\n return;\n }\n\n const existingPromise = collectionPromises.get(subscriptionKey);\n if (existingPromise) {\n logger.debug('Pending subscription found, waiting', { collectionName, subscriptionKey });\n return existingPromise;\n }\n\n // Placeholder ensures isSubscribed() returns true immediately\n collectionSubs.set(subscriptionKey, createPendingSubscriptionState(recordId));\n\n const subscriptionPromise = (async () => {\n try {\n const unsubscribe = await this.setupSubscription(collectionName, collection, recordId);\n\n const state = collectionSubs.get(subscriptionKey);\n if (state) {\n state.unsubscribe = unsubscribe;\n }\n } catch (error) {\n collectionSubs.delete(subscriptionKey);\n collectionPromises.delete(subscriptionKey);\n logger.error('Subscription failed', { collectionName, subscriptionKey, error });\n await this.handleReconnection(collectionName, collection, recordId);\n throw error;\n }\n // Keep promise for waitForSubscription to check completion\n })();\n\n collectionPromises.set(subscriptionKey, subscriptionPromise);\n\n try {\n await subscriptionPromise;\n } catch (_error) {\n // Error logged and reconnection initiated above\n }\n }\n\n /**\n * Unsubscribe from real-time updates.\n *\n * @param collectionName - The PocketBase collection name\n * @param recordId - Optional: Unsubscribe from specific record, or omit for collection-wide\n */\n unsubscribe(collectionName: string, recordId?: string): void {\n const collectionSubs = this.subscriptions.get(collectionName);\n if (!collectionSubs) return;\n\n const subscriptionKey = getSubscriptionKey(recordId);\n const state = collectionSubs.get(subscriptionKey);\n\n if (state) {\n const unsubPromise = state.unsubscribe();\n if (unsubPromise && typeof unsubPromise.catch === 'function') {\n unsubPromise.catch((error) => {\n logger.debug('Unsubscribe failed (expected if connection closed)', {\n collectionName,\n subscriptionKey,\n error\n });\n });\n }\n collectionSubs.delete(subscriptionKey);\n logger.debug('Unsubscribed', { collectionName, subscriptionKey });\n }\n\n const collectionPromises = this.subscriptionPromises.get(collectionName);\n if (collectionPromises) {\n collectionPromises.delete(subscriptionKey);\n if (collectionPromises.size === 0) {\n this.subscriptionPromises.delete(collectionName);\n }\n }\n\n if (collectionSubs.size === 0) {\n this.subscriptions.delete(collectionName);\n }\n }\n\n /**\n * Unsubscribe from all subscriptions for a collection.\n *\n * @param collectionName - The PocketBase collection name\n */\n unsubscribeAll(collectionName: string): void {\n const collectionSubs = this.subscriptions.get(collectionName);\n if (!collectionSubs) return;\n\n logger.debug('Unsubscribing from all subscriptions', { collectionName, count: collectionSubs.size });\n\n for (const state of collectionSubs.values()) {\n const unsubPromise = state.unsubscribe();\n if (unsubPromise && typeof unsubPromise.catch === 'function') {\n unsubPromise.catch((error) => {\n logger.debug('Unsubscribe failed (expected if connection closed)', {\n collectionName,\n error\n });\n });\n }\n }\n\n this.subscriptions.delete(collectionName);\n this.subscriptionPromises.delete(collectionName);\n }\n\n // ============================================================================\n // State Queries\n // ============================================================================\n\n /**\n * Check if subscribed to a collection.\n *\n * @param collectionName - The PocketBase collection name\n * @param recordId - Optional: Check specific record subscription, or omit for collection-wide\n */\n isSubscribed(collectionName: string, recordId?: string): boolean {\n const collectionSubs = this.subscriptions.get(collectionName);\n if (!collectionSubs) return false;\n\n const subscriptionKey = getSubscriptionKey(recordId);\n return collectionSubs.has(subscriptionKey);\n }\n\n /**\n * Wait for a subscription to be fully established (useful for testing).\n *\n * @param collectionName - The collection name\n * @param recordId - Optional specific record ID\n * @param timeoutMs - Timeout in milliseconds\n */\n async waitForSubscription(\n collectionName: string,\n recordId?: string,\n timeoutMs: number = SUBSCRIPTION_CONFIG.DEFAULT_WAIT_TIMEOUT_MS\n ): Promise<void> {\n const subscriptionKey = getSubscriptionKey(recordId);\n const collectionSubs = this.subscriptions.get(collectionName);\n\n if (collectionSubs?.has(subscriptionKey)) {\n const collectionPromises = this.subscriptionPromises.get(collectionName);\n if (!collectionPromises?.has(subscriptionKey)) {\n return;\n }\n }\n\n const collectionPromises = this.subscriptionPromises.get(collectionName);\n const promise = collectionPromises?.get(subscriptionKey);\n\n if (!promise) {\n const isSubscribed = collectionSubs?.has(subscriptionKey);\n if (!isSubscribed) {\n throw new Error(`No subscription found for ${collectionName}:${subscriptionKey}`);\n }\n return;\n }\n\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => reject(new Error(`Subscription timeout after ${timeoutMs}ms`)), timeoutMs);\n });\n\n await Promise.race([promise, timeoutPromise]);\n }\n\n // ============================================================================\n // Lifecycle Management\n // ============================================================================\n\n /**\n * Track subscriber addition for a collection.\n * Automatically subscribes when first subscriber is added.\n *\n * @param collectionName - The PocketBase collection name\n * @param collection - The TanStack DB collection to sync with\n */\n async addSubscriber<T extends object>(\n collectionName: string,\n collection: Collection<T>\n ): Promise<void> {\n const currentCount = this.subscriberCounts.get(collectionName) || 0;\n const newCount = currentCount + 1;\n this.subscriberCounts.set(collectionName, newCount);\n\n logger.debug('Subscriber added', { collectionName, count: newCount });\n\n const cleanupTimer = this.cleanupTimers.get(collectionName);\n if (cleanupTimer) {\n clearTimeout(cleanupTimer);\n this.cleanupTimers.delete(collectionName);\n logger.debug('Cleanup timer cancelled', { collectionName });\n }\n\n if (newCount === 1 && !this.isSubscribed(collectionName)) {\n logger.debug('First subscriber - starting subscription', { collectionName });\n await this.subscribe(collectionName, collection);\n }\n }\n\n /**\n * Track subscriber removal for a collection.\n * Automatically unsubscribes (with delay) when last subscriber is removed.\n *\n * @param collectionName - The PocketBase collection name\n */\n removeSubscriber(collectionName: string): void {\n const currentCount = this.subscriberCounts.get(collectionName) || 0;\n const newCount = Math.max(0, currentCount - 1);\n this.subscriberCounts.set(collectionName, newCount);\n\n logger.debug('Subscriber removed', { collectionName, count: newCount });\n\n if (newCount === 0) {\n const existingTimer = this.cleanupTimers.get(collectionName);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n const cleanupTimer = setTimeout(() => {\n const finalCount = this.subscriberCounts.get(collectionName) || 0;\n if (finalCount === 0) {\n logger.debug('Cleanup timer fired - unsubscribing', { collectionName });\n this.unsubscribeAll(collectionName);\n this.subscriberCounts.delete(collectionName);\n }\n this.cleanupTimers.delete(collectionName);\n }, SUBSCRIPTION_CONFIG.CLEANUP_DELAY_MS);\n\n this.cleanupTimers.set(collectionName, cleanupTimer);\n logger.debug('Cleanup timer scheduled', {\n collectionName,\n delayMs: SUBSCRIPTION_CONFIG.CLEANUP_DELAY_MS\n });\n }\n }\n\n /**\n * Get the current subscriber count for a collection.\n * Useful for debugging and testing.\n *\n * @param collectionName - The PocketBase collection name\n * @returns Current subscriber count\n */\n getSubscriberCount(collectionName: string): number {\n return this.subscriberCounts.get(collectionName) || 0;\n }\n}\n","import React, { createContext, useContext, type ReactNode } from 'react';\nimport type { Collection } from '@tanstack/db';\nimport type { SchemaDeclaration } from './types';\n\n/**\n * Map of collection names to TanStack DB Collection instances.\n * Keys are user-defined strings, values are Collection instances.\n *\n * @example\n * ```ts\n * const stores = {\n * jobs: jobsCollection,\n * customers: customersCollection,\n * addresses: addressesCollection\n * };\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CollectionsMap = Record<string, Collection<any>>;\n\n/**\n * Context for providing collections to React components.\n * @internal\n */\nconst CollectionsContext = createContext<CollectionsMap | null>(null);\n\n/**\n * Props for the CollectionsProvider component.\n */\nexport interface CollectionsProviderProps {\n /** Map of collection name to Collection instance */\n collections: CollectionsMap;\n /** React children to render */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes collections available to all child components.\n * Wrap your app with this provider to use the useStore and useStores hooks.\n *\n * @example\n * ```tsx\n * const factory = new CollectionFactory<Schema>(pb, queryClient);\n * const collections = {\n * jobs: factory.create('jobs'),\n * customers: factory.create('customers'),\n * addresses: factory.create('addresses')\n * };\n *\n * function App() {\n * return (\n * <CollectionsProvider collections={collections}>\n * <YourApp />\n * </CollectionsProvider>\n * );\n * }\n * ```\n */\nexport function CollectionsProvider({ collections, children }: CollectionsProviderProps) {\n return (\n <CollectionsContext.Provider value={collections}>\n {children}\n </CollectionsContext.Provider>\n );\n}\n\n/**\n * Hook to access a single collection from the provider.\n * Returns the Collection instance for the specified key.\n *\n * @template T - The record type for the collection\n * @param key - The collection key as defined in the provider\n * @returns The Collection instance\n * @throws Error if used outside of CollectionsProvider or if key doesn't exist\n *\n * @example\n * ```tsx\n * function JobsList() {\n * const jobsCollection = useStore<JobsRecord>('jobs');\n *\n * const { data } = useLiveQuery((q) =>\n * q.from({ jobs: jobsCollection })\n * );\n *\n * return (\n * <ul>\n * {data?.map(job => <li key={job.id}>{job.name}</li>)}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useStore<T extends object = object>(key: string): Collection<T> {\n const context = useContext(CollectionsContext);\n\n if (!context) {\n throw new Error('useStore must be used within a CollectionsProvider');\n }\n\n if (!(key in context)) {\n throw new Error(`Collection \"${key}\" not found in CollectionsProvider`);\n }\n\n return context[key] as Collection<T>;\n}\n\n/**\n * Hook to access multiple collections from the provider.\n * Returns an array of Collection instances matching the order of the keys array.\n *\n * @template T - Tuple type of record types for each collection\n * @param keys - Array of collection keys as defined in the provider\n * @returns Array of Collection instances in the same order as keys\n * @throws Error if used outside of CollectionsProvider or if any key doesn't exist\n *\n * @example\n * ```tsx\n * function JobsWithCustomers() {\n * const [jobsCollection, customersCollection] = useStores<\n * [JobsRecord, CustomersRecord]\n * >(['jobs', 'customers']);\n *\n * const { data } = useLiveQuery((q) =>\n * q.from({ job: jobsCollection })\n * .join(\n * { customer: customersCollection },\n * ({ job, customer }) => eq(job.customer, customer.id),\n * 'left'\n * )\n * );\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useStores<T extends readonly object[]>(\n keys: readonly string[]\n): { [K in keyof T]: Collection<T[K]> } {\n const context = useContext(CollectionsContext);\n\n if (!context) {\n throw new Error('useStores must be used within a CollectionsProvider');\n }\n\n const collections = keys.map((key) => {\n if (!(key in context)) {\n throw new Error(`Collection \"${key}\" not found in CollectionsProvider`);\n }\n return context[key];\n });\n\n return collections as { [K in keyof T]: Collection<T[K]> };\n}\n","import PocketBase from 'pocketbase';\nimport { createCollection, type Collection } from \"@tanstack/db\"\nimport { queryCollectionOptions } from \"@tanstack/query-db-collection\"\nimport { QueryClient } from '@tanstack/react-query'\nimport { SubscriptionManager } from './subscription-manager';\nimport type {\n SchemaDeclaration,\n SubscribableCollection,\n JoinHelper,\n CreateCollectionOptions,\n RelationsConfig,\n WithExpand,\n} from './types';\n\nexport type {\n SchemaDeclaration,\n SubscribableCollection,\n JoinHelper,\n CreateCollectionOptions,\n RelationsConfig,\n} from './types';\n\nexport {\n CollectionsProvider,\n useStore,\n useStores,\n type CollectionsMap,\n type CollectionsProviderProps,\n} from './provider';\n\n/**\n * Factory for creating type-safe TanStack DB collections backed by PocketBase.\n * Integrates real-time subscriptions with automatic synchronization.\n */\nexport class CollectionFactory<Schema extends SchemaDeclaration, TMaxDepth extends 0 | 1 | 2 | 3 | 4 | 5 | 6 = 2> {\n private subscriptionManager: SubscriptionManager;\n\n constructor(public pocketbase: PocketBase, public queryClient: QueryClient) {\n this.subscriptionManager = new SubscriptionManager(pocketbase);\n }\n\n /**\n * Setup automatic subscription lifecycle management.\n * Hooks into TanStack DB's subscriber events to manage real-time subscriptions.\n */\n private setupSubscriptionLifecycle<T extends object>(\n collectionName: string,\n baseCollection: Collection<T>\n ): void {\n baseCollection.on('subscribers:change', (event) => {\n const newCount = event.subscriberCount;\n const previousCount = event.previousSubscriberCount;\n\n if (newCount > previousCount) {\n // Fire and forget - subscription handled asynchronously\n this.subscriptionManager.addSubscriber(collectionName, baseCollection).catch(() => {\n // Silently handle subscription errors - reconnection will be attempted\n });\n } else if (newCount < previousCount) {\n this.subscriptionManager.removeSubscriber(collectionName);\n }\n });\n }\n\n /**\n * Create a TanStack DB collection from a PocketBase collection.\n *\n * Collections are lazy by default - they don't fetch data or subscribe until queried.\n * Real-time subscriptions automatically start when the first query becomes active\n * and stop when the last query unmounts (with a cleanup delay to prevent thrashing).\n *\n * @param collection - The name of the collection\n * @param options - Optional configuration including relations and expand\n *\n * @example\n * Basic usage with automatic lifecycle management:\n * ```ts\n * const jobsCollection = factory.create('jobs');\n *\n * // In your component - subscription starts automatically\n * const { data } = useLiveQuery((q) =>\n * q.from({ jobs: jobsCollection })\n * );\n * // Subscription stops automatically when component unmounts\n * ```\n *\n * @example\n * With query operators (filters, sorting):\n * ```ts\n * const jobsCollection = factory.create('jobs');\n *\n * // In your component:\n * const { data } = useLiveQuery((q) =>\n * q.from({ jobs: jobsCollection })\n * .where(({ jobs }) => and(\n * eq(jobs.status, 'ACTIVE'),\n * gt(jobs.created, new Date('2025-01-01'))\n * ))\n * .orderBy(({ jobs }) => jobs.created, 'desc')\n * );\n * ```\n *\n * @example\n * With relation expansion:\n * ```ts\n * const jobsCollection = factory.create('jobs', {\n * expand: 'customer,location'\n * });\n *\n * // Expanded relations available in record.expand\n * ```\n *\n * @example\n * With relations (for manual joins):\n * ```ts\n * const customersCollection = factory.create('customers');\n * const jobsCollection = factory.create('jobs', {\n * relations: { customer: customersCollection }\n * });\n *\n * // In your component, manually build joins:\n * const { data } = useLiveQuery((q) =>\n * q.from({ job: jobsCollection })\n * .join(\n * { customer: customersCollection },\n * ({ job, customer }) => eq(job.customer, customer.id),\n * \"left\"\n * )\n * .select(({ job, customer }) => ({\n * ...job,\n * expand: {\n * customer: customer ? { ...customer } : undefined\n * }\n * }))\n * );\n * ```\n *\n * @example\n * Manual subscription control (advanced):\n * ```ts\n * const jobsCollection = factory.create('jobs');\n *\n * // Manually subscribe to specific record (bypasses automatic lifecycle)\n * await jobsCollection.subscribe('record_id_123');\n *\n * // Check subscription status\n * const isSubbed = jobsCollection.isSubscribed('record_id_123');\n *\n * // Manually unsubscribe\n * jobsCollection.unsubscribe('record_id_123');\n * ```\n */\n create<\n C extends keyof Schema & string,\n E extends string | undefined = undefined\n >(\n collection: C,\n options?: CreateCollectionOptions<Schema, C, E>\n ): Collection<WithExpand<Schema, C, E>> & SubscribableCollection<WithExpand<Schema, C, E>> & JoinHelper<Schema, C, WithExpand<Schema, C, E>> {\n type RecordType = WithExpand<Schema, C, E>;\n\n const baseCollection = createCollection(\n queryCollectionOptions<RecordType>({\n queryKey: [collection],\n queryFn: async () => {\n const queryOptions: { expand?: string } = {};\n if (options?.expand) {\n queryOptions.expand = options.expand;\n }\n\n const result = await this.pocketbase\n .collection(collection)\n .getFullList(queryOptions);\n\n return result as unknown as RecordType[];\n },\n queryClient: this.queryClient,\n getKey: (item: RecordType) => (item as { id: string }).id,\n startSync: options?.startSync ?? false,\n })\n );\n\n const subscribableCollection = Object.assign(baseCollection, {\n subscribe: async (recordId?: string) => {\n await this.subscriptionManager.subscribe(collection, baseCollection, recordId);\n },\n unsubscribe: (recordId?: string) => {\n this.subscriptionManager.unsubscribe(collection, recordId);\n },\n unsubscribeAll: () => {\n this.subscriptionManager.unsubscribeAll(collection);\n },\n isSubscribed: (recordId?: string) => {\n return this.subscriptionManager.isSubscribed(collection, recordId);\n },\n waitForSubscription: async (recordId?: string, timeoutMs?: number) => {\n await this.subscriptionManager.waitForSubscription(collection, recordId, timeoutMs);\n },\n relations: options?.relations || {} as RelationsConfig<Schema, C>\n });\n\n this.setupSubscriptionLifecycle(collection, baseCollection);\n\n return subscribableCollection as Collection<RecordType> & SubscribableCollection<RecordType> & JoinHelper<Schema, C, RecordType>;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/pocketbase-query-converter.ts","../src/logger.ts","../src/collection.ts","../src/react.tsx","../src/util.ts"],"names":["createTanStackCollection"],"mappings":"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","file":"index.js","sourcesContent":["import { parseWhereExpression, parseOrderByExpression, type FieldPath, type ParsedOrderBy } from '@tanstack/db';\nimport type { IR } from '@tanstack/db';\n\ntype BasicExpression<T = any> = IR.BasicExpression<T>;\n\nfunction escapeValue(value: any): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n if (typeof value === 'number') {\n return value.toString();\n }\n if (typeof value === 'string') {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`;\n }\n if (value instanceof Date) {\n return `\"${value.toISOString()}\"`;\n }\n if (Array.isArray(value)) {\n return `[${value.map(escapeValue).join(',')}]`;\n }\n return `\"${String(value)}\"`;\n}\n\nfunction fieldPathToString(path: FieldPath): string {\n return path.join('.');\n}\n\nexport function convertToPocketBaseFilter(\n where: BasicExpression<boolean> | undefined | null\n): string | undefined {\n if (!where) {\n return undefined;\n }\n\n const result = parseWhereExpression(where, {\n handlers: {\n eq: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} = ${escapeValue(value)}`;\n },\n gt: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} > ${escapeValue(value)}`;\n },\n gte: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} >= ${escapeValue(value)}`;\n },\n lt: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} < ${escapeValue(value)}`;\n },\n lte: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} <= ${escapeValue(value)}`;\n },\n and: (...conditions: string[]) => {\n if (conditions.length === 0) return '';\n if (conditions.length === 1) return conditions[0];\n return `(${conditions.join(' && ')})`;\n },\n or: (...conditions: string[]) => {\n if (conditions.length === 0) return '';\n if (conditions.length === 1) return conditions[0];\n return `(${conditions.join(' || ')})`;\n },\n not: (condition: string) => {\n return `!(${condition})`;\n },\n in: (field: FieldPath, values: any[]) => {\n if (!Array.isArray(values)) {\n values = [values];\n }\n const conditions = values.map(v => `${fieldPathToString(field)} = ${escapeValue(v)}`);\n return conditions.length > 1 ? `(${conditions.join(' || ')})` : conditions[0];\n },\n like: (field: FieldPath, value: any) => {\n return `${fieldPathToString(field)} ~ ${escapeValue(value)}`;\n },\n isNull: (field: FieldPath) => {\n return `${fieldPathToString(field)} = null`;\n },\n isUndefined: (field: FieldPath) => {\n return `${fieldPathToString(field)} = null`;\n },\n },\n onUnknownOperator: (operator: string, args: any[]) => {\n throw new Error(\n `Unsupported operator '${operator}' for PocketBase filter conversion. ` +\n `Supported operators: eq, gt, gte, lt, lte, in, like, and, or, not, isNull, isUndefined`\n );\n },\n });\n\n return result || undefined;\n}\n\nexport function convertToPocketBaseSort(\n orderBy: IR.OrderBy | undefined | null\n): string | undefined {\n if (!orderBy) {\n return undefined;\n }\n\n const sorts = parseOrderByExpression(orderBy);\n\n if (sorts.length === 0) {\n return undefined;\n }\n\n return sorts\n .map((sort: ParsedOrderBy) => {\n const field = fieldPathToString(sort.field);\n return sort.direction === 'desc' ? `-${field}` : field;\n })\n .join(',');\n}\n","/**\n * Logger interface for subscription events and internal operations.\n * Users can provide their own implementation to integrate with external logging services.\n */\nexport interface Logger {\n /**\n * Log debug-level messages (typically only shown in development).\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n debug: (msg: string, context?: object) => void;\n\n /**\n * Log info-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n info: (msg: string, context?: object) => void;\n\n /**\n * Log warning-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n warn: (msg: string, context?: object) => void;\n\n /**\n * Log error-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n error: (msg: string, context?: object) => void;\n}\n\n/**\n * Default console-based logger implementation.\n * Only logs debug messages in development mode.\n */\nconst defaultLogger: Logger = {\n debug: (msg: string, context?: object) => {\n // Only log debug in development\n if (process.env.NODE_ENV === 'development') {\n // biome-ignore lint/suspicious/noConsoleLog: Debug logging is acceptable in development\n console.log(`[pbtsdb] ${msg}`, context || '');\n }\n },\n info: (msg: string, context?: object) => {\n // biome-ignore lint/suspicious/noConsoleLog: Info logging is acceptable\n console.info(`[pbtsdb] ${msg}`, context || '');\n },\n warn: (msg: string, context?: object) => {\n // biome-ignore lint/suspicious/noConsoleLog: Warning logging is acceptable\n console.warn(`[pbtsdb] ${msg}`, context || '');\n },\n error: (msg: string, context?: object) => {\n // biome-ignore lint/suspicious/noConsoleLog: Error logging is acceptable\n console.error(`[pbtsdb] ${msg}`, context || '');\n },\n};\n\n/**\n * Current logger instance (can be replaced by users).\n */\nlet currentLogger: Logger = defaultLogger;\n\n/**\n * Internal logger instance used by the library.\n */\nexport const logger: Logger = {\n debug: (msg: string, context?: object) => currentLogger.debug(msg, context),\n info: (msg: string, context?: object) => currentLogger.info(msg, context),\n warn: (msg: string, context?: object) => currentLogger.warn(msg, context),\n error: (msg: string, context?: object) => currentLogger.error(msg, context),\n};\n\n/**\n * Set a custom logger implementation.\n * This allows users to integrate with their own logging services (e.g., Sentry, LogRocket, etc.).\n *\n * @param customLogger - The custom logger implementation\n *\n * @example\n * ```ts\n * import { setLogger } from 'pbtsdb';\n *\n * // Integration with a custom logging service\n * setLogger({\n * debug: (msg, context) => myLogger.debug(msg, context),\n * warn: (msg, context) => myLogger.warn(msg, context),\n * error: (msg, context) => {\n * myLogger.error(msg, context);\n * Sentry.captureMessage(msg, { level: 'error', extra: context });\n * },\n * });\n * ```\n *\n * @example\n * ```ts\n * // Disable all logging\n * setLogger({\n * debug: () => {},\n * warn: () => {},\n * error: () => {},\n * });\n * ```\n */\nexport function setLogger(customLogger: Logger): void {\n currentLogger = customLogger;\n}\n\n/**\n * Reset the logger to the default implementation.\n */\nexport function resetLogger(): void {\n currentLogger = defaultLogger;\n}\n","import PocketBase from 'pocketbase';\nimport type { RecordSubscription } from 'pocketbase';\nimport { createCollection as createTanStackCollection, type Collection, type LoadSubsetOptions } from \"@tanstack/react-db\"\nimport { queryCollectionOptions, type QueryCollectionUtils } from \"@tanstack/query-db-collection\"\nimport { QueryClient } from '@tanstack/react-query'\nimport { convertToPocketBaseFilter, convertToPocketBaseSort } from './pocketbase-query-converter';\nimport type {\n SchemaDeclaration,\n CreateCollectionOptions,\n ExtractRecordType,\n ExpandTargetCollection,\n BaseRecord,\n} from './types';\nimport { logger } from './logger';\n\nexport type {\n SchemaDeclaration,\n CreateCollectionOptions,\n BaseRecord,\n} from './types';\n\n/**\n * Extended LoadSubsetOptions that includes PocketBase-specific expand parameter.\n * @internal\n */\ntype ExtendedLoadSubsetOptions = LoadSubsetOptions & {\n pbExpand?: string;\n};\n\n/**\n * Compute the record type with expand property when expand option is configured.\n * @internal\n */\ntype WithExpandFromConfig<\n Schema extends SchemaDeclaration,\n C extends keyof Schema,\n Opts\n> = Opts extends { expand: infer E }\n ? ExtractRecordType<Schema, C> & {\n expand?: {\n [K in keyof E]: K extends keyof import('./types').ExtractRelations<Schema, C>\n ? import('./types').ExtractRelations<Schema, C>[K] extends Array<infer U>\n ? U[]\n : import('./types').ExtractRelations<Schema, C>[K]\n : never;\n };\n }\n : ExtractRecordType<Schema, C>;\n\n/**\n * Subscription helpers added to collection instances.\n * @internal\n */\ninterface CollectionSubscriptionHelpers {\n /** The PocketBase collection name */\n collectionName: string;\n /** Wait for subscription to be established (useful in tests) */\n waitForSubscription: (timeout?: number) => Promise<void>;\n /** Check if collection has an active subscription */\n isSubscribed: () => boolean;\n}\n\n/**\n * Inferred collection type from config options.\n * @internal\n */\ntype InferCollectionType<\n Schema extends SchemaDeclaration,\n C extends keyof Schema,\n Opts extends CreateCollectionOptions<Schema, C>\n> = Collection<\n WithExpandFromConfig<Schema, C, Opts>,\n string | number,\n // TUtils - QueryCollectionUtils from TanStack Query DB Collection\n QueryCollectionUtils<WithExpandFromConfig<Schema, C, Opts>, string | number, WithExpandFromConfig<Schema, C, Opts>>,\n // TSchema - we don't use StandardSchema validation\n never,\n Opts extends { omitOnInsert: infer O extends readonly import('./types').OmittableFields<ExtractRecordType<Schema, C>>[] }\n ? import('./types').ComputeInsertType<ExtractRecordType<Schema, C>, O>\n : ExtractRecordType<Schema, C>\n> & CollectionSubscriptionHelpers;\n\n\n/**\n * Creates a type-safe TanStack DB collection backed by PocketBase.\n * Use this when you need fine-grained control or need to create collections with dependencies.\n *\n * @param pb - PocketBase client instance\n * @param queryClient - TanStack Query client\n * @returns A curried function that takes collection name and options\n *\n * @example\n * Basic usage:\n * ```ts\n * const booksCollection = createCollection<Schema>(pb, queryClient)('books', {});\n *\n * // Use directly\n * const books = await booksCollection.getFullList();\n * ```\n *\n * @example\n * With auto-expand relations:\n * ```ts\n * const authorsCollection = createCollection<Schema>(pb, queryClient)('authors', {});\n * const booksCollection = createCollection<Schema>(pb, queryClient)('books', {\n * expand: {\n * author: authorsCollection // Always expand, auto-upsert into authorsCollection\n * }\n * });\n *\n * // Expand is automatic - no .expand() call needed\n * const { data } = useLiveQuery((q) => q.from({ books: booksCollection }));\n * // data[0].expand.author is typed and populated\n * ```\n */\nexport function createCollection<Schema extends SchemaDeclaration>(\n pb: PocketBase,\n queryClient: QueryClient\n) {\n return <\n C extends keyof Schema & string,\n Opts extends CreateCollectionOptions<Schema, C> = CreateCollectionOptions<Schema, C>\n >(\n collectionName: C,\n options?: Opts\n ): InferCollectionType<Schema, C, Opts> => {\n type RecordType = ExtractRecordType<Schema, C>;\n const expandStores = options?.expand as Record<string, ExpandTargetCollection> | undefined;\n const expandString = expandStores ? Object.keys(expandStores).sort().join(',') : undefined;\n\n async function fetchRecords(loadOptions?: ExtendedLoadSubsetOptions): Promise<RecordType[]> {\n const filter = convertToPocketBaseFilter(loadOptions?.where);\n const sort = convertToPocketBaseSort(loadOptions?.orderBy);\n const limit = loadOptions?.limit;\n\n let items: RecordType[];\n if (!filter && !sort && !limit && !expandString) {\n items = await pb.collection(collectionName).getFullList() as unknown as RecordType[];\n } else {\n const result = await pb.collection(collectionName).getList(1, limit || 500, {\n filter,\n sort,\n expand: expandString,\n });\n items = result.items as unknown as RecordType[];\n }\n\n if (expandStores) {\n for (const record of items) {\n const expandData = (record as RecordType & { expand?: Record<string, object | object[]> }).expand;\n if (!expandData) continue;\n\n for (const [key, value] of Object.entries(expandData)) {\n const targetStore = expandStores[key];\n if (!targetStore.utils) continue;\n if (!targetStore.isReady()) {\n if (targetStore.config?.syncMode === 'on-demand') {\n await targetStore._sync.startSync();\n } else {\n logger.warn(`not syncing ${key} on ${collectionName} because store is not yet ready`)\n continue\n }\n }\n const values = Array.isArray(value) ? value : [value];\n targetStore.utils.writeUpsert(values);\n }\n }\n }\n\n return items;\n }\n\n const collectionOptions = queryCollectionOptions({\n queryClient,\n queryKey: [collectionName],\n syncMode: options?.syncMode ?? 'eager',\n queryFn: async (ctx): Promise<RecordType[]> => {\n return fetchRecords(ctx.meta?.loadSubsetOptions as ExtendedLoadSubsetOptions | undefined);\n },\n getKey: (item: RecordType) => {\n const record = item as any;\n if (!record || typeof record !== 'object' || !('id' in record)) {\n throw new Error(`Record in collection '${collectionName}' is missing required 'id' field. Received: ${JSON.stringify(item)}`);\n }\n return record.id;\n },\n onInsert: options?.onInsert === false ? undefined : options?.onInsert ?? (async ({ transaction }) => {\n await Promise.all(\n transaction.mutations.map(async (mutation) => {\n const { created, updated, collectionId, collectionName: _, ...data } = mutation.modified as unknown as Record<string, unknown>;\n await pb.collection(collectionName).create(data);\n })\n );\n }),\n onUpdate: options?.onUpdate === false ? undefined : options?.onUpdate ?? (async ({ transaction }) => {\n await Promise.all(\n transaction.mutations.map(async (mutation) => {\n const recordWithId = mutation.original as { id: string };\n await pb.collection(collectionName).update(recordWithId.id, mutation.changes);\n })\n );\n }),\n onDelete: options?.onDelete === false ? undefined : options?.onDelete ?? (async ({ transaction }) => {\n await Promise.all(\n transaction.mutations.map(async (mutation) => {\n const recordWithId = mutation.original as { id: string };\n await pb.collection(collectionName).delete(recordWithId.id);\n })\n );\n })\n });\n\n const collection = createTanStackCollection(collectionOptions);\n\n // Real-time subscription state\n let unsubscribeFn: (() => Promise<void>) | null = null;\n let isSubscribed = false;\n let subscriptionPromise: Promise<void> | null = null;\n let subscriptionResolve: (() => void) | null = null;\n\n // Handle real-time events from PocketBase\n const handleRealtimeEvent = (event: RecordSubscription<RecordType>) => {\n if (!collection.utils) return;\n\n collection.utils.writeBatch(() => {\n switch (event.action) {\n case 'create':\n collection.utils.writeInsert(event.record);\n break;\n case 'update':\n collection.utils.writeUpdate(event.record);\n break;\n case 'delete':\n if (event.record && 'id' in event.record) {\n collection.utils.writeDelete((event.record as { id: string }).id);\n }\n break;\n }\n });\n };\n\n // Start PocketBase real-time subscription\n const startSubscription = async () => {\n if (isSubscribed) return;\n\n // Create promise before starting so waiters can await it\n if (!subscriptionPromise) {\n subscriptionPromise = new Promise<void>((resolve) => {\n subscriptionResolve = resolve;\n });\n }\n\n try {\n unsubscribeFn = await pb.collection(collectionName).subscribe('*', handleRealtimeEvent);\n isSubscribed = true;\n logger.debug('Subscription started', { collectionName });\n // Resolve the promise to notify waiters\n if (subscriptionResolve) {\n subscriptionResolve();\n }\n } catch (error) {\n logger.error('Failed to start subscription', { collectionName, error });\n }\n };\n\n // Stop PocketBase real-time subscription\n const stopSubscription = async () => {\n if (!isSubscribed || !unsubscribeFn) return;\n\n try {\n await unsubscribeFn();\n unsubscribeFn = null;\n isSubscribed = false;\n // Reset promise for next subscription cycle\n subscriptionPromise = null;\n subscriptionResolve = null;\n logger.debug('Subscription stopped', { collectionName });\n } catch (error) {\n logger.debug('Unsubscribe failed (expected if connection closed)', { collectionName, error });\n }\n };\n\n // Wait for subscription to be established (for testing)\n const waitForSubscription = async (timeout = 5000): Promise<void> => {\n if (isSubscribed) return;\n\n if (!subscriptionPromise) {\n // No subscription in progress, wait for one to start\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(() => {\n if (subscriptionPromise) {\n clearInterval(checkInterval);\n resolve();\n }\n }, 10);\n setTimeout(() => {\n clearInterval(checkInterval);\n resolve();\n }, timeout);\n });\n }\n\n if (subscriptionPromise) {\n await Promise.race([\n subscriptionPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error('Subscription timeout')), timeout)\n )\n ]);\n }\n };\n\n // Manage subscription based on collection subscriber count\n collection.on('subscribers:change', (event: { subscriberCount: number; previousSubscriberCount: number }) => {\n const newCount = event.subscriberCount;\n const previousCount = event.previousSubscriberCount;\n\n if (newCount > 0 && previousCount === 0) {\n // First subscriber - start real-time subscription\n startSubscription().catch(() => {});\n } else if (newCount === 0 && previousCount > 0) {\n // Last subscriber removed - stop real-time subscription\n stopSubscription().catch(() => {});\n }\n });\n\n // Add collectionName and subscription helpers\n Object.assign(collection, {\n collectionName,\n waitForSubscription,\n isSubscribed: () => isSubscribed,\n });\n\n return collection as any;\n };\n}\n\n","import React, { createContext, useContext, type ReactNode } from 'react';\n\n/**\n * UseStore hook type for variadic collection access.\n * @internal\n */\ntype UseStoreFn<CollectionsMap> = <K extends (keyof CollectionsMap)[]>(\n ...keys: K\n) => { [I in keyof K]: K[I] extends keyof CollectionsMap ? CollectionsMap[K[I]] : never };\n\n/**\n * Return type for createReactProvider function.\n */\nexport interface ReactProviderResult<CollectionsMap> {\n /**\n * React Context Provider component.\n * Wrap your app with this provider to make collections available to useStore.\n */\n Provider: React.FC<{ children: ReactNode }>;\n\n /**\n * Hook to access collections from the provider.\n * Uses variadic arguments for clean syntax with automatic type inference.\n *\n * @example\n * ```tsx\n * // Single collection\n * const [books] = useStore('books');\n *\n * // Multiple collections (no 'as const' needed!)\n * const [books, authors] = useStore('books', 'authors');\n * ```\n */\n useStore: UseStoreFn<CollectionsMap>;\n}\n\n/**\n * Creates a React Provider and useStore hook from a collections map.\n *\n * @param collections - Map of collection keys to Collection instances\n * @returns Object containing Provider component and useStore hook\n *\n * @example\n * Basic usage:\n * ```tsx\n * import { createCollection, createReactProvider } from 'pbtsdb';\n * import { useLiveQuery } from '@tanstack/react-db';\n *\n * // Step 1: Create collections\n * const c = createCollection<Schema>(pb, queryClient);\n * const collections = {\n * books: c('books', {}),\n * authors: c('authors', {}),\n * };\n *\n * // Step 2: Wrap for React\n * const { Provider, useStore } = createReactProvider(collections);\n *\n * // Step 3: Wrap your app\n * function App() {\n * return (\n * <QueryClientProvider client={queryClient}>\n * <Provider>\n * <BooksList />\n * </Provider>\n * </QueryClientProvider>\n * );\n * }\n *\n * // Step 4: Use in components\n * function BooksList() {\n * const [books] = useStore('books');\n * const { data } = useLiveQuery((q) => q.from({ books }));\n * return <div>{data?.map(book => <p key={book.id}>{book.title}</p>)}</div>;\n * }\n * ```\n *\n * @example\n * Variadic useStore pattern:\n * ```tsx\n * function BooksWithAuthors() {\n * const [books, authors] = useStore('books', 'authors');\n *\n * const { data } = useLiveQuery((q) =>\n * q.from({ book: books })\n * .join(\n * { author: authors },\n * ({ book, author }) => eq(book.author, author.id),\n * 'left'\n * )\n * );\n *\n * return <div>...</div>;\n * }\n * ```\n *\n * @example\n * With auto-expand collections:\n * ```tsx\n * const c = createCollection<Schema>(pb, queryClient);\n * const authors = c('authors', {});\n * const books = c('books', {\n * expand: {\n * author: authors\n * }\n * });\n *\n * const { Provider, useStore } = createReactProvider({ authors, books });\n *\n * function BooksWithExpandedAuthors() {\n * const [books] = useStore('books');\n * const { data } = useLiveQuery((q) => q.from({ books }));\n *\n * return (\n * <ul>\n * {data?.map(book => (\n * <li key={book.id}>\n * {book.title} by {book.expand?.author?.name}\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function createReactProvider<CollectionsMap extends Record<string, any>>(\n collections: CollectionsMap\n): ReactProviderResult<CollectionsMap> {\n const Context = createContext<CollectionsMap | null>(null);\n\n const Provider: React.FC<{ children: ReactNode }> = ({ children }) => (\n <Context.Provider value={collections}>{children}</Context.Provider>\n );\n\n function useStore<K extends (keyof CollectionsMap)[]>(\n ...keys: K\n ): { [I in keyof K]: K[I] extends keyof CollectionsMap ? CollectionsMap[K[I]] : never } {\n const context = useContext(Context);\n\n if (!context) {\n throw new Error('useStore must be used within the Provider returned by createReactProvider');\n }\n\n return keys.map((key) => {\n if (!(key in context)) {\n throw new Error(`Collection \"${String(key)}\" not found in collections`);\n }\n return context[key];\n }) as { [I in keyof K]: K[I] extends keyof CollectionsMap ? CollectionsMap[K[I]] : never };\n }\n\n return {\n Provider,\n useStore: useStore as UseStoreFn<CollectionsMap>,\n };\n}\n","/**\n * Generates a new PocketBase-compatible record ID.\n * Returns a 15-character alphanumeric string (lowercase letters and numbers).\n *\n * PocketBase uses 15-character IDs for records, formatted as lowercase alphanumeric.\n *\n * @returns A 15-character alphanumeric string suitable for use as a PocketBase record ID\n *\n * @example\n * ```ts\n * const id = newRecordId(); // \"a1b2c3d4e5f6g7h\"\n * ```\n */\nexport function newRecordId(): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < 15; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n"]}
package/llms.txt CHANGED
@@ -1,12 +1,16 @@
1
1
  # pbtsdb
2
2
 
3
- > Type-safe PocketBase integration with TanStack Query and TanStack DB for React applications. Provides reactive collections with automatic real-time subscriptions, full TypeScript type safety, and minimal boilerplate.
3
+ > Type-safe PocketBase integration with TanStack Query and TanStack DB for React applications. Provides reactive collections with automatic real-time subscriptions, optimistic mutations, full TypeScript type safety, and minimal boilerplate.
4
4
 
5
5
  This library connects PocketBase (backend-as-a-service) to TanStack's reactive database tools. Use it when building React applications that need real-time data synchronization with PocketBase while maintaining strict type safety.
6
6
 
7
- ## Core Pattern
7
+ ## Core Pattern (React)
8
8
 
9
9
  ```typescript
10
+ import { createCollection, createReactProvider, newRecordId } from 'pbtsdb';
11
+ import { useLiveQuery } from '@tanstack/react-db';
12
+ import { eq } from '@tanstack/db';
13
+
10
14
  // 1. Define schema with type and relations properties
11
15
  export type Schema = {
12
16
  books: {
@@ -15,28 +19,79 @@ export type Schema = {
15
19
  author?: Author;
16
20
  };
17
21
  };
22
+ authors: {
23
+ type: Author;
24
+ relations: {};
25
+ };
18
26
  }
19
27
 
20
- // 2. Create factory (once per app)
21
- const factory = new CollectionFactory<Schema>(pb, queryClient);
28
+ // 2. Create collections using curried createCollection
29
+ const c = createCollection<Schema>(pb, queryClient);
30
+ const collections = {
31
+ books: c('books', {}),
32
+ authors: c('authors', {}),
33
+ };
34
+
35
+ // 3. Create React Provider and useStore hook
36
+ const { Provider, useStore } = createReactProvider(collections);
37
+
38
+ // 4. Wrap your app with Provider
39
+ <Provider>
40
+ <App />
41
+ </Provider>
42
+
43
+ // 5. Use in components - useStore returns an array!
44
+ function BooksList() {
45
+ const [books] = useStore('books'); // ✅ Destructure from array
46
+ const { data } = useLiveQuery((q) => q.from({ books }));
47
+ // Subscriptions start/stop automatically with component lifecycle
48
+ }
22
49
 
23
- // 3. Create collections with optional expand for type-safe relations
24
- const booksCollection = factory.create('books', {
25
- expand: 'author' as const // Use 'as const' for type inference
26
- });
50
+ function BooksWithAuthors() {
51
+ const [books, authors] = useStore('books', 'authors'); // ✅ Variadic access
52
+ const { data } = useLiveQuery((q) =>
53
+ q.from({ book: books })
54
+ .join({ author: authors }, ({ book, author }) => eq(book.author, author.id), 'left')
55
+ );
56
+ }
57
+ ```
58
+
59
+ **useStore() API:**
60
+ - Single key: `const [books] = useStore('books')` → returns array with typed collection
61
+ - Multiple keys: `const [books, authors] = useStore('books', 'authors')` → returns typed tuple
62
+ - Types are inferred from the collections passed to `createReactProvider`
27
63
 
28
- // 4. Use in React components with automatic subscriptions
29
- const { data } = useLiveQuery((q) => q.from({ books: booksCollection }));
30
- // Subscriptions start/stop automatically with component lifecycle
64
+ **Custom Collection Keys:**
65
+ ```typescript
66
+ const collections = {
67
+ myBooks: c('books', {}) // Key 'myBooks', PocketBase collection 'books'
68
+ };
69
+ const { Provider, useStore } = createReactProvider(collections);
70
+ const [myBooks] = useStore('myBooks');
31
71
  ```
32
72
 
33
73
  ## Key Concepts
34
74
 
35
- - **CollectionFactory**: Create ONE factory per app, use it to create multiple collections
75
+ - **createCollection**: Curried function `createCollection<Schema>(pb, queryClient)` returns `(collectionName, options) => Collection`
76
+ - **createReactProvider**: Wraps collections for React, returns `{ Provider, useStore }`
36
77
  - **Collections are lazy**: No network activity until first query
37
78
  - **Subscriptions are automatic**: Start when component mounts, stop 5s after unmount
38
- - **Type-safe expand**: Use `as const` on expand strings for full TypeScript inference
39
- - **Schema structure**: Use `type` and `relations` properties (not `Row`/`Relations`)
79
+ - **Schema structure**: Use `type` and `relations` properties (lowercase)
80
+ - **Package name**: Import from `pbtsdb`
81
+
82
+ ## Non-React Usage
83
+
84
+ For non-React environments, use `createCollection` directly:
85
+
86
+ ```typescript
87
+ import { createCollection } from 'pbtsdb';
88
+
89
+ const c = createCollection<Schema>(pb, queryClient);
90
+ const booksCollection = c('books', {});
91
+
92
+ // Collections have TanStack DB interface
93
+ // Use with useLiveQuery or direct access
94
+ ```
40
95
 
41
96
  ## Testing
42
97
 
@@ -52,25 +107,110 @@ Tests use real PocketBase instance (not mocked). Server infrastructure is fully
52
107
  - [README.md](README.md): User-facing API reference with examples
53
108
  - [test/schema.ts](test/schema.ts): Reference schema implementation
54
109
 
110
+ ## Mutations
111
+
112
+ Collections support insert, update, and delete with automatic PocketBase sync:
113
+
114
+ ```typescript
115
+ import { newRecordId, createCollection, createReactProvider } from 'pbtsdb';
116
+
117
+ // Setup with custom mutation handlers (optional)
118
+ const c = createCollection<Schema>(pb, queryClient);
119
+ const collections = {
120
+ books: c('books', {
121
+ onInsert: async ({ transaction }) => { /* custom logic */ },
122
+ onUpdate: false, // Disable updates (throws error if called)
123
+ onDelete: false, // Disable deletes
124
+ })
125
+ };
126
+ const { Provider, useStore } = createReactProvider(collections);
127
+
128
+ // In component
129
+ function BooksList() {
130
+ const [books] = useStore('books');
131
+
132
+ // Insert with optimistic update (UI updates immediately)
133
+ const tx = books.insert({
134
+ id: newRecordId(), // Generate PocketBase-compatible ID
135
+ title: 'New Book',
136
+ // ... other fields
137
+ });
138
+
139
+ // Update with optimistic update
140
+ books.update('record_id', (draft) => {
141
+ draft.title = 'Updated Title';
142
+ });
143
+
144
+ // Update with config (non-optimistic - waits for server)
145
+ books.update('record_id', { optimistic: false }, (draft) => {
146
+ draft.title = 'Server-First Update';
147
+ });
148
+
149
+ // Delete with optimistic update
150
+ books.delete('record_id');
151
+
152
+ // Batch mutations - merges multiple updates to same record
153
+ books.utils.writeBatch(() => {
154
+ books.update('id1', (draft) => { draft.field1 = 'value1' });
155
+ books.update('id1', (draft) => { draft.field2 = 'value2' }); // Merged!
156
+ books.update('id2', (draft) => { draft.field = 'value' });
157
+ });
158
+
159
+ // Wait for persistence
160
+ await tx.isPersisted.promise; // States: pending → persisting → completed
161
+ }
162
+ ```
163
+
164
+ **Key Points:**
165
+ - Mutations are optimistic by default (UI updates immediately)
166
+ - Auto-syncs to PocketBase in background
167
+ - Batch mutations merge updates to same record
168
+ - Transaction states: pending → persisting → completed
169
+ - Use `newRecordId()` to generate PocketBase-compatible IDs
170
+
55
171
  ## Common Patterns
56
172
 
57
- **Approach 1: Type-Safe Expand (Recommended)**
173
+ **Approach 1: Auto-Expand (Recommended)**
58
174
  ```typescript
59
- const jobs = factory.create('jobs', { expand: 'customer,address' as const });
60
- // Single PocketBase query, server-side join, fully typed expand property
175
+ const c = createCollection<Schema>(pb, queryClient);
176
+ const authors = c('authors', {});
177
+ const books = c('books', {
178
+ expand: {
179
+ author: authors // Auto-expand and auto-upsert
180
+ }
181
+ });
182
+
183
+ // Expand is automatic - no .expand() call needed
184
+ const { data } = useLiveQuery((q) => q.from({ books }));
185
+
186
+ // Expanded records automatically inserted into authors collection
187
+ // data[0].expand?.author is typed!
61
188
  ```
62
189
 
63
- **Approach 2: TanStack Joins (Advanced)**
190
+ **When to use Auto-Expand:**
191
+ - You want expanded records to populate their own collections automatically
192
+ - Performance: Single server query with server-side expand
193
+ - Related data always available when fetching parent records
194
+
195
+ **Approach 2: TanStack Joins**
64
196
  ```typescript
65
- const jobs = factory.create('jobs', { relations: { customer: customersCollection }});
197
+ const c = createCollection<Schema>(pb, queryClient);
198
+ const collections = {
199
+ jobs: c('jobs', {}),
200
+ customers: c('customers', {}),
201
+ };
202
+ const { Provider, useStore } = createReactProvider(collections);
203
+
204
+ // In component
205
+ const [jobs, customers] = useStore('jobs', 'customers');
66
206
  // Client-side joins with full type safety, supports inner/left/right/full joins
67
207
  ```
68
208
 
69
209
  ## Critical Rules
70
210
 
71
211
  - NEVER use `any` types - defeats the purpose of this library
72
- - ALWAYS use `as const` on expand strings for type inference
73
- - Create ONE CollectionFactory instance per PocketBase connection
212
+ - useStore always returns an array - destructure it: `const [books] = useStore('books')`
213
+ - Create ONE set of collections per PocketBase connection
74
214
  - Schema must match actual PocketBase collection structure
75
215
  - Code should be self-documenting - avoid obvious comments
76
216
 
@@ -78,10 +218,10 @@ const jobs = factory.create('jobs', { relations: { customer: customersCollection
78
218
 
79
219
  ### When NOT to Use
80
220
 
81
- - Non-React environments (use PocketBase SDK directly)
82
221
  - Simple CRUD without real-time (PocketBase SDK is simpler)
83
222
  - Very large collections (>10k records - use pagination)
84
223
  - Non-PocketBase backends (use TanStack Query directly)
224
+ - Server-side only Node.js (use PocketBase SDK directly)
85
225
 
86
226
  ### Package Details
87
227
 
@@ -89,3 +229,4 @@ const jobs = factory.create('jobs', { relations: { customer: customersCollection
89
229
  - Collections use TanStack Query for caching and TanStack DB for reactivity
90
230
  - Real-time via PocketBase Server-Sent Events (SSE)
91
231
  - Automatic reconnection with exponential backoff on subscription failures
232
+ - Default syncMode is 'eager' (matches TanStack DB default)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pbtsdb",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Type-safe PocketBase integration with TanStack Query and TanStack DB",
5
5
  "keywords": [
6
6
  "pocketbase",
@@ -47,7 +47,7 @@
47
47
  "lint": "biome check .",
48
48
  "lint:fix": "biome check . --write",
49
49
  "typecheck": "tsc --noEmit --skipLibCheck",
50
- "test": "start-server-and-test test:server http://127.0.0.1:8210/api/health test:run",
50
+ "test": "start-server-and-test test:server http://127.0.0.1:8210/api/health 'vitest $TEST'",
51
51
  "test:run": "vitest",
52
52
  "test:server": "./scripts/start-test-server.sh",
53
53
  "test:server:migrate": "pocketbase migrate --dir ./pb_data"
@@ -61,24 +61,24 @@
61
61
  "react-dom": ">=18.0.0"
62
62
  },
63
63
  "devDependencies": {
64
- "@tanstack/query-db-collection": ">=1.0.0",
65
- "@tanstack/react-db": ">=0.1.0",
66
- "@tanstack/react-query": ">=5.0.0",
67
- "@testing-library/react": ">=14.0.0",
68
- "@types/node": ">=18.0.0",
69
- "@types/react": ">=18.0.0",
70
- "biome": ">=0.3.0",
71
- "dotenv": ">=16.0.0",
72
- "eventsource": ">=2.0.0",
73
- "jsdom": ">=20.0.0",
74
- "npm-run-all": ">=4.0.0",
75
- "pocketbase": ">=0.21.0",
76
- "react": ">=18.0.0",
77
- "react-dom": ">=18.0.0",
78
- "start-server-and-test": ">=2.0.0",
64
+ "@tanstack/query-db-collection": ">=1.0.5",
65
+ "@tanstack/react-db": ">=0.1.53",
66
+ "@tanstack/react-query": ">=5.90.11",
67
+ "@testing-library/react": ">=16.3.0",
68
+ "@types/node": ">=24.10.1",
69
+ "@types/react": ">=19.2.7",
70
+ "biome": ">=0.3.3",
71
+ "dotenv": ">=17.2.3",
72
+ "eventsource": ">=4.1.0",
73
+ "jsdom": ">=27.2.0",
74
+ "npm-run-all": ">=4.1.5",
75
+ "pocketbase": ">=0.26.3",
76
+ "react": ">=19.2.0",
77
+ "react-dom": ">=19.2.0",
78
+ "start-server-and-test": ">=2.1.3",
79
79
  "tsup": "^8.5.1",
80
- "tsx": ">=4.0.0",
81
- "typescript": ">=5.0.0",
82
- "vitest": ">=1.0.0"
80
+ "tsx": ">=4.21.0",
81
+ "typescript": ">=5.9.3",
82
+ "vitest": ">=4.0.14"
83
83
  }
84
84
  }