CodeMapPanel

tcmts.share.CodeMapPanel · #222gya27 · component · runs in the browser

uses useMemo

Beside the code map: what's chosen in it. With nothing chosen, the clouds and the most used definitions; a cloud (or a namespace in it), what it's made of, the clouds it's most tied to, what's most used in it and what's used mostly from elsewhere; a definition, its doc, what it uses and what uses it. Each item picks what it names.

import { cloudHues, codeHref, CodeMapDoc, CodeMapRow, Place } from "#codebase/tcmts/share";
import type { CodeMap, MapFocus } from "#codebase/tcmts/share";
import { useMemo } from "react";

export function CodeMapPanel({
  map,
  lens,
  focus,
  pick,
}: {
  map: CodeMap;
  lens: "clusters" | "namespaces";
  focus: MapFocus | null;
  pick: (f: MapFocus) => void;
}) {
  const L = map[lens];
  const usedBy = useMemo(() => {
    const u = map.dots.map(() => [] as number[]);
    for (let k = 0; k < map.refs.length; k += 2) u[map.refs[k + 1]!]!.push(map.refs[k]!);
    return u;
  }, [map]);
  const uses = useMemo(() => {
    const u = map.dots.map(() => [] as number[]);
    for (let k = 0; k < map.refs.length; k += 2) u[map.refs[k]!]!.push(map.refs[k + 1]!);
    return u;
  }, [map]);
  const name = (j: number) => map.dots[j]!.path.slice(map.dots[j]!.path.lastIndexOf(".") + 1);
  const dot = (j: number) => ({ dot: j, cloud: L.cloud[j]! });
  const hues = useMemo(() => cloudHues(L), [L]);
  const swatch = (c: number) => (
    <span className="cmswatch" style={{ color: (hues[c] ?? -1) < 0 ? "var(--cm-loose)" : `var(--cm${hues[c]})` }} />
  );
  const mostUsed = (js: number[], k = 6) => [...js].sort((a, b) => usedBy[b]!.length - usedBy[a]!.length).slice(0, k);
  if (!focus) {
    return (
      <>
        <div className="kind">Codebase</div>
        <p className="muted">
          {map.dots.length.toLocaleString("en")} definition{map.dots.length === 1 ? "" : "s"},{" "}
          {(map.refs.length / 2).toLocaleString("en")} reference{map.refs.length === 2 ? "" : "s"} between them.{" "}
          {lens === "clusters"
            ? "Each cloud is a group that references itself more than the rest, named for the namespaces most of it is in; the puffs in it are those namespaces."
            : "Each cloud is a namespace, the puffs in it the namespaces under it."}{" "}
          A star's size is how much it's used.
        </p>
        <h4>Clouds</h4>
        <ul className="cmlist">
          {L.clouds.slice(0, 12).map((c, ci) => (
            <CodeMapRow key={ci} onPick={() => pick({ cloud: ci })} count={c.n}>
              {swatch(ci)}
              {c.label}
            </CodeMapRow>
          ))}
        </ul>
        <h4>Most used</h4>
        <ul className="cmlist">
          {mostUsed([...map.dots.keys()]).map((j) => (
            <CodeMapRow key={j} onPick={() => pick(dot(j))} count={usedBy[j]!.length}>
              <span className="mono">{name(j)}</span>
            </CodeMapRow>
          ))}
        </ul>
      </>
    );
  }
  if (focus.dot !== undefined) {
    const d = map.dots[focus.dot]!;
    const home = L.cloud[focus.dot]!;
    const refs = (js: number[], none: string) =>
      js.length ? (
        <ul className="cmlist">
          {mostUsed(js, 12).map((j) => (
            <CodeMapRow key={j} onPick={() => pick(dot(j))}>
              <span className="mono">{map.dots[j]!.path}</span>
            </CodeMapRow>
          ))}
          {js.length > 12 && <li className="muted">and {js.length - 12} more</li>}
        </ul>
      ) : (
        <p className="muted">{none}</p>
      );
    return (
      <>
        <div className="kind">{d.type ? "Type" : "Definition"}</div>
        <h3 className="mono">
          <a href={codeHref(d.path)}>{d.path}</a>
        </h3>
        <CodeMapDoc path={d.path} />
        <p className="muted">
          {d.place && <Place place={d.place} label />} in {swatch(home)}
          {L.clouds[home]!.label}
        </p>
        <h4>
          Uses <span className="muted">{uses[focus.dot]!.length}</span>
        </h4>
        {refs(uses[focus.dot]!, "Nothing in the codebase.")}
        <h4>
          Used by <span className="muted">{usedBy[focus.dot]!.length}</span>
        </h4>
        {refs(usedBy[focus.dot]!, "Nothing: an entry point, or unused.")}
      </>
    );
  }
  const c = L.clouds[focus.cloud]!;
  const p = focus.puff !== undefined ? c.puffs[focus.puff] : undefined;
  const members = [...map.dots.keys()].filter((j) => L.cloud[j] === focus.cloud && (focus.puff === undefined || L.puff[j] === focus.puff));
  const tied = L.links.filter(([a, b]) => a === focus.cloud || b === focus.cloud).slice(0, 6);
  // (what's used mostly from another cloud: it may belong there)
  const strays = members.flatMap((j) => {
    const users = usedBy[j]!;
    if (users.length < 3) return [];
    const by = new Map<number, number>();
    for (const u of users) by.set(L.cloud[u]!, (by.get(L.cloud[u]!) ?? 0) + 1);
    const [other, k] = [...by].sort((a, b) => b[1] - a[1])[0]!;
    return other !== focus.cloud && k / users.length > 0.7 ? [[j, other] as const] : [];
  });
  const ns = p?.ns ?? c.ns;
  return (
    <>
      <div className="kind">{p ? `Namespace in ${c.label}` : lens === "clusters" ? "Cloud" : "Namespace"}</div>
      <h3 className={p || lens === "namespaces" ? "mono" : ""}>
        {swatch(focus.cloud)}
        {p ? p.ns : c.label}
      </h3>
      <p className="muted">
        {(p ?? c).n.toLocaleString("en")} definitions
        {!p && ` in ${c.puffs.length} namespace${c.puffs.length === 1 ? "" : "s"}`}
        {ns !== undefined && (
          <>
            {" · "}
            <a href={codeHref(ns)}>namespace page</a>
          </>
        )}
      </p>
      {!p && (
        <>
          <h4>Made of</h4>
          <ul className="cmlist">
            {c.puffs.slice(0, 8).map((q, pi) => (
              <CodeMapRow key={q.ns} onPick={() => pick({ cloud: focus.cloud, puff: pi })} count={q.n}>
                <span className="mono">{q.label}</span>
              </CodeMapRow>
            ))}
            {c.puffs.length > 8 && <li className="muted">and {c.puffs.length - 8} more</li>}
          </ul>
          {tied.length > 0 && (
            <>
              <h4>Most tied to</h4>
              <ul className="cmlist">
                {tied.map(([a, b, w]) => {
                  const o = a === focus.cloud ? b : a;
                  return (
                    <CodeMapRow key={o} onPick={() => pick({ cloud: o })} count={w}>
                      {swatch(o)}
                      {L.clouds[o]!.label}
                    </CodeMapRow>
                  );
                })}
              </ul>
            </>
          )}
        </>
      )}
      <h4>Most used here</h4>
      <ul className="cmlist">
        {mostUsed(members).map((j) => (
          <CodeMapRow key={j} onPick={() => pick(dot(j))} count={usedBy[j]!.length}>
            <span className="mono">{name(j)}</span>
          </CodeMapRow>
        ))}
      </ul>
      {strays.length > 0 && (
        <>
          <h4>
            Used mostly from elsewhere <span className="muted">{strays.length}</span>
          </h4>
          <p className="muted small">Most of what uses these is in another cloud: they may belong there.</p>
          <ul className="cmlist">
            {strays.slice(0, 6).map(([j, o]) => (
              <CodeMapRow key={j} onPick={() => pick(dot(j))} count={`→ ${L.clouds[o]!.label}`}>
                <span className="mono">{name(j)}</span>
              </CodeMapRow>
            ))}
          </ul>
        </>
      )}
    </>
  );
}

uses

used by