57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
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<VibeState>((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 }),
|
|
}));
|