@libp2p/kad-dht 9.1.5 → 9.2.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 (46) hide show
  1. package/dist/index.min.js +16 -16
  2. package/dist/src/content-fetching/index.js +4 -4
  3. package/dist/src/content-fetching/index.js.map +1 -1
  4. package/dist/src/content-routing/index.d.ts +1 -2
  5. package/dist/src/content-routing/index.d.ts.map +1 -1
  6. package/dist/src/content-routing/index.js +8 -5
  7. package/dist/src/content-routing/index.js.map +1 -1
  8. package/dist/src/dual-kad-dht.d.ts +1 -2
  9. package/dist/src/dual-kad-dht.d.ts.map +1 -1
  10. package/dist/src/dual-kad-dht.js +7 -7
  11. package/dist/src/dual-kad-dht.js.map +1 -1
  12. package/dist/src/index.d.ts +16 -14
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +3 -3
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/network.d.ts +3 -3
  17. package/dist/src/network.d.ts.map +1 -1
  18. package/dist/src/network.js +9 -9
  19. package/dist/src/network.js.map +1 -1
  20. package/dist/src/peer-routing/index.d.ts +3 -3
  21. package/dist/src/peer-routing/index.d.ts.map +1 -1
  22. package/dist/src/peer-routing/index.js +14 -8
  23. package/dist/src/peer-routing/index.js.map +1 -1
  24. package/dist/src/query/events.d.ts +10 -10
  25. package/dist/src/query/events.d.ts.map +1 -1
  26. package/dist/src/query/events.js +36 -19
  27. package/dist/src/query/events.js.map +1 -1
  28. package/dist/src/query/manager.d.ts +2 -3
  29. package/dist/src/query/manager.d.ts.map +1 -1
  30. package/dist/src/query/manager.js +2 -1
  31. package/dist/src/query/manager.js.map +1 -1
  32. package/dist/src/query/query-path.d.ts +2 -2
  33. package/dist/src/query/query-path.d.ts.map +1 -1
  34. package/dist/src/query/query-path.js +1 -1
  35. package/dist/src/query/query-path.js.map +1 -1
  36. package/dist/typedoc-urls.json +4 -3
  37. package/package.json +2 -1
  38. package/src/content-fetching/index.ts +4 -4
  39. package/src/content-routing/index.ts +9 -7
  40. package/src/dual-kad-dht.ts +13 -14
  41. package/src/index.ts +25 -14
  42. package/src/network.ts +13 -13
  43. package/src/peer-routing/index.ts +17 -11
  44. package/src/query/events.ts +54 -21
  45. package/src/query/manager.ts +4 -4
  46. package/src/query/query-path.ts +3 -3
@@ -11,7 +11,6 @@ import { queryErrorEvent } from './query/events.js'
11
11
  import type { DualKadDHT, KadDHT, KadDHTComponents, KadDHTInit, QueryEvent, QueryOptions } from './index.js'
12
12
  import type { PeerId } from '@libp2p/interface-peer-id'
13
13
  import type { PeerInfo } from '@libp2p/interface-peer-info'
14
- import type { AbortOptions } from '@libp2p/interfaces'
15
14
  import type { CID } from 'multiformats/cid'
16
15
 
17
16
  const log = logger('libp2p:kad-dht')
@@ -26,11 +25,11 @@ class DHTContentRouting implements ContentRouting {
26
25
  this.dht = dht
27
26
  }
28
27
 
