Files
vue-desktop/src/apps/AppRegistry.ts

97 lines
2.3 KiB
TypeScript
Raw Normal View History

2025-09-24 16:43:10 +08:00
import type { AppRegistration } from './types/AppManifest'
import { reactive, markRaw } from 'vue'
/**
*
*
*/
export class AppRegistry {
private static instance: AppRegistry | null = null
private apps = reactive(new Map<string, AppRegistration>())
private constructor() {}
static getInstance(): AppRegistry {
if (!AppRegistry.instance) {
AppRegistry.instance = new AppRegistry()
}
return AppRegistry.instance
}
/**
*
*/
registerApp(registration: AppRegistration): void {
// 使用 markRaw 标记组件,避免被设为响应式
const safeRegistration = {
...registration,
component: registration.component ? markRaw(registration.component) : registration.component
}
this.apps.set(registration.manifest.id, safeRegistration)
console.log(`已注册内置应用: ${registration.manifest.name}`)
}
/**
*
*/
getApp(appId: string): AppRegistration | undefined {
return this.apps.get(appId)
}
/**
*
*/
getAllApps(): AppRegistration[] {
return Array.from(this.apps.values())
}
/**
*
*/
getBuiltInApps(): AppRegistration[] {
return Array.from(this.apps.values()).filter(app => app.isBuiltIn)
}
/**
*
*/
hasApp(appId: string): boolean {
return this.apps.has(appId)
}
/**
*
*/
getAppsByCategory(category: string): AppRegistration[] {
return Array.from(this.apps.values()).filter(
app => app.manifest.category === category
)
}
/**
*
*/
searchApps(query: string): AppRegistration[] {
const lowercaseQuery = query.toLowerCase()
return Array.from(this.apps.values()).filter(app => {
const manifest = app.manifest
return (
manifest.name.toLowerCase().includes(lowercaseQuery) ||
manifest.description.toLowerCase().includes(lowercaseQuery) ||
manifest.keywords?.some(keyword =>
keyword.toLowerCase().includes(lowercaseQuery)
)
)
})
}
/**
*
*/
clear(): void {
this.apps.clear()
}
}
// 导出单例实例
export const appRegistry = AppRegistry.getInstance()