@waku/core 0.0.36-27c1236.0 → 0.0.36-34d4730.0

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/bundle/index.js CHANGED
@@ -1,8 +1,5 @@
1
- import { v as version_0, a as allocUnsafe, b as alloc, e as encodingLength$1, c as encode$2, d as decode$4, F as FilterSubscribeRequest, f as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, g as PushResponse, S as StoreQueryRequest$1, h as StoreQueryResponse$1, t as toString$1, i as bases, j as fromString, u as utf8ToBytes, k as createEncoder, p as pubsubTopicToSingleShardInfo, l as bytesToUtf8, s as shardInfoToPubsubTopics, W as WakuMetadataRequest, m as pubsubTopicsToShardInfo, n as WakuMetadataResponse, o as concat$1, q as sha256, r as bytesToHex, w as numberToBytes } from './version_0-CyeTW0Vr.js';
2
- export { x as createDecoder } from './version_0-CyeTW0Vr.js';
3
- import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, L as Logger, P as ProtocolError, T as Tags, E as EPeersByDiscoveryEvents, f as EConnectionStateEvents } from './index-CTo1my9M.js';
4
- import { B as BaseProtocol } from './base_protocol-DvQrudwy.js';
5
- export { S as StreamManager } from './base_protocol-DvQrudwy.js';
1
+ import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, v as version_0, f as allocUnsafe, g as alloc, h as encodingLength$1, i as encode$2, j as decode$4, L as Logger, F as FilterSubscribeRequest, k as FilterSubscribeResponse$1, M as MessagePush, P as ProtocolError, l as PushRpc$1, m as PushResponse, S as StoreQueryRequest$1, n as StoreQueryResponse$1, t as toString$1, o as bases, p as fromString, u as utf8ToBytes, q as createEncoder, r as pubsubTopicToSingleShardInfo, s as bytesToUtf8, T as Tags, E as EPeersByDiscoveryEvents, w as shardInfoToPubsubTopics, x as EConnectionStateEvents, W as WakuMetadataRequest, y as pubsubTopicsToShardInfo, z as WakuMetadataResponse, A as concat$1, B as sha256, C as bytesToHex, D as numberToBytes } from './version_0-BhBcavwU.js';
2
+ export { G as createDecoder } from './version_0-BhBcavwU.js';
6
3
 
7
4
  /* eslint-disable */
8
5
  var encode_1 = encode$1;
@@ -2136,6 +2133,129 @@ const duplexPipelineFn = (duplex) => {
2136
2133
  };
2137
2134
  };
2138
2135
 
