Bjornpool commited on
Commit
2d73424
·
1 Parent(s): 4c2f88b

fix: cache wykresów — eliminacja race condition z dynamic import

Browse files
frontend/app/dashboard/components/ChartsSection.tsx CHANGED
@@ -16,6 +16,7 @@ import EmotionalPieChart from "../../../components/EmotionalPieChart";
16
  import FakeNewsBarChart from "../../../components/FakeNewsBarChart";
17
  import ProgressBar from "../../../components/ProgressBar";
18
  import { useDashboardCharts } from "../../hooks/useDashboardCharts";
 
19
  import locales from "../../../lib/locales";
20
  import MiniSpinner from "./MiniSpinner";
21
  import ArticlesModal from "./ArticlesModal";
@@ -94,11 +95,10 @@ export default function ChartsSection({
94
 
95
  useEffect(() => {
96
  setIsClient(true);
97
-
98
- import("../../../app/stores/newsCache").then(({ useNewsCache }) => {
99
- const cache = useNewsCache.getState();
100
- setCachedCharts(cache.get<ChartsCache>(CHARTS_CACHE_KEY));
101
- });
102
  }, []);
103
 
104
  useEffect(() => {
@@ -189,20 +189,17 @@ export default function ChartsSection({
189
 
190
  if (!barData?.length && !emotionData?.length) return;
191
 
192
- import("../../../app/stores/newsCache").then(({ useNewsCache }) => {
193
- const cache = useNewsCache.getState();
194
-
195
- const currentCache = cache.get<ChartsCache>(CHARTS_CACHE_KEY);
196
- const areDataEqual =
197
- JSON.stringify(currentCache?.barData) === JSON.stringify(barData) &&
198
- JSON.stringify(currentCache?.emotionData) === JSON.stringify(emotionData);
199
 
200
- if (areDataEqual) return;
201
 
202
- const payload: ChartsCache = { barData, emotionData, totalSources };
203
- cache.set(CHARTS_CACHE_KEY, payload);
204
- setCachedCharts(payload);
205
- });
206
  }, [
207
  isClient,
208
  chartsStarted,
 
16
  import FakeNewsBarChart from "../../../components/FakeNewsBarChart";
17
  import ProgressBar from "../../../components/ProgressBar";
18
  import { useDashboardCharts } from "../../hooks/useDashboardCharts";
19
+ import { useNewsCache } from "../../stores/newsCache";
20
  import locales from "../../../lib/locales";
21
  import MiniSpinner from "./MiniSpinner";
22
  import ArticlesModal from "./ArticlesModal";
 
95
 
96
  useEffect(() => {
97
  setIsClient(true);
98
+ // Synchroniczny odczyt — brak dynamic import eliminuje race condition
99
+ // z hasLoadedRef, który blokował użycie cache na kolejnych wejściach
100
+ const cached = useNewsCache.getState().get<ChartsCache>(CHARTS_CACHE_KEY);
101
+ setCachedCharts(cached);
 
102
  }, []);
103
 
104
  useEffect(() => {
 
189
 
190
  if (!barData?.length && !emotionData?.length) return;
191
 
192
+ const cache = useNewsCache.getState();
193
+ const currentCache = cache.get<ChartsCache>(CHARTS_CACHE_KEY);
194
+ const areDataEqual =
195
+ JSON.stringify(currentCache?.barData) === JSON.stringify(barData) &&
196
+ JSON.stringify(currentCache?.emotionData) === JSON.stringify(emotionData);
 
 
197
 
198
+ if (areDataEqual) return;
199
 
200
+ const payload: ChartsCache = { barData, emotionData, totalSources };
201
+ cache.set(CHARTS_CACHE_KEY, payload);
202
+ setCachedCharts(payload);
 
203
  }, [
204
  isClient,
205
  chartsStarted,
frontend/app/hooks/useDashboardCharts.ts CHANGED
@@ -159,6 +159,9 @@ if (barsMap.size === 0) return; // nic w cache — nie nadpisuj pustą tablicą
159
 
160
  const workers = Array.from({ length: CONCURRENCY }, () => fetchWorker());
161
  await Promise.allSettled(workers);
 
 
 
162
  setChartsLoading(false);
163
 
164
  console.log("[CHARTS] gotowe. barData końcowy:", barData.map(b => b.label));
 
159
 
160
  const workers = Array.from({ length: CONCURRENCY }, () => fetchWorker());
161
  await Promise.allSettled(workers);
162
+
163
+ // Wymuś przeliczenie po zakończeniu — CACHE HIT nie wyzwala subskrypcji Zustand
164
+ recomputeFromCache();
165
  setChartsLoading(false);
166
 
167
  console.log("[CHARTS] gotowe. barData końcowy:", barData.map(b => b.label));