Public
Script
v8
June 26, 2024
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 npm:hono/jsx */
import { api } from "https://esm.town/v/pomdtr/api";
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
import { Island } from "https://esm.town/v/pomdtr/hono_island";
import { Test } from "https://esm.town/v/pomdtr/test";
import {
createHistory,
type HistoryEntry,
readHistory,
writeHistory,
} from "https://esm.town/v/pomdtr/test_explorer_history";
import TestExplorer, { type Test as TestType } from "https://esm.town/v/pomdtr/test_explorer_ui";
import { Hono } from "npm:hono@4.0.8";
import stripAnsi from "npm:strip-ansi@7.1.0";
const router = new Hono();
const { author } = extractValInfo(import.meta.url);
router.get("/", async (c) => {
try {
const tests = await loadTests();
return c.html(
<html>
<head>
<link rel="icon" href="https://fav.farm/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.colors.min.css"
/>
<style
dangerouslySetInnerHTML={{
__html: `ul li { list-style: none; }`,
}}
>
</style>
<script src="https://esm.town/v/pomdtr/hydrate_hono_islands" type="module" defer></script>
</head>
<body>
<Island src="pomdtr/test_explorer_ui">
<TestExplorer tests={tests} />
</Island>
</body>
</html>,
);
} catch (e) {
return new Response(`${e.message} ${e.stack}`, { status: 500 });
}
});
router.post("/api/refresh", async () => {
const tests = await loadTests();
return Response.json(tests);
});
async function loadTests(): Promise<TestType[]> {
const query = `https://esm.town/v/${author}/test_explorer`;
const { data: vals } = await api(`/v1/search/vals?query=${query}`, { authenticated: true });
const tests = {};
for (const val of vals) {
const mod = await import(`https://esm.town/v/${val.author.username}/${val.name}`);
for (const [name, value] of Object.entries(mod)) {
if (value instanceof Test) {
tests[`${val.author.username}/${val.name}/${name}`] = { val, name };
}
}
}
const history = await loadHistory();
for (const entry of history) {
const key = `${entry.val_slug}/${entry.test_name}`;
const test = tests[key];
if (!test) {
continue;
}
test.status = entry.status;
test.last_run_at = entry.last_run_at;
}
return Object.values(tests);
}
async function loadHistory(): Promise<HistoryEntry[]> {
try {
const entries = await readHistory();
return entries;
} catch (err) {
if (err.message.includes("no such table")) {
await createHistory();
return [];
}
throw err;
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
v8 was merged from the PR "Return the error text if an error is encountere…" by maxm
Comments
Nobody has commented on this val yet: be the first!
v8
June 26, 2024