mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-16 21:53:23 +00:00
refactor(app): carve the viz layer out of app.js — and delete the loader seam (R3a) (#880)
static/js/viz.js (770 lines) — the viz picker, renderer selection, Auto-match, the WebGL2 probe, the 3D-promotion nag, the notation hints. Bodies VERBATIM. app.js 11,603 → 10,857. THE SEAM IS GONE. #878's plugin-loader needed configurePluginLoader({ populateVizPicker }) purely because _populateVizPicker lived in app.js and importing app.js would have closed a cycle. viz.js is a LEAF — it imports NOTHING — so plugin-loader now imports _populateVizPicker straight from it. The _host object, the configure function, its loud-default guard, and the wiring line in app.js are all deleted. The second carve simplifies the first. app.js -> { plugin-loader, viz } plugin-loader -> viz viz -> (nothing) NOT A PURE MOVE — one listener block had to be SPLIT. app.js had a single top-level `if (window.feedBack) { … }` registering four handlers, and only two were viz. song:loaded / arrangement:changed / song:ready (the mastery slider) stay in app.js and now call the imported _autoMatchViz / _maybeShowNotationViewHint. The viz:reverted handler MOVES, because it REASSIGNS _cancelPendingAutoLabel and an imported binding is read-only — `_cancelPendingAutoLabel = null` would throw if the listener stayed behind while the state moved. ORDER CHECKED, NOT ASSUMED: viz.js's song:ready listener now registers BEFORE app.js's own (imports evaluate first). Safe — _pendingPromotionNag is only ever set inside _populateVizPicker, which runs at boot/plugin-refresh, never from inside the other song:ready handler, so the two are independent. VERIFIED — the listeners are the risk here, so they were DRIVEN, not just booted. A/B against origin/main in two browsers: * viz picker: 6 options (auto|default|venue|drum_highway_3d|keys_highway_3d| highway_3d), selected highway_3d, Auto label — IDENTICAL. This alone proves plugin-loader's direct import of viz.js works. * emit('viz:reverted') -> picker resets to default, localStorage resets to default, the warning logs — IDENTICAL. The MOVED listener fires. * emit('song:ready') -> mastery slider enables, no throw — IDENTICAL. The SPLIT listener still does both halves. * plugin screens, module injections, 37 capability participants — IDENTICAL. * zero console/page errors on both. pytest 2396, node 1038/1038, ESLint 0, tailwind-fresh clean. no-cycle re-bitten on the 3-module graph (viz -> plugin-loader fails). Codex preflight raised a [P2] claiming viz.js's top-level bus guards would be false because "app.js only creates the event bus later" — FALSE POSITIVE. app.js does not create the bus; capabilities.js does, from its own <script type="module"> at index.html:122, and module scripts execute in document order, so the bus exists long before app.js's import graph evaluates. Instrumented the setter: by viz.js's turn `window.feedBack.on` is already a function, and the viz:reverted listener is provably attached (firing it resets the picker). The ordering is also enforced by test_app_shell_loads_capability_registry_before_app_runtime. Harnesses: 5 tests retargeted to viz.js across legacy_shim_hits, venue_scene_3d, venue_viz (each SPLIT — their non-viz tests still read app.js). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5b904706d0
commit
a222b45c02
@@ -9,6 +9,9 @@ const venueScene = require('../../static/v3/venue-scene-3d.js');
|
||||
const venueViz = require('../../static/v3/venue-viz.js');
|
||||
const pov = require('../../static/v3/venue-instrument-pov.js');
|
||||
const APP_JS = path.join(__dirname, '..', '..', 'static', 'app.js');
|
||||
// The viz layer (setViz / the venue option / the picker) was carved out of
|
||||
// app.js into its own module (R3a).
|
||||
const VIZ_JS = path.join(__dirname, '..', '..', 'static', 'js', 'viz.js');
|
||||
const H3D_JS = path.join(__dirname, '..', '..', 'plugins', 'highway_3d', 'screen.js');
|
||||
const INDEX_HTML = path.join(__dirname, '..', '..', 'static', 'v3', 'index.html');
|
||||
const ASSET_DIR = path.join(__dirname, '..', '..', 'static', 'assets', 'venue', 'themes', 'small-club');
|
||||
@@ -185,8 +188,8 @@ test('venue-scene-3d exports bg plate asset ids', () => {
|
||||
assert.equal(venueScene.ASSET_BASE, '/static/assets/venue/themes/small-club/');
|
||||
});
|
||||
|
||||
test('app.js syncs venue 3D scene on viz changes', () => {
|
||||
const src = fs.readFileSync(APP_JS, 'utf8');
|
||||
test('viz.js syncs venue 3D scene on viz changes', () => {
|
||||
const src = fs.readFileSync(VIZ_JS, 'utf8');
|
||||
assert.match(src, /v3VenueScene3d\.syncViz\('venue'\)/);
|
||||
assert.match(src, /v3VenueScene3d\.syncViz\(id\)/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user