writeViews

tcmts.cli.views.writeViews · #f4odzizu · term · runs on the server

uses node:fs

Bring this branch's views (srcDir) up to date with its names. The codebase's own branch has every definition's, for the editor; a session only those something asked for (a stack trace's, its language server's), each kept as it reads now. Only what changed since the last time is rewritten: the definitions the name log says changed, and what depends on them (their views spell those names, and say where they run). Everything is, the first time, after switching branches, or when the log can't say.

import type { CodebaseCore } from "#codebase/tcmts/cli/codebase";
import { Placement } from "#codebase/tcmts/cli/placement";
import { rewriteViews, srcDir, viewFile, viewsKey, writeAllViews, writeView } from "#codebase/tcmts/cli/views";
import fs from "node:fs";
import path_1 from "node:path";

export function writeViews(cb: CodebaseCore, all = false) {
  const head = cb.store.logHead();
  const branch = cb.store.branch().name;
  const key = viewsKey(cb);
  const at = cb.store.getSetting(key);
  const sep = at?.lastIndexOf("@") ?? -1;
  const since = at && at.slice(0, sep) === branch ? Number(at.slice(sep + 1)) : undefined;
  // (a session's: only the ones there)
  const every = !cb.sessionDir;
  if (all || since === undefined || !(since <= head) || !fs.existsSync(srcDir(cb))) {
    if (every) writeAllViews(cb);
    else rewriteViews(cb);
  } else if (since < head) {
    const entries = cb.store.history(Number.MAX_SAFE_INTEGER, since);
    const changed = new Set(
      entries.flatMap((e) => [e.oldHash, e.newHash].filter((h): h is string => !!h)),
    );
    // and everything that uses them, directly or not
    const queue = [...changed];
    while (queue.length)
      for (const d of cb.store.dependents(queue.pop()!))
        if (!changed.has(d)) {
          changed.add(d);
          queue.push(d);
        }
    const placement = new Placement(cb);
    for (const n of cb.store.names())
      if (changed.has(n.hash) && (every || fs.existsSync(viewFile(cb, n.hash))))
        writeView(cb, n.hash, placement);
    // a name that's gone takes its file with it
    for (const e of entries) {
      if (cb.store.hashesAt(e.path).length) continue;
      for (const ext of [".ts", ".tsx"])
        fs.rmSync(path_1.join(srcDir(cb), `${e.path.replaceAll(".", "/")}${ext}`), {
          force: true,
        });
    }
  }
  cb.store.setSetting(key, `${branch}@${head}`);
}

uses

used by