// In contrast to `node run `, this opens a shell-like // environment that allows faster execution of code since it // doesn't have to reload the plugin system. This is mostly // done since Clover's primary dev-env is a Windows 7 laptop; // It takes her machine 600ms to load the plugin file on it's own. import process from "node:process"; import * as util from "node:util"; const exts = [".tsx", ".ts", ".js", ".marko"]; process.stderr.write("Loading..."); const { hot } = await import("./run.js"); // get plugins ready const { errorAllWidgets } = hot.load("@paperclover/console/Widget"); process.stderr.write("\r" + " ".repeat("Loading...".length) + "\r"); const repl = hot.load("node:repl").start({ prompt: "% ", eval(code, _global, _id, done) { evaluate(code) .catch((err) => { // TODO: improve @paperclover/console's ability to print AggregateError // and errors with extra random properties console.error(util.inspect(err, false, 10, true)); }) .then((result) => done(null, result)); }, ignoreUndefined: true, //completer, }); repl.setupHistory(".clover/repl-history.txt", () => {}); setTimeout(() => { hot.reloadRecursive("./framework/generate.ts"); }, 100); async function evaluate(code) { code = code.trim(); if (code === "clear" || code === "cls") { return console.clear(); } if (code[0] === "=") { try { const result = await eval(code[1]); console.info(inspect(result)); } catch (err) { if (err instanceof SyntaxError) { const result = await eval("(async() => { return " + code + " })()"); console.info(inspect(result)); } else { throw err; } } } let split = code.split(/\s+/); if (split.length === 0) return; // Shell commands const cliPassthrough = [ "deno", "explorer", "git", "iexplore", "node", "npm", "open", "rg", "start", "vi", ]; if (cliPassthrough.includes(split[0]) || split[0].startsWith("$")) { if (split[0].startsWith("$")) { if ((split[0] = split[0].slice(1)).trim() === "") split.shift(); } if (process.platform === "win32" && split[0] === "open") split[0] = "start"; if (split[0] === "explorer" || split[0] === "start") { split[1] = split[1]?.replaceAll("/", "\\"); } try { child_process.execSync(split.join(" "), { stdio: "inherit", env: { EDITOR: "vi", ...process.env }, }); } catch (err) { const { status, signalCode } = err; console.error( `Exited with ${status ? "code " + status : "signal " + signalCode}`, ); } return; } let found; for (const base of [".", "framework"]) { for (const e of exts) { const file = path.join(base, split[0] + e); if (fs.existsSync(file)) { found = file; break; } } } if (!found) { console.error("\x1b[33mNo file matches: " + split[0] + "\x1b[0m"); return; } const m = hot.reloadRecursive(found); await m.main?.(); errorAllWidgets( path.basename(found, path.extname(found)) + ".main() returning", ); } import * as fs from "node:fs"; import * as path from "node:path"; import * as child_process from "node:child_process";