@ldhop/react
Version:
Follow your nose through linked data resources - for React
106 lines • 5.12 kB
JavaScript
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));
};
/**
* @deprecated Please use useLdhopQuery instead.
*/
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=useLDhopQueryLegacy.js.map