New architecture
This commit is contained in:
115
src-tauri/assets/viewer-src/build.cjs
Normal file
115
src-tauri/assets/viewer-src/build.cjs
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* build.cjs — esbuild script for the PDF viewer TypeScript bundle.
|
||||
*
|
||||
* Produces two output files in ../assets/viewer/:
|
||||
* viewer.bundle.js — main viewer (IIFE, no PDF.js included)
|
||||
* render-worker.bundle.js — render worker (pdf.min.js prepended + IIFE)
|
||||
*
|
||||
* Usage:
|
||||
* node build.cjs — one-shot production build (minified)
|
||||
* node build.cjs --watch — watch mode for development (unminified)
|
||||
*/
|
||||
|
||||
const esbuild = require("esbuild");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const isWatch = process.argv.includes("--watch");
|
||||
const minify = !isWatch;
|
||||
|
||||
const ROOT = __dirname;
|
||||
const PDFJS_WORKER_MIN = path.join(ROOT, "../viewer/pdfjs/pdf.worker.min.js");
|
||||
const PDFJS_MIN = path.join(ROOT, "../viewer/pdfjs/pdf.min.js");
|
||||
const OUT_DIR = path.join(ROOT, "../viewer");
|
||||
|
||||
// Preamble prepended to the render-worker bundle.
|
||||
//
|
||||
// Sets `globalThis.window = globalThis` before pdf.worker.min.js runs so that:
|
||||
// 1. pdf.worker.min.js does NOT auto-call WorkerMessageHandler.initializeFromPort(self)
|
||||
// (which would hijack our render-worker's own onmessage handler).
|
||||
// 2. pdf.worker.min.js DOES set globalThis.pdfjsWorker.WorkerMessageHandler as usual.
|
||||
// 3. pdf.min.js's _mainThreadWorkerMessageHandler getter then finds the handler via
|
||||
// globalThis.pdfjsWorker and uses it inline — no document.createElement needed.
|
||||
const RENDER_WORKER_PREAMBLE = Buffer.from("globalThis.window=globalThis;\n");
|
||||
|
||||
// ── Render-worker plugin: prepend preamble + pdf.worker.min.js + pdf.min.js ───
|
||||
//
|
||||
// Bundle order matters:
|
||||
// 1. Preamble — sets globalThis.window = globalThis
|
||||
// 2. pdf.worker.min.js — sets globalThis.pdfjsWorker.WorkerMessageHandler
|
||||
// (skips auto-setup because window is now defined)
|
||||
// 3. pdf.min.js — sets globalThis.pdfjsLib; fake-worker path reads pdfjsWorker
|
||||
// 4. Compiled TS — our render-worker code
|
||||
function prependPdfjsPlugin() {
|
||||
const pdfjsWorkerMin = fs.readFileSync(PDFJS_WORKER_MIN);
|
||||
const pdfjsMin = fs.readFileSync(PDFJS_MIN);
|
||||
const NL = Buffer.from("\n");
|
||||
return {
|
||||
name: "prepend-pdfjs",
|
||||
setup(build) {
|
||||
build.onEnd(result => {
|
||||
if (result.errors.length > 0 || !result.outputFiles) return;
|
||||
const compiled = Buffer.from(result.outputFiles[0].contents);
|
||||
const combined = Buffer.concat([
|
||||
RENDER_WORKER_PREAMBLE,
|
||||
pdfjsWorkerMin, NL,
|
||||
pdfjsMin, NL,
|
||||
compiled,
|
||||
]);
|
||||
fs.writeFileSync(path.join(OUT_DIR, "render-worker.bundle.js"), combined);
|
||||
if (!isWatch) console.log("[viewer-src] render-worker.bundle.js written");
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const sharedOptions = { bundle: true, format: "iife", target: "es2020", minify };
|
||||
|
||||
if (isWatch) {
|
||||
const viewerCtx = await esbuild.context({
|
||||
...sharedOptions,
|
||||
entryPoints: ["src/viewer.ts"],
|
||||
outfile: path.join(OUT_DIR, "viewer.bundle.js"),
|
||||
});
|
||||
|
||||
const workerCtx = await esbuild.context({
|
||||
...sharedOptions,
|
||||
entryPoints: ["src/render-worker.ts"],
|
||||
write: false,
|
||||
plugins: [prependPdfjsPlugin()],
|
||||
});
|
||||
|
||||
await viewerCtx.watch();
|
||||
await workerCtx.watch();
|
||||
console.log("[viewer-src] watching for changes…");
|
||||
// Keep the process alive
|
||||
return;
|
||||
}
|
||||
|
||||
// One-shot build
|
||||
await esbuild.build({
|
||||
...sharedOptions,
|
||||
entryPoints: ["src/viewer.ts"],
|
||||
outfile: path.join(OUT_DIR, "viewer.bundle.js"),
|
||||
});
|
||||
console.log("[viewer-src] viewer.bundle.js written");
|
||||
|
||||
// Render worker: build to memory then prepend preamble + worker + pdf.min.js
|
||||
const workerResult = await esbuild.build({
|
||||
...sharedOptions,
|
||||
entryPoints: ["src/render-worker.ts"],
|
||||
write: false,
|
||||
});
|
||||
const pdfjsWorkerMin = fs.readFileSync(PDFJS_WORKER_MIN);
|
||||
const pdfjsMin = fs.readFileSync(PDFJS_MIN);
|
||||
const NL = Buffer.from("\n");
|
||||
const compiled = Buffer.from(workerResult.outputFiles[0].contents);
|
||||
fs.writeFileSync(
|
||||
path.join(OUT_DIR, "render-worker.bundle.js"),
|
||||
Buffer.concat([RENDER_WORKER_PREAMBLE, pdfjsWorkerMin, NL, pdfjsMin, NL, compiled]),
|
||||
);
|
||||
console.log("[viewer-src] render-worker.bundle.js written");
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user