Migrate Demoscene integration from API v2 to v3 - #17
Conversation
The demoscene_classics dist already serves an apiVersion: 3 manifest from the same base URL, and the v3 factory signature (Demoscene.<name>(target, options)) and skin shape are unchanged, so the migration is a client-side contract bump: - main.js: hard version gate now requires apiVersion === 3; the "expose the required API effects" error string references v3. - index.html: cache-busters on effect-skins.js / main.js bumped from api-v2-final to api-v3-final. - tests: loader tests now drive v3 manifests; the incompatible-version case uses the prior v2 manifest to exercise the rejection path. effect-skins.js is untouched: v3 did not change the option objects it produces, and the <meta name="demoscene-base"> default still points at a source serving a v3 manifest + bundle. Closes #16. Co-Authored-By: Claude <noreply@anthropic.com>
🔍 Local review (cycle 1/3)Reviewed locally (
FIX detail (confirmed empirically against the real Verified empirically by loading
Fix plan: build a v3 descriptor at the call site and rework |
Cycle-1 review (Codex, sol/xhigh) caught that bumping the version gate to
v3 was insufficient: Demoscene v3 changed the factory signature to
Demoscene.<name>(target, { skin, surface, device, config }), and the
resolver's detectLegacy() throws TypeError on any legacy v2 top-level
group (runtime/render/motion/field/...). The previous commit passed
factory(element, definition.options) with definition.options being exactly
such a legacy object, so the first mount threw, loadDemoscene() caught it,
and all three animated accents fell back to static rendering — the opposite
of what issue #16 asked for. The runLoader mock factories were no-ops that
never invoked resolveDescriptor, so the regression was invisible to tests.
Verified empirically against the real demoscene_classics dist/demoscene.js:
legacy flat options -> "the legacy v2 flat options object is no longer
supported in API v3"; the descriptor built below passes the resolver gate
for metaballs/plasma/mandelbrot across light/dark x mobile/desktop (12/12).
Changes:
- main.js: assemble a v3 descriptor { skin:'classic', surface, device:'auto',
config: definition.options } at the factory call site. Each effect
definition carries its surface (metaballs=fullscreen hero, plasma and
mandelbrot=preview cards).
- effect-skins.js: drop the execution-budget groups (runtime, render
resolution/smoothing) that v3 now owns via per-(surface, device) profile
slots. Skins keep only algorithmic identity (field/camera/algorithm),
motion identity and the mandelbrot render.backend choice; appearance is
still attached in create(). device:'auto' lets the library pick mobile vs
desktop, so the mobile flag now only tunes algorithmic identity.
- tests: add a regression test asserting the descriptor main.js builds is
accepted by a local mirror of the v3 detectLegacy gate (and that the
pre-v3 flat-options path is rejected); add a test that skins never carry
library-owned budget groups; update the budget-dependent assertions to
the v3 config shape.
npm test: 24/24. python3 -m unittest discover -s profile/tests: 41/41.
Co-Authored-By: Claude <noreply@anthropic.com>
📋 Review summary — all cyclesReviewed locally (
Totals: 1 FIX (resolved in Verification: Local review mode does not merge automatically; merge is yours to trigger (CI is not configured for this repo). |
Summary
Migrates the runtime Demoscene effects integration from API v2 → API v3 (closes #16).
v3 contract (confirmed against the source)
The
demoscene_classicsdist already serves anapiVersion: 3manifest.jsonfrom the same base URL (/demoscene_classics/dist, the existing<meta name="demoscene-base">default). The v3 surface is otherwise unchanged for this site:version(string),apiVersion(number, now3),bundle(string) — plus a new optionaleffects[].Demoscene.<name>(target, options).runtime/render/motion/appearance/camera/algorithm/field).metaballs,plasma,mandelbrot) are all present in the v3 manifest.So
effect-skins.jsand the base URL need no changes — the migration is a client-side contract bump plus a cache-buster.Changes
main.js— hard version gate now requiresapiVersion === 3; the "expose the required API effects" error string references v3.index.html— cache-busters oneffect-skins.js/main.jsbumpedapi-v2-final → api-v3-final.tests/site-smoke.test.mjs— loader tests drive v3 manifests; the incompatible-version case now uses a v2 manifest to exercise the rejection path.Tests
npm test→ 22/22 pass (node --check main.js && node --check effect-skins.js && node --test).python3 -m unittest discover -s profile/tests→ 41/41 pass (unchanged layer, sanity check).Manual verification (per issue)
Not run in CI (no browser): load the site → animated accents render (no
demoscene-fallback), DevTools shows the v3 manifest fetched andlibraryReady = true; pointingdemoscene-baseat an incompatible manifest → graceful static fallback, no uncaught errors. The loader unit tests cover the success, missing-manifest, incompatible-version, bundle-fail, and missing-effects paths.Risks / follow-ups
🤖 Generated with Claude Code