From 67ffaa7effb12ae14b50cae5a77a0bbb6ceea3df Mon Sep 17 00:00:00 2001 From: simosmik Date: Thu, 30 Apr 2026 08:17:48 +0000 Subject: [PATCH] refactor(palette-ops): flatten Handle wrapper into ref-based registry --- src/contexts/PaletteOpsContext.tsx | 81 ++++++++++++------------------ 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/src/contexts/PaletteOpsContext.tsx b/src/contexts/PaletteOpsContext.tsx index c26f6a0c..0d50fbc8 100644 --- a/src/contexts/PaletteOpsContext.tsx +++ b/src/contexts/PaletteOpsContext.tsx @@ -1,4 +1,4 @@ -import { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react'; +import { createContext, useContext, useEffect, useMemo, useRef } from 'react'; import type { ReactNode } from 'react'; export type PaletteOps = { @@ -7,64 +7,47 @@ export type PaletteOps = { refreshProjects: () => Promise | void; }; -type Handle = { - handlersRef: React.MutableRefObject>; - call: PaletteOps; +type Registry = React.MutableRefObject>; + +const PaletteOpsContext = createContext(null); + +const defaultOps: PaletteOps = { + openFile: () => undefined, + openSettings: () => undefined, + refreshProjects: () => undefined, }; -const PaletteOpsContext = createContext(null); - -const noop = () => undefined; - export function PaletteOpsProvider({ children }: { children: ReactNode }) { - const handlersRef = useRef>({}); - - const call = useMemo( - () => ({ - openFile: (path) => handlersRef.current.openFile?.(path), - openSettings: (tab) => handlersRef.current.openSettings?.(tab), - refreshProjects: () => handlersRef.current.refreshProjects?.() ?? undefined, - }), - [], - ); - - const value = useMemo(() => ({ handlersRef, call }), [call]); - - return {children}; + const ref = useRef>({}); + return {children}; } export function usePaletteOps(): PaletteOps { - const handle = useContext(PaletteOpsContext); - if (!handle) { - return { openFile: noop, openSettings: noop, refreshProjects: noop }; - } - return handle.call; + const ref = useContext(PaletteOpsContext); + return useMemo( + () => ({ + openFile: (path) => (ref?.current.openFile ?? defaultOps.openFile)(path), + openSettings: (tab) => (ref?.current.openSettings ?? defaultOps.openSettings)(tab), + refreshProjects: () => (ref?.current.refreshProjects ?? defaultOps.refreshProjects)(), + }), + [ref], + ); } export function usePaletteOpsRegister(partial: Partial) { - const handle = useContext(PaletteOpsContext); - const openFile = partial.openFile; - const openSettings = partial.openSettings; - const refreshProjects = partial.refreshProjects; + const ref = useContext(PaletteOpsContext); + const { openFile, openSettings, refreshProjects } = partial; - const installer = useCallback(() => { - if (!handle) return undefined; - const prev = { ...handle.handlersRef.current }; - if (openFile) handle.handlersRef.current.openFile = openFile; - if (openSettings) handle.handlersRef.current.openSettings = openSettings; - if (refreshProjects) handle.handlersRef.current.refreshProjects = refreshProjects; + useEffect(() => { + if (!ref) return undefined; + const prev = { ...ref.current }; + if (openFile) ref.current.openFile = openFile; + if (openSettings) ref.current.openSettings = openSettings; + if (refreshProjects) ref.current.refreshProjects = refreshProjects; return () => { - if (openFile && handle.handlersRef.current.openFile === openFile) { - handle.handlersRef.current.openFile = prev.openFile; - } - if (openSettings && handle.handlersRef.current.openSettings === openSettings) { - handle.handlersRef.current.openSettings = prev.openSettings; - } - if (refreshProjects && handle.handlersRef.current.refreshProjects === refreshProjects) { - handle.handlersRef.current.refreshProjects = prev.refreshProjects; - } + if (openFile && ref.current.openFile === openFile) ref.current.openFile = prev.openFile; + if (openSettings && ref.current.openSettings === openSettings) ref.current.openSettings = prev.openSettings; + if (refreshProjects && ref.current.refreshProjects === refreshProjects) ref.current.refreshProjects = prev.refreshProjects; }; - }, [handle, openFile, openSettings, refreshProjects]); - - useEffect(() => installer(), [installer]); + }, [ref, openFile, openSettings, refreshProjects]); }