SinceRelease
uses tcmts.share.shareNow, which uses process
What changed under namespace since the history entry since (a package's last release), as the history has it:
each entry that edited, added, removed or renamed something there, newest first (of the latest 400), each a link to
its page with what it changed there; and how many definitions that is in all. Why a release waits, its API the same
or not.
import { historyList } from "#codebase/tcmts/cli/changes"; import { ago, at, entrySummary, Fold, shareNow } from "#codebase/tcmts/share"; import { entryTitle } from "#codebase/tcmts/store"; export function SinceRelease({ namespace, since, version }: { namespace: string; since: string; version: string }) { const s = shareNow(); const under = (n: string) => !namespace || n === namespace || n.startsWith(`${namespace}.`); const entries: { hash: string; title: string; ts: number; edited: number; added: number; removed: number }[] = []; const edited = new Set<string>(); const added = new Set<string>(); for (const h of historyList(s.cb, 400)) { if (h.hash === since) break; const e = entrySummary(s, h.hash); const ed = e.edited.filter(under); const ad = e.added.filter(under); const rm = e.removed.filter(under); if (!ed.length && !ad.length && !rm.length && !e.renamed.some((r) => under(r.to))) continue; for (const n of ed) edited.add(n); for (const n of ad) added.add(n); entries.push({ hash: h.hash, title: entryTitle(h), ts: h.ts, edited: ed.length, added: ad.length, removed: rm.length }); } if (!entries.length) return null; const row = (e: (typeof entries)[number]) => ( <a className="lrow tracerow" key={e.hash} href={at(`/history/${e.hash}`)}> <div> {e.title} <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}> {[e.edited && `${e.edited} edited`, e.added && `${e.added} added`, e.removed && `${e.removed} removed`] .filter(Boolean) .join(" · ") || "renamed"} </div> </div> <span className="muted">{ago(e.ts)}</span> </a> ); return ( <div className="box"> <div className="boxhead"> <b>Since {version}</b> <span className="muted"> {edited.size} definition{edited.size === 1 ? "" : "s"} edited and {added.size} added under {namespace}, in{" "} {entries.length} entr{entries.length === 1 ? "y" : "ies"} </span> </div> {entries.slice(0, 6).map(row)} {entries.length > 6 && ( <div className="tracerest"> <Fold head={<span className="muted">{entries.length - 6} more</span>}>{entries.slice(6).map(row)}</Fold> </div> )} </div> ); }
uses
- tcmts.cli.changes.historyList
- tcmts.share.Fold
- tcmts.share.ago
- tcmts.share.at
- tcmts.share.entrySummary
- tcmts.share.shareNow
- tcmts.store.entryTitle