mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-10-03 11:37:54 +00:00
Move the D-section (~21 lines) from screen.js factory scope to its own module.
Exports:
- loadThree() — memoised import() with local-vendor→CDN fallback; same body verbatim
- T (live let-binding) — updated to the Three.js namespace on first resolution
screen.js gains: import { loadThree, T } from './src/three-loader.js'
screen.js loses: let T = null; let threeLoadPromise = null; function loadThree()
T and loadThree remain accessible to the IIFE via module-scope closure. The live
let-binding means the IIFE reads the populated T after loadThree() resolves
without any call-site changes.
Panel-controls vm test: strip regex extended to consume all consecutive import
lines; T: null + loadThree stubs added to sandbox context.
Class-killer tests (8 new — highway_3d_three_loader.test.js):
- loadThree exported (mutation: rename/remove → import fails)
- T exported as mutable let (mutation: const → T=mod throws TypeError)
- T=mod in both .then handlers (mutation: remove both → T stays null)
- memoisation guard !threeLoadPromise (mutation: remove → race + duplicate loads)
- CDN fallback .catch chain (mutation: remove → deploy failures unrecoverable)
- threeLoadPromise reset on failure (mutation: remove → no retry possible)
- screen.js imports loadThree+T (wiring confirmed)
- IIFE no longer declares local T or threeLoadPromise (shadow defeated)
All class-killer mutations confirmed distinguishable before commit.
Base run (5e401af): 180/180 pass.
Post-cut run: 188/188 pass.
Command: node --test tests/js/highway_3d*.test.js plugins/highway_3d/tests/*.test.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014uZ169yfoFYArXz962g7KW
39 lines
1.5 KiB
JavaScript
39 lines
1.5 KiB
JavaScript
/**
|
|
* Three.js lazy loader — h3d-carve-2.
|
|
*
|
|
* Memoised singleton: the first `loadThree()` call kicks off the import;
|
|
* every subsequent call returns the same promise. `T` is a live-binding
|
|
* export so the IIFE in screen.js sees the updated reference after the
|
|
* promise resolves without any explicit getter call.
|
|
*
|
|
* Falls back to jsdelivr CDN when the local vendor copy is unavailable
|
|
* (air-gapped / static-file layout mismatch / dev origin).
|
|
*/
|
|
|
|
// ── URL constants (mirrors screen.js A-section; never vary at runtime) ──────
|
|
|
|
const THREE_URL = '/static/vendor/three/three.module.min.js';
|
|
const THREE_CDN = 'https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.min.js';
|
|
|
|
// ── Memoised loader ───────────────────────────────────────────────────────────
|
|
|
|
/** Live binding — updated to the Three.js module namespace on first load. */
|
|
export let T = null;
|
|
|
|
let threeLoadPromise = null;
|
|
|
|
export function loadThree() {
|
|
if (!threeLoadPromise) {
|
|
threeLoadPromise = import(THREE_URL)
|
|
.then(mod => { T = mod; return mod; })
|
|
.catch(() => import(THREE_CDN)
|
|
.then(mod => { T = mod; return mod; })
|
|
.catch(e => {
|
|
console.error('[3D-Hwy] Three.js load failed:', e);
|
|
threeLoadPromise = null;
|
|
throw e;
|
|
}));
|
|
}
|
|
return threeLoadPromise;
|
|
}
|