diff options
| author | Adam Soltys <[email protected]> | 2026-08-26 14:16:41 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-26 14:16:41 -0700 |
| commit | e18a74b936e43aeb7f74df433d88f294f9bcc877 (patch) | |
| tree | f50c34564d964555ee44a3b1e199e10240016d43 /tools/feature-registry-check.js | |
| parent | 0427a1b02c21fd5fa9f5df8a86e435dbb84a8451 (diff) | |
| download | coinosv3-e18a74b936e43aeb7f74df433d88f294f9bcc877.tar.gz coinosv3-e18a74b936e43aeb7f74df433d88f294f9bcc877.zip | |
The app arrives in movements: real ESM chunks split the bundle (entry 333KB, shared chunks alongside, 61KB of gifts/NWC/hats deferred past first paint into slots that keep their hook seniority), the lazy scripts wear IIFE coats so their names can't collide with the page's — which is what silently broke the remote-signer button — nip98 moves out of the login module so minimal builds stop hauling backup relays, and the smoke test learns the front door's new steps while the regtest stack rises from its IBD nap
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'tools/feature-registry-check.js')
| -rw-r--r-- | tools/feature-registry-check.js | 51 |
1 files changed, 20 insertions, 31 deletions
diff --git a/tools/feature-registry-check.js b/tools/feature-registry-check.js index 9b7ac5e..0931156 100644 --- a/tools/feature-registry-check.js +++ b/tools/feature-registry-check.js @@ -1,40 +1,29 @@ -// Guard: src/features/index.js and build.js's ALL_FEATURES must agree. +// Guard: src/features/index.js and build.js's featureIndexSource must agree. // They drifted once (nwc was added to index.js only, so its i18n strings // shipped but its code never did — the settings card silently never rendered, // because build.js SWAPS OUT features/index.js for a generated module). +// +// The strongest form of agreement is equality: the checked-in module must be +// code-identical (comments and whitespace aside) to what featureIndexSource +// generates for the full feature set — imports, construction order, deferred +// placeholder slots, and the deferred loader all included. // bun tools/feature-registry-check.js import { readFileSync } from 'node:fs'; +import { featureIndexSource, enabledFeatures } from '../build.js'; -const idx = readFileSync(new URL('../src/features/index.js', import.meta.url), 'utf8'); -const build = readFileSync(new URL('../build.js', import.meta.url), 'utf8'); +const strip = (s) => s + .replace(/\/\/[^\n]*/g, '') // line comments + .replace(/\s+/g, ' ') // whitespace runs + .replace(/, /g, ',').replace(/ ,/g, ',') + .trim(); -const inIndex = [...idx.matchAll(/import \{ (\w+Feature) \} from '\.\/([\w-]+)\.js'/g)] - .map((m) => ({ fn: m[1], name: m[2] })); -const registry = build.match(/const ALL_FEATURES = \{([^}]*)\}/s)?.[1] || ''; -const inBuild = [...registry.matchAll(/(\w+):\s*'(\w+Feature)'/g)].map((m) => ({ name: m[1], fn: m[2] })); +const idx = readFileSync(new URL('../src/features/index.js', import.meta.url), 'utf8'); +const gen = featureIndexSource(enabledFeatures(undefined)); -let ok = true; -for (const f of inIndex) { - if (!inBuild.find((b) => b.fn === f.fn)) { - console.log(`x ${f.fn} (${f.name}.js) is in features/index.js but NOT in build.js ALL_FEATURES — it will not ship`); - ok = false; - } -} -for (const b of inBuild) { - if (!inIndex.find((f) => f.fn === b.fn)) { - console.log(`x ${b.fn} is in build.js ALL_FEATURES but not imported in features/index.js`); - ok = false; - } -} -// Compare the ORDER FEATURES ARE CONSTRUCTED IN (hook precedence depends on -// it), not the order they happen to be imported in. -const built = [...(idx.match(/return \[([^\]]*)\]/s)?.[1] || '') - .matchAll(/(\w+Feature)\(ctx\)/g)].map((m) => m[1]); -const orderIdx = built.join(','); -const orderBuild = inBuild.map((b) => b.fn).join(','); -if (ok && orderIdx !== orderBuild) { - console.log(`x feature ORDER differs (hook precedence depends on it)\n index.js: ${orderIdx}\n build.js: ${orderBuild}`); - ok = false; +if (strip(idx) !== strip(gen)) { + console.log('x src/features/index.js does not match build.js featureIndexSource (full set)'); + console.log('\n--- generated (normalized) ---\n' + strip(gen)); + console.log('\n--- checked in (normalized) ---\n' + strip(idx)); + process.exit(1); } -if (ok) console.log(`ok ${inIndex.length} features registered consistently`); -process.exit(ok ? 0 : 1); +console.log(`ok features/index.js matches the generator (${enabledFeatures(undefined).length} features, deferred slots included)`); |
