tcmts.share

test/
6 definitions

Apps

App () => Element
The web UI a `tcm serve` server shows (`/forge/`): a codebase's front page, namespaces and definitions, search, contributions and their review, history, branches, releases and people. Each page renders on the server from the codebase it serves (`TCM_SHARE_CODEBASE`, or this app's own, under `tcm dev`); links between them are followed in the app. `tcm dev tcmts.share.App` serves tcm's own codebase while you work on it.

Types

ContributionChanges type
What a contribution changes: from where its branch left its target (or, once merged, what the merge brought).
DiffRow type
A row of a diff as a page shows it: a line (added, removed or unchanged; its numbers before and after; its HTML), or a run of `gap` lines left out (`cut`: the end of one cut short).
EntrySummary type
What one history entry changed, by name.
NameChange type
A name whose hashes differ between two namespaces: what it pointed at in each (none: it wasn't there).
NameTreeNode type
A namespace node as NameTrees keeps it: its names' hashes and the nodes in it, by name.
NameTrees typeof NameTrees
A codebase's history entries' names, read as the trees they're stored as. A namespace node's hash is its content's, so two entries' names differ only under nodes whose hashes differ, and comparing them reads only those; one name is a walk down its path. What's read is kept (a node never changes), and so are the last few entries' names, each made from the names asked for before it and what changed between them: walking a branch's history back reads each step's changes, not every name of every entry.
PackageInfo type
A package a codebase declares, as its manifest's source says it: read, never run (a page runs no code).
PageError typeof PageError
What a page shows if it doesn't load (the server failed or refused it, or is unreachable): what went wrong and a way to try again, not a blank page. Going to another page tries that one.
PlaceMix type
How much of a namespace's code runs where.
ProjectInfo type
What a codebase is, for its pages: its name and description, its packages, its README and contributing guide.
ReviewItem type
One changed definition in a contribution, with its lines before and after.
Share type
A page being made: the codebase served, who's asking, and where from.
ShareCache type
What a server keeps between page requests: what depends only on the branch's head (its names, placement, what each definition is for), made once for each head and dropped when it moves; and what never changes (an entry's changes, a release's definitions, the history's namespaces).
Tab type
The tabs every page has.

Server

