@libp2p/devtools-metrics 0.2.0 → 0.2.1
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/dist/index.min.js +1 -1
- package/dist/src/index.d.ts +24 -95
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +66 -131
- package/dist/src/index.js.map +1 -1
- package/dist/src/rpc/codecs/cid.d.ts +4 -0
- package/dist/src/rpc/codecs/cid.d.ts.map +1 -0
- package/dist/src/rpc/codecs/cid.js +8 -0
- package/dist/src/rpc/codecs/cid.js.map +1 -0
- package/dist/src/rpc/codecs/custom-progress-event.d.ts +4 -0
- package/dist/src/rpc/codecs/custom-progress-event.d.ts.map +1 -0
- package/dist/src/rpc/codecs/custom-progress-event.js +15 -0
- package/dist/src/rpc/codecs/custom-progress-event.js.map +1 -0
- package/dist/src/rpc/codecs/multiaddr.d.ts +4 -0
- package/dist/src/rpc/codecs/multiaddr.d.ts.map +1 -0
- package/dist/src/rpc/codecs/multiaddr.js +8 -0
- package/dist/src/rpc/codecs/multiaddr.js.map +1 -0
- package/dist/src/rpc/codecs/peer-id.d.ts +4 -0
- package/dist/src/rpc/codecs/peer-id.d.ts.map +1 -0
- package/dist/src/rpc/codecs/peer-id.js +9 -0
- package/dist/src/rpc/codecs/peer-id.js.map +1 -0
- package/dist/src/rpc/index.d.ts +99 -0
- package/dist/src/rpc/index.d.ts.map +1 -0
- package/dist/src/rpc/index.js +11 -0
- package/dist/src/rpc/index.js.map +1 -0
- package/dist/src/rpc/rpc.d.ts +4 -0
- package/dist/src/rpc/rpc.d.ts.map +1 -0
- package/dist/src/rpc/rpc.js +51 -0
- package/dist/src/rpc/rpc.js.map +1 -0
- package/dist/src/utils/debounce.d.ts +2 -0
- package/dist/src/utils/debounce.d.ts.map +1 -0
- package/dist/src/utils/debounce.js +21 -0
- package/dist/src/utils/debounce.js.map +1 -0
- package/dist/src/utils/get-peers.d.ts +9 -0
- package/dist/src/utils/get-peers.d.ts.map +1 -0
- package/dist/src/utils/get-peers.js +42 -0
- package/dist/src/utils/get-peers.js.map +1 -0
- package/dist/src/utils/get-self.d.ts +8 -0
- package/dist/src/utils/get-self.d.ts.map +1 -0
- package/dist/src/utils/get-self.js +13 -0
- package/dist/src/utils/get-self.js.map +1 -0
- package/dist/src/utils/to-object.d.ts +2 -0
- package/dist/src/utils/to-object.d.ts.map +1 -0
- package/dist/src/utils/to-object.js +8 -0
- package/dist/src/utils/to-object.js.map +1 -0
- package/dist/typedoc-urls.json +17 -13
- package/package.json +34 -8
- package/src/index.ts +101 -257
- package/src/rpc/codecs/cid.ts +9 -0
- package/src/rpc/codecs/custom-progress-event.ts +17 -0
- package/src/rpc/codecs/multiaddr.ts +10 -0
- package/src/rpc/codecs/peer-id.ts +11 -0
- package/src/rpc/index.ts +122 -0
- package/src/rpc/rpc.ts +59 -0
- package/src/utils/debounce.ts +23 -0
- package/src/utils/get-peers.ts +53 -0
- package/src/utils/get-self.ts +21 -0
- package/src/utils/to-object.ts +9 -0
package/src/index.ts
CHANGED
|
@@ -17,11 +17,22 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { serviceCapabilities, start, stop } from '@libp2p/interface'
|
|
20
|
-
import { enable, disable } from '@libp2p/logger'
|
|
21
20
|
import { simpleMetrics } from '@libp2p/simple-metrics'
|
|
21
|
+
import { pipe } from 'it-pipe'
|
|
22
|
+
import { pushable } from 'it-pushable'
|
|
23
|
+
import { rpc, type RPC } from 'it-rpc'
|
|
22
24
|
import { base64 } from 'multiformats/bases/base64'
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
+
import { valueCodecs } from './rpc/index.js'
|
|
26
|
+
import { metricsRpc } from './rpc/rpc.js'
|
|
27
|
+
import { debounce } from './utils/debounce.js'
|
|
28
|
+
import { getPeers } from './utils/get-peers.js'
|
|
29
|
+
import { getSelf } from './utils/get-self.js'
|
|
30
|
+
import type { DevToolsRPC } from './rpc/index.js'
|
|
31
|
+
import type { ComponentLogger, Connection, Libp2pEvents, Logger, Metrics, MultiaddrConnection, PeerId, PeerStore, Stream, ContentRouting, PeerRouting, TypedEventTarget, Startable } from '@libp2p/interface'
|
|
32
|
+
import type { TransportManager, Registrar, ConnectionManager, AddressManager } from '@libp2p/interface-internal'
|
|
33
|
+
import type { Pushable } from 'it-pushable'
|
|
34
|
+
|
|
35
|
+
export * from './rpc/index.js'
|
|
25
36
|
|
|
26
37
|
export const SOURCE_DEVTOOLS = '@libp2p/devtools-metrics:devtools'
|
|
27
38
|
export const SOURCE_SERVICE_WORKER = '@libp2p/devtools-metrics:worker'
|
|
@@ -36,39 +47,12 @@ Object.defineProperty(globalThis, LIBP2P_DEVTOOLS_METRICS_KEY, {
|
|
|
36
47
|
writable: false
|
|
37
48
|
})
|
|
38
49
|
|
|
39
|
-
/**
|
|
40
|
-
* Sent when new metrics are available
|
|
41
|
-
*/
|
|
42
|
-
export interface MetricsMessage {
|
|
43
|
-
source: typeof SOURCE_METRICS
|
|
44
|
-
type: 'metrics'
|
|
45
|
-
metrics: Record<string, any>
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* This message represents the current state of the libp2p node
|
|
50
|
-
*/
|
|
51
|
-
export interface SelfMessage {
|
|
52
|
-
source: typeof SOURCE_METRICS
|
|
53
|
-
type: 'self'
|
|
54
|
-
peer: SelfPeer
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* This message represents the current state of the libp2p node
|
|
59
|
-
*/
|
|
60
|
-
export interface PeersMessage {
|
|
61
|
-
source: typeof SOURCE_METRICS
|
|
62
|
-
type: 'peers'
|
|
63
|
-
peers: Peer[]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
50
|
/**
|
|
67
51
|
* Sent by the DevTools service worker to the DevTools panel when the inspected
|
|
68
52
|
* page has finished (re)loading
|
|
69
53
|
*/
|
|
70
54
|
export interface PageLoadedMessage {
|
|
71
|
-
source:
|
|
55
|
+
source: typeof SOURCE_DEVTOOLS
|
|
72
56
|
type: 'page-loaded'
|
|
73
57
|
tabId: number
|
|
74
58
|
}
|
|
@@ -81,47 +65,40 @@ export interface PageLoadedMessage {
|
|
|
81
65
|
* not having granted permission for the script to run.
|
|
82
66
|
*/
|
|
83
67
|
export interface PermissionsErrorMessage {
|
|
84
|
-
source:
|
|
68
|
+
source: typeof SOURCE_DEVTOOLS
|
|
85
69
|
type: 'permissions-error'
|
|
86
70
|
tabId: number
|
|
87
71
|
}
|
|
88
72
|
|
|
89
73
|
/**
|
|
90
|
-
* This
|
|
74
|
+
* This event is intercepted by the service worker which injects a content
|
|
75
|
+
* script into the current page which copies the passed value to the clipboard.
|
|
91
76
|
*/
|
|
92
|
-
export interface
|
|
93
|
-
source:
|
|
94
|
-
type: '
|
|
77
|
+
export interface CopyToClipboardMessage {
|
|
78
|
+
source: typeof SOURCE_DEVTOOLS
|
|
79
|
+
type: 'copy-to-clipboard'
|
|
95
80
|
tabId: number
|
|
81
|
+
value: string
|
|
96
82
|
}
|
|
97
83
|
|
|
98
84
|
/**
|
|
99
|
-
*
|
|
85
|
+
* Invoke a method on the libp2p object
|
|
100
86
|
*/
|
|
101
|
-
export interface
|
|
102
|
-
source:
|
|
103
|
-
type: '
|
|
104
|
-
namespace: string
|
|
87
|
+
export interface RPCMessage {
|
|
88
|
+
source: typeof SOURCE_DEVTOOLS | typeof SOURCE_METRICS
|
|
89
|
+
type: 'libp2p-rpc'
|
|
105
90
|
tabId: number
|
|
106
|
-
}
|
|
107
91
|
|
|
108
|
-
/**
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
* @see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard#writing_to_the_clipboard
|
|
113
|
-
*/
|
|
114
|
-
export interface CopyToClipboardMessage {
|
|
115
|
-
source: '@libp2p/devtools-metrics:devtools'
|
|
116
|
-
type: 'copy-to-clipboard'
|
|
117
|
-
value: string
|
|
118
|
-
tabId: number
|
|
92
|
+
/**
|
|
93
|
+
* The RPC message encoded as a multibase string
|
|
94
|
+
*/
|
|
95
|
+
message: string
|
|
119
96
|
}
|
|
120
97
|
|
|
121
98
|
/**
|
|
122
99
|
* Messages that are sent from the application page to the DevTools panel
|
|
123
100
|
*/
|
|
124
|
-
export type ApplicationMessage =
|
|
101
|
+
export type ApplicationMessage = RPCMessage
|
|
125
102
|
|
|
126
103
|
/**
|
|
127
104
|
* Messages that are sent from the service worker
|
|
@@ -131,34 +108,7 @@ export type WorkerMessage = PageLoadedMessage | PermissionsErrorMessage
|
|
|
131
108
|
/**
|
|
132
109
|
* Messages that are sent from the DevTools panel page to the application page
|
|
133
110
|
*/
|
|
134
|
-
export type DevToolsMessage =
|
|
135
|
-
|
|
136
|
-
export interface SelfPeer {
|
|
137
|
-
/**
|
|
138
|
-
* The identifier of the peer
|
|
139
|
-
*/
|
|
140
|
-
id: string
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* The list of multiaddrs the peer is listening on
|
|
144
|
-
*/
|
|
145
|
-
multiaddrs: string[]
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Any peer store tags the peer has
|
|
149
|
-
*/
|
|
150
|
-
tags: Record<string, number>
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Any peer store metadata the peer has
|
|
154
|
-
*/
|
|
155
|
-
metadata: Record<string, string>
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* The protocols the peer supports
|
|
159
|
-
*/
|
|
160
|
-
protocols: string[]
|
|
161
|
-
}
|
|
111
|
+
export type DevToolsMessage = CopyToClipboardMessage | RPCMessage
|
|
162
112
|
|
|
163
113
|
export interface Address {
|
|
164
114
|
/**
|
|
@@ -178,33 +128,6 @@ export interface Address {
|
|
|
178
128
|
isConnected?: boolean
|
|
179
129
|
}
|
|
180
130
|
|
|
181
|
-
export interface Peer {
|
|
182
|
-
/**
|
|
183
|
-
* The identifier of the remote peer
|
|
184
|
-
*/
|
|
185
|
-
id: string
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* The list of addresses the peer has that we know about
|
|
189
|
-
*/
|
|
190
|
-
addresses: Address[]
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Any peer store tags the peer has
|
|
194
|
-
*/
|
|
195
|
-
tags: Record<string, number>
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Any peer store metadata the peer has
|
|
199
|
-
*/
|
|
200
|
-
metadata: Record<string, string>
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* The protocols the peer supports, if known
|
|
204
|
-
*/
|
|
205
|
-
protocols: string[]
|
|
206
|
-
}
|
|
207
|
-
|
|
208
131
|
export interface DevToolsMetricsInit {
|
|
209
132
|
/**
|
|
210
133
|
* How often to pass metrics to the DevTools panel
|
|
@@ -220,36 +143,47 @@ export interface DevToolsMetricsComponents {
|
|
|
220
143
|
registrar: Registrar
|
|
221
144
|
connectionManager: ConnectionManager
|
|
222
145
|
peerStore: PeerStore
|
|
146
|
+
|
|
147
|
+
contentRouting: ContentRouting
|
|
148
|
+
peerRouting: PeerRouting
|
|
149
|
+
addressManager: AddressManager
|
|
223
150
|
}
|
|
224
151
|
|
|
225
|
-
class DevToolsMetrics implements Metrics {
|
|
152
|
+
class DevToolsMetrics implements Metrics, Startable {
|
|
226
153
|
private readonly log: Logger
|
|
227
154
|
private readonly components: DevToolsMetricsComponents
|
|
228
155
|
private readonly simpleMetrics: Metrics
|
|
229
156
|
private readonly intervalMs?: number
|
|
157
|
+
private readonly rpcQueue: Pushable<Uint8Array>
|
|
158
|
+
private readonly rpc: RPC
|
|
159
|
+
private readonly devTools: DevToolsRPC
|
|
230
160
|
|
|
231
161
|
constructor (components: DevToolsMetricsComponents, init?: Partial<DevToolsMetricsInit>) {
|
|
232
162
|
this.log = components.logger.forComponent('libp2p:devtools-metrics')
|
|
233
163
|
this.intervalMs = init?.intervalMs
|
|
234
164
|
this.components = components
|
|
235
165
|
|
|
166
|
+
// create RPC endpoint
|
|
167
|
+
this.rpcQueue = pushable()
|
|
168
|
+
this.rpc = rpc({
|
|
169
|
+
valueCodecs
|
|
170
|
+
})
|
|
171
|
+
this.devTools = this.rpc.createClient('devTools')
|
|
172
|
+
|
|
236
173
|
// collect information on current peers and sent it to the dev tools panel
|
|
237
174
|
this.onPeersUpdate = debounce(this.onPeersUpdate.bind(this), 1000)
|
|
238
|
-
this.onSelfUpdate = this.onSelfUpdate.bind(this)
|
|
175
|
+
this.onSelfUpdate = debounce(this.onSelfUpdate.bind(this), 1000)
|
|
239
176
|
this.onIncomingMessage = this.onIncomingMessage.bind(this)
|
|
240
177
|
|
|
241
178
|
// collect metrics
|
|
242
179
|
this.simpleMetrics = simpleMetrics({
|
|
243
180
|
intervalMs: this.intervalMs,
|
|
244
181
|
onMetrics: (metrics) => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
metrics
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
this.log('post metrics message')
|
|
252
|
-
window.postMessage(message, '*')
|
|
182
|
+
this.devTools.safeDispatchEvent('metrics', {
|
|
183
|
+
detail: metrics
|
|
184
|
+
}).catch(err => {
|
|
185
|
+
this.log.error('error sending metrics', err)
|
|
186
|
+
})
|
|
253
187
|
}
|
|
254
188
|
})({})
|
|
255
189
|
}
|
|
@@ -297,8 +231,32 @@ class DevToolsMetrics implements Metrics {
|
|
|
297
231
|
// process incoming messages from devtools
|
|
298
232
|
window.addEventListener('message', this.onIncomingMessage)
|
|
299
233
|
|
|
234
|
+
// create rpc target
|
|
235
|
+
this.rpc.createTarget('metrics', metricsRpc(this.components))
|
|
236
|
+
|
|
300
237
|
// send metrics
|
|
301
238
|
await start(this.simpleMetrics)
|
|
239
|
+
|
|
240
|
+
// send RPC messages
|
|
241
|
+
Promise.resolve()
|
|
242
|
+
.then(async () => {
|
|
243
|
+
await pipe(
|
|
244
|
+
this.rpcQueue,
|
|
245
|
+
this.rpc,
|
|
246
|
+
async source => {
|
|
247
|
+
for await (const buf of source) {
|
|
248
|
+
window.postMessage({
|
|
249
|
+
source: SOURCE_METRICS,
|
|
250
|
+
type: 'libp2p-rpc',
|
|
251
|
+
message: base64.encode(buf)
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
})
|
|
257
|
+
.catch(err => {
|
|
258
|
+
this.log.error('error while reading RPC messages', err)
|
|
259
|
+
})
|
|
302
260
|
}
|
|
303
261
|
|
|
304
262
|
async stop (): Promise<void> {
|
|
@@ -311,90 +269,6 @@ class DevToolsMetrics implements Metrics {
|
|
|
311
269
|
await stop(this.simpleMetrics)
|
|
312
270
|
}
|
|
313
271
|
|
|
314
|
-
private onPeersUpdate (): void {
|
|
315
|
-
Promise.resolve().then(async () => {
|
|
316
|
-
const message: PeersMessage = {
|
|
317
|
-
source: SOURCE_METRICS,
|
|
318
|
-
type: 'peers',
|
|
319
|
-
peers: []
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
const connections = this.components.connectionManager.getConnectionsMap()
|
|
323
|
-
const connectedAddresses = [...connections.values()].flatMap(conn => conn).map(conn => conn.remoteAddr.toString())
|
|
324
|
-
|
|
325
|
-
for (const [peerId, conns] of connections.entries()) {
|
|
326
|
-
try {
|
|
327
|
-
const peer = await this.components.peerStore.get(peerId)
|
|
328
|
-
|
|
329
|
-
message.peers.push({
|
|
330
|
-
id: peerId.toString(),
|
|
331
|
-
addresses: peer.addresses.map(({ isCertified, multiaddr }) => {
|
|
332
|
-
const addr = multiaddr.toString()
|
|
333
|
-
|
|
334
|
-
return {
|
|
335
|
-
multiaddr: addr,
|
|
336
|
-
isCertified,
|
|
337
|
-
isConnected: connectedAddresses.includes(addr)
|
|
338
|
-
}
|
|
339
|
-
}),
|
|
340
|
-
protocols: [...peer.protocols],
|
|
341
|
-
tags: toObject(peer.tags, (t) => t.value),
|
|
342
|
-
metadata: toObject(peer.metadata, (buf) => base64.encode(buf))
|
|
343
|
-
})
|
|
344
|
-
} catch (err) {
|
|
345
|
-
this.log.error('could not load peer data from peer store', err)
|
|
346
|
-
|
|
347
|
-
message.peers.push({
|
|
348
|
-
id: peerId.toString(),
|
|
349
|
-
addresses: conns.map(conn => {
|
|
350
|
-
const addr = conn.remoteAddr.toString()
|
|
351
|
-
|
|
352
|
-
return {
|
|
353
|
-
multiaddr: addr,
|
|
354
|
-
isConnected: connectedAddresses.includes(addr)
|
|
355
|
-
}
|
|
356
|
-
}),
|
|
357
|
-
protocols: [],
|
|
358
|
-
tags: {},
|
|
359
|
-
metadata: {}
|
|
360
|
-
})
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
window.postMessage(message, '*')
|
|
365
|
-
})
|
|
366
|
-
.catch(err => {
|
|
367
|
-
this.log.error('error sending peers message', err)
|
|
368
|
-
})
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
private onSelfUpdate (evt: CustomEvent<PeerUpdate>): void {
|
|
372
|
-
this.sendSelfUpdate(evt.detail.peer)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
private sendSelfUpdate (peer: PeerStorePeer): void {
|
|
376
|
-
Promise.resolve()
|
|
377
|
-
.then(async () => {
|
|
378
|
-
const message: SelfMessage = {
|
|
379
|
-
source: SOURCE_METRICS,
|
|
380
|
-
type: 'self',
|
|
381
|
-
peer: {
|
|
382
|
-
id: peer.id.toString(),
|
|
383
|
-
multiaddrs: peer.addresses.map(({ multiaddr }) => multiaddr.toString()),
|
|
384
|
-
protocols: [...peer.protocols],
|
|
385
|
-
tags: toObject(peer.tags, (t) => t.value),
|
|
386
|
-
metadata: toObject(peer.metadata, (buf) => base64.encode(buf))
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
this.log('post node update message')
|
|
391
|
-
window.postMessage(message, '*')
|
|
392
|
-
})
|
|
393
|
-
.catch(err => {
|
|
394
|
-
this.log.error('error sending self update', err)
|
|
395
|
-
})
|
|
396
|
-
}
|
|
397
|
-
|
|
398
272
|
private onIncomingMessage (event: MessageEvent<DevToolsMessage>): void {
|
|
399
273
|
// Only accept messages from same frame
|
|
400
274
|
if (event.source !== window) {
|
|
@@ -408,29 +282,33 @@ class DevToolsMetrics implements Metrics {
|
|
|
408
282
|
return
|
|
409
283
|
}
|
|
410
284
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const peer = await this.components.peerStore.get(this.components.peerId)
|
|
285
|
+
if (message.type === 'libp2p-rpc') {
|
|
286
|
+
this.rpcQueue.push(base64.decode(message.message))
|
|
287
|
+
}
|
|
288
|
+
}
|
|
416
289
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
this.log.error('error sending identify response', err)
|
|
290
|
+
private onSelfUpdate (): void {
|
|
291
|
+
Promise.resolve()
|
|
292
|
+
.then(async () => {
|
|
293
|
+
await this.devTools.safeDispatchEvent('self', {
|
|
294
|
+
detail: await getSelf(this.components)
|
|
423
295
|
})
|
|
424
|
-
|
|
296
|
+
})
|
|
297
|
+
.catch(err => {
|
|
298
|
+
this.log.error('error sending peers message', err)
|
|
299
|
+
})
|
|
300
|
+
}
|
|
425
301
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
|
|
302
|
+
private onPeersUpdate (): void {
|
|
303
|
+
Promise.resolve()
|
|
304
|
+
.then(async () => {
|
|
305
|
+
await this.devTools.safeDispatchEvent('peers', {
|
|
306
|
+
detail: await getPeers(this.components, this.log)
|
|
307
|
+
})
|
|
308
|
+
})
|
|
309
|
+
.catch(err => {
|
|
310
|
+
this.log.error('error sending peers message', err)
|
|
311
|
+
})
|
|
434
312
|
}
|
|
435
313
|
}
|
|
436
314
|
|
|
@@ -439,37 +317,3 @@ export function devToolsMetrics (init?: Partial<DevToolsMetricsInit>): (componen
|
|
|
439
317
|
return new DevToolsMetrics(components, init)
|
|
440
318
|
}
|
|
441
319
|
}
|
|
442
|
-
|
|
443
|
-
function toObject <T, R> (map: Map<string, T>, transform: (value: T) => R): Record<string, R> {
|
|
444
|
-
const output: Record<string, any> = {}
|
|
445
|
-
|
|
446
|
-
for (const [key, value] of map.entries()) {
|
|
447
|
-
output[key] = transform(value)
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
return output
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function debounce (callback: () => void, wait: number = 100): () => void {
|
|
454
|
-
let timeout: ReturnType<typeof setTimeout>
|
|
455
|
-
let start: number | undefined
|
|
456
|
-
|
|
457
|
-
return (): void => {
|
|
458
|
-
if (start == null) {
|
|
459
|
-
start = Date.now()
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (timeout != null && Date.now() - start > wait) {
|
|
463
|
-
clearTimeout(timeout)
|
|
464
|
-
start = undefined
|
|
465
|
-
callback()
|
|
466
|
-
return
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
clearTimeout(timeout)
|
|
470
|
-
timeout = setTimeout(() => {
|
|
471
|
-
start = undefined
|
|
472
|
-
callback()
|
|
473
|
-
}, wait)
|
|
474
|
-
}
|
|
475
|
-
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid'
|
|
2
|
+
import type { ValueCodec } from 'it-rpc'
|
|
3
|
+
|
|
4
|
+
export const cidCodec: ValueCodec<CID> = {
|
|
5
|
+
type: 4096,
|
|
6
|
+
canEncode: (val) => val.code != null && val.version != null && val.multihash != null && val['/'] != null,
|
|
7
|
+
encode: (val) => val.bytes,
|
|
8
|
+
decode: (buf) => CID.decode(buf)
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { encode, decode } from 'cborg'
|
|
2
|
+
import { CustomProgressEvent } from 'progress-events'
|
|
3
|
+
import type { ValueCodec } from 'it-rpc'
|
|
4
|
+
|
|
5
|
+
export const customProgressEventCodec: ValueCodec<CustomProgressEvent> = {
|
|
6
|
+
type: 4099,
|
|
7
|
+
canEncode: (val) => val instanceof CustomProgressEvent,
|
|
8
|
+
encode: (val, codec, context, invocation) => encode({
|
|
9
|
+
type: val.type,
|
|
10
|
+
detail: codec.toValue(val.detail, context, invocation)
|
|
11
|
+
}),
|
|
12
|
+
decode: (val, codec, pushable, invocation) => {
|
|
13
|
+
const { type, detail } = decode(val)
|
|
14
|
+
|
|
15
|
+
return new CustomProgressEvent(type, codec.fromValue(detail, pushable, invocation))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { isMultiaddr, multiaddr } from '@multiformats/multiaddr'
|
|
2
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
3
|
+
import type { ValueCodec } from 'it-rpc'
|
|
4
|
+
|
|
5
|
+
export const multiaddrCodec: ValueCodec<Multiaddr> = {
|
|
6
|
+
type: 4097,
|
|
7
|
+
canEncode: (val) => isMultiaddr(val),
|
|
8
|
+
encode: (val) => val.bytes,
|
|
9
|
+
decode: (buf) => multiaddr(buf)
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isPeerId } from '@libp2p/interface'
|
|
2
|
+
import { peerIdFromBytes } from '@libp2p/peer-id'
|
|
3
|
+
import type { PeerId } from '@libp2p/interface'
|
|
4
|
+
import type { ValueCodec } from 'it-rpc'
|
|
5
|
+
|
|
6
|
+
export const peerIdCodec: ValueCodec<PeerId> = {
|
|
7
|
+
type: 4098,
|
|
8
|
+
canEncode: (val) => isPeerId(val),
|
|
9
|
+
encode: (val) => val.toBytes(),
|
|
10
|
+
decode: (buf) => peerIdFromBytes(buf)
|
|
11
|
+
}
|
package/src/rpc/index.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { cidCodec } from './codecs/cid.js'
|
|
2
|
+
import { customProgressEventCodec } from './codecs/custom-progress-event.js'
|
|
3
|
+
import { multiaddrCodec } from './codecs/multiaddr.js'
|
|
4
|
+
import { peerIdCodec } from './codecs/peer-id.js'
|
|
5
|
+
import type { ContentRouting, PeerId, PeerRouting, AbortOptions } from '@libp2p/interface'
|
|
6
|
+
import type { OpenConnectionOptions } from '@libp2p/interface-internal'
|
|
7
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
8
|
+
import type { ValueCodec } from 'it-rpc'
|
|
9
|
+
|
|
10
|
+
export const valueCodecs: Array<ValueCodec<any>> = [
|
|
11
|
+
cidCodec,
|
|
12
|
+
multiaddrCodec,
|
|
13
|
+
peerIdCodec,
|
|
14
|
+
customProgressEventCodec
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
export interface NodeAddress {
|
|
18
|
+
multiaddr: Multiaddr
|
|
19
|
+
listen?: boolean
|
|
20
|
+
announce?: boolean
|
|
21
|
+
observed?: boolean
|
|
22
|
+
default?: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface NodeStatus {
|
|
26
|
+
peerId: PeerId
|
|
27
|
+
agent?: string
|
|
28
|
+
addresses: NodeAddress[]
|
|
29
|
+
protocols: string[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PeerAddress {
|
|
33
|
+
multiaddr: Multiaddr
|
|
34
|
+
isConnected?: boolean
|
|
35
|
+
isCertified?: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Peer {
|
|
39
|
+
/**
|
|
40
|
+
* The identifier of the remote peer
|
|
41
|
+
*/
|
|
42
|
+
id: PeerId
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The list of addresses the peer has that we know about
|
|
46
|
+
*/
|
|
47
|
+
addresses: PeerAddress[]
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Any peer store tags the peer has
|
|
51
|
+
*/
|
|
52
|
+
tags: Record<string, number>
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Any peer store metadata the peer has
|
|
56
|
+
*/
|
|
57
|
+
metadata: Record<string, string>
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The protocols the peer supports, if known
|
|
61
|
+
*/
|
|
62
|
+
protocols: string[]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* RPC operations exposed by the metrics
|
|
67
|
+
*/
|
|
68
|
+
export interface MetricsRPC {
|
|
69
|
+
/**
|
|
70
|
+
* Called by DevTools on initial connect
|
|
71
|
+
*/
|
|
72
|
+
init(options?: AbortOptions): Promise<{ self: Peer, peers: Peer[], debug: string }>
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Update the currently active debugging namespaces
|
|
76
|
+
*/
|
|
77
|
+
setDebug(namespace?: string): Promise<void>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Open a connection to the passed peer or multiaddr
|
|
81
|
+
*/
|
|
82
|
+
openConnection(peerIdOrMultiaddr: string, options?: OpenConnectionOptions): Promise<void>
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Close connections open to the specified peer
|
|
86
|
+
*/
|
|
87
|
+
closeConnection(peerId: PeerId, options?: AbortOptions): Promise<void>
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Make content routing queries
|
|
91
|
+
*/
|
|
92
|
+
contentRouting: ContentRouting
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Make peer routing queries
|
|
96
|
+
*/
|
|
97
|
+
peerRouting: PeerRouting
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface DevToolsEvents {
|
|
101
|
+
/**
|
|
102
|
+
* Node metrics have been updated
|
|
103
|
+
*/
|
|
104
|
+
'metrics': CustomEvent<Record<string, any>>
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The node's status has changed - new addresses and/or protocols, etc
|
|
108
|
+
*/
|
|
109
|
+
'self': CustomEvent<Peer>
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The node's connected peers have changed
|
|
113
|
+
*/
|
|
114
|
+
'peers': CustomEvent<Peer[]>
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* RPC operations exposed by the DevTools
|
|
119
|
+
*/
|
|
120
|
+
export interface DevToolsRPC {
|
|
121
|
+
safeDispatchEvent<Detail>(type: keyof DevToolsEvents, detail?: CustomEventInit<Detail>): Promise<void>
|
|
122
|
+
}
|