import { defineStore } from 'pinia' import { FileGraph, FileObject } from '@linux-odyssey/file-graph' import { IQuest } from '@linux-odyssey/models' import { createSession, getQuest, getSessions } from '../utils/api' import Socket from '../utils/socket' import SocketTerminal from '../utils/terminal' import { Session, StageResponse } from '../types' const socket = new Socket() const term = new SocketTerminal(40, 80) interface Store { session: Session questId: string quest: IQuest | null } const useSession = defineStore('session', { state: (): Store => ({ session: { _id: '', status: 'inactive', graph: new FileGraph({ path: '/', type: 'folder', discovered: false, }), pwd: '', hints: [], tasks: [], responses: [], }, questId: '', quest: null, }), actions: { async setQuest(questId: string) { this.quest = await getQuest(questId) this.questId = questId }, async setSession(session: Session) { this.session = session this.session.graph = new FileGraph(session.graph) term.reset() await socket.connect(session) term.focus() }, async createSession() { const session = await createSession(this.questId) this.setSession(session) }, async getActiveSession() { const sessions = await getSessions({ questId: this.questId, limit: 1, order: 'desc', status: 'active', }) if (sessions.length > 0) { this.setSession(sessions[0]) return true } return false }, updateGraph(event: { discover?: FileObject[]; pwd?: string }) { if (event.discover) { this.session.graph.discover(event.discover) } if (event.pwd) { this.session.pwd = event.pwd } }, newResponse(response: StageResponse) { this.session.responses.push(response.responses) this.session.hints.push(response.hints) this.session.tasks = response.tasks this.session.status = response.status }, reset() { socket.reset() term.reset() this.$reset() }, setup() { socket.on('terminal', (data: string) => { term.write(data) }) term.onData((data: string) => { socket.emit('terminal', data) }) socket.on('graph', (event: { discover: FileObject[]; pwd: string }) => { this.updateGraph(event) }) socket.on('response', (response: StageResponse) => { this.newResponse(response) }) }, }, }) export function useTerminal() { return term } // export async function init(questId: string) { // if (!questId) throw new Error('No quest ID provided') // reset() // try { // await setQuest(questId) // } catch (err) { // console.error(err) // throw new LoadQuestError('Failed to load quest', questId) // } // try { // await getActiveSession(questId) // } catch (err) { // console.error(err) // throw new LoadSessionError('Failed to load session', questId) // } // } export default useSession