Error boundary for chart, marketplace SWR cache, and page-load perf logging - #717
Merged
Chucks1093 merged 3 commits intoJul 28, 2026
Conversation
…layerorg#690) Extends SectionErrorBoundary with optional title/description props (backward compatible, defaulting to prior copy) so the bonding curve sparkline in CreatorCard can fail independently without taking down the whole card or profile page. Retry is manual only (no auto-retry loop).
…esslayerorg#691) Sets a 60s staleTime on useInfiniteCreatorMarketplace so cached pages render instantly on remount while React Query silently refetches in the background. Adds isRefreshing (true only during a background refetch, never during the initial load or next-page fetch) and wires a "Refreshing..." indicator into CreatorMarketplaceInfiniteList. Buy/sell trades now also invalidate queryKeys.creators.all in useTradeMutation's onSettled so the marketplace list never has to wait out the staleTime after a completed trade.
…cesslayerorg#693) Reworks useNavigationTiming to accept a page_name and read performance.getEntriesByType('navigation')[0] after the page becomes interactive, logging { page_name, ttfb, dcl, load_complete } via console.info('[page-load-perf]', ...). Gated to import.meta.env.PROD so it never fires in dev/test, debounced via a ref guard to exactly one log per mount, and read asynchronously (after 'load') so it never blocks rendering. Moves the call site from App.tsx (global, every route) to HomePage (marketplace) and CreatorDetailPage (creator profile) specifically, per the issue's scope. The previous global hook lacked a production gate and used different field names, so it didn't satisfy the ask.
|
@davedumto Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
5 tasks
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.
Summary
Three independent, related improvements to the marketplace/creator-profile experience: a scoped error boundary around the bonding curve chart, stale-while-revalidate caching for the marketplace list, and Navigation Timing API perf logging on the two key pages.
closes #690
closes #691
closes #693
Changes
Add error boundary around the bonding curve chart to prevent a chart crash from breaking the whole profile page #690 — Error boundary around the bonding curve chart:
SectionErrorBoundarygained two new optional, backward-compatible props (title,description) so its fallback copy can be overridden per-section (all existing callers —LandingPage.tsx's creator list/AppErrorBoundary— are unaffected since neither prop is passed there). The bonding-curve sparkline block inCreatorCard.tsxis now wrapped in<SectionErrorBoundary title="Chart unavailable — try refreshing" description="" ...>, so a chart-render crash no longer takes down the whole card. Retry is manual only (clicking "Retry" resets the boundary) — there is no auto-retry loop. The caught error is logged via the boundary's existingcomponentDidCatch→console.error.Add stale-while-revalidate cache behaviour to the marketplace key list query #691 — Stale-while-revalidate cache for the marketplace list:
useInfiniteCreatorMarketplacenow setsstaleTime: 60_000on itsuseInfiniteQuery, so a cached page renders instantly (no spinner) on remount within 60s while React Query silently refetches in the background once stale. The hook exposes a newisRefreshingflag — true only while a background refetch is in flight after data has already been shown once, never during the initial load or a next-page fetch — whichCreatorMarketplaceInfiniteListuses to show a small "Refreshing…"role="status"indicator.useTradeMutation'sonSettlednow also invalidatesqueryKeys.creators.all(in addition to the existing wallet-holdings invalidation), so a completed buy/sell doesn't have to wait out the 60s staleTime before the marketplace reflects the trade.Add page load performance log using the Navigation Timing API on the marketplace and creator profile pages #693 — Page-load performance logging: Reworked the existing (but incomplete)
useNavigationTiminghook to accept apageName, readperformance.getEntriesByType('navigation')[0]after the page becomes interactive, and log{ page_name, ttfb, dcl, load_complete }viaconsole.info('[page-load-perf]', ...). Logging is gated toimport.meta.env.PROD(never fires in dev/test), debounced via a ref guard to exactly one log per mount, and happens asynchronously after theloadevent so it never blocks rendering. The hook's call site moved fromApp.tsx(fired globally on every route with no production gate or exact field names) toHomePage(page_name: 'marketplace') andCreatorDetailPage(page_name: 'creator_profile') specifically, matching the issue's scope.Test plan
SectionErrorBoundary.test.tsx: 9 tests (4 pre-existing + 5 new) covering custom title/description, description omission, manual-only retry, and thecomponentDidCatchlog — all passing.useInfiniteCreatorMarketplace.test.ts: 7 tests (4 pre-existing + 3 new) covering instant cache-hit on remount,isRefreshingtoggling correctly around a background refetch, andisRefreshingstaying false during initial/next-page loads — all passing.CreatorMarketplaceInfiniteList.test.tsx: 9 tests (6 pre-existing + 3 new) covering the "Refreshing…" indicator's visibility and that cached creators keep rendering (no skeleton regression) during a background refresh — all passing.tradeCacheInvalidation.test.ts: 3 tests (2 pre-existing + 1 new) covering thatqueryKeys.creators.allis invalidated on trade settlement — all passing.useNavigationTiming.test.ts(new file): 5 tests covering the PROD gate, exact log shape, theload-event fallback path, single-log-per-mount debouncing, and the no-entry-available case — all passing.npx tsc -b(project build/typecheck) andnpx eslinton all touched files are clean.vitestsuite: all failures present (TransactionHistory.*,WalletActivityFeed.infiniteScroll.integration.test.tsx) are pre-existing and unrelated — confirmed by reproducing the samelocalStorage.clear is not a functionfailure with these commits fully reverted (stash test). No regressions introduced by this PR.LandingPage.tsx(which also renders creator cards/bonding-curve charts and already consumesSectionErrorBoundaryelsewhere) isn't currently wired intoroutes.tsxand appears to be a separate, not-yet-routed page — #690's fix was applied at theCreatorCardcomponent level instead, so it covers every place the chart is actually rendered today, including whereverLandingPageeventually gets wired up.