Rechercher

PythonReactSEOPDF
GitHub Skill

zustand-store-development

Guide for creating and modifying Zustand stores with IndexedDB persistence in the DEVS platform. Use this when asked to create a new store, modify store logic, or work with state management.

codename-co☆ 5 Étoiles du dépôt0 Forks du dépôt

Installation

Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.

Voir la source ↗Guides

Instructions

Zustand Store Development for DEVS

When creating or modifying Zustand stores in the DEVS platform, follow these patterns and best practices.

Directory Structure

Stores are located in src/stores/. Each store manages a specific domain entity.

Store Pattern Template

import { create } from 'zustand'
import { db } from '@/lib/db'
import { toast } from '@/lib/toast'

// 1. Define the store state interface
interface EntityState {
  entities: Entity[]
  isLoading: boolean
  error: string | null
}

// 2. Define the store actions interface
interface EntityActions {
  loadEntities: () => Promise<void>
  createEntity: (data: CreateEntityInput) => Promise<Entity>
  updateEntity: (id: string, updates: Partial<Entity>) => Promise<void>
  deleteEntity: (id: string) => Promise<void>
  getEntityById: (id: string) => Entity | undefined
}

// 3. Create the store with both state and actions
export const useEntityStore = create<EntityState & EntityActions>(
  (set, get) => ({
    // Initial state
    entities: [],
    isLoading: false,
    error: null,

    // Actions
    loadEntities: async () => {
      set({ isLoading: true, error: null })
      try {
        const entities = await db.entities.toArray()
        set({ entities, isLoading: false })
      } catch (error) {
        set({ error: (error as Error).message, isLoading: false })
        toast.error('Failed to load entities')
      }
    },

    createEntity: async (data) => {
      const entity: Entity = {
        id: crypto.randomUUID(),
        ...data,
        createdAt: new Date(),
        updatedAt: new Date(),
      }

      await db.entities.add(entity)
      set((state) => ({ entities: [...state.entities, entity] }))
      return entity
    },

    updateEntity: async (id, updates) => {
      const updatedData = { ...updates, updatedAt: new Date() }
      await db.entities.update(id, updatedData)
      set((state) => ({
        entities: state.entities.map((e) =>
          e.id === id ? { ...e, ...updatedData } : e,
        ),
      }))
    },

    deleteEntity: async (id) => {
      await db.entities.delete(id)
      set((state) => ({
        entities: state.entities.filter((e) => e.id !== id),
      }))
    },

    getEntityById: (id) => {
      return get().entities.find((e) => e.id === id)
    },
  }),
)

// 4. Export standalone functions for non-React contexts
export const getEntityById = (id: string) =>
  useEntityStore.getState().getEntityById(id)
export const createEntity = (data: CreateEntityInput) =>
  useEntityStore.getState().createEntity(data)
export const updateEntity = (id: string, updates: Partial<Entity>) =>
  useEntityStore.getState().updateEntity(id, updates)
export const deleteEntity = (id: string) =>
  useEntityStore.getState().deleteEntity(id)

Critical Rules

  1. Export standalone functions: Always export functions directly for use in non-React contexts (lib/, orchestrator, etc.)

    // ✅ Correct - use exported functions in lib code
    import { getAgentById, createAgent } from '@/stores/agentStore'
    
    // ❌ Wrong - don't use hooks in lib code
    const { getAgentById } = useAgentStore()
    
  2. Database initialization: Always check db.isInitialized() before operations if the store loads at app startup

  3. Optimistic updates: Update local state immediately, then persist to IndexedDB

  4. Error handling: Use try/catch with toast notifications for user feedback

  5. Timestamps: Always update updatedAt when modifying entities

Testing Requirements (TDD Mandatory)

All store changes MUST follow TDD:

  1. Create test file at src/test/stores/{storeName}.test.ts
  2. Write failing tests first
  3. Implement minimum code to pass
  4. Run npm run test:coverage before committing

Example test structure:

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { useEntityStore } from '@/stores/entityStore'

describe('entityStore', () => {
  beforeEach(() => {
    useEntityStore.setState({ entities: [], isLoading: false, error: null })
  })

  describe('createEntity', () => {
    it('should create entity with correct structure', async () => {
      const result = await useEntityStore
        .getState()
        .createEntity({ name: 'Test' })
      expect(result).toHaveProperty('id')
      expect(result.name).toBe('Test')
    })
  })
})

Existing Stores Reference

  • agentStore - AI agent management with slug generation
  • taskStore - Task lifecycle and requirement validation
  • conversationStore - Multi-agent chat history
  • artifactStore - Task deliverables
  • contextStore - Inter-agent context sharing
  • userStore - User preferences and settings
  • agentMemoryStore - Agent learning and memory

Exemples

Consultez les exemples du dépôt source.

Voir la source ↗

Historique source

Date d’indexation
2026-01-20
Mise à jour de l’index
2026-02-02
Branch
main

Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!