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:
padreug 2025-09-04 23:43:33 +02:00
parent 2d8215a35e
commit 519a9003d4
16 changed files with 2520 additions and 14 deletions

157
src/app.ts Normal file
View 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>
`
}
}