d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
72 lines
1.9 KiB
Markdown
72 lines
1.9 KiB
Markdown
---
|
|
paths:
|
|
- "apps/sim/**/store.ts"
|
|
- "apps/sim/**/stores/**/*.ts"
|
|
---
|
|
|
|
# Zustand Store Patterns
|
|
|
|
Stores live in `stores/`. Complex stores split into `store.ts` + `types.ts`.
|
|
|
|
## Basic Store
|
|
|
|
```typescript
|
|
import { create } from 'zustand'
|
|
import { devtools } from 'zustand/middleware'
|
|
import type { FeatureState } from '@/stores/feature/types'
|
|
|
|
const initialState = { items: [] as Item[], activeId: null as string | null }
|
|
|
|
export const useFeatureStore = create<FeatureState>()(
|
|
devtools(
|
|
(set, get) => ({
|
|
...initialState,
|
|
setItems: (items) => set({ items }),
|
|
addItem: (item) => set((state) => ({ items: [...state.items, item] })),
|
|
reset: () => set(initialState),
|
|
}),
|
|
{ name: 'feature-store' }
|
|
)
|
|
)
|
|
```
|
|
|
|
## Persisted Store
|
|
|
|
```typescript
|
|
import { create } from 'zustand'
|
|
import { persist } from 'zustand/middleware'
|
|
|
|
export const useFeatureStore = create<FeatureState>()(
|
|
persist(
|
|
(set) => ({
|
|
width: 300,
|
|
setWidth: (width) => set({ width }),
|
|
_hasHydrated: false,
|
|
setHasHydrated: (v) => set({ _hasHydrated: v }),
|
|
}),
|
|
{
|
|
name: 'feature-state',
|
|
partialize: (state) => ({ width: state.width }),
|
|
onRehydrateStorage: () => (state) => state?.setHasHydrated(true),
|
|
}
|
|
)
|
|
)
|
|
```
|
|
|
|
## Rules
|
|
|
|
1. Use `devtools` middleware (named stores)
|
|
2. Use `persist` only when data should survive reload
|
|
3. `persist` MUST use `partialize` with an explicit whitelist of the durable fields. Exclude transient flags (`isResizing`, drag/hover state) and `_hasHydrated` from the whitelist, and never spread the whole state (`{ ...state }`) — it leaks actions and transient state into storage
|
|
4. `_hasHydrated` pattern for persisted stores needing hydration tracking
|
|
5. Immutable updates only
|
|
6. `set((state) => ...)` when depending on previous state
|
|
7. Provide `reset()` action
|
|
|
|
## Outside React
|
|
|
|
```typescript
|
|
const items = useFeatureStore.getState().items
|
|
useFeatureStore.setState({ items: newItems })
|
|
```
|