evaluateInScratch

tcmts.studio.evaluateInScratch · #2qetdbe2 · term · runs on the server

uses node:util

What expr comes to, in a scratch file (text being what it holds): run as a statement of it would be, once, its value (a React element rendered too) and what it wrote out; what's wrong with it, if it doesn't check (it sees the file's top-level names, not what's local to a definition).

import { evaluateCached } from "#codebase/tcmts/cli/testing";
import { HttpError } from "#codebase/tcmts/server";
import { analyzedScratch, editableCodebase, scratchPath } from "#codebase/tcmts/studio";
import type { ScratchValue } from "#codebase/tcmts/studio";
import { stripVTControlCharacters } from "node:util";

export async function evaluateInScratch(
  file: string,
  text: string,
  expr: string,
): Promise<ScratchValue> {
  const cb = editableCodebase();
  const abs = scratchPath(cb, file, text);
  if (!/\.tsx?$/.test(file)) throw new HttpError(400, `${file} isn't code.`);
  const head = `${text}${text.endsWith("\n") ? "" : "\n"}\n`;
  const line = head.split("\n").length;
  const asked = `${head};(${expr});\n`;
  const a = analyzedScratch(cb, abs, asked);
  const here = a.diagnostics.find((d) =>
    new RegExp(`:${line}:\\d+`).test(stripVTControlCharacters(d.formatted)),
  );
  if (here) return { line, ok: false, value: here.message };
  if (a.diagnostics.length || a.errors.length)
    return {
      line,
      ok: false,
      value: `${file} has problems: fix them, and it's evaluated with the rest.`,
    };
  const w = a.watches.find((x) => x.line === line);
  if (!w) return { line, ok: false, value: "That isn't an expression to evaluate." };
  const r = evaluateCached(cb, [w], cb.source([...a.defs, ...a.watches]), true).get(line);
  if (!r) return { line, ok: false, value: "It didn't run." };
  return {
    line,
    ok: r.ok,
    value: stripVTControlCharacters(r.value),
    ...(r.html !== undefined ? { html: r.html } : {}),
    ...(r.output ? { output: stripVTControlCharacters(r.output) } : {}),
  };
}

uses

used by