UNPKG

@ldhop/react

Version:

Follow your nose through linked data resources - for React

103 lines 5.06 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { QueryAndStore, fetchRdfDocument, } from '@ldhop/core'; import { useQueries } from '@tanstack/react-query'; import isEqual from 'lodash/isEqual.js'; import mapValues from 'lodash/mapValues.js'; import { Quad, Store } from 'n3'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; const defaultGetAdditionalData = () => ({}); const areQuadsEqual = (q1, q2) => { if (q1.length !== q2.length) return false; const set1 = new Set(q1); return q2.every(q => set1.has(q)); }; export const useLDhopQuery = ({ query, variables, fetch, getQueryKey = resource => ['rdfDocument', resource], staleTime = Infinity, getAdditionalData = defaultGetAdditionalData, }) => { const variableSets = useMemo(() => mapValues(variables, array => new Set(array)), [variables]); const [resources, setResources] = useState([]); const [outputVariables, setOutputVariables] = useState({}); const [outputStore, setOutputStore] = useState(new Store()); const [outputQuads, setOutputQuads] = useState([]); const [isMissing, setIsMissing] = useState(false); const combine = useCallback((results) => { var _a; return (Object.assign(Object.assign({}, ((_a = getAdditionalData(results)) !== null && _a !== void 0 ? _a : {})), { data: Object.fromEntries(results.map((result, i) => [resources[i], result === null || result === void 0 ? void 0 : result.data])), pending: results.some(result => result.isPending) })); }, [getAdditionalData, resources]); const results = useQueries({ queries: resources.map(resource => ({ queryKey: getQueryKey(resource), queryFn: () => fetchRdfDocument(resource, fetch), staleTime, })), combine, }); const qas = useRef(new QueryAndStore(query, variableSets)); const lastResults = useRef(results.data); // if query or variables change, restart the query useEffect(() => { qas.current = new QueryAndStore(query, variableSets); const missingResources = qas.current.getMissingResources(); setResources(missingResources); setOutputStore(qas.current.store); lastResults.current = {}; }, [query, variableSets]); useEffect(() => { if (!results) return; for (const resource in results.data) { const result = results.data[resource]; if (!result) continue; const lastResource = lastResults.current[resource]; // find results that weren't added, yet if ((lastResource === null || lastResource === void 0 ? void 0 : lastResource.hash) === result.hash) continue; // put them to QueryAndStore qas.current.addResource(resource, result.data, result.ok ? 'success' : 'error'); } // get resources that weren't added, and add them to resources const missingResources = qas.current.getMissingResources(); setIsMissing(missingResources.length > 0); setResources(resources => { const newResources = []; for (const r of missingResources) if (!resources.includes(r)) newResources.push(r); if (newResources.length === 0) return resources; else return newResources.concat(resources); }); const nextOutputVariables = mapValues(qas.current.getAllVariables(), uriSet => Array.from(uriSet)); setOutputVariables(outputVariables => isEqual(nextOutputVariables, outputVariables) ? outputVariables : nextOutputVariables); setOutputStore(qas.current.store); const nextOutputQuads = [...qas.current.store]; setOutputQuads(outputQuads => areQuadsEqual(outputQuads, nextOutputQuads) ? outputQuads : nextOutputQuads); lastResults.current = results.data; }, [results]); // eslint-disable-next-line @typescript-eslint/no-unused-vars const _a = results, { data, pending } = _a, rest = __rest(_a, ["data", "pending"]); return useMemo(() => (Object.assign({ store: outputStore, quads: outputQuads, variables: outputVariables, qas: qas.current, isLoading: results === null || results === void 0 ? void 0 : results.pending, isMissing }, rest)), [ isMissing, outputQuads, outputStore, outputVariables, rest, results === null || results === void 0 ? void 0 : results.pending, ]); }; //# sourceMappingURL=useLDhopQuery.js.map