import { create } from 'zustand'; import type { Track, VibeSession } from '../types'; import type { VibePlanItem } from '../services/vibeService'; // The durable plan is authoritative. `buffer` is only its currently // uncommitted, hydrated preview; it may be replaced at any feedback boundary. interface VibeState { activeSessionId: string | null; seedTrackId: string | null; planVersion: number | null; /** Durable cursor for the track currently in Vibe playback. */ currentPlanItem: VibePlanItem | null; centerTrack: Track | null; buffer: Track[]; initialBatchStatus: 'idle' | 'loading' | 'exhausted' | 'failed'; setActiveSession: (session: VibeSession | null) => void; setSeedTrackId: (seedTrackId: string | null) => void; setCenterTrack: (track: Track | null) => void; /** Returns false when a response belongs to an older plan revision. */ setPlan: (planVersion: number | null, preview: Track[]) => boolean; setCurrentPlanItem: (item: VibePlanItem | null) => void; setInitialBatchStatus: (status: VibeState['initialBatchStatus']) => void; reset: () => void; } const initialState = { activeSessionId: null as string | null, seedTrackId: null as string | null, planVersion: null as number | null, currentPlanItem: null as VibePlanItem | null, centerTrack: null as Track | null, buffer: [] as Track[], initialBatchStatus: 'idle' as const, }; export const useVibeStore = create((set, get) => ({ ...initialState, setActiveSession: (session) => set( session ? { activeSessionId: session.sessionId, seedTrackId: session.seedTrackId } : { activeSessionId: null, seedTrackId: null }, ), setSeedTrackId: (seedTrackId) => set({ seedTrackId }), setCenterTrack: (centerTrack) => set({ centerTrack }), setPlan: (planVersion, buffer) => { const current = get().planVersion; if (planVersion === null || (current !== null && planVersion < current)) return false; set({ planVersion, buffer }); return true; }, setCurrentPlanItem: (currentPlanItem) => set({ currentPlanItem }), setInitialBatchStatus: (initialBatchStatus) => set({ initialBatchStatus }), reset: () => set({ ...initialState }), }));