feat: query devtools, error boundary, real-time P&L polling, and funding countdown#100
Merged
Merged
Conversation
Issue SO4-Markets#63 — TanStack Query DevTools in dev mode - Add @tanstack/react-query-devtools to devDependencies - Render <ReactQueryDevtools initialIsOpen={false} /> inside QueryProvider guarded by import.meta.env.DEV; excluded from production bundle Issue SO4-Markets#64 — Global error boundary + query error fallback UI - QueryProvider: add QueryCache onError handler that logs to console in dev and fires a Sonner toast via parseSorobanError(); auth errors (401/403/unauthorized) are silently skipped - New ErrorPage component (app/error-page.tsx) with a "Reload" button - ErrorBoundary class component wraps AppProviders; renders ErrorPage on unhandled render errors, resets state on button click Issue SO4-Markets#65 — Real-time P&L polling for open positions - usePositions: refetchInterval 15 000 → 5 000 ms for near-real-time P&L / liquidation price updates - Add refetchIntervalInBackground: false so network requests pause when the browser tab is backgrounded; wallet disconnect already stops polling via enabled: !!account Issue SO4-Markets#66 — Live funding countdown timer in PositionsList - New useFundingRate hook returns nextEpochTs (next 8-hour epoch) and ratePerHour; adds fundingRate query key to the central key factory - useFundingCountdown (inside PositionsList) drives a setInterval tick every second and formats the remaining time as "Xh Xm" - PositionsList: new "Next Funding" column shows the shared countdown for all open-position rows Closes SO4-Markets#63 Closes SO4-Markets#64 Closes SO4-Markets#65 Closes SO4-Markets#66
|
@ijeoma270 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! 🚀 |
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.
Fixes #63
Fixes #64
Fixes #65
Fixes #66
What changed
#63 — TanStack Query DevTools in dev mode
@tanstack/react-query-devtoolstodevDependenciesinapps/web/package.jsonQueryProviderconditionally renders<ReactQueryDevtools initialIsOpen={false} />behindimport.meta.env.DEV; Vite tree-shakes it from production bundles entirely#64 — Global error boundary + query error fallback UI
QueryProvidernow creates aQueryCachewith anonErrorcallback: logs toconsole.errorin dev, fires a red Sonner toast withparseSorobanError()message for user-visible failures; auth-related errors (401/403/unauthorized/unauthenticated) are silently skippedErrorPagecomponent (app/error-page.tsx) — renders a centred "Something went wrong" message with a Reload buttonErrorBoundaryclass component added toAppProviders— wraps the whole tree, callsgetDerivedStateFromError/componentDidCatch, renders<ErrorPage onReset={...} />on failure and resets state when the user clicks Reload#65 — Real-time P&L polling for open positions
usePositions:refetchIntervallowered from15 000→5 000ms so P&L, liquidation price, and funding debt update roughly every 5 srefetchIntervalInBackground: false— network requests pause automatically when the tab is hidden; disconnecting the wallet already stops polling viaenabled: !!account#66 — Live funding countdown timer in PositionsList
useFundingRatehook (hooks/useFundingRate.ts) returns{ ratePerHour, nextEpochTs }computed from the standard 8-hour funding epoch schedule; refreshes every 60 sfundingRatekey to the centralqueryKeysfactoryuseFundingCountdown(private hook insidePositionsList) runs asetIntervalevery second, diffsDate.now()againstnextEpochTs, and formats remaining time as"Xh Xm"or"Xm"; the interval is cleaned up via theuseEffectreturnPositionsListgains a Next Funding column visible on all open-position rowsHow to test
#63 — run
bun dev, open the app, a floating ⚛ button appears in the bottom-right corner in dev mode.#64 — throw inside any child component (
throw new Error("test")); the app renders the reload page. For query errors, mock a failing query; a red toast appears within seconds.#65 — open the Trade page with a connected wallet and watch the P&L column refresh roughly every 5 s. Switch to another browser tab and confirm no network requests fire (DevTools → Network).
#66 — open the Trade page with positions loaded; the Next Funding column counts down in real-time (updates every second). Verify it resets after each 8-hour epoch.