@waku/core 0.0.28 → 0.0.29-3ec2344.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.
Files changed (35) hide show
  1. package/bundle/{base_protocol-D0Zdzb-v.js → base_protocol-3fdjkRTX.js} +60 -18
  2. package/bundle/{browser-DoQRY-an.js → browser-H8Jgqifo.js} +5 -0
  3. package/bundle/{index-BJwgMx4y.js → index-BQ8SG1DC.js} +11 -20
  4. package/bundle/index.js +106 -362
  5. package/bundle/lib/base_protocol.js +3 -3
  6. package/bundle/lib/message/version_0.js +3 -3
  7. package/bundle/lib/predefined_bootstrap_nodes.js +1 -1
  8. package/bundle/{version_0-C6o0DvNW.js → version_0-D_Nwtppu.js} +5 -1
  9. package/dist/.tsbuildinfo +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/lib/filter/index.d.ts +13 -2
  13. package/dist/lib/filter/index.js +74 -259
  14. package/dist/lib/filter/index.js.map +1 -1
  15. package/dist/lib/keep_alive_manager.js +1 -1
  16. package/dist/lib/light_push/index.js +3 -3
  17. package/dist/lib/light_push/index.js.map +1 -1
  18. package/dist/lib/metadata/index.js +11 -1
  19. package/dist/lib/metadata/index.js.map +1 -1
  20. package/dist/lib/store/index.js +8 -1
  21. package/dist/lib/store/index.js.map +1 -1
  22. package/dist/lib/stream_manager.d.ts +4 -2
  23. package/dist/lib/stream_manager.js +58 -16
  24. package/dist/lib/stream_manager.js.map +1 -1
  25. package/dist/lib/wait_for_remote_peer.js +1 -1
  26. package/dist/lib/wait_for_remote_peer.js.map +1 -1
  27. package/package.json +1 -136
  28. package/src/index.ts +1 -1
  29. package/src/lib/filter/index.ts +138 -455
  30. package/src/lib/keep_alive_manager.ts +1 -1
  31. package/src/lib/light_push/index.ts +4 -7
  32. package/src/lib/metadata/index.ts +10 -1
  33. package/src/lib/store/index.ts +7 -1
  34. package/src/lib/stream_manager.ts +73 -23
  35. package/src/lib/wait_for_remote_peer.ts +1 -1
