mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
3459400ed7831dcb9524c19a48fb357a25059e7e
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a029ee63cb |
fix(catalog,ci): catch hook-order violations + add CI gate
Two follow-ups to the CatalogPurchaseWidgetView fix (
|
||
|
|
d28819db89 |
fix(snapshots): re-apply the 3 snapshot-consumer migrations with the use-between/useSyncExternalStore incompatibility resolved
Root cause of last session's "(intermediate value)() is undefined" at ToolbarView.tsx:46: use-between 1.x ships its own React-dispatcher proxy (ownDispatcher in node_modules/use-between/release/index.esm.js:54-169) that re-implements only useState, useReducer, useEffect, useLayoutEffect, useCallback, useMemo, useRef and useImperativeHandle. It does NOT implement useSyncExternalStore. When the inner state function of useBetween(stateFn) calls useSyncExternalStore (directly or via useExternalSnapshot / useUserDataSnapshot), React resolves the dispatcher to use-between's proxy, finds .useSyncExternalStore missing, and calls undefined() — that's the exact production crash in Firefox. Chrome reports the same as "dispatcher.useSyncExternalStore is not a function". Neither the vite alias ( |
||
|
|
e142efd793 |
revert(hooks): roll back the three snapshot-consumer migrations to pre-71a0eee state
The migrations of useSessionInfo, useChatWidget.ownUserId and the
AvatarInfo Ignore/Unignore menu to the new useSessionSnapshots hooks
were correct in code but produce a persistent runtime error in the
user's deployment:
TypeError: (intermediate value)() is undefined
ToolbarView ToolbarView.tsx:46
The error fires from React's render loop on the first paint —
ToolbarView is the first mounted consumer of useSessionInfo, which is
why it carries the boundary message. Two attempted fixes did not
resolve it on the user's side:
-
|
||
|
|
c35a2d4b4f |
fix(useSessionSnapshots): defensive guards against missing renderer methods
The snapshot hooks were chained against renderer Manager methods (getUserDataSnapshot, getIgnoredUsersSnapshot, subscribe, …) under the assumption that the resolved \`@nitrots/nitro-renderer\` bundle always includes the v2.1.0+ snapshot API. That assumption fails in two real scenarios: 1. A stale \`dist/index.js\` shadows the source umbrella at resolution time (the vite alias commit |
||
|
|
71a0eee195 |
refactor(hooks/session): migrate useSessionInfo to useUserDataSnapshot
Replace the local useState mirror of userFigure / userRespectRemaining /
petRespectRemaining (driven by useMessageEvent<UserInfoEvent> +
useMessageEvent<FigureUpdateEvent> + manual setUser after giveRespect)
with a single useUserDataSnapshot() read.
Why this works: SessionDataManager already invalidates its snapshot
on every state change that mattered to the old hook — UserInfoEvent
handler (line 142), FigureUpdateEvent listener (line 117),
giveRespect / givePetRespect (lines 540/551). The snapshot's
respectsLeft / respectsPetLeft map directly to the parser fields
respectsRemaining / respectsPetRemaining the old code mirrored.
Net result: 3 useState declarations + 2 useMessageEvent subscriptions
removed; respectUser / respectPet become trivial pass-throughs (no
post-call setState because the manager's invalidate dispatches the
event for us). UserSettingsEvent stays on useMessageEvent —
chatStyleId is not in the snapshot.
Also drops the deprecated `userInfo: UserInfoDataParser` field from
the return shape — no in-tree consumer reads it (verified via grep
across src/), it was carried as legacy clutter.
Consumers unchanged: ToolbarView, HcCenterView, ChatInputView,
AvatarInfoPetTrainingPanelView, InfoStandWidgetPetView, AvatarInfoWidget
{Avatar,Pet,OwnPet}View. All destructure individual fields, not the
deprecated userInfo.
Verification: yarn typecheck clean, yarn test 203/203.
|
||
|
|
b2a86da912 |
feat(hooks/session): React-side consumer hooks for the renderer snapshot pattern
The renderer exposes six referentially-stable snapshot getters under the v2.1.0 React-friendly pattern (SessionData / RoomSession / IgnoredUsers / GroupBadges / RoomUserList / SoundVolumes), each invalidated by a dedicated NitroEventType.*_UPDATED dispatch. Until now nothing on the client consumed them — useExternalSnapshot existed as a useSyncExternalStore wrapper but no widget was wired up to a snapshot. Add thin consumer hooks under src/hooks/session/useSessionSnapshots.ts, each a useExternalSnapshot wrapper around the matching subscribe+getter pair: - useUserDataSnapshot() → Readonly<IUserDataSnapshot> - useActiveRoomSessionSnapshot() → Readonly<IRoomSessionSnapshot> | null - useIgnoredUsersSnapshot() → ReadonlyArray<string> - useIsUserIgnored(name) → boolean (useMemo over the array) - useGroupBadgesSnapshot() → ReadonlyMap<number, string> - useGroupBadge(groupId) → string (useMemo over the map) - useVolumesSnapshot() → Readonly<ISoundVolumesSnapshot> - useRoomUserListSnapshot() → ReadonlyArray<IRoomUserData> Two design details worth noting: - useRoomUserListSnapshot subscribes to BOTH ROOM_USER_LIST_UPDATED (for join/leave/update inside a session) AND ROOM_SESSION_UPDATED (because the underlying userDataManager reference flips when the active room session changes). A single module-level frozen EMPTY_USER_LIST is the fallback when no session is active, keeping reference stability across reads in the no-room state. - useIsUserIgnored / useGroupBadge memoize the scalar derivation so a re-render only happens when the underlying snapshot reference flips, not on unrelated useExternalSnapshot wake-ups. These hooks unlock per-component snapshot consumption — widgets that previously juggled addEventListener + useState pairs (or worse, read GetSessionDataManager().userId directly and never re-rendered) can now go through one of these and get reactivity for free. Migration of existing consumers (useSessionInfo, AvatarInfoUtilities, etc.) is the next pass. Verification: yarn typecheck clean, yarn test 203/203, yarn build green. |
||
|
|
7feb10ab15 | 🆙 Init V3 |