@waku/core 0.0.18 → 0.0.19

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/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  The file is maintained by [Release Please](https://github.com/googleapis/release-please) based on [Conventional Commits](https://www.conventionalcommits.org) specification,
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.0.19](https://github.com/waku-org/js-waku/compare/core-v0.0.18...core-v0.0.19) (2023-05-26)
9
+
10
+
11
+ ### ⚠ BREAKING CHANGES
12
+
13
+ * filter v2 ([#1332](https://github.com/waku-org/js-waku/issues/1332))
14
+
15
+ ### Features
16
+
17
+ * Filter v2 ([#1332](https://github.com/waku-org/js-waku/issues/1332)) ([8d0e647](https://github.com/waku-org/js-waku/commit/8d0e64796695fbafad0a033552eb4412bdff3d78))
18
+
19
+
20
+ ### Dependencies
21
+
22
+ * The following workspace dependencies were updated
23
+ * dependencies
24
+ * @waku/interfaces bumped from 0.0.13 to 0.0.14
25
+ * @waku/proto bumped from * to 0.0.5
26
+ * @waku/utils bumped from 0.0.6 to 0.0.7
27
+
8
28
  ## [0.0.18](https://github.com/waku-org/js-waku/compare/core-v0.0.17...core-v0.0.18) (2023-05-18)
9
29
 
10
30
 
package/bundle/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { g as getDefaultExportFromCjs, d as debug } from './browser-bde977a3.js';
2
- import { c as createEncoder, v as version_0, F as FilterRpc$1, P as PushRpc$1, a as PushResponse, H as HistoryRpc$1, b as PagingInfo, d as HistoryResponse } from './version_0-c6b47311.js';
3
- export { e as createDecoder } from './version_0-c6b47311.js';
2
+ import { c as createEncoder, v as version_0, F as FilterRpc$1, M as MessagePush, a as FilterSubscribeRequest, b as FilterSubscribeResponse$1, P as PushRpc$1, d as PushResponse, H as HistoryRpc$1, e as PagingInfo, f as HistoryResponse } from './version_0-9c941081.js';
3
+ export { g as createDecoder } from './version_0-9c941081.js';
4
4
  import { BaseProtocol } from './lib/base_protocol.js';
5
5
 
6
6
  const symbol$2 = Symbol.for('@libp2p/peer-id');
@@ -2975,7 +2975,7 @@ var Tags;
2975
2975
  })(Tags || (Tags = {}));
2976
2976
 
2977
2977
  const RelayPingContentTopic = "/relay-ping/1/ping/null";
2978
- const log$6 = debug("waku:keep-alive");
2978
+ const log$7 = debug("waku:keep-alive");
2979
2979
  class KeepAliveManager {
2980
2980
  pingKeepAliveTimers;
2981
2981
  relayKeepAliveTimers;
@@ -2995,7 +2995,7 @@ class KeepAliveManager {
2995
2995
  if (pingPeriodSecs !== 0) {
2996
2996
  const interval = setInterval(() => {
2997
2997
  libp2pPing(peerId).catch((e) => {
2998
- log$6(`Ping failed (${peerIdStr})`, e);
2998
+ log$7(`Ping failed (${peerIdStr})`, e);
2999
2999
  });
3000
3000
  }, pingPeriodSecs * 1000);
3001
3001
  this.pingKeepAliveTimers.set(peerIdStr, interval);
@@ -3007,10 +3007,10 @@ class KeepAliveManager {
3007
3007
  ephemeral: true,
3008
3008
  });
3009
3009
  const interval = setInterval(() => {
3010
- log$6("Sending Waku Relay ping message");
3010
+ log$7("Sending Waku Relay ping message");
3011
3011
  relay
3012
3012
  .send(encoder, { payload: new Uint8Array([1]) })
3013
- .catch((e) => log$6("Failed to send relay ping", e));
3013
+ .catch((e) => log$7("Failed to send relay ping", e));
3014
3014
  }, relayPeriodSecs * 1000);
3015
3015
  this.relayKeepAliveTimers.set(peerId, interval);
3016
3016
  }
@@ -3038,7 +3038,7 @@ class KeepAliveManager {
3038
3038
  }
3039
3039
  }
3040
3040
 
3041
- const log$5 = debug("waku:connection-manager");
3041
+ const log$6 = debug("waku:connection-manager");
3042
3042
  const DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED = 1;
3043
3043
  const DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER = 3;
3044
3044
  class ConnectionManager {
@@ -3065,8 +3065,8 @@ class ConnectionManager {
3065
3065
  };
3066
3066
  this.keepAliveManager = new KeepAliveManager(keepAliveOptions, relay);
3067
3067
  this.run()
3068
- .then(() => log$5(`Connection Manager is now running`))
3069
- .catch((error) => log$5(`Unexpected error while running service`, error));
3068
+ .then(() => log$6(`Connection Manager is now running`))
3069
+ .catch((error) => log$6(`Unexpected error while running service`, error));
3070
3070
  }
3071
3071
  async run() {
3072
3072
  // start event listeners
@@ -3084,7 +3084,7 @@ class ConnectionManager {
3084
3084
  let dialAttempt = 0;
3085
3085
  while (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3086
3086
  try {
3087
- log$5(`Dialing peer ${peerId.toString()}`);
3087
+ log$6(`Dialing peer ${peerId.toString()}`);
3088
3088
  await this.libp2pComponents.dial(peerId);
3089
3089
  const tags = await this.getTagNamesForPeer(peerId);
3090
3090
  // add tag to connection describing discovery mechanism
@@ -3098,16 +3098,16 @@ class ConnectionManager {
3098
3098
  catch (e) {
3099
3099
  const error = e;
3100
3100
  this.dialErrorsForPeer.set(peerId.toString(), error);
3101
- log$5(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3101
+ log$6(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3102
3102
  dialAttempt = this.dialAttemptsForPeer.get(peerId.toString()) ?? 1;
3103
3103
  this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt + 1);
3104
3104
  if (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3105
- log$5(`Reattempting dial (${dialAttempt})`);
3105
+ log$6(`Reattempting dial (${dialAttempt})`);
3106
3106
  }
3107
3107
  }
3108
3108
  }
3109
3109
  try {
3110
- log$5(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${JSON.stringify(this.dialErrorsForPeer.get(peerId.toString()).errors[0])}
3110
+ log$6(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${JSON.stringify(this.dialErrorsForPeer.get(peerId.toString()).errors[0])}
3111
3111
  }`);
3112
3112
  this.dialErrorsForPeer.delete(peerId.toString());
3113
3113
  return await this.libp2pComponents.peerStore.delete(peerId);
@@ -3142,7 +3142,7 @@ class ConnectionManager {
3142
3142
  const { id: peerId } = evt.detail;
3143
3143
  if (!(await this.shouldDialPeer(peerId)))
3144
3144
  return;
3145
- this.dialPeer(peerId).catch((err) => log$5(`Error dialing peer ${peerId.toString()} : ${err}`));
3145
+ this.dialPeer(peerId).catch((err) => log$6(`Error dialing peer ${peerId.toString()} : ${err}`));
3146
3146
  },
3147
3147
  "peer:connect": (evt) => {
3148
3148
  {
@@ -3191,7 +3191,7 @@ class ConnectionManager {
3191
3191
  const DefaultPingKeepAliveValueSecs = 0;
3192
3192
  const DefaultRelayKeepAliveValueSecs = 5 * 60;
3193
3193
  const DefaultUserAgent = "js-waku";
3194
- const log$4 = debug("waku:waku");
3194
+ const log$5 = debug("waku:waku");
3195
3195
  class WakuNode {
3196
3196
  libp2p;
3197
3197
  relay;
@@ -3219,7 +3219,7 @@ class WakuNode {
3219
3219
  : 0;
3220
3220
  const peerId = this.libp2p.peerId.toString();
3221
3221
  this.connectionManager = ConnectionManager.create(peerId, libp2p, { pingKeepAlive, relayKeepAlive }, this.relay);
3222
- log$4("Waku node created", peerId, `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
3222
+ log$5("Waku node created", peerId, `relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
3223
3223
  .lightPush}, filter: ${!!this.filter}`);
3224
3224
  }
3225
3225
  /**
@@ -3243,7 +3243,7 @@ class WakuNode {
3243
3243
  this.relay.gossipSub.multicodecs.forEach((codec) => codecs.push(codec));
3244
3244
  }
3245
3245
  else {
3246
- log$4("Relay codec not included in dial codec: protocol not mounted locally");
3246
+ log$5("Relay codec not included in dial codec: protocol not mounted locally");
3247
3247
  }
3248
3248
  }
3249
3249
  if (_protocols.includes(Protocols.Store)) {
@@ -3251,7 +3251,7 @@ class WakuNode {
3251
3251
  codecs.push(this.store.multicodec);
3252
3252
  }
3253
3253
  else {
3254
- log$4("Store codec not included in dial codec: protocol not mounted locally");
3254
+ log$5("Store codec not included in dial codec: protocol not mounted locally");
3255
3255
  }
3256
3256
  }
3257
3257
  if (_protocols.includes(Protocols.LightPush)) {
@@ -3259,7 +3259,7 @@ class WakuNode {
3259
3259
  codecs.push(this.lightPush.multicodec);
3260
3260
  }
3261
3261
  else {
3262
- log$4("Light Push codec not included in dial codec: protocol not mounted locally");
3262
+ log$5("Light Push codec not included in dial codec: protocol not mounted locally");
3263
3263
  }
3264
3264
  }
3265
3265
  if (_protocols.includes(Protocols.Filter)) {
@@ -3267,10 +3267,10 @@ class WakuNode {
3267
3267
  codecs.push(this.filter.multicodec);
3268
3268
  }
3269
3269
  else {
3270
- log$4("Filter codec not included in dial codec: protocol not mounted locally");
3270
+ log$5("Filter codec not included in dial codec: protocol not mounted locally");
3271
3271
  }
3272
3272
  }
3273
- log$4(`Dialing to ${peerId.toString()} with protocols ${_protocols}`);
3273
+ log$5(`Dialing to ${peerId.toString()} with protocols ${_protocols}`);
3274
3274
  return this.libp2p.dialProtocol(peerId, codecs);
3275
3275
  }
3276
3276
  async start() {
@@ -3315,7 +3315,7 @@ var waku = /*#__PURE__*/Object.freeze({
3315
3315
  */
3316
3316
  const DefaultPubSubTopic = "/waku/2/default-waku/proto";
3317
3317
 
3318
- var index$3 = /*#__PURE__*/Object.freeze({
3318
+ var index$4 = /*#__PURE__*/Object.freeze({
3319
3319
  __proto__: null,
3320
3320
  version_0: version_0
3321
3321
  });
@@ -4876,7 +4876,7 @@ class FilterRpc {
4876
4876
  }
4877
4877
 
4878
4878
  const FilterCodec = "/vac/waku/filter/2.0.0-beta1";
4879
- const log$3 = debug("waku:filter");
4879
+ const log$4 = debug("waku:filter");
4880
4880
  /**
4881
4881
  * Implements client side of the [Waku v2 Filter protocol](https://rfc.vac.dev/spec/12/).
4882
4882
  *
@@ -4895,7 +4895,7 @@ class Filter extends BaseProtocol {
4895
4895
  this.subscriptions = new Map();
4896
4896
  this.libp2p
4897
4897
  .handle(this.multicodec, this.onRequest.bind(this))
4898
- .catch((e) => log$3("Failed to register filter protocol", e));
4898
+ .catch((e) => log$4("Failed to register filter protocol", e));
4899
4899
  }
4900
4900
  /**
4901
4901
  * @param decoders Decoder or array of Decoders to use to decode messages, it also specifies the content topics.
@@ -4916,10 +4916,10 @@ class Filter extends BaseProtocol {
4916
4916
  const stream = await this.newStream(peer);
4917
4917
  try {
4918
4918
  const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
4919
- log$3("response", res);
4919
+ log$4("response", res);
4920
4920
  }
4921
4921
  catch (e) {
4922
- log$3("Error subscribing to peer ", peer.id.toString(), "for content topics", contentTopics, ": ", e);
4922
+ log$4("Error subscribing to peer ", peer.id.toString(), "for content topics", contentTopics, ": ", e);
4923
4923
  throw e;
4924
4924
  }
4925
4925
  const subscription = {
@@ -4947,7 +4947,7 @@ class Filter extends BaseProtocol {
4947
4947
  return map;
4948
4948
  }
4949
4949
  onRequest(streamData) {
4950
- log$3("Receiving message push");
4950
+ log$4("Receiving message push");
4951
4951
  try {
4952
4952
  pipe(streamData.stream, decode, async (source) => {
4953
4953
  for await (const bytes of source) {
@@ -4957,30 +4957,30 @@ class Filter extends BaseProtocol {
4957
4957
  }
4958
4958
  }
4959
4959
  }).then(() => {
4960
- log$3("Receiving pipe closed.");
4960
+ log$4("Receiving pipe closed.");
4961
4961
  }, (e) => {
4962
- log$3("Error with receiving pipe", e);
4962
+ log$4("Error with receiving pipe", e);
4963
4963
  });
4964
4964
  }
4965
4965
  catch (e) {
4966
- log$3("Error decoding message", e);
4966
+ log$4("Error decoding message", e);
4967
4967
  }
4968
4968
  }
4969
4969
  async pushMessages(requestId, messages) {
4970
4970
  const subscription = this.subscriptions.get(requestId);
4971
4971
  if (!subscription) {
4972
- log$3(`No subscription locally registered for request ID ${requestId}`);
4972
+ log$4(`No subscription locally registered for request ID ${requestId}`);
4973
4973
  return;
4974
4974
  }
4975
4975
  const { decoders, callback, pubSubTopic } = subscription;
4976
4976
  if (!decoders || !decoders.length) {
4977
- log$3(`No decoder registered for request ID ${requestId}`);
4977
+ log$4(`No decoder registered for request ID ${requestId}`);
4978
4978
  return;
4979
4979
  }
4980
4980
  for (const protoMessage of messages) {
4981
4981
  const contentTopic = protoMessage.contentTopic;
4982
4982
  if (!contentTopic) {
4983
- log$3("Message has no content topic, skipping");
4983
+ log$4("Message has no content topic, skipping");
4984
4984
  return;
4985
4985
  }
4986
4986
  let didDecodeMsg = false;
@@ -4992,7 +4992,7 @@ class Filter extends BaseProtocol {
4992
4992
  return;
4993
4993
  const decoded = await dec.fromProtoObj(pubSubTopic, toProtoMessage(protoMessage));
4994
4994
  if (!decoded) {
4995
- log$3("Not able to decode message");
4995
+ log$4("Not able to decode message");
4996
4996
  return;
4997
4997
  }
4998
4998
  // This is just to prevent more decoding attempt
@@ -5009,7 +5009,7 @@ class Filter extends BaseProtocol {
5009
5009
  await pipe([unsubscribeRequest.encode()], encode, stream.sink);
5010
5010
  }
5011
5011
  catch (e) {
5012
- log$3("Error unsubscribing", e);
5012
+ log$4("Error unsubscribing", e);
5013
5013
  throw e;
5014
5014
  }
5015
5015
  }
@@ -5018,12 +5018,351 @@ function wakuFilter(init = {}) {
5018
5018
  return (libp2p) => new Filter(libp2p, init);
5019
5019
  }
5020
5020
 
5021
- var index$2 = /*#__PURE__*/Object.freeze({
5021
+ var index$3 = /*#__PURE__*/Object.freeze({
5022
5022
  __proto__: null,
5023
5023
  FilterCodec: FilterCodec,
5024
5024
  wakuFilter: wakuFilter
5025
5025
  });
5026
5026
 
5027
+ /**
5028
+ * FilterPushRPC represents a message conforming to the Waku FilterPush protocol.
5029
+ * Protocol documentation: https://rfc.vac.dev/spec/12/
5030
+ */
5031
+ class FilterPushRpc {
5032
+ proto;
5033
+ constructor(proto) {
5034
+ this.proto = proto;
5035
+ }
5036
+ static decode(bytes) {
5037
+ const res = MessagePush.decode(bytes);
5038
+ return new FilterPushRpc(res);
5039
+ }
5040
+ encode() {
5041
+ return MessagePush.encode(this.proto);
5042
+ }
5043
+ get wakuMessage() {
5044
+ return this.proto.wakuMessage;
5045
+ }
5046
+ /**
5047
+ * Get the pubsub topic from the FilterPushRpc object.
5048
+ * @returns string
5049
+ */
5050
+ get pubsubTopic() {
5051
+ return this.proto.pubsubTopic;
5052
+ }
5053
+ }
5054
+ class FilterSubscribeRpc {
5055
+ proto;
5056
+ constructor(proto) {
5057
+ this.proto = proto;
5058
+ }
5059
+ static createSubscribeRequest(pubsubTopic, contentTopics) {
5060
+ return new FilterSubscribeRpc({
5061
+ requestId: v4(),
5062
+ filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.SUBSCRIBE,
5063
+ pubsubTopic,
5064
+ contentTopics,
5065
+ });
5066
+ }
5067
+ static createUnsubscribeRequest(pubsubTopic, contentTopics) {
5068
+ return new FilterSubscribeRpc({
5069
+ requestId: v4(),
5070
+ filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.UNSUBSCRIBE,
5071
+ pubsubTopic,
5072
+ contentTopics,
5073
+ });
5074
+ }
5075
+ static createUnsubscribeAllRequest(pubsubTopic) {
5076
+ return new FilterSubscribeRpc({
5077
+ requestId: v4(),
5078
+ filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.UNSUBSCRIBE_ALL,
5079
+ pubsubTopic,
5080
+ contentTopics: [],
5081
+ });
5082
+ }
5083
+ static createSubscriberPingRequest() {
5084
+ return new FilterSubscribeRpc({
5085
+ requestId: v4(),
5086
+ filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.SUBSCRIBER_PING,
5087
+ pubsubTopic: "",
5088
+ contentTopics: [],
5089
+ });
5090
+ }
5091
+ static decode(bytes) {
5092
+ const res = FilterSubscribeRequest.decode(bytes);
5093
+ return new FilterSubscribeRpc(res);
5094
+ }
5095
+ encode() {
5096
+ return FilterSubscribeRequest.encode(this.proto);
5097
+ }
5098
+ get filterSubscribeType() {
5099
+ return this.proto.filterSubscribeType;
5100
+ }
5101
+ get requestId() {
5102
+ return this.proto.requestId;
5103
+ }
5104
+ get pubsubTopic() {
5105
+ return this.proto.pubsubTopic;
5106
+ }
5107
+ get contentTopics() {
5108
+ return this.proto.contentTopics;
5109
+ }
5110
+ }
5111
+ class FilterSubscribeResponse {
5112
+ proto;
5113
+ constructor(proto) {
5114
+ this.proto = proto;
5115
+ }
5116
+ static decode(bytes) {
5117
+ const res = FilterSubscribeResponse$1.decode(bytes);
5118
+ return new FilterSubscribeResponse(res);
5119
+ }
5120
+ encode() {
5121
+ return FilterSubscribeResponse$1.encode(this.proto);
5122
+ }
5123
+ get statusCode() {
5124
+ return this.proto.statusCode;
5125
+ }
5126
+ get statusDesc() {
5127
+ return this.proto.statusDesc;
5128
+ }
5129
+ get requestId() {
5130
+ return this.proto.requestId;
5131
+ }
5132
+ }
5133
+
5134
+ const log$3 = debug("waku:filter:v2");
5135
+ const FilterV2Codecs = {
5136
+ SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
5137
+ PUSH: "/vac/waku/filter-push/2.0.0-beta1",
5138
+ };
5139
+ class Subscription {
5140
+ peer;
5141
+ pubSubTopic;
5142
+ newStream;
5143
+ subscriptionCallbacks;
5144
+ constructor(pubSubTopic, remotePeer, newStream) {
5145
+ this.peer = remotePeer;
5146
+ this.pubSubTopic = pubSubTopic;
5147
+ this.newStream = newStream;
5148
+ this.subscriptionCallbacks = new Map();
5149
+ }
5150
+ async subscribe(decoders, callback) {
5151
+ const decodersArray = Array.isArray(decoders) ? decoders : [decoders];
5152
+ const decodersGroupedByCT = groupByContentTopic(decodersArray);
5153
+ const contentTopics = Array.from(decodersGroupedByCT.keys());
5154
+ const stream = await this.newStream(this.peer);
5155
+ const request = FilterSubscribeRpc.createSubscribeRequest(this.pubSubTopic, contentTopics);
5156
+ try {
5157
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
5158
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
5159
+ if (statusCode < 200 || statusCode >= 300) {
5160
+ throw new Error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
5161
+ }
5162
+ log$3("Subscribed to peer ", this.peer.id.toString(), "for content topics", contentTopics);
5163
+ }
5164
+ catch (e) {
5165
+ throw new Error("Error subscribing to peer: " +
5166
+ this.peer.id.toString() +
5167
+ " for content topics: " +
5168
+ contentTopics +
5169
+ ": " +
5170
+ e);
5171
+ }
5172
+ // Save the callback functions by content topics so they
5173
+ // can easily be removed (reciprocally replaced) if `unsubscribe` (reciprocally `subscribe`)
5174
+ // is called for those content topics
5175
+ decodersGroupedByCT.forEach((decoders, contentTopic) => {
5176
+ // Cast the type because a given `subscriptionCallbacks` map may hold
5177
+ // Decoder that decode to different implementations of `IDecodedMessage`
5178
+ const subscriptionCallback = {
5179
+ decoders,
5180
+ callback,
5181
+ };
5182
+ // The callback and decoder may override previous values, this is on
5183
+ // purpose as the user may call `subscribe` to refresh the subscription
5184
+ this.subscriptionCallbacks.set(contentTopic, subscriptionCallback);
5185
+ });
5186
+ }
5187
+ async unsubscribe(contentTopics) {
5188
+ const stream = await this.newStream(this.peer);
5189
+ const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(this.pubSubTopic, contentTopics);
5190
+ try {
5191
+ await pipe([unsubscribeRequest.encode()], encode, stream.sink);
5192
+ }
5193
+ catch (error) {
5194
+ throw new Error("Error subscribing: " + error);
5195
+ }
5196
+ contentTopics.forEach((contentTopic) => {
5197
+ this.subscriptionCallbacks.delete(contentTopic);
5198
+ });
5199
+ }
5200
+ async ping() {
5201
+ const stream = await this.newStream(this.peer);
5202
+ const request = FilterSubscribeRpc.createSubscriberPingRequest();
5203
+ try {
5204
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
5205
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
5206
+ if (statusCode < 200 || statusCode >= 300) {
5207
+ throw new Error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
5208
+ }
5209
+ log$3("Ping successful");
5210
+ }
5211
+ catch (error) {
5212
+ log$3("Error pinging: ", error);
5213
+ throw new Error("Error pinging: " + error);
5214
+ }
5215
+ }
5216
+ async unsubscribeAll() {
5217
+ const stream = await this.newStream(this.peer);
5218
+ const request = FilterSubscribeRpc.createUnsubscribeAllRequest(this.pubSubTopic);
5219
+ try {
5220
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
5221
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
5222
+ if (statusCode < 200 || statusCode >= 300) {
5223
+ throw new Error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
5224
+ }
5225
+ this.subscriptionCallbacks.clear();
5226
+ log$3("Unsubscribed from all content topics");
5227
+ }
5228
+ catch (error) {
5229
+ throw new Error("Error unsubscribing from all content topics: " + error);
5230
+ }
5231
+ }
5232
+ async processMessage(message) {
5233
+ const contentTopic = message.contentTopic;
5234
+ const subscriptionCallback = this.subscriptionCallbacks.get(contentTopic);
5235
+ if (!subscriptionCallback) {
5236
+ log$3("No subscription callback available for ", contentTopic);
5237
+ return;
5238
+ }
5239
+ await pushMessage(subscriptionCallback, this.pubSubTopic, message);
5240
+ }
5241
+ }
5242
+ class FilterV2 extends BaseProtocol {
5243
+ libp2p;
5244
+ options;
5245
+ activeSubscriptions = new Map();
5246
+ getActiveSubscription(pubSubTopic, peerIdStr) {
5247
+ return this.activeSubscriptions.get(`${pubSubTopic}_${peerIdStr}`);
5248
+ }
5249
+ setActiveSubscription(pubSubTopic, peerIdStr, subscription) {
5250
+ this.activeSubscriptions.set(`${pubSubTopic}_${peerIdStr}`, subscription);
5251
+ return subscription;
5252
+ }
5253
+ constructor(libp2p, options) {
5254
+ super(FilterV2Codecs.SUBSCRIBE, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
5255
+ this.libp2p = libp2p;
5256
+ this.libp2p
5257
+ .handle(FilterV2Codecs.PUSH, this.onRequest.bind(this))
5258
+ .catch((e) => {
5259
+ log$3("Failed to register ", FilterV2Codecs.PUSH, e);
5260
+ });
5261
+ this.activeSubscriptions = new Map();
5262
+ this.options = options ?? {};
5263
+ }
5264
+ async createSubscription(pubSubTopic, peerId) {
5265
+ const _pubSubTopic = pubSubTopic ?? this.options.pubSubTopic ?? DefaultPubSubTopic;
5266
+ const peer = await this.getPeer(peerId);
5267
+ const subscription = this.getActiveSubscription(_pubSubTopic, peer.id.toString()) ??
5268
+ this.setActiveSubscription(_pubSubTopic, peer.id.toString(), new Subscription(_pubSubTopic, peer, this.newStream.bind(this, peer)));
5269
+ return subscription;
5270
+ }
5271
+ toSubscriptionIterator(decoders, opts) {
5272
+ return toAsyncIterator(this, decoders, opts);
5273
+ }
5274
+ /**
5275
+ * This method is used to satisfy the `IReceiver` interface.
5276
+ *
5277
+ * @hidden
5278
+ *
5279
+ * @param decoders The decoders to use for the subscription.
5280
+ * @param callback The callback function to use for the subscription.
5281
+ * @param opts Optional protocol options for the subscription.
5282
+ *
5283
+ * @returns A Promise that resolves to a function that unsubscribes from the subscription.
5284
+ *
5285
+ * @remarks
5286
+ * This method should not be used directly.
5287
+ * Instead, use `createSubscription` to create a new subscription.
5288
+ */
5289
+ async subscribe(decoders, callback, opts) {
5290
+ const subscription = await this.createSubscription(undefined, opts?.peerId);
5291
+ subscription.subscribe(decoders, callback);
5292
+ const contentTopics = Array.from(groupByContentTopic(Array.isArray(decoders) ? decoders : [decoders]).keys());
5293
+ return async () => {
5294
+ await subscription.unsubscribe(contentTopics);
5295
+ };
5296
+ }
5297
+ onRequest(streamData) {
5298
+ log$3("Receiving message push");
5299
+ try {
5300
+ pipe(streamData.stream, decode, async (source) => {
5301
+ for await (const bytes of source) {
5302
+ const response = FilterPushRpc.decode(bytes.slice());
5303
+ const { pubsubTopic, wakuMessage } = response;
5304
+ if (!wakuMessage) {
5305
+ log$3("Received empty message");
5306
+ return;
5307
+ }
5308
+ if (!pubsubTopic) {
5309
+ log$3("PubSub topic missing from push message");
5310
+ return;
5311
+ }
5312
+ const peerIdStr = streamData.connection.remotePeer.toString();
5313
+ const subscription = this.getActiveSubscription(pubsubTopic, peerIdStr);
5314
+ if (!subscription) {
5315
+ log$3(`No subscription locally registered for topic ${pubsubTopic}`);
5316
+ return;
5317
+ }
5318
+ await subscription.processMessage(wakuMessage);
5319
+ }
5320
+ }).then(() => {
5321
+ log$3("Receiving pipe closed.");
5322
+ }, (e) => {
5323
+ log$3("Error with receiving pipe", e);
5324
+ });
5325
+ }
5326
+ catch (e) {
5327
+ log$3("Error decoding message", e);
5328
+ }
5329
+ }
5330
+ }
5331
+ function wakuFilterV2(init = {}) {
5332
+ return (libp2p) => new FilterV2(libp2p, init);
5333
+ }
5334
+ async function pushMessage(subscriptionCallback, pubSubTopic, message) {
5335
+ const { decoders, callback } = subscriptionCallback;
5336
+ const { contentTopic } = message;
5337
+ if (!contentTopic) {
5338
+ log$3("Message has no content topic, skipping");
5339
+ return;
5340
+ }
5341
+ let didDecodeMsg = false;
5342
+ // We don't want to wait for decoding failure, just attempt to decode
5343
+ // all messages and do the call back on the one that works
5344
+ // noinspection ES6MissingAwait
5345
+ decoders.forEach(async (dec) => {
5346
+ if (didDecodeMsg)
5347
+ return;
5348
+ const decoded = await dec.fromProtoObj(pubSubTopic, message);
5349
+ // const decoded = await dec.fromProtoObj(pubSubTopic, message);
5350
+ if (!decoded) {
5351
+ log$3("Not able to decode message");
5352
+ return;
5353
+ }
5354
+ // This is just to prevent more decoding attempt
5355
+ // TODO: Could be better if we were to abort promises
5356
+ didDecodeMsg = Boolean(decoded);
5357
+ await callback(decoded);
5358
+ });
5359
+ }
5360
+
5361
+ var index$2 = /*#__PURE__*/Object.freeze({
5362
+ __proto__: null,
5363
+ wakuFilterV2: wakuFilterV2
5364
+ });
5365
+
5027
5366
  class PushRpc {
5028
5367
  proto;
5029
5368
  constructor(proto) {
@@ -6074,4 +6413,4 @@ function getEnabledProtocols(waku) {
6074
6413
  return protocols;
6075
6414
  }
6076
6415
 
6077
- export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, KeepAliveManager, LightPushCodec, PageDirection, StoreCodec, WakuNode, createCursor, createEncoder, index$3 as message, waitForRemotePeer, waku, wakuFilter, wakuLightPush, wakuStore, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
6416
+ export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, KeepAliveManager, LightPushCodec, PageDirection, StoreCodec, WakuNode, createCursor, createEncoder, index$4 as message, waitForRemotePeer, waku, wakuFilter as wakuFilterV1, wakuFilterV2, wakuLightPush, wakuStore, index$3 as waku_filter_v1, index$2 as waku_filter_v2, index$1 as waku_light_push, index as waku_store };
@@ -1,2 +1,2 @@
1
- export { D as DecodedMessage, f as Decoder, E as Encoder, V as Version, e as createDecoder, c as createEncoder, m as proto } from '../../version_0-c6b47311.js';
1
+ export { D as DecodedMessage, h as Decoder, E as Encoder, V as Version, g as createDecoder, c as createEncoder, m as proto } from '../../version_0-9c941081.js';
2
2
  import '../../browser-bde977a3.js';