File size: 3,322 Bytes
f56a29b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /**
* Stage API - Navigation
*
* Factory function that creates the navigation namespace of the Stage API.
* Handles scene navigation (goTo, next, previous, current).
*/
import type { Scene } from '@/lib/types/stage';
import type { StageStore, APIResult } from './stage-api-types';
import { validateSceneId, getScene } from './stage-api-defaults';
/**
* Create the navigation API
*
* @param store - Zustand store instance
* @returns Navigation namespace API
*/
export function createNavigationAPI(store: StageStore) {
return {
/**
* Navigate to a specific scene
*
* @param sceneId - Scene ID
* @returns Whether successful
*/
goTo(sceneId: string): APIResult<boolean> {
try {
const state = store.getState();
if (!validateSceneId(state.scenes, sceneId)) {
return { success: false, error: `Scene not found: ${sceneId}` };
}
store.setState({ currentSceneId: sceneId });
return { success: true, data: true };
} catch (error) {
return { success: false, error: String(error) };
}
},
/**
* Next scene
*
* @returns Whether successful
*/
next(): APIResult<boolean> {
try {
const state = store.getState();
if (!state.currentSceneId || state.scenes.length === 0) {
return { success: false, error: 'No current scene' };
}
const currentIndex = state.scenes.findIndex((s) => s.id === state.currentSceneId);
if (currentIndex === -1 || currentIndex === state.scenes.length - 1) {
return { success: false, error: 'Already at last scene' };
}
const nextScene = state.scenes[currentIndex + 1];
store.setState({ currentSceneId: nextScene.id });
return { success: true, data: true };
} catch (error) {
return { success: false, error: String(error) };
}
},
/**
* Previous scene
*
* @returns Whether successful
*/
previous(): APIResult<boolean> {
try {
const state = store.getState();
if (!state.currentSceneId || state.scenes.length === 0) {
return { success: false, error: 'No current scene' };
}
const currentIndex = state.scenes.findIndex((s) => s.id === state.currentSceneId);
if (currentIndex === -1 || currentIndex === 0) {
return { success: false, error: 'Already at first scene' };
}
const prevScene = state.scenes[currentIndex - 1];
store.setState({ currentSceneId: prevScene.id });
return { success: true, data: true };
} catch (error) {
return { success: false, error: String(error) };
}
},
/**
* Get the current scene
*
* @returns Current scene
*/
current(): APIResult<Scene> {
try {
const state = store.getState();
if (!state.currentSceneId) {
return { success: false, error: 'No current scene' };
}
const scene = getScene(state.scenes, state.currentSceneId);
if (!scene) {
return { success: false, error: 'Current scene not found' };
}
return { success: true, data: scene };
} catch (error) {
return { success: false, error: String(error) };
}
},
};
}
|