Skip to content

2026 overhaul#74

Merged
mracette merged 145 commits into
devfrom
2026-overhaul
Jun 27, 2026
Merged

2026 overhaul#74
mracette merged 145 commits into
devfrom
2026-overhaul

Conversation

@mracette

Copy link
Copy Markdown
Owner

No description provided.

mracette and others added 30 commits June 21, 2026 17:05
The pnpm migration's fresh resolve bumped deps within their semver ranges;
chroma-js 2.1.2->2.6.0 broke swampPalette (new chroma() no longer constructable),
crashing the swamp scene. Pin all direct deps to their pre-migration (yarn.lock)
versions so the pnpm baseline is behavior-identical, and assert the canvas is
attached rather than visible so the smoke test does not depend on asset load time.
…cument smoke scope

Address final-review findings: assert info-specific content (.info-subheader)
instead of a non-empty #app tautology; set reuseExistingServer to !CI; note in
the checklist that the smoke test does not exercise asset/audio loading.
Adds the regression baseline and migrates the package manager to pnpm with all
direct deps pinned to pre-migration versions. Smoke 5/5 green; final review clean.
Replace react-scripts with Vite 6 (dev server :3000, output to build/). Move
index.html to repo root, swap process.env.REACT_APP_*/PUBLIC_URL for
import.meta.env, point Playwright webServer at Vite.

Fixes required to make the migration actually run:
- esbuild jsx loader for .js files (this codebase keeps JSX in .js)
- replace require(app-config.json) with an ESM import (Vite is ESM-only)

Also remove stale committed CRA build artifacts from public/ (bundle.js,
styles.css + maps). React 17 and three r108 unchanged; build OK, smoke 5/5.
Replace the CRA react-app preset and .eslintrc.json with eslint.config.js
(react-hooks + react-refresh), drop eslint-plugin-prettier, bump Prettier to 3.
CRA is gone, so pnpm no longer needs a flat node_modules. Strict mode reinstall
surfaced no phantom dependencies; build and smoke stay green.
Prettier 3 was installed but unwired after dropping eslint-plugin-prettier;
add a 'format' script so it is runnable standalone (per the P1 plan).
mracette added 7 commits June 26, 2026 12:14
…radually

The stop branch used gsap.to(strokeDashoffset: 0), which reads its start value
lazily. The active->stopped re-render sets the resting offset to 0 first, so
gsap animated 0->0 (a no-op) and the ring appeared instantly. Use gsap.fromTo
from the full offset, symmetric with the start sweep, so it always fills in.
Driving the svg strokeDashoffset off the live `active` prop made React reset
it on the active->stopped re-render, racing gsap: with gsap.to it snapped full
(React set 0 before gsap read it); with gsap.fromTo it flashed full for a frame
(React painted 0 before gsap's first tick). Seed the resting offset from the
mount-time active state only, so React never re-applies it and gsap owns the
property — gsap.to now reads the real current offset and fills smoothly.
Integrate ~25 commits of quality work (perf-review merge, CDN/CI changes, and the vanilla-extract + cx styling refactor) into the studio branch.

Conflict resolutions keep the studio cleanups on top of quality's refactor:
- ToggleButton: kept the ToggleButtonView extraction; carried quality's scoped toggleButton/svgCircle classes (via cx) into ToggleButtonView.
- LoadingIcon/LoadingScreen/CustomSongIcons.css: kept the dead loading-state removal; dropped quality's now-unused loadingButton style/import.
- SocialIcons: kept the instagram removal on quality's cx-refactored rows.
Studio updated for quality's newly-scoped classes: SongIconsStory uses songSelectionPanel/songLink, MenuStory uses flexPanel; menu e2e selector .menu-button-parent -> .menu-button-child.
- StudioSidebar: compose classes with cx and dedup groups via Set
- Add root CLAUDE.md noting the cx className convention
- Studio: redirect unknown/bare storyId to the default story's URL
- Document /studio dev-server coupling in the e2e spec
- Rename ToggleButtonView active prop to initialActive (write-once contract)

Claude-Session: https://claude.ai/code/session_011utsEBGPQyyYstVH2HdAxR
Add dev-only /studio component playground
@mracette mracette changed the base branch from master to dev June 26, 2026 21:29
Comment thread src/utils/mathUtils.ts Outdated
Comment thread src/components/toggle-button/ToggleButtonGroup.tsx
Comment thread src/components/toggle-button/ToggleButtonGroup.tsx Outdated
Comment thread src/components/EffectsPanel.tsx Outdated
Comment thread src/components/toggle-button/ToggleButtonView.tsx Outdated
Comment thread src/components/toggle-button/ToggleButton.tsx Outdated
Comment thread src/stores/musicPlayerStore.ts Outdated
Comment thread src/viz/subjects/Stars.ts Outdated
Comment thread src/viz/scenes/mornings/renderMelody.ts Outdated
Comment thread src/components/MusicPlayer.tsx
Comment thread src/viz/SceneManager.ts
Comment thread src/components/LandingPage.tsx Outdated
mracette added 3 commits June 26, 2026 23:15
Correctness:
- mathUtils.normalize: branches were inverted and the `clamp` param
  shadowed the clamp helper, so the default path threw and clamp=true
  never clamped (FOV escaped its range on extreme aspect ratios).
- ToggleButtonGroup randomize: clamp the target count to the voice
  count so the de-dupe loop can't spin forever / index past the end.

Reducer removal (also clears the lone react-refresh warning):
- Replace LandingPage useReducer + landingPageReducer with useState and
  a song lookup; rename the `dispatch({type})` prop to `onSelect(id)`
  across the song icons, LandingPageMobile, and the story.

Simplification / reuse:
- Collapse the solo/mute and background-mode conditionals.
- Dedupe the store reset/randomize callback registries; export and
  reuse VoiceState instead of a duplicate PlayerState union.
- Reuse mathUtils.clamp/lerp and a new audioUtils.averageVolume helper;
  drop a dead Stars.lerp method, dead rotateZ params, and a
  commented-out Redux button.
- Widen cx() to accept null.
Twin of the MusicPlayer change: the trailing else-if (!backgroundMode)
is always true, so collapse it to else.
Add "type":"module" and rewrite the last require/module.exports holdouts
(eslint + playwright configs, e2e specs and helpers) as import/export so
the whole package is uniformly ESM. Clears the ts(80001) suggestions.
mracette added 5 commits June 27, 2026 17:32
Replace the hand-rolled chroma-js shim with @types/chroma-js (the official
types are complete), and drop the ~25 `(chroma as any)` casts plus the
non-idiomatic `new chroma(...)` calls. Type the EXT_disjoint_timer_query
extension and the OfflineAudioContext vendor fallback instead of casting to
any, add easeQuad to the d3-ease shim, use rest params over `arguments`,
ignore _-prefixed unused vars, and drop a dead `vh` import.

Remaining 20 are intentional: ~11 three.js casts (types pinned at
@types/three 0.103 vs three 0.108 runtime) and 9 React Compiler advisory
diagnostics on deliberate imperative escape hatches.
Delete unused shaders/birds.ts and the stale LandingPage.vert/.frag (the
landing-page shaders are inlined in LandingPageParticles.ts). Replace the
hand-rolled d3-color/d3-ease/d3-scale-chromatic shims with @types/d3-* @3.
The remaining any casts are all in the viz layer, bridging the
@types/three@0.103 vs three@0.108 runtime gap. Scope the rule off to src/viz
so those stop warning while the rest of the codebase keeps the guard.
@mracette mracette merged commit 64048ad into dev Jun 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant