Three top-level files brought in sync with the work landed on
feat/react19-modernization:
- CHANGELOG.md gets a 'React 19 Modernization Phase 2 (2026-05-12)'
section spanning all four pattern groups (event-state companions,
TanStack queries on the catalog layer, god-hook splits in the
doorbell + singleton-filter styles, Pixi v8 / TS 5.7+ alignment),
the Vitest growth 65 -> 113, and the in-scope logic bug fixes.
- ARCHITECTURE.md bumps the test ledger 99 -> 113 (adds the
avatar-info reducer suite), documents the new pure-module test
convention (concrete file paths + 'import type' for renderer
event types), and lists the two new singleton-filter splits
(notification, friends).
- CLAUDE.md mirrors the same updates plus a 'Singleton-filter split'
recipe alongside the doorbell-style one; useNitroEventInvalidator
is documented next to useNitroQuery; the 'What's wired up' table
enumerates all 10 split hooks. Test count bumped 99 -> 113 in
both the 'Vitest' row and the green-bar house rule.
useNotification is consumed by ~44 sites in the codebase but most of
them only need a single imperative entry point (typically simpleAlert
or showConfirm). The hook also runs ~24 useMessageEvent listeners
internally to translate server events into queued notifications.
Same singleton-filter pattern as useWiredTools / useTranslation:
- useNotificationStore (internal, was useNotificationState) — the
previous body unchanged. ~30 listeners + 5 state slices + 8 actions
in one closure.
- useNotificationState (public, read-only) — useBetween filter
exposing only the three queue arrays (alerts, bubbleAlerts,
confirms). Used by the global NotificationView renderer.
- useNotificationActions (public, imperative) — useBetween filter
exposing the 8 entry points: simpleAlert / showNitroAlert /
showTradeAlert / showConfirm / showSingleBubble +
closeAlert / closeBubbleAlert / closeConfirm.
- useNotification (deprecated shim) — composes the singleton via
useBetween, preserving the historical return shape so the 44
existing call sites keep working.
Also brings CLAUDE.md's 'What's wired up' table up to date with the
splits done this session (chat-input doorbell-style, wired-tools +
translation singleton-filter, plus this notification one) and the
8 useCatalog fetch migrations to TanStack queries.
- Pattern #2 (useNitroQuery): list the eight catalog-layer queries
carved out of useCatalog this session (gift / groups / club offers /
pet palette / marketplace / club gifts), plus the new
useNitroEventInvalidator companion for server-push refresh.
- Note ICatalogOptions deleted — the legacy 'catalogOptions' bag has
no remaining fields after the migrations, useCatalog no longer
exposes it.
- New 'useCatalog decomposition (in progress)' table — what's been
lifted to TanStack and what's deferred (page tree + Builders Club
status, both core state slices that move with the data/actions
split).
- Pattern #4 (god-hook split): add the three new splits done this
session (chat-input doorbell-style, wired-tools singleton-filter,
translation singleton-filter inline).
- Bump Vitest count 83 → 99 (added 16 cases on the
useCatalogFavorites helpers).
- Note the pure-module test convention: import from concrete file
paths rather than the api barrel to avoid jsdom pulling in Pixi.
- Typecheck baseline: client now reports 0 too (was 57 at last
doc-write); the section's enumerated sweeps all landed.
- CLAUDE.md: bump '77/77' references to '99/99' (both places).
Two doc changes so a fresh local Claude Code session can pick up the
branch without re-discovering the conventions and the work-in-progress.
CLAUDE.md (new, repo root)
- Onboarding file Claude Code reads automatically at session start.
- TL;DR with branch name + PR number, points at docs/ARCHITECTURE.md.
- Stack snapshot (React 19, TS 7 native, Vite 8 + Compiler, Zustand 5,
TanStack Query 5, Vitest 3).
- Layout convention spelled out — `src/components/<area>/<feature>/`
for views, `src/hooks/<area>/<feature?>/` flat for hooks. The
rejected-feature-folders decision is the most stepped-on rake, so
it lives here at the top.
- The canonical 3-file god-hook split shape with doorbell as the
reference.
- Patterns to use with copy-pasteable signatures: useNitroEventState,
useMessageEventState, useNitroQuery (with the accept() filter),
Zustand stores via createNitroStore, WidgetErrorBoundary.
- "Wired up vs not yet" matrix: what each pattern is adopted on and
what the next reasonable target is.
- Pointer to the two still-open logic bugs (MainView CREATED/ENDED
race; LayoutFurniImageView async fetch race) with fix shapes.
- House rules: commit author override, no claude/... branch names,
never merge a layout-violating branch, skip-motivated splits are
fine if explained in the commit message.
docs/ARCHITECTURE.md (refresh)
- "What's already in place" rewritten to reflect the full state of
the feat/react19-modernization branch:
* stale references to the old claude/update-react-typescript-He2rs
branch removed
* the three additional god-hook splits done since the last edit
(furni-chooser, user-chooser, friend-request) added
* the 4 useNitroQuery migration sites listed (OfferView,
CatalogLayoutRoomAdsView, ModToolsChatlogView, CfhChatlogView)
* the three additional WiredCreatorToolsView tab extractions
(Monitor, Inspection, Variables) with the 4493 -> 3544 line
counter
* dead-code removal of the legacy login dialogs documented
* the Vitest count updated from 22 to 77 across 6 test files
* usePollSubscriptions hoist to RoomWidgetsView noted
- "How to pick the next refactor PR" rewritten:
* completed items removed (the previous list still had
"hoist usePollSubscriptions" as todo even though it's done,
and "per-tab WiredCreatorTools split" same)
* remaining priorities re-ordered: useCatalog migration (1),
useCatalog split (2), per-widget error boundaries (3),
wired-tools shared-state Zustand slice (4), the two open
logic bugs (5), wider Vitest coverage (6).
* "skipped intentionally" subsection added for the god-hook
splits that need design work first (pet-package, word-quiz,
chat-input, chat-widget, avatar-info).
Verification
- yarn test: 77/77 still passing.
- grep claude/update-react-typescript-He2rs docs/ARCHITECTURE.md: 0
(no stale branch refs).
Now a fresh `claude` session in this repo can read CLAUDE.md, follow
the link to ARCHITECTURE.md, and start contributing without re-asking
the conventions.