package/bundle/index.js CHANGED
@@ -1,73 +1,9 @@
1
- import { v as version_0, e as encodingLength, a as encode$1, d as decode$1, M as MessagePush, F as FilterSubscribeRequest, b as FilterSubscribeResponse$1, P as PushRpc$1, c as PushResponse, H as HistoryRpc$1, f as PagingInfo, g as HistoryResponse, h as createEncoder, W as WakuMetadataResponse, i as WakuMetadataRequest } from './version_0-C6o0DvNW.js';
2
- export { j as createDecoder } from './version_0-C6o0DvNW.js';
3
- import { g as getDefaultExportFromCjs, P as ProtocolError, a as Protocols, E as EConnectionStateEvents, T as Tags, b as EPeersByDiscoveryEvents } from './browser-DoQRY-an.js';
4
- import { b as bytesToUtf8, u as utf8ToBytes, c as concat$1, s as sha256, a as allocUnsafe, d as alloc, L as Logger, e as singleShardInfoToPubsubTopic, f as ensurePubsubTopicIsConfigured, D as DefaultPubsubTopic, p as pubsubTopicToSingleShardInfo, g as shardInfoToPubsubTopics } from './index-BJwgMx4y.js';
5
- import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-D0Zdzb-v.js';
6
- export { S as StreamManager } from './base_protocol-D0Zdzb-v.js';
7
-
8
- function groupByContentTopic(values) {
9
- const groupedDecoders = new Map();
10
- values.forEach((value) => {
11
- let decs = groupedDecoders.get(value.contentTopic);
12
- if (!decs) {
13
- groupedDecoders.set(value.contentTopic, []);
14
- decs = groupedDecoders.get(value.contentTopic);
15
- }
16
- decs.push(value);
17
- });
18
- return groupedDecoders;
19
- }
20
-
21
- const FRAME_RATE = 60;
22
- /**
23
- * Function that transforms IReceiver subscription to iterable stream of data.
24
- * @param receiver - object that allows to be subscribed to;
25
- * @param decoder - parameter to be passed to receiver for subscription;
26
- * @param options - options for receiver for subscription;
27
- * @param iteratorOptions - optional configuration for iterator;
28
- * @returns iterator and stop function to terminate it.
29
- */
30
- async function toAsyncIterator(receiver, decoder, iteratorOptions) {
31
- const iteratorDelay = iteratorOptions?.iteratorDelay ?? FRAME_RATE;
32
- const messages = [];
33
- let unsubscribe;
34
- unsubscribe = await receiver.subscribe(decoder, (message) => {
35
- messages.push(message);
36
- });
37
- const isWithTimeout = Number.isInteger(iteratorOptions?.timeoutMs);
38
- const timeoutMs = iteratorOptions?.timeoutMs ?? 0;
39
- const startTime = Date.now();
40
- async function* iterator() {
41
- while (true) {
42
- if (isWithTimeout && Date.now() - startTime >= timeoutMs) {
43
- return;
44
- }
45
- await wait(iteratorDelay);
46
- const message = messages.shift();
47
- if (!unsubscribe && messages.length === 0) {
48
- return message;
49
- }
50
- if (!message && unsubscribe) {
51
- continue;
52
- }
53
- yield message;
54
- }
55
- }
56
- return {
57
- iterator: iterator(),
58
- async stop() {
59
- if (unsubscribe) {
60
- await unsubscribe();
61
- unsubscribe = undefined;
62
- }
63
- }
64
- };
65
- }
66
- function wait(ms) {
67
- return new Promise((resolve) => {
68
- setTimeout(resolve, ms);
69
- });
70
- }
1
+ import { v as version_0, e as encodingLength, a as encode$1, d as decode$1, M as MessagePush, F as FilterSubscribeRequest, b as FilterSubscribeResponse$1, P as PushRpc$1, c as PushResponse, H as HistoryRpc$1, f as PagingInfo, g as HistoryResponse, h as createEncoder, W as WakuMetadataResponse, i as WakuMetadataRequest } from './version_0-D_Nwtppu.js';
2
+ export { j as createDecoder } from './version_0-D_Nwtppu.js';
3
+ import { g as getDefaultExportFromCjs, P as ProtocolError, a as Protocols, E as EConnectionStateEvents, T as Tags, b as EPeersByDiscoveryEvents } from './browser-H8Jgqifo.js';
4
+ import { a as allocUnsafe, b as alloc, L as Logger, u as utf8ToBytes, p as pubsubTopicToSingleShardInfo, s as shardInfoToPubsubTopics } from './index-BQ8SG1DC.js';
5
+ import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-3fdjkRTX.js';
6
+ export { S as StreamManager } from './base_protocol-3fdjkRTX.js';
71
7
 
72
8
  const MB = 1024 ** 2;
73
9
  const SIZE_CAP_IN_MB = 1;
@@ -91,33 +27,6 @@ var index$3 = /*#__PURE__*/Object.freeze({
91
27
  version_0: version_0
92
28
  });
93
29
 
