Skip to content

Commit 49a5293

Browse files
committed
chore(stores): remove Zustand environment store and dead init scaffolding (#3929)
1 parent 38e80fc commit 49a5293

File tree

15 files changed

+73
-671
lines changed

15 files changed

+73
-671
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-selector-setup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { useParams } from 'next/navigation'
55
import { SELECTOR_CONTEXT_FIELDS } from '@/lib/workflows/subblocks/context'
66
import type { SubBlockConfig } from '@/blocks/types'
77
import { extractEnvVarName, isEnvVarReference, isReference } from '@/executor/constants'
8+
import { usePersonalEnvironment } from '@/hooks/queries/environment'
89
import type { SelectorContext, SelectorKey } from '@/hooks/selectors/types'
9-
import { useEnvironmentStore } from '@/stores/settings/environment'
1010
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
1111
import { useDependsOnGate } from './use-depends-on-gate'
1212
import { useSubBlockValue } from './use-sub-block-value'
@@ -32,7 +32,7 @@ export function useSelectorSetup(
3232
const activeWorkflowId = useWorkflowRegistry((s) => s.activeWorkflowId)
3333
const workflowId = (params?.workflowId as string) || activeWorkflowId || ''
3434

35-
const envVariables = useEnvironmentStore((s) => s.variables)
35+
const { data: envVariables = {} } = usePersonalEnvironment()
3636

3737
const { finalDisabled, dependencyValues, canonicalIndex } = useDependsOnGate(
3838
blockId,

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
} from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks'
2929
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
3030
import { useVariablesStore as usePanelVariablesStore } from '@/stores/panel'
31+
import type { Variable } from '@/stores/panel/variables/types'
3132
import {
3233
getVariablesPosition,
3334
MAX_VARIABLES_HEIGHT,
@@ -36,7 +37,6 @@ import {
3637
MIN_VARIABLES_WIDTH,
3738
useVariablesStore,
3839
} from '@/stores/variables/store'
39-
import type { Variable } from '@/stores/variables/types'
4040
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
4141

4242
/**

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import { WorkflowValidationError } from '@/serializer'
3737
import { useCurrentWorkflowExecution, useExecutionStore } from '@/stores/execution'
3838
import { useNotificationStore } from '@/stores/notifications'
3939
import { useVariablesStore } from '@/stores/panel'
40-
import { useEnvironmentStore } from '@/stores/settings/environment'
4140
import {
4241
clearExecutionPointer,
4342
consolePersistence,
@@ -120,7 +119,6 @@ export function useWorkflowExecution() {
120119
}))
121120
)
122121
const hasHydrated = useTerminalConsoleStore((s) => s._hasHydrated)
123-
const getAllVariables = useEnvironmentStore((s) => s.getAllVariables)
124122
const { getVariablesByWorkflowId, variables } = useVariablesStore(
125123
useShallow((s) => ({
126124
getVariablesByWorkflowId: s.getVariablesByWorkflowId,
@@ -744,7 +742,6 @@ export function useWorkflowExecution() {
744742
activeWorkflowId,
745743
currentWorkflow,
746744
toggleConsole,
747-
getAllVariables,
748745
getVariablesByWorkflowId,
749746
setIsExecuting,
750747
setIsDebugging,

apps/sim/hooks/queries/environment.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { useEffect } from 'react'
21
import { createLogger } from '@sim/logger'
32
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
43
import type { WorkspaceEnvironmentData } from '@/lib/environment/api'
54
import { fetchPersonalEnvironment, fetchWorkspaceEnvironment } from '@/lib/environment/api'
65
import { workspaceCredentialKeys } from '@/hooks/queries/credentials'
76
import { API_ENDPOINTS } from '@/stores/constants'
87
import type { EnvironmentVariable } from '@/stores/settings/environment'
9-
import { useEnvironmentStore } from '@/stores/settings/environment'
108

119
export type { WorkspaceEnvironmentData } from '@/lib/environment/api'
1210
export type { EnvironmentVariable } from '@/stores/settings/environment'
@@ -22,29 +20,16 @@ export const environmentKeys = {
2220
workspace: (workspaceId: string) => [...environmentKeys.all, 'workspace', workspaceId] as const,
2321
}
2422

25-
/**
26-
* Environment Variable Types
27-
*/
2823
/**
2924
* Hook to fetch personal environment variables
3025
*/
3126
export function usePersonalEnvironment() {
32-
const setVariables = useEnvironmentStore((state) => state.setVariables)
33-
34-
const query = useQuery({
27+
return useQuery({
3528
queryKey: environmentKeys.personal(),
3629
queryFn: ({ signal }) => fetchPersonalEnvironment(signal),
3730
staleTime: 60 * 1000, // 1 minute
3831
placeholderData: keepPreviousData,
3932
})
40-
41-
useEffect(() => {
42-
if (query.data) {
43-
setVariables(query.data)
44-
}
45-
}, [query.data, setVariables])
46-
47-
return query
4833
}
4934

5035
/**

apps/sim/hooks/selectors/use-selector-query.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useMemo } from 'react'
22
import { useQuery } from '@tanstack/react-query'
33
import { extractEnvVarName, isEnvVarReference, isReference } from '@/executor/constants'
4+
import { usePersonalEnvironment } from '@/hooks/queries/environment'
45
import { getSelectorDefinition, mergeOption } from '@/hooks/selectors/registry'
56
import type { SelectorKey, SelectorOption, SelectorQueryArgs } from '@/hooks/selectors/types'
6-
import { useEnvironmentStore } from '@/stores/settings/environment'
77

88
interface SelectorHookArgs extends Omit<SelectorQueryArgs, 'key'> {
99
search?: string
@@ -31,7 +31,7 @@ export function useSelectorOptionDetail(
3131
key: SelectorKey,
3232
args: SelectorHookArgs & { detailId?: string }
3333
) {
34-
const envVariables = useEnvironmentStore((s) => s.variables)
34+
const { data: envVariables = {} } = usePersonalEnvironment()
3535
const definition = getSelectorDefinition(key)
3636

3737
const resolvedDetailId = useMemo(() => {

apps/sim/stores/index.ts

Lines changed: 21 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -1,205 +1,20 @@
11
'use client'
22

3-
import { useEffect } from 'react'
43
import { createLogger } from '@sim/logger'
4+
import { getQueryClient } from '@/app/_shell/providers/get-query-client'
5+
import { environmentKeys } from '@/hooks/queries/environment'
56
import { useExecutionStore } from '@/stores/execution'
6-
import { useVariablesStore } from '@/stores/panel'
7-
import { useEnvironmentStore } from '@/stores/settings/environment'
87
import { consolePersistence, useTerminalConsoleStore } from '@/stores/terminal'
98
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
109
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
1110
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
1211

1312
const logger = createLogger('Stores')
1413

15-
// Track initialization state
16-
let isInitializing = false
17-
let appFullyInitialized = false
18-
let dataInitialized = false // Flag for actual data loading completion
19-
20-
/**
21-
* Initialize the application state and sync system
22-
* localStorage persistence has been removed - relies on DB and Zustand stores only
23-
*/
24-
async function initializeApplication(): Promise<void> {
25-
if (typeof window === 'undefined' || isInitializing) return
26-
27-
isInitializing = true
28-
appFullyInitialized = false
29-
30-
// Track initialization start time
31-
const initStartTime = Date.now()
32-
33-
try {
34-
// Load environment variables directly from DB
35-
await useEnvironmentStore.getState().loadEnvironmentVariables()
36-
37-
// Mark data as initialized only after sync managers have loaded data from DB
38-
dataInitialized = true
39-
40-
// Log initialization timing information
41-
const initDuration = Date.now() - initStartTime
42-
logger.info(`Application initialization completed in ${initDuration}ms`)
43-
44-
// Mark application as fully initialized
45-
appFullyInitialized = true
46-
} catch (error) {
47-
logger.error('Error during application initialization:', { error })
48-
// Still mark as initialized to prevent being stuck in initializing state
49-
appFullyInitialized = true
50-
// But don't mark data as initialized on error
51-
dataInitialized = false
52-
} finally {
53-
isInitializing = false
54-
}
55-
}
56-
57-
/**
58-
* Checks if application is fully initialized
59-
*/
60-
export function isAppInitialized(): boolean {
61-
return appFullyInitialized
62-
}
63-
64-
/**
65-
* Checks if data has been loaded from the database
66-
* This should be checked before any sync operations
67-
*/
68-
export function isDataInitialized(): boolean {
69-
return dataInitialized
70-
}
71-
72-
/**
73-
* Handle application cleanup before unload
74-
*/
75-
function handleBeforeUnload(event: BeforeUnloadEvent): void {
76-
// Check if we're on an authentication page and skip confirmation if we are
77-
if (typeof window !== 'undefined') {
78-
const path = window.location.pathname
79-
// Skip confirmation for auth-related pages
80-
if (
81-
path === '/login' ||
82-
path === '/signup' ||
83-
path === '/reset-password' ||
84-
path === '/verify'
85-
) {
86-
return
87-
}
88-
}
89-
90-
// Standard beforeunload pattern
91-
event.preventDefault()
92-
event.returnValue = ''
93-
}
94-
95-
/**
96-
* Clean up sync system
97-
*/
98-
function cleanupApplication(): void {
99-
window.removeEventListener('beforeunload', handleBeforeUnload)
100-
// Note: No sync managers to dispose - Socket.IO handles cleanup
101-
}
102-
103-
/**
104-
* Clear all user data when signing out
105-
* localStorage persistence has been removed
106-
*/
107-
export async function clearUserData(): Promise<void> {
108-
if (typeof window === 'undefined') return
109-
110-
try {
111-
// Note: No sync managers to dispose - Socket.IO handles cleanup
112-
113-
// Reset all stores to their initial state
114-
resetAllStores()
115-
116-
// Clear localStorage except for essential app settings (minimal usage)
117-
const keysToKeep = ['next-favicon', 'theme']
118-
const keysToRemove = Object.keys(localStorage).filter((key) => !keysToKeep.includes(key))
119-
keysToRemove.forEach((key) => localStorage.removeItem(key))
120-
121-
// Reset application initialization state
122-
appFullyInitialized = false
123-
dataInitialized = false
124-
125-
logger.info('User data cleared successfully')
126-
} catch (error) {
127-
logger.error('Error clearing user data:', { error })
128-
}
129-
}
130-
131-
/**
132-
* Hook to manage application lifecycle
133-
*/
134-
export function useAppInitialization() {
135-
useEffect(() => {
136-
// Use Promise to handle async initialization
137-
initializeApplication()
138-
139-
return () => {
140-
cleanupApplication()
141-
}
142-
}, [])
143-
}
144-
145-
/**
146-
* Hook to reinitialize the application after successful login
147-
* Use this in the login success handler or post-login page
148-
*/
149-
export function useLoginInitialization() {
150-
useEffect(() => {
151-
reinitializeAfterLogin()
152-
}, [])
153-
}
154-
15514
/**
156-
* Reinitialize the application after login
157-
* This ensures we load fresh data from the database for the new user
15+
* Reset all Zustand stores and React Query caches to initial state.
15816
*/
159-
export async function reinitializeAfterLogin(): Promise<void> {
160-
if (typeof window === 'undefined') return
161-
162-
try {
163-
// Reset application initialization state
164-
appFullyInitialized = false
165-
dataInitialized = false
166-
167-
// Note: No sync managers to dispose - Socket.IO handles cleanup
168-
169-
// Clean existing state to avoid stale data
170-
resetAllStores()
171-
172-
// Reset initialization flags to force a fresh load
173-
isInitializing = false
174-
175-
// Reinitialize the application
176-
await initializeApplication()
177-
178-
logger.info('Application reinitialized after login')
179-
} catch (error) {
180-
logger.error('Error reinitializing application:', { error })
181-
}
182-
}
183-
184-
// Initialize immediately when imported on client
185-
if (typeof window !== 'undefined') {
186-
initializeApplication()
187-
}
188-
189-
// Export all stores
190-
export {
191-
useWorkflowStore,
192-
useWorkflowRegistry,
193-
useEnvironmentStore,
194-
useExecutionStore,
195-
useTerminalConsoleStore,
196-
useVariablesStore,
197-
useSubBlockStore,
198-
}
199-
200-
// Helper function to reset all stores
20117
export const resetAllStores = () => {
202-
// Reset all stores to initial state
20318
useWorkflowRegistry.setState({
20419
activeWorkflowId: null,
20520
error: null,
@@ -213,7 +28,7 @@ export const resetAllStores = () => {
21328
})
21429
useWorkflowStore.getState().clear()
21530
useSubBlockStore.getState().clear()
216-
useEnvironmentStore.getState().reset()
31+
getQueryClient().removeQueries({ queryKey: environmentKeys.all })
21732
useExecutionStore.getState().reset()
21833
useTerminalConsoleStore.setState({
21934
workflowEntries: {},
@@ -222,21 +37,24 @@ export const resetAllStores = () => {
22237
isOpen: false,
22338
})
22439
consolePersistence.persist()
225-
// Custom tools are managed by React Query cache, not a Zustand store
226-
// Variables store has no tracking to reset; registry hydrates
22740
}
22841

229-
// Helper function to log all store states
230-
export const logAllStores = () => {
231-
const state = {
232-
workflow: useWorkflowStore.getState(),
233-
workflowRegistry: useWorkflowRegistry.getState(),
234-
environment: useEnvironmentStore.getState(),
235-
execution: useExecutionStore.getState(),
236-
console: useTerminalConsoleStore.getState(),
237-
subBlock: useSubBlockStore.getState(),
238-
variables: useVariablesStore.getState(),
239-
}
42+
/**
43+
* Clear all user data when signing out.
44+
*/
45+
export async function clearUserData(): Promise<void> {
46+
if (typeof window === 'undefined') return
24047

241-
return state
48+
try {
49+
resetAllStores()
50+
51+
// Clear localStorage except for essential app settings
52+
const keysToKeep = ['next-favicon', 'theme']
53+
const keysToRemove = Object.keys(localStorage).filter((key) => !keysToKeep.includes(key))
54+
keysToRemove.forEach((key) => localStorage.removeItem(key))
55+
56+
logger.info('User data cleared successfully')
57+
} catch (error) {
58+
logger.error('Error clearing user data:', { error })
59+
}
24260
}

0 commit comments

Comments
 (0)