@waku/core 0.0.29-fd60cc2.0 → 0.0.29
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 +33 -0
- package/bundle/{base_protocol-B8NGoK0E.js → base_protocol-CrPXdVvO.js} +1 -1
- package/bundle/{index-DBP1NHED.js → index-NYIjIEV5.js} +5 -13
- package/bundle/index.js +56 -370
- package/bundle/lib/base_protocol.js +2 -2
- package/bundle/lib/message/version_0.js +2 -2
- package/bundle/{version_0-B6lI5jri.js → version_0-C6GyvOeg.js} +3 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/filter/index.d.ts +13 -2
- package/dist/lib/filter/index.js +48 -274
- package/dist/lib/filter/index.js.map +1 -1
- package/dist/lib/keep_alive_manager.js +1 -1
- package/dist/lib/wait_for_remote_peer.js +1 -1
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/package.json +134 -1
- package/src/index.ts +1 -1
- package/src/lib/filter/index.ts +109 -475
- package/src/lib/keep_alive_manager.ts +1 -1
- package/src/lib/wait_for_remote_peer.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,39 @@ 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.29](https://github.com/waku-org/js-waku/compare/core-v0.0.28...core-v0.0.29) (2024-04-30)
|
9
|
+
|
10
|
+
|
11
|
+
### ⚠ BREAKING CHANGES
|
12
|
+
|
13
|
+
* use ShardingParams on subscriptions, make Decoder/Encoder auto sharding friendly by default ([#1958](https://github.com/waku-org/js-waku/issues/1958))
|
14
|
+
* **lightpush:** move protocol implementation to `@waku/sdk` (1/n) ([#1964](https://github.com/waku-org/js-waku/issues/1964))
|
15
|
+
|
16
|
+
### Features
|
17
|
+
|
18
|
+
* Use ShardingParams on subscriptions, make Decoder/Encoder auto sharding friendly by default ([#1958](https://github.com/waku-org/js-waku/issues/1958)) ([f3627c4](https://github.com/waku-org/js-waku/commit/f3627c46a4c231013c5ffa4aa6f1ecbe3c06c5e3))
|
19
|
+
|
20
|
+
|
21
|
+
### Bug Fixes
|
22
|
+
|
23
|
+
* Only override ping metadata in peer store ([#1984](https://github.com/waku-org/js-waku/issues/1984)) ([fb34b72](https://github.com/waku-org/js-waku/commit/fb34b7262a8d85fdf76cb30774d14bcd3a150f58))
|
24
|
+
* Use correct shard index when creating encoder ([9514653](https://github.com/waku-org/js-waku/commit/95146534288f842ff1cf180fc62850d539937a05))
|
25
|
+
|
26
|
+
|
27
|
+
### Miscellaneous Chores
|
28
|
+
|
29
|
+
* **lightpush:** Move protocol implementation to `@waku/sdk` (1/n) ([#1964](https://github.com/waku-org/js-waku/issues/1964)) ([5fb1006](https://github.com/waku-org/js-waku/commit/5fb100602b347ad13718c85c52d22a932c15aa18))
|
30
|
+
|
31
|
+
|
32
|
+
### Dependencies
|
33
|
+
|
34
|
+
* The following workspace dependencies were updated
|
35
|
+
* dependencies
|
36
|
+
* @waku/enr bumped from ^0.0.22 to ^0.0.23
|
37
|
+
* @waku/interfaces bumped from 0.0.23 to 0.0.24
|
38
|
+
* @waku/proto bumped from 0.0.6 to 0.0.7
|
39
|
+
* @waku/utils bumped from 0.0.16 to 0.0.17
|
40
|
+
|
8
41
|
## [0.0.28](https://github.com/waku-org/js-waku/compare/core-v0.0.27...core-v0.0.28) (2024-04-09)
|
9
42
|
|
10
43
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { c as bytesToUtf8, L as Logger, e as ensureShardingConfigured } from './index-NYIjIEV5.js';
|
2
2
|
import { T as Tags } from './browser-DoQRY-an.js';
|
3
3
|
|
4
4
|
const decodeRelayShard = (bytes) => {
|
@@ -379,7 +379,6 @@ const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
|
379
379
|
/**
|
380
380
|
* DefaultPubsubTopic is the default gossipsub topic to use for Waku.
|
381
381
|
*/
|
382
|
-
const DefaultPubsubTopic = "/waku/2/default-waku/proto";
|
383
382
|
/**
|
384
383
|
* The default cluster ID for The Waku Network
|
385
384
|
*/
|
@@ -424,9 +423,9 @@ function concat(byteArrays, totalLength) {
|
|
424
423
|
}
|
425
424
|
|
426
425
|
const singleShardInfoToPubsubTopic = (shardInfo) => {
|
427
|
-
if (shardInfo.
|
426
|
+
if (shardInfo.shard === undefined)
|
428
427
|
throw new Error("Invalid shard");
|
429
|
-
return `/waku/2/rs/${shardInfo.clusterId}/${shardInfo.shard}`;
|
428
|
+
return `/waku/2/rs/${shardInfo.clusterId ?? DEFAULT_CLUSTER_ID}/${shardInfo.shard}`;
|
430
429
|
};
|
431
430
|
const shardInfoToPubsubTopics = (shardInfo) => {
|
432
431
|
if ("contentTopics" in shardInfo && shardInfo.contentTopics) {
|
@@ -465,13 +464,6 @@ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
|
465
464
|
shard
|
466
465
|
};
|
467
466
|
};
|
468
|
-
//TODO: move part of BaseProtocol instead of utils
|
469
|
-
// return `ProtocolError.TOPIC_NOT_CONFIGURED` instead of throwing
|
470
|
-
function ensurePubsubTopicIsConfigured(pubsubTopic, configuredTopics) {
|
471
|
-
if (!configuredTopics.includes(pubsubTopic)) {
|
472
|
-
throw new Error(`Pubsub topic ${pubsubTopic} has not been configured on this instance. Configured topics are: ${configuredTopics}. Please update your configuration by passing in the topic during Waku node instantiation.`);
|
473
|
-
}
|
474
|
-
}
|
475
467
|
/**
|
476
468
|
* Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
|
477
469
|
* @param contentTopic String to validate
|
@@ -543,9 +535,9 @@ function determinePubsubTopic(contentTopic, pubsubTopicShardInfo) {
|
|
543
535
|
if (typeof pubsubTopicShardInfo == "string") {
|
544
536
|
return pubsubTopicShardInfo;
|
545
537
|
}
|
546
|
-
return pubsubTopicShardInfo?.shard
|
538
|
+
return pubsubTopicShardInfo?.shard !== undefined
|
547
539
|
? singleShardInfoToPubsubTopic(pubsubTopicShardInfo)
|
548
|
-
: contentTopicToPubsubTopic(contentTopic, pubsubTopicShardInfo?.clusterId
|
540
|
+
: contentTopicToPubsubTopic(contentTopic, pubsubTopicShardInfo?.clusterId ?? DEFAULT_CLUSTER_ID);
|
549
541
|
}
|
550
542
|
/**
|
551
543
|
* Validates sharding configuration and sets defaults where possible.
|
@@ -619,4 +611,4 @@ class Logger {
|
|
619
611
|
}
|
620
612
|
}
|
621
613
|
|
622
|
-
export {
|
614
|
+
export { Logger as L, allocUnsafe as a, alloc as b, bytesToUtf8 as c, determinePubsubTopic as d, ensureShardingConfigured as e, fromString as f, pubsubTopicToSingleShardInfo as p, shardInfoToPubsubTopics as s, utf8ToBytes as u };
|
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-
|
2
|
-
export { j as createDecoder } from './version_0-
|
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-C6GyvOeg.js';
|
2
|
+
export { j as createDecoder } from './version_0-C6GyvOeg.js';
|
3
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 {
|
5
|
-
import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-
|
6
|
-
export { S as StreamManager } from './base_protocol-
|
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
|
-
}
|
4
|
+
import { a as allocUnsafe, b as alloc, L as Logger, u as utf8ToBytes, p as pubsubTopicToSingleShardInfo, s as shardInfoToPubsubTopics } from './index-NYIjIEV5.js';
|
5
|
+
import { B as BaseProtocol, d as decodeRelayShard, e as encodeRelayShard } from './base_protocol-CrPXdVvO.js';
|
6
|
+
export { S as StreamManager } from './base_protocol-CrPXdVvO.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,249 +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
|
-
|
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.
|
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 pubsubTopics = this.getPubsubTopics(decoders);
|
1935
|
-
if (pubsubTopics.length === 0) {
|
1936
|
-
throw Error("Failed to subscribe: no pubsubTopic found on decoders provided.");
|
1937
|
-
}
|
1938
|
-
if (pubsubTopics.length > 1) {
|
1939
|
-
throw Error("Failed to subscribe: all decoders should have the same pubsub topic. Use createSubscription to be more agile.");
|
1940
|
-
}
|
1941
|
-
const subscription = await this.createSubscription(pubsubTopics[0]);
|
1942
|
-
await subscription.subscribe(decoders, callback);
|
1943
|
-
const contentTopics = Array.from(groupByContentTopic(Array.isArray(decoders) ? decoders : [decoders]).keys());
|
1944
|
-
return async () => {
|
1945
|
-
await subscription.unsubscribe(contentTopics);
|
1946
|
-
};
|
1947
1621
|
}
|
1948
1622
|
onRequest(streamData) {
|
1949
1623
|
const { connection, stream } = streamData;
|
@@ -1962,12 +1636,7 @@ class Filter extends BaseProtocol {
|
|
1962
1636
|
log$6.error("Pubsub topic missing from push message");
|
1963
1637
|
return;
|
1964
1638
|
}
|
1965
|
-
|
1966
|
-
if (!subscription) {
|
1967
|
-
log$6.error(`No subscription locally registered for topic ${pubsubTopic}`);
|
1968
|
-
return;
|
1969
|
-
}
|
1970
|
-
await subscription.processMessage(wakuMessage);
|
1639
|
+
await this.handleIncomingMessage(pubsubTopic, wakuMessage);
|
1971
1640
|
}
|
1972
1641
|
}).then(() => {
|
1973
1642
|
log$6.info("Receiving pipe closed.");
|
@@ -1979,43 +1648,60 @@ class Filter extends BaseProtocol {
|
|
1979
1648
|
log$6.error("Error decoding message", e);
|
1980
1649
|
}
|
1981
1650
|
}
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1651
|
+
async subscribe(pubsubTopic, peer, contentTopics) {
|
1652
|
+
const stream = await this.getStream(peer);
|
1653
|
+
const request = FilterSubscribeRpc.createSubscribeRequest(pubsubTopic, contentTopics);
|
1654
|
+
const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
|
1655
|
+
if (!res || !res.length) {
|
1656
|
+
throw Error(`No response received for request ${request.requestId}: ${res}`);
|
1985
1657
|
}
|
1986
|
-
|
1987
|
-
|
1658
|
+
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
1659
|
+
if (statusCode < 200 || statusCode >= 300) {
|
1660
|
+
throw new Error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
1988
1661
|
}
|
1989
|
-
const pubsubTopics = new Set(decoders.map((d) => d.pubsubTopic));
|
1990
|
-
return [...pubsubTopics];
|
1991
1662
|
}
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
async function pushMessage(subscriptionCallback, pubsubTopic, message) {
|
1997
|
-
const { decoders, callback } = subscriptionCallback;
|
1998
|
-
const { contentTopic } = message;
|
1999
|
-
if (!contentTopic) {
|
2000
|
-
log$6.warn("Message has no content topic, skipping");
|
2001
|
-
return;
|
1663
|
+
async unsubscribe(pubsubTopic, peer, contentTopics) {
|
1664
|
+
const stream = await this.getStream(peer);
|
1665
|
+
const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(pubsubTopic, contentTopics);
|
1666
|
+
await pipe([unsubscribeRequest.encode()], encode, stream.sink);
|
2002
1667
|
}
|
2003
|
-
|
2004
|
-
const
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
1668
|
+
async unsubscribeAll(pubsubTopic, peer) {
|
1669
|
+
const stream = await this.getStream(peer);
|
1670
|
+
const request = FilterSubscribeRpc.createUnsubscribeAllRequest(pubsubTopic);
|
1671
|
+
const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
|
1672
|
+
if (!res || !res.length) {
|
1673
|
+
throw Error(`No response received for request ${request.requestId}: ${res}`);
|
1674
|
+
}
|
1675
|
+
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
1676
|
+
if (statusCode < 200 || statusCode >= 300) {
|
1677
|
+
throw new Error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
1678
|
+
}
|
2009
1679
|
}
|
2010
|
-
|
2011
|
-
|
1680
|
+
async ping(peer) {
|
1681
|
+
const stream = await this.getStream(peer);
|
1682
|
+
const request = FilterSubscribeRpc.createSubscriberPingRequest();
|
1683
|
+
try {
|
1684
|
+
const res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
|
1685
|
+
if (!res || !res.length) {
|
1686
|
+
throw Error(`No response received for request ${request.requestId}: ${res}`);
|
1687
|
+
}
|
1688
|
+
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
1689
|
+
if (statusCode < 200 || statusCode >= 300) {
|
1690
|
+
throw new Error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
1691
|
+
}
|
1692
|
+
log$6.info(`Ping successful for peer ${peer.id.toString()}`);
|
1693
|
+
}
|
1694
|
+
catch (error) {
|
1695
|
+
log$6.error("Error pinging: ", error);
|
1696
|
+
throw error; // Rethrow the actual error instead of wrapping it
|
1697
|
+
}
|
2012
1698
|
}
|
2013
1699
|
}
|
2014
1700
|
|
2015
1701
|
var index$2 = /*#__PURE__*/Object.freeze({
|
2016
1702
|
__proto__: null,
|
2017
1703
|
FilterCodecs: FilterCodecs,
|
2018
|
-
|
1704
|
+
FilterCore: FilterCore
|
2019
1705
|
});
|
2020
1706
|
|
2021
1707
|
class PushRpc {
|
@@ -2612,7 +2298,7 @@ async function waitForRemotePeer(waku, protocols, timeoutMs) {
|
|
2612
2298
|
if (protocols.includes(Protocols.Filter)) {
|
2613
2299
|
if (!waku.filter)
|
2614
2300
|
throw new Error("Cannot wait for Filter peer: protocol not mounted");
|
2615
|
-
promises.push(waitForConnectedPeer(waku.filter, waku.libp2p.services.metadata));
|
2301
|
+
promises.push(waitForConnectedPeer(waku.filter.protocol, waku.libp2p.services.metadata));
|
2616
2302
|
}
|
2617
2303
|
if (timeoutMs) {
|
2618
2304
|
await rejectOnTimeout(Promise.all(promises), timeoutMs, "Timed out waiting for a remote peer.");
|
@@ -2830,7 +2516,7 @@ class KeepAliveManager {
|
|
2830
2516
|
return;
|
2831
2517
|
}
|
2832
2518
|
try {
|
2833
|
-
await peerStore.
|
2519
|
+
await peerStore.merge(peerId, {
|
2834
2520
|
metadata: {
|
2835
2521
|
ping: utf8ToBytes(ping.toString())
|
2836
2522
|
}
|
@@ -3402,4 +3088,4 @@ function wakuMetadata(shardInfo) {
|
|
3402
3088
|
return (components) => new Metadata(shardInfo, components);
|
3403
3089
|
}
|
3404
3090
|
|
3405
|
-
export { ConnectionManager, FilterCodecs, KeepAliveManager, LightPushCodec, LightPushCore, MetadataCodec, PageDirection, StoreCore, createEncoder, index$3 as message, waitForRemotePeer,
|
3091
|
+
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-
|
1
|
+
import '../index-NYIjIEV5.js';
|
2
2
|
import '../browser-DoQRY-an.js';
|
3
|
-
export { B as BaseProtocol } from '../base_protocol-
|
3
|
+
export { B as BaseProtocol } from '../base_protocol-CrPXdVvO.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-
|
2
|
-
import '../../index-
|
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-C6GyvOeg.js';
|
2
|
+
import '../../index-NYIjIEV5.js';
|
3
3
|
import '../../browser-DoQRY-an.js';
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { a as allocUnsafe,
|
1
|
+
import { a as allocUnsafe, f as fromString, b as alloc$1, L as Logger, d as determinePubsubTopic } from './index-NYIjIEV5.js';
|
2
2
|
|
3
3
|
/* eslint-disable no-fallthrough */
|
4
4
|
const N1 = Math.pow(2, 7);
|
@@ -3228,14 +3228,14 @@ var HistoryResponse;
|
|
3228
3228
|
(function (HistoryError) {
|
3229
3229
|
HistoryError["NONE"] = "NONE";
|
3230
3230
|
HistoryError["INVALID_CURSOR"] = "INVALID_CURSOR";
|
3231
|
-
HistoryError["
|
3231
|
+
HistoryError["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
|
3232
3232
|
HistoryError["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
3233
3233
|
})(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
|
3234
3234
|
let __HistoryErrorValues;
|
3235
3235
|
(function (__HistoryErrorValues) {
|
3236
3236
|
__HistoryErrorValues[__HistoryErrorValues["NONE"] = 0] = "NONE";
|
3237
3237
|
__HistoryErrorValues[__HistoryErrorValues["INVALID_CURSOR"] = 1] = "INVALID_CURSOR";
|
3238
|
-
__HistoryErrorValues[__HistoryErrorValues["
|
3238
|
+
__HistoryErrorValues[__HistoryErrorValues["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
3239
3239
|
__HistoryErrorValues[__HistoryErrorValues["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
3240
3240
|
})(__HistoryErrorValues || (__HistoryErrorValues = {}));
|
3241
3241
|
(function (HistoryError) {
|