rescribet/link-redux

View on GitHub
src/hooks/useResourceLinks.ts

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
import { Node } from "@ontologies/core";
import { normalizeType} from "link-lib";
import React from "react";

import { useMemoizedDataSubjects } from "../helpers";
import { dataPropsToPropMap } from "../hocs/link/dataPropsToPropMap";
import { globalLinkOptsDefaults } from "../hocs/link/globalLinkOptsDefaults";
import {
  ArityPreservingPropSet,
  LaxNode,
  LinkedDataObject,
  LinkOpts,
  MapDataToPropsParam,
  TermOpts,
} from "../types";
import { useDataInvalidation } from "./useDataInvalidation";

import { useLRS } from "./useLRS";
import { useManyLinkedObjectProperties } from "./useManyLinkedObjectProperties";

export function useResourceLinks<
  T extends MapDataToPropsParam = {},
  D extends LinkOpts = TermOpts,
>(
  subjects: LaxNode | Node[],
  mapDataToProps: T,
  opts?: D,
): Array<LinkedDataObject<T, D>> {
  const defaultedOpts = opts ?? (globalLinkOptsDefaults as D);

  const lrs = useLRS();
  const dataSubjects = normalizeType(subjects);
  const lastUpdate = useDataInvalidation(dataSubjects);

  const [propMap, requestedProperties] = React.useMemo(
    () => dataPropsToPropMap(mapDataToProps, defaultedOpts),
    [mapDataToProps, opts],
  );

  const propSets: ArityPreservingPropSet[] = React.useMemo(
    () => dataSubjects.map((subject) => {
      if (!subject) { return [subject, undefined]; }

      const record = lrs.tryRecord(subject);

      return [subject.value, record ?? { _id: subject }];
    }),
    [
      lrs,
      useMemoizedDataSubjects(dataSubjects),
      requestedProperties,
      lastUpdate,
    ],
  );

  return useManyLinkedObjectProperties<typeof propMap, any, LinkedDataObject<T, D>>(
    propSets,
    propMap,
    defaultedOpts.returnType,
  );
}