DefinitionView

tcmts.share.DefinitionView · #ceqaab7p · term · runs on the server

uses tcmts.share.shareNow, which uses process

A definition: its doc and code (references linked, their types shown on hover), what uses it; beside them what only a codebase knows: what it uses, the tests that reach it, its history, its other names, the releases it's in.

import { isBytes } from "#codebase/tcmts/cli/files";
import { isManifestPath } from "#codebase/tcmts/cli/manifests";
import { esc } from "#codebase/tcmts/cli/pages";
import { isTestPath } from "#codebase/tcmts/cli/testing";
import {
  ago, at, CodeBox, codeHref, CopyButton, Crumbs, Frame, Html, htmlLines, leafOf, linkRefs, markdownHtml, nameHistory,
  NamespaceView, outcomeOf, PackageBox, pageOf, parentOf, Place, projectNow, releaseHas, shareNow, testsReaching,
} from "#codebase/tcmts/share";
import { Link, Toolbar } from "react-aria-components";

export function DefinitionView({ name, hash }: { name: string; hash: string }) {
  const s = shareNow();
  const p = pageOf(s, hash);
  if (!p) return <NamespaceView ns={name} />;
  const rec = s.cb.store.getDef(hash)!;
  const placement = s.cache.placement(s.cb);
  // (which tests reach it follows the names; whether they pass, their results, which come without the names moving)
  const tests =
    rec.kind === "file"
      ? []
      : s.cache
          .atHead(s.cb, `tests ${hash}`, () => testsReaching(s.cb, hash))
          .map((t) => ({ path: t.path, hash: t.hash, ...outcomeOf(s.cb, t.hash) }));
  const log = s.cache.atHead(s.cb, `log ${name}`, () => nameHistory(s, name));
  const inReleases = s.cb.store.releases().filter((r) => releaseHas(s, r.causal, hash));
  const others = p.names.filter((n) => n !== name);
  const pkg = isManifestPath(name)
    ? projectNow(s).packages.find((x) => x.manifestPath === name)
    : undefined;
  const kind =
    rec.kind === "file"
      ? `${p.format || "a"} file`
      : rec.kind === "type"
        ? "type"
        : (p.signature ?? "");
  return (
    <Frame tab="code" title={name}>
      <div className="page cols-2">
        <div>
          <div className="crumbs">
            <Crumbs name={name} />
          </div>
          <div className="filters" style={{ marginBottom: 6 }}>
            <span style={{ fontSize: 22, fontWeight: 600, overflowWrap: "anywhere" }}>
              {leafOf(name)}
            </span>
            {p.test ? (
              <span className="chip">
                {p.test === "passed"
                  ? "✓ test passes"
                  : p.test === "failed"
                    ? "✗ test fails"
                    : "test, not run here"}
              </span>
            ) : (
              <Place place={p.place} label />
            )}
            <span className="hash">{p.short}</span>
            <Toolbar aria-label="Definition" className="right actions">
              <CopyButton text={name} label="Copy name" />
              <CopyButton text={`tcm edit ${name}`} label="Edit with tcm" />
            </Toolbar>
          </div>
          {p.why && (
            <p className="muted" style={{ margin: "0 0 10px" }}>
              {String(p.why)}
            </p>
          )}
          {rec.kind !== "file" && p.docMarkdown && (
            <Html className="md" html={markdownHtml(s.cb, p.docMarkdown)} />
          )}
          {pkg && <PackageBox pkg={pkg} />}
          <div style={{ marginTop: 14 }}>
            {rec.kind === "file" && isBytes(rec) ? (
              <div className="box">
                <div className="boxhead">
                  <span className="mono sighead">{kind}</span>
                </div>
                {p.image ? (
                  <div className="boxbody">
                    <img src={p.image} alt={name} style={{ maxWidth: "100%" }} />
                  </div>
                ) : (
                  <Html className="boxbody muted" html={p.sourceHtml ?? ""} />
                )}
              </div>
            ) : rec.kind === "file" ? (
              <CodeBox
                head={<span className="mono sighead">{kind}</span>}
                lines={htmlLines(p.sourceHtml ?? esc(rec.sourceText))}
                preview={
                  p.docMarkdown ? (
                    <Html className="boxbody md" html={markdownHtml(s.cb, p.docMarkdown)} />
                  ) : p.image ? (
                    <div className="boxbody">
                      <img src={p.image} alt={name} style={{ maxWidth: "100%" }} />
                    </div>
                  ) : undefined
                }
              />
            ) : p.sourceHtml ? (
              <CodeBox
                head={
                  <span className="mono sighead" title={kind}>
                    {kind}
                  </span>
                }
                lines={htmlLines(linkRefs(s.cb, p.sourceHtml))}
              />
            ) : null}
          </div>
          <div className="box">
            <div className="boxhead">
              <b>Used by</b>
              <span className="count">{p.usedBy.length}</span>
              <span className="right muted">a change here re-hashes these</span>
            </div>
            {p.usedBy.length ? (
              p.usedBy.map((u) => (
                <div className="drow full" key={u.name}>
                  <Place
                    place={
                      u.kind === "term" && !isTestPath(u.name)
                        ? placement.placeOf(u.hash).place
                        : undefined
                    }
                  />
                  <a className="mono" href={codeHref(u.name)}>
                    {u.name}
                  </a>
                  <span className="sig">
                    {u.kind === "file" ? "file" : u.kind === "type" ? "type" : (u.signature ?? "")}
                  </span>
                </div>
              ))
            ) : (
              <div className="empty">Nothing uses it.</div>
            )}
          </div>
        </div>
        <aside className="side">
          <div className="sect">
            <h4>Uses</h4>
            {p.uses.length ? (
              p.uses.map((u) => (
                <div key={u.name}>
                  <a className="mono" href={codeHref(u.name)}>
                    {u.name}
                  </a>
                </div>
              ))
            ) : (
              <span className="muted">Nothing in the codebase.</span>
            )}
          </div>
          {tests.length > 0 && (
            <div className="sect">
              <h4>Tests that reach it</h4>
              {tests.slice(0, 12).map((t) => (
                <div className="tick" key={t.path}>
                  {t.ok === undefined ? (
                    <span className="muted" title="not run here">
                      ○
                    </span>
                  ) : t.ok ? (
                    <span className="ok" title="passes">
                      ✓
                    </span>
                  ) : (
                    <span className="bad" title="fails">
                      ✗
                    </span>
                  )}
                  <a className="mono" href={codeHref(t.path)} title={t.path}>
                    {leafOf(t.path)}
                  </a>
                </div>
              ))}
              {tests.length > 12 && <span className="muted">+ {tests.length - 12} more</span>}
            </div>
          )}
          <div className="sect">
            <h4>History</h4>
            {log.length ? (
              log.map((e) => (
                <div className="hist" key={e.causal}>
                  <span
                    className={`badge ${e.change === "added" ? "b-new" : e.change === "removed" ? "b-rm" : "b-edit"}`}
                  >
                    {e.change}
                  </span>
                  <span>
                    <a href={at(`/history/${e.causal}`)} style={{ color: "var(--fg)" }}>
                      {e.command}
                    </a>
                    <span className="when">{ago(e.ts)}</span>
                  </span>
                </div>
              ))
            ) : (
              <span className="muted">No entries.</span>
            )}
          </div>
          <div className="sect">
            <h4>Also named</h4>
            {others.length ? (
              others.map((n) => (
                <div key={n}>
                  <a className="mono" href={codeHref(n)}>
                    {n}
                  </a>
                </div>
              ))
            ) : (
              <span className="muted">No other names. A rename keeps the hash.</span>
            )}
          </div>
          <div className="sect">
            <h4>In a release</h4>
            {inReleases.length ? (
              inReleases.map((r) => (
                <div key={`${r.package}@${r.version}`}>
                  <a href={at(`/releases#${r.package}@${r.version}`)}>
                    {r.package} {r.version}
                  </a>
                </div>
              ))
            ) : (
              <span className="muted">Not in one yet.</span>
            )}
          </div>
        </aside>
      </div>
      <div className="dock">
        <Link className="btn" href={codeHref(parentOf(name))}>
          ↑ {leafOf(parentOf(name)) || "Up"}
        </Link>
        <CopyButton text={name} label="Copy name" />
      </div>
    </Frame>
  );
}

uses

used by