@ar.io/wayfinder-core 0.0.5-alpha.2 → 0.0.5-alpha.4
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 +58 -2
- package/dist/classifiers/gql-classifier.d.ts +1 -2
- package/dist/classifiers/gql-classifier.d.ts.map +1 -1
- package/dist/classifiers/gql-classifier.js +16 -0
- package/dist/gateways/network.d.ts +2 -3
- package/dist/gateways/network.d.ts.map +1 -1
- package/dist/gateways/simple-cache.d.ts +1 -19
- package/dist/gateways/simple-cache.d.ts.map +1 -1
- package/dist/gateways/simple-cache.js +10 -11
- package/dist/gateways/static.d.ts +1 -1
- package/dist/gateways/static.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/logger.d.ts +1 -10
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +16 -0
- package/dist/routing/ping.d.ts +1 -2
- package/dist/routing/ping.d.ts.map +1 -1
- package/dist/routing/preferred-with-fallback.d.ts +1 -2
- package/dist/routing/preferred-with-fallback.d.ts.map +1 -1
- package/dist/routing/preferred-with-fallback.js +16 -0
- package/dist/routing/random.d.ts +1 -1
- package/dist/routing/random.d.ts.map +1 -1
- package/dist/routing/round-robin.d.ts +1 -19
- package/dist/routing/round-robin.d.ts.map +1 -1
- package/dist/routing/round-robin.js +10 -11
- package/dist/routing/simple-cache.d.ts +37 -0
- package/dist/routing/simple-cache.d.ts.map +1 -0
- package/dist/routing/simple-cache.js +72 -0
- package/dist/routing/static.d.ts +1 -19
- package/dist/routing/static.d.ts.map +1 -1
- package/dist/routing/static.js +10 -11
- package/dist/telemetry.d.ts +33 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +115 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/utils/hash.d.ts +1 -2
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/verification/data-root-verifier.d.ts +2 -3
- package/dist/verification/data-root-verifier.d.ts.map +1 -1
- package/dist/verification/hash-verifier.d.ts +2 -3
- package/dist/verification/hash-verifier.d.ts.map +1 -1
- package/dist/verification/signature-verifier.d.ts +4 -4
- package/dist/verification/signature-verifier.d.ts.map +1 -1
- package/dist/verification/signature-verifier.js +2 -0
- package/dist/wayfinder.d.ts +29 -113
- package/dist/wayfinder.d.ts.map +1 -1
- package/dist/wayfinder.js +163 -90
- package/package.json +6 -1
package/dist/wayfinder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"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"}
|
package/dist/wayfinder.js
CHANGED
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { EventEmitter } from 'eventemitter3';
|
|
18
18
|
import { defaultLogger } from './logger.js';
|
|
19
|
+
import { context, trace } from '@opentelemetry/api';
|
|
19
20
|
import { FastestPingRoutingStrategy } from './routing/ping.js';
|
|
21
|
+
import { initTelemetry, startRequestSpans } from './telemetry.js';
|
|
20
22
|
import { sandboxFromId } from './utils/base64.js';
|
|
21
23
|
import { HashVerificationStrategy } from './verification/hash-verifier.js';
|
|
22
24
|
// known regexes for wayfinder urls
|
|
@@ -68,7 +70,7 @@ export const resolveWayfinderUrl = ({ originalUrl, selectedGateway, logger, }) =
|
|
|
68
70
|
return new URL(originalUrl);
|
|
69
71
|
};
|
|
70
72
|
export class WayfinderEmitter extends EventEmitter {
|
|
71
|
-
constructor({ verification, routing } = {}) {
|
|
73
|
+
constructor({ verification, routing, parentEmitter, } = {}) {
|
|
72
74
|
super();
|
|
73
75
|
if (verification) {
|
|
74
76
|
if (verification.onVerificationSucceeded) {
|
|
@@ -92,6 +94,29 @@ export class WayfinderEmitter extends EventEmitter {
|
|
|
92
94
|
this.on('routing-succeeded', routing.onRoutingSucceeded);
|
|
93
95
|
}
|
|
94
96
|
}
|
|
97
|
+
if (parentEmitter) {
|
|
98
|
+
this.on('routing-started', (event) => {
|
|
99
|
+
parentEmitter.emit('routing-started', event);
|
|
100
|
+
});
|
|
101
|
+
this.on('routing-skipped', (event) => {
|
|
102
|
+
parentEmitter.emit('routing-skipped', event);
|
|
103
|
+
});
|
|
104
|
+
this.on('routing-succeeded', (event) => {
|
|
105
|
+
parentEmitter.emit('routing-succeeded', event);
|
|
106
|
+
});
|
|
107
|
+
this.on('verification-succeeded', (event) => {
|
|
108
|
+
parentEmitter.emit('verification-succeeded', event);
|
|
109
|
+
});
|
|
110
|
+
this.on('verification-failed', (event) => {
|
|
111
|
+
parentEmitter.emit('verification-failed', event);
|
|
112
|
+
});
|
|
113
|
+
this.on('verification-progress', (event) => {
|
|
114
|
+
parentEmitter.emit('verification-progress', event);
|
|
115
|
+
});
|
|
116
|
+
this.on('verification-skipped', (event) => {
|
|
117
|
+
parentEmitter.emit('verification-skipped', event);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
95
120
|
}
|
|
96
121
|
}
|
|
97
122
|
export function tapAndVerifyReadableStream({ originalStream, contentLength, verifyData, txId, emitter, strict = false, }) {
|
|
@@ -182,19 +207,35 @@ export function tapAndVerifyReadableStream({ originalStream, contentLength, veri
|
|
|
182
207
|
* @param resolveUrl - the function to construct the redirect url for ar:// requests
|
|
183
208
|
* @returns a wrapped fetch function that supports ar:// protocol and always returns Response
|
|
184
209
|
*/
|
|
185
|
-
export const wayfinderFetch = ({
|
|
210
|
+
export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verificationSettings, routingSettings, emitter, tracer, }) => {
|
|
186
211
|
return async (input, init) => {
|
|
212
|
+
const {
|
|
213
|
+
// allows for overriding the verification and routing settings for a single request
|
|
214
|
+
verificationSettings: requestVerificationSettings, routingSettings: requestRoutingSettings, ...restInit } = init ?? {};
|
|
187
215
|
const url = input instanceof URL ? input.toString() : input.toString();
|
|
216
|
+
const requestEmitter = new WayfinderEmitter({
|
|
217
|
+
verification: requestVerificationSettings?.events,
|
|
218
|
+
routing: requestRoutingSettings?.events,
|
|
219
|
+
parentEmitter: emitter,
|
|
220
|
+
});
|
|
221
|
+
const { parentSpan } = startRequestSpans({
|
|
222
|
+
originalUrl: url,
|
|
223
|
+
verificationSettings: requestVerificationSettings ?? verificationSettings,
|
|
224
|
+
routingSettings: requestRoutingSettings ?? routingSettings,
|
|
225
|
+
gatewaysProvider,
|
|
226
|
+
emitter: requestEmitter,
|
|
227
|
+
tracer,
|
|
228
|
+
});
|
|
188
229
|
if (!url.toString().startsWith('ar://')) {
|
|
189
230
|
logger?.debug('URL is not a wayfinder url, skipping routing', {
|
|
190
231
|
input,
|
|
191
232
|
});
|
|
192
|
-
|
|
233
|
+
requestEmitter.emit('routing-skipped', {
|
|
193
234
|
originalUrl: JSON.stringify(input),
|
|
194
235
|
});
|
|
195
236
|
return fetch(input, init);
|
|
196
237
|
}
|
|
197
|
-
|
|
238
|
+
requestEmitter.emit('routing-started', {
|
|
198
239
|
originalUrl: input.toString(),
|
|
199
240
|
});
|
|
200
241
|
const maxRetries = 3;
|
|
@@ -220,7 +261,7 @@ export const wayfinderFetch = ({ emitter = new WayfinderEmitter(), logger = defa
|
|
|
220
261
|
selectedGateway,
|
|
221
262
|
logger,
|
|
222
263
|
});
|
|
223
|
-
|
|
264
|
+
requestEmitter.emit('routing-succeeded', {
|
|
224
265
|
originalUrl: url,
|
|
225
266
|
selectedGateway: selectedGateway.toString(),
|
|
226
267
|
redirectUrl: redirectUrl.toString(),
|
|
@@ -229,70 +270,97 @@ export const wayfinderFetch = ({ emitter = new WayfinderEmitter(), logger = defa
|
|
|
229
270
|
originalUrl: url,
|
|
230
271
|
redirectUrl: redirectUrl.toString(),
|
|
231
272
|
});
|
|
273
|
+
const requestSpan = parentSpan
|
|
274
|
+
? tracer?.startSpan('wayfinder.fetch', undefined, trace.setSpan(context.active(), parentSpan))
|
|
275
|
+
: undefined;
|
|
232
276
|
// make the request to the target gateway using the redirect url
|
|
233
277
|
const response = await fetch(redirectUrl.toString(), {
|
|
234
278
|
// enforce CORS given we're likely going to a different origin, but always allow the client to override
|
|
235
279
|
redirect: 'follow',
|
|
236
280
|
mode: 'cors',
|
|
237
|
-
...
|
|
281
|
+
...restInit,
|
|
282
|
+
});
|
|
283
|
+
// add response attributes to the span
|
|
284
|
+
requestSpan?.setAttribute('response.status', response.status);
|
|
285
|
+
requestSpan?.setAttribute('response.statusText', response.statusText);
|
|
286
|
+
response.headers.forEach((value, key) => {
|
|
287
|
+
requestSpan?.setAttribute(`response.headers.${key}`, value);
|
|
238
288
|
});
|
|
239
289
|
logger?.debug(`Successfully routed request to gateway`, {
|
|
240
290
|
redirectUrl: redirectUrl.toString(),
|
|
241
291
|
originalUrl: url,
|
|
242
292
|
});
|
|
243
293
|
// only verify data if the redirect url is different from the original url
|
|
244
|
-
if (redirectUrl.toString()
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
+
if (redirectUrl.toString() === url) {
|
|
295
|
+
logger?.debug('Redirect URL is the same as the original URL, skipping verification', {
|
|
296
|
+
redirectUrl: redirectUrl.toString(),
|
|
297
|
+
originalUrl: url,
|
|
298
|
+
});
|
|
299
|
+
requestEmitter.emit('verification-skipped', {
|
|
300
|
+
originalUrl: url,
|
|
301
|
+
});
|
|
302
|
+
requestSpan?.end();
|
|
303
|
+
return response;
|
|
304
|
+
}
|
|
305
|
+
// if verification is disabled, return the response
|
|
306
|
+
if (!(verificationSettings.enabled &&
|
|
307
|
+
verificationSettings.strategy?.verifyData)) {
|
|
308
|
+
logger?.debug('Verification is disabled or no verification strategy is provided, skipping verification', {
|
|
309
|
+
redirectUrl: redirectUrl.toString(),
|
|
310
|
+
originalUrl: url,
|
|
311
|
+
});
|
|
312
|
+
requestEmitter.emit('verification-skipped', {
|
|
313
|
+
originalUrl: url,
|
|
314
|
+
});
|
|
315
|
+
requestSpan?.end();
|
|
316
|
+
return response;
|
|
317
|
+
}
|
|
318
|
+
// Verify the response
|
|
319
|
+
// TODO: add more verification and response attributes to the span
|
|
320
|
+
const headers = response.headers;
|
|
321
|
+
// transaction id is either in the response headers or the path of the request as the first parameter
|
|
322
|
+
const txId = headers.get('x-arns-resolved-id') ??
|
|
323
|
+
redirectUrl.pathname.split('/')[1];
|
|
324
|
+
const contentLength = +(headers.get('content-length') ?? 0);
|
|
325
|
+
requestSpan?.setAttribute('txId', txId);
|
|
326
|
+
requestSpan?.setAttribute('contentLength', contentLength);
|
|
327
|
+
requestSpan?.end();
|
|
328
|
+
if (!txIdRegex.test(txId)) {
|
|
329
|
+
// no transaction id found, skip verification
|
|
330
|
+
logger?.debug('No transaction id found, skipping verification', {
|
|
331
|
+
redirectUrl: redirectUrl.toString(),
|
|
332
|
+
originalUrl: url,
|
|
333
|
+
});
|
|
334
|
+
requestEmitter.emit('verification-skipped', {
|
|
335
|
+
originalUrl: url,
|
|
336
|
+
});
|
|
337
|
+
return response;
|
|
338
|
+
}
|
|
339
|
+
// Check if the response has a body
|
|
340
|
+
if (response.body) {
|
|
341
|
+
const newClientStream = tapAndVerifyReadableStream({
|
|
342
|
+
originalStream: response.body,
|
|
343
|
+
contentLength,
|
|
344
|
+
verifyData: verificationSettings.strategy?.verifyData.bind(verificationSettings.strategy),
|
|
345
|
+
txId,
|
|
346
|
+
emitter: requestEmitter,
|
|
347
|
+
strict: verificationSettings.strict,
|
|
348
|
+
});
|
|
349
|
+
return new Response(newClientStream, {
|
|
350
|
+
status: response.status,
|
|
351
|
+
statusText: response.statusText,
|
|
352
|
+
headers: response.headers,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
// No response body to verify, skip verification
|
|
357
|
+
logger?.debug('No response body to verify', {
|
|
358
|
+
redirectUrl: redirectUrl.toString(),
|
|
359
|
+
originalUrl: url,
|
|
360
|
+
txId,
|
|
361
|
+
});
|
|
362
|
+
return response;
|
|
294
363
|
}
|
|
295
|
-
return response;
|
|
296
364
|
}
|
|
297
365
|
catch (error) {
|
|
298
366
|
logger?.debug('Failed to route request', {
|
|
@@ -341,6 +409,14 @@ export class Wayfinder {
|
|
|
341
409
|
* The verification settings to use when verifying data.
|
|
342
410
|
*/
|
|
343
411
|
verificationSettings;
|
|
412
|
+
/**
|
|
413
|
+
* Telemetry configuration used for OpenTelemetry tracing
|
|
414
|
+
*/
|
|
415
|
+
telemetrySettings;
|
|
416
|
+
/**
|
|
417
|
+
* OpenTelemetry tracer instance
|
|
418
|
+
*/
|
|
419
|
+
tracer;
|
|
344
420
|
/**
|
|
345
421
|
* A helper function that resolves the redirect url for ar:// requests to a target gateway.
|
|
346
422
|
*
|
|
@@ -392,7 +468,13 @@ export class Wayfinder {
|
|
|
392
468
|
*/
|
|
393
469
|
logger;
|
|
394
470
|
/**
|
|
395
|
-
* The event emitter for wayfinder that emits routing and verification events.
|
|
471
|
+
* The event emitter for wayfinder that emits routing and verification events for all requests.
|
|
472
|
+
*
|
|
473
|
+
* This is useful for tracking all requests and their statuses, and is updated for each request.
|
|
474
|
+
*
|
|
475
|
+
* If you prefer request-specific events, you can pass in the events to the `request` function.
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
396
478
|
*
|
|
397
479
|
* const wayfinder = new Wayfinder()
|
|
398
480
|
*
|
|
@@ -419,10 +501,8 @@ export class Wayfinder {
|
|
|
419
501
|
* console.log('Verification passed!', event);
|
|
420
502
|
* },
|
|
421
503
|
* onVerificationFailed: (event) => {
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* onVerificationProgress: (event) => {
|
|
425
|
-
* console.log('Verification progress!', event);
|
|
504
|
+
* console.log('Verification failed!', event);
|
|
505
|
+
* },
|
|
426
506
|
* },
|
|
427
507
|
* }
|
|
428
508
|
* routingSettings: {
|
|
@@ -451,13 +531,9 @@ export class Wayfinder {
|
|
|
451
531
|
* @param options - Wayfinder configuration options
|
|
452
532
|
*/
|
|
453
533
|
constructor({ logger = defaultLogger, gatewaysProvider, // forcing it to be required to avoid making ar-io-sdk a dependency
|
|
454
|
-
verificationSettings, routingSettings, }) {
|
|
534
|
+
verificationSettings, routingSettings, telemetrySettings, }) {
|
|
455
535
|
this.logger = logger;
|
|
456
536
|
this.gatewaysProvider = gatewaysProvider;
|
|
457
|
-
this.emitter = new WayfinderEmitter({
|
|
458
|
-
verification: verificationSettings?.events,
|
|
459
|
-
routing: routingSettings?.events,
|
|
460
|
-
});
|
|
461
537
|
// default verification settings
|
|
462
538
|
this.verificationSettings = {
|
|
463
539
|
enabled: verificationSettings?.enabled ??
|
|
@@ -465,46 +541,39 @@ export class Wayfinder {
|
|
|
465
541
|
strategy: new HashVerificationStrategy({
|
|
466
542
|
trustedGateways: [new URL('https://permagate.io')],
|
|
467
543
|
}),
|
|
468
|
-
events: {
|
|
469
|
-
onVerificationFailed: (event) => {
|
|
470
|
-
this.logger.error('Verification failed', event);
|
|
471
|
-
},
|
|
472
|
-
onVerificationSucceeded: (event) => {
|
|
473
|
-
this.logger.info('Verification succeeded', event);
|
|
474
|
-
},
|
|
475
|
-
onVerificationProgress: (event) => {
|
|
476
|
-
this.logger.info('Verification progress', event);
|
|
477
|
-
},
|
|
478
|
-
},
|
|
479
544
|
// overwrite the default settings with the provided ones
|
|
480
545
|
...verificationSettings,
|
|
481
546
|
};
|
|
482
547
|
// default routing settings
|
|
483
548
|
this.routingSettings = {
|
|
549
|
+
events: {},
|
|
484
550
|
strategy: new FastestPingRoutingStrategy({
|
|
485
551
|
timeoutMs: 1000,
|
|
552
|
+
maxConcurrency: 5, // 5 concurrent HEAD requests on the requested path
|
|
486
553
|
logger: defaultLogger,
|
|
487
554
|
}),
|
|
488
|
-
events: {
|
|
489
|
-
onRoutingStarted: (event) => {
|
|
490
|
-
this.logger.debug('Routing started', event);
|
|
491
|
-
},
|
|
492
|
-
onRoutingSkipped: (event) => {
|
|
493
|
-
this.logger.debug('Routing skipped', event);
|
|
494
|
-
},
|
|
495
|
-
onRoutingSucceeded: (event) => {
|
|
496
|
-
this.logger.debug('Routing succeeded', event);
|
|
497
|
-
},
|
|
498
|
-
},
|
|
499
555
|
// overwrite the default settings with the provided ones
|
|
500
556
|
...routingSettings,
|
|
501
557
|
};
|
|
558
|
+
this.emitter = new WayfinderEmitter({
|
|
559
|
+
verification: this.verificationSettings?.events,
|
|
560
|
+
routing: this.routingSettings?.events,
|
|
561
|
+
});
|
|
562
|
+
this.telemetrySettings = {
|
|
563
|
+
enabled: telemetrySettings?.enabled ?? false,
|
|
564
|
+
sampleRate: telemetrySettings?.sampleRate ?? 0.1, // 10% sample rate by default
|
|
565
|
+
apiKey: telemetrySettings?.apiKey ?? 'c8gU8dHlu6V7e5k2Gn9LaG', // intentionally left here - if it gets abused we'll disable it
|
|
566
|
+
exporterUrl: telemetrySettings?.exporterUrl ?? 'https://api.honeycomb.io/v1/traces', // TODO: replace with proxy url and remove api key
|
|
567
|
+
serviceName: telemetrySettings?.serviceName ?? 'wayfinder-core',
|
|
568
|
+
};
|
|
569
|
+
this.tracer = initTelemetry(this.telemetrySettings);
|
|
502
570
|
this.request = wayfinderFetch({
|
|
503
571
|
logger: this.logger,
|
|
504
572
|
emitter: this.emitter,
|
|
505
573
|
gatewaysProvider: this.gatewaysProvider,
|
|
506
574
|
routingSettings: this.routingSettings,
|
|
507
575
|
verificationSettings: this.verificationSettings,
|
|
576
|
+
tracer: this.tracer,
|
|
508
577
|
});
|
|
509
578
|
this.resolveUrl = async ({ originalUrl, logger = this.logger }) => {
|
|
510
579
|
const selectedGateway = await this.routingSettings.strategy.selectGateway({
|
|
@@ -516,6 +585,10 @@ export class Wayfinder {
|
|
|
516
585
|
logger,
|
|
517
586
|
});
|
|
518
587
|
};
|
|
519
|
-
this.logger.debug(
|
|
588
|
+
this.logger.debug('Wayfinder initialized', {
|
|
589
|
+
verificationSettings: this.verificationSettings,
|
|
590
|
+
routingSettings: this.routingSettings,
|
|
591
|
+
telemetrySettings: this.telemetrySettings,
|
|
592
|
+
});
|
|
520
593
|
}
|
|
521
594
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ar.io/wayfinder-core",
|
|
3
|
-
"version": "0.0.5-alpha.
|
|
3
|
+
"version": "0.0.5-alpha.4",
|
|
4
4
|
"description": "WayFinder core library for intelligently routing to optimal AR.IO gateways",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -49,6 +49,11 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@dha-team/arbundles": "^1.0.3",
|
|
52
|
+
"@opentelemetry/api": "^1.9.0",
|
|
53
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.202.0",
|
|
54
|
+
"@opentelemetry/sdk-trace-base": "^2.0.1",
|
|
55
|
+
"@opentelemetry/sdk-trace-node": "^2.0.1",
|
|
56
|
+
"@opentelemetry/sdk-trace-web": "^2.0.1",
|
|
52
57
|
"arweave": "^1.14.0",
|
|
53
58
|
"eventemitter3": "^5.0.1",
|
|
54
59
|
"plimit-lit": "^3.0.1",
|