Audit: testable cube logic, renderer optimization, PWA cache fix - #1
Merged
Conversation
…hing Refactor and tighten the CubeFlow trainer without changing its zero-build, browser-only deployment model. Testability - Extract pure cube-state logic (validation, parity, scramble, move helpers) into src/cube-logic.js with no DOM/Three.js dependencies so it can run under Node. app.js now imports these and maps machine- readable validation codes to its user-facing copy. - Add a node:test suite (test/cube-logic.test.mjs) and package.json dev tooling. Covers count/center/corner/edge/parity validation, scramble well-formedness, and move inversion round-trips. Renderer performance - Share the shell geometry, shell material, and sticker geometry across all cubelets instead of cloning them on every rebuild (each move rebuilds the cube), cutting per-move allocations sharply. - Replace the always-on requestAnimationFrame loop with on-demand rendering: frames are drawn only when the view changes or damping is still settling, so an idle cube no longer renders 60fps forever. PWA reliability - Service worker now uses stale-while-revalidate for same-origin assets so deployments reach returning visitors, precaches the new logic module, and keeps cache-first for immutable CDN libraries. Tooling and docs - Add the GitHub Pages workflow the README references (runs tests, then deploys the static site); update README architecture and add a Tests section; ignore node_modules. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDijW82Hm9yCyUpntvaRRp
The Pages workflow only triggered on push to main, so PRs had zero CI signal before merge. Split into a test.yml that runs on every PR and push, and keep pages.yml focused on deploying main (it still runs the test suite as a pre-deploy gate). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDijW82Hm9yCyUpntvaRRp
Several elements (canvas-fallback, solve-empty, secondary-button/install
-button, cube-canvas) set `display` unconditionally in a normal-priority
author rule, which always wins over the user-agent stylesheet's
`[hidden] { display: none }` regardless of specificity. This made the
"3D view unavailable" fallback panel render on top of the working 3D
canvas on every single page load for every visitor, independent of
browser, WebGL, or CDN availability — reported as a live bug on GitHub
Pages and confirmed via DevTools (fallback.hidden was true, WebGL was
hardware-accelerated, and the Three.js/cube.js CDN requests returned
200, yet the panel stayed visible).
Add a single global `[hidden] { display: none !important; }` rule so
the native hidden attribute works everywhere, instead of patching each
affected selector individually.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDijW82Hm9yCyUpntvaRRp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
An audit / test / optimize pass on the CubeFlow trainer. The app keeps its zero-build, browser-only deployment model — the only new dependency (cube.js engine + Node test runner) is dev-only and gitignored.
Changes
🐛 Service worker never updated returning users
Same-origin app assets (
app.js,styles.css,cube-renderer.js) were served cache-first against a static cache version, so any deploy after a visitor's first load would never reach them. Switched same-origin assets to stale-while-revalidate, precached the new logic module, bumped the cache version, and kept cache-first for immutable CDN libraries.⚡ Renderer performance
requestAnimationFrameloop (which rendered forever even on a completely idle cube) with on-demand rendering — frames draw only when the view changes or OrbitControls damping is still settling.🧪 Testability + tests (there were none)
src/cube-logic.js— no DOM/Three.js deps.app.jsnow maps machine-readable validation codes to its user-facing copy.node:testsuite (test/cube-logic.test.mjs, 13 tests) covering count/center/corner-twist/edge-flip/parity validation, scramble well-formedness + determinism, and move-inversion round-trips.📄 Tooling & docs
.github/workflows/pages.yml) — runs tests, then deploys the static site..gitignorefornode_modules.Verification
npm test).Not included (deliberately)
The app still loads Three.js and cube.js from jsDelivr at runtime. Vendoring them into
assets/vendor/(as the README suggests) would make the PWA fully offline and dependency-free, but adds ~1 MB of library files to the repo — left as a follow-up call.🤖 Generated with Claude Code
https://claude.ai/code/session_01XDijW82Hm9yCyUpntvaRRp
Generated by Claude Code