@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
67 lines (66 loc) • 2.89 kB
JavaScript
import { useEffect, useMemo, useRef } from "react";
import { arrayShallow } from "@1771technologies/lytenyte-shared";
import { useEvent } from "@1771technologies/lytenyte-core/internal";
import { ServerData } from "../server-data.js";
export function useSource(props, s, globalSignal) {
const prevQueryKeyRef = useRef(null);
const queryKey = useMemo(() => {
const current = prevQueryKeyRef.current;
if (!current) {
prevQueryKeyRef.current = props.queryKey;
return prevQueryKeyRef.current;
}
if (!arrayShallow(current, props.queryKey)) {
prevQueryKeyRef.current = props.queryKey;
}
return prevQueryKeyRef.current;
}, [props.queryKey]);
const queryFn = useEvent(props.queryFn);
const dataFetcher = useMemo(() => {
const fetcher = (req, expansions) => {
const model = { rowGroupExpansions: expansions };
return queryFn({ model, queryKey, reqTime: Date.now(), requests: req });
};
return fetcher;
}, [queryFn, queryKey]);
const sourceRef = useRef(null);
if (!sourceRef.current) {
sourceRef.current = new ServerData({
defaultExpansion: props.rowGroupDefaultExpansion ?? false,
blocksize: props.blockSize ?? 200,
expansions: s.expansions,
onResetLoadBegin: () => {
s.setIsLoading(true);
s.setLoadingError(null);
},
// I know what I am about. This is fine, we only care the global signal has changed.
// eslint-disable-next-line react-hooks/purity
onInvalidate: () => globalSignal(Date.now()),
onResetLoadEnd: () => s.setIsLoading(false),
onResetLoadError: (e) => s.setLoadingError(e),
onFlatten: (f) => {
s.setTopCount(f.top);
s.setBotCount(f.bottom);
s.setRowCount(f.center + f.top + f.bottom);
s.setMaxDepth(f.maxDepth);
s.setRows(f.rowIndexToRow);
s.setIdUniverse(new Set(f.tree.rowIdToNode.keys()));
// Not sure why this is being flagged. This is not being used in hook. This is also fine. We don't
// actually care about the value, just that it will be different from the previous value.
// eslint-disable-next-line react-hooks/purity
globalSignal(Date.now());
},
});
}
useEffect(() => {
sourceRef.current.dataFetcher = dataFetcher;
}, [dataFetcher]);
const prevExpansions = useRef(s.expansions);
useEffect(() => {
if (prevExpansions.current === s.expansions)
return;
prevExpansions.current = s.expansions;
sourceRef.current.expansions = s.expansions;
}, [s.expansions]);
return sourceRef.current;
}