29
- async provide (cid: CID): Promise<void> {
30
- await drain(this.dht.provide(cid))
28
+ async provide (cid: CID, options: QueryOptions = {}): Promise<void> {
29
+ await drain(this.dht.provide(cid, options))
31
30
  }
32
31
 
33
- async * findProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
32
+ async * findProviders (cid: CID, options: QueryOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
34
33
  for await (const event of this.dht.findProviders(cid, options)) {
35
34
  if (event.name === 'PROVIDER') {
36
35
  yield * event.providers
@@ -38,11 +37,11 @@ class DHTContentRouting implements ContentRouting {
38
37
  }
39
38
  }
40
39
 
41
- async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
40
+ async put (key: Uint8Array, value: Uint8Array, options?: QueryOptions): Promise<void> {
42
41
  await drain(this.dht.put(key, value, options))
43
42
  }
44
43
 
45
- async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
44
+ async get (key: Uint8Array, options?: QueryOptions): Promise<Uint8Array> {
46
45
  for await (const event of this.dht.get(key, options)) {
47
46
  if (event.name === 'VALUE') {
48
47
  return event.value
@@ -63,7 +62,7 @@ class DHTPeerRouting implements PeerRouting {
63
62
  this.dht = dht
64
63
  }
65
64
 
66
- async findPeer (peerId: PeerId, options: AbortOptions = {}): Promise<PeerInfo> {
65
+ async findPeer (peerId: PeerId, options: QueryOptions = {}): Promise<PeerInfo> {
67
66
  for await (const event of this.dht.findPeer(peerId, options)) {
68
67
  if (event.name === 'FINAL_PEER') {
69
68
  return event.peer
@@ -73,7 +72,7 @@ class DHTPeerRouting implements PeerRouting {
73
72
  throw new CodeError('Not found', 'ERR_NOT_FOUND')
74
73
  }
75
74
 
76
- async * getClosestPeers (key: Uint8Array, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
75
+ async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncIterable<PeerInfo> {
77
76
  for await (const event of this.dht.getClosestPeers(key, options)) {
78
77
  if (event.name === 'FINAL_PEER') {
79
78
  yield event.peer
@@ -207,7 +206,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
207
206
  )) {
208
207
  yield event
209
208
 
210
- if (event.name === 'DIALING_PEER') {
209
+ if (event.name === 'DIAL_PEER') {
211
210
  queriedPeers = true
212
211
  }
213
212
 
@@ -219,7 +218,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
219
218
  }
220
219
  }
221
220
 
222
- if (event.name === 'SENDING_QUERY') {
221
+ if (event.name === 'SEND_QUERY') {
223
222
  queriedPeers = true
224
223
  }
225
224
  }
@@ -232,7 +231,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
232
231
  yield queryErrorEvent({
233
232
  from: this.components.peerId,
234
233
  error: new CodeError('Not found', 'ERR_NOT_FOUND')
235
- })
234
+ }, options)
236
235
  }
237
236
  }
238
237
 
@@ -241,7 +240,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
241
240
  /**
242
241
  * Announce to the network that we can provide given key's value
243
242
  */
244
- async * provide (key: CID, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
243
+ async * provide (key: CID, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
245
244
  let sent = 0
246
245
  let success = 0
247
246
  const errors = []
@@ -256,7 +255,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
256
255
  for await (const event of merge(...dhts.map(dht => dht.provide(key, options)))) {
257
256
  yield event
258
257
 
259
- if (event.name === 'SENDING_QUERY') {
258
+ if (event.name === 'SEND_QUERY') {
260
259
  sent++
261
260
  }
262
261
 
@@ -304,7 +303,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
304
303
  )) {
305
304
  yield event
306
305
 
307
- if (event.name === 'SENDING_QUERY' || event.name === 'FINAL_PEER') {
306
+ if (event.name === 'SEND_QUERY' || event.name === 'FINAL_PEER') {
308
307
  queriedPeers = true
309
308
  }
310
309
  }
package/src/index.ts CHANGED
@@ -10,19 +10,20 @@ import type { Registrar } from '@libp2p/interface-registrar'
10
10
  import type { AbortOptions } from '@libp2p/interfaces'
11
11
  import type { Datastore } from 'interface-datastore'
12
12
  import type { CID } from 'multiformats/cid'
13
+ import type { ProgressOptions, ProgressEvent } from 'progress-events'
13
14
 
14
15
  /**
15
16
  * The types of events emitted during DHT queries
16
17
  */
17
18
  export enum EventTypes {
18
- SENDING_QUERY = 0,
19
+ SEND_QUERY = 0,
19
20
  PEER_RESPONSE,
20
21
  FINAL_PEER,
21
22
  QUERY_ERROR,
22
23
  PROVIDER,
23
24
  VALUE,
24
- ADDING_PEER,
25
- DIALING_PEER
25
+ ADD_PEER,
26
+ DIAL_PEER
26
27
  }
27
28
 
28
29
  /**
@@ -45,17 +46,27 @@ export interface DHTRecord {
45
46
  timeReceived?: Date
46
47
  }
47
48
 
48
- export interface QueryOptions extends AbortOptions {
49
+ export type DHTProgressEvents =
50
+ ProgressEvent<'kad-dht:query:send-query', SendQueryEvent> |
51
+ ProgressEvent<'kad-dht:query:peer-response', PeerResponseEvent> |
52
+ ProgressEvent<'kad-dht:query:final-peer', FinalPeerEvent> |
53
+ ProgressEvent<'kad-dht:query:query-error', QueryErrorEvent> |
54
+ ProgressEvent<'kad-dht:query:provider', ProviderEvent> |
55
+ ProgressEvent<'kad-dht:query:value', ValueEvent> |
56
+ ProgressEvent<'kad-dht:query:add-peer', AddPeerEvent> |
57
+ ProgressEvent<'kad-dht:query:dial-peer', DialPeerEvent>
58
+
59
+ export interface QueryOptions extends AbortOptions, ProgressOptions {
49
60
  queryFuncTimeout?: number
50
61
  }
51
62
 
52
63
  /**
53
64
  * Emitted when sending queries to remote peers
54
65
  */
55
- export interface SendingQueryEvent {
66
+ export interface SendQueryEvent {
56
67
  to: PeerId
57
- type: EventTypes.SENDING_QUERY
58
- name: 'SENDING_QUERY'
68
+ type: EventTypes.SEND_QUERY
69
+ name: 'SEND_QUERY'
59
70
  messageName: keyof typeof MessageType
60
71
  messageType: MessageType
61
72
  }
@@ -118,22 +129,22 @@ export interface ValueEvent {
118
129
  /**
119
130
  * Emitted when peers are added to a query
120
131
  */
121
- export interface AddingPeerEvent {
122
- type: EventTypes.ADDING_PEER
123
- name: 'ADDING_PEER'
132
+ export interface AddPeerEvent {
133
+ type: EventTypes.ADD_PEER
134
+ name: 'ADD_PEER'
124
135
  peer: PeerId
125
136
  }
126
137
 
127
138
  /**
128
139
  * Emitted when peers are dialled as part of a query
129
140
  */
130
- export interface DialingPeerEvent {
141
+ export interface DialPeerEvent {
131
142
  peer: PeerId
132
- type: EventTypes.DIALING_PEER
133
- name: 'DIALING_PEER'
143
+ type: EventTypes.DIAL_PEER
144
+ name: 'DIAL_PEER'
134
145
  }
135
146
 
136
- export type QueryEvent = SendingQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddingPeerEvent | DialingPeerEvent
147
+ export type QueryEvent = SendQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddPeerEvent | DialPeerEvent
137
148
 
138
149
  export interface RoutingTable {
139
150
  size: number
package/src/network.ts CHANGED
@@ -8,12 +8,12 @@ import * as lp from 'it-length-prefixed'
8
8
  import { pipe } from 'it-pipe'
9
9
  import { Message } from './message/index.js'
10
10
  import {
11
- dialingPeerEvent,
12
- sendingQueryEvent,
11
+ dialPeerEvent,
12
+ sendQueryEvent,
13
13
  peerResponseEvent,
14
14
  queryErrorEvent
15
15
  } from './query/events.js'
16
- import type { KadDHTComponents, QueryEvent } from './index.js'
16
+ import type { KadDHTComponents, QueryEvent, QueryOptions } from './index.js'
17
17
  import type { Stream } from '@libp2p/interface-connection'
18
18
  import type { PeerId } from '@libp2p/interface-peer-id'
19
19
  import type { PeerInfo } from '@libp2p/interface-peer-info'
@@ -82,14 +82,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
82
82
  /**
83
83
  * Send a request and record RTT for latency measurements
84
84
  */
85
- async * sendRequest (to: PeerId, msg: Message, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
85
+ async * sendRequest (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
86
86
  if (!this.running) {
87
87
  return
88
88
  }
89
89
 
90
90
  this.log('sending %s to %p', msg.type, to)
91
- yield dialingPeerEvent({ peer: to })
92
- yield sendingQueryEvent({ to, type: msg.type })
91
+ yield dialPeerEvent({ peer: to }, options)
92
+ yield sendQueryEvent({ to, type: msg.type }, options)
93
93
 
94
94
  let stream: Stream | undefined
95
95
 
@@ -105,9 +105,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
105
105
  closer: response.closerPeers,
106
106
  providers: response.providerPeers,
107
107
  record: response.record
108
- })
108
+ }, options)
109
109
  } catch (err: any) {
110
- yield queryErrorEvent({ from: to, error: err })
110
+ yield queryErrorEvent({ from: to, error: err }, options)
111
111
  } finally {
112
112
  if (stream != null) {
113
113
  stream.close()
@@ -118,14 +118,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
118
118
  /**
119
119
  * Sends a message without expecting an answer
120
120
  */
121
- async * sendMessage (to: PeerId, msg: Message, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
121
+ async * sendMessage (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
122
122
  if (!this.running) {
123
123
  return
124
124
  }
125
125
 
126
126
  this.log('sending %s to %p', msg.type, to)
127
- yield dialingPeerEvent({ peer: to })
128
- yield sendingQueryEvent({ to, type: msg.type })
127
+ yield dialPeerEvent({ peer: to }, options)
128
+ yield sendQueryEvent({ to, type: msg.type }, options)
129
129
 
130
130
  let stream: Stream | undefined
131
131
 
@@ -135,9 +135,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
135
135
 
136
136
  await this._writeMessage(stream, msg.serialize(), options)
137
137
 
138
- yield peerResponseEvent({ from: to, messageType: msg.type })
138
+ yield peerResponseEvent({ from: to, messageType: msg.type }, options)
139
139
  } catch (err: any) {
140
- yield queryErrorEvent({ from: to, error: err })
140
+ yield queryErrorEvent({ from: to, error: err }, options)
141
141
  } finally {
142
142
  if (stream != null) {
143
143
  stream.close()
@@ -13,7 +13,7 @@ import {
13
13
  valueEvent
14
14
  } from '../query/events.js'
15
15
  import * as utils from '../utils.js'
16
- import type { KadDHTComponents, DHTRecord, DialingPeerEvent, FinalPeerEvent, QueryEvent, Validators } from '../index.js'
16
+ import type { KadDHTComponents, DHTRecord, DialPeerEvent, FinalPeerEvent, QueryEvent, Validators } from '../index.js'
17
17
  import type { Network } from '../network.js'
18
18
  import type { QueryManager, QueryOptions } from '../query/manager.js'
19
19
  import type { QueryFunc } from '../query/types.js'
@@ -122,7 +122,7 @@ export class PeerRouting {
122
122
  throw new CodeError('public key missing', 'ERR_PUBLIC_KEY_MISSING')
123
123
  }
124
124
 
125
- yield valueEvent({ from: peer, value: recPeer.publicKey })
125
+ yield valueEvent({ from: peer, value: recPeer.publicKey }, options)
126
126
  }
127
127
  }
128
128
 
@@ -144,7 +144,7 @@ export class PeerRouting {
144
144
  yield finalPeerEvent({
145
145
  from: this.components.peerId,
146
146
  peer: pi
147
- })
147
+ }, options)
148
148
  return
149
149
  }
150
150
 
@@ -153,7 +153,10 @@ export class PeerRouting {
153
153
  const findPeerQuery: QueryFunc = async function * ({ peer, signal }) {
154
154
  const request = new Message(MESSAGE_TYPE.FIND_NODE, id.toBytes(), 0)
155
155
 
156
- for await (const event of self.network.sendRequest(peer, request, { signal })) {
156
+ for await (const event of self.network.sendRequest(peer, request, {
157
+ ...options,
158
+ signal
159
+ })) {
157
160
  yield event
158
161
 
159
162
  if (event.name === 'PEER_RESPONSE') {
@@ -161,7 +164,7 @@ export class PeerRouting {
161
164
 
162
165
  // found the peer
163
166
  if (match != null) {
164
- yield finalPeerEvent({ from: event.from, peer: match })
167
+ yield finalPeerEvent({ from: event.from, peer: match }, options)
165
168
  }
166
169
  }
167
170
  }
@@ -178,7 +181,7 @@ export class PeerRouting {
178
181
  }
179
182
 
180
183
  if (!foundPeer) {
181
- yield queryErrorEvent({ from: this.components.peerId, error: new CodeError('Not found', 'ERR_NOT_FOUND') })
184
+ yield queryErrorEvent({ from: this.components.peerId, error: new CodeError('Not found', 'ERR_NOT_FOUND') }, options)
182
185
  }
183
186
  }
184
187
 
@@ -186,7 +189,7 @@ export class PeerRouting {
186
189
  * Kademlia 'node lookup' operation on a key, which could be a the
187
190
  * bytes from a multihash or a peer ID
188
191
  */
189
- async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<DialingPeerEvent | QueryEvent> {
192
+ async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<DialPeerEvent | QueryEvent> {
190
193
  this.log('getClosestPeers to %b', key)
191
194
  const id = await utils.convertBuffer(key)
192
195
  const tablePeers = this.routingTable.closestPeers(id)
@@ -199,7 +202,10 @@ export class PeerRouting {
199
202
  self.log('closerPeersSingle %s from %p', uint8ArrayToString(key, 'base32'), peer)
200
203
  const request = new Message(MESSAGE_TYPE.FIND_NODE, key, 0)
201
204
 
202
- yield * self.network.sendRequest(peer, request, { signal })
205
+ yield * self.network.sendRequest(peer, request, {
206
+ ...options,
207
+ signal
208
+ })
203
209
  }
204
210
 
205
211
  for await (const event of this.queryManager.run(key, getCloserPeersQuery, options)) {
@@ -223,7 +229,7 @@ export class PeerRouting {
223
229
  multiaddrs: peer.addresses.map(({ multiaddr }) => multiaddr),
224
230
  protocols: peer.protocols
225
231
  }
226
- })
232
+ }, options)
227
233
  } catch (err: any) {
228
234
  if (err.code !== 'ERR_NOT_FOUND') {
229
235
  throw err
@@ -238,7 +244,7 @@ export class PeerRouting {
238
244
  *
239
245
  * Note: The peerStore is updated with new addresses found for the given peer.
240
246
  */
241
- async * getValueOrPeers (peer: PeerId, key: Uint8Array, options: AbortOptions = {}): AsyncGenerator<DialingPeerEvent | QueryEvent> {
247
+ async * getValueOrPeers (peer: PeerId, key: Uint8Array, options: AbortOptions = {}): AsyncGenerator<DialPeerEvent | QueryEvent> {
242
248
  for await (const event of this._getValueSingle(peer, key, options)) {
243
249
  if (event.name === 'PEER_RESPONSE') {
244
250
  if (event.record != null) {
@@ -249,7 +255,7 @@ export class PeerRouting {
249
255
  const errMsg = 'invalid record received, discarded'
250
256
  this.log(errMsg)
251
257
 
252
- yield queryErrorEvent({ from: event.from, error: new CodeError(errMsg, 'ERR_INVALID_RECORD') })
258
+ yield queryErrorEvent({ from: event.from, error: new CodeError(errMsg, 'ERR_INVALID_RECORD') }, options)
253
259
  continue
254
260
  }
255
261
  }
@@ -1,5 +1,6 @@
1
+ import { CustomEvent } from '@libp2p/interfaces/events'
1
2
  import { MESSAGE_TYPE_LOOKUP } from '../message/index.js'
2
- import type { SendingQueryEvent, PeerResponseEvent, DialingPeerEvent, AddingPeerEvent, ValueEvent, ProviderEvent, QueryErrorEvent, FinalPeerEvent } from '../index.js'
3
+ import type { SendQueryEvent, PeerResponseEvent, DialPeerEvent, AddPeerEvent, ValueEvent, ProviderEvent, QueryErrorEvent, FinalPeerEvent, QueryOptions } from '../index.js'
3
4
  import type { Message } from '../message/dht.js'
4
5
  import type { PeerId } from '@libp2p/interface-peer-id'
5
6
  import type { PeerInfo } from '@libp2p/interface-peer-info'
@@ -10,14 +11,18 @@ export interface QueryEventFields {
10
11
  type: Message.MessageType
11
12
  }
12
13
 
13
- export function sendingQueryEvent (fields: QueryEventFields): SendingQueryEvent {
14
- return {
14
+ export function sendQueryEvent (fields: QueryEventFields, options: QueryOptions = {}): SendQueryEvent {
15
+ const event: SendQueryEvent = {
15
16
  ...fields,
16
- name: 'SENDING_QUERY',
17
+ name: 'SEND_QUERY',
17
18
  type: 0,
18
19
  messageName: fields.type,
19
20
  messageType: MESSAGE_TYPE_LOOKUP.indexOf(fields.type.toString())
20
21
  }
22
+
23
+ options.onProgress?.(new CustomEvent('kad-dht:query:send-query', { detail: event }))
24
+
25
+ return event
21
26
  }
22
27
 
23
28
  export interface PeerResponseEventField {
@@ -28,8 +33,8 @@ export interface PeerResponseEventField {
28
33
  record?: Libp2pRecord
29
34
  }
30
35
 
31
- export function peerResponseEvent (fields: PeerResponseEventField): PeerResponseEvent {
32
- return {
36
+ export function peerResponseEvent (fields: PeerResponseEventField, options: QueryOptions = {}): PeerResponseEvent {
37
+ const event: PeerResponseEvent = {
33
38
  ...fields,
34
39
  name: 'PEER_RESPONSE',
35
40
  type: 1,
@@ -37,6 +42,10 @@ export function peerResponseEvent (fields: PeerResponseEventField): PeerResponse
37
42
  closer: (fields.closer != null) ? fields.closer : [],
38
43
  providers: (fields.providers != null) ? fields.providers : []
39
44
  }
45
+
46
+ options.onProgress?.(new CustomEvent('kad-dht:query:peer-response', { detail: event }))
47
+
48
+ return event
40
49
  }
41
50
 
42
51
  export interface FinalPeerEventFields {
@@ -44,12 +53,16 @@ export interface FinalPeerEventFields {
44
53
  peer: PeerInfo
45
54
  }
46
55
 
47
- export function finalPeerEvent (fields: FinalPeerEventFields): FinalPeerEvent {
48
- return {
56
+ export function finalPeerEvent (fields: FinalPeerEventFields, options: QueryOptions = {}): FinalPeerEvent {
57
+ const event: FinalPeerEvent = {
49
58
  ...fields,
50
59
  name: 'FINAL_PEER',
51
60
  type: 2
52
61
  }
62
+
63
+ options.onProgress?.(new CustomEvent('kad-dht:query:final-peer', { detail: event }))
64
+
65
+ return event
53
66
  }
54
67
 
55
68
  export interface ErrorEventFields {
@@ -57,12 +70,16 @@ export interface ErrorEventFields {
57
70
  error: Error
58
71
  }
59
72
 
60
- export function queryErrorEvent (fields: ErrorEventFields): QueryErrorEvent {
61
- return {
73
+ export function queryErrorEvent (fields: ErrorEventFields, options: QueryOptions = {}): QueryErrorEvent {
74
+ const event: QueryErrorEvent = {
62
75
  ...fields,
63
76
  name: 'QUERY_ERROR',
64
77
  type: 3
65
78
  }
79
+
80
+ options.onProgress?.(new CustomEvent('kad-dht:query:query-error', { detail: event }))
81
+
82
+ return event
66
83
  }
67
84
 
68
85
  export interface ProviderEventFields {
@@ -70,12 +87,16 @@ export interface ProviderEventFields {
70
87
  providers: PeerInfo[]
71
88
  }
72
89
 
73
- export function providerEvent (fields: ProviderEventFields): ProviderEvent {
74
- return {
90
+ export function providerEvent (fields: ProviderEventFields, options: QueryOptions = {}): ProviderEvent {
91
+ const event: ProviderEvent = {
75
92
  ...fields,
76
93
  name: 'PROVIDER',
77
94
  type: 4
78
95
  }
96
+
97
+ options.onProgress?.(new CustomEvent('kad-dht:query:provider', { detail: event }))
98
+
99
+ return event
79
100
  }
80
101
 
81
102
  export interface ValueEventFields {
@@ -83,34 +104,46 @@ export interface ValueEventFields {
83
104
  value: Uint8Array
84
105
  }
85
106
 
86
- export function valueEvent (fields: ValueEventFields): ValueEvent {
87
- return {
107
+ export function valueEvent (fields: ValueEventFields, options: QueryOptions = {}): ValueEvent {
108
+ const event: ValueEvent = {
88
109
  ...fields,
89
110
  name: 'VALUE',
90
111
  type: 5
91
112
  }
113
+
114
+ options.onProgress?.(new CustomEvent('kad-dht:query:value', { detail: event }))
115
+
116
+ return event
92
117
  }
93
118
 
94
119
  export interface PeerEventFields {
95
120
  peer: PeerId
96
121
  }
97
122
 
98
- export function addingPeerEvent (fields: PeerEventFields): AddingPeerEvent {
99
- return {
123
+ export function addPeerEvent (fields: PeerEventFields, options: QueryOptions = {}): AddPeerEvent {
124
+ const event: AddPeerEvent = {
100
125
  ...fields,
101
- name: 'ADDING_PEER',
126
+ name: 'ADD_PEER',
102
127
  type: 6
103
128
  }
129
+
130
+ options.onProgress?.(new CustomEvent('kad-dht:query:add-peer', { detail: event }))
131
+
132
+ return event
104
133
  }
105
134
 
106
- export interface DialingPeerEventFields {
135
+ export interface DialPeerEventFields {
107
136
  peer: PeerId
108
137
  }
109
138
 
110
- export function dialingPeerEvent (fields: DialingPeerEventFields): DialingPeerEvent {
111
- return {
139
+ export function dialPeerEvent (fields: DialPeerEventFields, options: QueryOptions = {}): DialPeerEvent {
140
+ const event: DialPeerEvent = {
112
141
  ...fields,
113
- name: 'DIALING_PEER',
142
+ name: 'DIAL_PEER',
114
143
  type: 7
115
144
  }
145
+
146
+ options.onProgress?.(new CustomEvent('kad-dht:query:dial-peer', { detail: event }))
147
+
148
+ return event
116
149
  }
@@ -12,11 +12,10 @@ import {
12
12
  import { convertBuffer } from '../utils.js'
13
13
  import { queryPath } from './query-path.js'
14
14
  import type { QueryFunc } from './types.js'
15
- import type { QueryEvent } from '../index.js'
15
+ import type { QueryEvent, QueryOptions as RootQueryOptions } from '../index.js'
16
16
  import type { RoutingTable } from '../routing-table/index.js'
17
17
  import type { Metric, Metrics } from '@libp2p/interface-metrics'
18
18
  import type { PeerId } from '@libp2p/interface-peer-id'
19
- import type { AbortOptions } from '@libp2p/interfaces'
20
19
  import type { Startable } from '@libp2p/interfaces/startable'
21
20
  import type { DeferredPromise } from 'p-defer'
22
21
 
@@ -37,7 +36,7 @@ export interface QueryManagerComponents {
37
36
  metrics?: Metrics
38
37
  }
39
38
 
40
- export interface QueryOptions extends AbortOptions {
39
+ export interface QueryOptions extends RootQueryOptions {
41
40
  queryFuncTimeout?: number
42
41
  isSelfQuery?: boolean
43
42
  }
@@ -192,7 +191,8 @@ export class QueryManager implements Startable {
192
191
  cleanUp,
193
192
  queryFuncTimeout: options.queryFuncTimeout,
194
193
  log,
195
- peersSeen
194
+ peersSeen,
195
+ onProgress: options.onProgress
196
196
  })
197
197
  })
198
198
 
@@ -7,7 +7,7 @@ import { xor } from 'uint8arrays/xor'
7
7
  import { convertPeerId, convertBuffer } from '../utils.js'
8
8
  import { queryErrorEvent } from './events.js'
9
9
  import type { CleanUpEvents } from './manager.js'
10
- import type { QueryEvent } from '../index.js'
10
+ import type { QueryEvent, QueryOptions } from '../index.js'
11
11
  import type { QueryFunc } from '../query/types.js'
12
12
  import type { PeerId } from '@libp2p/interface-peer-id'
13
13
  import type { EventEmitter } from '@libp2p/interfaces/events'
@@ -16,7 +16,7 @@ import type { PeerSet } from '@libp2p/peer-collections'
16
16
 
17
17
  const MAX_XOR = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
18
18
 
19
- export interface QueryPathOptions {
19
+ export interface QueryPathOptions extends QueryOptions {
20
20
  /**
21
21
  * What are we trying to find
22
22
  */
@@ -160,7 +160,7 @@ export async function * queryPath (options: QueryPathOptions): AsyncGenerator<Qu
160
160
  return queryErrorEvent({
161
161
  from: peer,
162
162
  error: err
163
- })
163
+ }, options)
164
164
  }
165
165
  } finally {
166
166
  compoundSignal.clear()