refactor(store): split gatewayStore into specialized domain stores
Major restructuring: - Split monolithic gatewayStore into 5 focused stores: - connectionStore: WebSocket connection and gateway lifecycle - configStore: quickConfig, workspaceInfo, MCP services - agentStore: clones, usage stats, agent management - handStore: hands, approvals, triggers, hand runs - workflowStore: workflows, workflow runs, execution - Update all components to use new stores with selector pattern - Remove
This commit is contained in:
@@ -6,8 +6,7 @@
|
||||
*
|
||||
* The coordinator:
|
||||
* 1. Injects the shared client into all stores
|
||||
* 2. Provides a composite hook that combines all store slices
|
||||
* 3. Re-exports all individual stores for direct access
|
||||
* 2. Re-exports all individual stores for direct access
|
||||
*/
|
||||
|
||||
// === Re-export Individual Stores ===
|
||||
@@ -26,6 +25,12 @@ export type { WorkflowStore, WorkflowStateSlice, WorkflowActionsSlice, Workflow,
|
||||
export { useConfigStore, setConfigStoreClient } from './configStore';
|
||||
export type { ConfigStore, ConfigStateSlice, ConfigActionsSlice, QuickConfig, WorkspaceInfo, ChannelInfo, ScheduledTask, SkillInfo } from './configStore';
|
||||
|
||||
export { useSecurityStore, setSecurityStoreClient } from './securityStore';
|
||||
export type { SecurityStore, SecurityStateSlice, SecurityActionsSlice, SecurityLayer, SecurityStatus, AuditLogEntry } from './securityStore';
|
||||
|
||||
export { useSessionStore, setSessionStoreClient } from './sessionStore';
|
||||
export type { SessionStore, SessionStateSlice, SessionActionsSlice, Session, SessionMessage } from './sessionStore';
|
||||
|
||||
// === New Stores ===
|
||||
export { useMemoryGraphStore } from './memoryGraphStore';
|
||||
export type { MemoryGraphStore, GraphNode, GraphEdge, GraphFilter, GraphLayout } from './memoryGraphStore';
|
||||
@@ -49,14 +54,15 @@ export type {
|
||||
SessionOptions,
|
||||
} from '../components/BrowserHand/templates/types';
|
||||
|
||||
// === Composite Store Hook ===
|
||||
// === Store Initialization ===
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useConnectionStore, getClient } from './connectionStore';
|
||||
import { useAgentStore, setAgentStoreClient } from './agentStore';
|
||||
import { useHandStore, setHandStoreClient } from './handStore';
|
||||
import { useWorkflowStore, setWorkflowStoreClient } from './workflowStore';
|
||||
import { useConfigStore, setConfigStoreClient } from './configStore';
|
||||
import { getClient } from './connectionStore';
|
||||
import { setAgentStoreClient } from './agentStore';
|
||||
import { setHandStoreClient } from './handStore';
|
||||
import { setWorkflowStoreClient } from './workflowStore';
|
||||
import { setConfigStoreClient } from './configStore';
|
||||
import { setSecurityStoreClient } from './securityStore';
|
||||
import { setSessionStoreClient } from './sessionStore';
|
||||
|
||||
/**
|
||||
* Initialize all stores with the shared client.
|
||||
@@ -70,207 +76,8 @@ export function initializeStores(): void {
|
||||
setHandStoreClient(client);
|
||||
setWorkflowStoreClient(client);
|
||||
setConfigStoreClient(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that provides a composite view of all stores.
|
||||
* Use this for components that need access to multiple store slices.
|
||||
*
|
||||
* For components that only need specific slices, import the individual
|
||||
* store hooks directly (e.g., useConnectionStore, useAgentStore).
|
||||
*/
|
||||
export function useCompositeStore() {
|
||||
// Subscribe to all stores
|
||||
const connectionState = useConnectionStore((s) => s.connectionState);
|
||||
const gatewayVersion = useConnectionStore((s) => s.gatewayVersion);
|
||||
const connectionError = useConnectionStore((s) => s.error);
|
||||
const logs = useConnectionStore((s) => s.logs);
|
||||
const localGateway = useConnectionStore((s) => s.localGateway);
|
||||
const localGatewayBusy = useConnectionStore((s) => s.localGatewayBusy);
|
||||
const isLoading = useConnectionStore((s) => s.isLoading);
|
||||
const client = useConnectionStore((s) => s.client);
|
||||
|
||||
const clones = useAgentStore((s) => s.clones);
|
||||
const usageStats = useAgentStore((s) => s.usageStats);
|
||||
const pluginStatus = useAgentStore((s) => s.pluginStatus);
|
||||
|
||||
const hands = useHandStore((s) => s.hands);
|
||||
const handRuns = useHandStore((s) => s.handRuns);
|
||||
const triggers = useHandStore((s) => s.triggers);
|
||||
const approvals = useHandStore((s) => s.approvals);
|
||||
|
||||
const workflows = useWorkflowStore((s) => s.workflows);
|
||||
const workflowRuns = useWorkflowStore((s) => s.workflowRuns);
|
||||
|
||||
const quickConfig = useConfigStore((s) => s.quickConfig);
|
||||
const workspaceInfo = useConfigStore((s) => s.workspaceInfo);
|
||||
const channels = useConfigStore((s) => s.channels);
|
||||
const scheduledTasks = useConfigStore((s) => s.scheduledTasks);
|
||||
const skillsCatalog = useConfigStore((s) => s.skillsCatalog);
|
||||
const models = useConfigStore((s) => s.models);
|
||||
const modelsLoading = useConfigStore((s) => s.modelsLoading);
|
||||
const modelsError = useConfigStore((s) => s.modelsError);
|
||||
|
||||
// Get all actions
|
||||
const connect = useConnectionStore((s) => s.connect);
|
||||
const disconnect = useConnectionStore((s) => s.disconnect);
|
||||
const clearLogs = useConnectionStore((s) => s.clearLogs);
|
||||
const refreshLocalGateway = useConnectionStore((s) => s.refreshLocalGateway);
|
||||
const startLocalGateway = useConnectionStore((s) => s.startLocalGateway);
|
||||
const stopLocalGateway = useConnectionStore((s) => s.stopLocalGateway);
|
||||
const restartLocalGateway = useConnectionStore((s) => s.restartLocalGateway);
|
||||
|
||||
const loadClones = useAgentStore((s) => s.loadClones);
|
||||
const createClone = useAgentStore((s) => s.createClone);
|
||||
const updateClone = useAgentStore((s) => s.updateClone);
|
||||
const deleteClone = useAgentStore((s) => s.deleteClone);
|
||||
const loadUsageStats = useAgentStore((s) => s.loadUsageStats);
|
||||
const loadPluginStatus = useAgentStore((s) => s.loadPluginStatus);
|
||||
|
||||
const loadHands = useHandStore((s) => s.loadHands);
|
||||
const getHandDetails = useHandStore((s) => s.getHandDetails);
|
||||
const triggerHand = useHandStore((s) => s.triggerHand);
|
||||
const loadHandRuns = useHandStore((s) => s.loadHandRuns);
|
||||
const loadTriggers = useHandStore((s) => s.loadTriggers);
|
||||
const createTrigger = useHandStore((s) => s.createTrigger);
|
||||
const deleteTrigger = useHandStore((s) => s.deleteTrigger);
|
||||
const loadApprovals = useHandStore((s) => s.loadApprovals);
|
||||
const respondToApproval = useHandStore((s) => s.respondToApproval);
|
||||
|
||||
const loadWorkflows = useWorkflowStore((s) => s.loadWorkflows);
|
||||
const getWorkflow = useWorkflowStore((s) => s.getWorkflow);
|
||||
const createWorkflow = useWorkflowStore((s) => s.createWorkflow);
|
||||
const updateWorkflow = useWorkflowStore((s) => s.updateWorkflow);
|
||||
const deleteWorkflow = useWorkflowStore((s) => s.deleteWorkflow);
|
||||
const triggerWorkflow = useWorkflowStore((s) => s.triggerWorkflow);
|
||||
const loadWorkflowRuns = useWorkflowStore((s) => s.loadWorkflowRuns);
|
||||
|
||||
const loadQuickConfig = useConfigStore((s) => s.loadQuickConfig);
|
||||
const saveQuickConfig = useConfigStore((s) => s.saveQuickConfig);
|
||||
const loadWorkspaceInfo = useConfigStore((s) => s.loadWorkspaceInfo);
|
||||
const loadChannels = useConfigStore((s) => s.loadChannels);
|
||||
const getChannel = useConfigStore((s) => s.getChannel);
|
||||
const createChannel = useConfigStore((s) => s.createChannel);
|
||||
const updateChannel = useConfigStore((s) => s.updateChannel);
|
||||
const deleteChannel = useConfigStore((s) => s.deleteChannel);
|
||||
const loadScheduledTasks = useConfigStore((s) => s.loadScheduledTasks);
|
||||
const createScheduledTask = useConfigStore((s) => s.createScheduledTask);
|
||||
const loadSkillsCatalog = useConfigStore((s) => s.loadSkillsCatalog);
|
||||
const getSkill = useConfigStore((s) => s.getSkill);
|
||||
const createSkill = useConfigStore((s) => s.createSkill);
|
||||
const updateSkill = useConfigStore((s) => s.updateSkill);
|
||||
const deleteSkill = useConfigStore((s) => s.deleteSkill);
|
||||
const loadModels = useConfigStore((s) => s.loadModels);
|
||||
|
||||
// Memoize the composite store to prevent unnecessary re-renders
|
||||
return useMemo(() => ({
|
||||
// Connection state
|
||||
connectionState,
|
||||
gatewayVersion,
|
||||
error: connectionError,
|
||||
logs,
|
||||
localGateway,
|
||||
localGatewayBusy,
|
||||
isLoading,
|
||||
client,
|
||||
|
||||
// Agent state
|
||||
clones,
|
||||
usageStats,
|
||||
pluginStatus,
|
||||
|
||||
// Hand state
|
||||
hands,
|
||||
handRuns,
|
||||
triggers,
|
||||
approvals,
|
||||
|
||||
// Workflow state
|
||||
workflows,
|
||||
workflowRuns,
|
||||
|
||||
// Config state
|
||||
quickConfig,
|
||||
workspaceInfo,
|
||||
channels,
|
||||
scheduledTasks,
|
||||
skillsCatalog,
|
||||
models,
|
||||
modelsLoading,
|
||||
modelsError,
|
||||
|
||||
// Connection actions
|
||||
connect,
|
||||
disconnect,
|
||||
clearLogs,
|
||||
refreshLocalGateway,
|
||||
startLocalGateway,
|
||||
stopLocalGateway,
|
||||
restartLocalGateway,
|
||||
|
||||
// Agent actions
|
||||
loadClones,
|
||||
createClone,
|
||||
updateClone,
|
||||
deleteClone,
|
||||
loadUsageStats,
|
||||
loadPluginStatus,
|
||||
|
||||
// Hand actions
|
||||
loadHands,
|
||||
getHandDetails,
|
||||
triggerHand,
|
||||
loadHandRuns,
|
||||
loadTriggers,
|
||||
createTrigger,
|
||||
deleteTrigger,
|
||||
loadApprovals,
|
||||
respondToApproval,
|
||||
|
||||
// Workflow actions
|
||||
loadWorkflows,
|
||||
getWorkflow,
|
||||
createWorkflow,
|
||||
updateWorkflow,
|
||||
deleteWorkflow,
|
||||
triggerWorkflow,
|
||||
loadWorkflowRuns,
|
||||
|
||||
// Config actions
|
||||
loadQuickConfig,
|
||||
saveQuickConfig,
|
||||
loadWorkspaceInfo,
|
||||
loadChannels,
|
||||
getChannel,
|
||||
createChannel,
|
||||
updateChannel,
|
||||
deleteChannel,
|
||||
loadScheduledTasks,
|
||||
createScheduledTask,
|
||||
loadSkillsCatalog,
|
||||
getSkill,
|
||||
createSkill,
|
||||
updateSkill,
|
||||
deleteSkill,
|
||||
loadModels,
|
||||
|
||||
// Legacy sendMessage (delegates to client)
|
||||
sendMessage: async (message: string, sessionKey?: string) => {
|
||||
return client.chat(message, { sessionKey });
|
||||
},
|
||||
}), [
|
||||
connectionState, gatewayVersion, connectionError, logs, localGateway, localGatewayBusy, isLoading, client,
|
||||
clones, usageStats, pluginStatus,
|
||||
hands, handRuns, triggers, approvals,
|
||||
workflows, workflowRuns,
|
||||
quickConfig, workspaceInfo, channels, scheduledTasks, skillsCatalog, models, modelsLoading, modelsError,
|
||||
connect, disconnect, clearLogs, refreshLocalGateway, startLocalGateway, stopLocalGateway, restartLocalGateway,
|
||||
loadClones, createClone, updateClone, deleteClone, loadUsageStats, loadPluginStatus,
|
||||
loadHands, getHandDetails, triggerHand, loadHandRuns, loadTriggers, createTrigger, deleteTrigger, loadApprovals, respondToApproval,
|
||||
loadWorkflows, getWorkflow, createWorkflow, updateWorkflow, deleteWorkflow, triggerWorkflow, loadWorkflowRuns,
|
||||
loadQuickConfig, saveQuickConfig, loadWorkspaceInfo, loadChannels, getChannel, createChannel, updateChannel, deleteChannel,
|
||||
loadScheduledTasks, createScheduledTask, loadSkillsCatalog, getSkill, createSkill, updateSkill, deleteSkill, loadModels,
|
||||
]);
|
||||
setSecurityStoreClient(client);
|
||||
setSessionStoreClient(client);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user