@waku/core 0.0.22 → 0.0.24
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 +61 -0
- package/bundle/base_protocol-2a0c882e.js +1250 -0
- package/bundle/{browser-bde977a3.js → browser-90197c87.js} +26 -1
- package/bundle/index.js +20048 -3236
- package/bundle/lib/base_protocol.js +2 -116
- package/bundle/lib/message/version_0.js +2 -2
- package/bundle/lib/predefined_bootstrap_nodes.js +6 -6
- package/bundle/{version_0-86411fdf.js → version_0-f4afd324.js} +907 -814
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/base_protocol.d.ts +18 -5
- package/dist/lib/base_protocol.js +25 -8
- package/dist/lib/base_protocol.js.map +1 -1
- package/dist/lib/connection_manager.d.ts +15 -3
- package/dist/lib/connection_manager.js +92 -34
- package/dist/lib/connection_manager.js.map +1 -1
- package/dist/lib/filter/filter_rpc.js +4 -4
- package/dist/lib/filter/index.d.ts +4 -0
- package/dist/lib/filter/index.js +38 -29
- package/dist/lib/filter/index.js.map +1 -1
- package/dist/lib/filterPeers.d.ts +10 -0
- package/dist/lib/filterPeers.js +31 -0
- package/dist/lib/filterPeers.js.map +1 -0
- package/dist/lib/keep_alive_manager.d.ts +4 -2
- package/dist/lib/keep_alive_manager.js +62 -19
- package/dist/lib/keep_alive_manager.js.map +1 -1
- package/dist/lib/light_push/index.js +85 -38
- package/dist/lib/light_push/index.js.map +1 -1
- package/dist/lib/light_push/push_rpc.d.ts +1 -1
- package/dist/lib/light_push/push_rpc.js +3 -3
- package/dist/lib/message/version_0.d.ts +13 -13
- package/dist/lib/message/version_0.js +21 -18
- package/dist/lib/message/version_0.js.map +1 -1
- package/dist/lib/predefined_bootstrap_nodes.js +6 -6
- package/dist/lib/store/history_rpc.d.ts +1 -1
- package/dist/lib/store/history_rpc.js +4 -4
- package/dist/lib/store/index.d.ts +1 -6
- package/dist/lib/store/index.js +91 -47
- package/dist/lib/store/index.js.map +1 -1
- package/dist/lib/stream_manager.d.ts +15 -0
- package/dist/lib/stream_manager.js +56 -0
- package/dist/lib/stream_manager.js.map +1 -0
- package/dist/lib/to_proto_message.js +1 -1
- package/dist/lib/wait_for_remote_peer.d.ts +2 -2
- package/dist/lib/wait_for_remote_peer.js +10 -7
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/dist/lib/waku.d.ts +6 -5
- package/dist/lib/waku.js +6 -4
- package/dist/lib/waku.js.map +1 -1
- package/package.json +17 -33
- package/src/index.ts +6 -9
- package/src/lib/base_protocol.ts +49 -18
- package/src/lib/connection_manager.ts +132 -41
- package/src/lib/filter/filter_rpc.ts +4 -4
- package/src/lib/filter/index.ts +53 -41
- package/src/lib/filterPeers.ts +43 -0
- package/src/lib/keep_alive_manager.ts +79 -22
- package/src/lib/light_push/index.ts +132 -51
- package/src/lib/light_push/push_rpc.ts +3 -3
- package/src/lib/message/version_0.ts +27 -15
- package/src/lib/predefined_bootstrap_nodes.ts +7 -7
- package/src/lib/store/history_rpc.ts +6 -6
- package/src/lib/store/index.ts +121 -63
- package/src/lib/stream_manager.ts +72 -0
- package/src/lib/to_proto_message.ts +1 -1
- package/src/lib/wait_for_remote_peer.ts +11 -8
- package/src/lib/waku.ts +7 -4
- package/dist/lib/push_or_init_map.d.ts +0 -1
- package/dist/lib/push_or_init_map.js +0 -9
- package/dist/lib/push_or_init_map.js.map +0 -1
- package/src/lib/push_or_init_map.ts +0 -13
package/src/lib/store/index.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
import type { Stream } from "@libp2p/interface
|
2
|
-
import type { PeerId } from "@libp2p/interface-peer-id";
|
1
|
+
import type { Stream } from "@libp2p/interface/connection";
|
3
2
|
import { sha256 } from "@noble/hashes/sha256";
|
4
3
|
import {
|
5
4
|
Cursor,
|
@@ -8,9 +7,10 @@ import {
|
|
8
7
|
IStore,
|
9
8
|
Libp2p,
|
10
9
|
ProtocolCreateOptions,
|
10
|
+
PubSubTopic
|
11
11
|
} from "@waku/interfaces";
|
12
12
|
import { proto_store as proto } from "@waku/proto";
|
13
|
-
import { isDefined } from "@waku/utils";
|
13
|
+
import { ensurePubsubTopicIsConfigured, isDefined } from "@waku/utils";
|
14
14
|
import { concat, utf8ToBytes } from "@waku/utils/bytes";
|
15
15
|
import debug from "debug";
|
16
16
|
import all from "it-all";
|
@@ -40,10 +40,6 @@ export interface TimeFilter {
|
|
40
40
|
}
|
41
41
|
|
42
42
|
export interface QueryOptions {
|
43
|
-
/**
|
44
|
-
* The peer to query. If undefined, a pseudo-random peer is selected from the connected Waku Store peers.
|
45
|
-
*/
|
46
|
-
peerId?: PeerId;
|
47
43
|
/**
|
48
44
|
* The direction in which pages are retrieved:
|
49
45
|
* - { @link PageDirection.BACKWARD }: Most recent page first.
|
@@ -79,13 +75,62 @@ export interface QueryOptions {
|
|
79
75
|
* The Waku Store protocol can be used to retrieved historical messages.
|
80
76
|
*/
|
81
77
|
class Store extends BaseProtocol implements IStore {
|
82
|
-
|
78
|
+
private readonly pubsubTopics: PubSubTopic[];
|
79
|
+
private readonly NUM_PEERS_PROTOCOL = 1;
|
83
80
|
|
84
81
|
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
85
82
|
super(StoreCodec, libp2p.components);
|
86
|
-
this.
|
83
|
+
this.pubsubTopics = options?.pubsubTopics ?? [DefaultPubSubTopic];
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Processes messages based on the provided callback and options.
|
88
|
+
* @private
|
89
|
+
*/
|
90
|
+
private async processMessages<T extends IDecodedMessage>(
|
91
|
+
messages: Promise<T | undefined>[],
|
92
|
+
callback: (message: T) => Promise<void | boolean> | boolean | void,
|
93
|
+
options?: QueryOptions
|
94
|
+
): Promise<boolean> {
|
95
|
+
let abort = false;
|
96
|
+
const messagesOrUndef: Array<T | undefined> = await Promise.all(messages);
|
97
|
+
let processedMessages: Array<T> = messagesOrUndef.filter(isDefined);
|
98
|
+
|
99
|
+
if (this.shouldReverseOrder(options)) {
|
100
|
+
processedMessages = processedMessages.reverse();
|
101
|
+
}
|
102
|
+
|
103
|
+
await Promise.all(
|
104
|
+
processedMessages.map(async (msg) => {
|
105
|
+
if (msg && !abort) {
|
106
|
+
abort = Boolean(await callback(msg));
|
107
|
+
}
|
108
|
+
})
|
109
|
+
);
|
110
|
+
|
111
|
+
return abort;
|
112
|
+
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Determines whether to reverse the order of messages based on the provided options.
|
116
|
+
*
|
117
|
+
* Messages in pages are ordered from oldest (first) to most recent (last).
|
118
|
+
* https://github.com/vacp2p/rfc/issues/533
|
119
|
+
*
|
120
|
+
* @private
|
121
|
+
*/
|
122
|
+
private shouldReverseOrder(options?: QueryOptions): boolean {
|
123
|
+
return (
|
124
|
+
typeof options?.pageDirection === "undefined" ||
|
125
|
+
options?.pageDirection === PageDirection.BACKWARD
|
126
|
+
);
|
87
127
|
}
|
88
128
|
|
129
|
+
/**
|
130
|
+
* @deprecated Use `queryWithOrderedCallback` instead
|
131
|
+
**/
|
132
|
+
queryOrderedCallback = this.queryWithOrderedCallback;
|
133
|
+
|
89
134
|
/**
|
90
135
|
* Do a query to a Waku Store to retrieve historical/missed messages.
|
91
136
|
*
|
@@ -103,42 +148,20 @@ class Store extends BaseProtocol implements IStore {
|
|
103
148
|
* or if an error is encountered when processing the reply,
|
104
149
|
* or if two decoders with the same content topic are passed.
|
105
150
|
*/
|
106
|
-
async
|
151
|
+
async queryWithOrderedCallback<T extends IDecodedMessage>(
|
107
152
|
decoders: IDecoder<T>[],
|
108
153
|
callback: (message: T) => Promise<void | boolean> | boolean | void,
|
109
154
|
options?: QueryOptions
|
110
155
|
): Promise<void> {
|
111
|
-
let abort = false;
|
112
156
|
for await (const promises of this.queryGenerator(decoders, options)) {
|
113
|
-
if (
|
114
|
-
const messagesOrUndef: Array<T | undefined> = await Promise.all(promises);
|
115
|
-
|
116
|
-
let messages: Array<T> = messagesOrUndef.filter(isDefined);
|
117
|
-
|
118
|
-
// Messages in pages are ordered from oldest (first) to most recent (last).
|
119
|
-
// https://github.com/vacp2p/rfc/issues/533
|
120
|
-
if (
|
121
|
-
typeof options?.pageDirection === "undefined" ||
|
122
|
-
options?.pageDirection === PageDirection.BACKWARD
|
123
|
-
) {
|
124
|
-
messages = messages.reverse();
|
125
|
-
}
|
126
|
-
|
127
|
-
await Promise.all(
|
128
|
-
messages.map(async (msg) => {
|
129
|
-
if (msg && !abort) {
|
130
|
-
abort = Boolean(await callback(msg));
|
131
|
-
}
|
132
|
-
})
|
133
|
-
);
|
157
|
+
if (await this.processMessages(promises, callback, options)) break;
|
134
158
|
}
|
135
159
|
}
|
136
160
|
|
137
161
|
/**
|
138
162
|
* Do a query to a Waku Store to retrieve historical/missed messages.
|
139
|
-
*
|
140
163
|
* The callback function takes a `Promise<WakuMessage>` in input,
|
141
|
-
* useful if messages
|
164
|
+
* useful if messages need to be decrypted and performance matters.
|
142
165
|
*
|
143
166
|
* The order of the messages passed to the callback is as follows:
|
144
167
|
* - within a page, messages are expected to be ordered from oldest to most recent
|
@@ -152,7 +175,7 @@ class Store extends BaseProtocol implements IStore {
|
|
152
175
|
* or if an error is encountered when processing the reply,
|
153
176
|
* or if two decoders with the same content topic are passed.
|
154
177
|
*/
|
155
|
-
async
|
178
|
+
async queryWithPromiseCallback<T extends IDecodedMessage>(
|
156
179
|
decoders: IDecoder<T>[],
|
157
180
|
callback: (
|
158
181
|
message: Promise<T | undefined>
|
@@ -160,17 +183,15 @@ class Store extends BaseProtocol implements IStore {
|
|
160
183
|
options?: QueryOptions
|
161
184
|
): Promise<void> {
|
162
185
|
let abort = false;
|
163
|
-
let promises: Promise<void>[] = [];
|
164
186
|
for await (const page of this.queryGenerator(decoders, options)) {
|
165
|
-
const _promises = page.map(async (
|
166
|
-
if (
|
167
|
-
|
168
|
-
}
|
187
|
+
const _promises = page.map(async (msgPromise) => {
|
188
|
+
if (abort) return;
|
189
|
+
abort = Boolean(await callback(msgPromise));
|
169
190
|
});
|
170
191
|
|
171
|
-
|
192
|
+
await Promise.all(_promises);
|
193
|
+
if (abort) break;
|
172
194
|
}
|
173
|
-
await Promise.all(promises);
|
174
195
|
}
|
175
196
|
|
176
197
|
/**
|
@@ -183,18 +204,23 @@ class Store extends BaseProtocol implements IStore {
|
|
183
204
|
* as follows:
|
184
205
|
* - within a page, messages SHOULD be ordered from oldest to most recent
|
185
206
|
* - pages direction depends on { @link QueryOptions.pageDirection }
|
186
|
-
*
|
187
|
-
* However, there is no way to guarantee the behavior of the remote node.
|
188
|
-
*
|
189
207
|
* @throws If not able to reach a Waku Store peer to query,
|
190
208
|
* or if an error is encountered when processing the reply,
|
191
209
|
* or if two decoders with the same content topic are passed.
|
210
|
+
*
|
211
|
+
* This API only supports querying a single pubsub topic at a time.
|
212
|
+
* If multiple decoders are provided, they must all have the same pubsub topic.
|
213
|
+
* @throws If multiple decoders with different pubsub topics are provided.
|
214
|
+
* @throws If no decoders are provided.
|
215
|
+
* @throws If no decoders are found for the provided pubsub topic.
|
192
216
|
*/
|
193
217
|
async *queryGenerator<T extends IDecodedMessage>(
|
194
218
|
decoders: IDecoder<T>[],
|
195
219
|
options?: QueryOptions
|
196
220
|
): AsyncGenerator<Promise<T | undefined>[]> {
|
197
|
-
|
221
|
+
if (decoders.length === 0) {
|
222
|
+
throw new Error("No decoders provided");
|
223
|
+
}
|
198
224
|
|
199
225
|
let startTime, endTime;
|
200
226
|
|
@@ -203,6 +229,33 @@ class Store extends BaseProtocol implements IStore {
|
|
203
229
|
endTime = options.timeFilter.endTime;
|
204
230
|
}
|
205
231
|
|
232
|
+
// convert array to set to remove duplicates
|
233
|
+
const uniquePubSubTopicsInQuery = Array.from(
|
234
|
+
new Set(decoders.map((decoder) => decoder.pubsubTopic))
|
235
|
+
);
|
236
|
+
|
237
|
+
// If multiple pubsub topics are provided, throw an error
|
238
|
+
if (uniquePubSubTopicsInQuery.length > 1) {
|
239
|
+
throw new Error(
|
240
|
+
"API does not support querying multiple pubsub topics at once"
|
241
|
+
);
|
242
|
+
}
|
243
|
+
|
244
|
+
// we can be certain that there is only one pubsub topic in the query
|
245
|
+
const pubSubTopicForQuery = uniquePubSubTopicsInQuery[0];
|
246
|
+
|
247
|
+
ensurePubsubTopicIsConfigured(pubSubTopicForQuery, this.pubsubTopics);
|
248
|
+
|
249
|
+
// check that the pubsubTopic from the Cursor and Decoder match
|
250
|
+
if (
|
251
|
+
options?.cursor?.pubsubTopic &&
|
252
|
+
options.cursor.pubsubTopic !== pubSubTopicForQuery
|
253
|
+
) {
|
254
|
+
throw new Error(
|
255
|
+
`Cursor pubsub topic (${options?.cursor?.pubsubTopic}) does not match decoder pubsub topic (${pubSubTopicForQuery})`
|
256
|
+
);
|
257
|
+
}
|
258
|
+
|
206
259
|
const decodersAsMap = new Map();
|
207
260
|
decoders.forEach((dec) => {
|
208
261
|
if (decodersAsMap.has(dec.contentTopic)) {
|
@@ -213,27 +266,35 @@ class Store extends BaseProtocol implements IStore {
|
|
213
266
|
decodersAsMap.set(dec.contentTopic, dec);
|
214
267
|
});
|
215
268
|
|
216
|
-
const contentTopics = decoders
|
269
|
+
const contentTopics = decoders
|
270
|
+
.filter((decoder) => decoder.pubsubTopic === pubSubTopicForQuery)
|
271
|
+
.map((dec) => dec.contentTopic);
|
272
|
+
|
273
|
+
if (contentTopics.length === 0) {
|
274
|
+
throw new Error("No decoders found for topic " + pubSubTopicForQuery);
|
275
|
+
}
|
217
276
|
|
218
277
|
const queryOpts = Object.assign(
|
219
278
|
{
|
220
|
-
|
279
|
+
pubsubTopic: pubSubTopicForQuery,
|
221
280
|
pageDirection: PageDirection.BACKWARD,
|
222
|
-
pageSize: DefaultPageSize
|
281
|
+
pageSize: DefaultPageSize
|
223
282
|
},
|
224
283
|
options,
|
225
284
|
{ contentTopics, startTime, endTime }
|
226
285
|
);
|
227
286
|
|
228
|
-
log("Querying history with the following options",
|
229
|
-
...options,
|
230
|
-
peerId: options?.peerId?.toString(),
|
231
|
-
});
|
287
|
+
log("Querying history with the following options", options);
|
232
288
|
|
233
|
-
const peer =
|
289
|
+
const peer = (
|
290
|
+
await this.getPeers({
|
291
|
+
numPeers: this.NUM_PEERS_PROTOCOL,
|
292
|
+
maxBootstrapPeers: 1
|
293
|
+
})
|
294
|
+
)[0];
|
234
295
|
|
235
296
|
for await (const messages of paginate<T>(
|
236
|
-
this.
|
297
|
+
this.getStream.bind(this, peer),
|
237
298
|
queryOpts,
|
238
299
|
decodersAsMap,
|
239
300
|
options?.cursor
|
@@ -266,7 +327,7 @@ async function* paginate<T extends IDecodedMessage>(
|
|
266
327
|
|
267
328
|
log(
|
268
329
|
"Querying store peer",
|
269
|
-
`for (${queryOpts.
|
330
|
+
`for (${queryOpts.pubsubTopic})`,
|
270
331
|
queryOpts.contentTopics
|
271
332
|
);
|
272
333
|
|
@@ -313,7 +374,7 @@ async function* paginate<T extends IDecodedMessage>(
|
|
313
374
|
const decoder = decoders.get(contentTopic);
|
314
375
|
if (decoder) {
|
315
376
|
return decoder.fromProtoObj(
|
316
|
-
queryOpts.
|
377
|
+
queryOpts.pubsubTopic,
|
317
378
|
toProtoMessage(protoMsg)
|
318
379
|
);
|
319
380
|
}
|
@@ -346,10 +407,7 @@ async function* paginate<T extends IDecodedMessage>(
|
|
346
407
|
}
|
347
408
|
}
|
348
409
|
|
349
|
-
export async function createCursor(
|
350
|
-
message: IDecodedMessage,
|
351
|
-
pubsubTopic: string = DefaultPubSubTopic
|
352
|
-
): Promise<Cursor> {
|
410
|
+
export async function createCursor(message: IDecodedMessage): Promise<Cursor> {
|
353
411
|
if (
|
354
412
|
!message ||
|
355
413
|
!message.timestamp ||
|
@@ -367,9 +425,9 @@ export async function createCursor(
|
|
367
425
|
|
368
426
|
return {
|
369
427
|
digest,
|
370
|
-
pubsubTopic,
|
428
|
+
pubsubTopic: message.pubsubTopic,
|
371
429
|
senderTime: messageTime,
|
372
|
-
receiverTime: messageTime
|
430
|
+
receiverTime: messageTime
|
373
431
|
};
|
374
432
|
}
|
375
433
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import type { PeerUpdate } from "@libp2p/interface";
|
2
|
+
import type { Stream } from "@libp2p/interface/connection";
|
3
|
+
import { Peer } from "@libp2p/interface/peer-store";
|
4
|
+
import { Libp2p } from "@waku/interfaces";
|
5
|
+
import { selectConnection } from "@waku/utils/libp2p";
|
6
|
+
import debug from "debug";
|
7
|
+
|
8
|
+
export class StreamManager {
|
9
|
+
private streamPool: Map<string, Promise<Stream | void>>;
|
10
|
+
private readonly log: debug.Debugger;
|
11
|
+
|
12
|
+
constructor(
|
13
|
+
public multicodec: string,
|
14
|
+
public getConnections: Libp2p["getConnections"],
|
15
|
+
public addEventListener: Libp2p["addEventListener"]
|
16
|
+
) {
|
17
|
+
this.log = debug(`waku:stream-manager:${multicodec}`);
|
18
|
+
this.addEventListener(
|
19
|
+
"peer:update",
|
20
|
+
this.handlePeerUpdateStreamPool.bind(this)
|
21
|
+
);
|
22
|
+
this.getStream = this.getStream.bind(this);
|
23
|
+
this.streamPool = new Map();
|
24
|
+
}
|
25
|
+
|
26
|
+
public async getStream(peer: Peer): Promise<Stream> {
|
27
|
+
const peerIdStr = peer.id.toString();
|
28
|
+
const streamPromise = this.streamPool.get(peerIdStr);
|
29
|
+
|
30
|
+
if (!streamPromise) {
|
31
|
+
return this.newStream(peer); // fallback by creating a new stream on the spot
|
32
|
+
}
|
33
|
+
|
34
|
+
// We have the stream, let's remove it from the map
|
35
|
+
this.streamPool.delete(peerIdStr);
|
36
|
+
|
37
|
+
this.prepareNewStream(peer);
|
38
|
+
|
39
|
+
const stream = await streamPromise;
|
40
|
+
|
41
|
+
if (!stream || stream.status === "closed") {
|
42
|
+
return this.newStream(peer); // fallback by creating a new stream on the spot
|
43
|
+
}
|
44
|
+
|
45
|
+
return stream;
|
46
|
+
}
|
47
|
+
|
48
|
+
private async newStream(peer: Peer): Promise<Stream> {
|
49
|
+
const connections = this.getConnections(peer.id);
|
50
|
+
const connection = selectConnection(connections);
|
51
|
+
if (!connection) {
|
52
|
+
throw new Error("Failed to get a connection to the peer");
|
53
|
+
}
|
54
|
+
return connection.newStream(this.multicodec);
|
55
|
+
}
|
56
|
+
|
57
|
+
private prepareNewStream(peer: Peer): void {
|
58
|
+
const streamPromise = this.newStream(peer).catch(() => {
|
59
|
+
// No error thrown as this call is not triggered by the user
|
60
|
+
this.log(`Failed to prepare a new stream for ${peer.id.toString()}`);
|
61
|
+
});
|
62
|
+
this.streamPool.set(peer.id.toString(), streamPromise);
|
63
|
+
}
|
64
|
+
|
65
|
+
private handlePeerUpdateStreamPool = (evt: CustomEvent<PeerUpdate>): void => {
|
66
|
+
const peer = evt.detail.peer;
|
67
|
+
if (peer.protocols.includes(this.multicodec)) {
|
68
|
+
this.log(`Preemptively opening a stream to ${peer.id.toString()}`);
|
69
|
+
this.prepareNewStream(peer);
|
70
|
+
}
|
71
|
+
};
|
72
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { IdentifyResult } from "@libp2p/interface
|
1
|
+
import type { IdentifyResult } from "@libp2p/interface";
|
2
2
|
import type { IBaseProtocol, IRelay, Waku } from "@waku/interfaces";
|
3
3
|
import { Protocols } from "@waku/interfaces";
|
4
4
|
import debug from "debug";
|
@@ -9,8 +9,8 @@ const log = debug("waku:wait-for-remote-peer");
|
|
9
9
|
/**
|
10
10
|
* Wait for a remote peer to be ready given the passed protocols.
|
11
11
|
* Must be used after attempting to connect to nodes, using
|
12
|
-
* {@link @waku/core
|
13
|
-
* {@link @waku/sdk
|
12
|
+
* {@link @waku/core!WakuNode.dial} or a bootstrap method with
|
13
|
+
* {@link @waku/sdk!createLightNode}.
|
14
14
|
*
|
15
15
|
* If the passed protocols is a GossipSub protocol, then it resolves only once
|
16
16
|
* a peer is in a mesh, to help ensure that other peers will send and receive
|
@@ -96,15 +96,18 @@ async function waitForConnectedPeer(protocol: IBaseProtocol): Promise<void> {
|
|
96
96
|
}
|
97
97
|
|
98
98
|
/**
|
99
|
-
* Wait for
|
100
|
-
* mesh.
|
99
|
+
* Wait for at least one peer with the given protocol to be connected and in the gossipsub
|
100
|
+
* mesh for all pubsubTopics.
|
101
101
|
*/
|
102
102
|
async function waitForGossipSubPeerInMesh(waku: IRelay): Promise<void> {
|
103
103
|
let peers = waku.getMeshPeers();
|
104
|
+
const pubsubTopics = waku.pubsubTopics;
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
for (const topic of pubsubTopics) {
|
107
|
+
while (peers.length == 0) {
|
108
|
+
await pEvent(waku.gossipSub, "gossipsub:heartbeat");
|
109
|
+
peers = waku.getMeshPeers(topic);
|
110
|
+
}
|
108
111
|
}
|
109
112
|
}
|
110
113
|
|
package/src/lib/waku.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import type { Stream } from "@libp2p/interface
|
2
|
-
import { isPeerId, PeerId } from "@libp2p/interface
|
1
|
+
import type { Stream } from "@libp2p/interface/connection";
|
2
|
+
import { isPeerId, PeerId } from "@libp2p/interface/peer-id";
|
3
3
|
import { multiaddr, Multiaddr, MultiaddrInput } from "@multiformats/multiaddr";
|
4
4
|
import type {
|
5
5
|
IFilter,
|
@@ -7,14 +7,15 @@ import type {
|
|
7
7
|
IRelay,
|
8
8
|
IStore,
|
9
9
|
Libp2p,
|
10
|
-
|
10
|
+
PubSubTopic,
|
11
|
+
Waku
|
11
12
|
} from "@waku/interfaces";
|
12
13
|
import { Protocols } from "@waku/interfaces";
|
13
14
|
import debug from "debug";
|
14
15
|
|
15
16
|
import { ConnectionManager } from "./connection_manager.js";
|
16
17
|
|
17
|
-
export const DefaultPingKeepAliveValueSecs =
|
18
|
+
export const DefaultPingKeepAliveValueSecs = 5 * 60;
|
18
19
|
export const DefaultRelayKeepAliveValueSecs = 5 * 60;
|
19
20
|
export const DefaultUserAgent = "js-waku";
|
20
21
|
|
@@ -52,6 +53,7 @@ export class WakuNode implements Waku {
|
|
52
53
|
|
53
54
|
constructor(
|
54
55
|
options: WakuOptions,
|
56
|
+
public readonly pubsubTopics: PubSubTopic[],
|
55
57
|
libp2p: Libp2p,
|
56
58
|
store?: (libp2p: Libp2p) => IStore,
|
57
59
|
lightPush?: (libp2p: Libp2p) => ILightPush,
|
@@ -86,6 +88,7 @@ export class WakuNode implements Waku {
|
|
86
88
|
peerId,
|
87
89
|
libp2p,
|
88
90
|
{ pingKeepAlive, relayKeepAlive },
|
91
|
+
pubsubTopics,
|
89
92
|
this.relay
|
90
93
|
);
|
91
94
|
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare function pushOrInitMapSet<K, V>(map: Map<K, Set<V>>, key: K, newValue: V): void;
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"push_or_init_map.js","sourceRoot":"","sources":["../../src/lib/push_or_init_map.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAC9B,GAAmB,EACnB,GAAM,EACN,QAAW;IAEX,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE;QAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACxB,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAW,CAAC;KAC9B;IAED,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACpB,CAAC"}
|