mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-05 23:33:08 +00:00
add ICodec
This commit is contained in:
parent
0c852e4201
commit
9e7719e519
@ -1,9 +1,11 @@
|
|||||||
export { createEncoder, createDecoder } from "./lib/message/version_0.js";
|
export { createEncoder, createDecoder } from "./lib/message/version_0.js";
|
||||||
|
export { createCodec } from "./lib/message/index.js";
|
||||||
export type {
|
export type {
|
||||||
Encoder,
|
Encoder,
|
||||||
Decoder,
|
Decoder,
|
||||||
DecodedMessage
|
DecodedMessage
|
||||||
} from "./lib/message/version_0.js";
|
} from "./lib/message/version_0.js";
|
||||||
|
export type { Codec } from "./lib/message/index.js";
|
||||||
export * as message from "./lib/message/index.js";
|
export * as message from "./lib/message/index.js";
|
||||||
|
|
||||||
export * as waku_filter from "./lib/filter/index.js";
|
export * as waku_filter from "./lib/filter/index.js";
|
||||||
|
|||||||
76
packages/core/src/lib/message/codec.ts
Normal file
76
packages/core/src/lib/message/codec.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import type {
|
||||||
|
ICodec,
|
||||||
|
IDecodedMessage,
|
||||||
|
IDecoder,
|
||||||
|
IEncoder,
|
||||||
|
IMessage,
|
||||||
|
IMetaSetter,
|
||||||
|
IProtoMessage,
|
||||||
|
IRoutingInfo,
|
||||||
|
PubsubTopic
|
||||||
|
} from "@waku/interfaces";
|
||||||
|
|
||||||
|
import { Decoder, Encoder } from "./version_0.js";
|
||||||
|
|
||||||
|
export class Codec implements ICodec<IDecodedMessage> {
|
||||||
|
private encoder: IEncoder;
|
||||||
|
private decoder: IDecoder<IDecodedMessage>;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
public contentTopic: string,
|
||||||
|
public ephemeral: boolean = false,
|
||||||
|
public routingInfo: IRoutingInfo,
|
||||||
|
public metaSetter?: IMetaSetter
|
||||||
|
) {
|
||||||
|
this.encoder = new Encoder(
|
||||||
|
contentTopic,
|
||||||
|
ephemeral,
|
||||||
|
routingInfo,
|
||||||
|
metaSetter
|
||||||
|
);
|
||||||
|
this.decoder = new Decoder(contentTopic, routingInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get pubsubTopic(): PubsubTopic {
|
||||||
|
return this.routingInfo.pubsubTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
||||||
|
return this.encoder.toWire(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toProtoObj(
|
||||||
|
message: IMessage
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
|
return this.encoder.toProtoObj(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public fromWireToProtoObj(
|
||||||
|
bytes: Uint8Array
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
|
return this.decoder.fromWireToProtoObj(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async fromProtoObj(
|
||||||
|
pubsubTopic: string,
|
||||||
|
proto: IProtoMessage
|
||||||
|
): Promise<IDecodedMessage | undefined> {
|
||||||
|
return this.decoder.fromProtoObj(pubsubTopic, proto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CodecParams = {
|
||||||
|
contentTopic: string;
|
||||||
|
ephemeral: boolean;
|
||||||
|
routingInfo: IRoutingInfo;
|
||||||
|
metaSetter?: IMetaSetter;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createCodec(params: CodecParams): Codec {
|
||||||
|
return new Codec(
|
||||||
|
params.contentTopic,
|
||||||
|
params.ephemeral,
|
||||||
|
params.routingInfo,
|
||||||
|
params.metaSetter
|
||||||
|
);
|
||||||
|
}
|
||||||
2
packages/core/src/lib/message/constants.ts
Normal file
2
packages/core/src/lib/message/constants.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const OneMillion = BigInt(1_000_000);
|
||||||
|
export const Version = 0;
|
||||||
@ -1 +1,3 @@
|
|||||||
export * as version_0 from "./version_0.js";
|
export * as version_0 from "./version_0.js";
|
||||||
|
export { Codec, createCodec } from "./codec.js";
|
||||||
|
export { OneMillion, Version } from "./constants.js";
|
||||||
|
|||||||
@ -16,10 +16,10 @@ import { bytesToHex } from "@waku/utils/bytes";
|
|||||||
|
|
||||||
import { messageHash } from "../message_hash/index.js";
|
import { messageHash } from "../message_hash/index.js";
|
||||||
|
|
||||||
const log = new Logger("message:version-0");
|
import { OneMillion, Version } from "./constants.js";
|
||||||
const OneMillion = BigInt(1_000_000);
|
|
||||||
|
const log = new Logger("message:version-0");
|
||||||
|
|
||||||
export const Version = 0;
|
|
||||||
export { proto };
|
export { proto };
|
||||||
|
|
||||||
export class DecodedMessage implements IDecodedMessage {
|
export class DecodedMessage implements IDecodedMessage {
|
||||||
|
|||||||
@ -111,3 +111,5 @@ export interface IDecoder<T extends IDecodedMessage> {
|
|||||||
proto: IProtoMessage
|
proto: IProtoMessage
|
||||||
) => Promise<T | undefined>;
|
) => Promise<T | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ICodec<T extends IDecodedMessage> = IEncoder & IDecoder<T>;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import type { IFilter } from "./filter.js";
|
|||||||
import type { HealthStatus } from "./health_status.js";
|
import type { HealthStatus } from "./health_status.js";
|
||||||
import type { Libp2p } from "./libp2p.js";
|
import type { Libp2p } from "./libp2p.js";
|
||||||
import type { ILightPush } from "./light_push.js";
|
import type { ILightPush } from "./light_push.js";
|
||||||
import { IDecodedMessage, IDecoder, IEncoder } from "./message.js";
|
import { ICodec, IDecodedMessage, IDecoder, IEncoder } from "./message.js";
|
||||||
import type { Protocols } from "./protocols.js";
|
import type { Protocols } from "./protocols.js";
|
||||||
import type { IRelay } from "./relay.js";
|
import type { IRelay } from "./relay.js";
|
||||||
import type { ShardId } from "./sharding.js";
|
import type { ShardId } from "./sharding.js";
|
||||||
@ -25,6 +25,8 @@ export type CreateEncoderParams = CreateDecoderParams & {
|
|||||||
ephemeral?: boolean;
|
ephemeral?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CreateCodecParams = CreateDecoderParams & CreateEncoderParams;
|
||||||
|
|
||||||
export enum WakuEvent {
|
export enum WakuEvent {
|
||||||
Connection = "waku:connection",
|
Connection = "waku:connection",
|
||||||
Health = "waku:health"
|
Health = "waku:health"
|
||||||
@ -206,6 +208,8 @@ export interface IWaku {
|
|||||||
waitForPeers(protocols?: Protocols[], timeoutMs?: number): Promise<void>;
|
waitForPeers(protocols?: Protocols[], timeoutMs?: number): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated Use {@link createCodec} instead
|
||||||
|
*
|
||||||
* Creates a decoder for Waku messages on a specific content topic.
|
* Creates a decoder for Waku messages on a specific content topic.
|
||||||
*
|
*
|
||||||
* A decoder is used to decode messages from the Waku network format.
|
* A decoder is used to decode messages from the Waku network format.
|
||||||
@ -235,6 +239,8 @@ export interface IWaku {
|
|||||||
createDecoder(params: CreateDecoderParams): IDecoder<IDecodedMessage>;
|
createDecoder(params: CreateDecoderParams): IDecoder<IDecodedMessage>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated Use {@link createCodec} instead
|
||||||
|
*
|
||||||
* Creates an encoder for Waku messages on a specific content topic.
|
* Creates an encoder for Waku messages on a specific content topic.
|
||||||
*
|
*
|
||||||
* An encoder is used to encode messages into the Waku network format.
|
* An encoder is used to encode messages into the Waku network format.
|
||||||
@ -264,6 +270,36 @@ export interface IWaku {
|
|||||||
*/
|
*/
|
||||||
createEncoder(params: CreateEncoderParams): IEncoder;
|
createEncoder(params: CreateEncoderParams): IEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a codec for Waku messages on a specific content topic.
|
||||||
|
*
|
||||||
|
* A codec is used to encode and decode messages from the Waku network format.
|
||||||
|
* The codec automatically handles shard configuration based on the Waku node's network settings.
|
||||||
|
*
|
||||||
|
* @param {CreateCodecParams} params - Configuration for the codec including content topic and optionally shard information and ephemeral flag
|
||||||
|
* @returns {ICodec<IDecodedMessage>} A codec instance configured for the specified content topic
|
||||||
|
* @throws {Error} If the shard configuration is incompatible with the node's network settings
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // Create a codec with default network shard settings
|
||||||
|
* const codec = waku.createCodec({
|
||||||
|
* contentTopic: "/my-app/1/chat/proto"
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // Create a codec with custom shard settings
|
||||||
|
* const customCodec = waku.createCodec({
|
||||||
|
* contentTopic: "/my-app/1/chat/proto",
|
||||||
|
* ephemeral: true,
|
||||||
|
* shardInfo: {
|
||||||
|
* clusterId: 1,
|
||||||
|
* shard: 5
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
createCodec(params: CreateCodecParams): ICodec<IDecodedMessage>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {boolean} `true` if the node was started and `false` otherwise
|
* @returns {boolean} `true` if the node was started and `false` otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export function toRLNSignal(contentTopic: string, msg: IMessage): Uint8Array {
|
|||||||
|
|
||||||
export class RlnMessage<T extends IDecodedMessage> implements IRlnMessage {
|
export class RlnMessage<T extends IDecodedMessage> implements IRlnMessage {
|
||||||
public pubsubTopic = "";
|
public pubsubTopic = "";
|
||||||
public version = message.version_0.Version;
|
public version = message.Version;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private rlnInstance: RLNInstance,
|
private rlnInstance: RLNInstance,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { IDecodedMessage, IFilter, IStore } from "@waku/interfaces";
|
import { ICodec, IDecodedMessage, IFilter, IStore } from "@waku/interfaces";
|
||||||
|
|
||||||
import { MessageStore } from "./message_store.js";
|
import { MessageStore } from "./message_store.js";
|
||||||
import { IAckManager, ICodec } from "./utils.js";
|
import { IAckManager } from "./utils.js";
|
||||||
|
|
||||||
type AckManagerConstructorParams = {
|
type AckManagerConstructorParams = {
|
||||||
messageStore: MessageStore;
|
messageStore: MessageStore;
|
||||||
@ -35,7 +35,7 @@ export class AckManager implements IAckManager {
|
|||||||
this.storeAckManager.stop();
|
this.storeAckManager.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async subscribe(codec: ICodec): Promise<boolean> {
|
public async subscribe(codec: ICodec<IDecodedMessage>): Promise<boolean> {
|
||||||
return (
|
return (
|
||||||
(await this.filterAckManager.subscribe(codec)) ||
|
(await this.filterAckManager.subscribe(codec)) ||
|
||||||
(await this.storeAckManager.subscribe(codec))
|
(await this.storeAckManager.subscribe(codec))
|
||||||
@ -44,7 +44,7 @@ export class AckManager implements IAckManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FilterAckManager implements IAckManager {
|
class FilterAckManager implements IAckManager {
|
||||||
private codecs: Set<ICodec> = new Set();
|
private codecs: Set<ICodec<IDecodedMessage>> = new Set();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private messageStore: MessageStore,
|
private messageStore: MessageStore,
|
||||||
@ -63,7 +63,7 @@ class FilterAckManager implements IAckManager {
|
|||||||
this.codecs.clear();
|
this.codecs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async subscribe(codec: ICodec): Promise<boolean> {
|
public async subscribe(codec: ICodec<IDecodedMessage>): Promise<boolean> {
|
||||||
const success = await this.filter.subscribe(
|
const success = await this.filter.subscribe(
|
||||||
codec,
|
codec,
|
||||||
this.onMessage.bind(this)
|
this.onMessage.bind(this)
|
||||||
@ -86,7 +86,7 @@ class FilterAckManager implements IAckManager {
|
|||||||
class StoreAckManager implements IAckManager {
|
class StoreAckManager implements IAckManager {
|
||||||
private interval: ReturnType<typeof setInterval> | null = null;
|
private interval: ReturnType<typeof setInterval> | null = null;
|
||||||
|
|
||||||
private codecs: Set<ICodec> = new Set();
|
private codecs: Set<ICodec<IDecodedMessage>> = new Set();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private messageStore: MessageStore,
|
private messageStore: MessageStore,
|
||||||
@ -112,7 +112,7 @@ class StoreAckManager implements IAckManager {
|
|||||||
this.interval = null;
|
this.interval = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async subscribe(codec: ICodec): Promise<boolean> {
|
public async subscribe(codec: ICodec<IDecodedMessage>): Promise<boolean> {
|
||||||
this.codecs.add(codec);
|
this.codecs.add(codec);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
export { Messaging } from "./messaging.js";
|
export { Messaging } from "./messaging.js";
|
||||||
|
export type { RequestId } from "./utils.js";
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
import { IDecodedMessage, IDecoder, IEncoder } from "@waku/interfaces";
|
import { ICodec, IDecodedMessage } from "@waku/interfaces";
|
||||||
|
|
||||||
// TODO: create a local entity for that that will literally extend existing encoder and decoder from package/core
|
|
||||||
export type ICodec = IEncoder & IDecoder<IDecodedMessage>;
|
|
||||||
|
|
||||||
export type RequestId = string;
|
export type RequestId = string;
|
||||||
|
|
||||||
export interface IAckManager {
|
export interface IAckManager {
|
||||||
start(): void;
|
start(): void;
|
||||||
stop(): void;
|
stop(): void;
|
||||||
subscribe(codec: ICodec): Promise<boolean>;
|
subscribe(codec: ICodec<IDecodedMessage>): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,11 +5,18 @@ import {
|
|||||||
TypedEventEmitter
|
TypedEventEmitter
|
||||||
} from "@libp2p/interface";
|
} from "@libp2p/interface";
|
||||||
import type { MultiaddrInput } from "@multiformats/multiaddr";
|
import type { MultiaddrInput } from "@multiformats/multiaddr";
|
||||||
import { ConnectionManager, createDecoder, createEncoder } from "@waku/core";
|
import {
|
||||||
|
ConnectionManager,
|
||||||
|
createCodec,
|
||||||
|
createDecoder,
|
||||||
|
createEncoder
|
||||||
|
} from "@waku/core";
|
||||||
import type {
|
import type {
|
||||||
|
CreateCodecParams,
|
||||||
CreateDecoderParams,
|
CreateDecoderParams,
|
||||||
CreateEncoderParams,
|
CreateEncoderParams,
|
||||||
CreateNodeOptions,
|
CreateNodeOptions,
|
||||||
|
ICodec,
|
||||||
IDecodedMessage,
|
IDecodedMessage,
|
||||||
IDecoder,
|
IDecoder,
|
||||||
IEncoder,
|
IEncoder,
|
||||||
@ -35,6 +42,7 @@ import { Filter } from "../filter/index.js";
|
|||||||
import { HealthIndicator } from "../health_indicator/index.js";
|
import { HealthIndicator } from "../health_indicator/index.js";
|
||||||
import { LightPush } from "../light_push/index.js";
|
import { LightPush } from "../light_push/index.js";
|
||||||
import { Messaging } from "../messaging/index.js";
|
import { Messaging } from "../messaging/index.js";
|
||||||
|
import type { RequestId } from "../messaging/index.js";
|
||||||
import { PeerManager } from "../peer_manager/index.js";
|
import { PeerManager } from "../peer_manager/index.js";
|
||||||
import { Store } from "../store/index.js";
|
import { Store } from "../store/index.js";
|
||||||
|
|
||||||
@ -295,8 +303,25 @@ export class WakuNode implements IWaku {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public send(encoder: IEncoder, message: IMessage): Promise<void> {
|
public send(encoder: IEncoder, message: IMessage): Promise<RequestId> {
|
||||||
return this.messaging?.send(encoder, message) ?? Promise.resolve();
|
if (!this.messaging) {
|
||||||
|
throw new Error("Messaging not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.messaging.send(encoder, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public createCodec(params: CreateCodecParams): ICodec<IDecodedMessage> {
|
||||||
|
const routingInfo = this.createRoutingInfo(
|
||||||
|
params.contentTopic,
|
||||||
|
params.shardId
|
||||||
|
);
|
||||||
|
|
||||||
|
return createCodec({
|
||||||
|
contentTopic: params.contentTopic,
|
||||||
|
ephemeral: params.ephemeral ?? false,
|
||||||
|
routingInfo: routingInfo
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private createRoutingInfo(
|
private createRoutingInfo(
|
||||||
|
|||||||
@ -2,9 +2,11 @@ import { Peer, PeerId, Stream, TypedEventEmitter } from "@libp2p/interface";
|
|||||||
import { MultiaddrInput } from "@multiformats/multiaddr";
|
import { MultiaddrInput } from "@multiformats/multiaddr";
|
||||||
import {
|
import {
|
||||||
Callback,
|
Callback,
|
||||||
|
CreateCodecParams,
|
||||||
CreateDecoderParams,
|
CreateDecoderParams,
|
||||||
CreateEncoderParams,
|
CreateEncoderParams,
|
||||||
HealthStatus,
|
HealthStatus,
|
||||||
|
ICodec,
|
||||||
IDecodedMessage,
|
IDecodedMessage,
|
||||||
IDecoder,
|
IDecoder,
|
||||||
IEncoder,
|
IEncoder,
|
||||||
@ -154,6 +156,9 @@ export class MockWakuNode implements IWaku {
|
|||||||
public createEncoder(_params: CreateEncoderParams): IEncoder {
|
public createEncoder(_params: CreateEncoderParams): IEncoder {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
public createCodec(_params: CreateCodecParams): ICodec<IDecodedMessage> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
public isStarted(): boolean {
|
public isStarted(): boolean {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user