@ar.io/wayfinder-core 1.0.1-alpha.1 → 1.0.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.
@@ -0,0 +1,36 @@
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
+ import { GatewaysProvider } from '@ar.io/wayfinder-core';
18
+ import type { Logger } from '../types.js';
19
+ export declare class LocalStorageGatewaysProvider implements GatewaysProvider {
20
+ private readonly storageKey;
21
+ private readonly defaultTtlSeconds;
22
+ private readonly gatewaysProvider;
23
+ private readonly ttlSeconds;
24
+ private readonly logger;
25
+ constructor({ ttlSeconds, gatewaysProvider, logger, }: {
26
+ ttlSeconds?: number;
27
+ gatewaysProvider: GatewaysProvider;
28
+ logger?: Logger;
29
+ });
30
+ getGateways(): Promise<URL[]>;
31
+ private getCachedGateways;
32
+ private isCacheValid;
33
+ private cacheGateways;
34
+ clearCache(): void;
35
+ }
36
+ //# sourceMappingURL=local-storage-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage-cache.d.ts","sourceRoot":"","sources":["../../src/gateways/local-storage-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA+B1C,qBAAa,4BAA6B,YAAW,gBAAgB;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,EACV,UAAmC,EACnC,gBAAgB,EAChB,MAAsB,GACvB,EAAE;QACD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAaK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAmBnC,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,aAAa;IAmBrB,UAAU,IAAI,IAAI;CAWnB"}
@@ -0,0 +1,83 @@
1
+ import { defaultLogger } from '../logger.js';
2
+ import { isBrowser } from '../utils/browser.js';
3
+ export class LocalStorageGatewaysProvider {
4
+ storageKey = 'wayfinder-gateways-cache';
5
+ defaultTtlSeconds = 3600; // 1 hour default
6
+ gatewaysProvider;
7
+ ttlSeconds;
8
+ logger;
9
+ constructor({ ttlSeconds = this.defaultTtlSeconds, gatewaysProvider, logger = defaultLogger, }) {
10
+ if (!isBrowser()) {
11
+ throw new Error('LocalStorageGatewaysProvider is only available in browser environments. Consider using SimpleCacheGatewaysProvider for node.js environments.');
12
+ }
13
+ this.gatewaysProvider = gatewaysProvider;
14
+ this.ttlSeconds = ttlSeconds;
15
+ this.gatewaysProvider = gatewaysProvider;
16
+ this.logger = logger;
17
+ }
18
+ async getGateways() {
19
+ const cached = this.getCachedGateways();
20
+ if (cached && this.isCacheValid(cached)) {
21
+ this.logger?.debug('Using cached gateways', {
22
+ ttlSeconds: this.ttlSeconds,
23
+ timestamp: cached.timestamp,
24
+ expiresAt: cached.expiresAt,
25
+ gateways: cached.gateways.length,
26
+ });
27
+ return cached.gateways.map((gateway) => new URL(gateway));
28
+ }
29
+ const gateways = await this.gatewaysProvider.getGateways();
30
+ this.cacheGateways(gateways);
31
+ return gateways;
32
+ }
33
+ getCachedGateways() {
34
+ try {
35
+ if (typeof window === 'undefined' || !window.localStorage) {
36
+ return undefined;
37
+ }
38
+ const cached = window.localStorage.getItem(this.storageKey);
39
+ if (!cached) {
40
+ return undefined;
41
+ }
42
+ return JSON.parse(cached);
43
+ }
44
+ catch (error) {
45
+ this.logger?.warn('Failed to retrieve cached gateways:', error);
46
+ return undefined;
47
+ }
48
+ }
49
+ isCacheValid(cached) {
50
+ const now = Date.now();
51
+ const expiresAt = cached.timestamp + cached.ttlSeconds * 1000;
52
+ const gatewaysCount = cached.gateways.length;
53
+ return now < expiresAt && gatewaysCount > 0;
54
+ }
55
+ cacheGateways(gateways) {
56
+ try {
57
+ if (typeof window === 'undefined' || !window.localStorage) {
58
+ return;
59
+ }
60
+ const cached = {
61
+ gateways: gateways.map((gateway) => gateway.toString()),
62
+ timestamp: Date.now(),
63
+ expiresAt: Date.now() + this.ttlSeconds * 1000,
64
+ ttlSeconds: this.ttlSeconds,
65
+ };
66
+ window.localStorage.setItem(this.storageKey, JSON.stringify(cached));
67
+ }
68
+ catch (error) {
69
+ this.logger?.warn('Failed to cache gateways:', error);
70
+ }
71
+ }
72
+ clearCache() {
73
+ try {
74
+ if (typeof window === 'undefined' || !window.localStorage) {
75
+ return;
76
+ }
77
+ window.localStorage.removeItem(this.storageKey);
78
+ }
79
+ catch (error) {
80
+ this.logger?.warn('Failed to clear gateway cache:', error);
81
+ }
82
+ }
83
+ }
@@ -1,28 +1,35 @@
1
+ import type { GatewaysProvider, Logger } from '../types.js';
1
2
  /**
2
- * WayFinder
3
- * Copyright (C) 2022-2025 Permanent Data Solutions, Inc.
3
+ * Simple in-memory cache provider for gateways that fetches gateways from a
4
+ * GatewaysProvider and caches them for a given number of seconds. Ideal for
5
+ * node.js environments where you want to cache gateways for a given number of
6
+ * seconds and avoid rate limiting. If you are in a browser environment,
7
+ * consider using LocalStorageGatewaysProvider instead.
8
+ *
9
+ * ```ts
10
+ * import { NetworkGatewaysProvider, SimpleCacheGatewaysProvider } from '@ar.io/wayfinder-core';
4
11
  *
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
12
+ * // Create your network provider (fetches gateways from the network)
13
+ * const networkProvider = new NetworkGatewaysProvider({ ... });
8
14
  *
9
- * http://www.apache.org/licenses/LICENSE-2.0
15
+ * // Wrap with SimpleCacheGatewaysProvider for caching
16
+ * const cachedProvider = new SimpleCacheGatewaysProvider({
17
+ * gatewaysProvider: networkProvider,
18
+ * ttlSeconds: 3600, // cache for 1 hour
19
+ * });
10
20
  *
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.
21
+ * // Use cachedProvider to get gateways
22
+ * const gateways = await cachedProvider.getGateways();
23
+ * ```
16
24
  */
