mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-04 05:43:10 +00:00
chore: simplify encoders/decoders
This commit is contained in:
parent
907b5f8c5f
commit
991e5cedc5
@ -336,6 +336,7 @@ export const moderatePost = async (
|
|||||||
|
|
||||||
const modMsg: ModerateMessage = {
|
const modMsg: ModerateMessage = {
|
||||||
type: MessageType.MODERATE,
|
type: MessageType.MODERATE,
|
||||||
|
id: uuidv4(),
|
||||||
cellId,
|
cellId,
|
||||||
targetType: 'post',
|
targetType: 'post',
|
||||||
targetId: postId,
|
targetId: postId,
|
||||||
@ -386,6 +387,7 @@ export const moderateComment = async (
|
|||||||
|
|
||||||
const modMsg: ModerateMessage = {
|
const modMsg: ModerateMessage = {
|
||||||
type: MessageType.MODERATE,
|
type: MessageType.MODERATE,
|
||||||
|
id: uuidv4(),
|
||||||
cellId,
|
cellId,
|
||||||
targetType: 'comment',
|
targetType: 'comment',
|
||||||
targetId: commentId,
|
targetId: commentId,
|
||||||
@ -433,6 +435,7 @@ export const moderateUser = async (
|
|||||||
|
|
||||||
const modMsg: ModerateMessage = {
|
const modMsg: ModerateMessage = {
|
||||||
type: MessageType.MODERATE,
|
type: MessageType.MODERATE,
|
||||||
|
id: uuidv4(),
|
||||||
cellId,
|
cellId,
|
||||||
targetType: 'user',
|
targetType: 'user',
|
||||||
targetId: userAddress,
|
targetId: userAddress,
|
||||||
|
|||||||
@ -1,70 +1,105 @@
|
|||||||
import { createDecoder, createEncoder } from '@waku/sdk';
|
import {
|
||||||
|
IDecodedMessage,
|
||||||
|
IDecoder,
|
||||||
|
IEncoder,
|
||||||
|
LightNode,
|
||||||
|
} from '@waku/sdk';
|
||||||
import { MessageType } from './types';
|
import { MessageType } from './types';
|
||||||
import { CellMessage, PostMessage, CommentMessage, VoteMessage } from './types';
|
import {
|
||||||
import { CONTENT_TOPICS, NETWORK_CONFIG } from './constants';
|
CellMessage,
|
||||||
|
PostMessage,
|
||||||
|
CommentMessage,
|
||||||
|
VoteMessage,
|
||||||
|
} from './types';
|
||||||
|
import { CONTENT_TOPICS } from './constants';
|
||||||
import { OpchanMessage } from '@/types/forum';
|
import { OpchanMessage } from '@/types/forum';
|
||||||
|
|
||||||
// Create the sharded pubsub topic
|
export class CodecManager {
|
||||||
const PUBSUB_TOPIC = `/waku/2/rs/${NETWORK_CONFIG.clusterId}/0`;
|
private encoders: Map<MessageType, IEncoder> = new Map();
|
||||||
|
private decoders: Map<MessageType, IDecoder<IDecodedMessage>> = new Map();
|
||||||
|
|
||||||
export const encoders = {
|
constructor(private node: LightNode) {
|
||||||
[MessageType.CELL]: createEncoder({
|
this.encoders = new Map(
|
||||||
contentTopic: CONTENT_TOPICS[MessageType.CELL],
|
Object.values(MessageType).map((type) => [
|
||||||
routingInfo: { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }
|
type,
|
||||||
}),
|
this.node.createEncoder({ contentTopic: CONTENT_TOPICS[type] }),
|
||||||
[MessageType.POST]: createEncoder({
|
])
|
||||||
contentTopic: CONTENT_TOPICS[MessageType.POST],
|
);
|
||||||
routingInfo: { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }
|
|
||||||
}),
|
|
||||||
[MessageType.COMMENT]: createEncoder({
|
|
||||||
contentTopic: CONTENT_TOPICS[MessageType.COMMENT],
|
|
||||||
routingInfo: { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }
|
|
||||||
}),
|
|
||||||
[MessageType.VOTE]: createEncoder({
|
|
||||||
contentTopic: CONTENT_TOPICS[MessageType.VOTE],
|
|
||||||
routingInfo: { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }
|
|
||||||
}),
|
|
||||||
[MessageType.MODERATE]: createEncoder({
|
|
||||||
contentTopic: CONTENT_TOPICS[MessageType.MODERATE],
|
|
||||||
routingInfo: { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const decoders = {
|
this.decoders = new Map(
|
||||||
[MessageType.CELL]: createDecoder(CONTENT_TOPICS[MessageType.CELL], { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }),
|
Object.values(MessageType).map((type) => [
|
||||||
[MessageType.POST]: createDecoder(CONTENT_TOPICS[MessageType.POST], { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }),
|
type,
|
||||||
[MessageType.COMMENT]: createDecoder(CONTENT_TOPICS[MessageType.COMMENT], { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }),
|
this.node.createDecoder({ contentTopic: CONTENT_TOPICS[type] }),
|
||||||
[MessageType.VOTE]: createDecoder(CONTENT_TOPICS[MessageType.VOTE], { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC }),
|
])
|
||||||
[MessageType.MODERATE]: createDecoder(CONTENT_TOPICS[MessageType.MODERATE], { clusterId: NETWORK_CONFIG.clusterId, shardId: 0, pubsubTopic: PUBSUB_TOPIC })
|
);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode a message object into a Uint8Array for transmission
|
|
||||||
*/
|
|
||||||
export function encodeMessage(message: OpchanMessage): Uint8Array {
|
|
||||||
const messageJson = JSON.stringify(message);
|
|
||||||
return new TextEncoder().encode(messageJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode a message from a Uint8Array based on its type
|
|
||||||
*/
|
|
||||||
export function 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}`);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get decoder for a specific message type
|
||||||
|
*/
|
||||||
|
getDecoder(
|
||||||
|
messageType: MessageType
|
||||||
|
): IDecoder<IDecodedMessage> {
|
||||||
|
const decoder = this.decoders.get(messageType);
|
||||||
|
if (!decoder) {
|
||||||
|
throw new Error(`No decoder found for message type: ${messageType}`);
|
||||||
|
}
|
||||||
|
return decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all decoders for subscribing to multiple message types
|
||||||
|
*/
|
||||||
|
getAllDecoders(): IDecoder<IDecodedMessage>[] {
|
||||||
|
return Array.from(this.decoders.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get decoders for specific message types
|
||||||
|
*/
|
||||||
|
getDecoders(
|
||||||
|
messageTypes: MessageType[]
|
||||||
|
): IDecoder<IDecodedMessage>[] {
|
||||||
|
return messageTypes.map((type) => this.getDecoder(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -11,12 +11,6 @@ export const CONTENT_TOPICS: Record<MessageType, string> = {
|
|||||||
[MessageType.MODERATE]: '/opchan-sds/1/moderate/proto'
|
[MessageType.MODERATE]: '/opchan-sds/1/moderate/proto'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NETWORK_CONFIG = {
|
|
||||||
// contentTopics: Object.values(CONTENT_TOPICS),
|
|
||||||
clusterId: 1,
|
|
||||||
shards: [0,1,2,3,4,5,6,7]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bootstrap nodes for the Waku network
|
* Bootstrap nodes for the Waku network
|
||||||
* These are public Waku nodes that our node will connect to on startup
|
* These are public Waku nodes that our node will connect to on startup
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { CommentCache, MessageType, VoteCache, ModerateMessage } from "./types";
|
|||||||
import { PostCache } from "./types";
|
import { PostCache } from "./types";
|
||||||
import { CellCache } from "./types";
|
import { CellCache } from "./types";
|
||||||
import { OpchanMessage } from "@/types/forum";
|
import { OpchanMessage } from "@/types/forum";
|
||||||
import { NETWORK_CONFIG } from "./constants";
|
|
||||||
import { ReliableMessageManager } from "./reliable_channel";
|
import { ReliableMessageManager } from "./reliable_channel";
|
||||||
|
|
||||||
export type HealthChangeCallback = (isReady: boolean, health: HealthStatus) => void;
|
export type HealthChangeCallback = (isReady: boolean, health: HealthStatus) => void;
|
||||||
@ -37,7 +36,6 @@ class MessageManager {
|
|||||||
public static async create(): Promise<MessageManager> {
|
public static async create(): Promise<MessageManager> {
|
||||||
const node = await createLightNode({
|
const node = await createLightNode({
|
||||||
defaultBootstrap: true,
|
defaultBootstrap: true,
|
||||||
networkConfig: NETWORK_CONFIG,
|
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { IDecodedMessage, LightNode, ReliableChannel, ReliableChannelEvent } from "@waku/sdk";
|
import { IDecodedMessage, LightNode, ReliableChannel, ReliableChannelEvent } from "@waku/sdk";
|
||||||
import { MessageType } from "./types";
|
import { MessageType } from "./types";
|
||||||
import { decodeMessage, decoders, encodeMessage, encoders } from "./codec";
|
import { CodecManager } from "./codec";
|
||||||
import { generateStringId } from "@/lib/utils";
|
import { generateStringId } from "@/lib/utils";
|
||||||
import { OpchanMessage } from "@/types/forum";
|
import { OpchanMessage } from "@/types/forum";
|
||||||
|
|
||||||
@ -18,15 +18,17 @@ export class ReliableMessageManager {
|
|||||||
private channels: Map<MessageType, ReliableChannel<IDecodedMessage>> = new Map();
|
private channels: Map<MessageType, ReliableChannel<IDecodedMessage>> = new Map();
|
||||||
private messageCallbacks: Map<string, MessageStatusCallback> = new Map();
|
private messageCallbacks: Map<string, MessageStatusCallback> = new Map();
|
||||||
private incomingMessageCallbacks: IncomingMessageCallback[] = [];
|
private incomingMessageCallbacks: IncomingMessageCallback[] = [];
|
||||||
|
private codecManager: CodecManager;
|
||||||
|
|
||||||
constructor(node: LightNode) {
|
constructor(node: LightNode) {
|
||||||
|
this.codecManager = new CodecManager(node);
|
||||||
this.initializeChannels(node);
|
this.initializeChannels(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initializeChannels(node: LightNode) {
|
private async initializeChannels(node: LightNode) {
|
||||||
for (const type of Object.values(MessageType)) {
|
for (const type of Object.values(MessageType)) {
|
||||||
const encoder = encoders[type];
|
const encoder = this.codecManager.getEncoder(type);
|
||||||
const decoder = decoders[type];
|
const decoder = this.codecManager.getDecoder(type);
|
||||||
const senderId = generateStringId();
|
const senderId = generateStringId();
|
||||||
const channelId = `opchan-${type}`; // Unique channel ID for each message type
|
const channelId = `opchan-${type}`; // Unique channel ID for each message type
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ export class ReliableMessageManager {
|
|||||||
try {
|
try {
|
||||||
const wakuMessage = event.detail;
|
const wakuMessage = event.detail;
|
||||||
if (wakuMessage.payload) {
|
if (wakuMessage.payload) {
|
||||||
const opchanMessage = decodeMessage(wakuMessage.payload);
|
const opchanMessage = this.codecManager.decodeMessage(wakuMessage.payload);
|
||||||
|
|
||||||
|
|
||||||
this.incomingMessageCallbacks.forEach(callback => {
|
this.incomingMessageCallbacks.forEach(callback => {
|
||||||
@ -92,7 +94,7 @@ export class ReliableMessageManager {
|
|||||||
throw new Error(`No reliable channel for message type: ${message.type}`);
|
throw new Error(`No reliable channel for message type: ${message.type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const encodedMessage = encodeMessage(message);
|
const encodedMessage = this.codecManager.encodeMessage(message);
|
||||||
const messageId = ReliableChannel.getMessageId(encodedMessage);
|
const messageId = ReliableChannel.getMessageId(encodedMessage);
|
||||||
|
|
||||||
// Store callback for this message
|
// Store callback for this message
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user