tcmts.loader

packages/
39 definitions
sourcemap/
5 definitions

Types

DefSource type
Where definitions come from: the store, possibly overlaid with not-yet-added scratch definitions.
Kept type
A pure constant's value, evaluated once: where its initializer is in its stored text, and the value as code.
Layout type
RenderOptions type
Rendered type
ShimName type
Style type
- `cache`: a component module in `.tcm/cache`, imports by hash, exported as `h_<hash>` - `internal`: like cache but without exports; used to re-typecheck definitions after an update - `scratch`: editable source for the project root, imports through `#codebase/...`
TestRun type
WatchResult type

Server

augmentationRoot (lay: Pick<Layout, "shimDir">) => string
Where `writeShim` puts a type package for each augmentation (named by its path, importing its module), for checks to list in `types`: every check in the codebase sees each one, as TypeScript's whole program would.
evaluateWatches (watches: { hash: string; componentHash: string; line: number; }[], src: DefSource, lay: Layout) =>…
Evaluate watch expressions (already materialized as definitions) in a child process.
layout (root: string) => Layout
materialize (hashes: Iterable<string>, src: DefSource, lay: Layout, opts?: { keepExisting?: boolean | undefined…
Write the cache modules `hashes` need: their components and everything those import. `keepExisting` leaves a module that's already there as it is, rather than rendering it again: a component's code never changes, only the names and source maps it's rendered with, which is all an internal re-check needs. `trustExisting` goes further: an existing module's imports aren't followed either (they were written with it), so only what's new is visited; for the `#codebase` shim after a change, which needs modules to import, not their names up to date.
nodeArgs (lay: Layout) => string[]
Node flags for processes tcm spawns; the transform hook, when the cache has one, compiles marked modules.
pathToFileURLString (p: string) => string
render (members: DefRecord[], src: DefSource, lay: Layout, opts: RenderOptions) => Rendered
run (hash: string, args: string[], src: DefSource, lay: Layout) => number
Run a definition: call it with `args` if it's a function, await the result, print it if not undefined.
runStreaming (hash: string, args: string[], src: DefSource, lay: Layout, onOutput: (stream: "stderr" | "stdout",…
Like `run`, but hands output to a callback as it arrives (for running on behalf of a remote client).
runTests (tests: { hash: string; componentHash: string; }[], src: DefSource, lay: Layout) => TestRun[]
Run tests (functions that pass by returning without throwing, and fail on `false`) in one child process, capturing each one's console output.
writeIfChanged (file: string, text: string) => boolean
writePairModule (name: string, recs: DefRecord[], src: DefSource, lay: Layout) => string
One module exporting a type and a value under one name. TypeScript won't merge two re-exports, but it merges a local declaration with a re-export, so the type is rendered here (under this name, with its type parameters intact) and the value is re-exported beside it. Returns the file name within the cache.
writeRunner (hash: string, src: DefSource, lay: Layout) => string
The module that runs a definition (calls it with the process's arguments, prints the result): `tcm run`'s.
writeShim (names: ShimName[], src: DefSource, lay: Layout, only?: Set<string> | undefined) => void
Regenerate `.tcm/codebase/**` so scratch files can `import { x } from "#codebase/ns"`: a file per namespace. With `only`, just those namespaces' files (the ones whose names changed), and only the modules they import that aren't there yet: the rest of the shim, and every module already written, are as they were.

Shared

TEST_TIMEOUT_MS 10000
TRANSFORM_MARK "// tcm: transform"
TYPE_KEYWORDS Set<string>
Valid binding names that would parse as something else where an imported name is spliced into a type.
externalsOf (members: DefRecord[]) => ExtRef[]
The packages definitions import, the JSX runtime their elements compile to included.
fileModule (rec: DefRecord) => string
A file's module: its content as the value of its export, as saved (its `{@link}`s as written, so the module is a function of its hash). Text is a string; bytes, a Uint8Array.
groupImports (lines: string[]) => string[]
Imports as one statement per module (type-only names in one of their own): `import { a, b as c } from "x";`, wrapped when long. Default and namespace imports stay as they are. In order of module.
importLine (local: string, exported: string, from: string, typeOnly: boolean) => string
initOrder (members: DefRecord[]) => DefRecord[]
Order component members so module-init-time references are already initialized. A function called as a member is initialized (`const yieldNow = makePrimitive(…)`) runs its body then: what that uses is needed first too (`makePrimitiveProto`), and so on through the functions it calls. One only read (`const Reference = Service`) isn't run.
isAugmentation (rec: Pick<DefRecord, "ir">) => boolean
Whether a definition is an augmentation (`declare global { … }`): it declares no name of its own, so nothing imports it, and every check in the codebase includes it instead (see `writeShim`).
lastSegment (name: string) => string
moduleFile (componentHash: string, src: Pick<DefSource, "members">) => string
A component's module: `.tsx` when it uses JSX (TypeScript only parses JSX there), `.ts` otherwise. Its first JSX member's runtime is named in a pragma, so every compiler (tcm's module hook, Vite, the type checker) compiles the elements to the pinned version.
realPackage (module: string) => string
runnerStdout number | "inherit"
Where test and watch runners' stdout goes: ours, unless that's a protocol channel (`tcm lsp`).
sanitize (s: string) => string
sendRunnerOutputToStderr () => void
valueSource (value: unknown, others?: Set<unknown>, most?: number) => string | undefined
A value as code that makes it again (`new globalThis.Map([[1, "a"]])`), for a pure constant evaluated once: plain data (numbers, strings, bigints, arrays, plain objects, Maps, Sets, Dates, RegExps). Undefined if it can't be made again the same: a function, a class's instance, a frozen object, an object found twice in it or among `others` (what other definitions hold: a copy would be a different object), or more than `most` characters of code.

Tests

testGroupImports () => void
A scratch file's imports read as written by hand: one statement per module, type-only names apart, wrapped when long.
testInitOrderFollowsFunctionsCalledAtInit () => void
A member initialized by calling a function of its component comes after what that function uses, which may come after it in the component (Effect's `yieldNow = makePrimitive(…)`, whose body reads `makePrimitiveProto`).
testValueSourceMakesItAgain () => void

Files

package file