The write compare was comparing two orderings of the same set

rega's L43 check: three of four pass — the row-click shader compile is 0 ms on both engines (was
3.8 s / 7.5 s), the tab visit is no worse, the highlight stays. The collapse did not: still nine
setPaintProperty calls per row click instead of three.

Their hypothesis is right, and I had the evidence before I wrote the code. The two callers build the
same region from different lists — node.isoCodes and mapLayers.regionIsoMap[slug] — and they do not
agree on ORDER. rega said so in the very first stack trace on this bug: "a case over ['IND',…]" from one
path, "a case over ['MYS',…], a different literal order" from the other. I then wrote a JSON-string
compare, which cannot match two orderings of one set. The pre-warm half worked because that expression
is a shared constant; this half compared text that was never going to be equal.

The list is now canonical before both the compare and the write — de-duplicated, upper-cased, sorted —
so the expression is a function of the SET, which is the thing the two callers actually agree on. Order
is irrelevant to `in` membership, and the case normalisation is a no-op on today's data (both lists come
from the same regions dataset, and the highlight matches now, so they are already upper-case); it is
there so a future source that ships lower-case cannot silently select nothing.

★ IT IS ALSO A TEST, and worth reading as one. If the count drops to 3, the two sources agree about
which countries are in a region. If it does not, they disagree about the CONTENT — a data defect this
compare would otherwise have hidden behind a last-writer-wins repaint, and the next thing to chase.

Verified: gates:pre 13/13. Chained on f7a2f001 (same file). Needs rega: re-count with the same probe.
This commit is contained in:
Doxa Maps 2026-09-28 06:25:36 +00:00
parent 16c98acfe9
commit c0c1a72851

View file

@ -1113,7 +1113,19 @@ const REGION_IDLE_COLOR = ['case', ['has', 'iso_3166_1_alpha_3'], 'rgba(60,60,80
const REGION_IDLE_WIDTH = ['case', ['has', 'iso_3166_1_alpha_3'], 0.6, 0.6]
function paintRegionScope(m, isoCodes) {
if (!m || !m.getLayer('regions-fill')) return
const list = Array.isArray(isoCodes) ? isoCodes.filter(Boolean) : []
// ★ CANONICAL FIRST, OR THE COMPARE BELOW IS A LIE (rega, L43: still 9 writes per click, not 3).
// The two sources build the same region from different lists — node.isoCodes and
// mapLayers.regionIsoMap[slug] — and they do not agree on ORDER. rega had already told me that in
// the very first stack trace ("a case over ['IND',…]" then "a case over ['MYS',…], a different
// literal order") and I wrote a JSON-string compare anyway, which can never match two orderings of
// the same set. Sorting and de-duplicating makes the expression a function of the SET, which is what
// the two callers actually agree on.
//
// It is also a test: if the write count does not drop to 3, the two sources disagree about WHICH
// countries are in the region, which is a data defect this compare would otherwise have hidden.
const list = Array.isArray(isoCodes)
? [...new Set(isoCodes.filter(Boolean).map((c) => String(c).toUpperCase()))].sort()
: []
const isoArr = ['literal', list]
const fill = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 0.85, 0.15] : REGION_IDLE_FILL
const color = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], '#111827', 'rgba(60,60,80,0.15)'] : REGION_IDLE_COLOR