UNPKG

@tanstack/react-db

Version:

React integration for @tanstack/db

91 lines (90 loc) 3.49 kB
import { useRef, useSyncExternalStore } from "react"; import { createLiveQueryCollection } from "@tanstack/db"; function useLiveQuery(configOrQueryOrCollection, deps = []) { const isCollection = configOrQueryOrCollection && typeof configOrQueryOrCollection === `object` && typeof configOrQueryOrCollection.subscribeChanges === `function` && typeof configOrQueryOrCollection.startSyncImmediate === `function` && typeof configOrQueryOrCollection.id === `string`; const collectionRef = useRef(null); const depsRef = useRef(null); const configRef = useRef(null); const needsNewCollection = !collectionRef.current || isCollection && configRef.current !== configOrQueryOrCollection || !isCollection && (depsRef.current === null || depsRef.current.length !== deps.length || depsRef.current.some((dep, i) => dep !== deps[i])); if (needsNewCollection) { if (isCollection) { configOrQueryOrCollection.startSyncImmediate(); collectionRef.current = configOrQueryOrCollection; configRef.current = configOrQueryOrCollection; } else { if (typeof configOrQueryOrCollection === `function`) { collectionRef.current = createLiveQueryCollection({ query: configOrQueryOrCollection, startSync: true, gcTime: 0 // Live queries created by useLiveQuery are cleaned up immediately }); } else { collectionRef.current = createLiveQueryCollection({ startSync: true, gcTime: 0, // Live queries created by useLiveQuery are cleaned up immediately ...configOrQueryOrCollection }); } depsRef.current = [...deps]; } } const versionRef = useRef(0); const snapshotRef = useRef(null); if (needsNewCollection) { versionRef.current = 0; snapshotRef.current = null; } const subscribeRef = useRef(null); if (!subscribeRef.current || needsNewCollection) { subscribeRef.current = (onStoreChange) => { const unsubscribe = collectionRef.current.subscribeChanges(() => { versionRef.current += 1; onStoreChange(); }); return () => { unsubscribe(); }; }; } const getSnapshotRef = useRef(null); if (!getSnapshotRef.current || needsNewCollection) { getSnapshotRef.current = () => { const currentVersion = versionRef.current; const currentCollection = collectionRef.current; if (!snapshotRef.current || snapshotRef.current._version !== currentVersion) { snapshotRef.current = { get state() { return new Map(currentCollection.entries()); }, get data() { return Array.from(currentCollection.values()); }, collection: currentCollection, _version: currentVersion }; } return snapshotRef.current; }; } const snapshot = useSyncExternalStore( subscribeRef.current, getSnapshotRef.current ); return { state: snapshot.state, data: snapshot.data, collection: snapshot.collection, status: snapshot.collection.status, isLoading: snapshot.collection.status === `loading` || snapshot.collection.status === `initialCommit`, isReady: snapshot.collection.status === `ready`, isIdle: snapshot.collection.status === `idle`, isError: snapshot.collection.status === `error`, isCleanedUp: snapshot.collection.status === `cleaned-up` }; } export { useLiveQuery }; //# sourceMappingURL=useLiveQuery.js.map