Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

repp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import { renderToString } from "npm:react-dom/server";
import { blob } from "https://esm.town/v/std/blob?v=12";
import { createHash } from "node:crypto";
import base32Encode from "npm:base32-encode";
const oneSecond = 1000;
const TIMEOUT = 5 * oneSecond;
blob.setJSON;
const fetch = async (req: Request): Promise<Response> => {
let repp = new Repp([{
code: "",
}, {
code: ``,
}]);
if (req.method === "GET") {
return new Response(
renderToString(
<div>
<form method="POST">
<textarea name="code">hi</textarea>
<button type="submit">Submit</button>
</form>
</div>,
),
{ headers: { "content-type": "text/html" } },
);
}
};
interface Segment {
code: string;
result?: { args: unknown[]; level: string; index: number }[];
}
const hashSegments = (segments: Segment[]): string => {
return base32Encode(
createHash("sha256").update(JSON.stringify(segments.map(s => s.code))).digest().slice(0, 20),
"RFC4648",
{ padding: false },
).toLowerCase();
};
type Log = {
level: string;
args: unknown[];
stack: string;
};
// The script we run within the worker. Don't reference anything
// outside of this function as it won't be available within the worker. We could even host this in a separate val and pass
const workerScript = () => {
type Log = {
level: string;
args: unknown[];
stack: string;
};
const logs: Log[] = [];
globalThis.console = new Proxy(console, {
get(target, key) {
const real = target[key];
if (typeof real === "function" && typeof key === "string") {
const fn = function(...args: any[]) {
logs.push({
level: key,
stack: new Error().stack.replace("Error\n", "")
.split("\n").filter((s) => !s.includes("Proxy.fn"))
.join("\n"),
args,
});
return real.call(this, ...args);
};
return fn;
}
},
});
async function evaluate(url) {
try {
const _ = await import(url);
return;
} catch (err) {
return { error: { message: err.message, stack: err.stack.replaceAll(url, "./script.ts") } };
}
}
self.onmessage = async (e) => {
const blob = new Blob([e.data], { type: "text/tsx" });
const url = URL.createObjectURL(blob);
let resp = await evaluate(url);
logs.forEach((l) => {
l.stack = l.stack.replaceAll(url, "./script.ts");
});
self.postMessage(JSON.stringify({ resp, logs }));
};
};
type EvalResponse = { segments?: Segment[]; error?: { message: string; stack: string } };
maxm-repp.web.val.run
May 18, 2024