Skip to content

Fix RadioScanner crash: react-fast-marquee CJS interop shim#178

Merged
robbiebyrd merged 1 commit into
mainfrom
fix/marquee-cjs-interop
Jul 10, 2026
Merged

Fix RadioScanner crash: react-fast-marquee CJS interop shim#178
robbiebyrd merged 1 commit into
mainfrom
fix/marquee-cjs-interop

Conversation

@robbiebyrd

Copy link
Copy Markdown
Collaborator

RadioScanner crashed on open with Element type is invalid ... got: object in NowPlayingList.

Root cause: react-fast-marquee ships CJS-only (main: dist/index.js, no exports map). Vite 8's rolldown dep optimizer emits export default require_dist() — the raw CJS namespace {__esModule, default: Marquee} — so the default import reaches React as an object, not a component. The unit tests mocked the module, which is exactly how this got past the gates on #177.

Fix:

  • New RadioScanner/marquee.ts shim that unwraps .default defensively (correct under dev, build, and vitest interop shapes); both call sites import it. A real-render test (ResizeObserver stubbed) now exercises the actual package instead of a mock.
  • Restores the per-title marquee layout that the RadioScanner: swap react-marquee-text for react-fast-marquee #177 merge clobbered (marquee wraps each title span, not the whole list).
  • OFFLINE ticker wrapper pdiv (the marquee renders block divs; div-in-p is invalid HTML and React 19 errors on it).

Verified live on a fresh vite dev server: RadioScanner opens, marquees scroll, console clean of both the crash and the DOM-nesting error. Gates: tsc, eslint, 375 tests green.

🤖 Generated with Claude Code

https://claude.ai/code/session_019NMS1V2keS3pTbWRemCd9o

…le marquee

react-fast-marquee ships CJS-only; Vite 8's rolldown optimizer re-exports the
raw CJS namespace as the default export, so the component arrived as
{__esModule, default} and React crashed RadioScanner with 'Element type is
invalid'. New ./marquee shim unwraps .default defensively (all interop
shapes). Tests mocked the module, which is how this slipped past the gates —
the shim has a real-render test now.

Also restores the per-title marquee layout that PR #177's merge clobbered,
and swaps the OFFLINE wrapper p->div (marquee renders block divs; div-in-p
is invalid HTML and React 19 errors on it).

Verified live: RadioScanner opens clean on a fresh vite dev server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019NMS1V2keS3pTbWRemCd9o
@robbiebyrd robbiebyrd enabled auto-merge July 10, 2026 02:44
@github-actions

Copy link
Copy Markdown

Playwright E2E — 1 passed · 0 failed · 0 flaky · 0 skipped

Full report

@robbiebyrd robbiebyrd merged commit 27fc8d5 into main Jul 10, 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