> ## Documentation Index
> Fetch the complete documentation index at: https://songbird.studiocollective.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Zustand Slices (`react_ui/src/data/slices/`)

# Zustand Slices (`react_ui/src/data/slices/`)

Each Zustand store is defined as a **slice** — a function that returns state + actions for one domain. Slices are composed into full stores in `store.ts`.

## Files

| Slice                | Store ID          | Persisted To     | Purpose                                                                                                                |
| -------------------- | ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `transport.ts`       | `transport:state` | `daw.state.json` | BPM, key signature, scale, loop state, playback position. **Git-tracked**.                                             |
| `mixer.ts`           | `mixer:state`     | `daw.mixer.json` | Track list, volumes, pans, mutes, solos, sends, plugins, notes, sections. **Git-tracked** — changes trigger commits.   |
| `chat.ts`            | `chat:state`      | `daw.ai.json`    | AI chat messages, threads, right panel visibility, active model. **Git-tracked**.                                      |
| `lyria.ts`           | `ai:lyria`        | `daw.ai.json`    | AI music generation config per track (temperature, density, brightness, prompts). **Git-tracked**.                     |
| `collab.ts`          | —                 | —                | Collaboration state: connected users, room info, invite codes, cursor positions. Not persisted.                        |
| `inlineGenerate.ts`  | —                 | —                | Inline AI generation state: drag region, generation progress, results. Tracks Option+click-drag audio/MIDI generation. |
| `customEditors.ts`   | —                 | —                | Custom editor panel state: which stock plugin UI is active, editor panel visibility.                                   |
| `scriptFxEditors.ts` | —                 | —                | ScriptFX editor state: open editors, script content, compilation status.                                               |
| `index.ts`           | —                 | —                | Barrel exports.                                                                                                        |

## Slice Pattern

Each slice follows this pattern:

```typescript theme={null}
export const TransportStateID = 'transport:state';

export interface TransportState {
  bpm: number;
  // ... state fields
  setBpm: (bpm: number) => void;
  // ... actions
}

export const useTransportSlice: StateCreator<TransportState> = (set, get) => ({
  bpm: 120,
  setBpm: (bpm) => set({ bpm }),
});
```

Slices are composed in `store.ts`:

```typescript theme={null}
export const useTransportStore = create<TransportState>()(
  persist((...a) => ({ ...useTransportSlice(...a) }), { name: TransportStateID, ... })
);
```

## Design Principles

* **One slice per domain** — Don't mix mixer state with transport state. Each slice owns one file and one `StateCreator`.
* **Actions inside the slice** — State actions (setters, computed updates) live in the slice, not in components.
* **Integer rounding for mixer** — `setVolume()` and `setPan()` round to integers. This is critical for echo prevention — float precision diffs would cause infinite commit loops.
* **Partial merge for engine updates** — When the engine pushes state via events, use `setState((prev) => ({ ...prev, ...partial }))` to avoid overwriting fields the engine side doesn't know about.
* **`partialize` for persistence** — Use the `partialize` option to exclude transient fields (like `initialized`) from persistence. Only persist what should survive a reload.
