From a19dd53423428a2e57f6f75ab289bafdb35c0fd2 Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 17 Oct 2025 12:40:22 +0200 Subject: [PATCH] feat(debug): add live performance timing with digital stopwatch display --- src/components/Debug.tsx | 76 ++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/src/components/Debug.tsx b/src/components/Debug.tsx index 2615f3d9..913a991d 100644 --- a/src/components/Debug.tsx +++ b/src/components/Debug.tsx @@ -29,11 +29,26 @@ const Debug: React.FC = () => { const [bunkerUri, setBunkerUri] = useState('') const [isBunkerLoading, setIsBunkerLoading] = useState(false) const [bunkerError, setBunkerError] = useState(null) + + // Live timing state + const [liveTiming, setLiveTiming] = useState<{ + nip44?: { type: 'encrypt' | 'decrypt'; startTime: number } + nip04?: { type: 'encrypt' | 'decrypt'; startTime: number } + }>({}) useEffect(() => { return DebugBus.subscribe((e) => setLogs(prev => [...prev, e].slice(-300))) }, []) + // Live timer effect - triggers re-renders for live timing updates + useEffect(() => { + const interval = setInterval(() => { + // Force re-render to update live timing display + setLiveTiming(prev => prev) + }, 16) // ~60fps for smooth updates + return () => clearInterval(interval) + }, []) + const signer = useMemo(() => (activeAccount as unknown as { signer?: unknown })?.signer, [activeAccount]) const pubkey = (activeAccount as unknown as { pubkey?: string })?.pubkey @@ -45,15 +60,25 @@ const Debug: React.FC = () => { try { const api = (signer as { [key: string]: { encrypt: (pubkey: string, message: string) => Promise } })[mode] DebugBus.info('debug', `encrypt start ${mode}`, { pubkey, len: payload.length }) + + // Start live timing const start = performance.now() + setLiveTiming(prev => ({ ...prev, [mode]: { type: 'encrypt', startTime: start } })) + const cipher = await api.encrypt(pubkey, payload) const ms = Math.round(performance.now() - start) + + // Stop live timing + setLiveTiming(prev => ({ ...prev, [mode]: undefined })) + DebugBus.info('debug', `encrypt done ${mode}`, { len: typeof cipher === 'string' ? cipher.length : -1, ms }) if (mode === 'nip44') setCipher44(cipher) else setCipher04(cipher) if (mode === 'nip44') setTEncrypt44(ms) else setTEncrypt04(ms) } catch (e) { + // Stop live timing on error + setLiveTiming(prev => ({ ...prev, [mode]: undefined })) DebugBus.error('debug', `encrypt error ${mode}`, e instanceof Error ? e.message : String(e)) } } @@ -68,15 +93,25 @@ const Debug: React.FC = () => { return } DebugBus.info('debug', `decrypt start ${mode}`, { len: cipher.length }) + + // Start live timing const start = performance.now() + setLiveTiming(prev => ({ ...prev, [mode]: { type: 'decrypt', startTime: start } })) + const plain = await api.decrypt(pubkey, cipher) const ms = Math.round(performance.now() - start) + + // Stop live timing + setLiveTiming(prev => ({ ...prev, [mode]: undefined })) + DebugBus.info('debug', `decrypt done ${mode}`, { len: typeof plain === 'string' ? plain.length : -1, ms }) if (mode === 'nip44') setPlain44(String(plain)) else setPlain04(String(plain)) if (mode === 'nip44') setTDecrypt44(ms) else setTDecrypt04(ms) } catch (e) { + // Stop live timing on error + setLiveTiming(prev => ({ ...prev, [mode]: undefined })) DebugBus.error('debug', `decrypt error ${mode}`, e instanceof Error ? e.message : String(e)) } } @@ -141,12 +176,33 @@ const Debug: React.FC = () => { >{value || '—'} ) - const Stat = ({ label, value }: { label: string; value?: string | number | null }) => ( - - - {label}: {value ?? '—'} - - ) + const getLiveTiming = (mode: 'nip44' | 'nip04', type: 'encrypt' | 'decrypt') => { + const timing = liveTiming[mode] + if (timing && timing.type === type) { + const elapsed = Math.round(performance.now() - timing.startTime) + return `${elapsed}ms` + } + return null + } + + const Stat = ({ label, value, mode, type }: { + label: string; + value?: string | number | null; + mode?: 'nip44' | 'nip04'; + type?: 'encrypt' | 'decrypt'; + }) => { + const liveValue = mode && type ? getLiveTiming(mode, type) : null + const displayValue = liveValue || (value ?? '—') + const isLive = !!liveValue + + return ( + + + {label}: {displayValue} + {isLive && ⏱️} + + ) + } return (
@@ -248,15 +304,15 @@ const Debug: React.FC = () => {
- - + +
- - + +