94
- /**
95
- * Deterministic Message Hashing as defined in
96
- * [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
97
- */
98
- function messageHash(pubsubTopic, message) {
99
- const pubsubTopicBytes = utf8ToBytes(pubsubTopic);
100
- const contentTopicBytes = utf8ToBytes(message.contentTopic);
101
- let bytes;
102
- if (message.meta) {
103
- bytes = concat$1([
104
- pubsubTopicBytes,
105
- message.payload,
106
- contentTopicBytes,
107
- message.meta
108
- ]);
109
- }
110
- else {
111
- bytes = concat$1([pubsubTopicBytes, message.payload, contentTopicBytes]);
112
- }
113
- return sha256(bytes);
114
- }
115
- function messageHashStr(pubsubTopic, message) {
116
- const hash = messageHash(pubsubTopic, message);
117
- const hashStr = bytesToUtf8(hash);
118
- return hashStr;
119
- }
120
-
121
30
  /**
122
31
  * @packageDocumentation
123
32
  *
@@ -1701,242 +1610,14 @@ const FilterCodecs = {
1701
1610
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
1702
1611
  PUSH: "/vac/waku/filter-push/2.0.0-beta1"
1703
1612
  };
1704
- /**
1705
- * A subscription object refers to a subscription to a given pubsub topic.
1706
- */
1707
- class Subscription {
1708
- peers;
1709
- pubsubTopic;
1710
- newStream;
1711
- receivedMessagesHashStr = [];
1712
- subscriptionCallbacks;
1713
- constructor(pubsubTopic, remotePeers, newStream) {
1714
- this.peers = remotePeers;
1715
- this.pubsubTopic = pubsubTopic;
1716
- this.newStream = newStream;
1717
- this.subscriptionCallbacks = new Map();
1718
- }
1719
- async subscribe(decoders, callback) {
1720
- const decodersArray = Array.isArray(decoders) ? decoders : [decoders];
1721
- // check that all decoders are configured for the same pubsub topic as this subscription
1722
- decodersArray.forEach((decoder) => {
1723
- if (decoder.pubsubTopic !== this.pubsubTopic) {
1724
- throw new Error(`Pubsub topic not configured: decoder is configured for pubsub topic ${decoder.pubsubTopic} but this subscription is for pubsub topic ${this.pubsubTopic}. Please create a new Subscription for the different pubsub topic.`);
1725
- }
1726
- });
1727
- const decodersGroupedByCT = groupByContentTopic(decodersArray);
1728
- const contentTopics = Array.from(decodersGroupedByCT.keys());
1729
- const promises = this.peers.map(async (peer) => {
1730
- const stream = await this.newStream(peer);
1731
- const request = FilterSubscribeRpc.createSubscribeRequest(this.pubsubTopic, contentTopics);
1732
- try {
1733
- const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1734
- if (!res || !res.length) {
1735
- throw Error(`No response received for request ${request.requestId}: ${res}`);
1736
- }
1737
- const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1738
- if (statusCode < 200 || statusCode >= 300) {
1739
- throw new Error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1740
- }
1741
- log$6.info("Subscribed to peer ", peer.id.toString(), "for content topics", contentTopics);
1742
- }
1743
- catch (e) {
1744
- throw new Error("Error subscribing to peer: " +
1745
- peer.id.toString() +
1746
- " for content topics: " +
1747
- contentTopics +
1748
- ": " +
1749
- e);
1750
- }
1751
- });
1752
- const results = await Promise.allSettled(promises);
1753
- this.handleErrors(results, "subscribe");
1754
- // Save the callback functions by content topics so they
1755
- // can easily be removed (reciprocally replaced) if `unsubscribe` (reciprocally `subscribe`)
1756
- // is called for those content topics
1757
- decodersGroupedByCT.forEach((decoders, contentTopic) => {
1758
- // Cast the type because a given `subscriptionCallbacks` map may hold
1759
- // Decoder that decode to different implementations of `IDecodedMessage`
1760
- const subscriptionCallback = {
1761
- decoders,
1762
- callback
1763
- };
1764
- // The callback and decoder may override previous values, this is on
1765
- // purpose as the user may call `subscribe` to refresh the subscription
1766
- this.subscriptionCallbacks.set(contentTopic, subscriptionCallback);
1767
- });
1768
- }
1769
- async unsubscribe(contentTopics) {
1770
- const promises = this.peers.map(async (peer) => {
1771
- const stream = await this.newStream(peer);
1772
- const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(this.pubsubTopic, contentTopics);
1773
- try {
1774
- await pipe([unsubscribeRequest.encode()], encode, stream.sink);
1775
- }
1776
- catch (error) {
1777
- throw new Error("Error unsubscribing: " + error);
1778
- }
1779
- contentTopics.forEach((contentTopic) => {
1780
- this.subscriptionCallbacks.delete(contentTopic);
1781
- });
1782
- });
1783
- const results = await Promise.allSettled(promises);
1784
- this.handleErrors(results, "unsubscribe");
1785
- }
1786
- async ping() {
1787
- const promises = this.peers.map(async (peer) => {
1788
- const stream = await this.newStream(peer);
1789
- const request = FilterSubscribeRpc.createSubscriberPingRequest();
1790
- try {
1791
- const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1792
- if (!res || !res.length) {
1793
- throw Error(`No response received for request ${request.requestId}: ${res}`);
1794
- }
1795
- const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1796
- if (statusCode < 200 || statusCode >= 300) {
1797
- throw new Error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1798
- }
1799
- log$6.info(`Ping successful for peer ${peer.id.toString()}`);
1800
- }
1801
- catch (error) {
1802
- log$6.error("Error pinging: ", error);
1803
- throw error; // Rethrow the actual error instead of wrapping it
1804
- }
1805
- });
1806
- const results = await Promise.allSettled(promises);
1807
- this.handleErrors(results, "ping");
1808
- }
1809
- async unsubscribeAll() {
1810
- const promises = this.peers.map(async (peer) => {
1811
- const stream = await this.newStream(peer);
1812
- const request = FilterSubscribeRpc.createUnsubscribeAllRequest(this.pubsubTopic);
1813
- try {
1814
- const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1815
- if (!res || !res.length) {
1816
- throw Error(`No response received for request ${request.requestId}: ${res}`);
1817
- }
1818
- const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1819
- if (statusCode < 200 || statusCode >= 300) {
1820
- throw new Error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1821
- }
1822
- this.subscriptionCallbacks.clear();
1823
- log$6.info(`Unsubscribed from all content topics for pubsub topic ${this.pubsubTopic}`);
1824
- }
1825
- catch (error) {
1826
- throw new Error("Error unsubscribing from all content topics: " + error);
1827
- }
1828
- });
1829
- const results = await Promise.allSettled(promises);
1830
- this.handleErrors(results, "unsubscribeAll");
1831
- }
1832
- async processMessage(message) {
1833
- const hashedMessageStr = messageHashStr(this.pubsubTopic, message);
1834
- if (this.receivedMessagesHashStr.includes(hashedMessageStr)) {
1835
- log$6.info("Message already received, skipping");
1836
- return;
1837
- }
1838
- this.receivedMessagesHashStr.push(hashedMessageStr);
1839
- const { contentTopic } = message;
1840
- const subscriptionCallback = this.subscriptionCallbacks.get(contentTopic);
1841
- if (!subscriptionCallback) {
1842
- log$6.error("No subscription callback available for ", contentTopic);
1843
- return;
1844
- }
1845
- log$6.info("Processing message with content topic ", contentTopic, " on pubsub topic ", this.pubsubTopic);
1846
- await pushMessage(subscriptionCallback, this.pubsubTopic, message);
1847
- }
1848
- // Filter out only the rejected promises and extract & handle their reasons
1849
- handleErrors(results, type) {
1850
- const errors = results
1851
- .filter((result) => result.status === "rejected")
1852
- .map((rejectedResult) => rejectedResult.reason);
1853
- if (errors.length === this.peers.length) {
1854
- const errorCounts = new Map();
1855
- // TODO: streamline error logging with https://github.com/orgs/waku-org/projects/2/views/1?pane=issue&itemId=42849952
1856
- errors.forEach((error) => {
1857
- const message = error instanceof Error ? error.message : String(error);
1858
- errorCounts.set(message, (errorCounts.get(message) || 0) + 1);
1859
- });
1860
- const uniqueErrorMessages = Array.from(errorCounts, ([message, count]) => `${message} (occurred ${count} times)`).join(", ");
1861
- throw new Error(`Error ${type} all peers: ${uniqueErrorMessages}`);
1862
- }
1863
- else if (errors.length > 0) {
1864
- // TODO: handle renewing faulty peers with new peers (https://github.com/waku-org/js-waku/issues/1463)
1865
- log$6.warn(`Some ${type} failed. These will be refreshed with new peers`, errors);
1866
- }
1867
- else {
1868
- log$6.info(`${type} successful for all peers`);
1869
- }
1870
- }
1871
- }
1872
- const DEFAULT_NUM_PEERS = 3;
1873
- class Filter extends BaseProtocol {
1874
- activeSubscriptions = new Map();
1875
- getActiveSubscription(pubsubTopic) {
1876
- return this.activeSubscriptions.get(pubsubTopic);
1877
- }
1878
- setActiveSubscription(pubsubTopic, subscription) {
1879
- this.activeSubscriptions.set(pubsubTopic, subscription);
1880
- return subscription;
1881
- }
1882
- //TODO: Remove when FilterCore and FilterSDK are introduced
1883
- numPeersToUse;
1884
- constructor(libp2p, options) {
1613
+ class FilterCore extends BaseProtocol {
1614
+ handleIncomingMessage;
1615
+ constructor(handleIncomingMessage, libp2p, options) {
1885
1616
  super(FilterCodecs.SUBSCRIBE, libp2p.components, log$6, options.pubsubTopics, options);
1886
- this.numPeersToUse = options?.numPeersToUse ?? DEFAULT_NUM_PEERS;
1617
+ this.handleIncomingMessage = handleIncomingMessage;
1887
1618
  libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this)).catch((e) => {
1888
1619
  log$6.error("Failed to register ", FilterCodecs.PUSH, e);
1889
1620
  });
1890
- this.activeSubscriptions = new Map();
1891
- }
1892
- /**
1893
- * Creates a new subscription to the given pubsub topic.
1894
- * The subscription is made to multiple peers for decentralization.
1895
- * @param pubsubTopicShardInfo The pubsub topic to subscribe to.
1896
- * @returns The subscription object.
1897
- */
1898
- async createSubscription(pubsubTopicShardInfo = DefaultPubsubTopic) {
1899
- const pubsubTopic = typeof pubsubTopicShardInfo == "string"
1900
- ? pubsubTopicShardInfo
1901
- : singleShardInfoToPubsubTopic(pubsubTopicShardInfo);
1902
- ensurePubsubTopicIsConfigured(pubsubTopic, this.pubsubTopics);
1903
- const peers = await this.getPeers({
1904
- maxBootstrapPeers: 1,
1905
- numPeers: this.numPeersToUse
1906
- });
1907
- if (peers.length === 0) {
1908
- throw new Error("No peer found to initiate subscription.");
1909
- }
1910
- log$6.info(`Creating filter subscription with ${peers.length} peers: `, peers.map((peer) => peer.id.toString()));
1911
- const subscription = this.getActiveSubscription(pubsubTopic) ??
1912
- this.setActiveSubscription(pubsubTopic, new Subscription(pubsubTopic, peers, this.getStream.bind(this)));
1913
- return subscription;
1914
- }
1915
- toSubscriptionIterator(decoders) {
1916
- return toAsyncIterator(this, decoders);
1917
- }
1918
- /**
1919
- * This method is used to satisfy the `IReceiver` interface.
1920
- *
1921
- * @hidden
1922
- *
1923
- * @param decoders The decoders to use for the subscription.
1924
- * @param callback The callback function to use for the subscription.
1925
- * @param opts Optional protocol options for the subscription.
1926
- *
1927
- * @returns A Promise that resolves to a function that unsubscribes from the subscription.
1928
- *
1929
- * @remarks
1930
- * This method should not be used directly.
1931
- * Instead, use `createSubscription` to create a new subscription.
1932
- */
1933
- async subscribe(decoders, callback) {
1934
- const subscription = await this.createSubscription();
1935
- await subscription.subscribe(decoders, callback);
1936
- const contentTopics = Array.from(groupByContentTopic(Array.isArray(decoders) ? decoders : [decoders]).keys());
1937
- return async () => {
1938
- await subscription.unsubscribe(contentTopics);
1939
- };
1940
1621
  }
1941
1622
  onRequest(streamData) {
1942
1623
  const { connection, stream } = streamData;
@@ -1955,12 +1636,7 @@ class Filter extends BaseProtocol {
1955
1636
  log$6.error("Pubsub topic missing from push message");
1956
1637
  return;
1957
1638
  }
1958
- const subscription = this.getActiveSubscription(pubsubTopic);
1959
- if (!subscription) {
1960
- log$6.error(`No subscription locally registered for topic ${pubsubTopic}`);
1961
- return;
1962
- }
1963
- await subscription.processMessage(wakuMessage);
1639
+ await this.handleIncomingMessage(pubsubTopic, wakuMessage);
1964
1640
  }
1965
1641
  }).then(() => {
1966
1642
  log$6.info("Receiving pipe closed.");
@@ -1972,33 +1648,84 @@ class Filter extends BaseProtocol {
1972
1648
  log$6.error("Error decoding message", e);
1973
1649
  }
1974
1650
  }
1975
- }
1976
- function wakuFilter(init = { pubsubTopics: [] }) {
1977
- return (libp2p) => new Filter(libp2p, init);
1978
- }
1979
- async function pushMessage(subscriptionCallback, pubsubTopic, message) {
1980
- const { decoders, callback } = subscriptionCallback;
1981
- const { contentTopic } = message;
1982
- if (!contentTopic) {
1983
- log$6.warn("Message has no content topic, skipping");
1984
- return;
1651
+ async subscribe(pubsubTopic, peer, contentTopics) {
1652
+ let stream;
1653
+ try {
1654
+ stream = await this.getStream(peer);
1655
+ }
1656
+ catch (error) {
1657
+ throw new Error(`Failed to get stream for peer ${peer.id.toString()}`);
1658
+ }
1659
+ const request = FilterSubscribeRpc.createSubscribeRequest(pubsubTopic, contentTopics);
1660
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1661
+ if (!res || !res.length) {
1662
+ throw Error(`No response received for request ${request.requestId}: ${res}`);
1663
+ }
1664
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1665
+ if (statusCode < 200 || statusCode >= 300) {
1666
+ throw new Error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1667
+ }
1985
1668
  }
1986
- try {
1987
- const decodePromises = decoders.map((dec) => dec
1988
- .fromProtoObj(pubsubTopic, message)
1989
- .then((decoded) => decoded || Promise.reject("Decoding failed")));
1990
- const decodedMessage = await Promise.any(decodePromises);
1991
- await callback(decodedMessage);
1669
+ async unsubscribe(pubsubTopic, peer, contentTopics) {
1670
+ let stream;
1671
+ try {
1672
+ stream = await this.getStream(peer);
1673
+ }
1674
+ catch (error) {
1675
+ throw new Error(`Failed to get stream for peer ${peer.id.toString()}`);
1676
+ }
1677
+ const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(pubsubTopic, contentTopics);
1678
+ await pipe([unsubscribeRequest.encode()], encode, stream.sink);
1679
+ }
1680
+ async unsubscribeAll(pubsubTopic, peer) {
1681
+ let stream;
1682
+ try {
1683
+ stream = await this.getStream(peer);
1684
+ }
1685
+ catch (error) {
1686
+ throw new Error(`Failed to get stream for peer ${peer.id.toString()}`);
1687
+ }
1688
+ const request = FilterSubscribeRpc.createUnsubscribeAllRequest(pubsubTopic);
1689
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1690
+ if (!res || !res.length) {
1691
+ throw Error(`No response received for request ${request.requestId}: ${res}`);
1692
+ }
1693
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1694
+ if (statusCode < 200 || statusCode >= 300) {
1695
+ throw new Error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1696
+ }
1992
1697
  }
1993
- catch (e) {
1994
- log$6.error("Error decoding message", e);
1698
+ async ping(peer) {
1699
+ let stream;
1700
+ try {
1701
+ stream = await this.getStream(peer);
1702
+ }
1703
+ catch (error) {
1704
+ throw new Error(`Failed to get stream for peer ${peer.id.toString()}`);
1705
+ }
1706
+ const request = FilterSubscribeRpc.createSubscriberPingRequest();
1707
+ try {
1708
+ const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
1709
+ if (!res || !res.length) {
1710
+ throw Error(`No response received for request ${request.requestId}: ${res}`);
1711
+ }
1712
+ const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
1713
+ if (statusCode < 200 || statusCode >= 300) {
1714
+ throw new Error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
1715
+ }
1716
+ log$6.info(`Ping successful for peer ${peer.id.toString()}`);
1717
+ }
1718
+ catch (error) {
1719
+ log$6.error("Error pinging: ", error);
1720
+ throw error; // Rethrow the actual error instead of wrapping it
1721
+ }
1995
1722
  }
1996
1723
  }
1997
1724
 
1998
1725
  var index$2 = /*#__PURE__*/Object.freeze({
1999
1726
  __proto__: null,
2000
1727
  FilterCodecs: FilterCodecs,
2001
- wakuFilter: wakuFilter
1728
+ FilterCore: FilterCore
2002
1729
  });
2003
1730
 
2004
1731
  class PushRpc {
@@ -2084,12 +1811,12 @@ class LightPushCore extends BaseProtocol {
2084
1811
  try {
2085
1812
  stream = await this.getStream(peer);
2086
1813
  }
2087
- catch (err) {
2088
- log$5.error(`Failed to get a stream for remote peer${peer.id.toString()}`, err);
1814
+ catch (error) {
1815
+ log$5.error("Failed to get stream", error);
2089
1816
  return {
2090
1817
  success: null,
2091
1818
  failure: {
2092
- error: ProtocolError.REMOTE_PEER_FAULT,
1819
+ error: ProtocolError.NO_STREAM_AVAILABLE,
2093
1820
  peerId: peer.id
2094
1821
  }
2095
1822
  };
@@ -2261,7 +1988,14 @@ class StoreCore extends BaseProtocol {
2261
1988
  while (true) {
2262
1989
  queryOpts.cursor = currentCursor;
2263
1990
  const historyRpcQuery = HistoryRpc.createQuery(queryOpts);
2264
- const stream = await this.getStream(peer);
1991
+ let stream;
1992
+ try {
1993
+ stream = await this.getStream(peer);
1994
+ }
1995
+ catch (e) {
1996
+ log$4.error("Failed to get stream", e);
1997
+ break;
1998
+ }
2265
1999
  const res = await pipe([historyRpcQuery.encode()], encode, stream, decode, async (source) => await all(source));
2266
2000
  const bytes = new Uint8ArrayList();
2267
2001
  res.forEach((chunk) => {
@@ -2595,7 +2329,7 @@ async function waitForRemotePeer(waku, protocols, timeoutMs) {
2595
2329
  if (protocols.includes(Protocols.Filter)) {
2596
2330
  if (!waku.filter)
2597
2331
  throw new Error("Cannot wait for Filter peer: protocol not mounted");
2598
- promises.push(waitForConnectedPeer(waku.filter, waku.libp2p.services.metadata));
2332
+ promises.push(waitForConnectedPeer(waku.filter.protocol, waku.libp2p.services.metadata));
2599
2333
  }
2600
2334
  if (timeoutMs) {
2601
2335
  await rejectOnTimeout(Promise.all(promises), timeoutMs, "Timed out waiting for a remote peer.");
@@ -2813,7 +2547,7 @@ class KeepAliveManager {
2813
2547
  return;
2814
2548
  }
2815
2549
  try {
2816
- await peerStore.patch(peerId, {
2550
+ await peerStore.merge(peerId, {
2817
2551
  metadata: {
2818
2552
  ping: utf8ToBytes(ping.toString())
2819
2553
  }
@@ -3328,7 +3062,17 @@ class Metadata extends BaseProtocol {
3328
3062
  error: ProtocolError.NO_PEER_AVAILABLE
3329
3063
  };
3330
3064
  }
3331
- const stream = await this.getStream(peer);
3065
+ let stream;
3066
+ try {
3067
+ stream = await this.getStream(peer);
3068
+ }
3069
+ catch (error) {
3070
+ log.error("Failed to get stream", error);
3071
+ return {
3072
+ shardInfo: null,
3073
+ error: ProtocolError.NO_STREAM_AVAILABLE
3074
+ };
3075
+ }
3332
3076
  const encodedResponse = await pipe([request], encode, stream, decode, async (source) => await all(source));
3333
3077
  const { error, shardInfo } = this.decodeMetadataResponse(encodedResponse);
3334
3078
  if (error) {
@@ -3385,4 +3129,4 @@ function wakuMetadata(shardInfo) {
3385
3129
  return (components) => new Metadata(shardInfo, components);
3386
3130
  }
3387
3131
 
3388
- export { ConnectionManager, FilterCodecs, KeepAliveManager, LightPushCodec, LightPushCore, MetadataCodec, PageDirection, StoreCore, createEncoder, index$3 as message, waitForRemotePeer, wakuFilter, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
3132
+ export { ConnectionManager, FilterCodecs, FilterCore, KeepAliveManager, LightPushCodec, LightPushCore, MetadataCodec, PageDirection, StoreCore, createEncoder, index$3 as message, waitForRemotePeer, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
@@ -1,3 +1,3 @@
1
- import '../index-BJwgMx4y.js';
2
- import '../browser-DoQRY-an.js';
3
- export { B as BaseProtocol } from '../base_protocol-D0Zdzb-v.js';
1
+ import '../index-BQ8SG1DC.js';
2
+ import '../browser-H8Jgqifo.js';
3
+ export { B as BaseProtocol } from '../base_protocol-3fdjkRTX.js';
@@ -1,3 +1,3 @@
1
- export { D as DecodedMessage, k as Decoder, E as Encoder, V as Version, j as createDecoder, h as createEncoder, m as proto } from '../../version_0-C6o0DvNW.js';
2
- import '../../index-BJwgMx4y.js';
3
- import '../../browser-DoQRY-an.js';
1
+ export { D as DecodedMessage, k as Decoder, E as Encoder, V as Version, j as createDecoder, h as createEncoder, m as proto } from '../../version_0-D_Nwtppu.js';
2
+ import '../../index-BQ8SG1DC.js';
3
+ import '../../browser-H8Jgqifo.js';
@@ -1,4 +1,4 @@
1
- import '../browser-DoQRY-an.js';
1
+ import '../browser-H8Jgqifo.js';
2
2
 
3
3
  /**
4
4
  * Return pseudo random subset of the input.
@@ -1,4 +1,4 @@
1
- import { a as allocUnsafe, h as fromString, d as alloc$1, L as Logger, i as determinePubsubTopic } from './index-BJwgMx4y.js';
1
+ import { a as allocUnsafe, f as fromString, b as alloc$1, L as Logger, d as determinePubsubTopic } from './index-BQ8SG1DC.js';
2
2
 
3
3
  /* eslint-disable no-fallthrough */
4
4
  const N1 = Math.pow(2, 7);
@@ -3228,11 +3228,15 @@ var HistoryResponse;
3228
3228
  (function (HistoryError) {
3229
3229
  HistoryError["NONE"] = "NONE";
3230
3230
  HistoryError["INVALID_CURSOR"] = "INVALID_CURSOR";
3231
+ HistoryError["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
3232
+ HistoryError["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
3231
3233
  })(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
3232
3234
  let __HistoryErrorValues;
3233
3235
  (function (__HistoryErrorValues) {
3234
3236
  __HistoryErrorValues[__HistoryErrorValues["NONE"] = 0] = "NONE";
3235
3237
  __HistoryErrorValues[__HistoryErrorValues["INVALID_CURSOR"] = 1] = "INVALID_CURSOR";
3238
+ __HistoryErrorValues[__HistoryErrorValues["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
3239
+ __HistoryErrorValues[__HistoryErrorValues["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
3236
3240
  })(__HistoryErrorValues || (__HistoryErrorValues = {}));
3237
3241
  (function (HistoryError) {
3238
3242
  HistoryError.codec = () => {