From 14011a8246ea94aa54e7e17e40be8ff11c7fb274 Mon Sep 17 00:00:00 2001 From: loucass003 Date: Wed, 26 Mar 2025 21:11:59 +0100 Subject: [PATCH] Optimise config loading for early loading of sentry. remove loading state of config as not needed anymore. Update sentry to latest --- gui/package.json | 8 +- gui/src/AppLayout.tsx | 28 ++---- .../components/providers/ConfigContext.tsx | 27 ++++-- .../providers/StatusSystemContext.tsx | 2 + gui/src/hooks/app.ts | 2 + gui/src/hooks/config.ts | 65 +++++++------- gui/src/utils/sentry.ts | 3 + pnpm-lock.yaml | 86 +++++++++---------- 8 files changed, 110 insertions(+), 111 deletions(-) diff --git a/gui/package.json b/gui/package.json index d197ffc1c..7e7e6ce88 100644 --- a/gui/package.json +++ b/gui/package.json @@ -11,7 +11,7 @@ "@hookform/resolvers": "^3.6.0", "@react-three/drei": "^9.114.3", "@react-three/fiber": "^8.17.10", - "@sentry/react": "^8.44.0", + "@sentry/react": "^9.9.0", "@sentry/vite-plugin": "^2.22.7", "@tailwindcss/typography": "^0.5.15", "@tanstack/react-query": "^5.48.0", @@ -93,7 +93,7 @@ "spdx-satisfies": "^5.0.1", "tailwind-gradient-mask-image": "^1.2.0", "tailwindcss": "^3.4.13", - "vite": "^5.4.8", - "typescript-eslint": "^8.8.0" + "typescript-eslint": "^8.8.0", + "vite": "^5.4.8" } -} +} \ No newline at end of file diff --git a/gui/src/AppLayout.tsx b/gui/src/AppLayout.tsx index 950eda6f4..4ecaa0cf2 100644 --- a/gui/src/AppLayout.tsx +++ b/gui/src/AppLayout.tsx @@ -1,14 +1,12 @@ -import { useEffect, useLayoutEffect } from 'react'; +import { useLayoutEffect } from 'react'; import { useConfig } from './hooks/config'; -import { Outlet, useNavigate } from 'react-router-dom'; -import { getSentryOrCompute } from './utils/sentry'; +import { Outlet } from 'react-router-dom'; export function AppLayout() { - const { loading, config } = useConfig(); - const navigate = useNavigate(); + const { config } = useConfig(); useLayoutEffect(() => { - if (loading || !config) return; + if (!config) return; if (config.theme !== undefined) { document.documentElement.dataset.theme = config.theme; } @@ -26,23 +24,7 @@ export function AppLayout() { `${config.textSize}rem` ); } - }, [config, loading]); - - useLayoutEffect(() => { - if (config && !config.doneOnboarding) { - navigate('/onboarding/home'); - } - }, [config?.doneOnboarding]); - - // const location = useLocation(); - // const navigationType = useNavigationType(); - // useEffect(() => { - // if (import.meta.env.PROD) return; - // console.log('The current URL is', { ...location }); - // console.log('The last navigation action was', navigationType); - // }, [location, navigationType]); - - if (loading) return <>; + }, [config]); return ( <> diff --git a/gui/src/components/providers/ConfigContext.tsx b/gui/src/components/providers/ConfigContext.tsx index 4fa8bac93..d0598f563 100644 --- a/gui/src/components/providers/ConfigContext.tsx +++ b/gui/src/components/providers/ConfigContext.tsx @@ -1,17 +1,30 @@ -import { ReactNode, useEffect, useContext } from 'react'; -import { ConfigContextC, useConfigProvider } from '@/hooks/config'; +import { ReactNode, useContext, useLayoutEffect } from 'react'; +import { ConfigContextC, loadConfig, useConfigProvider } from '@/hooks/config'; import { DEFAULT_LOCALE, LangContext } from '@/i18n/config'; +import { getSentryOrCompute } from '@/utils/sentry'; + +const config = await loadConfig(); +if (config?.errorTracking !== undefined) { + // load sentry ASAP to catch early errors + getSentryOrCompute(config.errorTracking ?? false); +} export function ConfigContextProvider({ children }: { children: ReactNode }) { - const context = useConfigProvider(); + const context = useConfigProvider(config); const { changeLocales } = useContext(LangContext); - useEffect(() => { - context.loadConfig().then((config) => { - changeLocales([config?.lang || DEFAULT_LOCALE]); - }); + useLayoutEffect(() => { + changeLocales([config?.lang || DEFAULT_LOCALE]); }, []); + useLayoutEffect(() => { + if (config?.errorTracking !== undefined) { + // Alows for sentry to refresh if user change the setting once the gui + // is initialized + getSentryOrCompute(config.errorTracking ?? false); + } + }, [config?.errorTracking]); + return ( {children} diff --git a/gui/src/components/providers/StatusSystemContext.tsx b/gui/src/components/providers/StatusSystemContext.tsx index f04bf420b..4beca6ac1 100644 --- a/gui/src/components/providers/StatusSystemContext.tsx +++ b/gui/src/components/providers/StatusSystemContext.tsx @@ -4,6 +4,8 @@ import { StatusSystemC, useProvideStatusContext } from '@/hooks/status-system'; export function StatusProvider({ children }: { children: ReactNode }) { const context = useProvideStatusContext(); + // throw new Error('BOOOOMMMMMM'); + return ( {children} ); diff --git a/gui/src/hooks/app.ts b/gui/src/hooks/app.ts index c36be6287..1ec89f1b6 100644 --- a/gui/src/hooks/app.ts +++ b/gui/src/hooks/app.ts @@ -4,6 +4,7 @@ import { Reducer, useContext, useEffect, + useLayoutEffect, useMemo, useReducer, useState, @@ -26,6 +27,7 @@ import { useDataFeedConfig } from './datafeed-config'; import { useWebsocketAPI } from './websocket-api'; import { error } from '@/utils/logging'; import { cacheWrap } from './cache'; +import { getSentryOrCompute } from '@/utils/sentry'; export interface FirmwareRelease { name: string; diff --git a/gui/src/hooks/config.ts b/gui/src/hooks/config.ts index 33619c46f..1d8ef116e 100644 --- a/gui/src/hooks/config.ts +++ b/gui/src/hooks/config.ts @@ -45,9 +45,7 @@ export interface Config { export interface ConfigContext { config: Config | null; - loading: boolean; setConfig: (config: Partial) => Promise; - loadConfig: () => Promise; saveConfig: () => Promise; } @@ -89,9 +87,37 @@ function fallbackToDefaults(loadedConfig: any): Config { return Object.assign({}, defaultConfig, loadedConfig); } -export function useConfigProvider(): ConfigContext { - const [currConfig, set] = useState(null); - const [loading, setLoading] = useState(false); +// Move the load of the config ouside of react +// allows to load everything before the first render +export const loadConfig = async () => { + try { + const migrated = await store.get('configMigratedToTauri'); + if (!migrated) { + const oldConfig = localStorage.getItem('config.json'); + + if (oldConfig) await store.set('config.json', oldConfig); + + store.set('configMigratedToTauri', 'true'); + } + + const json = await store.get('config.json'); + + if (!json) throw new Error('Config has ceased existing for some reason'); + + const loadedConfig = fallbackToDefaults(JSON.parse(json)); + // set(loadedConfig); + // setLoading(false); + return loadedConfig; + } catch (e) { + error(e); + // setConfig(defaultConfig); + // setLoading(false); + return null; + } +} + +export function useConfigProvider(initialConfig: Config | null): ConfigContext { + const [currConfig, set] = useState(initialConfig || defaultConfig as Config); const tauri = useIsTauri(); useDebouncedEffect( @@ -148,36 +174,7 @@ export function useConfigProvider(): ConfigContext { return { config: currConfig, - loading, setConfig, - loadConfig: async () => { - setLoading(true); - try { - const migrated = await store.get('configMigratedToTauri'); - if (!migrated) { - const oldConfig = localStorage.getItem('config.json'); - - if (oldConfig) await store.set('config.json', oldConfig); - - store.set('configMigratedToTauri', 'true'); - } - - const json = await store.get('config.json'); - - if (!json) throw new Error('Config has ceased existing for some reason'); - - const loadedConfig = fallbackToDefaults(JSON.parse(json)); - set(loadedConfig); - - setLoading(false); - return loadedConfig; - } catch (e) { - error(e); - setConfig(defaultConfig); - setLoading(false); - return null; - } - }, saveConfig: async () => { if (!tauri) return; await (store as Store).save(); diff --git a/gui/src/utils/sentry.ts b/gui/src/utils/sentry.ts index bb8437a85..2076b5def 100644 --- a/gui/src/utils/sentry.ts +++ b/gui/src/utils/sentry.ts @@ -9,6 +9,9 @@ import { } from 'react-router-dom'; export function getSentryOrCompute(enabled = false) { + // if sentry is already initialized - SKIP + if (enabled && Sentry.isInitialized()) return; + const client = Sentry.getClient(); if (client) { log(`${enabled ? 'Enabled' : 'Disabled'} error logging with Sentry.`); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a130adcf..803f51446 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,8 +39,8 @@ importers: specifier: ^8.17.10 version: 8.17.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.163.0) '@sentry/react': - specifier: ^8.44.0 - version: 8.47.0(react@18.3.1) + specifier: ^9.9.0 + version: 9.9.0(react@18.3.1) '@sentry/vite-plugin': specifier: ^2.22.7 version: 2.22.7 @@ -970,29 +970,29 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@sentry-internal/browser-utils@8.47.0': - resolution: {integrity: sha512-vOXzYzHTKkahTLDzWWIA4EiVCQ+Gk+7xGWUlNcR2ZiEPBqYZVb5MjsUozAcc7syrSUy6WicyFjcomZ3rlCVQhg==} - engines: {node: '>=14.18'} + '@sentry-internal/browser-utils@9.9.0': + resolution: {integrity: sha512-V/YhKLis98JFkqBGZaEBlDNFpJHJjoCvNb05raAYXdITfDIl37Kxqj0zX+IzyRhqnswkQ+DBTyoEoci09IR2bQ==} + engines: {node: '>=18'} - '@sentry-internal/feedback@8.47.0': - resolution: {integrity: sha512-IAiIemTQIalxAOYhUENs9bZ8pMNgJnX3uQSuY7v0gknEqClOGpGkG04X/cxCmtJUj1acZ9ShTGDxoh55a+ggAQ==} - engines: {node: '>=14.18'} + '@sentry-internal/feedback@9.9.0': + resolution: {integrity: sha512-hrxuOLm0Xsnx75hTNt3eLgNNjER3egrHZShdRzlMiakfKpA9f2X10z75vlZmT5ZUygDQnp9UVUnu28cDuVb9Zw==} + engines: {node: '>=18'} - '@sentry-internal/replay-canvas@8.47.0': - resolution: {integrity: sha512-M4W9UGouEeELbGbP3QsXLDVtGiQSZoWJlKwqMWyqdQgZuLoKw0S33+60t6teLVMhuQZR0UI9VJTF5coiXysnnA==} - engines: {node: '>=14.18'} + '@sentry-internal/replay-canvas@9.9.0': + resolution: {integrity: sha512-YK0ixGjquahGpNsQskCEVwycdHlwNBLCx9XJr1BmGnlOw6fUCmpyVetaGg/ZyhkzKGNXAGoTa4s7FUFnAG4bKg==} + engines: {node: '>=18'} - '@sentry-internal/replay@8.47.0': - resolution: {integrity: sha512-G/S40ZBORj0HSMLw/uVC6YDEPN/dqVk901vf4VYfml686DEhJrZesfAfp5SydJumQ0NKZQrdtvny+BWnlI5H1w==} - engines: {node: '>=14.18'} + '@sentry-internal/replay@9.9.0': + resolution: {integrity: sha512-EWczKMu3qiZ0SUUWU3zkGod+AWD/VQCLiQw+tw+PEpdHbRZIdYKsEptengZCFKthrwe2QmYpVCTSRxGvujJ/6g==} + engines: {node: '>=18'} '@sentry/babel-plugin-component-annotate@2.22.7': resolution: {integrity: sha512-aa7XKgZMVl6l04NY+3X7BP7yvQ/s8scn8KzQfTLrGRarziTlMGrsCOBQtCNWXOPEbtxAIHpZ9dsrAn5EJSivOQ==} engines: {node: '>= 14'} - '@sentry/browser@8.47.0': - resolution: {integrity: sha512-K6BzHisykmbFy/wORtGyfsAlw7ShevLALzu3ReZZZ18dVubO1bjSNjkZQU9MJD5Jcb9oLwkq89n3N9XIBfvdRA==} - engines: {node: '>=14.18'} + '@sentry/browser@9.9.0': + resolution: {integrity: sha512-pIMdkOC+iggZefBs6ck5fL1mBhbLzjdw/8K99iqSeDh+lLvmlHVZajAhPlmw50xfH8CyQ1s22dhcL+zXbg3NKw==} + engines: {node: '>=18'} '@sentry/bundler-plugin-core@2.22.7': resolution: {integrity: sha512-ouQh5sqcB8vsJ8yTTe0rf+iaUkwmeUlGNFi35IkCFUQlWJ22qS6OfvNjOqFI19e6eGUXks0c/2ieFC4+9wJ+1g==} @@ -1044,13 +1044,13 @@ packages: engines: {node: '>= 10'} hasBin: true - '@sentry/core@8.47.0': - resolution: {integrity: sha512-iSEJZMe3DOcqBFZQAqgA3NB2lCWBc4Gv5x/SCri/TVg96wAlss4VrUunSI2Mp0J4jJ5nJcJ2ChqHSBAU48k3FA==} - engines: {node: '>=14.18'} + '@sentry/core@9.9.0': + resolution: {integrity: sha512-GxKvx8PSgoWhLLS+/WBGIXy7rsFcnJBPDqFXIfcAGy89k2j06d9IP0kiIc63qBGStSUkh5FFJLPTakZ5RXiFXA==} + engines: {node: '>=18'} - '@sentry/react@8.47.0': - resolution: {integrity: sha512-SRk2Up+qBTow4rQGiRXViC2i4M5w/tae5w8I/rmX+IxFoPyh8wXERcLAj/8xbbRm8aR+A4i5gNgfFtrYsyFJFA==} - engines: {node: '>=14.18'} + '@sentry/react@9.9.0': + resolution: {integrity: sha512-7BE2Lx5CNtHtlNSS7Z9HxKquohC0xhdFceO3NlMXlx+dZuVCMoQmLISB8SQEcHw+2VO24MvtP3LPEzdeNbkIfg==} + engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x @@ -5189,33 +5189,33 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@sentry-internal/browser-utils@8.47.0': + '@sentry-internal/browser-utils@9.9.0': dependencies: - '@sentry/core': 8.47.0 + '@sentry/core': 9.9.0 - '@sentry-internal/feedback@8.47.0': + '@sentry-internal/feedback@9.9.0': dependencies: - '@sentry/core': 8.47.0 + '@sentry/core': 9.9.0 - '@sentry-internal/replay-canvas@8.47.0': + '@sentry-internal/replay-canvas@9.9.0': dependencies: - '@sentry-internal/replay': 8.47.0 - '@sentry/core': 8.47.0 + '@sentry-internal/replay': 9.9.0 + '@sentry/core': 9.9.0 - '@sentry-internal/replay@8.47.0': + '@sentry-internal/replay@9.9.0': dependencies: - '@sentry-internal/browser-utils': 8.47.0 - '@sentry/core': 8.47.0 + '@sentry-internal/browser-utils': 9.9.0 + '@sentry/core': 9.9.0 '@sentry/babel-plugin-component-annotate@2.22.7': {} - '@sentry/browser@8.47.0': + '@sentry/browser@9.9.0': dependencies: - '@sentry-internal/browser-utils': 8.47.0 - '@sentry-internal/feedback': 8.47.0 - '@sentry-internal/replay': 8.47.0 - '@sentry-internal/replay-canvas': 8.47.0 - '@sentry/core': 8.47.0 + '@sentry-internal/browser-utils': 9.9.0 + '@sentry-internal/feedback': 9.9.0 + '@sentry-internal/replay': 9.9.0 + '@sentry-internal/replay-canvas': 9.9.0 + '@sentry/core': 9.9.0 '@sentry/bundler-plugin-core@2.22.7': dependencies: @@ -5271,12 +5271,12 @@ snapshots: - encoding - supports-color - '@sentry/core@8.47.0': {} + '@sentry/core@9.9.0': {} - '@sentry/react@8.47.0(react@18.3.1)': + '@sentry/react@9.9.0(react@18.3.1)': dependencies: - '@sentry/browser': 8.47.0 - '@sentry/core': 8.47.0 + '@sentry/browser': 9.9.0 + '@sentry/core': 9.9.0 hoist-non-react-statics: 3.3.2 react: 18.3.1