17
- import type { GatewaysProvider, Logger } from '../types.js';
18
25
  export declare class SimpleCacheGatewaysProvider implements GatewaysProvider {
19
26
  private gatewaysProvider;
27
+ private defaultTtlSeconds;
20
28
  private ttlSeconds;
21
- private lastUpdated;
29
+ private expiresAt;
22
30
  private gatewaysCache;
23
31
  private logger;
24
- constructor({ gatewaysProvider, ttlSeconds, // 1 hour
25
- logger, }: {
32
+ constructor({ gatewaysProvider, ttlSeconds, logger, }: {
26
33
  gatewaysProvider: GatewaysProvider;
27
34
  ttlSeconds?: number;
28
35
  logger?: Logger;
@@ -31,5 +38,6 @@ export declare class SimpleCacheGatewaysProvider implements GatewaysProvider {
31
38
  path?: string;
32
39
  subdomain?: string;
33
40
  }): Promise<URL[]>;
41
+ private isCacheValid;
34
42
  }
35
43
  //# sourceMappingURL=simple-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"simple-cache.d.ts","sourceRoot":"","sources":["../../src/gateways/simple-cache.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5D,qBAAa,2BAA4B,YAAW,gBAAgB;IAClE,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,EACV,gBAAgB,EAChB,UAAoB,EAAE,SAAS;IAC/B,MAAsB,GACvB,EAAE;QACD,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAQK,WAAW,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CACxE,GAAG,EAAE,CACN;CAmCF"}
1
+ {"version":3,"file":"simple-cache.d.ts","sourceRoot":"","sources":["../../src/gateways/simple-cache.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,2BAA4B,YAAW,gBAAgB;IAClE,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,EACV,gBAAgB,EAChB,UAAmC,EACnC,MAAsB,GACvB,EAAE;QACD,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAQK,WAAW,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CACxE,GAAG,EAAE,CACN;IAgCD,OAAO,CAAC,YAAY;CAGrB"}
@@ -15,33 +15,54 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  import { defaultLogger } from '../logger.js';
18
+ /**
19
+ * Simple in-memory cache provider for gateways that fetches gateways from a
20
+ * GatewaysProvider and caches them for a given number of seconds. Ideal for
21
+ * node.js environments where you want to cache gateways for a given number of
22
+ * seconds and avoid rate limiting. If you are in a browser environment,
23
+ * consider using LocalStorageGatewaysProvider instead.
24
+ *
25
+ * ```ts
26
+ * import { NetworkGatewaysProvider, SimpleCacheGatewaysProvider } from '@ar.io/wayfinder-core';
27
+ *
28
+ * // Create your network provider (fetches gateways from the network)
29
+ * const networkProvider = new NetworkGatewaysProvider({ ... });
30
+ *
31
+ * // Wrap with SimpleCacheGatewaysProvider for caching
32
+ * const cachedProvider = new SimpleCacheGatewaysProvider({
33
+ * gatewaysProvider: networkProvider,
34
+ * ttlSeconds: 3600, // cache for 1 hour
35
+ * });
36
+ *
37
+ * // Use cachedProvider to get gateways
38
+ * const gateways = await cachedProvider.getGateways();
39
+ * ```
40
+ */
18
41
  export class SimpleCacheGatewaysProvider {
19
42
  gatewaysProvider;
43
+ defaultTtlSeconds = 3600; // 1 hour default
20
44
  ttlSeconds;
21
- lastUpdated;
45
+ expiresAt;
22
46
  gatewaysCache;
23
47
  logger;
24
- constructor({ gatewaysProvider, ttlSeconds = 60 * 60, // 1 hour
25
- logger = defaultLogger, }) {
48
+ constructor({ gatewaysProvider, ttlSeconds = this.defaultTtlSeconds, logger = defaultLogger, }) {
26
49
  this.gatewaysCache = [];
27
50
  this.gatewaysProvider = gatewaysProvider;
28
51
  this.ttlSeconds = ttlSeconds;
29
- this.lastUpdated = 0;
52
+ this.expiresAt = 0;
30
53
  this.logger = logger;
31
54
  }
32
55
  async getGateways(params) {
33
- const now = Date.now();
34
- if (this.gatewaysCache.length === 0 ||
35
- now - this.lastUpdated > this.ttlSeconds * 1000) {
56
+ if (this.isCacheValid()) {
36
57
  try {
37
58
  this.logger.debug('Cache expired, fetching new gateways', {
38
- cacheAge: now - this.lastUpdated,
59
+ expiresAt: this.expiresAt,
39
60
  ttlSeconds: this.ttlSeconds,
40
61
  });
41
62
  // preserve the cache if the fetch fails
42
63
  const allGateways = await this.gatewaysProvider.getGateways(params);
43
64
  this.gatewaysCache = allGateways;
44
- this.lastUpdated = now;
65
+ this.expiresAt = Date.now() + this.ttlSeconds * 1000;
45
66
  this.logger.debug('Updated gateways cache', {
46
67
  gatewayCount: allGateways.length,
47
68
  });
@@ -55,11 +76,14 @@ export class SimpleCacheGatewaysProvider {
55
76
  }
56
77
  else {
57
78
  this.logger.debug('Using cached gateways', {
58
- cacheAge: now - this.lastUpdated,
79
+ expiresAt: this.expiresAt,
59
80
  ttlSeconds: this.ttlSeconds,
60
81
  gatewayCount: this.gatewaysCache.length,
61
82
  });
62
83
  }
63
84
  return this.gatewaysCache;
64
85
  }
86
+ isCacheValid() {
87
+ return Date.now() < this.expiresAt && this.gatewaysCache.length > 0;
88
+ }
65
89
  }
package/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ export * from './routing/simple-cache.js';
24
24
  export * from './gateways/network.js';
25
25
  export * from './gateways/simple-cache.js';
26
26
  export * from './gateways/static.js';
27
+ export * from './gateways/local-storage-cache.js';
27
28
  export * from './verification/data-root-verifier.js';
28
29
  export * from './verification/hash-verifier.js';
29
30
  export * from './verification/signature-verifier.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,cAAc,YAAY,CAAC;AAG3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AAGrC,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AAGrD,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,cAAc,YAAY,CAAC;AAG3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mCAAmC,CAAC;AAGlD,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AAGrD,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ export * from './routing/simple-cache.js';
27
27
  export * from './gateways/network.js';
28
28
  export * from './gateways/simple-cache.js';
29
29
  export * from './gateways/static.js';
30
+ export * from './gateways/local-storage-cache.js';
30
31
  // verification strategies
31
32
  export * from './verification/data-root-verifier.js';
32
33
  export * from './verification/hash-verifier.js';
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.1-alpha.1";
17
+ export declare const WAYFINDER_CORE_VERSION = "v1.0.1-alpha.2";
18
18
  //# sourceMappingURL=version.d.ts.map
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.1-alpha.1';
17
+ export const WAYFINDER_CORE_VERSION = 'v1.0.1-alpha.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/wayfinder-core",
3
- "version": "1.0.1-alpha.1",
3
+ "version": "1.0.1",
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",