From e44bea11c12615902e3394b0c7f47eea089a527d Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Fri, 26 Dec 2025 23:29:08 +0100 Subject: [PATCH] fix: Remove module-level side effect from useMachineStore initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Problem:** Store initialization was happening at module load via side effect: ```typescript useMachineStore.getState()._setupSubscriptions(); ``` This caused several issues: - Executed before app was ready - Made testing difficult (runs before test setup) - Hard to control initialization timing - Could cause issues in different environments **Solution:** - Added public `initialize()` method to useMachineStore - Call initialization from App component's useEffect (proper lifecycle) - Removed module-level side effect **Benefits:** - ✅ Controlled initialization timing - ✅ Better testability (no side effects on import) - ✅ Follows React lifecycle patterns - ✅ No behavioral changes for end users **Testing:** - Build tested successfully - Linter passed - All TypeScript types validated Fixes #38 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/App.tsx | 6 ++++++ src/stores/useMachineStore.ts | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c75e626..e2ed838 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ import { useEffect } from "react"; import { useShallow } from "zustand/react/shallow"; +import { useMachineStore } from "./stores/useMachineStore"; import { useMachineCacheStore } from "./stores/useMachineCacheStore"; import { usePatternStore } from "./stores/usePatternStore"; import { useUIStore } from "./stores/useUIStore"; @@ -23,6 +24,11 @@ function App() { document.title = `Respira v${__APP_VERSION__}`; }, []); + // Initialize machine store subscriptions (once on mount) + useEffect(() => { + useMachineStore.getState().initialize(); + }, []); + // Machine cache store - for auto-loading cached pattern const { resumedPattern, resumeFileName } = useMachineCacheStore( useShallow((state) => ({ diff --git a/src/stores/useMachineStore.ts b/src/stores/useMachineStore.ts index 0e47ce7..7ee6c57 100644 --- a/src/stores/useMachineStore.ts +++ b/src/stores/useMachineStore.ts @@ -57,6 +57,9 @@ interface MachineState { resumeSewing: () => Promise; deletePattern: () => Promise; + // Initialization + initialize: () => void; + // Internal methods _setupSubscriptions: () => void; _startPolling: () => void; @@ -309,6 +312,11 @@ export const useMachineStore = create((set, get) => ({ } }, + // Initialize the store (call once from App component) + initialize: () => { + get()._setupSubscriptions(); + }, + // Setup service subscriptions _setupSubscriptions: () => { const { service } = get(); @@ -421,9 +429,6 @@ export const useMachineStore = create((set, get) => ({ }, })); -// Initialize subscriptions when store is created -useMachineStore.getState()._setupSubscriptions(); - // Selector hooks for common use cases export const useIsConnected = () => useMachineStore((state) => state.isConnected);