From cb6ee50e7a4e43399d7045cfaae433cf03028cc2 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Fri, 25 Sep 2026 06:11:17 +0000 Subject: [PATCH] check:shared-reached: a bundle that never compiles the changed code is not "missing" the fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ensureEngineCSS is only called by initializeMap. A bundle that imports pieces of useMapInstance (ensureEngineScript, engineGlobal…) but never initializeMap has ensureEngineCSS tree-shaken away, so the guard can never appear in it and the race cannot happen there. The check counted those bundles as missing the fix. upg100 caught it on my-upg-100-list. The map-unmount-guard entry now also declares the unguarded shape. A bundle is missing the fix only if it still compiles ensureEngineCSS without the guard. With neither shape it is reported as not affected. Entries without a staleRe behave exactly as before. On today's tree: 7 bundles carry it, 2 are really stale (doxa-research-map, research-dashboard), and 3 are not affected (cities-internet, gospel-resources, my-upg-100-list). Before this, all three were reported as stale. --- ...check-shared-component-reached-bundles.mjs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/check-shared-component-reached-bundles.mjs b/internal/check-shared-component-reached-bundles.mjs index afa5c211b..a81bce70c 100644 --- a/internal/check-shared-component-reached-bundles.mjs +++ b/internal/check-shared-component-reached-bundles.mjs @@ -72,6 +72,13 @@ const MARKERS = [ component: 'library/composables/useMapInstance.js', sourceRe: /if \(!element\) return\n\s*const root = element\.getRootNode\(\)/, builtRe: /if\(!([\w$]+)\)return;const ([\w$]+)=\1\.getRootNode\(\);if\(!\(\2 instanceof ShadowRoot\)\)return/, + // ★ NOT EVERY CONSUMER COMPILES THE GUARDED FUNCTION. ensureEngineCSS is only called by + // initializeMap; a bundle that imports pieces of useMapInstance (ensureEngineScript, engineGlobal…) + // but never initializeMap gets it TREE-SHAKEN AWAY, so the guard can never appear there — and the + // race cannot happen there either. Reported by upg100 (my-upg-100-list) 2026-09-25: 3 of 12 + // bundles were false negatives. `staleRe` is the UNGUARDED shape: a bundle is MISSING the fix only + // if it still compiles ensureEngineCSS without the guard; with neither shape it is NOT AFFECTED. + staleRe: /const ([\w$]+)=([\w$]+)\.getRootNode\(\);if\(!\(\1 instanceof ShadowRoot\)\)return/g, marker: 'if (!element) return (ensureEngineCSS)', landed: 'studio, 2026-09-25', why: 'a map whose pane unmounts mid-initialise no longer throws "reading getRootNode" (check-map-unmount-mid-init)', @@ -80,6 +87,13 @@ const MARKERS = [ // A marker is a literal (`marker`, matched with includes) unless the entry supplies regexes. const inSource = (m, src) => (m.sourceRe ? m.sourceRe.test(src) : src.includes(m.marker)) const inBuilt = (m, js) => (m.builtRe ? m.builtRe.test(js) : js.includes(m.marker)) +// With a staleRe: does the bundle compile the OLD shape — an occurrence NOT immediately preceded by +// the guard? (The guarded form contains the old shape as a substring, hence the look-behind.) +const hasStale = (m, js) => { + if (!m.staleRe) return true + for (const x of js.matchAll(new RegExp(m.staleRe.source, 'g'))) if (!/return;$/.test(js.slice(Math.max(0, x.index - 24), x.index))) return true + return false +} if (!existsSync(TREE)) { console.log(`SHARED-REACHED-BUNDLES: SKIP — no built tree at ${TREE}.`) @@ -158,19 +172,23 @@ for (const m of MARKERS) { const have = [] const missing = [] const unbuilt = [] + const unaffected = [] for (const bundle of consumers) { const built = join(TREE, bundle, `${bundle}.js`) if (!existsSync(built)) { unbuilt.push(bundle); continue } const js = readFileSync(built, 'utf8') - ;(inBuilt(m, js) ? have : missing).push(bundle) + if (inBuilt(m, js)) have.push(bundle) + else if (hasStale(m, js)) missing.push(bundle) + else unaffected.push(bundle) } console.log(` ${m.id} — ${m.why}`) console.log(` landed ${m.landed}; ${have.length} of ${have.length + missing.length} built ` - + `consumer(s) carry it${unbuilt.length ? `, ${unbuilt.length} not built` : ''}`) + + `consumer(s) carry it${unaffected.length ? ` (${unaffected.length} not affected)` : ''}${unbuilt.length ? `, ${unbuilt.length} not built` : ''}`) if (have.length) console.log(` ✓ ${have.join(', ')}`) if (missing.length) console.log(` ✗ ${missing.join(', ')}`) if (unbuilt.length) console.log(` · not built: ${unbuilt.join(', ')}`) + if (unaffected.length) console.log(` – not affected (the changed code is not compiled in): ${unaffected.join(', ')}`) if (missing.length) { fails.push(`${m.id}: ${missing.length} bundle(s) do NOT carry "${m.why}" — ${missing.join(', ')}`)