OpChan/src/lib/waku/index.ts

165 lines
4.7 KiB
TypeScript
Raw Normal View History

2025-08-30 18:34:50 +05:30
import { HealthStatus } from '@waku/sdk';
import { OpchanMessage } from '@/types/forum';
import { WakuNodeManager, HealthChangeCallback } from './core/WakuNodeManager';
import {
MessageService,
MessageStatusCallback,
2025-09-09 12:31:26 +05:30
MissingMessageCallback,
MissingMessageEvent,
MissingMessageInfo,
2025-08-30 18:34:50 +05:30
} from './services/MessageService';
import { ReliableMessaging } from './core/ReliableMessaging';
2025-09-09 12:31:26 +05:30
export type { HealthChangeCallback, MessageStatusCallback, MissingMessageCallback, MissingMessageEvent, MissingMessageInfo };
class MessageManager {
2025-08-29 17:08:04 +05:30
private nodeManager: WakuNodeManager | null = null;
2025-09-04 13:27:47 +05:30
// LocalDatabase eliminates the need for CacheService
2025-08-29 17:08:04 +05:30
private messageService: MessageService | null = null;
private reliableMessaging: ReliableMessaging | null = null;
2025-09-05 12:53:15 +05:30
constructor() {}
2025-08-29 17:08:04 +05:30
public static async create(): Promise<MessageManager> {
const manager = new MessageManager();
await manager.initialize();
return manager;
}
private async initialize(): Promise<void> {
try {
this.nodeManager = await WakuNodeManager.create();
2025-08-30 18:34:50 +05:30
2025-08-29 17:08:04 +05:30
// Now create message service with proper dependencies
2025-08-30 18:34:50 +05:30
this.messageService = new MessageService(
this.reliableMessaging,
this.nodeManager
);
2025-08-29 17:08:04 +05:30
// Set up health-based reliable messaging initialization
2025-08-30 18:34:50 +05:30
this.nodeManager.onHealthChange(isReady => {
2025-08-29 17:08:04 +05:30
if (isReady && !this.reliableMessaging) {
this.initializeReliableMessaging();
} else if (!isReady && this.reliableMessaging) {
this.cleanupReliableMessaging();
}
2025-08-29 17:08:04 +05:30
});
} catch (error) {
2025-08-30 18:34:50 +05:30
console.error('Failed to initialize MessageManager:', error);
2025-08-29 17:08:04 +05:30
throw error;
}
2025-08-29 17:08:04 +05:30
}
2025-08-29 17:08:04 +05:30
private async initializeReliableMessaging(): Promise<void> {
if (!this.nodeManager || this.reliableMessaging) {
return;
}
2025-08-30 18:34:50 +05:30
try {
console.log('Initializing reliable messaging...');
this.reliableMessaging = new ReliableMessaging(
this.nodeManager.getNode()
);
this.messageService?.updateReliableMessaging(this.reliableMessaging);
console.log('Reliable messaging initialized successfully');
} catch (error) {
console.error('Failed to initialize reliable messaging:', error);
}
2025-08-29 17:08:04 +05:30
}
private cleanupReliableMessaging(): void {
if (this.reliableMessaging) {
2025-08-30 18:34:50 +05:30
console.log('Cleaning up reliable messaging due to health status');
2025-08-29 17:08:04 +05:30
this.reliableMessaging.cleanup();
this.reliableMessaging = null;
this.messageService?.updateReliableMessaging(null);
}
2025-08-29 17:08:04 +05:30
}
2025-08-29 15:43:10 +05:30
2025-08-29 17:08:04 +05:30
public async stop(): Promise<void> {
this.cleanupReliableMessaging();
this.messageService?.cleanup();
await this.nodeManager?.stop();
}
2025-08-29 15:43:10 +05:30
2025-08-29 17:08:04 +05:30
public get isReady(): boolean {
return this.nodeManager?.isReady ?? false;
}
2025-08-29 17:08:04 +05:30
public get currentHealth(): HealthStatus {
return this.nodeManager?.currentHealth ?? HealthStatus.Unhealthy;
}
2025-08-29 17:08:04 +05:30
public onHealthChange(callback: HealthChangeCallback): () => void {
if (!this.nodeManager) {
2025-08-30 18:34:50 +05:30
throw new Error('Node manager not initialized');
}
2025-08-29 17:08:04 +05:30
return this.nodeManager.onHealthChange(callback);
}
//TODO: return event handlers?
2025-08-30 18:34:50 +05:30
public async sendMessage(
message: OpchanMessage,
statusCallback?: MessageStatusCallback
): Promise<void> {
2025-08-29 17:08:04 +05:30
if (!this.messageService) {
2025-08-30 18:34:50 +05:30
throw new Error('MessageManager not fully initialized');
2025-08-29 15:43:10 +05:30
}
this.messageService.sendMessage(message, statusCallback);
2025-08-29 17:08:04 +05:30
}
2025-08-29 15:43:10 +05:30
2025-08-30 18:34:50 +05:30
public onMessageReceived(
callback: (message: OpchanMessage) => void
): () => void {
2025-08-29 17:08:04 +05:30
if (!this.messageService) {
2025-08-30 18:34:50 +05:30
throw new Error('MessageManager not fully initialized');
}
2025-08-29 17:08:04 +05:30
return this.messageService.onMessageReceived(callback);
}
2025-09-09 12:31:26 +05:30
public onMissingMessage(callback: MissingMessageCallback): () => void {
if (!this.messageService) {
throw new Error('MessageManager not fully initialized');
}
return this.messageService.onMissingMessage(callback);
}
public getMissingMessages(): MissingMessageInfo[] {
if (!this.messageService) {
return [];
}
return this.messageService.getMissingMessages();
}
public getRecoveredMessages(): string[] {
if (!this.messageService) {
return [];
}
return this.messageService.getRecoveredMessages();
}
public getMissingMessageCount(): number {
if (!this.messageService) {
return 0;
}
return this.messageService.getMissingMessageCount();
}
public getRecoveredMessageCount(): number {
if (!this.messageService) {
return 0;
}
return this.messageService.getRecoveredMessageCount();
}
2025-08-29 17:08:04 +05:30
public get messageCache() {
if (!this.messageService) {
2025-08-30 18:34:50 +05:30
throw new Error('MessageManager not fully initialized');
2025-04-16 15:40:20 +05:30
}
2025-08-29 17:08:04 +05:30
return this.messageService.messageCache;
}
}
const messageManager = await MessageManager.create();
export default messageManager;