Implement modular architecture with core services and Nostr integration
- Introduce a modular application structure with a new app configuration file to manage module settings and features. - Implement a dependency injection container for service management across modules. - Create a plugin manager to handle module registration, installation, and lifecycle management. - Develop a global event bus for inter-module communication, enhancing loose coupling between components. - Add core modules including base functionalities, Nostr feed, and PWA services, with support for dynamic loading and configuration. - Establish a Nostr client hub for managing WebSocket connections and event handling. - Enhance user experience with a responsive Nostr feed component, integrating admin announcements and community posts. - Refactor existing components to align with the new modular architecture, improving maintainability and scalability.
This commit is contained in:
parent
2d8215a35e
commit
519a9003d4
16 changed files with 2520 additions and 14 deletions
157
src/app.ts
Normal file
157
src/app.ts
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { createPinia } from 'pinia'
|
||||
// Core plugin system
|
||||
import { pluginManager } from './core/plugin-manager'
|
||||
import { eventBus } from './core/event-bus'
|
||||
import { container, SERVICE_TOKENS } from './core/di-container'
|
||||
|
||||
// App configuration
|
||||
import appConfig from './app.config'
|
||||
|
||||
// Base modules
|
||||
import baseModule from './modules/base'
|
||||
import nostrFeedModule from './modules/nostr-feed'
|
||||
|
||||
// Root component
|
||||
import App from './App.vue'
|
||||
|
||||
// Styles
|
||||
import './assets/index.css'
|
||||
|
||||
// Use existing i18n setup
|
||||
import { i18n } from './i18n'
|
||||
|
||||
/**
|
||||
* Initialize and start the modular application
|
||||
*/
|
||||
export async function createAppInstance() {
|
||||
console.log('🚀 Starting modular application...')
|
||||
|
||||
// Create Vue app
|
||||
const app = createApp(App)
|
||||
|
||||
// Create router
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
// Default route - will be populated by modules
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('./pages/Home.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('./pages/LoginDemo.vue'),
|
||||
meta: { requiresAuth: false }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// Use existing i18n setup
|
||||
|
||||
// Create Pinia store
|
||||
const pinia = createPinia()
|
||||
|
||||
// Install core plugins
|
||||
app.use(router)
|
||||
app.use(pinia)
|
||||
app.use(i18n)
|
||||
|
||||
// Initialize plugin manager
|
||||
pluginManager.init(app, router)
|
||||
|
||||
// Register modules based on configuration
|
||||
const moduleRegistrations = []
|
||||
|
||||
// Register base module first (required)
|
||||
if (appConfig.modules.base.enabled) {
|
||||
moduleRegistrations.push(
|
||||
pluginManager.register(baseModule, appConfig.modules.base)
|
||||
)
|
||||
}
|
||||
|
||||
// Register nostr-feed module
|
||||
if (appConfig.modules['nostr-feed'].enabled) {
|
||||
moduleRegistrations.push(
|
||||
pluginManager.register(nostrFeedModule, appConfig.modules['nostr-feed'])
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Register other modules as they're converted
|
||||
// - market module
|
||||
// - chat module
|
||||
// - events module
|
||||
|
||||
// Wait for all modules to register
|
||||
await Promise.all(moduleRegistrations)
|
||||
|
||||
// Install all enabled modules
|
||||
await pluginManager.installAll()
|
||||
|
||||
// Set up auth guard
|
||||
router.beforeEach(async (to, _from, next) => {
|
||||
const authService = container.inject(SERVICE_TOKENS.AUTH_SERVICE) as any
|
||||
|
||||
if (to.meta.requiresAuth && authService && !authService.isAuthenticated?.value) {
|
||||
next('/login')
|
||||
} else if (to.path === '/login' && authService && authService.isAuthenticated?.value) {
|
||||
next('/')
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
// Global error handling
|
||||
app.config.errorHandler = (err, _vm, info) => {
|
||||
console.error('Global error:', err, info)
|
||||
eventBus.emit('app:error', { error: err, info }, 'app')
|
||||
}
|
||||
|
||||
// Development helpers
|
||||
if (appConfig.features.developmentMode) {
|
||||
// Expose debugging helpers globally
|
||||
;(window as any).__pluginManager = pluginManager
|
||||
;(window as any).__eventBus = eventBus
|
||||
;(window as any).__container = container
|
||||
|
||||
console.log('🔧 Development mode enabled')
|
||||
console.log('Available globals: __pluginManager, __eventBus, __container')
|
||||
}
|
||||
|
||||
console.log('✅ Application initialized successfully')
|
||||
|
||||
return { app, router }
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the application
|
||||
*/
|
||||
export async function startApp() {
|
||||
try {
|
||||
const { app } = await createAppInstance()
|
||||
|
||||
// Mount the app
|
||||
app.mount('#app')
|
||||
|
||||
console.log('🎉 Application started!')
|
||||
|
||||
// Emit app started event
|
||||
eventBus.emit('app:started', {}, 'app')
|
||||
|
||||
} catch (error) {
|
||||
console.error('💥 Failed to start application:', error)
|
||||
|
||||
// Show error to user
|
||||
document.getElementById('app')!.innerHTML = `
|
||||
<div style="padding: 20px; text-align: center; color: red;">
|
||||
<h1>Application Failed to Start</h1>
|
||||
<p>${error instanceof Error ? error.message : 'Unknown error'}</p>
|
||||
<p>Please refresh the page or contact support.</p>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue