diff --git a/plugin-designs/doxa-research-map/scripts/check-clustering-modes.mjs b/plugin-designs/doxa-research-map/scripts/check-clustering-modes.mjs index 1485873be..64fc32358 100644 --- a/plugin-designs/doxa-research-map/scripts/check-clustering-modes.mjs +++ b/plugin-designs/doxa-research-map/scripts/check-clustering-modes.mjs @@ -41,7 +41,11 @@ import { fileURLToPath } from 'node:url' const TAG = 'CLUSTERING-MODES' const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..') -const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json') +// The tree's folder name is configurable and was renamed on 2026-09-25; reading it from the one +// helper is what keeps this gate pointed at the tree that exists. A hardcoded name does not error, +// it 404s — and a gate that 404s reports a clean page. +const { TREE_NAME } = await import(join(ROOT, 'internal', '_tree-name.mjs')) +const MANIFEST = join(ROOT, 'public', TREE_NAME, 'manifest.json') const skip = (why) => { console.log(`${TAG}: SKIP — ${why}`); process.exit(0) } if (!existsSync(MANIFEST)) skip('no built manifest (run `bun run tree` first).') @@ -57,7 +61,7 @@ const freePort = () => new Promise((ok) => { const s = createServer().listen(0, '127.0.0.1', () => { const p = s.address().port; s.close(() => ok(p)) }) }) const PORT = await freePort() -const TREE = `http://127.0.0.1:${PORT}/doxa-maps` +const TREE = `http://127.0.0.1:${PORT}/${TREE_NAME}` const LEAF = `${TREE}/${String(profile.iframeUrl).replace(/^\.\//, '')}` const tree = spawn(process.execPath, ['internal/serve-strict.mjs', '--port', String(PORT)], { cwd: ROOT, stdio: 'ignore' }) @@ -133,10 +137,29 @@ try { return JSON.parse(prev) } + // ★ WAIT FOR THE DRAWING TO CHANGE BEFORE WAITING FOR IT TO SETTLE. "Two consecutive reads + // agree" is not enough on its own: the previous mode's output is still on the map for as long + // as the new mode takes to compute, so a stable read can be the OLD picture. MEASURED — a rerun + // reported Network drawing 1,700 lines, exactly MST's number, where an earlier run of the same + // build gave 23,896. Not a product regression: the settle returned while MST's lines were still + // up. So each mode first waits for the report to DIFFER from what was on screen when it was + // clicked, and only then waits for it to stop moving. If it never differs, that is recorded as + // it stands and the assertions below say so — which is the honest outcome either way. + const changed = async (before, maxMs) => { + const t0 = Date.now() + while (Date.now() - t0 < maxMs) { + await sleep(1000) + if (JSON.stringify(draw()) !== before) return true + } + return false + } + const out = {} const MODES = ['off', 'mapbox', 'mst', 'network'] for (let i = 0; i < MODES.length; i++) { + const before = JSON.stringify(draw()) buttons[i].click() + await changed(before, 60000) out[MODES[i]] = await settle(90000) } return out diff --git a/plugin-designs/doxa-research-map/scripts/check-pin-dim-slider.mjs b/plugin-designs/doxa-research-map/scripts/check-pin-dim-slider.mjs index 42aea1efb..3d91e8a60 100644 --- a/plugin-designs/doxa-research-map/scripts/check-pin-dim-slider.mjs +++ b/plugin-designs/doxa-research-map/scripts/check-pin-dim-slider.mjs @@ -30,7 +30,11 @@ import { fileURLToPath } from 'node:url' const TAG = 'PIN-DIM-SLIDER' const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..') -const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json') +// The tree's folder name is configurable and was renamed on 2026-09-25; reading it from the one +// helper is what keeps this gate pointed at the tree that exists. A hardcoded name does not error, +// it 404s — and a gate that 404s reports a clean page. +const { TREE_NAME } = await import(join(ROOT, 'internal', '_tree-name.mjs')) +const MANIFEST = join(ROOT, 'public', TREE_NAME, 'manifest.json') const skip = (why) => { console.log(`${TAG}: SKIP — ${why}`); process.exit(0) } if (!existsSync(MANIFEST)) skip('no built manifest (run `bun run tree` first).') @@ -46,7 +50,7 @@ const freePort = () => new Promise((ok) => { const s = createServer().listen(0, '127.0.0.1', () => { const p = s.address().port; s.close(() => ok(p)) }) }) const PORT = await freePort() -const TREE = `http://127.0.0.1:${PORT}/doxa-maps` +const TREE = `http://127.0.0.1:${PORT}/${TREE_NAME}` const LEAF = `${TREE}/${String(profile.iframeUrl).replace(/^\.\//, '')}` const tree = spawn(process.execPath, ['internal/serve-strict.mjs', '--port', String(PORT)], { cwd: ROOT, stdio: 'ignore' }) const cleanup = () => { try { tree.kill() } catch { /* already gone */ } }