improvement(stores): standardized quality of stores and added max history to relevant stores

This commit is contained in:
Emir Karabeg
2025-02-18 00:58:32 -08:00
parent fb5272cb4e
commit d3a042ac22
5 changed files with 49 additions and 22 deletions
+1
View File
@@ -2,6 +2,7 @@ import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
import { ConsoleEntry, ConsoleStore } from './types'
// MAX across all workflows
const MAX_ENTRIES = 50
export const useConsoleStore = create<ConsoleStore>()(
+9 -3
View File
@@ -3,18 +3,20 @@ import { devtools } from 'zustand/middleware'
import { Notification, NotificationStore, NotificationType } from './types'
const STORAGE_KEY = 'workflow-notifications'
// Maximum number of notifications to keep across all workflows
const MAX_NOTIFICATIONS = 50
// Helper to load persisted notifications
const loadPersistedNotifications = (): Notification[] => {
if (typeof window === 'undefined') return []
const saved = localStorage.getItem(STORAGE_KEY)
return saved ? JSON.parse(saved) : []
return saved ? JSON.parse(saved).slice(0, MAX_NOTIFICATIONS) : []
}
// Helper to save notifications to localStorage
const persistNotifications = (notifications: Notification[]) => {
if (typeof window === 'undefined') return
localStorage.setItem(STORAGE_KEY, JSON.stringify(notifications))
localStorage.setItem(STORAGE_KEY, JSON.stringify(notifications.slice(0, MAX_NOTIFICATIONS)))
}
export const useNotificationStore = create<NotificationStore>()(
@@ -36,7 +38,11 @@ export const useNotificationStore = create<NotificationStore>()(
}
set((state) => {
const newNotifications = [...state.notifications, notification]
// Add new notification at the start and limit total count
const newNotifications = [notification, ...state.notifications].slice(
0,
MAX_NOTIFICATIONS
)
persistNotifications(newNotifications)
return { notifications: newNotifications }
})
+13
View File
@@ -2,16 +2,20 @@ import { StateCreator } from 'zustand'
import { HistoryActions, HistoryEntry, WorkflowHistory } from './history-types'
import { WorkflowState, WorkflowStore } from './types'
// MAX for each individual workflow
const MAX_HISTORY_LENGTH = 20
// Types for workflow store with history management capabilities
export interface WorkflowStoreWithHistory extends WorkflowStore, HistoryActions {
history: WorkflowHistory
}
// Higher-order store middleware that adds undo/redo functionality
export const withHistory = (
config: StateCreator<WorkflowStoreWithHistory>
): StateCreator<WorkflowStoreWithHistory> => {
return (set, get, api) => {
// Initialize store with history tracking
const initialState = config(set, get, api)
const initialHistoryEntry: HistoryEntry = {
state: {
@@ -31,9 +35,13 @@ export const withHistory = (
future: [],
},
// Check if undo operation is available
canUndo: () => get().history.past.length > 0,
// Check if redo operation is available
canRedo: () => get().history.future.length > 0,
// Restore previous state from history
undo: () => {
const { history, ...state } = get()
if (history.past.length === 0) return
@@ -52,6 +60,7 @@ export const withHistory = (
})
},
// Restore next state from history
redo: () => {
const { history, ...state } = get()
if (history.future.length === 0) return
@@ -70,6 +79,7 @@ export const withHistory = (
})
},
// Reset workflow to empty state
clear: () => {
const newState = {
blocks: {},
@@ -89,6 +99,7 @@ export const withHistory = (
return newState
},
// Jump to specific point in history
revertToHistoryState: (index: number) => {
const { history, ...state } = get()
const allStates = [...history.past, history.present, ...history.future]
@@ -113,6 +124,7 @@ export const withHistory = (
}
}
// Create a new history entry with current state snapshot
export const createHistoryEntry = (state: WorkflowState, action: string): HistoryEntry => ({
state: {
blocks: { ...state.blocks },
@@ -123,6 +135,7 @@ export const createHistoryEntry = (state: WorkflowState, action: string): Histor
action,
})
// Add new entry to history and maintain history size limit
export const pushHistory = (
set: (
partial:
+7 -19
View File
@@ -2,15 +2,18 @@ import { create } from 'zustand'
import { devtools } from 'zustand/middleware'
import { useWorkflowStore } from '../store'
import { WorkflowMetadata, WorkflowRegistry } from './types'
import { generateUniqueName } from './utils'
export const useWorkflowRegistry = create<WorkflowRegistry>()(
devtools(
(set, get) => ({
// Store state
workflows: {},
activeWorkflowId: null,
isLoading: false,
error: null,
// Switch to a different workflow and manage state persistence
setActiveWorkflow: async (id: string) => {
const { workflows } = get()
if (!workflows[id]) {
@@ -72,6 +75,7 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
set({ activeWorkflowId: id, error: null })
},
// Create new workflow with default starter block
addWorkflow: (metadata: WorkflowMetadata) => {
const uniqueName = generateUniqueName(get().workflows)
const updatedMetadata = { ...metadata, name: uniqueName }
@@ -216,6 +220,7 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
}
},
// Delete workflow and clean up associated storage
removeWorkflow: (id: string) => {
set((state) => {
const newWorkflows = { ...state.workflows }
@@ -277,6 +282,7 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
})
},
// Update workflow metadata
updateWorkflow: (id: string, metadata: Partial<WorkflowMetadata>) => {
set((state) => {
const workflow = state.workflows[id]
@@ -305,25 +311,7 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
)
)
const generateUniqueName = (existingWorkflows: Record<string, WorkflowMetadata>): string => {
// Extract numbers from existing workflow names using regex
const numbers = Object.values(existingWorkflows)
.map((w) => {
const match = w.name.match(/Workflow (\d+)/)
return match ? parseInt(match[1]) : 0
})
.filter((n) => n > 0)
if (numbers.length === 0) {
return 'Workflow 1'
}
// Find the maximum number and add 1
const nextNumber = Math.max(...numbers) + 1
return `Workflow ${nextNumber}`
}
// Initialize registry from localStorage
// Initialize registry from localStorage and set up persistence
const initializeRegistry = () => {
const savedRegistry = localStorage.getItem('workflow-registry')
if (savedRegistry) {
+19
View File
@@ -0,0 +1,19 @@
import { WorkflowMetadata } from './types'
export function generateUniqueName(existingWorkflows: Record<string, WorkflowMetadata>): string {
// Extract numbers from existing workflow names using regex
const numbers = Object.values(existingWorkflows)
.map((w) => {
const match = w.name.match(/Workflow (\d+)/)
return match ? parseInt(match[1]) : 0
})
.filter((n) => n > 0)
if (numbers.length === 0) {
return 'Workflow 1'
}
// Find the maximum number and add 1
const nextNumber = Math.max(...numbers) + 1
return `Workflow ${nextNumber}`
}