authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-06-07 14:52:40-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-10-14 02:40:44-07:00
log67635da6472e2ade6fde8646a21c3fb12af87acd
treef13b743cb151309d4898123bc08bd918f86f7502
parenta9419bd19945024b0e70a4c3fc56342cf5247d69
signature Commit is signed but in an unrecognized format.

restore repl.js

full disk scan with keyword '= hot.load("node:repl").'

1 files changed, 118 insertions(+), 1 deletions(-)

repl.js+118-1
...@@ -1 +1,118 @@...@@ -1 +1,118 @@
1// RIP1// In contrast to `node run <file>`, this opens a shell-like
2// environment that allows faster execution of code since it
3// doesn't have to reload the plugin system. This is mostly
4// done since Clover's primary dev-env is a Windows 7 laptop;
5// It takes her machine 600ms to load the plugin file on it's own.
6import process from "node:process";
7import * as util from "node:util";
8const exts = [".tsx", ".ts", ".js", ".marko"];
9
10process.stderr.write("Loading...");
11const { hot } = await import("./run.js"); // get plugins ready
12const { errorAllWidgets } = hot.load("@paperclover/console/Widget");
13process.stderr.write("\r" + " ".repeat("Loading...".length) + "\r");
14hot.load("node:repl").start({
15 prompt: "% ",
16 eval(code, _global, _id, done) {
17 evaluate(code)
18 .catch((err) => {
19 // TODO: improve @paperclover/console's ability to print AggregateError
20 // and errors with extra random properties
21 console.error(inspect(err));
22 })
23 .then((result) => done(null, result));
24 },
25 ignoreUndefined: true,
26 //completer,
27});
28
29setTimeout(() => {
30 hot.reloadRecursive("./framework/engine/ssr.ts");
31 hot.reloadRecursive("./framework/bundle.ts");
32}, 100);
33
34async function evaluate(code) {
35 code = code.trim();
36
37 if (code === "clear" || code === "cls") {
38 return console.clear();
39 }
40
41 if (code[0] === "=") {
42 try {
43 const result = await eval(code[1]);
44 console.log(inspect(result));
45 } catch (err) {
46 if (err instanceof SyntaxError) {
47 const result = await eval("(async() => { return " + code + " })()");
48 console.log(inspect(result));
49 } else {
50 throw err;
51 }
52 }
53 }
54
55 let split = code.split(/\s+/);
56 if (split.length === 0) return;
57
58 // Shell commands
59 const cliPassthrough = [
60 "deno",
61 "explorer",
62 "git",
63 "iexplore",
64 "node",
65 "npm",
66 "open",
67 "rg",
68 "start",
69 "vi",
70 ];
71 if (cliPassthrough.includes(split[0]) || split[0].startsWith("$")) {
72 if (split[0].startsWith("$")) {
73 if ((split[0] = split[0].slice(1)).trim() === "") split.shift();
74 }
75 if (process.platform === "win32" && split[0] === "open") split[0] = "start";
76 if (split[0] === "explorer" || split[0] === "start") {
77 split[1] = split[1]?.replaceAll("/", "\\");
78 }
79 try {
80 child_process.execSync(split.join(" "), {
81 stdio: "inherit",
82 env: { EDITOR: "vi", ...process.env },
83 });
84 } catch (err) {
85 const { status, signalCode } = err;
86 console.error(
87 `Exited with ${status ? "code " + status : "signal " + signalCode}`,
88 );
89 }
90 return;
91 }
92
93 let found;
94 for (const base of [".", "framework"]) {
95 for (const e of exts) {
96 const file = path.join(base, split[0] + e);
97 if (fs.existsSync(file)) {
98 found = file;
99 break;
100 }
101 }
102 }
103
104 if (!found) {
105 console.error("\x1b[33mNo file matches: " + split[0] + "\x1b[0m");
106 return;
107 }
108
109 const m = hot.reloadRecursive(found);
110 await m.main?.();
111 errorAllWidgets(
112 path.basename(found, path.extname(found)) + ".main() returning",
113 );
114}
115
116import * as fs from "node:fs";
117import * as path from "node:path";
118import * as child_process from "node:child_process";