// The CLJS compiler numbers protocol `…$dyn_<N>` vars with the JVM-global
// gensym counter, so two otherwise-identical release builds differ in those
// digits alone (verified: renumbering them is the ONLY delta between clean
// builds). These vars are file-local (`var` in the ESM module scope) and only
// ever referenced within the same file, so a consistent per-file renumbering
// in first-occurrence order is semantics-preserving — and makes the committed
// dist byte-deterministic, which deploy/check-dist.sh requires.
// (Canon copy: train-kit; this one walks BOTH stacks' dist/ recursively — the
// bot's four bundles live in two npm roots, stack-a/dist and stack-b/dist.)
//
// `proto_<N>` rides the same JVM-global counter: banca.lib.fold (compiled off
// the classpath into dist/worker.js) hoists its class-surface top-level
// `(let [proto …])` binding to a module-scope `var proto_<N>`, verified to be
// the only other delta between clean builds. Same class of var (file-local,
// never referenced across files), same fix.
//
// `proto_STAR__<N>` is the same binding under bursa.lib.match's spelling of it
// — `(let [proto* …])`, munged. The name of the local is the app author's
// taste and the counter is the JVM's; both hoist to the same kind of
// module-scope var, so both are normalized here.
import { readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
import { join } from "node:path";
const DISTS = ["../stack-a/dist", "../stack-b/dist"].map(
(d) => new URL(d, import.meta.url).pathname,
);
const DYN = /([A-Za-z0-9_$]+\$dyn|\bproto(?:_STAR_)?)_(\d+)\b/g;
function walk(dir) {
for (const name of readdirSync(dir)) {
const p = join(dir, name);
if (statSync(p).isDirectory()) walk(p);
else if (name.endsWith(".js")) fix(p);
}
}
function fix(file) {
const src = readFileSync(file, "utf8");
const mapping = new Map();
const out = src.replace(DYN, (m, stem) => {
if (!mapping.has(m)) mapping.set(m, `${stem}_${mapping.size + 1}`);
return mapping.get(m);
});
if (out !== src) writeFileSync(file, out);
}
for (const d of DISTS) walk(d);
console.log("normalize-gensyms: dyn vars renumbered deterministically");