This commit is contained in:
Mackie 2026-06-08 08:19:46 +08:00
parent 6469bb561a
commit 3affa30fa6
2 changed files with 43 additions and 12 deletions

View file

@ -1,23 +1,38 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
// Define the shape of your data
interface MarketUpdate {
symbol: string;
price: string;
id: string;
timestamp: number;
}
export const useDashboardData = () => { export const useDashboardData = () => {
const [data, setData] = useState<any[]>([]); // Store the latest price for each symbol in an object
const [latestPrices, setLatestPrices] = useState<Record<string, MarketUpdate>>({});
useEffect(() => { useEffect(() => {
// Instantiate the worker
const worker = new Worker(new URL('../worker/data.worker.ts', import.meta.url), { const worker = new Worker(new URL('../worker/data.worker.ts', import.meta.url), {
type: 'module', type: 'module',
}); });
worker.onmessage = (event) => { worker.onmessage = (event) => {
if (event.data.type === 'BATCH_UPDATE') { if (event.data.type === 'BATCH_UPDATE') {
// Keep only the latest 1000 items to prevent memory bloat setLatestPrices((prev) => {
setData((prev) => [...event.data.payload, ...prev].slice(0, 1000)); const newState = { ...prev };
// Loop through the batch and update only the specific symbol
event.data.payload.forEach((update: MarketUpdate) => {
newState[update.symbol] = update;
});
return newState;
});
} }
}; };
return () => worker.terminate(); return () => worker.terminate();
}, []); }, []);
return data; // Return the values as an array so you can easily map over them in your UI
return Object.values(latestPrices);
}; };

View file

@ -1,12 +1,28 @@
// src/worker/data.worker.ts // src/worker/data.worker.ts
const generateUpdate = () => ({
id: Math.random().toString(36).substring(7),
symbol: "BTC/USD",
price: (Math.random() * 50000).toFixed(2),
timestamp: Date.now(),
});
// Stream updates every 16ms (target ~60fps) const symbols = [
"BTC/USD",
"ETH/USD",
"SOL/USD",
"ADA/USD",
"DOT/USD",
"LINK/USD",
"XRP/USD",
"AVAX/USD"
];
const generateUpdate = () => {
// Randomly pick a symbol from the list
const symbol = symbols[Math.floor(Math.random() * symbols.length)];
return {
id: Math.random().toString(36).substring(7),
symbol: symbol,
price: (Math.random() * 50000).toFixed(2),
timestamp: Date.now(),
};
};
setInterval(() => { setInterval(() => {
const updates = Array.from({ length: 5 }, generateUpdate); const updates = Array.from({ length: 5 }, generateUpdate);
self.postMessage({ type: 'BATCH_UPDATE', payload: updates }); self.postMessage({ type: 'BATCH_UPDATE', payload: updates });