Skip to content

Commit 614f30d

Browse files
authored
feat: add Agent Version column to peers table (#2433)
* feat: add Agent Version column to peers table shows which IPFS implementation each peer is running (e.g., kubo/0.35.0) depends on ipfs/js-kubo-rpc-client#342 * fix: increase agent version truncation to 64 chars aligns with kubo's limit from ipfs/kubo#9465 * chore: update kubo-rpc-client to v5.3.0 - includes identify field support from ipfs/js-kubo-rpc-client#342 - add @babel/plugin-proposal-private-property-in-object to fix build warning - update browserslist database * refactor: remove agent version truncation - removes client-side truncation as it will be handled upstream in kubo via ipfs/kubo#9465 - simplifies agentVersion to use undefined instead of empty string when not present * refactor: compact connection column display - use slash notation (ip4/tcp) instead of bullets - shorten quic-v1 to quic - use monospace font like other technical columns
1 parent f3a8179 commit 614f30d

File tree

8 files changed

+83
-45
lines changed

8 files changed

+83
-45
lines changed

.aegir.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export default {
3434
'tachyons',
3535
'uint8arrays',
3636

37+
// babel-preset-react-app uses this without declaring it as a dependency
38+
// see: https://github.com/facebook/create-react-app/issues/13325
39+
'@babel/plugin-proposal-private-property-in-object',
40+
3741
// type-only deps
3842
'ipfs',
3943

package-lock.json

Lines changed: 31 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"it-first": "^1.0.6",
7474
"it-last": "^1.0.5",
7575
"it-map": "^1.0.5",
76-
"kubo-rpc-client": "^5.2.0",
76+
"kubo-rpc-client": "^5.3.0",
7777
"milliseconds": "^1.0.3",
7878
"money-clip": "^3.0.5",
7979
"multiformats": "^13.4.0",
@@ -107,6 +107,7 @@
107107
},
108108
"devDependencies": {
109109
"@babel/core": "^7.18.9",
110+
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
110111
"@babel/preset-react": "^7.18.6",
111112
"@ipld/dag-pb": "^4.0.8",
112113
"@jest/globals": "^29.7.0",

public/locales/en/peers.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"localNetwork": "Local Network",
44
"nearby": "nearby",
55
"protocols": "Open streams",
6+
"agentVersion": "Agent Version",
67
"addConnection": "Add connection",
78
"insertPeerAddress": "Insert the peer address you want to connect to.",
89
"addPermanentPeer": "Add to the permanent peering configuration",

src/bundles/peer-locations.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ function createPeersLocations (opts) {
9090
)).sort()
9191
: []).join(', ')
9292

93+
// Get agent version (truncation will be handled upstream in kubo via https://github.com/ipfs/kubo/pull/9465)
94+
const agentVersion = peer.identify?.AgentVersion
95+
9396
return {
9497
peerId,
9598
location,
@@ -101,7 +104,8 @@ function createPeersLocations (opts) {
101104
direction,
102105
latency,
103106
isPrivate,
104-
isNearby
107+
isNearby,
108+
agentVersion
105109
}
106110
}))
107111
)
@@ -157,7 +161,10 @@ const toLocationString = loc => {
157161
}
158162

159163
const parseConnection = (multiaddr) => {
160-
return multiaddr.protoNames().join(' • ')
164+
const protocols = multiaddr.protoNames()
165+
.map(p => p.startsWith('quic-v') ? 'quic' : p) // shorten quic-v1, quic-v2, etc to just 'quic'
166+
.join('/')
167+
return protocols
161168
}
162169

