From f10b3b8d7d931457218719cb7a939b1250f15f59 Mon Sep 17 00:00:00 2001 From: Johan Persson Date: Fri, 27 Feb 2026 09:46:18 +0100 Subject: [PATCH] refactor(ui): simplify useBreakpoint singleton store Initialize listeners as an eager Set to eliminate the undefined union type and non-null assertions. Add comment explaining the change listener algorithm. Signed-off-by: Johan Persson --- packages/ui/src/hooks/useBreakpoint.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/ui/src/hooks/useBreakpoint.ts b/packages/ui/src/hooks/useBreakpoint.ts index b870033f8d..7364fb29d0 100644 --- a/packages/ui/src/hooks/useBreakpoint.ts +++ b/packages/ui/src/hooks/useBreakpoint.ts @@ -50,10 +50,11 @@ function computeBreakpoint(): Breakpoint { } // --- Singleton store --- -// Created lazily on first subscribe/getSnapshot call. +// `current` is initialized lazily on first client-side access. +// `listeners` is eagerly initialized since Set is safe to create on the server. let current: Breakpoint | undefined; -let listeners: Set<() => void> | undefined; +const listeners = new Set<() => void>(); let initialized = false; function ensureInitialized(): void { @@ -62,34 +63,35 @@ function ensureInitialized(): void { } initialized = true; current = computeBreakpoint(); - listeners = new Set(); + // Register one listener per breakpoint. When any query fires, re-evaluate + // all breakpoints to find the new active one. Notify subscribers only if + // the active breakpoint actually changed. for (const bp of breakpoints) { const mql = window.matchMedia(`(min-width: ${bp.value}px)`); - const onChange = () => { + mql.addEventListener('change', () => { const next = computeBreakpoint(); if (next !== current) { current = next; - for (const cb of listeners!) { + for (const cb of listeners) { cb(); } } - }; - mql.addEventListener('change', onChange); + }); } } function subscribe(callback: () => void): () => void { ensureInitialized(); - listeners!.add(callback); + listeners.add(callback); return () => { - listeners!.delete(callback); + listeners.delete(callback); }; } function getSnapshot(): Breakpoint { ensureInitialized(); - return current!; + return current ?? 'initial'; } function getServerSnapshot(): Breakpoint {