- Introduced ProfileService to handle user profiles, including fetching and displaying profile information. - Updated NostrFeed module to register ProfileService in the DI container and initialize it during installation. - Enhanced NostrFeed.vue to utilize the profiles service for displaying user names alongside posts. - Created useProfiles composable for managing profile-related functionality, including fetching and subscribing to profile updates. These changes improve user engagement by providing richer profile information within the feed, enhancing the overall user experience.
168 lines
No EOL
3.9 KiB
TypeScript
168 lines
No EOL
3.9 KiB
TypeScript
import type { DIContainer, ServiceToken } from './types'
|
|
|
|
export type { 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'),
|
|
|
|
// Auth services
|
|
AUTH_SERVICE: Symbol('authService'),
|
|
|
|
// Payment services
|
|
PAYMENT_SERVICE: Symbol('paymentService'),
|
|
|
|
// Visibility services
|
|
VISIBILITY_SERVICE: Symbol('visibilityService'),
|
|
|
|
// Storage services
|
|
STORAGE_SERVICE: Symbol('storageService'),
|
|
|
|
// Toast services
|
|
TOAST_SERVICE: Symbol('toastService'),
|
|
|
|
// Market services
|
|
MARKET_STORE: Symbol('marketStore'),
|
|
PAYMENT_MONITOR: Symbol('paymentMonitor'),
|
|
|
|
// Chat services
|
|
CHAT_SERVICE: Symbol('chatService'),
|
|
|
|
// Feed services
|
|
FEED_SERVICE: Symbol('feedService'),
|
|
PROFILE_SERVICE: Symbol('profileService'),
|
|
|
|
// Events services
|
|
EVENTS_SERVICE: Symbol('eventsService'),
|
|
|
|
// Invoice services
|
|
INVOICE_SERVICE: Symbol('invoiceService'),
|
|
|
|
// Nostrmarket services
|
|
NOSTRMARKET_SERVICE: Symbol('nostrmarketService'),
|
|
NOSTRMARKET_API: Symbol('nostrmarketAPI'),
|
|
|
|
// Wallet services
|
|
WALLET_SERVICE: Symbol('walletService'),
|
|
WALLET_WEBSOCKET_SERVICE: Symbol('walletWebSocketService'),
|
|
|
|
// API services
|
|
LNBITS_API: Symbol('lnbitsAPI'),
|
|
} 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)
|
|
} |