163170
const parseLatency = (latency) => {

src/bundles/peer-locations.test.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ describe('selectPeerLocationsForSwarm', () => {
189189
expect(result).toEqual([
190190
{
191191
address: '1.test',
192-
connection: '1/test • endOfTest',
192+
agentVersion: undefined,
193+
connection: '1/test/endOfTest',
193194
coordinates: [1.11, 1.01],
194195
direction: undefined,
195196
flagCode: 'ROM',
@@ -202,7 +203,8 @@ describe('selectPeerLocationsForSwarm', () => {
202203
},
203204
{
204205
address: '2.test',
205-
connection: '2/test • endOfTest',
206+
agentVersion: undefined,
207+
connection: '2/test/endOfTest',
206208
coordinates: [2.22, 2.02],
207209
direction: undefined,
208210
flagCode: 'ROM',
@@ -252,8 +254,10 @@ describe('selectPeerLocationsForSwarm', () => {
252254
expect(result).toEqual([
253255
{
254256
address: '1.test',
255-
connection: '1/test • endOfTest',
257+
agentVersion: undefined,
258+
connection: '1/test/endOfTest',
256259
coordinates: [1.11, 1.01],
260+
direction: undefined,
257261
flagCode: 'ROM',
258262
isNearby: false,
259263
isPrivate: true,
@@ -292,7 +296,8 @@ describe('selectPeerLocationsForSwarm', () => {
292296
expect(result).toEqual([
293297
{
294298
address: '1.test',
295-
connection: '1/test • endOfTest',
299+
agentVersion: undefined,
300+
connection: '1/test/endOfTest',
296301
direction: undefined,
297302
coordinates: null,
298303
flagCode: null,

src/bundles/peers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const swarmPeersTTL = ms.seconds(10)
66
const bundle = createAsyncResourceBundle({
77
name: 'peers',
88
actionBaseType: 'PEERS',
9-
getPromise: ({ getIpfs }) => getIpfs().swarm.peers({ verbose: true, timeout: swarmPeersTTL }),
9+
getPromise: ({ getIpfs }) => getIpfs().swarm.peers({ verbose: true, identify: true, timeout: swarmPeersTTL }),
1010
staleAfter: swarmPeersTTL,
1111
persist: false,
1212
checkIfOnline: false

src/peers/PeersTable/PeersTable.js

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ const protocolsCellRenderer = (t) => ({ rowData }) => {
7575
)
7676
}
7777

78+
const agentVersionCellRenderer = (t) => ({ rowData }) => {
79+
const ref = React.createRef()
80+
const { agentVersion } = rowData
81+
if (!agentVersion) return (<span className='dib o-40 no-select'>-</span>)
82+
return (
83+
<CopyToClipboard text={agentVersion} onCopy={() => copyFeedback(ref, t)}>
84+
<span
85+
ref={ref}
86+
className='copyable'
87+
title={agentVersion}>
88+
{ agentVersion }
89+
</span>
90+
</CopyToClipboard>
91+
)
92+
}
93+
7894
const connectionCellRenderer = (t) => ({ rowData }) => {
7995
const ref = React.createRef()
8096
const { address, direction, peerId } = rowData
@@ -140,7 +156,7 @@ export const PeersTable = ({ className, t, peerLocationsForSwarm, selectedPeers
140156
const filteredPeerList = useMemo(() => {
141157
const filterLower = filter.toLowerCase()
142158
if (filterLower === '') return awaitedPeerLocationsForSwarm
143-
return awaitedPeerLocationsForSwarm.filter(({ location, latency, peerId, connection, protocols }) => {
159+
return awaitedPeerLocationsForSwarm.filter(({ location, latency, peerId, connection, protocols, agentVersion }) => {
144160
if (location != null && location.toLowerCase().includes(filterLower)) {
145161
return true
146162
}
@@ -150,13 +166,15 @@ export const PeersTable = ({ className, t, peerLocationsForSwarm, selectedPeers
150166
if (peerId != null && peerId.toString().includes(filter)) {
151167
return true
152168
}
153-
console.log('connection: ', connection)
154169
if (connection != null && connection.toLowerCase().includes(filterLower)) {
155170
return true
156171
}
157172
if (protocols != null && protocols.toLowerCase().includes(filterLower)) {
158173
return true
159174
}
175+
if (agentVersion != null && agentVersion.toLowerCase().includes(filterLower)) {
176+
return true
177+
}
160178

161179
return false
162180
})
@@ -186,11 +204,12 @@ export const PeersTable = ({ className, t, peerLocationsForSwarm, selectedPeers
186204
sort={sort}
187205
sortBy={sortBy}
188206
sortDirection={sortDirection}>
189-
<Column label={t('app:terms.location')} cellRenderer={locationCellRenderer(t)} dataKey='location' width={450} className='f6 charcoal truncate pl2' />
190-
<Column label={t('app:terms.latency')} cellRenderer={latencyCellRenderer} dataKey='latency' width={200} className='f6 charcoal pl2' />
191-
<Column label={t('app:terms.peerId')} cellRenderer={peerIdCellRenderer(t)} dataKey='peerId' width={250} className='charcoal monospace truncate f6 pl2' />
192-
<Column label={t('app:terms.connection')} cellRenderer={connectionCellRenderer(t)} dataKey='connection' width={250} className='f6 charcoal truncate pl2' />
193-
<Column label={t('protocols')} cellRenderer={protocolsCellRenderer(t)} dataKey='protocols' width={520} className='charcoal monospace truncate f7 pl2' />
207+
<Column label={t('app:terms.location')} cellRenderer={locationCellRenderer(t)} dataKey='location' width={350} className='f6 charcoal truncate pl2' />
208+
<Column label={t('app:terms.latency')} cellRenderer={latencyCellRenderer} dataKey='latency' width={100} className='f6 charcoal pl2' />
209+
<Column label={t('app:terms.peerId')} cellRenderer={peerIdCellRenderer(t)} dataKey='peerId' width={200} className='charcoal monospace truncate f6 pl2' />
210+
<Column label={t('app:terms.connection')} cellRenderer={connectionCellRenderer(t)} dataKey='connection' width={200} className='charcoal monospace truncate f7 pl2' />
211+
<Column label={t('agentVersion')} cellRenderer={agentVersionCellRenderer(t)} dataKey='agentVersion' width={250} className='charcoal monospace truncate f7 pl2' />
212+
<Column label={t('protocols')} cellRenderer={protocolsCellRenderer(t)} dataKey='protocols' width={420} className='charcoal monospace truncate f7 pl2' />
194213
</Table>
195214
</>
196215
)}

0 commit comments

Comments
 (0)