import { defineStore } from 'pinia' import { ref } from 'vue' import { invoke } from '@tauri-apps/api/core' import { listen, type UnlistenFn } from '@tauri-apps/api/event' import { moduleRegistry } from '@/modules/registry' /** 进程状态 */ export type ProcessStatus = 'running' | 'stopped' | 'crashed' | 'starting' /** 进程信息(与 Rust 端 ProcessInfo 对应) */ export interface ProcessInfo { id: string name: string status: ProcessStatus pid: number | null restartCount: number } /** 启动进程参数(与 Rust 端 StartProcessParams 对应,camelCase) */ export interface StartProcessParams { id: string executable: string args?: string[] cwd?: string name: string restartOnCrash?: boolean maxRestarts?: number } export const useProcessStore = defineStore('process', () => { /** 所有已知进程的状态映射(key = 模块 ID) */ const processes = ref>(new Map()) let unlistenFn: UnlistenFn | null = null /** 启动进程监听,接收 Rust 端的进程状态变更事件 */ const initListener = async () => { if (unlistenFn) return unlistenFn = await listen('process-status-changed', (event) => { processes.value.set(event.payload.id, event.payload) }) } /** 释放进程状态事件监听(应用退出或热重载时调用) */ const destroyListener = () => { if (unlistenFn) { unlistenFn() unlistenFn = null } } /** 通过模块 ID 启动进程(自动从注册表读取进程配置) */ const startByModule = async (moduleId: string): Promise => { const config = moduleRegistry.getConfig(moduleId) if (!config?.process) { throw new Error(`模块 "${moduleId}" 没有进程配置`) } const pc = config.process const params: StartProcessParams = { id: moduleId, executable: pc.executable, args: pc.args, cwd: pc.cwd, name: pc.name, restartOnCrash: pc.restartOnCrash, maxRestarts: pc.maxRestarts } const info = await invoke('process_start', { params }) processes.value.set(moduleId, info) return info } /** 通过模块 ID 停止进程 */ const stopByModule = async (moduleId: string): Promise => { await invoke('process_stop', { id: moduleId }) processes.value.delete(moduleId) } /** 获取单个进程状态(从 Rust 端查询最新值) */ const refreshStatus = async (moduleId: string): Promise => { const info = await invoke('process_status', { id: moduleId }) if (info) { processes.value.set(moduleId, info) } else { processes.value.delete(moduleId) } return info } /** 刷新所有进程状态 */ const refreshAll = async (): Promise => { const all = await invoke('process_all_status') processes.value.clear() all.forEach((info) => { processes.value.set(info.id, info) }) } /** 获取进程状态(从本地缓存读取,不触发 Rust 调用) */ const getProcessStatus = (moduleId: string): ProcessInfo | null => { return processes.value.get(moduleId) ?? null } /** 停止所有进程 */ const stopAll = async (): Promise => { await invoke('process_stop_all') processes.value.clear() } return { processes, initListener, destroyListener, startByModule, stopByModule, refreshStatus, refreshAll, getProcessStatus, stopAll } })