- Document migration approach in ZUSTAND_MIGRATION_STRATEGY.md - Add persistWithMigration utility for future stores - Add version and migrate to authStore, library, ui, cartStore, playerStore
63 lines
1.6 KiB
Markdown
63 lines
1.6 KiB
Markdown
# Zustand Store Migration Strategy
|
|
|
|
When the persisted store schema changes, we need a migration strategy to avoid corruption or runtime errors.
|
|
|
|
## Approach
|
|
|
|
1. **Version in storage key**: Each store uses a versioned storage key (e.g. `auth-storage-v1`).
|
|
2. **`migrate` callback**: The Zustand `persist` middleware accepts a `migrate` function that transforms old state to new schema.
|
|
3. **Fallback reset**: If migration fails, reset to default state rather than crash.
|
|
|
|
## migrate Function Signature
|
|
|
|
```ts
|
|
(state: unknown, version: number) => NewState
|
|
```
|
|
|
|
- `state`: The raw persisted value from localStorage (may be from an older version).
|
|
- `version`: The version number from the persisted state (0 if never set).
|
|
|
|
## Example
|
|
|
|
```ts
|
|
persist(
|
|
(set) => ({ ... }),
|
|
{
|
|
name: 'auth-storage',
|
|
version: 1,
|
|
migrate: (persistedState, version) => {
|
|
if (version === 0) {
|
|
// Old schema: { user, token, ... }
|
|
// New schema: { isAuthenticated, isLoading, error }
|
|
return {
|
|
isAuthenticated: !!persistedState?.user,
|
|
isLoading: false,
|
|
error: null,
|
|
};
|
|
}
|
|
return persistedState as AuthState;
|
|
},
|
|
}
|
|
)
|
|
```
|
|
|
|
## Stores Using Persist
|
|
|
|
- `authStore` — auth-storage
|
|
- `library` — library-storage
|
|
- `ui` — ui-storage
|
|
- `cartStore` — cart-storage
|
|
- `playerStore` — player-storage
|
|
|
|
## When to Bump Version
|
|
|
|
Bump `version` when:
|
|
- Adding/removing persisted fields
|
|
- Changing the shape of persisted data
|
|
- Renaming keys
|
|
|
|
## Testing Migration
|
|
|
|
1. Manually set old state in localStorage.
|
|
2. Reload the app.
|
|
3. Verify the store hydrates correctly.
|