2136
+ function selectOpenConnection(connections) {
2137
+ return connections
2138
+ .filter((c) => c.status === "open")
2139
+ .sort((left, right) => right.timeline.open - left.timeline.open)
2140
+ .at(0);
2141
+ }
2142
+
2143
+ const STREAM_LOCK_KEY = "consumed";
2144
+ class StreamManager {
2145
+ multicodec;
2146
+ libp2p;
2147
+ log;
2148
+ ongoingCreation = new Set();
2149
+ streamPool = new Map();
2150
+ constructor(multicodec, libp2p) {
2151
+ this.multicodec = multicodec;
2152
+ this.libp2p = libp2p;
2153
+ this.log = new Logger(`stream-manager:${multicodec}`);
2154
+ this.libp2p.events.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
2155
+ }
2156
+ async getStream(peerId) {
2157
+ const peerIdStr = peerId.toString();
2158
+ const scheduledStream = this.streamPool.get(peerIdStr);
2159
+ if (scheduledStream) {
2160
+ this.streamPool.delete(peerIdStr);
2161
+ await scheduledStream;
2162
+ }
2163
+ let stream = this.getOpenStreamForCodec(peerId);
2164
+ if (stream) {
2165
+ this.log.info(`Found existing stream peerId=${peerIdStr} multicodec=${this.multicodec}`);
2166
+ this.lockStream(peerIdStr, stream);
2167
+ return stream;
2168
+ }
2169
+ stream = await this.createStream(peerId);
2170
+ this.lockStream(peerIdStr, stream);
2171
+ return stream;
2172
+ }
2173
+ async createStream(peerId, retries = 0) {
2174
+ const connections = this.libp2p.connectionManager.getConnections(peerId);
2175
+ const connection = selectOpenConnection(connections);
2176
+ if (!connection) {
2177
+ throw new Error(`Failed to get a connection to the peer peerId=${peerId.toString()} multicodec=${this.multicodec}`);
2178
+ }
2179
+ let lastError;
2180
+ let stream;
2181
+ for (let i = 0; i < retries + 1; i++) {
2182
+ try {
2183
+ this.log.info(`Attempting to create a stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
2184
+ stream = await connection.newStream(this.multicodec);
2185
+ this.log.info(`Created stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
2186
+ break;
2187
+ }
2188
+ catch (error) {
2189
+ lastError = error;
2190
+ }
2191
+ }
2192
+ if (!stream) {
2193
+ throw new Error(`Failed to create a new stream for ${peerId.toString()} -- ` + lastError);
2194
+ }
2195
+ return stream;
2196
+ }
2197
+ async createStreamWithLock(peer) {
2198
+ const peerId = peer.id.toString();
2199
+ if (this.ongoingCreation.has(peerId)) {
2200
+ this.log.info(`Skipping creation of a stream due to lock for peerId=${peerId} multicodec=${this.multicodec}`);
2201
+ return;
2202
+ }
2203
+ try {
2204
+ this.ongoingCreation.add(peerId);
2205
+ await this.createStream(peer.id);
2206
+ }
2207
+ catch (error) {
2208
+ this.log.error(`Failed to createStreamWithLock:`, error);
2209
+ }
2210
+ finally {
2211
+ this.ongoingCreation.delete(peerId);
2212
+ }
2213
+ return;
2214
+ }
2215
+ handlePeerUpdateStreamPool = (evt) => {
2216
+ const { peer } = evt.detail;
2217
+ if (!peer.protocols.includes(this.multicodec)) {
2218
+ return;
2219
+ }
2220
+ const stream = this.getOpenStreamForCodec(peer.id);
2221
+ if (stream) {
2222
+ return;
2223
+ }
2224
+ this.scheduleNewStream(peer);
2225
+ };
2226
+ scheduleNewStream(peer) {
2227
+ this.log.info(`Scheduling creation of a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
2228
+ // abandon previous attempt
2229
+ if (this.streamPool.has(peer.id.toString())) {
2230
+ this.streamPool.delete(peer.id.toString());
2231
+ }
2232
+ this.streamPool.set(peer.id.toString(), this.createStreamWithLock(peer));
2233
+ }
2234
+ getOpenStreamForCodec(peerId) {
2235
+ const connections = this.libp2p.connectionManager.getConnections(peerId);
2236
+ const connection = selectOpenConnection(connections);
2237
+ if (!connection) {
2238
+ return;
2239
+ }
2240
+ const stream = connection.streams.find((s) => s.protocol === this.multicodec);
2241
+ if (!stream) {
2242
+ return;
2243
+ }
2244
+ const isStreamUnusable = ["done", "closed", "closing"].includes(stream.writeStatus || "");
2245
+ if (isStreamUnusable || this.isStreamLocked(stream)) {
2246
+ return;
2247
+ }
2248
+ return stream;
2249
+ }
2250
+ lockStream(peerId, stream) {
2251
+ this.log.info(`Locking stream for peerId:${peerId}\tstreamId:${stream.id}`);
2252
+ stream.metadata[STREAM_LOCK_KEY] = true;
2253
+ }
2254
+ isStreamLocked(stream) {
2255
+ return !!stream.metadata[STREAM_LOCK_KEY];
2256
+ }
2257
+ }
2258
+
2139
2259
  // Unique ID creation requires a high quality random # generator. In the browser we therefore
2140
2260
  // require the crypto API and do not support built-in fallback to lower quality random number
2141
2261
  // generators (like Math.random()).
@@ -2303,12 +2423,14 @@ const FilterCodecs = {
2303
2423
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
2304
2424
  PUSH: "/vac/waku/filter-push/2.0.0-beta1"
2305
2425
  };
2306
- class FilterCore extends BaseProtocol {
2426
+ class FilterCore {
2307
2427
  pubsubTopics;
2428
+ streamManager;
2308
2429
  static handleIncomingMessage;
2430
+ multicodec = FilterCodecs.SUBSCRIBE;
2309
2431
  constructor(handleIncomingMessage, pubsubTopics, libp2p) {
2310
- super(FilterCodecs.SUBSCRIBE, libp2p.components, pubsubTopics);
2311
2432
  this.pubsubTopics = pubsubTopics;
2433
+ this.streamManager = new StreamManager(FilterCodecs.SUBSCRIBE, libp2p.components);
2312
2434
  // TODO(weboko): remove when @waku/sdk 0.0.33 is released
2313
2435
  const prevHandler = FilterCore.handleIncomingMessage;
2314
2436
  FilterCore.handleIncomingMessage = !prevHandler
@@ -2337,7 +2459,7 @@ class FilterCore extends BaseProtocol {
2337
2459
  });
2338
2460
  }
2339
2461
  async subscribe(pubsubTopic, peerId, contentTopics) {
2340
- const stream = await this.getStream(peerId);
2462
+ const stream = await this.streamManager.getStream(peerId);
2341
2463
  const request = FilterSubscribeRpc.createSubscribeRequest(pubsubTopic, contentTopics);
2342
2464
  let res;
2343
2465
  try {
@@ -2372,7 +2494,7 @@ class FilterCore extends BaseProtocol {
2372
2494
  async unsubscribe(pubsubTopic, peerId, contentTopics) {
2373
2495
  let stream;
2374
2496
  try {
2375
- stream = await this.getStream(peerId);
2497
+ stream = await this.streamManager.getStream(peerId);
2376
2498
  }
2377
2499
  catch (error) {
2378
2500
  log$5.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
@@ -2404,7 +2526,7 @@ class FilterCore extends BaseProtocol {
2404
2526
  };
2405
2527
  }
2406
2528
  async unsubscribeAll(pubsubTopic, peerId) {
2407
- const stream = await this.getStream(peerId);
2529
+ const stream = await this.streamManager.getStream(peerId);
2408
2530
  const request = FilterSubscribeRpc.createUnsubscribeAllRequest(pubsubTopic);
2409
2531
  const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
2410
2532
  if (!res || !res.length) {
@@ -2435,7 +2557,7 @@ class FilterCore extends BaseProtocol {
2435
2557
  async ping(peerId) {
2436
2558
  let stream;
2437
2559
  try {
2438
- stream = await this.getStream(peerId);
2560
+ stream = await this.streamManager.getStream(peerId);
2439
2561
  }
2440
2562
  catch (error) {
2441
2563
  log$5.error(`Failed to get a stream for remote peer${peerId.toString()}`, error);
@@ -2577,11 +2699,13 @@ const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
2577
2699
  /**
2578
2700
  * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
2579
2701
  */
2580
- class LightPushCore extends BaseProtocol {
2702
+ class LightPushCore {
2581
2703
  pubsubTopics;
2704
+ streamManager;
2705
+ multicodec = LightPushCodec;
2582
2706
  constructor(pubsubTopics, libp2p) {
2583
- super(LightPushCodec, libp2p.components, pubsubTopics);
2584
2707
  this.pubsubTopics = pubsubTopics;
2708
+ this.streamManager = new StreamManager(LightPushCodec, libp2p.components);
2585
2709
  }
2586
2710
  async preparePushMessage(encoder, message) {
2587
2711
  try {
@@ -2625,7 +2749,7 @@ class LightPushCore extends BaseProtocol {
2625
2749
  }
2626
2750
  let stream;
2627
2751
  try {
2628
- stream = await this.getStream(peerId);
2752
+ stream = await this.streamManager.getStream(peerId);
2629
2753
  }
2630
2754
  catch (error) {
2631
2755
  log$4.error("Failed to get stream", error);
@@ -2804,11 +2928,13 @@ class StoreQueryResponse {
2804
2928
 
2805
2929
  const log$3 = new Logger("store");
2806
2930
  const StoreCodec = "/vac/waku/store-query/3.0.0";
2807
- class StoreCore extends BaseProtocol {
2931
+ class StoreCore {
2808
2932
  pubsubTopics;
2933
+ streamManager;
2934
+ multicodec = StoreCodec;
2809
2935
  constructor(pubsubTopics, libp2p) {
2810
- super(StoreCodec, libp2p.components, pubsubTopics);
2811
2936
  this.pubsubTopics = pubsubTopics;
2937
+ this.streamManager = new StreamManager(StoreCodec, libp2p.components);
2812
2938
  }
2813
2939
  async *queryPerPage(queryOpts, decoders, peerId) {
2814
2940
  // Only validate decoder content topics for content-filtered queries
@@ -2833,7 +2959,7 @@ class StoreCore extends BaseProtocol {
2833
2959
  });
2834
2960
  let stream;
2835
2961
  try {
2836
- stream = await this.getStream(peerId);
2962
+ stream = await this.streamManager.getStream(peerId);
2837
2963
  }
2838
2964
  catch (e) {
2839
2965
  log$3.error("Failed to get stream", e);
@@ -4783,13 +4909,15 @@ class ConnectionManager extends TypedEventEmitter {
4783
4909
 
4784
4910
  const log = new Logger("metadata");
4785
4911
  const MetadataCodec = "/vac/waku/metadata/1.0.0";
4786
- class Metadata extends BaseProtocol {
4912
+ class Metadata {
4787
4913
  pubsubTopics;
4914
+ streamManager;
4788
4915
  libp2pComponents;
4789
4916
  handshakesConfirmed = new Map();
4917
+ multicodec = MetadataCodec;
4790
4918
  constructor(pubsubTopics, libp2p) {
4791
- super(MetadataCodec, libp2p.components, pubsubTopics);
4792
4919
  this.pubsubTopics = pubsubTopics;
4920
+ this.streamManager = new StreamManager(MetadataCodec, libp2p);
4793
4921
  this.libp2pComponents = libp2p;
4794
4922
  void libp2p.registrar.handle(MetadataCodec, (streamData) => {
4795
4923
  void this.onRequest(streamData);
@@ -4809,7 +4937,7 @@ class Metadata extends BaseProtocol {
4809
4937
  }
4810
4938
  let stream;
4811
4939
  try {
4812
- stream = await this.getStream(peerId);
4940
+ stream = await this.streamManager.getStream(peerId);
4813
4941
  }
4814
4942
  catch (error) {
4815
4943
  log.error("Failed to get stream", error);
@@ -4973,4 +5101,4 @@ function messageHashStr(pubsubTopic, message) {
4973
5101
  return hashStr;
4974
5102
  }
4975
5103
 
4976
- export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, createEncoder, index$3 as message, messageHash, messageHashStr, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
5104
+ export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, StreamManager, createEncoder, index$3 as message, messageHash, messageHashStr, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
@@ -1,2 +1 @@
1
- export { D as DecodedMessage, z as Decoder, E as Encoder, V as Version, x as createDecoder, k as createEncoder, y as proto } from '../../version_0-CyeTW0Vr.js';
2
- import '../../index-CTo1my9M.js';
1
+ export { I as DecodedMessage, K as Decoder, J as Encoder, V as Version, G as createDecoder, q as createEncoder, H as proto } from '../../version_0-BhBcavwU.js';