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
137
src/core/di-container.ts
Normal file
137
src/core/di-container.ts
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import type { DIContainer, ServiceToken } from './types'
|
||||
|
||||
interface ServiceRegistration {
|
||||
service: any
|
||||
scope: 'singleton' | 'transient'
|
||||
instance?: any
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependency Injection Container
|
||||
* Manages service registration and injection across modules
|
||||
*/
|
||||
export class DIContainerImpl implements DIContainer {
|
||||
private services = new Map<ServiceToken, ServiceRegistration>()
|
||||
|
||||
/**
|
||||
* Register a service in the container
|
||||
*/
|
||||
provide<T>(token: ServiceToken, service: T, scope: 'singleton' | 'transient' = 'singleton'): void {
|
||||
this.services.set(token, {
|
||||
service,
|
||||
scope,
|
||||
instance: scope === 'singleton' ? service : undefined
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a service from the container
|
||||
*/
|
||||
inject<T>(token: ServiceToken): T | undefined {
|
||||
const registration = this.services.get(token)
|
||||
|
||||
if (!registration) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (registration.scope === 'singleton') {
|
||||
return registration.instance as T
|
||||
}
|
||||
|
||||
// For transient services, create new instance
|
||||
// Note: This assumes the service is a constructor function
|
||||
if (typeof registration.service === 'function') {
|
||||
try {
|
||||
return new registration.service() as T
|
||||
} catch (error) {
|
||||
console.error(`Error creating transient service for token ${String(token)}:`, error)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
return registration.service as T
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a service from the container
|
||||
*/
|
||||
remove(token: ServiceToken): boolean {
|
||||
return this.services.delete(token)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all services
|
||||
*/
|
||||
clear(): void {
|
||||
this.services.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered service tokens
|
||||
*/
|
||||
getRegisteredTokens(): ServiceToken[] {
|
||||
return Array.from(this.services.keys())
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a service is registered
|
||||
*/
|
||||
has(token: ServiceToken): boolean {
|
||||
return this.services.has(token)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service registration info
|
||||
*/
|
||||
getServiceInfo(token: ServiceToken): { scope: string; hasInstance: boolean } | undefined {
|
||||
const registration = this.services.get(token)
|
||||
if (!registration) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
scope: registration.scope,
|
||||
hasInstance: registration.instance !== undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global DI container instance
|
||||
export const container = new DIContainerImpl()
|
||||
|
||||
// Service token constants
|
||||
export const SERVICE_TOKENS = {
|
||||
// Core services
|
||||
EVENT_BUS: Symbol('eventBus'),
|
||||
ROUTER: Symbol('router'),
|
||||
|
||||
// Nostr services
|
||||
RELAY_HUB: Symbol('relayHub'),
|
||||
NOSTR_CLIENT_HUB: Symbol('nostrClientHub'),
|
||||
|
||||
// Auth services
|
||||
AUTH_SERVICE: Symbol('authService'),
|
||||
|
||||
// Market services
|
||||
MARKET_STORE: Symbol('marketStore'),
|
||||
PAYMENT_MONITOR: Symbol('paymentMonitor'),
|
||||
|
||||
// Chat services
|
||||
CHAT_SERVICE: Symbol('chatService'),
|
||||
|
||||
// Events services
|
||||
EVENTS_SERVICE: Symbol('eventsService'),
|
||||
} as const
|
||||
|
||||
// Type-safe injection helpers
|
||||
export function injectService<T>(token: ServiceToken): T {
|
||||
const service = container.inject<T>(token)
|
||||
if (!service) {
|
||||
throw new Error(`Service not found for token: ${String(token)}`)
|
||||
}
|
||||
return service
|
||||
}
|
||||
|
||||
export function tryInjectService<T>(token: ServiceToken): T | undefined {
|
||||
return container.inject<T>(token)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue