@ar.io/wayfinder-core 1.0.0 → 1.0.1-alpha.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 CHANGED
@@ -19,98 +19,76 @@ yarn add @ar.io/wayfinder-core
19
19
  ```javascript
20
20
  import { Wayfinder } from '@ar.io/wayfinder-core';
21
21
 
22
- // create a new Wayfinder instance with default settings
23
- const wayfinder = new Wayfinder();
22
+ // create a new Wayfinder instance that uses the top 10 gateways by operator stake from the ARIO Network
23
+ const wayfinder = new Wayfinder({
24
+ gatewaysProvider: new NetworkGatewaysProvider({
25
+ ario: ARIO.mainnet(),
26
+ sortBy: 'operatorStake',
27
+ sortOrder: 'desc',
28
+ limit: 10,
29
+ }),
30
+ });
24
31
 
25
32
  // use Wayfinder to fetch and verify data using ar:// protocol
26
33
  const response = await wayfinder.request('ar://example-name');
27
34
  ```
28
35
 
29
- ### Custom Configuration
36
+ ## ar:// Protocol
30
37
 
31
- You can customize the wayfinder instance with different gateways, verification strategies, and routing strategies based on your use case.
38
+ Wayfinder supports several ar:// URL formats:
32
39
 
33
- Example:
40
+ ```bash
41
+ ar://TRANSACTION_ID // Direct transaction ID
42
+ ar://NAME // ArNS name (paths supported)
43
+ ar:///info // Gateway endpoint (/info)
44
+ ```
34
45
 
35
- > _Wayfinder client that caches the top 10 gateways by operator stake from the ARIO Network for 1 hour and uses the fastest pinging routing strategy to select the fastest gateway for requests._
46
+ ## Dynamic Wayfinder URLs
47
+
48
+ Wayfinder supports a `resolveUrl` method which generates dynamic redirect URLs to a target gateway based on the provided routing strategy. This function can be used to directly replace any hard-coded gateway URLs, and instead use Wayfinder's routing logic to select a gateway for the request.
49
+
50
+ ### Dynamic routing for ArNS names
51
+
52
+ Given an ArNS name, the redirect URL will be the same as the original URL, but with the gateway selected by Wayfinder's routing strategy.
36
53
 
37
54
  ```javascript
38
- import { Wayfinder, NetworkGatewaysProvider, SimpleCacheGatewaysProvider, FastestPingRoutingStrategy, HashVerificationStrategy } from '@ar.io/wayfinder-core';
39
- import { ARIO } from '@ar.io/sdk';
55
+ const redirectUrl = await wayfinder.resolveUrl({
56
+ arnsName: 'ardrive',
57
+ });
58
+ // results in https://ardrive.<selected-gateway>
59
+ ```
40
60
 
