@tanstack/react-db
Version:
React integration for @tanstack/db
87 lines (84 loc) • 3.44 kB
JavaScript
import { useRef, useSyncExternalStore } from "react";
import { isCollection, BaseQueryBuilder, createLiveQueryCollection, createLiveQueryObserver } from "@tanstack/db";
const DEFAULT_GC_TIME_MS = 1;
function useLiveQuery(configOrQueryOrCollection, deps = []) {
const inputIsCollection = isCollection(configOrQueryOrCollection);
const collectionRef = useRef(
null
);
const depsRef = useRef(null);
const configRef = useRef(null);
const observerRef = useRef(
null
);
const needsNewCollection = !collectionRef.current || inputIsCollection && configRef.current !== configOrQueryOrCollection || !inputIsCollection && (depsRef.current === null || depsRef.current.length !== deps.length || depsRef.current.some((dep, i) => dep !== deps[i]));
if (needsNewCollection) {
if (inputIsCollection) {
const syncMode = configOrQueryOrCollection.config?.syncMode;
if (syncMode === `on-demand`) {
console.warn(
`[useLiveQuery] Warning: Passing a collection with syncMode "on-demand" directly to useLiveQuery will not load any data. In on-demand mode, data is only loaded when queries with predicates request it.
Instead, use a query builder function:
const { data } = useLiveQuery((q) => q.from({ c: myCollection }).select(({ c }) => c))
Or switch to syncMode "eager" if you want all data to sync automatically.`
);
}
configOrQueryOrCollection.startSyncImmediate();
collectionRef.current = configOrQueryOrCollection;
configRef.current = configOrQueryOrCollection;
} else {
if (typeof configOrQueryOrCollection === `function`) {
const queryBuilder = new BaseQueryBuilder();
const result = configOrQueryOrCollection(queryBuilder);
if (result === void 0 || result === null) {
collectionRef.current = null;
} else if (isCollection(result)) {
result.startSyncImmediate();
collectionRef.current = result;
} else if (result instanceof BaseQueryBuilder) {
collectionRef.current = createLiveQueryCollection({
query: configOrQueryOrCollection,
startSync: true,
gcTime: DEFAULT_GC_TIME_MS
});
} else if (result && typeof result === `object`) {
collectionRef.current = createLiveQueryCollection({
startSync: true,
gcTime: DEFAULT_GC_TIME_MS,
...result
});
} else {
throw new Error(
`useLiveQuery callback must return a QueryBuilder, LiveQueryCollectionConfig, Collection, undefined, or null. Got: ${typeof result}`
);
}
depsRef.current = [...deps];
} else {
collectionRef.current = createLiveQueryCollection({
startSync: true,
gcTime: DEFAULT_GC_TIME_MS,
...configOrQueryOrCollection
});
depsRef.current = [...deps];
}
}
}
if (needsNewCollection) {
observerRef.current = createLiveQueryObserver(collectionRef.current, {
mode: `wholesale`
});
}
const observer = observerRef.current;
const subscribeRef = useRef(null);
if (!subscribeRef.current || needsNewCollection) {
subscribeRef.current = (onStoreChange) => observer.subscribe(() => onStoreChange());
}
return useSyncExternalStore(
subscribeRef.current,
() => observer.getSnapshot()
);
}
export {
useLiveQuery
};
//# sourceMappingURL=useLiveQuery.js.map