README
server
The server API of a tcm app, as a library: the request, cookies, sessions and rate limits, typed tables and
transactions, and background jobs, as ordinary definitions you can read, pin and upgrade. tcm ships it, so
tcm lib add tcm server adds the release your tcm has, with no network (and tcm lib upgrade server the one a newer
tcm has). It's a tcm library, not an npm package: it holds everything its code uses, so a codebase that adds it has
every definition named.
import { HttpError, enqueue, every, request, table, transaction } from "#codebase/app/lib/server";
export type Note = { title: string; body: string; author: string };
export const notes = table<Note>("notes", { index: ["author"] });
export async function addNote(title: string, body: string): Promise<string> {
const author = request().headers.get("x-user") ?? "";
if (!author) throw new HttpError(401, "sign in first");
return transaction(async () => {
const id = await notes.insert({ title, body, author });
enqueue(notify, author, id);
return id;
});
}
export async function notify(author: string, id: string): Promise<void> {
console.log(`${author} wrote ${id}`);
}
export const nightly = every("0 3 * * *", async () => console.log(await notes.count()));
What it has
- The request:
request(),cookie(name),setCookie,deleteCookie;HttpError(status, message)for a failure meant for the caller (it runs anywhere, so browser code can tell one apart). - Sessions:
session(),setSession(data),clearSession(),revokeSessions(match): the data stays on the server, the cookie holds only an id. - Rate limits:
rateLimit(key, { max, per }), a 429 past the limit. - Tables:
table<Row>(name, opts)withput,insert,get,delete,update,find,findOne,count; rows checked against the row type, migrated from older ones (migrate),uniqueandindexfields. - Transactions:
transaction(fn)over every table, jobs queued when it commits. - Jobs:
enqueue(fn, ...args),enqueueAfter(seconds, fn, ...args),every(spec, fn)for a recurring one;runJobs()andwithRequest(init, fn)for tests.
tcm's runtime
It runs on tcm's server host, #tcm/host: the call being answered, the app's SQLite files, the store's lock and
transactions, and the job queue, one per process however many libraries use it. That's version 1 of tcm's host
protocol, as its manifest says: a tcm that doesn't serve that version won't build an app using it. Its manifest gives
table and every their roles, so a table declared with it keeps its row type's schema, and a definition every
makes runs on its schedule, wherever it's mounted.
Its versions follow semver from its API, as any package's do (releases).