@helia/verified-fetch 7.0.4 → 7.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.
- package/README.md +71 -0
- package/dist/index.min.js +61 -61
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +82 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +71 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/url-resolver.d.ts.map +1 -1
- package/dist/src/url-resolver.js +4 -3
- package/dist/src/url-resolver.js.map +1 -1
- package/dist/src/utils/abbreviate.d.ts +4 -0
- package/dist/src/utils/abbreviate.d.ts.map +1 -0
- package/dist/src/utils/abbreviate.js +45 -0
- package/dist/src/utils/abbreviate.js.map +1 -0
- package/dist/src/utils/server-timing.js +1 -1
- package/dist/src/utils/server-timing.js.map +1 -1
- package/dist/src/verified-fetch.d.ts.map +1 -1
- package/dist/src/verified-fetch.js +54 -1
- package/dist/src/verified-fetch.js.map +1 -1
- package/package.json +16 -14
- package/src/index.ts +83 -1
- package/src/url-resolver.ts +4 -3
- package/src/utils/abbreviate.ts +57 -0
- package/src/utils/server-timing.ts +1 -1
- package/src/verified-fetch.ts +59 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/verified-fetch",
|
|
3
|
-
"version": "7.0
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"description": "A fetch-like API for obtaining verified & trustless IPFS content on the web",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia-verified-fetch/tree/main/packages/verified-fetch#readme",
|
|
@@ -164,14 +164,14 @@
|
|
|
164
164
|
"release": "aegir release"
|
|
165
165
|
},
|
|
166
166
|
"dependencies": {
|
|
167
|
-
"@helia/block-brokers": "^5.1
|
|
168
|
-
"@helia/car": "^5.
|
|
167
|
+
"@helia/block-brokers": "^5.2.1",
|
|
168
|
+
"@helia/car": "^5.4.0",
|
|
169
169
|
"@helia/delegated-routing-v1-http-api-client": "^6.0.1",
|
|
170
|
-
"@helia/dnslink": "^1.
|
|
171
|
-
"@helia/interface": "^6.
|
|
172
|
-
"@helia/ipns": "^9.
|
|
173
|
-
"@helia/routers": "^5.0
|
|
174
|
-
"@helia/unixfs": "^7.0
|
|
170
|
+
"@helia/dnslink": "^1.2.0",
|
|
171
|
+
"@helia/interface": "^6.2.0",
|
|
172
|
+
"@helia/ipns": "^9.2.0",
|
|
173
|
+
"@helia/routers": "^5.1.0",
|
|
174
|
+
"@helia/unixfs": "^7.2.0",
|
|
175
175
|
"@ipld/dag-cbor": "^9.2.3",
|
|
176
176
|
"@ipld/dag-json": "^10.2.4",
|
|
177
177
|
"@ipld/dag-pb": "^4.1.5",
|
|
@@ -182,8 +182,10 @@
|
|
|
182
182
|
"@libp2p/webrtc": "^6.0.8",
|
|
183
183
|
"@libp2p/websockets": "^10.1.0",
|
|
184
184
|
"@multiformats/dns": "^1.0.6",
|
|
185
|
+
"@multiformats/multiaddr": "^13.0.1",
|
|
186
|
+
"@multiformats/multiaddr-matcher": "^3.0.2",
|
|
185
187
|
"file-type": "^21.1.1",
|
|
186
|
-
"helia": "^6.
|
|
188
|
+
"helia": "^6.1.1",
|
|
187
189
|
"interface-blockstore": "^6.0.1",
|
|
188
190
|
"ipfs-unixfs-exporter": "^15.0.2",
|
|
189
191
|
"ipns": "^10.1.3",
|
|
@@ -202,10 +204,10 @@
|
|
|
202
204
|
"uint8arrays": "^5.1.0"
|
|
203
205
|
},
|
|
204
206
|
"devDependencies": {
|
|
205
|
-
"@helia/dag-cbor": "^5.
|
|
206
|
-
"@helia/dag-json": "^5.
|
|
207
|
-
"@helia/http": "^3.
|
|
208
|
-
"@helia/json": "^5.
|
|
207
|
+
"@helia/dag-cbor": "^5.1.0",
|
|
208
|
+
"@helia/dag-json": "^5.1.0",
|
|
209
|
+
"@helia/http": "^3.1.1",
|
|
210
|
+
"@helia/json": "^5.1.0",
|
|
209
211
|
"@ipld/car": "^5.4.2",
|
|
210
212
|
"@libp2p/crypto": "^5.1.13",
|
|
211
213
|
"@libp2p/logger": "^6.2.0",
|
|
@@ -214,7 +216,7 @@
|
|
|
214
216
|
"aegir": "^47.0.24",
|
|
215
217
|
"blockstore-core": "^6.1.1",
|
|
216
218
|
"browser-readablestream-to-it": "^2.0.9",
|
|
217
|
-
"cborg": "^
|
|
219
|
+
"cborg": "^5.1.0",
|
|
218
220
|
"ipfs-unixfs-importer": "^16.0.1",
|
|
219
221
|
"it-all": "^3.0.8",
|
|
220
222
|
"magic-bytes.js": "^1.12.1",
|
package/src/index.ts
CHANGED
|
@@ -772,6 +772,77 @@
|
|
|
772
772
|
* - Any thrown error immediately stops the pipeline and returns the error response.
|
|
773
773
|
*
|
|
774
774
|
* For a detailed explanation of the pipeline, please refer to the discussion in [Issue #167](https://github.com/ipfs/helia-verified-fetch/issues/167).
|
|
775
|
+
*
|
|
776
|
+
* ### Server-Timing
|
|
777
|
+
*
|
|
778
|
+
* Detailed timing is found in the [Server-Timing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Server-Timing)
|
|
779
|
+
* HTTP header that is returned with every response when a resource is requested
|
|
780
|
+
* with the `withServerTiming` init option set to `true`.
|
|
781
|
+
*
|
|
782
|
+
* To prevent the header value growing too large, PeerIDs/CIDs are truncated to
|
|
783
|
+
* their first 10 characters and common strings are abbreviated.
|
|
784
|
+
*
|
|
785
|
+
* The values you may expect to see are described in the following table. Note
|
|
786
|
+
* that not all of them may be present in a given response.
|
|
787
|
+
*
|
|
788
|
+
* Router, block broker and transport abbreviations used in the `desc` fields
|
|
789
|
+
* follow.
|
|
790
|
+
*
|
|
791
|
+
* | Timing metric | Elaboration | Detail | Example |
|
|
792
|
+
* | ------------------ | --------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
793
|
+
* | d | DNSLink.resolve | Resolving a DNSLink to an IPFS path or IPNS name | `d;dur=0.200` |
|
|
794
|
+
* | i | IPFS.resolve | Resolving a CID + path to a CID | `i;dur=0.200` |
|
|
795
|
+
* | n | IPNS.resolve | Resolving an IPNS name to an IPFS path | `n;dur=0.200` |
|
|
796
|
+
* | p | Provider | A provider was found. The `desc` field contains the routing system that found the provider and the first 10 characters of the PeerId | `p;dur=0.000;desc="h,bagqbeaawn"` |
|
|
797
|
+
* | f | Find Providers | The total duration of the routing systems Find Providers operation. The `desc` field contains the routing system and how many providers were found | `f;dur=2.000;desc="h,4"` |
|
|
798
|
+
* | c | Connect | How long it took to connect to a provider. The `desc` field contains the type of provider, the first 10 characters of their PeerId and the transport used | `b;dur=0.000;desc="t,bagqbeaa7n,bafybeigoc,t"` |
|
|
799
|
+
* | b | Block | How long it took to retrieve a block from the provider once connected. The `desc` field contains the type of provider, the first 10 characters of their PeerId and the first 10 characters of the CID | `b;dur=0.000;desc="t,bagqbeaa7n,bafybeigoc"` |
|
|
800
|
+
*
|
|
801
|
+
* A full header might look like:
|
|
802
|
+
*
|
|
803
|
+
* ```
|
|
804
|
+
* i;dur=0.000,p;dur=0.000;desc="h,bagqbeaawn",p;dur=0.000;desc="h,bagqbeaawn",p;dur=1.000;desc="h,bagqbeaa7n",p;dur=1.000;desc="h,bagqbeaa7n",f;dur=1.000;desc="h,4",f;dur=1.000;desc="h,4",f;dur=144.000;desc="l,0",f;dur=144.000;desc="l,0",c;dur=206.000;desc="t,bagqbeaa7n,h",b;dur=1.000;desc="t,bagqbeaa7n,bafybeigoc"
|
|
805
|
+
* ```
|
|
806
|
+
*
|
|
807
|
+
* Here resolving a CID to a CID+path took less than a millisecond (e.g. a bare
|
|
808
|
+
* CID was requested).
|
|
809
|
+
*
|
|
810
|
+
* Two HTTP Gateway providers were found in the routing (`bagqbeaawn` and
|
|
811
|
+
* `bagqbeaa7n`). They are found twice because two block brokers are configured
|
|
812
|
+
* (bitswap and trustless-gateway) which both make a routing request (results
|
|
813
|
+
* are cached internally so the duration to find them the second time differs).
|
|
814
|
+
*
|
|
815
|
+
* It took 206ms to connect to `bagqbeaa7n` over HTTP, and 1s to retrieve the
|
|
816
|
+
* block for the CID `bafybeigo` from the Trustless Gateway `bagqbeaa7n`.
|
|
817
|
+
*
|
|
818
|
+
* All PeerIDs and CIDs above are truncated to 10 characters.
|
|
819
|
+
*
|
|
820
|
+
* #### Router abbreviations
|
|
821
|
+
*
|
|
822
|
+
* | Router | Elaboration |
|
|
823
|
+
* | ------ | --------------------- |
|
|
824
|
+
* | h | HTTP Gateway |
|
|
825
|
+
* | l | Libp2p (e.g. Kad-DHT) |
|
|
826
|
+
*
|
|
827
|
+
* #### Block broker abbreviations
|
|
828
|
+
*
|
|
829
|
+
* | Block Broker | Elaboration |
|
|
830
|
+
* | ------------ | ----------------- |
|
|
831
|
+
* | t | Trustless Gateway |
|
|
832
|
+
* | b | Bitswap |
|
|
833
|
+
*
|
|
834
|
+
* #### Transport abbreviations
|
|
835
|
+
*
|
|
836
|
+
* | Transport | Elaboration |
|
|
837
|
+
* | --------- | ------------- |
|
|
838
|
+
* | t | TCP |
|
|
839
|
+
* | h | HTTP |
|
|
840
|
+
* | w | WebSockets |
|
|
841
|
+
* | r | WebRTC |
|
|
842
|
+
* | d | WebRTC-Direct |
|
|
843
|
+
* | q | QUIC |
|
|
844
|
+
* | b | WebTransport |
|
|
845
|
+
* | u | Unknown |
|
|
775
846
|
*/
|
|
776
847
|
|
|
777
848
|
import { bitswap, trustlessGateway } from '@helia/block-brokers'
|
|
@@ -903,7 +974,7 @@ export interface PluginContext extends ResolveURLResult, Omit<VerifiedFetchInit,
|
|
|
903
974
|
/**
|
|
904
975
|
* A callback that receives progress events
|
|
905
976
|
*/
|
|
906
|
-
onProgress?(evt:
|
|
977
|
+
onProgress?(evt: VerifiedFetchProgressEvents): void
|
|
907
978
|
|
|
908
979
|
/**
|
|
909
980
|
* Any async operations should be invoked using server timings to allow
|
|
@@ -1218,6 +1289,17 @@ export interface VerifiedFetchInit extends RequestInit, ProgressOptions<Verified
|
|
|
1218
1289
|
*/
|
|
1219
1290
|
supportWebRedirects?: boolean
|
|
1220
1291
|
|
|
1292
|
+
/**
|
|
1293
|
+
* If a HAMT-sharded directory is encountered, paths will be translated
|
|
1294
|
+
* automatically, e.g. a request for `QmHamt/bar.txt` will be translated to
|
|
1295
|
+
* `QmHamt/F0/A1bar.txt` internally, pass `false` here to not perform this
|
|
1296
|
+
* translation which will then treat HAMT shard structures as
|
|
1297
|
+
* regular directories.
|
|
1298
|
+
*
|
|
1299
|
+
* @default true
|
|
1300
|
+
*/
|
|
1301
|
+
translateHAMTPath?: boolean
|
|
1302
|
+
|
|
1221
1303
|
/**
|
|
1222
1304
|
* If true, only operate on the local blockstore, do not perform any network
|
|
1223
1305
|
* operations.
|
package/src/url-resolver.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { CID } from 'multiformats/cid'
|
|
|
6
6
|
import QuickLRU from 'quick-lru'
|
|
7
7
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
8
8
|
import { CODEC_LIBP2P_KEY, SESSION_CACHE_MAX_SIZE, SESSION_CACHE_TTL_MS } from './constants.ts'
|
|
9
|
+
import { abbreviate } from './utils/abbreviate.ts'
|
|
9
10
|
import { applyRedirects } from './utils/apply-redirect.ts'
|
|
10
11
|
import { ServerTiming } from './utils/server-timing.ts'
|
|
11
12
|
import type { ResolveURLOptions, ResolveURLResult, URLResolver as URLResolverInterface } from './index.ts'
|
|
@@ -124,7 +125,7 @@ export class URLResolver implements URLResolverInterface {
|
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
private async resolveDNSLink (url: URL, serverTiming: ServerTiming, options?: ResolveURLOptions): Promise<ResolveURLResult | Response> {
|
|
127
|
-
const results = await serverTiming.time('dnsLink.resolve',
|
|
128
|
+
const results = await serverTiming.time(abbreviate('dnsLink.resolve'), '', this.components.dnsLink.resolve(url.hostname, options))
|
|
128
129
|
const result = results?.[0]
|
|
129
130
|
|
|
130
131
|
if (result == null) {
|
|
@@ -161,7 +162,7 @@ export class URLResolver implements URLResolverInterface {
|
|
|
161
162
|
|
|
162
163
|
private async resolveIPNSName (url: URL, serverTiming: ServerTiming, options?: ResolveURLOptions): Promise<ResolveURLResult | Response> {
|
|
163
164
|
const peerId = peerIdFromString(url.hostname)
|
|
164
|
-
const result = await serverTiming.time('ipns.resolve',
|
|
165
|
+
const result = await serverTiming.time(abbreviate('ipns.resolve'), '', this.components.ipnsResolver.resolve(peerId, options))
|
|
165
166
|
const path = normalizePath(`${result.path ?? ''}/${url.pathname}`)
|
|
166
167
|
|
|
167
168
|
const ipfsUrl = new URL(`ipfs://${result.cid}${path}`)
|
|
@@ -180,7 +181,7 @@ export class URLResolver implements URLResolverInterface {
|
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
private async resolveIPFSPath (url: URL, serverTiming: ServerTiming, options?: ResolveURLOptions): Promise<ResolveURLResult | Response> {
|
|
183
|
-
const walkPathResult = await serverTiming.time('ipfs.resolve', '', this.walkPath(url, options))
|
|
184
|
+
const walkPathResult = await serverTiming.time(abbreviate('ipfs.resolve'), '', this.walkPath(url, options))
|
|
184
185
|
|
|
185
186
|
if (walkPathResult instanceof Response) {
|
|
186
187
|
return walkPathResult
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { HTTP, HTTPS, QUIC, QUIC_V1, TCP, WebRTC, WebRTCDirect, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher'
|
|
2
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
3
|
+
|
|
4
|
+
const ABBREVIATIONS: Record<string, string> = {
|
|
5
|
+
// operations
|
|
6
|
+
'ipfs.resolve': 'i',
|
|
7
|
+
'dnsLink.resolve': 'd',
|
|
8
|
+
'ipns.resolve': 'n',
|
|
9
|
+
'found-provider': 'p',
|
|
10
|
+
'find-providers': 'f',
|
|
11
|
+
connect: 'c',
|
|
12
|
+
block: 'b',
|
|
13
|
+
|
|
14
|
+
// routers
|
|
15
|
+
'http-gateway-router': 'h',
|
|
16
|
+
'libp2p-router': 'l',
|
|
17
|
+
|
|
18
|
+
// block brokers
|
|
19
|
+
'trustless-gateway': 't',
|
|
20
|
+
bitswap: 'b'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function abbreviate (str: string): string {
|
|
24
|
+
return ABBREVIATIONS[str] ?? str
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function abbreviateAddress (ma: Multiaddr): string {
|
|
28
|
+
if (TCP.exactMatch(ma)) {
|
|
29
|
+
return 't'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (HTTP.exactMatch(ma) || HTTPS.exactMatch(ma)) {
|
|
33
|
+
return 'h'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (WebSockets.exactMatch(ma) || WebSocketsSecure.exactMatch(ma)) {
|
|
37
|
+
return 'w'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (WebRTC.exactMatch(ma)) {
|
|
41
|
+
return 'r'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (WebRTCDirect.exactMatch(ma)) {
|
|
45
|
+
return 'd'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (QUIC.exactMatch(ma) || QUIC_V1.exactMatch(ma)) {
|
|
49
|
+
return 'q'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (WebTransport.exactMatch(ma)) {
|
|
53
|
+
return 'b'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return 'u'
|
|
57
|
+
}
|
|
@@ -25,6 +25,6 @@ export class ServerTiming {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
add (name: string, description: string, duration: number | string): void {
|
|
28
|
-
this.headers.push(`${name};dur=${Number(duration).toFixed(this.precision)}
|
|
28
|
+
this.headers.push(`${name};dur=${Number(duration).toFixed(this.precision)}${description === '' ? '' : `;desc="${description}"`}`)
|
|
29
29
|
}
|
|
30
30
|
}
|
package/src/verified-fetch.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { RawPlugin } from './plugins/plugin-handle-raw.ts'
|
|
|
12
12
|
import { TarPlugin } from './plugins/plugin-handle-tar.js'
|
|
13
13
|
import { UnixFSPlugin } from './plugins/plugin-handle-unixfs.js'
|
|
14
14
|
import { URLResolver } from './url-resolver.ts'
|
|
15
|
+
import { abbreviate, abbreviateAddress } from './utils/abbreviate.ts'
|
|
15
16
|
import { contentTypeParser } from './utils/content-type-parser.js'
|
|
16
17
|
import { getContentType, getSupportedContentTypes, CONTENT_TYPE_OCTET_STREAM, MEDIA_TYPE_IPNS_RECORD, CONTENT_TYPE_IPNS } from './utils/content-types.ts'
|
|
17
18
|
import { errorToObject } from './utils/error-to-object.ts'
|
|
@@ -58,6 +59,10 @@ function isIPNSRecordRequest (headers: Headers): boolean {
|
|
|
58
59
|
return mediaType === MEDIA_TYPE_IPNS_RECORD
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
function truncate (obj?: any): string {
|
|
63
|
+
return `${obj}`.substring(0, 10)
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
export class VerifiedFetch {
|
|
62
67
|
private readonly helia: Helia
|
|
63
68
|
private readonly ipnsResolver: IPNSResolver
|
|
@@ -211,6 +216,10 @@ export class VerifiedFetch {
|
|
|
211
216
|
return this.handleFinalResponse(accept)
|
|
212
217
|
}
|
|
213
218
|
|
|
219
|
+
const routingTimers: Record<string, { start: number, found: number }> = {}
|
|
220
|
+
const connectTimers: Record<string, { start: number, transport: string }> = {}
|
|
221
|
+
const blockTimers: Record<string, number> = {}
|
|
222
|
+
|
|
214
223
|
const context: PluginContext = {
|
|
215
224
|
...options,
|
|
216
225
|
...resolveResult,
|
|
@@ -219,7 +228,56 @@ export class VerifiedFetch {
|
|
|
219
228
|
range,
|
|
220
229
|
serverTiming,
|
|
221
230
|
headers,
|
|
222
|
-
requestedMimeTypes
|
|
231
|
+
requestedMimeTypes,
|
|
232
|
+
onProgress: (evt) => {
|
|
233
|
+
options?.onProgress?.(evt)
|
|
234
|
+
|
|
235
|
+
if (evt.type === 'helia:routing:find-providers:start') {
|
|
236
|
+
routingTimers[evt.detail.routing] = {
|
|
237
|
+
start: Date.now(),
|
|
238
|
+
found: 0
|
|
239
|
+
}
|
|
240
|
+
} else if (evt.type === 'helia:routing:find-providers:provider') {
|
|
241
|
+
if (routingTimers[evt.detail.routing] == null) {
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
routingTimers[evt.detail.routing].found++
|
|
246
|
+
|
|
247
|
+
serverTiming.add(abbreviate('found-provider'), `${abbreviate(evt.detail.routing)},${truncate(evt.detail.provider.id)}`, Date.now() - routingTimers[evt.detail.routing].start)
|
|
248
|
+
} else if (evt.type === 'helia:routing:find-providers:end') {
|
|
249
|
+
const routing = routingTimers[evt.detail.routing]
|
|
250
|
+
|
|
251
|
+
if (routing == null) {
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
serverTiming.add(abbreviate('find-providers'), `${abbreviate(evt.detail.routing)},${routing.found}`, Date.now() - routing.start)
|
|
256
|
+
} else if (evt.type === 'helia:block-broker:connect') {
|
|
257
|
+
connectTimers[`connect-${evt.detail.broker}-${evt.detail.provider}`] = {
|
|
258
|
+
start: Date.now(),
|
|
259
|
+
transport: ''
|
|
260
|
+
}
|
|
261
|
+
} else if (evt.type === 'helia:block-broker:connected') {
|
|
262
|
+
const start = connectTimers[`connect-${evt.detail.broker}-${evt.detail.provider}`]
|
|
263
|
+
|
|
264
|
+
if (start == null) {
|
|
265
|
+
return
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
serverTiming.add(abbreviate('connect'), `${abbreviate(evt.detail.broker)},${truncate(evt.detail.provider)},${abbreviateAddress(evt.detail.address)}`, Date.now() - start.start)
|
|
269
|
+
} else if (evt.type === 'helia:block-broker:request-block') {
|
|
270
|
+
blockTimers[`block-${evt.detail.broker}-${evt.detail.cid}-${evt.detail.provider}`] = Date.now()
|
|
271
|
+
} else if (evt.type === 'helia:block-broker:receive-block') {
|
|
272
|
+
const start = blockTimers[`block-${evt.detail.broker}-${evt.detail.cid}-${evt.detail.provider}`]
|
|
273
|
+
|
|
274
|
+
if (start == null) {
|
|
275
|
+
return
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
serverTiming.add(abbreviate('block'), `${abbreviate(evt.detail.broker)},${truncate(evt.detail.provider)},${truncate(evt.detail.cid)}`, Date.now() - start)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
223
281
|
}
|
|
224
282
|
|
|
225
283
|
this.log.trace('finding handler for cid code "0x%s" and response content types %s', resolveResult.terminalElement.cid.code.toString(16), accept.map(header => header.contentType.mediaType).join(', '))
|