CodebasePage

tcmts.registry.pages.CodebasePage · #tr5xqmx7 · term · runs on the server

is an async component

A listed codebase: its README, and its code (its namespaces and definitions, each opening on the forge's pages in the registry's frame), as the registry last mirrored its main branch; beside them, the server it's at, how to get it, and when it was mirrored.

import { shellWord } from "#codebase/tcmts/cli/ui";
import {
  codebaseBrowseHref, codebaseHost, codebaseHref, codebases, registryShare, said, whoHref, whoIs,
} from "#codebase/tcmts/registry";
import { NotHere, RegistryFrame } from "#codebase/tcmts/registry/pages";
import {
  ago, at, childrenOf, codeHref, CopyButton, DefRow, Html, leafOf, markdownHtml, NavTabs, shareNow, Trail,
} from "#codebase/tcmts/share";

export async function CodebasePage({
  who: asked,
  name,
  tab,
}: {
  who: string;
  name: string;
  tab: string;
}) {
  registryShare();
  const who = await whoIs(asked);
  if (!who) return <NotHere what={`The registry doesn't know @${asked}.`} />;
  const c = (await codebases.find({ did: who.did, state: "verified" }))
    .map((x) => x.value)
    .find((x) => x.name === name);
  if (!c) return <NotHere what={`${said(who)} doesn't list a codebase called ${name}.`} />;
  const s = shareNow();
  const cb = s.cb;
  const rows = c.mount
    ? cb.store.names(undefined, true).filter((r) => r.path.startsWith(`${c.mount}.`))
    : [];
  const { namespaces, defs } = c.mount ? childrenOf(rows, c.mount) : { namespaces: [], defs: [] };
  const readme = defs.find((r) => leafOf(r.path) === "README" && r.kind === "file");
  const shown = tab === "code" || (!tab && !readme) ? "code" : "readme";
  const remoteAdd = `tcm remote add ${name} ${shellWord(c.url)}`;
  return (
    <RegistryFrame tab="codebases" title={`${said(who)}/${name}`}>
      <div className="page cols-2">
        <div>
          <div className="crumbs">
            <Trail
              items={[
                { label: "Codebases", href: at("/codebases") },
                { label: said(who), href: whoHref(who) },
                { label: name },
              ]}
            />
          </div>
          <div className="libhead">
            <h1 className="title mono">{name}</h1>
            <span className="signed">✓ signed by {said(who)}</span>
          </div>
          {c.description && <p className="lede">{c.description}</p>}
          <div className="facts">
            <span className="mono">{codebaseHost(c)}</span>
            <span>listed {ago(Date.parse(c.createdAt))}</span>
            {c.mount && (
              <span>
                {rows.length.toLocaleString("en")} definition{rows.length === 1 ? "" : "s"}
              </span>
            )}
            {c.fetchedAt && <span>mirrored {ago(c.fetchedAt.getTime())}</span>}
          </div>
          {!c.mount && !c.reason && (
            <div className="notice">
              ⋯ Mirroring: fetching its main branch from its server and checking every hash; its
              code appears when that's done.
            </div>
          )}
          {c.reason && (
            <div className="notice bad">
              ⚠ {c.mount ? "Not mirrored again" : "Not mirrored"}: {c.reason}.
              {c.mount ? " What's shown is its main branch as it was mirrored before." : ""}
            </div>
          )}
          <div className="subtabs">
            <NavTabs
              label="Codebase"
              selected={shown}
              tabs={[
                { id: "readme", label: "README", href: codebaseHref(who, name, "readme") },
                {
                  id: "code",
                  label: "Code",
                  href: codebaseHref(who, name, "code"),
                  count: rows.length,
                },
              ]}
            />
          </div>
          {shown === "readme" &&
            (readme ? (
              <div className="box">
                <Html
                  className="boxbody md"
                  html={markdownHtml(cb, cb.store.getDef(readme.hash)?.sourceText ?? "")}
                />
              </div>
            ) : (
              <div className="empty">{c.description || `${name} has no README.`}</div>
            ))}
          {shown === "code" &&
            (rows.length ? (
              <>
                {namespaces.length > 0 && (
                  <div className="box">
                    <div className="boxhead">
                      <b>Namespaces</b>
                      <span className="muted">{namespaces.length}</span>
                    </div>
                    {[...namespaces]
                      .sort((a, b) => (a.name < b.name ? -1 : 1))
                      .map((n) => (
                        <div className="nsrow" key={n.name}>
                          <a className="mono" href={codeHref(n.name)}>
                            {leafOf(n.name)}
                          </a>
                          <span className="sig">{`${n.rows.length.toLocaleString("en")} definition${n.rows.length === 1 ? "" : "s"}`}</span>
                        </div>
                      ))}
                  </div>
                )}
                {defs.length > 0 && (
                  <div className="box">
                    {defs.map((r) => (
                      <DefRow key={r.path} row={r} />
                    ))}
                  </div>
                )}
              </>
            ) : (
              <div className="empty">Its code isn't here yet.</div>
            ))}
        </div>
        <div className="side">
          <div className="sect">
            <h4>Served at</h4>
            <div>
              <a className="mono" href={codebaseBrowseHref(c)} rel="nofollow noopener">
                {c.url}
              </a>
            </div>
            <div className="muted">
              its own web UI: history, contributions and the code as it is now
            </div>
          </div>
          <div className="sect">
            <h4>Get it</h4>
            <div className="copy">
              <code>{remoteAdd}</code>
              <CopyButton text={remoteAdd} label="Copy" />
            </div>
            <div className="muted">
              then <code>tcm pull {name}</code>
            </div>
          </div>
          {c.head && (
            <div className="sect">
              <h4>Mirrored</h4>
              <div>
                main at <span className="hash">{c.head.slice(0, 8)}</span>
              </div>
            </div>
          )}
        </div>
      </div>
    </RegistryFrame>
  );
}

uses

used by