41
- const wayfinder = new Wayfinder({
42
- // cache the top 10 gateways by operator stake from the ARIO Network for 1 hour
43
- gatewaysProvider: new SimpleCacheGatewaysProvider({
44
- ttlSeconds: 60 * 60, // cache the gateways for 1 hour
45
- gatewaysProvider: new NetworkGatewaysProvider({
46
- ario: ARIO.mainnet(),
47
- sortBy: 'operatorStake',
48
- sortOrder: 'desc',
49
- limit: 10,
50
- }),
51
- }),
52
- // routing settings
53
- routingSettings: {
54
- // use the fastest pinging strategy to select the fastest gateway for requests
55
- strategy: new FastestPingRoutingStrategy({
56
- timeoutMs: 1000,
57
- }),
58
- // events
59
- events: {
60
- onRoutingStarted: (event) => {
61
- console.log('Routing started!', event);
62
- },
63
- onRoutingSkipped: (event) => {
64
- console.log('Routing skipped!', event);
65
- },
66
- onRoutingSucceeded: (event) => {
67
- console.log('Routing succeeded!', event);
68
- },
69
- },
70
- },
71
- // verification settings
72
- verificationSettings: {
73
- // enable verification - if false, verification will be skipped for all requests
74
- enabled: true,
75
- // verify the data using the hash of the data against a list of trusted gateways
76
- strategy: new HashVerificationStrategy({
77
- trustedGateways: ['https://permagate.io'],
78
- }),
79
- // strict verification - if true, verification failures will cause requests to fail
80
- strict: true,
81
- // events
82
- events: {
83
- onVerificationProgress: (event) => {
84
- console.log('Verification progress!', event);
85
- },
86
- onVerificationSucceeded: (event) => {
87
- console.log('Verification succeeded!', event);
88
- },
89
- onVerificationFailed: (event) => {
90
- console.log('Verification failed!', event);
91
- },
92
- },
93
- },
94
- // telemetry configuration
95
- telemetrySettings: {
96
- enabled: true, // disabled by default (must be explicitly enabled)
97
- sampleRate: 0.1, // 10% sample rate by default
98
- },
61
+ ### Dynamic routing for txIds
62
+
63
+ Given a txId, the redirect URL will be the same as the original URL, but with the gateway selected by Wayfinder's routing strategy.
64
+
65
+ ```javascript
66
+ const redirectUrl = await wayfinder.resolveUrl({
67
+ txId: 'example-tx-id',
99
68
  });
69
+ // results in https://<selected-gateway>/example-tx-id
100
70
  ```
101
71
 
102
- ### Telemetry
72
+ ### Dynamic routing for legacy arweave.net or arweave.dev URLs
103
73
 
104
- Wayfinder can optionally emit OpenTelemetry spans for every request. **By default, telemetry is disabled**. You can control this behavior with the `telemetrySettings` option.
74
+ Given a legacy arweave.net or arweave.dev URL, the redirect URL will be the same as the original URL, but with the gateway selected by Wayfinder's routing strategy.
105
75
 
106
- ## ar:// Protocol
76
+ ```javascript
77
+ const redirectUrl = await wayfinder.resolveUrl({
78
+ originalUrl: 'https://arweave.net/example-tx-id',
79
+ });
80
+ // results in https://<selected-gateway>/example-tx-id
81
+ ```
107
82
 
108
- Wayfinder supports several ar:// URL formats:
83
+ ### Dynamic routing for ar:// URLs
109
84
 
110
- ```bash
111
- ar://TRANSACTION_ID // Direct transaction ID
112
- ar://NAME // ArNS name (paths supported)
113
- ar:///info // Gateway endpoint (/info)
85
+ Given an ar:// URL, the redirect URL will be the same as the original URL, but with the gateway selected by Wayfinder's routing strategy.
86
+
87
+ ```javascript
88
+ const redirectUrl = await wayfinder.resolveUrl({
89
+ originalUrl: 'ar://example-name/subpath?query=value',
90
+ });
91
+ // results in https://<selected-gateway>/example-name/subpath?query=value
114
92
  ```
115
93
 
116
94
  ## Gateway Providers
@@ -151,6 +129,7 @@ Wayfinder supports multiple routing strategies to select target gateways for you
151
129
  | `StaticRoutingStrategy` | Always uses a single gateway | When you need to use a specific gateway |
152
130
  | `RoundRobinRoutingStrategy` | Selects gateways in round-robin order | Good for load balancing and resilience |
153
131
  | `FastestPingRoutingStrategy` | Selects the fastest gateway based on ping time | Good for performance and latency |
132
+ | `PreferredWithFallbackRoutingStrategy` | Uses a preferred gateway, with a fallback strategy if the preferred gateway is not available | Good for performance and resilience. Ideal for builders who run their own gateways. |
154
133
 
155
134
  ### RandomRoutingStrategy
156
135
 
@@ -217,6 +196,21 @@ const gateway = await routingStrategy.selectGateway({
217
196
  });
218
197
  ```
219
198
 
199
+ ### PreferredWithFallbackRoutingStrategy
200
+
201
+ Uses a preferred gateway, with a fallback strategy if the preferred gateway is not available. This is useful for builders who run their own gateways and want to use their own gateway as the preferred gateway, but also want to have a fallback strategy in case their gateway is not available.
202
+
203
+ ```javascript
204
+ import { Wayfinder, PreferredWithFallbackRoutingStrategy } from '@ar.io/wayfinder-core';
205
+
206
+ const routingStrategy = new PreferredWithFallbackRoutingStrategy({
207
+ preferredGateway: 'https://permagate.io',
208
+ fallbackStrategy: new FastestPingRoutingStrategy({
209
+ timeoutMs: 500,
210
+ }),
211
+ });
212
+ ```
213
+
220
214
  ## Verification Strategies
221
215
 
222
216
  Wayfinder includes verification mechanisms to ensure the integrity of retrieved data. Verification strategies offer different trade-offs between complexity, performance, and security.
@@ -382,16 +376,93 @@ const response = await wayfinder.request('ar://example-name', {
382
376
 
383
377
  ## Advanced Usage
384
378
 
385
- ### Custom URL Resolution
379
+ ### Custom Configuration
380
+
381
+ You can customize the wayfinder instance with different gateways, verification strategies, and routing strategies based on your use case.
386
382
 
387
- Returns the resolved URL for a given ar:// URL. This is useful for debugging and for users who want to know the target gateway for a given ar:// URL.
383
+ Example:
384
+
385
+ > _Wayfinder client that caches the top 10 gateways by operator stake from the ARIO Network for 1 hour and uses the fastest pinging routing strategy to select the fastest gateway for requests._
388
386
 
389
387
  ```javascript
390
- // Get the resolved URL without making a request
391
- const redirectUrl = await wayfinder.resolveUrl({
392
- originalUrl: 'ar://example-name',
388
+ import { Wayfinder, NetworkGatewaysProvider, SimpleCacheGatewaysProvider, FastestPingRoutingStrategy, HashVerificationStrategy } from '@ar.io/wayfinder-core';
389
+ import { ARIO } from '@ar.io/sdk';
390
+
391
+ const wayfinder = new Wayfinder({
392
+ // cache the top 10 gateways by operator stake from the ARIO Network for 1 hour
393
+ gatewaysProvider: new SimpleCacheGatewaysProvider({
394
+ ttlSeconds: 60 * 60, // cache the gateways for 1 hour
395
+ gatewaysProvider: new NetworkGatewaysProvider({
396
+ ario: ARIO.mainnet(),
397
+ sortBy: 'operatorStake',
398
+ sortOrder: 'desc',
399
+ limit: 10,
400
+ }),
401
+ }),
402
+ // routing settings
403
+ routingSettings: {
404
+ // use the fastest pinging strategy to select the fastest gateway for requests
405
+ strategy: new FastestPingRoutingStrategy({
406
+ timeoutMs: 1000,
407
+ }),
408
+ // events
409
+ events: {
410
+ onRoutingStarted: (event) => {
411
+ console.log('Routing started!', event);
412
+ },
413
+ onRoutingSkipped: (event) => {
414
+ console.log('Routing skipped!', event);
415
+ },
416
+ onRoutingSucceeded: (event) => {
417
+ console.log('Routing succeeded!', event);
418
+ },
419
+ },
420
+ },
421
+ // verification settings
422
+ verificationSettings: {
423
+ // enable verification - if false, verification will be skipped for all requests
424
+ enabled: true,
425
+ // verify the data using the hash of the data against a list of trusted gateways
426
+ strategy: new HashVerificationStrategy({
427
+ trustedGateways: ['https://permagate.io'],
428
+ }),
429
+ // strict verification - if true, verification failures will cause requests to fail
430
+ strict: true,
431
+ // events
432
+ events: {
433
+ onVerificationProgress: (event) => {
434
+ console.log('Verification progress!', event);
435
+ },
436
+ onVerificationSucceeded: (event) => {
437
+ console.log('Verification succeeded!', event);
438
+ },
439
+ onVerificationFailed: (event) => {
440
+ console.log('Verification failed!', event);
441
+ },
442
+ },
443
+ },
444
+ });
445
+ ```
446
+
447
+ ### Telemetry
448
+
449
+ Wayfinder can optionally emit OpenTelemetry spans for every request. **By default, telemetry is disabled**. You can control this behavior with the `telemetrySettings` option.
450
+
451
+ ```javascript
452
+
453
+ const wayfinder = new Wayfinder({
454
+ gatewaysProvider: new NetworkGatewaysProvider({
455
+ ario: ARIO.mainnet(),
456
+ sortBy: 'operatorStake',
457
+ sortOrder: 'desc',
458
+ limit: 10,
459
+ }),
460
+ telemetrySettings: {
461
+ enabled: true, // disabled by default (must be explicitly enabled)
462
+ sampleRate: 0.1, // 10% sample rate by default
463
+ exporterUrl: 'https://your-custom-otel-exporter', // optional, defaults to https://api.honeycomb.io/v1/traces
464
+ },
393
465
  });
394
- console.log(`This request would be routed to: ${redirectUrl}`);
395
466
  ```
396
467
 
397
468
  ## Request Flow
@@ -14,11 +14,11 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- import { Span, type Tracer } from '@opentelemetry/api';
17
+ import { Span, type Tracer, TracerProvider } from '@opentelemetry/api';
18
18
  import 'zone.js';
19
19
  import { WayfinderEmitter } from './emitter.js';
20
20
  import type { GatewaysProvider, TelemetrySettings, WayfinderOptions } from './types.js';
21
- export declare const initTelemetry: ({ enabled, sampleRate, exporterUrl, apiKey, }: TelemetrySettings) => Tracer | undefined;
21
+ export declare const initTelemetry: ({ enabled, sampleRate, exporterUrl, apiKey, }: TelemetrySettings) => TracerProvider | undefined;
22
22
  export declare const startRequestSpans: ({ originalUrl, emitter, tracer, verificationSettings, routingSettings, gatewaysProvider, }?: {
23
23
  originalUrl?: string;
24
24
  emitter?: WayfinderEmitter;
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAGL,IAAI,EACJ,KAAK,MAAM,EAIZ,MAAM,oBAAoB,CAAC;AAc5B,OAAO,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,aAAa,GAAI,+CAK3B,iBAAiB,KAAG,MAAM,GAAG,SA2C/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,6FAO/B;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;IAChE,eAAe,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IACtD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CAChC;;;;CA+EL,CAAC"}
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAGL,IAAI,EACJ,KAAK,MAAM,EACX,cAAc,EAIf,MAAM,oBAAoB,CAAC;AAc5B,OAAO,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,eAAO,MAAM,aAAa,GAAI,+CAK3B,iBAAiB,KAAG,cAAc,GAAG,SA4CvC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,6FAO/B;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;IAChE,eAAe,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IACtD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CAChC;;;;CA+EL,CAAC"}
package/dist/telemetry.js CHANGED
@@ -23,12 +23,19 @@ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
23
23
  import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
24
24
  import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions';
25
25
  import 'zone.js';
26
+ import { isBrowser, isChromeExtension } from './utils/browser.js';
26
27
  import { WAYFINDER_CORE_VERSION } from './version.js';
28
+ // avoid re-initializing the tracer provider and tracer
29
+ let tracerProvider;
27
30
  export const initTelemetry = ({ enabled = false, sampleRate = 0.1, // 10% sample rate by default
28
31
  exporterUrl = 'https://api.honeycomb.io/v1/traces', apiKey = 'c8gU8dHlu6V7e5k2Gn9LaG', // intentionally left here - if it gets abused we'll disable it
29
32
  }) => {
30
33
  if (enabled === false)
31
34
  return undefined;
35
+ // if the tracer provider and tracer are already initialized, return the tracer
36
+ if (tracerProvider) {
37
+ return tracerProvider;
38
+ }
32
39
  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR);
33
40
  const exporter = new OTLPTraceExporter({
34
41
  url: exporterUrl,
@@ -37,14 +44,14 @@ exporterUrl = 'https://api.honeycomb.io/v1/traces', apiKey = 'c8gU8dHlu6V7e5k2Gn
37
44
  'x-honeycomb-dataset': 'wayfinder-core',
38
45
  },
39
46
  });
40
- const isBrowser = typeof window !== 'undefined';
41
- const spanProcessor = new BatchSpanProcessor(exporter);
42
47
  const sampler = new TraceIdRatioBasedSampler(sampleRate);
48
+ const spanProcessor = new BatchSpanProcessor(exporter);
43
49
  const resource = resourceFromAttributes({
44
50
  [ATTR_SERVICE_NAME]: 'wayfinder-core',
45
51
  [ATTR_SERVICE_VERSION]: WAYFINDER_CORE_VERSION,
46
52
  });
47
- const provider = isBrowser
53
+ const useWebTracer = isBrowser() || isChromeExtension();
54
+ const provider = useWebTracer
48
55
  ? new WebTracerProvider({
49
56
  sampler,
50
57
  resource,
@@ -55,17 +62,11 @@ exporterUrl = 'https://api.honeycomb.io/v1/traces', apiKey = 'c8gU8dHlu6V7e5k2Gn
55
62
  resource,
56
63
  spanProcessors: [spanProcessor],
57
64
  });
58
- if (isBrowser) {
59
- // import zone.js for browser
60
- provider.register({
61
- contextManager: new ZoneContextManager(),
62
- });
63
- }
64
- else {
65
- // node environments don't need zone.js
66
- provider.register();
67
- }
68
- return trace.getTracer('wayfinder-core');
65
+ provider.register({
66
+ // zone.js is only used in the browser (node/extensions/service workers don't need it)
67
+ contextManager: isBrowser() ? new ZoneContextManager() : undefined,
68
+ });
69
+ return tracerProvider;
69
70
  };
70
71
  export const startRequestSpans = ({ originalUrl, emitter, tracer, verificationSettings, routingSettings, gatewaysProvider, } = {}) => {
71
72
  const parentSpan = tracer?.startSpan('wayfinder.request', {
@@ -0,0 +1,25 @@
1
+ /**
2
+ * WayFinder
3
+ * Copyright (C) 2022-2025 Permanent Data Solutions, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Returns true if running in a browser environment (window is defined).
19
+ */
20
+ export declare function isBrowser(): boolean;
21
+ /**
22
+ * Returns true if running as a Chrome extension (chrome.runtime and chrome.runtime.id are defined).
23
+ */
24
+ export declare function isChromeExtension(): boolean;
25
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAInC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WayFinder
3
+ * Copyright (C) 2022-2025 Permanent Data Solutions, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Returns true if running in a browser environment (window is defined).
19
+ */
20
+ export function isBrowser() {
21
+ return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
22
+ }
23
+ /**
24
+ * Returns true if running as a Chrome extension (chrome.runtime and chrome.runtime.id are defined).
25
+ */
26
+ export function isChromeExtension() {
27
+ return (typeof chrome !== 'undefined' &&
28
+ typeof chrome.runtime !== 'undefined' &&
29
+ typeof chrome.runtime.id === 'string');
30
+ }
package/dist/version.d.ts CHANGED
@@ -14,5 +14,5 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- export declare const WAYFINDER_CORE_VERSION = "v1.0.0";
17
+ export declare const WAYFINDER_CORE_VERSION = "v1.0.1-alpha.0";
18
18
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,WAAW,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,mBAAmB,CAAC"}
package/dist/version.js CHANGED
@@ -14,4 +14,4 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- export const WAYFINDER_CORE_VERSION = 'v1.0.0';
17
+ export const WAYFINDER_CORE_VERSION = 'v1.0.1-alpha.0';
@@ -14,7 +14,7 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- import { type Tracer } from '@opentelemetry/api';
17
+ import { type Tracer, TracerProvider } from '@opentelemetry/api';
18
18
  import { WayfinderEmitter } from './emitter.js';
19
19
  import type { GatewaysProvider, Logger, TelemetrySettings, VerificationStrategy, WayfinderFetch, WayfinderOptions, WayfinderURL, WayfinderURLParams } from './types.js';
20
20
  export declare const wayfinderRequestHeaders: ({ traceId, }: {
@@ -114,9 +114,9 @@ export declare class Wayfinder {
114
114
  */
115
115
  readonly telemetrySettings: TelemetrySettings;
116
116
  /**
117
- * OpenTelemetry tracer instance
117
+ * OpenTelemetry tracer provider instance
118
118
  */
119
- protected tracer?: Tracer;
119
+ protected tracerProvider?: TracerProvider;
120
120
  /**
121
121
  * A helper function that resolves a provided url to a target gateway.
122
122
  *
@@ -1 +1 @@
1
- {"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"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"}
package/dist/wayfinder.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  import { defaultLogger } from './logger.js';
18
- import { context, trace } from '@opentelemetry/api';
18
+ import { context, trace, } from '@opentelemetry/api';
19
19
  import { WayfinderEmitter } from './emitter.js';
20
20
  import { FastestPingRoutingStrategy } from './routing/ping.js';
21
21
  import { initTelemetry, startRequestSpans } from './telemetry.js';
@@ -250,6 +250,7 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
250
250
  });
251
251
  const maxRetries = 3;
252
252
  const retryDelay = 1000;
253
+ let requestSpan;
253
254
  for (let i = 0; i < maxRetries; i++) {
254
255
  try {
255
256
  // extract routing information from the ar:// URL
@@ -282,7 +283,7 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
282
283
  originalUrl: url,
283
284
  redirectUrl: redirectUrl.toString(),
284
285
  });
285
- const requestSpan = parentSpan
286
+ requestSpan = parentSpan
286
287
  ? tracer?.startSpan('wayfinder.fetch', undefined, trace.setSpan(context.active(), parentSpan))
287
288
  : undefined;
288
289
  // make the request to the target gateway using the redirect url
@@ -382,6 +383,7 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
382
383
  }
383
384
  }
384
385
  catch (error) {
386
+ requestSpan?.end();
385
387
  logger?.debug('Failed to route request', {
386
388
  error: error.message,
387
389
  stack: error.stack,
@@ -393,6 +395,9 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
393
395
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
394
396
  }
395
397
  }
398
+ finally {
399
+ requestSpan?.end();
400
+ }
396
401
  }
397
402
  throw new Error('Failed to route request after max retries', {
398
403
  cause: {
@@ -433,9 +438,9 @@ export class Wayfinder {
433
438
  */
434
439
  telemetrySettings;
435
440
  /**
436
- * OpenTelemetry tracer instance
441
+ * OpenTelemetry tracer provider instance
437
442
  */
438
- tracer;
443
+ tracerProvider;
439
444
  /**
440
445
  * A helper function that resolves a provided url to a target gateway.
441
446
  *
@@ -602,14 +607,14 @@ export class Wayfinder {
602
607
  apiKey: telemetrySettings?.apiKey,
603
608
  exporterUrl: telemetrySettings?.exporterUrl,
604
609
  };
605
- this.tracer = initTelemetry(this.telemetrySettings);
610
+ this.tracerProvider = initTelemetry(this.telemetrySettings);
606
611
  this.request = wayfinderFetch({
607
612
  logger: this.logger,
608
613
  emitter: this.emitter,
609
614
  gatewaysProvider: this.gatewaysProvider,
610
615
  routingSettings: this.routingSettings,
611
616
  verificationSettings: this.verificationSettings,
612
- tracer: this.tracer,
617
+ tracer: this.tracerProvider?.getTracer('wayfinder-core'),
613
618
  });
614
619
  this.resolveUrl = async (params) => {
615
620
  const wayfinderUrl = createWayfinderUrl(params);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/wayfinder-core",
3
- "version": "1.0.0",
3
+ "version": "1.0.1-alpha.0",
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",