@tanstack/react-db
Version:
React integration for @tanstack/db
91 lines (90 loc) • 3.49 kB
JavaScript
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