import { isMainThread, parentPort, workerData } from "node:worker_threads";
import { getBlobUrl, setBlobUrl } from "#lib/markup/paths.ts";
import { renderMarkup } from "#lib/markup/render.ts";
import type { RenderTask } from "#lib/ssr/render.ts";
export const WORKER_ROLE = "tangled-ssr-render";
// dynamic import in pool.ts gives this module its own chunk url in both dev and build
export const workerUrl = import.meta.url;
const runTask = async (task: RenderTask): Promise<string> => {
if (task.kind === "markup") return renderMarkup(task.source, task.ctx);
await import("#lib/syntax.ts");
const { preloadFile } = await import("@pierre/diffs/ssr");
const { prerenderedHTML } = await preloadFile({
file: { name: task.name, contents: task.contents },
options: task.options
});
return prerenderedHTML;
};
export type WorkerMessage =
{ ready: true } | { id: number; html: string } | { id: number; error: string };
export interface WorkerInit {
role: typeof WORKER_ROLE;
blobUrl: string;
}
export const workerInit = (): WorkerInit => ({ role: WORKER_ROLE, blobUrl: getBlobUrl() });
const init = workerData as WorkerInit | undefined;
if (!isMainThread && parentPort && init?.role === WORKER_ROLE) {
const port = parentPort;
setBlobUrl(init.blobUrl);
port.on("message", ({ id, task }: { id: number; task: RenderTask }) => {
runTask(task).then(
(html) => port.postMessage({ id, html } satisfies WorkerMessage),
(cause: unknown) =>
port.postMessage({ id, error: String(cause) } satisfies WorkerMessage)
);
});
port.postMessage({ ready: true } satisfies WorkerMessage);
}