2025-08-30 18:34:50 +05:30
|
|
|
import { IDecodedMessage, IDecoder, IEncoder, LightNode } from '@waku/sdk';
|
2025-08-29 17:08:04 +05:30
|
|
|
import { MessageType } from '../../types/waku';
|
2025-08-29 16:30:19 +05:30
|
|
|
import {
|
|
|
|
|
CellMessage,
|
|
|
|
|
PostMessage,
|
|
|
|
|
CommentMessage,
|
|
|
|
|
VoteMessage,
|
2025-08-29 17:08:04 +05:30
|
|
|
} from '../../types/waku';
|
2025-08-29 16:30:19 +05:30
|
|
|
import { CONTENT_TOPICS } from './constants';
|
2025-08-29 14:53:02 +05:30
|
|
|
import { OpchanMessage } from '@/types/forum';
|
2025-04-16 14:45:27 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
export class CodecManager {
|
|
|
|
|
private encoders: Map<MessageType, IEncoder> = new Map();
|
|
|
|
|
private decoders: Map<MessageType, IDecoder<IDecodedMessage>> = new Map();
|
2025-08-29 15:43:10 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
constructor(private node: LightNode) {
|
|
|
|
|
this.encoders = new Map(
|
2025-08-30 18:34:50 +05:30
|
|
|
Object.values(MessageType).map(type => [
|
2025-08-29 16:30:19 +05:30
|
|
|
type,
|
|
|
|
|
this.node.createEncoder({ contentTopic: CONTENT_TOPICS[type] }),
|
|
|
|
|
])
|
|
|
|
|
);
|
2025-04-16 14:45:27 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
this.decoders = new Map(
|
2025-08-30 18:34:50 +05:30
|
|
|
Object.values(MessageType).map(type => [
|
2025-08-29 16:30:19 +05:30
|
|
|
type,
|
|
|
|
|
this.node.createDecoder({ contentTopic: CONTENT_TOPICS[type] }),
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-04-16 14:08:26 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
/**
|
|
|
|
|
* Encode a message for transmission
|
|
|
|
|
*/
|
|
|
|
|
encodeMessage(message: OpchanMessage): Uint8Array {
|
|
|
|
|
const messageJson = JSON.stringify(message);
|
|
|
|
|
return new TextEncoder().encode(messageJson);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Decode a received message
|
|
|
|
|
*/
|
|
|
|
|
decodeMessage(payload: Uint8Array): OpchanMessage {
|
|
|
|
|
const messageJson = new TextDecoder().decode(payload);
|
|
|
|
|
const message = JSON.parse(messageJson) as OpchanMessage;
|
|
|
|
|
|
|
|
|
|
switch (message.type) {
|
|
|
|
|
case MessageType.CELL:
|
|
|
|
|
return message as CellMessage;
|
|
|
|
|
case MessageType.POST:
|
|
|
|
|
return message as PostMessage;
|
|
|
|
|
case MessageType.COMMENT:
|
|
|
|
|
return message as CommentMessage;
|
|
|
|
|
case MessageType.VOTE:
|
|
|
|
|
return message as VoteMessage;
|
|
|
|
|
default:
|
|
|
|
|
throw new Error(`Unknown message type: ${message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get encoder for a specific message type
|
|
|
|
|
*/
|
|
|
|
|
getEncoder(messageType: MessageType): IEncoder {
|
|
|
|
|
const encoder = this.encoders.get(messageType);
|
|
|
|
|
if (!encoder) {
|
|
|
|
|
throw new Error(`No encoder found for message type: ${messageType}`);
|
|
|
|
|
}
|
|
|
|
|
return encoder;
|
|
|
|
|
}
|
2025-04-16 14:08:26 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
/**
|
|
|
|
|
* Get decoder for a specific message type
|
|
|
|
|
*/
|
2025-08-30 18:34:50 +05:30
|
|
|
getDecoder(messageType: MessageType): IDecoder<IDecodedMessage> {
|
2025-08-29 16:30:19 +05:30
|
|
|
const decoder = this.decoders.get(messageType);
|
|
|
|
|
if (!decoder) {
|
|
|
|
|
throw new Error(`No decoder found for message type: ${messageType}`);
|
|
|
|
|
}
|
|
|
|
|
return decoder;
|
|
|
|
|
}
|
2025-04-16 14:08:26 +05:30
|
|
|
|
2025-08-29 16:30:19 +05:30
|
|
|
/**
|
|
|
|
|
* Get all decoders for subscribing to multiple message types
|
|
|
|
|
*/
|
|
|
|
|
getAllDecoders(): IDecoder<IDecodedMessage>[] {
|
|
|
|
|
return Array.from(this.decoders.values());
|
2025-04-22 10:39:32 +05:30
|
|
|
}
|
2025-08-29 16:30:19 +05:30
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get decoders for specific message types
|
|
|
|
|
*/
|
2025-08-30 18:34:50 +05:30
|
|
|
getDecoders(messageTypes: MessageType[]): IDecoder<IDecodedMessage>[] {
|
|
|
|
|
return messageTypes.map(type => this.getDecoder(type));
|
2025-08-29 16:30:19 +05:30
|
|
|
}
|
|
|
|
|
}
|