BranchesPage () => Promise<Element>
The branches: each one's latest change, how far it is from the default, and any contribution proposing it.
ChangeCard ({ c, item, comments, }: { c: Contribution; item: ReviewItem; comments: Comment[]; }) => Element
One change in a contribution (ChangeBox), with what reviewing it adds: "Viewed", its comments, and a form to comment on it.
CodePage ({ name }: { name: string; }) => Promise<Element>
The page at a name: its definition's, or the namespace's if it's only that.
CommentView ({ k }: { k: Comment; }) => Element
A comment, or an event told as one.
ContributionPage ({ id, tab }: { id: number; tab: string; }) => Promise<Element>
A contribution's page: the conversation (its description, comments and events, the merge box), or the changes read along a review path (what's new before what uses it, then tests; what only re-hashed last, folded).
ContributionsPage ({ state }: { state: string; }) => Promise<Element>
The contributions: open ones, or merged, closed or all of them.
DefRow ({ row, full }: { row: NameRow; full?: boolean | undefined; }) => Element
A definition in a list: where it runs, its name, its type, the first line of its doc.
DefinitionView ({ name, hash }: { name: string; hash: string; }) => Element
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.
EntryChangeGroup ({ hash, from, to, }: { hash: string; from: number; to: number; }) => Promise<Element | null>
Some of a history entry's changes (`from` to `to`, in review order), as its page shows them (MoreChanges).
EntryPage ({ hash: asked }: { hash: string; }) => Promise<Element>
One history entry: what it's for (its message, if it has one), when and how it was made, and what it changed, each definition with its lines (as a contribution's changes show), what only re-hashed folded away.
Frame ({ tab, title, children, always, }: { tab: "" | Tab; title: string; children: ReactNode; always?: b…
Every page's frame: the project's name, the finder, who's signed in, and the tabs with their counts. On a private server, with no token, it's the sign-in page instead. A codebase shown, not served, has no sign-in, contributions or people. An app showing these pages as its own sets pageFrame.
FrontPage () => Promise<Element>
The front page: what the project is and how to get it, what you can use (its packages, apps and docs), a map of its namespaces with where their code runs, and its README.
HistoryPage ({ branch, under, page, }: { branch: string; under: string; page: number; }) => Promise<Element>
The history: a branch's entries by day, each with what it changed by name and count (an entry that re-hashed hundreds of definitions but edited four reads as small), `under` one namespace if asked.
MergeBox ({ c, m, tests }: { c: Contribution; m: Mergeable | null; tests: number; }) => Element
Whether it merges, and what the viewer may do about it: merge (the maintainer), close or reopen (theirs too).
NamespaceView ({ ns }: { ns: string; }) => Promise<Element>
A namespace: where it is, the namespaces in it (a list, each with its size, description and where its code runs), its definitions by what they're for, its README.
PackageBox ({ pkg }: { pkg: PackageInfo; }) => Element
A package, on its manifest's page: what it is and its releases, the commands it runs, what it exports, and the apps, files and end-to-end tests it ships, each a link to what it names.
PeoplePage () => Promise<Element>
Who works on the codebase here: its maintainer and the contributors the maintainer has added, with what each has done here; and how to become one.
ProjectSide () => Element
The project's side panel: what it is, how to get it, its packages, who works on it (a codebase shown, not served: what it is and its packages).
ReleasesPage () => Promise<Element>
The releases, newest first: each package's version, when, and its notes (written from its API's changes).
Say ({ c, about, fixed }: { c: Contribution; about: string[]; fixed?: string | undefined; }) => Element
Where the viewer comments from: a form, or a note to sign in.
SearchPage ({ q }: { q: string; }) => Promise<Element>
SignIn ({ then }: { then: string; }) => Element
Signing in, with a contributor's token or the server's (the link `tcm contribute` prints does it by itself).
SignInPage ({ then }: { then?: string | undefined; }) => Promise<Element>
The sign-in page, at its own address.
actOn (id: number, what: "close" | "comment" | "merge" | "reopen", o?: { body?: string | undefined; about…
Do what a contribution's page asks, as the caller may: comment, merge, close or reopen.
callerNow (cb: Codebase) => Caller | undefined
Who the request is from: the token its cookie holds (the server's, its maintainer's; a contributor's), or none, a reader (on a public server). Undefined when the server is private and there's no token. With no server token at all, everyone is its maintainer (`tcm dev` on a codebase of your own), or, public, a reader (a codebase `tcm serve --forge` shows).
contributionChanges (cb: Codebase, c: Contribution) => ContributionChanges | undefined
A contribution's changes, in review order; undefined if its branches are gone.
definitionLines (cb: Codebase, hash: string, nameOf: (h: string) => string | undefined, text?: { version: string | …
A definition's code as lines, as a diff compares it, its references read with `nameOf`; `text` reads one of its text versions (its comments, layout and doc), `undefined` the one it was first stored with.
entryChanges (s: Pick<Share, "cache" | "cb">, hash: string) => { items: ReviewItem[]; diff: NamespaceDiff; } | u…
What a history entry changed, definition by definition (reviewItems, in review order), and what only re-hashed; undefined for the first entry. Names come as `entryDiff`'s do.
highlightedLines (cb: Codebase, hash: string, lines: string[], exact?: boolean) => string[]
A definition's lines (definitionLines) as highlighted HTML, one for each: code coloured as its page colours it; a file by its format (TypeScript, JavaScript and JSON coloured, other text as it is). Not `exact`, JSX is read by the scanner alone, which is quick (text between tags may be coloured as code).
inSlices (steps: Iterable<() => unknown>, go?: () => boolean, o?: { slice?: number | undefined; background?:…
Run `steps` in turn, letting other work run every `slice` milliseconds, so what a page or the warm-up makes in bulk doesn't hold up the pages asked for meanwhile; in the `background`, it waits while a page is making something. It stops when `go` says to; whether it finished.
markdownHtml (cb: Codebase, md: string) => string
Markdown as HTML for a page: `tcm-page:<hash>` links (a doc's links to code, a page's to other pages) open that definition's page, images kept in the codebase (`tcm-page:<hash>` too) are shown, each a link to its page, and TypeScript code blocks are highlighted. Other links are kept only to http(s), mailto and relative addresses (`safeHref`): a README, a comment or a contribution's description can't make a `javascript:` link.
pageOf (s: Share, hash: string) => (NonNullable<{ hash: string; short: string; names: string[]; kind: "fil…
A definition's page data, its doc's examples shown as written: a page runs no code.
reviewItems (cb: Codebase, d: NamespaceDiff, oldNames: (h: string) => string | undefined, newNames: (h: string)…
The changed definitions a namespace diff holds, each with its lines, coloured (highlightedLines): what's added or removed, whole; what's edited or reworded, as a line diff; what's renamed or conflicted, by name. `oldNames` and `newNames` name what the code refers to, before and after.
roleNow (s: Pick<Share, "cache" | "cb">, r: NameRow) => Role
What a named definition is for (roleOf), told once for each head.
searchFor (q: string) => Promise<{ path: string; match: string; signature: string; detail: string; href: stri…
What the finder finds for the header's search box: the first twenty, by name, doc or type.
searchResults (s: Share, q: string) => { path: string; match: string; signature: string; detail: string; href: st…
What the finder finds: by name, words in docs, or a type, each with its page.
servedCodebase () => { cb: Codebase; cache: ShareCache; }
shareCache () => ShareCache
shareNow () => Share & { signedIn: boolean; }
The page being made: the codebase, who's asking, from where.
signIn (token: string) => Promise<string>
Sign this browser in with a token (a contributor's, or the server's): kept as a cookie. Says who it is.
signOut () => Promise<void>
warmUp (s: Pick<Share, "cache" | "cb">, slice?: number) => Promise<void>
Make what the pages read of the branch's head before they're asked for it, as they'd make it: what each definition is for (and where it runs), the front page's map, how many history entries there are, and the history's first ten pages, in the background (inSlices); it stops if the head moves.

Browser

ActButton ({ id, what, label, kind, }: { id: number; what: "close" | "merge" | "reopen"; label: string; kind?…
A contribution's merge, close or reopen button: done as the viewer may, then the page shows what it came to, and a toast says so (or why not).
CodeBox ({ head, lines, preview, }: { head: ReactNode; lines: string[]; preview?: ReactNode; }) => Element
A definition's or file's code in a box: a head, the line count, then its lines, numbered (`CodeLines`). A file with a view of its own (Markdown rendered, an image) shows that first, with a switch to its code; an address naming lines shows the code.
CodeLines ({ lines }: { lines: string[]; }) => Element
Code as numbered lines. A line's number links to it (`#L12`); shift-clicking another makes a range (`#L12-L20`). The lines the address names are marked and scrolled to.
CommentForm ({ id, about, fixed, named, as, }: { id: number; about: string[]; fixed?: string | undefined; named…
Comment on a contribution, or on one of its definitions (`fixed`); the maintainer signs with a name.
CopyButton ({ text, label, primary, }: { text: string; label: string; primary?: boolean | undefined; }) => Ele…
A button that copies some text (a name, a command), saying so (or that the browser wouldn't); pointing at it shows what it copies.
DiffLines ({ rows, more }: { rows: DiffRow[]; more?: string | undefined; }) => Element | null
A diff's rows (foldDiff's), coloured as code: what's added and removed marked, each line numbered before and after, ⋮ for the lines left out. One line after another, or side by side as DiffMode chooses (on a screen wide enough). `more` is where the rest of a diff cut short is (its definition's page).
DiffMode () => Element
The switch between diffs' two layouts, one line after another (unified) and side by side (split): for every diff on the page, and remembered by the browser.
HistoryFilter ({ branches, branch, under, }: { branches: string[]; branch: string; under: string; }) => Element
The history's filter: which branch (a select), and under which namespace (a search field).
MoreChanges ({ hash, from, total }: { hash: string; from: number; total: number; }) => Element
A history entry's changes from `from` on, loaded as they're scrolled to: ten at a time, each ten asked for when the page comes within a screen of them, and the next ten's turn only once those are in. A merge of hundreds sends what's read.
SearchBox () => Element
The finder in the header (React Aria's Autocomplete: a search field over a list of results): names, words in docs, or a type (`:(xs: T[]) => T`), with results as you type. ⌘K or / goes to it, arrows choose, Enter opens the result chosen (or, with none chosen, the search page). On the search page it holds what was searched for.
SignInForm ({ then }: { then: string; }) => Element
The sign-in form: a token (a contributor's, or the server's), then the page asked for.
TokenFromLink () => null
A token in the address's fragment (the link `tcm contribute` prints) signs the browser in, and leaves the address.
UserMenu ({ who, canSignOut }: { who: string; canSignOut: boolean; }) => Element
Who's signed in, as their avatar, which opens a menu: who it is, where their work is, and signing out.
ViewedToggle ({ k }: { k: string; }) => Element
"Viewed": folds a change's card away, and the browser remembers it (by contribution, name and hash).
copyText (text: string) => Promise<void>
Put some text on the clipboard: by the Clipboard API, or, where a page may not use it (an embedded browser, a page without the permission), by copying a selection of it, as browsers always have. Fails if neither is allowed.

Shared

Avatar ({ name, large }: { name: string; large?: boolean | undefined; }) => Element
Someone's avatar: a placeholder, the same for everyone until people have pictures, named for who it is.
BADGES Record<"added" | "conflicted" | "edited" | "removed" | "renamed" | "reworded", [string, string]>
BASE "/forge"
Where the web UI's pages are on a `tcm serve` server (and `/`, on one without a `--site`).
ChangeBox ({ item, extra, children, }: { item: ReviewItem; extra?: ReactNode; children?: ReactNode; }) => Ele…
One changed definition: its kind, name and hashes, and its lines (DiffLines); `extra` goes in its head, `children` after its lines.
Chevron () => Element
A chevron, pointing down: what opens a list, a menu or a fold (which turns it to point right while closed).
Crumbs ({ name }: { name: string; }) => Element
A dotted name as links up through its namespaces (Trail); the last part is the page itself.
EntryBadges ({ e }: { e: EntrySummary; }) => Element
An entry's changes as badges: edited, added, removed, renamed, and what only re-hashed.
FORGE_ICON string
The web UI's icon (a `#`: a codebase of hashes). Pages link it, and `tcm serve` answers `/favicon.ico` with it.
Fold ({ head, children }: { head: ReactNode; children: ReactNode; }) => Element
Something folded away under a head that opens it (React Aria's Disclosure): what only re-hashed, a comment form.
GetIt ({ command, isPublic }: { command: string; isPublic: boolean; }) => Element
"Get it": a button that opens how to (React Aria's dialog, in a popover): the command that makes a codebase and pulls this one, to copy, and what comes after.
Html ({ html, className, as }: { html: string; className?: string | undefined; as?: "div" | "pre" | "spa…
HTML made on the server (rendered Markdown, highlighted code) in a page.
NavTabs ({ label, selected, tabs, vertical, }: { label: string; selected: string; tabs: { id: string; label…
A row of tabs that are links (the project's, a contribution's, a list's states): React Aria's Tabs, with the page's own selected (none, on a page of none of them). Arrow keys move between them; Enter or a click goes. (Its tabs are elements, not a function of the list: it renders on the server too, and a function can't go to the browser.) `vertical`, they're a column: a sidebar's.
Place ({ place, label }: { place?: string | undefined; label?: boolean | undefined; }) => Element
Where a definition runs, as a dot (and, with `label`, words).
PlaceBar ({ mix }: { mix: PlaceMix; }) => Element
A bar of where a namespace's code runs.
Ripple ({ ch }: { ch: ContributionChanges; }) => Element
What the change touches, as a row: added, edited, removed; what re-hashed because of them; the tests they reach.
SHARE_STYLE "\n:root { color-scheme: light dark;\n --bg:#fff; --bg2:#f6f8fa; --bg3:#eef1f4; --fg:#1f2328; --di…
The web UI's stylesheet: one for every page, light and dark as the system is, laid out for a phone too.
StateBadge ({ c }: { c: Contribution; }) => Element
A contribution's state as a badge.
TOKEN_COOKIE "tcm_token"
The cookie a browser signed in to a server keeps its token in.
Toasts () => Element
Where toasts show: the page's corner, each one dismissable.
Trail ({ items }: { items: { label: string; href?: string | undefined; }[]; }) => Element
Where a page is, as links up to it (React Aria's Breadcrumbs); the last is the page itself.
ago (ts: number, now?: number) => string
When something happened, as a page says it: minutes, hours or days ago, then the date.
at (path: string) => string
A path of the app as a link.
base () => string
Where the app is served (`tcm start --base`), for its links: "" at a site's root.
childrenOf (rows: NameRow[], ns: string) => { namespaces: { name: string; rows: NameRow[]; }[]; defs: NameRow[…
The namespaces directly in one, and its definitions.
codeHref (name: string) => string
A definition's or namespace's page.
contributionHref (id: number) => string
diffWithHtml (a: { lines: string[]; html: string[]; }, b: { lines: string[]; html: string[]; }) => { lines: [" "…
Two versions' lines as a line diff, each line with its HTML: a removed line's as it was, an added or unchanged line's as it is now.
entriesIn (s: Pick<Share, "cache" | "cb">, causal: string) => number
How many history entries lead to an entry, it too (its ancestors).
entryDiff (s: Pick<Share, "cache" | "cb">, hash: string) => NamespaceDiff | undefined
What a history entry changed, from the entry before it (its first parent: a merge's, what it brought); undefined for the first entry. Its names, and its parent's, are made from the names read last (NameTrees).
entrySummary (s: Pick<Share, "cache" | "cb">, hash: string) => EntrySummary
What a history entry changed, from the entry before it (a merge: what it brought), kept: an entry never changes.
foldDiff (lines: [" " | "+" | "-", string][], html?: string[] | undefined, most?: number) => DiffRow[]
A change's lines as the rows a page sends (DiffRow): each change and two lines of context around it, the rest as gaps, each line once (its HTML, or its text made HTML); past `most` rows, the rest one gap. Done before the page goes to the browser, so a one-line edit to a long definition sends a few lines, not two copies of it.
getItCommand (s: Share) => string
The commands that get a copy of the codebase from this server.
highlightedTexts Map<string, string[]>
Lines already coloured (highlightedLines), by their text and how it was read: a diff's sides come again and again (an entry's page, a contribution's, the next entry's). The newest few thousand are kept.
htmlLines (html: string) => string[]
Highlighted code's HTML as lines: an element a line break falls inside is closed at the end of its line and opened again on the next, so each line is whole. A final line break ends the last line; it doesn't start another.
isEvent (k: Comment) => boolean
An event (closing, reopening) is kept as a comment saying so.
keepWarm (served: { cb: Codebase; cache: ShareCache; }) => void
Keep the served codebase's pages made ahead: when its branch's head moves (a push, a merge), warmUp again. It looks every two seconds.
leafOf (p: string) => string
linkRefs (cb: Codebase, html: string) => string
Highlighted code (`highlight`'s) with its references made links: to the page of the definition or namespace they name, with the definition's name and type to show on hover.
manifestFields (text: string) => Record<string, unknown>
A package manifest's fields as its source writes them: the object it declares, read, never run (a page runs no code). Strings, and arrays and objects of them, come through (`as const` and the like after one are fine); anything computed doesn't.
nameHistory (s: Pick<Share, "cache" | "cb">, name: string, branch?: string | undefined, scan?: number, limit?: …
The history entries that changed what a name is: when it was added, each change to its code (or what it uses), and its removal, newest first; looking back `scan` entries along the branch's first parents, at most `limit`.
namesNow (s: Pick<Share, "cache" | "cb">) => NameRow[]
The branch's names, its files' too, as of its head.
namespaceSummary (s: Share, rows: NameRow[], ns: string) => string
A namespace's description: the first paragraph of the README in it, or of its own doc.
opened Map<string, { cb: Codebase; cache: ShareCache; }>
The codebase the app shows, opened once: the one `TCM_SHARE_CODEBASE` names (tcm serve's), or the app's own.
outcomeOf (cb: Codebase, hash: string) => { ok?: boolean | undefined; }
Whether a test passes, as its results say (none: it hasn't run here).
packageFileName (rows: NameRow[], ns: string, file: string) => string | undefined
The name a package's manifest means by one of its `files`: a name in its namespace, or a path from the codebase's root (`../README.md`), read as the file kept under the namespace it would be written from.
pageFrame { current?: ((p: { tab: "" | Tab; title: string; children: ReactNode; }) => ReactNode) | undefined;…
The frame every page is drawn in, if an app showing the forge's pages has its own (the registry: its header, not a project's): set once, as that app's pages start.
pagesWorking { n: number; }
How many pages are making something in slices (inSlices) now: what runs in the background waits for them.
parentOf (p: string) => string
The namespace a dotted name is in, and its last part.
placeMix (s: Pick<Share, "cache" | "cb">, rows: NameRow[], key: string) => PlaceMix
How many of these definitions run where (types, tests and files left out), kept for the head they were counted at.
projectInfo (cb: Codebase, rows: NameRow[]) => ProjectInfo
The project a codebase is: named for the package at its top namespace (or the namespace; with several, the codebase's directory), described by that package's doc or the first sentence of its README. Manifests are read from their source, not evaluated.
projectNow (s: Pick<Share, "cache" | "cb">) => ProjectInfo
The project the codebase is (projectInfo), as of the branch's head.
releaseHas (s: Pick<Share, "cache" | "cb">, causal: string, hash: string) => boolean
Whether a release (by its history entry) has a definition, by any name: what's in a release is read once.
reviewOrder (items: ReviewItem[], usesOf: (hash: string) => string[]) => ReviewItem[]
The order to review changes in: what's new before what uses it, so each definition is read after what it depends on; then tests; removed and renamed last. `usesOf` says which hashes a hash uses.
safeHref (href: string) => string | undefined
A link's address, if it's one a page may link to: http, https or mailto, or one with no scheme (a path, `#…`). Others (`javascript:`, `data:`, `vbscript:`…) are undefined, read as a browser reads them (it skips tabs, newlines and leading spaces and control characters, so `java\tscript:` is `javascript:`).
summaryOf (d: NamespaceDiff) => EntrySummary
A history entry's changes by name (EntrySummary), from what diffNamespaces says it changed.
testsReaching (cb: Codebase, hash: string, limit?: number) => { path: string; hash: string; ok?: boolean | undefi…
The tests a definition reaches: tests among what uses it, however far (up to `limit` definitions looked at).
toasts ToastQueue<{ title: string; description?: string | undefined; tone?: "bad" | "ok" | undefined; }>
What the page's actions came to (merged, signed out, a comment added, or why one failed), said for a moment.

Tests

testDiffWithHtmlKeepsEachLinesHtml () => void
A coloured diff reads as the plain one does: each line's HTML is that line's, from the side it comes from.
testFoldDiffSendsWhatItShows () => void
A diff sends what it shows: changes with two lines of context, each line once, the rest counted.
testHtmlLinesCloseWhatSpansALine () => void
Lines of highlighted code each close what they open: a comment over three lines is three spans.
testManifestFieldsReadTheSource () => void
A manifest is read from its source: its fields, its names relative to its namespace, never run.
testReviewOrder () => void