@libp2p/pubsub 1.2.9 → 1.2.12

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.
package/README.md CHANGED
@@ -15,9 +15,9 @@ npm i libp2p-pubsub
15
15
  ```
16
16
 
17
17
  ```javascript
18
- import { PubsubBaseProtocol } from '@libp2p/pubsub'
18
+ import { PubSubBaseProtocol } from '@libp2p/pubsub'
19
19
 
20
- class MyPubsubImplementation extends PubsubBaseProtocol {
20
+ class MyPubsubImplementation extends PubSubBaseProtocol {
21
21
  // .. extra methods here
22
22
  }
23
23
  ```
@@ -1,27 +1,24 @@
1
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
- import type { Registrar, IncomingStreamData } from '@libp2p/interfaces/registrar';
4
+ import type { IncomingStreamData } from '@libp2p/interfaces/registrar';
5
5
  import type { Connection } from '@libp2p/interfaces/connection';
6
- import type { PubSub, Message, StrictNoSign, StrictSign, PubSubOptions, PubSubEvents, RPC, PeerStreams, RPCSubscription } from '@libp2p/interfaces/pubsub';
7
- import type { Logger } from '@libp2p/logger';
8
- import type { PeerMap } from '@libp2p/peer-map';
9
- import type { IRPC } from './message/rpc.js';
10
- import { RPC as RPCProto } from './message/rpc.js';
6
+ import type { PubSub, Message, StrictNoSign, StrictSign, PubSubInit, PubSubEvents, PeerStreams, PubSubRPCMessage, PubSubRPC, PubSubRPCSubscription } from '@libp2p/interfaces/pubsub';
7
+ import { PeerMap, PeerSet } from '@libp2p/peer-collections';
8
+ import { Components, Initializable } from '@libp2p/interfaces/components';
11
9
  export interface TopicValidator {
12
10
  (topic: string, message: Message): Promise<void>;
13
11
  }
14
12
  /**
15
- * PubsubBaseProtocol handles the peers and connections logic for pubsub routers
13
+ * PubSubBaseProtocol handles the peers and connections logic for pubsub routers
16
14
  * and specifies the API that pubsub routers should have.
17
15
  */
18
- export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents = PubSubEvents> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents> {
19
- peerId: PeerId;
16
+ export declare abstract class PubSubBaseProtocol extends EventEmitter<PubSubEvents> implements PubSub, Initializable {
20
17
  started: boolean;
21
18
  /**
22
19
  * Map of topics to which peers are subscribed to
23
20
  */
24
- topics: Map<string, Set<string>>;
21
+ topics: Map<string, PeerSet>;
25
22
  /**
26
23
  * List of our subscriptions
27
24
  */
@@ -50,13 +47,12 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
50
47
  */
51
48
  topicValidators: Map<string, TopicValidator>;
52
49
  queue: Queue;
53
- registrar: Registrar;
54
50
  multicodecs: string[];
55
- protected log: Logger;
56
- protected _libp2p: any;
57
- private _registrarHandlerId;
51
+ components: Components;
58
52
  private _registrarTopologyId;
59
- constructor(props: PubSubOptions);
53
+ protected enabled: boolean;
54
+ constructor(props: PubSubInit);
55
+ init(components: Components): void;
60
56
  /**
61
57
  * Register the pubsub protocol onto the libp2p node.
62
58
  *
@@ -71,7 +67,7 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
71
67
  /**
72
68
  * On an inbound stream opened
73
69
  */
74
- protected _onIncomingStream(evt: CustomEvent<IncomingStreamData>): void;
70
+ protected _onIncomingStream(data: IncomingStreamData): void;
75
71
  /**
76
72
  * Registrar notifies an established connection with pubsub protocol
77
73
  */
@@ -95,13 +91,13 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
95
91
  /**
96
92
  * Handles an rpc request from a peer
97
93
  */
98
- processRpc(from: PeerId, peerStreams: PeerStreams, rpc: RPC): Promise<void>;
94
+ processRpc(from: PeerId, peerStreams: PeerStreams, rpc: PubSubRPC): Promise<boolean>;
99
95
  /**
100
96
  * Handles a subscription change from a peer
101
97
  */
102
- processRpcSubOpt(id: PeerId, subOpt: RPCSubscription): void;
98
+ processRpcSubOpt(id: PeerId, subOpt: PubSubRPCSubscription): void;
103
99
  /**
104
- * Handles an message from a peer
100
+ * Handles a message from a peer
105
101
  */
106
102
  processMessage(from: PeerId, msg: Message): Promise<void>;
107
103
  /**
@@ -118,12 +114,22 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
118
114
  * Decode Uint8Array into an RPC object.
119
115
  * This can be override to use a custom router protobuf.
120
116
  */
121
- decodeRpc(bytes: Uint8Array): RPCProto;
117
+ abstract decodeRpc(bytes: Uint8Array): PubSubRPC;
122
118
  /**
123
119
  * Encode RPC object into a Uint8Array.
124
120
  * This can be override to use a custom router protobuf.
125
121
  */
126
- encodeRpc(rpc: IRPC): Uint8Array;
122
+ abstract encodeRpc(rpc: PubSubRPC): Uint8Array;
123
+ /**
124
+ * Decode Uint8Array into an RPC object.
125
+ * This can be override to use a custom router protobuf.
126
+ */
127
+ abstract decodeMessage(bytes: Uint8Array): PubSubRPCMessage;
128
+ /**
129
+ * Encode RPC object into a Uint8Array.
130
+ * This can be override to use a custom router protobuf.
131
+ */
132
+ abstract encodeMessage(rpc: PubSubRPCMessage): Uint8Array;
127
133
  /**
128
134
  * Send an rpc object to a peer
129
135
  */
@@ -135,7 +141,7 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
135
141
  /**
136
142
  * Send an rpc object to a peer
137
143
  */
138
- sendRpc(peer: PeerId, rpc: IRPC): void;
144
+ sendRpc(peer: PeerId, rpc: PubSubRPC): void;
139
145
  /**
140
146
  * Validates the given message. The signature will be checked for authenticity.
141
147
  * Throws an error on invalid messages
@@ -153,12 +159,15 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
153
159
  /**
154
160
  * Publishes messages to all subscribed peers
155
161
  */
156
- dispatchEvent(event: CustomEvent): boolean;
162
+ dispatchEvent(event: CustomEvent<Uint8Array | Message>): boolean;
157
163
  /**
158
164
  * Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
159
- * For example, a Floodsub implementation might simply publish each message to each topic for every peer
165
+ * For example, a Floodsub implementation might simply publish each message to each topic for every peer.
166
+ *
167
+ * `sender` might be this peer, or we might be forwarding a message on behalf of another peer, in which case sender
168
+ * is the peer we received the message from, which may not be the peer the message was created by.
160
169
  */
161
- abstract publishMessage(peerId: PeerId, message: Message): Promise<void>;
170
+ abstract publishMessage(sender: PeerId, message: Message): Promise<void>;
162
171
  /**
163
172
  * Subscribes to a given topic.
164
173
  */
@@ -172,7 +181,7 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
172
181
  */
173
182
  getTopics(): string[];
174
183
  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;
184
+ addEventListener(type: string, callback: EventHandler<any>, options?: AddEventListenerOptions | boolean): void;
185
+ removeEventListener(type: string, callback: EventHandler<any> | undefined, options?: EventListenerOptions | boolean): void;
177
186
  }
178
187
  //# 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":"AACA,OAAO,EAAE,YAAY,EAAe,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,KAAK,MAAM,SAAS,CAAA;AAS3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,qBAAqB,EAA0B,MAAM,2BAA2B,CAAA;AAC7M,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAIzE,MAAM,WAAW,cAAc;IAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE;AAEpF;;;GAGG;AACH,8BAAsB,kBAAmB,SAAQ,YAAY,CAAC,YAAY,CAAE,YAAW,MAAM,EAAE,aAAa;IACnG,OAAO,EAAE,OAAO,CAAA;IACvB;;OAEG;IACI,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC;;OAEG;IACI,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACjC;;OAEG;IACI,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAClC;;OAEG;IACI,qBAAqB,EAAE,OAAO,YAAY,GAAG,OAAO,UAAU,CAAA;IACrE;;OAEG;IACI,eAAe,EAAE,OAAO,CAAA;IAC/B;;OAEG;IACI,QAAQ,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACI,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IAC5C,KAAK,EAAE,KAAK,CAAA;IACZ,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,EAAE,UAAU,CAAmB;IAEhD,OAAO,CAAC,oBAAoB,CAAoB;IAChD,SAAS,CAAC,OAAO,EAAE,OAAO,CAAA;gBAEb,KAAK,EAAE,UAAU;IA4B9B,IAAI,CAAE,UAAU,EAAE,UAAU;IAM5B;;;;OAIG;IACG,KAAK;IAuBX;;OAEG;IACG,IAAI;IAuBV,SAAS;IAIT;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAE,IAAI,EAAE,kBAAkB;IAUrD;;OAEG;cACa,gBAAgB,CAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;IAelE;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU;IAOhE;;OAEG;IACH,OAAO,CAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW;IAwBvD;;OAEG;IACH,SAAS,CAAC,WAAW,CAAE,MAAM,EAAE,MAAM;IAuBrC;;OAEG;IACG,eAAe,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,WAAW;IA6ClG;;OAEG;IACG,UAAU,CAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAoD3F;;OAEG;IACH,gBAAgB,CAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB;IAsB3D;;OAEG;IACG,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO;IA0BhD;;;OAGG;IACH,QAAQ,CAAE,GAAG,EAAE,OAAO;IAoBtB;;;OAGG;IACH,UAAU,CAAE,EAAE,EAAE,MAAM;IAItB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAE,KAAK,EAAE,UAAU,GAAG,SAAS;IAEjD;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAE,GAAG,EAAE,SAAS,GAAG,UAAU;IAE/C;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAE,KAAK,EAAE,UAAU,GAAG,gBAAgB;IAE5D;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAE,GAAG,EAAE,gBAAgB,GAAG,UAAU;IAE1D;;OAEG;IACH,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE;IASjG;;OAEG;IACH,OAAO,CAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS;IAYrC;;;OAGG;IACG,QAAQ,CAAE,OAAO,EAAE,OAAO;IAoChC;;;OAGG;IACG,YAAY,CAAE,OAAO,EAAE,OAAO;IAepC;;OAEG;IACH,cAAc,CAAE,KAAK,EAAE,MAAM;IAkB7B;;OAEG;IACH,aAAa,CAAE,KAAK,EAAE,WAAW,CAAC,UAAU,GAAG,OAAO,CAAC,GAAG,OAAO;IAoDjE;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzE;;OAEG;IACH,SAAS,CAAE,KAAK,EAAE,MAAM;IAoBxB;;OAEG;IACH,WAAW,CAAE,KAAK,EAAE,MAAM;IA4B1B;;OAEG;IACH,SAAS;IAQT,QAAQ;IAQR,gBAAgB,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO;IAOxG,mBAAmB,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO;CAUrH"}
package/dist/src/index.js CHANGED
@@ -7,27 +7,25 @@ import { createTopology } from '@libp2p/topology';
7
7
  import { codes } from './errors.js';
8
8
  import { PeerStreams as PeerStreamsImpl } from './peer-streams.js';
9
9
  import { toMessage, ensureArray, randomSeqno, noSignMsgId, msgId, toRpcMessage } from './utils.js';
10
- import { signMessage, verifySignature } from './message/sign.js';
11
- import { base58btc } from 'multiformats/bases/base58';
12
- import { peerMap } from '@libp2p/peer-map';
13
- import { peerIdFromString } from '@libp2p/peer-id';
14
- import { RPC as RPCProto } from './message/rpc.js';
10
+ import { signMessage, verifySignature } from './sign.js';
11
+ import { PeerMap, PeerSet } from '@libp2p/peer-collections';
12
+ import { Components } from '@libp2p/interfaces/components';
13
+ const log = logger('libp2p:pubsub');
15
14
  /**
16
- * PubsubBaseProtocol handles the peers and connections logic for pubsub routers
15
+ * PubSubBaseProtocol handles the peers and connections logic for pubsub routers
17
16
  * and specifies the API that pubsub routers should have.
18
17
  */
19
- export class PubsubBaseProtocol extends EventEmitter {
18
+ export class PubSubBaseProtocol extends EventEmitter {
20
19
  constructor(props) {
21
20
  super();
22
- const { debugName = 'libp2p:pubsub', multicodecs = [], peerId, registrar, globalSignaturePolicy = 'StrictSign', canRelayMessage = false, emitSelf = false, messageProcessingConcurrency = 10 } = props;
23
- this.log = logger(debugName);
21
+ this.components = new Components();
22
+ const { multicodecs = [], globalSignaturePolicy = 'StrictSign', canRelayMessage = false, emitSelf = false, messageProcessingConcurrency = 10 } = props;
24
23
  this.multicodecs = ensureArray(multicodecs);
25
- this.registrar = registrar;
26
- this.peerId = peerId;
24
+ this.enabled = props.enabled !== false;
27
25
  this.started = false;
28
26
  this.topics = new Map();
29
27
  this.subscriptions = new Set();
30
- this.peers = peerMap();
28
+ this.peers = new PeerMap();
31
29
  this.globalSignaturePolicy = globalSignaturePolicy === 'StrictNoSign' ? 'StrictNoSign' : 'StrictSign';
32
30
  this.canRelayMessage = canRelayMessage;
33
31
  this.emitSelf = emitSelf;
@@ -37,6 +35,9 @@ export class PubsubBaseProtocol extends EventEmitter {
37
35
  this._onPeerConnected = this._onPeerConnected.bind(this);
38
36
  this._onPeerDisconnected = this._onPeerDisconnected.bind(this);
39
37
  }
38
+ init(components) {
39
+ this.components = components;
40
+ }
40
41
  // LIFECYCLE METHODS
41
42
  /**
42
43
  * Register the pubsub protocol onto the libp2p node.
@@ -44,45 +45,43 @@ export class PubsubBaseProtocol extends EventEmitter {
44
45
  * @returns {void}
45
46
  */
46
47
  async start() {
47
- if (this.started) {
48
+ if (this.started || !this.enabled) {
48
49
  return;
49
50
  }
50
- this.log('starting');
51
+ log('starting');
51
52
  // Incoming streams
52
53
  // Called after a peer dials us
53
- this._registrarHandlerId = await this.registrar.handle(this.multicodecs, this._onIncomingStream);
54
+ await this.components.getRegistrar().handle(this.multicodecs, this._onIncomingStream);
54
55
  // register protocol with topology
55
56
  // Topology callbacks called on connection manager changes
56
57
  const topology = createTopology({
57
58
  onConnect: this._onPeerConnected,
58
59
  onDisconnect: this._onPeerDisconnected
59
60
  });
60
- this._registrarTopologyId = this.registrar.register(this.multicodecs, topology);
61
- this.log('started');
61
+ this._registrarTopologyId = await this.components.getRegistrar().register(this.multicodecs, topology);
62
+ log('started');
62
63
  this.started = true;
63
64
  }
64
65
  /**
65
66
  * Unregister the pubsub protocol and the streams with other peers will be closed.
66
67
  */
67
68
  async stop() {
68
- if (!this.started) {
69
+ if (!this.started || !this.enabled) {
69
70
  return;
70
71
  }
71
72
  // unregister protocol and handlers
72
73
  if (this._registrarTopologyId != null) {
73
- this.registrar.unregister(this._registrarTopologyId);
74
- }
75
- if (this._registrarHandlerId != null) {
76
- await this.registrar.unhandle(this._registrarHandlerId);
74
+ this.components.getRegistrar().unregister(this._registrarTopologyId);
77
75
  }
78
- this.log('stopping');
76
+ await this.components.getRegistrar().unhandle(this.multicodecs);
77
+ log('stopping');
79
78
  for (const peerStreams of this.peers.values()) {
80
79
  peerStreams.close();
81
80
  }
82
81
  this.peers.clear();
83
82
  this.subscriptions = new Set();
84
83
  this.started = false;
85
- this.log('stopped');
84
+ log('stopped');
86
85
  }
87
86
  isStarted() {
88
87
  return this.started;
@@ -90,26 +89,26 @@ export class PubsubBaseProtocol extends EventEmitter {
90
89
  /**
91
90
  * On an inbound stream opened
92
91
  */
93
- _onIncomingStream(evt) {
94
- const { protocol, stream, connection } = evt.detail;
92
+ _onIncomingStream(data) {
93
+ const { protocol, stream, connection } = data;
95
94
  const peerId = connection.remotePeer;
96
95
  const peer = this.addPeer(peerId, protocol);
97
96
  const inboundStream = peer.attachInboundStream(stream);
98
97
  this.processMessages(peerId, inboundStream, peer)
99
- .catch(err => this.log(err));
98
+ .catch(err => log(err));
100
99
  }
101
100
  /**
102
101
  * Registrar notifies an established connection with pubsub protocol
103
102
  */
104
103
  async _onPeerConnected(peerId, conn) {
105
- this.log('connected %p', peerId);
104
+ log('connected %p', peerId);
106
105
  try {
107
106
  const { stream, protocol } = await conn.newStream(this.multicodecs);
108
107
  const peer = this.addPeer(peerId, protocol);
109
108
  await peer.attachOutboundStream(stream);
110
109
  }
111
110
  catch (err) {
112
- this.log.error(err);
111
+ log.error(err);
113
112
  }
114
113
  // Immediately send my own subscriptions to the newly established conn
115
114
  this.send(peerId, { subscriptions: Array.from(this.subscriptions).map(sub => sub.toString()), subscribe: true });
@@ -119,7 +118,7 @@ export class PubsubBaseProtocol extends EventEmitter {
119
118
  */
120
119
  _onPeerDisconnected(peerId, conn) {
121
120
  const idB58Str = peerId.toString();
122
- this.log('connection ended', idB58Str);
121
+ log('connection ended', idB58Str);
123
122
  this._removePeer(peerId);
124
123
  }
125
124
  /**
@@ -132,7 +131,7 @@ export class PubsubBaseProtocol extends EventEmitter {
132
131
  return existing;
133
132
  }
134
133
  // else create a new peer streams
135
- this.log('new peer %p', peerId);
134
+ log('new peer %p', peerId);
136
135
  const peerStreams = new PeerStreamsImpl({
137
136
  id: peerId,
138
137
  protocol
@@ -147,7 +146,6 @@ export class PubsubBaseProtocol extends EventEmitter {
147
146
  * Notifies the router that a peer has been disconnected
148
147
  */
149
148
  _removePeer(peerId) {
150
- const id = peerId.toString();
151
149
  const peerStreams = this.peers.get(peerId);
152
150
  if (peerStreams == null) {
153
151
  return;
@@ -155,11 +153,11 @@ export class PubsubBaseProtocol extends EventEmitter {
155
153
  // close peer streams
156
154
  peerStreams.close();
157
155
  // delete peer streams
158
- this.log('delete peer %p', peerId);
156
+ log('delete peer %p', peerId);
159
157
  this.peers.delete(peerId);
160
158
  // remove peer from topics map
161
159
  for (const peers of this.topics.values()) {
162
- peers.delete(id);
160
+ peers.delete(peerId);
163
161
  }
164
162
  return peerStreams;
165
163
  }
@@ -175,14 +173,14 @@ export class PubsubBaseProtocol extends EventEmitter {
175
173
  const messages = [];
176
174
  for (const msg of (rpcMsg.messages ?? [])) {
177
175
  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);
176
+ log('message from %p was missing from, data or topic fields, dropping', peerId);
179
177
  continue;
180
178
  }
181
179
  messages.push({
182
180
  from: msg.from,
183
181
  data: msg.data,
184
182
  topic: msg.topic,
185
- seqno: msg.seqno ?? undefined,
183
+ sequenceNumber: msg.sequenceNumber ?? undefined,
186
184
  signature: msg.signature ?? undefined,
187
185
  key: msg.key ?? undefined
188
186
  });
@@ -192,13 +190,13 @@ export class PubsubBaseProtocol extends EventEmitter {
192
190
  // to prevent a top-level unhandled exception
193
191
  // This processing of rpc messages should happen without awaiting full validation/execution of prior messages
194
192
  this.processRpc(peerId, peerStreams, {
195
- subscriptions: (rpcMsg.subscriptions).map(sub => ({
193
+ subscriptions: (rpcMsg.subscriptions ?? []).map(sub => ({
196
194
  subscribe: Boolean(sub.subscribe),
197
195
  topic: sub.topic ?? ''
198
196
  })),
199
197
  messages
200
198
  })
201
- .catch(err => this.log(err));
199
+ .catch(err => log(err));
202
200
  }
203
201
  });
204
202
  }
@@ -211,38 +209,45 @@ export class PubsubBaseProtocol extends EventEmitter {
211
209
  */
212
210
  async processRpc(from, peerStreams, rpc) {
213
211
  if (!this.acceptFrom(from)) {
214
- this.log('received message from unacceptable peer %p', from);
215
- return;
212
+ log('received message from unacceptable peer %p', from);
213
+ return false;
216
214
  }
217
- this.log('rpc from %p', from);
215
+ log('rpc from %p', from);
218
216
  const { subscriptions, messages } = rpc;
219
- if (subscriptions.length > 0) {
220
- this.log('subscription update from %p', from);
217
+ if (subscriptions != null && subscriptions.length > 0) {
218
+ log('subscription update from %p', from);
221
219
  // update peer subscriptions
222
220
  subscriptions.forEach((subOpt) => {
223
221
  this.processRpcSubOpt(from, subOpt);
224
222
  });
225
223
  super.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
226
- detail: { peerId: peerStreams.id, subscriptions }
224
+ detail: {
225
+ peerId: peerStreams.id,
226
+ subscriptions: subscriptions.map(({ topic, subscribe }) => ({
227
+ topic: `${topic ?? ''}`,
228
+ subscribe: Boolean(subscribe)
229
+ }))
230
+ }
227
231
  }));
228
232
  }
229
- if (messages.length > 0) {
230
- this.log('messages from %p', from);
233
+ if (messages != null && messages.length > 0) {
234
+ log('messages from %p', from);
231
235
  this.queue.addAll(messages.map(message => async () => {
232
- if (!this.subscriptions.has(message.topic) && !this.canRelayMessage) {
233
- this.log('received message we didn\'t subscribe to. Dropping.');
234
- return;
236
+ if (message.topic == null || (!this.subscriptions.has(message.topic) && !this.canRelayMessage)) {
237
+ log('received message we didn\'t subscribe to. Dropping.');
238
+ return false;
235
239
  }
236
240
  try {
237
241
  const msg = await toMessage(message);
238
242
  await this.processMessage(from, msg);
239
243
  }
240
244
  catch (err) {
241
- this.log.error(err);
245
+ log.error(err);
242
246
  }
243
247
  }))
244
- .catch(err => this.log(err));
248
+ .catch(err => log(err));
245
249
  }
250
+ return true;
246
251
  }
247
252
  /**
248
253
  * Handles a subscription change from a peer
@@ -254,23 +259,23 @@ export class PubsubBaseProtocol extends EventEmitter {
254
259
  }
255
260
  let topicSet = this.topics.get(t);
256
261
  if (topicSet == null) {
257
- topicSet = new Set();
262
+ topicSet = new PeerSet();
258
263
  this.topics.set(t, topicSet);
259
264
  }
260
- if (subOpt.subscribe) {
265
+ if (subOpt.subscribe === true) {
261
266
  // subscribe peer to new topic
262
- topicSet.add(id.toString());
267
+ topicSet.add(id);
263
268
  }
264
269
  else {
265
270
  // unsubscribe from existing topic
266
- topicSet.delete(id.toString());
271
+ topicSet.delete(id);
267
272
  }
268
273
  }
269
274
  /**
270
- * Handles an message from a peer
275
+ * Handles a message from a peer
271
276
  */
272
277
  async processMessage(from, msg) {
273
- if (this.peerId.equals(from) && !this.emitSelf) {
278
+ if (this.components.getPeerId().equals(from) && !this.emitSelf) {
274
279
  return;
275
280
  }
276
281
  // Ensure the message is valid before processing it
@@ -278,11 +283,11 @@ export class PubsubBaseProtocol extends EventEmitter {
278
283
  await this.validate(msg);
279
284
  }
280
285
  catch (err) {
281
- this.log('Message is invalid, dropping it. %O', err);
286
+ log('Message is invalid, dropping it. %O', err);
282
287
  return;
283
288
  }
284
289
  if (this.subscriptions.has(msg.topic)) {
285
- const isFromSelf = this.peerId.equals(from);
290
+ const isFromSelf = this.components.getPeerId().equals(from);
286
291
  if (!isFromSelf || this.emitSelf) {
287
292
  super.dispatchEvent(new CustomEvent(msg.topic, {
288
293
  detail: msg
@@ -299,13 +304,13 @@ export class PubsubBaseProtocol extends EventEmitter {
299
304
  const signaturePolicy = this.globalSignaturePolicy;
300
305
  switch (signaturePolicy) {
301
306
  case 'StrictSign':
302
- if (msg.seqno == null) {
307
+ if (msg.sequenceNumber == null) {
303
308
  throw errcode(new Error('Need seqno when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_SEQNO);
304
309
  }
305
310
  if (msg.key == null) {
306
311
  throw errcode(new Error('Need key when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_KEY);
307
312
  }
308
- return msgId(msg.key, msg.seqno);
313
+ return msgId(msg.key, msg.sequenceNumber);
309
314
  case 'StrictNoSign':
310
315
  return noSignMsgId(msg.data);
311
316
  default:
@@ -319,20 +324,6 @@ export class PubsubBaseProtocol extends EventEmitter {
319
324
  acceptFrom(id) {
320
325
  return true;
321
326
  }
322
- /**
323
- * Decode Uint8Array into an RPC object.
324
- * This can be override to use a custom router protobuf.
325
- */
326
- decodeRpc(bytes) {
327
- return RPCProto.decode(bytes);
328
- }
329
- /**
330
- * Encode RPC object into a Uint8Array.
331
- * This can be override to use a custom router protobuf.
332
- */
333
- encodeRpc(rpc) {
334
- return RPCProto.encode(rpc).finish();
335
- }
336
327
  /**
337
328
  * Send an rpc object to a peer
338
329
  */
@@ -349,8 +340,7 @@ export class PubsubBaseProtocol extends EventEmitter {
349
340
  sendRpc(peer, rpc) {
350
341
  const peerStreams = this.peers.get(peer);
351
342
  if (peerStreams == null || !peerStreams.isWritable) {
352
- const msg = `Cannot send RPC to ${peer.toString(base58btc)} as there is no open stream to it available`;
353
- this.log.error(msg);
343
+ log.error('Cannot send RPC to %p as there is no open stream to it available', peer);
354
344
  return;
355
345
  }
356
346
  peerStreams.write(this.encodeRpc(rpc));
@@ -369,7 +359,7 @@ export class PubsubBaseProtocol extends EventEmitter {
369
359
  if (message.key != null) {
370
360
  throw errcode(new Error('StrictNoSigning: key should not be present'), codes.ERR_UNEXPECTED_KEY);
371
361
  }
372
- if (message.seqno != null) {
362
+ if (message.sequenceNumber != null) {
373
363
  throw errcode(new Error('StrictNoSigning: seqno should not be present'), codes.ERR_UNEXPECTED_SEQNO);
374
364
  }
375
365
  break;
@@ -377,10 +367,10 @@ export class PubsubBaseProtocol extends EventEmitter {
377
367
  if (message.signature == null) {
378
368
  throw errcode(new Error('StrictSigning: Signing required and no signature was present'), codes.ERR_MISSING_SIGNATURE);
379
369
  }
380
- if (message.seqno == null) {
370
+ if (message.sequenceNumber == null) {
381
371
  throw errcode(new Error('StrictSigning: Signing required and no seqno was present'), codes.ERR_MISSING_SEQNO);
382
372
  }
383
- if (!(await verifySignature(message))) {
373
+ if (!(await verifySignature(message, this.encodeMessage.bind(this)))) {
384
374
  throw errcode(new Error('StrictSigning: Invalid message signature'), codes.ERR_INVALID_SIGNATURE);
385
375
  }
386
376
  break;
@@ -400,8 +390,8 @@ export class PubsubBaseProtocol extends EventEmitter {
400
390
  const signaturePolicy = this.globalSignaturePolicy;
401
391
  switch (signaturePolicy) {
402
392
  case 'StrictSign':
403
- message.seqno = randomSeqno();
404
- return await signMessage(this.peerId, message);
393
+ message.sequenceNumber = randomSeqno();
394
+ return await signMessage(this.components.getPeerId(), message, this.encodeMessage.bind(this));
405
395
  case 'StrictNoSign':
406
396
  return await Promise.resolve(message);
407
397
  default:
@@ -423,7 +413,7 @@ export class PubsubBaseProtocol extends EventEmitter {
423
413
  if (peersInTopic == null) {
424
414
  return [];
425
415
  }
426
- return Array.from(peersInTopic).map(str => peerIdFromString(str));
416
+ return Array.from(peersInTopic.values());
427
417
  }
428
418
  /**
429
419
  * Publishes messages to all subscribed peers
@@ -433,15 +423,25 @@ export class PubsubBaseProtocol extends EventEmitter {
433
423
  throw new Error('Pubsub has not started');
434
424
  }
435
425
  const topic = event.type;
436
- let message = event.detail;
437
- if (message instanceof Uint8Array) {
426
+ let message;
427
+ if (event.detail instanceof Uint8Array) {
428
+ message = {
429
+ from: this.components.getPeerId(),
430
+ topic,
431
+ data: event.detail
432
+ };
433
+ }
434
+ else if (event.detail != null) {
435
+ message = event.detail;
436
+ }
437
+ else {
438
438
  message = {
439
- from: this.peerId,
439
+ from: this.components.getPeerId(),
440
440
  topic,
441
- data: message
441
+ data: new Uint8Array(0)
442
442
  };
443
443
  }
444
- this.log('publish', topic, message);
444
+ log('publish topic: %s from: %p data: %m', topic, message.from, message.data);
445
445
  Promise.resolve().then(async () => {
446
446
  message = await this.buildMessage(message);
447
447
  // dispatch the event if we are interested
@@ -456,10 +456,10 @@ export class PubsubBaseProtocol extends EventEmitter {
456
456
  }
457
457
  }
458
458
  // send to all the other peers
459
- await this.publishMessage(this.peerId, message);
459
+ await this.publishMessage(this.components.getPeerId(), message);
460
460
  })
461
461
  .catch(err => {
462
- this.log.error(err);
462
+ log.error(err);
463
463
  });
464
464
  return true;
465
465
  }
@@ -496,7 +496,7 @@ export class PubsubBaseProtocol extends EventEmitter {
496
496
  }
497
497
  const wasSubscribed = this.subscriptions.has(topicStr);
498
498
  const listeners = this.listenerCount(topicStr);
499
- this.log('unsubscribe from %s - am subscribed %s, listeners %d', topic, wasSubscribed, listeners);
499
+ log('unsubscribe from %s - am subscribed %s, listeners %d', topic, wasSubscribed, listeners);
500
500
  if (wasSubscribed && listeners === 0) {
501
501
  this.subscriptions.delete(topicStr);
502
502
  for (const peerId of this.peers.keys()) {
@@ -521,9 +521,11 @@ export class PubsubBaseProtocol extends EventEmitter {
521
521
  }
522
522
  addEventListener(type, callback, options) {
523
523
  this.subscribe(type.toString());
524
+ // @ts-expect-error have to ignore types to accommodate custom string event names
524
525
  super.addEventListener(type, callback, options);
525
526
  }
526
527
  removeEventListener(type, callback, options) {
528
+ // @ts-expect-error have to ignore types to accommodate custom string event names
527
529
  super.removeEventListener(type, callback, options);
528
530
  const topicStr = type.toString();
529
531
  if (this.listenerCount(topicStr) === 0) {