@libp2p/pubsub 1.2.6 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,10 @@ export declare const codes: {
15
15
  * Message expected to have a `seqno`, but doesn't
16
16
  */
17
17
  ERR_MISSING_SEQNO: string;
18
+ /**
19
+ * Message expected to have a `key`, but doesn't
20
+ */
21
+ ERR_MISSING_KEY: string;
18
22
  /**
19
23
  * Message `signature` is invalid
20
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK;IAChB;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEJ,CAAA"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK;IAChB;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEJ,CAAA"}
@@ -16,6 +16,10 @@ export const codes = {
16
16
  * Message expected to have a `seqno`, but doesn't
17
17
  */
18
18
  ERR_MISSING_SEQNO: 'ERR_MISSING_SEQNO',
19
+ /**
20
+ * Message expected to have a `key`, but doesn't
21
+ */
22
+ ERR_MISSING_KEY: 'ERR_MISSING_KEY',
19
23
  /**
20
24
  * Message `signature` is invalid
21
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;;OAEG;IACH,4BAA4B,EAAE,8BAA8B;IAC5D;;OAEG;IACH,8BAA8B,EAAE,gCAAgC;IAEhE,uBAAuB;IAEvB;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,gBAAgB,EAAE,kBAAkB;IAEpC,0BAA0B;IAE1B;;OAEG;IACH,mBAAmB,EAAE,qBAAqB;IAC1C;;OAEG;IACH,wBAAwB,EAAE,0BAA0B;IACpD;;OAEG;IACH,kBAAkB,EAAE,oBAAoB;IACxC;;OAEG;IACH,oBAAoB,EAAE,sBAAsB;CAC7C,CAAA"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;;OAEG;IACH,4BAA4B,EAAE,8BAA8B;IAC5D;;OAEG;IACH,8BAA8B,EAAE,gCAAgC;IAEhE,uBAAuB;IAEvB;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;OAEG;IACH,eAAe,EAAE,iBAAiB;IAClC;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,gBAAgB,EAAE,kBAAkB;IAEpC,0BAA0B;IAE1B;;OAEG;IACH,mBAAmB,EAAE,qBAAqB;IAC1C;;OAEG;IACH,wBAAwB,EAAE,0BAA0B;IACpD;;OAEG;IACH,kBAAkB,EAAE,oBAAoB;IACxC;;OAEG;IACH,oBAAoB,EAAE,sBAAsB;CAC7C,CAAA"}
@@ -1,9 +1,9 @@
1
- import { EventEmitter } from '@libp2p/interfaces';
1
+ import { EventEmitter, EventHandler } from '@libp2p/interfaces';
2
2
  import Queue from 'p-queue';
3
3
  import type { PeerId } from '@libp2p/interfaces/peer-id';
4
4
  import type { Registrar, IncomingStreamData } from '@libp2p/interfaces/registrar';
5
5
  import type { Connection } from '@libp2p/interfaces/connection';
6
- import type { PubSub, Message, StrictNoSign, StrictSign, PubSubOptions, PubSubEvents, RPCMessage, RPC, PeerStreams, RPCSubscription } from '@libp2p/interfaces/pubsub';
6
+ import type { PubSub, Message, StrictNoSign, StrictSign, PubSubOptions, PubSubEvents, RPC, PeerStreams, RPCSubscription } from '@libp2p/interfaces/pubsub';
7
7
  import type { Logger } from '@libp2p/logger';
8
8
  import type { PeerMap } from '@libp2p/peer-map';
9
9
  import type { IRPC } from './message/rpc.js';
@@ -15,7 +15,7 @@ export interface TopicValidator {
15
15
  * PubsubBaseProtocol handles the peers and connections logic for pubsub routers
16
16
  * and specifies the API that pubsub routers should have.
17
17
  */
18
- export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents> {
18
+ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents = PubSubEvents> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents> {
19
19
  peerId: PeerId;
20
20
  started: boolean;
21
21
  /**
@@ -83,7 +83,7 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
83
83
  /**
84
84
  * Notifies the router that a peer has been connected
85
85
  */
86
- protected _addPeer(peerId: PeerId, protocol: string): PeerStreams;
86
+ addPeer(peerId: PeerId, protocol: string): PeerStreams;
87
87
  /**
88
88
  * Notifies the router that a peer has been disconnected
89
89
  */
@@ -91,23 +91,19 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
91
91
  /**
92
92
  * Responsible for processing each RPC message received by other peers.
93
93
  */
94
- _processMessages(peerId: PeerId, stream: AsyncIterable<Uint8Array>, peerStreams: PeerStreams): Promise<void>;
94
+ processMessages(peerId: PeerId, stream: AsyncIterable<Uint8Array>, peerStreams: PeerStreams): Promise<void>;
95
95
  /**
96
96
  * Handles an rpc request from a peer
97
97
  */
98
- processRpc(from: PeerId, peerStreams: PeerStreams, rpc: RPC): Promise<boolean>;
98
+ processRpc(from: PeerId, peerStreams: PeerStreams, rpc: RPC): Promise<void>;
99
99
  /**
100
100
  * Handles a subscription change from a peer
101
101
  */
102
- _processRpcSubOpt(id: PeerId, subOpt: RPCSubscription): void;
102
+ processRpcSubOpt(id: PeerId, subOpt: RPCSubscription): void;
103
103
  /**
104
104
  * Handles an message from a peer
105
105
  */
106
- _processMessage(msg: Message): Promise<void>;
107
- /**
108
- * Emit a message from a peer
109
- */
110
- emitMessage(message: Message): void;
106
+ processMessage(from: PeerId, msg: Message): Promise<void>;
111
107
  /**
112
108
  * The default msgID implementation
113
109
  * Child class can override this.
@@ -117,25 +113,29 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
117
113
  * Whether to accept a message from a peer
118
114
  * Override to create a graylist
119
115
  */
120
- _acceptFrom(id: PeerId): boolean;
116
+ acceptFrom(id: PeerId): boolean;
121
117
  /**
122
118
  * Decode Uint8Array into an RPC object.
123
119
  * This can be override to use a custom router protobuf.
124
120
  */
125
- _decodeRpc(bytes: Uint8Array): RPCProto;
121
+ decodeRpc(bytes: Uint8Array): RPCProto;
126
122
  /**
127
123
  * Encode RPC object into a Uint8Array.
128
124
  * This can be override to use a custom router protobuf.
129
125
  */
130
- _encodeRpc(rpc: IRPC): Uint8Array;
126
+ encodeRpc(rpc: IRPC): Uint8Array;
131
127
  /**
132
128
  * Send an rpc object to a peer
133
129
  */
134
- _sendRpc(peer: PeerId, rpc: IRPC): void;
130
+ send(peer: PeerId, data: {
131
+ messages?: Message[];
132
+ subscriptions?: string[];
133
+ subscribe?: boolean;
134
+ }): void;
135
135
  /**
136
- * Send subscriptions to a peer
136
+ * Send an rpc object to a peer
137
137
  */
138
- _sendSubscriptions(id: PeerId, topics: string[], subscribe: boolean): void;
138
+ sendRpc(peer: PeerId, rpc: IRPC): void;
139
139
  /**
140
140
  * Validates the given message. The signature will be checked for authenticity.
141
141
  * Throws an error on invalid messages
@@ -145,7 +145,7 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
145
145
  * Normalizes the message and signs it, if signing is enabled.
146
146
  * Should be used by the routers to create the message to send.
147
147
  */
148
- protected _maybeSignMessage(message: Message): Promise<Message>;
148
+ buildMessage(message: Message): Promise<Message>;
149
149
  /**
150
150
  * Get a list of the peer-ids that are subscribed to one topic.
151
151
  */
@@ -153,18 +153,18 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
153
153
  /**
154
154
  * Publishes messages to all subscribed peers
155
155
  */
156
- publish(topic: string, message: Uint8Array): Promise<void>;
156
+ dispatchEvent(event: CustomEvent): boolean;
157
157
  /**
158
158
  * Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
159
159
  * For example, a Floodsub implementation might simply publish each message to each topic for every peer
160
160
  */
161
- abstract _publish(message: RPCMessage): Promise<void>;
161
+ abstract publishMessage(peerId: PeerId, message: Message): Promise<void>;
162
162
  /**
163
163
  * Subscribes to a given topic.
164
164
  */
165
165
  subscribe(topic: string): void;
166
166
  /**
167
- * Unsubscribe from the given topic.
167
+ * Unsubscribe from the given topic
168
168
  */
169
169
  unsubscribe(topic: string): void;
170
170
  /**
@@ -172,5 +172,7 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
172
172
  */
173
173
  getTopics(): string[];
174
174
  getPeers(): PeerId[];
175
+ addEventListener<U extends keyof EventMap>(type: U, callback: EventHandler<EventMap[U]>, options?: AddEventListenerOptions | boolean): void;
176
+ removeEventListener<U extends keyof EventMap>(type: U, callback: EventHandler<EventMap[U]> | undefined, options?: EventListenerOptions | boolean): void;
175
177
  }
176
178
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -3,10 +3,10 @@ import { EventEmitter, CustomEvent } from '@libp2p/interfaces';
3
3
  import errcode from 'err-code';
4
4
  import { pipe } from 'it-pipe';
5
5
  import Queue from 'p-queue';
6
- import { Topology } from '@libp2p/topology';
6
+ import { createTopology } from '@libp2p/topology';
7
7
  import { codes } from './errors.js';
8
8
  import { PeerStreams as PeerStreamsImpl } from './peer-streams.js';
9
- import { toRpcMessage, toMessage, ensureArray, randomSeqno, noSignMsgId, msgId } from './utils.js';
9
+ import { toMessage, ensureArray, randomSeqno, noSignMsgId, msgId, toRpcMessage } from './utils.js';
10
10
  import { signMessage, verifySignature } from './message/sign.js';
11
11
  import { base58btc } from 'multiformats/bases/base58';
12
12
  import { peerMap } from '@libp2p/peer-map';
@@ -53,7 +53,7 @@ export class PubsubBaseProtocol extends EventEmitter {
53
53
  this._registrarHandlerId = await this.registrar.handle(this.multicodecs, this._onIncomingStream);
54
54
  // register protocol with topology
55
55
  // Topology callbacks called on connection manager changes
56
- const topology = new Topology({
56
+ const topology = createTopology({
57
57
  onConnect: this._onPeerConnected,
58
58
  onDisconnect: this._onPeerDisconnected
59
59
  });
@@ -93,9 +93,9 @@ export class PubsubBaseProtocol extends EventEmitter {
93
93
  _onIncomingStream(evt) {
94
94
  const { protocol, stream, connection } = evt.detail;
95
95
  const peerId = connection.remotePeer;
96
- const peer = this._addPeer(peerId, protocol);
96
+ const peer = this.addPeer(peerId, protocol);
97
97
  const inboundStream = peer.attachInboundStream(stream);
98
- this._processMessages(peerId, inboundStream, peer)
98
+ this.processMessages(peerId, inboundStream, peer)
99
99
  .catch(err => this.log(err));
100
100
  }
101
101
  /**
@@ -105,14 +105,14 @@ export class PubsubBaseProtocol extends EventEmitter {
105
105
  this.log('connected %p', peerId);
106
106
  try {
107
107
  const { stream, protocol } = await conn.newStream(this.multicodecs);
108
- const peer = this._addPeer(peerId, protocol);
108
+ const peer = this.addPeer(peerId, protocol);
109
109
  await peer.attachOutboundStream(stream);
110
110
  }
111
111
  catch (err) {
112
112
  this.log.error(err);
113
113
  }
114
114
  // Immediately send my own subscriptions to the newly established conn
115
- this._sendSubscriptions(peerId, Array.from(this.subscriptions), true);
115
+ this.send(peerId, { subscriptions: Array.from(this.subscriptions).map(sub => sub.toString()), subscribe: true });
116
116
  }
117
117
  /**
118
118
  * Registrar notifies a closing connection with pubsub protocol
@@ -125,7 +125,7 @@ export class PubsubBaseProtocol extends EventEmitter {
125
125
  /**
126
126
  * Notifies the router that a peer has been connected
127
127
  */
128
- _addPeer(peerId, protocol) {
128
+ addPeer(peerId, protocol) {
129
129
  const existing = this.peers.get(peerId);
130
130
  // If peer streams already exists, do nothing
131
131
  if (existing != null) {
@@ -167,28 +167,36 @@ export class PubsubBaseProtocol extends EventEmitter {
167
167
  /**
168
168
  * Responsible for processing each RPC message received by other peers.
169
169
  */
170
- async _processMessages(peerId, stream, peerStreams) {
170
+ async processMessages(peerId, stream, peerStreams) {
171
171
  try {
172
172
  await pipe(stream, async (source) => {
173
173
  for await (const data of source) {
174
- const rpcMsg = this._decodeRpc(data);
175
- // Since _processRpc may be overridden entirely in unsafe ways,
174
+ const rpcMsg = this.decodeRpc(data);
175
+ const messages = [];
176
+ for (const msg of (rpcMsg.messages ?? [])) {
177
+ if (msg.from == null || msg.data == null || msg.topic == null) {
178
+ this.log('message from %p was missing from, data or topic fields, dropping', peerId);
179
+ continue;
180
+ }
181
+ messages.push({
182
+ from: msg.from,
183
+ data: msg.data,
184
+ topic: msg.topic,
185
+ seqno: msg.seqno ?? undefined,
186
+ signature: msg.signature ?? undefined,
187
+ key: msg.key ?? undefined
188
+ });
189
+ }
190
+ // Since processRpc may be overridden entirely in unsafe ways,
176
191
  // the simplest/safest option here is to wrap in a function and capture all errors
177
192
  // to prevent a top-level unhandled exception
178
193
  // This processing of rpc messages should happen without awaiting full validation/execution of prior messages
179
194
  this.processRpc(peerId, peerStreams, {
180
195
  subscriptions: (rpcMsg.subscriptions).map(sub => ({
181
196
  subscribe: Boolean(sub.subscribe),
182
- topicID: sub.topicID ?? ''
197
+ topic: sub.topic ?? ''
183
198
  })),
184
- msgs: (rpcMsg.msgs ?? []).map(msg => ({
185
- from: msg.from ?? peerId.multihash.bytes,
186
- data: msg.data ?? new Uint8Array(0),
187
- topicIDs: msg.topicIDs ?? [],
188
- seqno: msg.seqno ?? undefined,
189
- signature: msg.signature ?? undefined,
190
- key: msg.key ?? undefined
191
- }))
199
+ messages
192
200
  })
193
201
  .catch(err => this.log(err));
194
202
  }
@@ -202,36 +210,32 @@ export class PubsubBaseProtocol extends EventEmitter {
202
210
  * Handles an rpc request from a peer
203
211
  */
204
212
  async processRpc(from, peerStreams, rpc) {
213
+ if (!this.acceptFrom(from)) {
214
+ this.log('received message from unacceptable peer %p', from);
215
+ return;
216
+ }
205
217
  this.log('rpc from %p', from);
206
- const subs = rpc.subscriptions;
207
- const msgs = rpc.msgs;
208
- if (subs.length > 0) {
218
+ const { subscriptions, messages } = rpc;
219
+ if (subscriptions.length > 0) {
220
+ this.log('subscription update from %p', from);
209
221
  // update peer subscriptions
210
- subs.forEach((subOpt) => {
211
- this._processRpcSubOpt(from, subOpt);
222
+ subscriptions.forEach((subOpt) => {
223
+ this.processRpcSubOpt(from, subOpt);
212
224
  });
213
- this.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
214
- detail: { peerId: peerStreams.id, subscriptions: subs }
225
+ super.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
226
+ detail: { peerId: peerStreams.id, subscriptions }
215
227
  }));
216
228
  }
217
- if (!this._acceptFrom(from)) {
218
- this.log('received message from unacceptable peer %p', from);
219
- return false;
220
- }
221
- if (msgs.length > 0) {
222
- this.queue.addAll(msgs.map(message => async () => {
223
- const topics = message.topicIDs != null ? message.topicIDs : [];
224
- const hasSubscription = topics.some((topic) => this.subscriptions.has(topic));
225
- if (!hasSubscription && !this.canRelayMessage) {
229
+ if (messages.length > 0) {
230
+ this.log('messages from %p', from);
231
+ this.queue.addAll(messages.map(message => async () => {
232
+ if (!this.subscriptions.has(message.topic) && !this.canRelayMessage) {
226
233
  this.log('received message we didn\'t subscribe to. Dropping.');
227
234
  return;
228
235
  }
229
236
  try {
230
- const msg = toMessage({
231
- ...message,
232
- from: from.multihash.bytes
233
- });
234
- await this._processMessage(msg);
237
+ const msg = await toMessage(message);
238
+ await this.processMessage(from, msg);
235
239
  }
236
240
  catch (err) {
237
241
  this.log.error(err);
@@ -239,13 +243,12 @@ export class PubsubBaseProtocol extends EventEmitter {
239
243
  }))
240
244
  .catch(err => this.log(err));
241
245
  }
242
- return true;
243
246
  }
244
247
  /**
245
248
  * Handles a subscription change from a peer
246
249
  */
247
- _processRpcSubOpt(id, subOpt) {
248
- const t = subOpt.topicID;
250
+ processRpcSubOpt(id, subOpt) {
251
+ const t = subOpt.topic;
249
252
  if (t == null) {
250
253
  return;
251
254
  }
@@ -266,8 +269,8 @@ export class PubsubBaseProtocol extends EventEmitter {
266
269
  /**
267
270
  * Handles an message from a peer
268
271
  */
269
- async _processMessage(msg) {
270
- if (this.peerId.equals(msg.from) && !this.emitSelf) {
272
+ async processMessage(from, msg) {
273
+ if (this.peerId.equals(from) && !this.emitSelf) {
271
274
  return;
272
275
  }
273
276
  // Ensure the message is valid before processing it
@@ -278,21 +281,15 @@ export class PubsubBaseProtocol extends EventEmitter {
278
281
  this.log('Message is invalid, dropping it. %O', err);
279
282
  return;
280
283
  }
281
- // Emit to self
282
- this.emitMessage(msg);
283
- return await this._publish(toRpcMessage(msg));
284
- }
285
- /**
286
- * Emit a message from a peer
287
- */
288
- emitMessage(message) {
289
- message.topicIDs.forEach((topic) => {
290
- if (this.subscriptions.has(topic)) {
291
- this.dispatchEvent(new CustomEvent(topic, {
292
- detail: message
284
+ if (this.subscriptions.has(msg.topic)) {
285
+ const isFromSelf = this.peerId.equals(from);
286
+ if (!isFromSelf || this.emitSelf) {
287
+ super.dispatchEvent(new CustomEvent(msg.topic, {
288
+ detail: msg
293
289
  }));
294
290
  }
295
- });
291
+ }
292
+ await this.publishMessage(from, msg);
296
293
  }
297
294
  /**
298
295
  * The default msgID implementation
@@ -305,7 +302,10 @@ export class PubsubBaseProtocol extends EventEmitter {
305
302
  if (msg.seqno == null) {
306
303
  throw errcode(new Error('Need seqno when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_SEQNO);
307
304
  }
308
- return msgId(msg.from, msg.seqno);
305
+ if (msg.key == null) {
306
+ throw errcode(new Error('Need key when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_KEY);
307
+ }
308
+ return msgId(msg.key, msg.seqno);
309
309
  case 'StrictNoSign':
310
310
  return noSignMsgId(msg.data);
311
311
  default:
@@ -316,42 +316,44 @@ export class PubsubBaseProtocol extends EventEmitter {
316
316
  * Whether to accept a message from a peer
317
317
  * Override to create a graylist
318
318
  */
319
- _acceptFrom(id) {
319
+ acceptFrom(id) {
320
320
  return true;
321
321
  }
322
322
  /**
323
323
  * Decode Uint8Array into an RPC object.
324
324
  * This can be override to use a custom router protobuf.
325
325
  */
326
- _decodeRpc(bytes) {
326
+ decodeRpc(bytes) {
327
327
  return RPCProto.decode(bytes);
328
328
  }
329
329
  /**
330
330
  * Encode RPC object into a Uint8Array.
331
331
  * This can be override to use a custom router protobuf.
332
332
  */
333
- _encodeRpc(rpc) {
333
+ encodeRpc(rpc) {
334
334
  return RPCProto.encode(rpc).finish();
335
335
  }
336
336
  /**
337
337
  * Send an rpc object to a peer
338
338
  */
339
- _sendRpc(peer, rpc) {
339
+ send(peer, data) {
340
+ const { messages, subscriptions, subscribe } = data;
341
+ return this.sendRpc(peer, {
342
+ subscriptions: (subscriptions ?? []).map(str => ({ topic: str, subscribe: Boolean(subscribe) })),
343
+ messages: (messages ?? []).map(toRpcMessage)
344
+ });
345
+ }
346
+ /**
347
+ * Send an rpc object to a peer
348
+ */
349
+ sendRpc(peer, rpc) {
340
350
  const peerStreams = this.peers.get(peer);
341
351
  if (peerStreams == null || !peerStreams.isWritable) {
342
352
  const msg = `Cannot send RPC to ${peer.toString(base58btc)} as there is no open stream to it available`;
343
353
  this.log.error(msg);
344
354
  return;
345
355
  }
346
- peerStreams.write(this._encodeRpc(rpc));
347
- }
348
- /**
349
- * Send subscriptions to a peer
350
- */
351
- _sendSubscriptions(id, topics, subscribe) {
352
- return this._sendRpc(id, {
353
- subscriptions: topics.map(t => ({ topicID: t, subscribe: subscribe }))
354
- });
356
+ peerStreams.write(this.encodeRpc(rpc));
355
357
  }
356
358
  /**
357
359
  * Validates the given message. The signature will be checked for authenticity.
@@ -385,18 +387,16 @@ export class PubsubBaseProtocol extends EventEmitter {
385
387
  default:
386
388
  throw errcode(new Error('Cannot validate message: unhandled signature policy'), codes.ERR_UNHANDLED_SIGNATURE_POLICY);
387
389
  }
388
- for (const topic of message.topicIDs) {
389
- const validatorFn = this.topicValidators.get(topic);
390
- if (validatorFn != null) {
391
- await validatorFn(topic, message);
392
- }
390
+ const validatorFn = this.topicValidators.get(message.topic);
391
+ if (validatorFn != null) {
392
+ await validatorFn(message.topic, message);
393
393
  }
394
394
  }
395
395
  /**
396
396
  * Normalizes the message and signs it, if signing is enabled.
397
397
  * Should be used by the routers to create the message to send.
398
398
  */
399
- async _maybeSignMessage(message) {
399
+ async buildMessage(message) {
400
400
  const signaturePolicy = this.globalSignaturePolicy;
401
401
  switch (signaturePolicy) {
402
402
  case 'StrictSign':
@@ -419,7 +419,7 @@ export class PubsubBaseProtocol extends EventEmitter {
419
419
  if (topic == null) {
420
420
  throw errcode(new Error('topic is required'), 'ERR_NOT_VALID_TOPIC');
421
421
  }
422
- const peersInTopic = this.topics.get(topic);
422
+ const peersInTopic = this.topics.get(topic.toString());
423
423
  if (peersInTopic == null) {
424
424
  return [];
425
425
  }
@@ -428,22 +428,40 @@ export class PubsubBaseProtocol extends EventEmitter {
428
428
  /**
429
429
  * Publishes messages to all subscribed peers
430
430
  */
431
- async publish(topic, message) {
431
+ dispatchEvent(event) {
432
432
  if (!this.started) {
433
433
  throw new Error('Pubsub has not started');
434
434
  }
435
+ const topic = event.type;
436
+ let message = event.detail;
437
+ if (message instanceof Uint8Array) {
438
+ message = {
439
+ from: this.peerId,
440
+ topic,
441
+ data: message
442
+ };
443
+ }
435
444
  this.log('publish', topic, message);
436
- const msgObject = {
437
- from: this.peerId,
438
- data: message,
439
- topicIDs: [topic]
440
- };
441
- // ensure that the message follows the signature policy
442
- const msg = await this._maybeSignMessage(msgObject);
443
- // Emit to self if I'm interested and emitSelf enabled
444
- this.emitSelf && this.emitMessage(msg);
445
- // send to all the other peers
446
- await this._publish(toRpcMessage(msg));
445
+ Promise.resolve().then(async () => {
446
+ message = await this.buildMessage(message);
447
+ // dispatch the event if we are interested
448
+ if (this.emitSelf) {
449
+ if (this.subscriptions.has(topic)) {
450
+ super.dispatchEvent(new CustomEvent(topic, {
451
+ detail: message
452
+ }));
453
+ if (this.listenerCount(topic) === 0) {
454
+ this.unsubscribe(topic);
455
+ }
456
+ }
457
+ }
458
+ // send to all the other peers
459
+ await this.publishMessage(this.peerId, message);
460
+ })
461
+ .catch(err => {
462
+ this.log.error(err);
463
+ });
464
+ return true;
447
465
  }
448
466
  /**
449
467
  * Subscribes to a given topic.
@@ -452,24 +470,37 @@ export class PubsubBaseProtocol extends EventEmitter {
452
470
  if (!this.started) {
453
471
  throw new Error('Pubsub has not started');
454
472
  }
455
- if (!this.subscriptions.has(topic)) {
456
- this.subscriptions.add(topic);
473
+ const topicStr = topic.toString();
474
+ if (topicStr === 'pubsub:subscription-change') {
475
+ return;
476
+ }
477
+ if (!this.subscriptions.has(topicStr)) {
478
+ this.subscriptions.add(topicStr);
457
479
  for (const peerId of this.peers.keys()) {
458
- this._sendSubscriptions(peerId, [topic], true);
480
+ this.send(peerId, { subscriptions: [topicStr], subscribe: true });
459
481
  }
460
482
  }
461
483
  }
462
484
  /**
463
- * Unsubscribe from the given topic.
485
+ * Unsubscribe from the given topic
464
486
  */
465
487
  unsubscribe(topic) {
466
488
  if (!this.started) {
467
489
  throw new Error('Pubsub is not started');
468
490
  }
469
- if (this.subscriptions.has(topic) && this.listenerCount(topic) === 0) {
470
- this.subscriptions.delete(topic);
491
+ // @ts-expect-error topic should be a key of the event map
492
+ super.removeEventListener(topic);
493
+ const topicStr = topic.toString();
494
+ if (topicStr === 'pubsub:subscription-change') {
495
+ return;
496
+ }
497
+ const wasSubscribed = this.subscriptions.has(topicStr);
498
+ const listeners = this.listenerCount(topicStr);
499
+ this.log('unsubscribe from %s - am subscribed %s, listeners %d', topic, wasSubscribed, listeners);
500
+ if (wasSubscribed && listeners === 0) {
501
+ this.subscriptions.delete(topicStr);
471
502
  for (const peerId of this.peers.keys()) {
472
- this._sendSubscriptions(peerId, [topic], false);
503
+ this.send(peerId, { subscriptions: [topicStr], subscribe: false });
473
504
  }
474
505
  }
475
506
  }
@@ -488,5 +519,16 @@ export class PubsubBaseProtocol extends EventEmitter {
488
519
  }
489
520
  return Array.from(this.peers.keys());
490
521
  }
522
+ addEventListener(type, callback, options) {
523
+ this.subscribe(type.toString());
524
+ super.addEventListener(type, callback, options);
525
+ }
526
+ removeEventListener(type, callback, options) {
527
+ super.removeEventListener(type, callback, options);
528
+ const topicStr = type.toString();
529
+ if (this.listenerCount(topicStr) === 0) {
530
+ this.unsubscribe(topicStr);
531
+ }
532
+ }
491
533
  }
492
534
  //# sourceMappingURL=index.js.map