~james/core

core/web/src/lib/syntax.test.ts -rw-r--r-- 1.8 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
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
import { Worker } from "node:worker_threads";
import { describe, expect, it } from "vitest";

// shiki's js regex engine backtracks without end on this go struct literal. on the
// server each blob page with it pinned an instance's event loop for good; highlights'
// hand-written lexers have no regex engine to run away
const BACKTRACKING_GO = 'pp := struct {\n\t}{t(*p), strings.TrimSuffix(p.URL.String(), "/")}\n';

// a runaway regex can't be interrupted on its own thread, so this tokenizes in a
// worker and terminates it at the deadline
const WORKER = `
const { parentPort, workerData } = require("node:worker_threads");
import(workerData.pierre).then(async ({ getSharedHighlighter, registerCustomCSSVariableTheme }) => {
	registerCustomCSSVariableTheme("test", { background: "#ffffff", foreground: "#000000" });
	const highlighter = await getSharedHighlighter({
		themes: ["test"],
		langs: ["go"],
		preferredHighlighter: "highlights"
	});
	highlighter.codeToTokens(workerData.code, { lang: "go", theme: "test" });
	parentPort.postMessage("done");
});
`;

const tokenizesWithin = (code: string, ms: number): Promise<boolean> =>
	new Promise((resolve, reject) => {
		const worker = new Worker(WORKER, {
			eval: true,
			workerData: { pierre: import.meta.resolve("@pierre/diffs"), code }
		});
		const finish = (done: boolean) => {
			clearTimeout(timer);
			void worker.terminate();
			resolve(done);
		};
		const timer = setTimeout(() => finish(false), ms);
		worker.once("message", () => finish(true));
		worker.once("error", (err) => {
			clearTimeout(timer);
			reject(err);
		});
	});

describe("shared highlighter on the server", () => {
	it("tokenizes the backtracking go literal with highlights", async () => {
		expect(await tokenizesWithin(BACKTRACKING_GO, 10_000)).toBe(true);
	}, 15_000);
});