@prosopo/load-balancer 2.10.15 → 2.10.17

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/load-balancer@2.10.15 build:cjs
2
+ > @prosopo/load-balancer@2.10.17 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -23,14 +23,16 @@ ViteCommonJSConfig: .
23
23
  '@prosopo/util-crypto'
24
24
  ]
25
25
  }
26
- vite v6.4.1 building SSR bundle for production...
26
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
27
+ vite v8.1.5 building ssr environment for production...
27
28
  Bundle build started
28
- transforming...
29
- Build end
30
- ✓ 4 modules transformed.
29
+ 
30
+ ✓ 5 modules transformed.
31
31
  rendering chunks...
32
- dist/cjs/index.cjs 0.91 kB
33
- dist/cjs/retry.cjs 1.07 kB
34
- dist/cjs/balancer.cjs 2.21 kB
35
- dist/cjs/providers.cjs 5.10 kB
36
- ✓ built in 180ms
32
+ computing gzip size...
33
+ dist/cjs/index.cjs 1.00 kB │ gzip: 0.31 kB
34
+ dist/cjs/retry.cjs 1.13 kB │ gzip: 0.56 kB
35
+ dist/cjs/balancer.cjs 1.95 kB │ gzip: 0.95 kB
36
+ dist/cjs/providers.cjs 5.75 kB │ gzip: 2.02 kB
37
+
38
+ ✓ built in 63ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/load-balancer@2.10.15 build:tsc
2
+ > @prosopo/load-balancer@2.10.17 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 10:22:21 PM - Projects in this build:
5
+ 11:09:54 AM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -12,21 +12,21 @@
12
12
  * ../common/tsconfig.json
13
13
  * tsconfig.json
14
14
 
15
- 10:22:21 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
15
+ 11:09:54 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
16
16
 
17
- 10:22:21 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
17
+ 11:09:54 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
18
18
 
19
- 10:22:21 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
19
+ 11:09:54 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
20
20
 
21
- 10:22:21 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
21
+ 11:09:54 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
22
22
 
23
- 10:22:21 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
23
+ 11:09:54 AM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
24
24
 
25
- 10:22:21 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
25
+ 11:09:54 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
26
26
 
27
- 10:22:21 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
27
+ 11:09:54 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/batches.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
28
28
 
29
- 10:22:21 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
29
+ 11:09:54 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
30
30
 
31
- 10:22:21 PM - Building project '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'...
31
+ 11:09:54 AM - Building project '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'...
32
32
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/load-balancer@2.10.15 build
2
+ > @prosopo/load-balancer@2.10.17 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/load-balancer@2.10.15 build:cross-env
6
+ > @prosopo/load-balancer@2.10.17 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -27,14 +27,17 @@ ViteEsmConfig: .
27
27
  '@prosopo/util-crypto'
28
28
  ]
29
29
  }
30
- vite v6.4.1 building SSR bundle for production...
30
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
31
+ vite v8.1.5 building ssr environment for production...
31
32
  Bundle build started
32
- transforming...
33
- Build end
34
- ✓ 4 modules transformed.
33
+ 
34
+ ✓ 5 modules transformed.
35
35
  rendering chunks...
36
- dist/index.js 0.61 kB
37
- dist/retry.js 0.95 kB
38
- dist/balancer.js 1.98 kB
39
- dist/providers.js 4.81 kB
40
- ✓ built in 182ms
36
+ computing gzip size...
37
+ dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
38
+ dist/index.js 0.62 kB │ gzip: 0.23 kB
39
+ dist/retry.js 1.09 kB │ gzip: 0.55 kB
40
+ dist/balancer.js 1.78 kB │ gzip: 0.92 kB
41
+ dist/providers.js 5.51 kB │ gzip: 2.00 kB
42
+
43
+ ✓ built in 86ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @prosopo/load-balancer
2
2
 
3
+ ## 2.10.17
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [787017b]
7
+ - Updated dependencies [787017b]
8
+ - Updated dependencies [787017b]
9
+ - Updated dependencies [6f19cde]
10
+ - @prosopo/types@5.0.0
11
+
12
+ ## 2.10.16
13
+ ### Patch Changes
14
+
15
+ - e14fce6: chore(deps): bump vite to 6.4.3 and mongoose to 8.24.1, and adjust types for the mongoose 8.24 Document/ObjectId changes
16
+ - Updated dependencies [103318c]
17
+ - Updated dependencies [270a8d8]
18
+ - Updated dependencies [e14fce6]
19
+ - @prosopo/types@4.10.0
20
+ - @prosopo/common@3.1.48
21
+
3
22
  ## 2.10.15
4
23
  ### Patch Changes
5
24
 
@@ -0,0 +1,3 @@
1
+ import "node:module";
2
+ //#endregion
3
+ export {};
package/dist/balancer.js CHANGED
@@ -1,58 +1,38 @@
1
1
  import { ProsopoEnvError } from "@prosopo/common";
2
2
  import { z } from "zod";
3
- const HardcodedProviderSchema = z.object({
4
- address: z.string(),
5
- url: z.string(),
6
- datasetId: z.string(),
7
- weight: z.number().optional().default(1).transform((val) => {
8
- const weight = Math.round(val);
9
- return Math.max(1, Math.min(100, weight));
10
- })
3
+ //#region src/balancer.ts
4
+ var HardcodedProviderSchema = z.object({
5
+ address: z.string(),
6
+ url: z.string(),
7
+ datasetId: z.string(),
8
+ weight: z.number().optional().default(1).transform((val) => {
9
+ return Math.max(1, Math.min(100, Math.round(val)));
10
+ })
11
11
  });
12
- const IP_MODE_KEYS = ["ipv4", "ipv6"];
13
- const isProviderRecord = (value) => typeof value === "object" && value !== null;
14
- const convertHostedProvider = (provider, ipMode) => {
15
- const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
16
- const providers = Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => HardcodedProviderSchema.parse(value));
17
- return providers.sort((a, b) => a.url.localeCompare(b.url));
12
+ var IP_MODE_KEYS = ["ipv4", "ipv6"];
13
+ var isProviderRecord = (value) => typeof value === "object" && value !== null;
14
+ var convertHostedProvider = (provider, ipMode) => {
15
+ const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
16
+ return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => HardcodedProviderSchema.parse(value)).sort((a, b) => a.url.localeCompare(b.url));
18
17
  };
19
- const stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
20
- const getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
21
- const getLoadBalancerUrl = (environment) => {
22
- if (environment === "production") {
23
- return "https://provider-list.prosopo.io/";
24
- }
25
- if (environment === "staging") {
26
- return "https://provider-list.prosopo.io/staging.json";
27
- }
28
- throw new ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", {
29
- context: { environment }
30
- });
18
+ var stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
19
+ var getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
20
+ var getLoadBalancerUrl = (environment) => {
21
+ if (environment === "production") return "https://provider-list.prosopo.io/";
22
+ if (environment === "staging") return "https://provider-list.prosopo.io/staging.json";
23
+ throw new ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", { context: { environment } });
31
24
  };
32
- const loadBalancer = async (environment) => {
33
- if (environment === "development") {
34
- return [
35
- {
36
- address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
37
- url: "https://localhost:9229",
38
- datasetId: "0x7984714b92d61fd92fd6a7bc9b56b729481470bcc771c19c382ec679acf02e67",
39
- weight: 1
40
- }
41
- ];
42
- }
43
- const providers = await fetch(
44
- getLoadBalancerUrl(environment),
45
- {
46
- method: "GET",
47
- mode: "cors"
48
- }
49
- ).then((res) => res.json());
50
- return convertHostedProvider(providers);
51
- };
52
- export {
53
- convertHostedProvider,
54
- getLoadBalancerUrl,
55
- getProviderHostname,
56
- loadBalancer,
57
- stripIpModeLabel
25
+ var loadBalancer = async (environment) => {
26
+ if (environment === "development") return [{
27
+ address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
28
+ url: "https://localhost:9229",
29
+ datasetId: "0x7984714b92d61fd92fd6a7bc9b56b729481470bcc771c19c382ec679acf02e67",
30
+ weight: 1
31
+ }];
32
+ return convertHostedProvider(await fetch(getLoadBalancerUrl(environment), {
33
+ method: "GET",
34
+ mode: "cors"
35
+ }).then((res) => res.json()));
58
36
  };
37
+ //#endregion
38
+ export { convertHostedProvider, getLoadBalancerUrl, getProviderHostname, loadBalancer, stripIpModeLabel };
@@ -1,56 +1,40 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const common = require("@prosopo/common");
4
- const zod = require("zod");
5
- const HardcodedProviderSchema = zod.z.object({
6
- address: zod.z.string(),
7
- url: zod.z.string(),
8
- datasetId: zod.z.string(),
9
- weight: zod.z.number().optional().default(1).transform((val) => {
10
- const weight = Math.round(val);
11
- return Math.max(1, Math.min(100, weight));
12
- })
1
+ let _prosopo_common = require("@prosopo/common");
2
+ let zod = require("zod");
3
+ //#region src/balancer.ts
4
+ var HardcodedProviderSchema = zod.z.object({
5
+ address: zod.z.string(),
6
+ url: zod.z.string(),
7
+ datasetId: zod.z.string(),
8
+ weight: zod.z.number().optional().default(1).transform((val) => {
9
+ return Math.max(1, Math.min(100, Math.round(val)));
10
+ })
13
11
  });
14
- const IP_MODE_KEYS = ["ipv4", "ipv6"];
15
- const isProviderRecord = (value) => typeof value === "object" && value !== null;
16
- const convertHostedProvider = (provider, ipMode) => {
17
- const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
18
- const providers = Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => HardcodedProviderSchema.parse(value));
19
- return providers.sort((a, b) => a.url.localeCompare(b.url));
12
+ var IP_MODE_KEYS = ["ipv4", "ipv6"];
13
+ var isProviderRecord = (value) => typeof value === "object" && value !== null;
14
+ var convertHostedProvider = (provider, ipMode) => {
15
+ const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
16
+ return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => HardcodedProviderSchema.parse(value)).sort((a, b) => a.url.localeCompare(b.url));
20
17
  };
21
- const stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
22
- const getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
23
- const getLoadBalancerUrl = (environment) => {
24
- if (environment === "production") {
25
- return "https://provider-list.prosopo.io/";
26
- }
27
- if (environment === "staging") {
28
- return "https://provider-list.prosopo.io/staging.json";
29
- }
30
- throw new common.ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", {
31
- context: { environment }
32
- });
18
+ var stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
19
+ var getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
20
+ var getLoadBalancerUrl = (environment) => {
21
+ if (environment === "production") return "https://provider-list.prosopo.io/";
22
+ if (environment === "staging") return "https://provider-list.prosopo.io/staging.json";
23
+ throw new _prosopo_common.ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", { context: { environment } });
33
24
  };
34
- const loadBalancer = async (environment) => {
35
- if (environment === "development") {
36
- return [
37
- {
38
- address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
39
- url: "https://localhost:9229",
40
- datasetId: "0x7984714b92d61fd92fd6a7bc9b56b729481470bcc771c19c382ec679acf02e67",
41
- weight: 1
42
- }
43
- ];
44
- }
45
- const providers = await fetch(
46
- getLoadBalancerUrl(environment),
47
- {
48
- method: "GET",
49
- mode: "cors"
50
- }
51
- ).then((res) => res.json());
52
- return convertHostedProvider(providers);
25
+ var loadBalancer = async (environment) => {
26
+ if (environment === "development") return [{
27
+ address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
28
+ url: "https://localhost:9229",
29
+ datasetId: "0x7984714b92d61fd92fd6a7bc9b56b729481470bcc771c19c382ec679acf02e67",
30
+ weight: 1
31
+ }];
32
+ return convertHostedProvider(await fetch(getLoadBalancerUrl(environment), {
33
+ method: "GET",
34
+ mode: "cors"
35
+ }).then((res) => res.json()));
53
36
  };
37
+ //#endregion
54
38
  exports.convertHostedProvider = convertHostedProvider;
55
39
  exports.getLoadBalancerUrl = getLoadBalancerUrl;
56
40
  exports.getProviderHostname = getProviderHostname;
@@ -1,16 +1,15 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const providers = require("./providers.cjs");
4
- const balancer = require("./balancer.cjs");
5
- exports._resetHealthzRetryPolicy = providers._resetHealthzRetryPolicy;
6
- exports._resetPinCache = providers._resetPinCache;
7
- exports._resetProviderListCache = providers._resetProviderListCache;
8
- exports._setHealthzRetryPolicy = providers._setHealthzRetryPolicy;
9
- exports.getProviders = providers.getProviders;
10
- exports.getRandomActiveProvider = providers.getRandomActiveProvider;
11
- exports.getRandomProviderFromList = providers.getRandomProviderFromList;
12
- exports.convertHostedProvider = balancer.convertHostedProvider;
13
- exports.getLoadBalancerUrl = balancer.getLoadBalancerUrl;
14
- exports.getProviderHostname = balancer.getProviderHostname;
15
- exports.loadBalancer = balancer.loadBalancer;
16
- exports.stripIpModeLabel = balancer.stripIpModeLabel;
2
+ const require_balancer = require("./balancer.cjs");
3
+ const require_providers = require("./providers.cjs");
4
+ exports._resetHealthzRetryPolicy = require_providers._resetHealthzRetryPolicy;
5
+ exports._resetPinCache = require_providers._resetPinCache;
6
+ exports._resetProviderListCache = require_providers._resetProviderListCache;
7
+ exports._setHealthzRetryPolicy = require_providers._setHealthzRetryPolicy;
8
+ exports.convertHostedProvider = require_balancer.convertHostedProvider;
9
+ exports.getLoadBalancerUrl = require_balancer.getLoadBalancerUrl;
10
+ exports.getProviderHostname = require_balancer.getProviderHostname;
11
+ exports.getProviders = require_providers.getProviders;
12
+ exports.getRandomActiveProvider = require_providers.getRandomActiveProvider;
13
+ exports.getRandomProviderFromList = require_providers.getRandomProviderFromList;
14
+ exports.loadBalancer = require_balancer.loadBalancer;
15
+ exports.stripIpModeLabel = require_balancer.stripIpModeLabel;
@@ -1,137 +1,140 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const balancer = require("./balancer.cjs");
4
- const retry = require("./retry.cjs");
5
- const DNS_ENDPOINT = {
6
- development: "https://localhost:9229",
7
- staging: "https://staging.pronode.prosopo.io",
8
- production: "https://pronode.prosopo.io"
1
+ const require_balancer = require("./balancer.cjs");
2
+ const require_retry = require("./retry.cjs");
3
+ //#region src/providers.ts
4
+ var DNS_ENDPOINT = {
5
+ development: "https://localhost:9229",
6
+ staging: "https://staging.pronode.prosopo.io",
7
+ production: "https://pronode.prosopo.io"
9
8
  };
10
- const withIpModeLabel = (hostname, ipMode) => ipMode ? `${ipMode}.${hostname}` : hostname;
11
- const applyIpModeToUrl = (url, ipMode) => {
12
- if (!ipMode) return url;
13
- try {
14
- const parsed = new URL(url);
15
- parsed.hostname = withIpModeLabel(parsed.hostname, ipMode);
16
- return parsed.toString().replace(/\/$/, "");
17
- } catch {
18
- return url;
19
- }
9
+ var withIpModeLabel = (hostname, ipMode) => ipMode ? `${ipMode}.${hostname}` : hostname;
10
+ var applyIpModeToUrl = (url, ipMode) => {
11
+ if (!ipMode) return url;
12
+ try {
13
+ const parsed = new URL(url);
14
+ parsed.hostname = withIpModeLabel(parsed.hostname, ipMode);
15
+ return parsed.toString().replace(/\/$/, "");
16
+ } catch {
17
+ return url;
18
+ }
20
19
  };
21
- const cacheKey = (env, ipMode) => `${env}|${ipMode ?? "dual"}`;
22
- const pinPromiseCache = /* @__PURE__ */ new Map();
23
- const HEALTHZ_MAX_ATTEMPTS = 3;
24
- const HEALTHZ_RETRY_BASE_DELAY_MS = 250;
25
- const HEALTHZ_RETRY_MAX_DELAY_MS = 2e3;
26
- let healthzMaxAttempts = HEALTHZ_MAX_ATTEMPTS;
27
- let healthzRetryBaseDelayMs = HEALTHZ_RETRY_BASE_DELAY_MS;
28
- let healthzRetryMaxDelayMs = HEALTHZ_RETRY_MAX_DELAY_MS;
29
- const fetchPinnedHost = async (baseUrl) => {
30
- const res = await fetch(`${baseUrl}/healthz`, {
31
- method: "GET",
32
- cache: "no-store",
33
- credentials: "omit"
34
- });
35
- if (!res.ok) {
36
- throw new Error(`healthz responded with ${res.status}`);
37
- }
38
- const body = await res.json();
39
- if (typeof body.host !== "string" || body.host.length === 0) {
40
- throw new Error("healthz response missing host field");
41
- }
42
- return body.host;
20
+ var cacheKey = (env, ipMode) => `${env}|${ipMode ?? "dual"}`;
21
+ var pinPromiseCache = /* @__PURE__ */ new Map();
22
+ var HEALTHZ_MAX_ATTEMPTS = 3;
23
+ var HEALTHZ_RETRY_BASE_DELAY_MS = 250;
24
+ var HEALTHZ_RETRY_MAX_DELAY_MS = 2e3;
25
+ var healthzMaxAttempts = HEALTHZ_MAX_ATTEMPTS;
26
+ var healthzRetryBaseDelayMs = HEALTHZ_RETRY_BASE_DELAY_MS;
27
+ var healthzRetryMaxDelayMs = HEALTHZ_RETRY_MAX_DELAY_MS;
28
+ var fetchPinnedHost = async (baseUrl) => {
29
+ const res = await fetch(`${baseUrl}/healthz`, {
30
+ method: "GET",
31
+ cache: "no-store",
32
+ credentials: "omit"
33
+ });
34
+ if (!res.ok) throw new Error(`healthz responded with ${res.status}`);
35
+ const body = await res.json();
36
+ if (typeof body.host !== "string" || body.host.length === 0) throw new Error("healthz response missing host field");
37
+ return body.host;
43
38
  };
44
- const fetchPinnedHostWithRetry = (baseUrl) => retry.retryWithBackoff(() => fetchPinnedHost(baseUrl), {
45
- maxAttempts: healthzMaxAttempts,
46
- baseDelayMs: healthzRetryBaseDelayMs,
47
- maxDelayMs: healthzRetryMaxDelayMs
39
+ var fetchPinnedHostWithRetry = (baseUrl) => require_retry.retryWithBackoff(() => fetchPinnedHost(baseUrl), {
40
+ maxAttempts: healthzMaxAttempts,
41
+ baseDelayMs: healthzRetryBaseDelayMs,
42
+ maxDelayMs: healthzRetryMaxDelayMs
48
43
  });
49
- const resolveBaseUrl = (env) => DNS_ENDPOINT[env] ?? DNS_ENDPOINT.development;
50
- const resolvePinnedUrl = async (env, ipMode) => {
51
- const base = applyIpModeToUrl(resolveBaseUrl(env), ipMode);
52
- if (env === "development") return base;
53
- const key = cacheKey(env, ipMode);
54
- const cached = pinPromiseCache.get(key);
55
- if (cached) return cached;
56
- const promise = (async () => {
57
- try {
58
- const host = await fetchPinnedHostWithRetry(base);
59
- const parsed = new URL(base);
60
- parsed.hostname = withIpModeLabel(host, ipMode);
61
- return parsed.toString().replace(/\/$/, "");
62
- } catch (err) {
63
- pinPromiseCache.delete(key);
64
- throw err;
65
- }
66
- })();
67
- pinPromiseCache.set(key, promise);
68
- return promise;
44
+ var resolveBaseUrl = (env) => DNS_ENDPOINT[env] ?? DNS_ENDPOINT.development;
45
+ var resolvePinnedUrl = async (env, ipMode) => {
46
+ const base = applyIpModeToUrl(resolveBaseUrl(env), ipMode);
47
+ if (env === "development") return base;
48
+ const key = cacheKey(env, ipMode);
49
+ const cached = pinPromiseCache.get(key);
50
+ if (cached) return cached;
51
+ const promise = (async () => {
52
+ try {
53
+ const host = await fetchPinnedHostWithRetry(base);
54
+ const parsed = new URL(base);
55
+ parsed.hostname = withIpModeLabel(host, ipMode);
56
+ return parsed.toString().replace(/\/$/, "");
57
+ } catch (err) {
58
+ pinPromiseCache.delete(key);
59
+ throw err;
60
+ }
61
+ })();
62
+ pinPromiseCache.set(key, promise);
63
+ return promise;
69
64
  };
70
- const providerListPromiseCache = /* @__PURE__ */ new Map();
71
- const getProviders = async (env) => {
72
- const cached = providerListPromiseCache.get(env);
73
- if (cached) return cached;
74
- const promise = balancer.loadBalancer(env).catch((err) => {
75
- providerListPromiseCache.delete(env);
76
- throw err;
77
- });
78
- providerListPromiseCache.set(env, promise);
79
- return promise;
65
+ var providerListPromiseCache = /* @__PURE__ */ new Map();
66
+ /**
67
+ * Returns the full (cached) list of active providers for an environment.
68
+ * Used to look up a provider by url/address, e.g. to find the provider that
69
+ * issued a token before forwarding a verification request to it.
70
+ */
71
+ var getProviders = async (env) => {
72
+ const cached = providerListPromiseCache.get(env);
73
+ if (cached) return cached;
74
+ const promise = require_balancer.loadBalancer(env).catch((err) => {
75
+ providerListPromiseCache.delete(env);
76
+ throw err;
77
+ });
78
+ providerListPromiseCache.set(env, promise);
79
+ return promise;
80
80
  };
81
- const getRandomActiveProvider = async (env, ipMode) => {
82
- const url = await resolvePinnedUrl(env, ipMode);
83
- return {
84
- providerAccount: "dns-routed",
85
- provider: { url }
86
- };
81
+ var getRandomActiveProvider = async (env, ipMode) => {
82
+ return {
83
+ providerAccount: "dns-routed",
84
+ provider: { url: await resolvePinnedUrl(env, ipMode) }
85
+ };
87
86
  };
88
- const sameProviderUrl = (a, b) => a.replace(/\/$/, "") === b.replace(/\/$/, "");
89
- const pickWeightedProvider = (providers, random) => {
90
- const totalWeight = providers.reduce((sum, p) => sum + p.weight, 0);
91
- let threshold = random() * totalWeight;
92
- let chosen;
93
- for (const provider of providers) {
94
- chosen = provider;
95
- threshold -= provider.weight;
96
- if (threshold < 0) break;
97
- }
98
- return chosen;
87
+ var sameProviderUrl = (a, b) => a.replace(/\/$/, "") === b.replace(/\/$/, "");
88
+ var pickWeightedProvider = (providers, random) => {
89
+ const totalWeight = providers.reduce((sum, p) => sum + p.weight, 0);
90
+ let threshold = random() * totalWeight;
91
+ let chosen;
92
+ for (const provider of providers) {
93
+ chosen = provider;
94
+ threshold -= provider.weight;
95
+ if (threshold < 0) break;
96
+ }
97
+ return chosen;
99
98
  };
100
- const getRandomProviderFromList = async (env, ipMode, excludeUrl, random = Math.random) => {
101
- const providers = await getProviders(env);
102
- if (providers.length === 0) {
103
- return getRandomActiveProvider(env, ipMode);
104
- }
105
- const eligible = excludeUrl && providers.length > 1 ? providers.filter(
106
- (p) => !sameProviderUrl(applyIpModeToUrl(p.url, ipMode), excludeUrl)
107
- ) : providers;
108
- const pool = eligible.length > 0 ? eligible : providers;
109
- const chosen = pickWeightedProvider(pool, random);
110
- if (!chosen) {
111
- return getRandomActiveProvider(env, ipMode);
112
- }
113
- return {
114
- providerAccount: chosen.address,
115
- provider: { url: applyIpModeToUrl(chosen.url, ipMode) }
116
- };
99
+ /**
100
+ * Pick a random provider directly from the provider list, bypassing the
101
+ * DNS-routed endpoint. This is the error-fallback path: once a provider has
102
+ * errored, retrying it re-hits the same (possibly-down) endpoint, and a fleet
103
+ * of widgets doing that in a tight loop can accidentally DDoS the provider — so
104
+ * instead we spread the retry across the fleet by choosing a random provider
105
+ * from the list. `excludeUrl` (the provider that just failed) is dropped from
106
+ * the pool when other providers remain. In development the list holds only the
107
+ * single local provider, so this naturally degrades to retrying that provider.
108
+ * `random` is injectable so tests can make the pick deterministic.
109
+ */
110
+ var getRandomProviderFromList = async (env, ipMode, excludeUrl, random = Math.random) => {
111
+ const providers = await getProviders(env);
112
+ if (providers.length === 0) return getRandomActiveProvider(env, ipMode);
113
+ const eligible = excludeUrl && providers.length > 1 ? providers.filter((p) => !sameProviderUrl(applyIpModeToUrl(p.url, ipMode), excludeUrl)) : providers;
114
+ const chosen = pickWeightedProvider(eligible.length > 0 ? eligible : providers, random);
115
+ if (!chosen) return getRandomActiveProvider(env, ipMode);
116
+ return {
117
+ providerAccount: chosen.address,
118
+ provider: { url: applyIpModeToUrl(chosen.url, ipMode) }
119
+ };
117
120
  };
118
- const _resetPinCache = () => {
119
- pinPromiseCache.clear();
121
+ var _resetPinCache = () => {
122
+ pinPromiseCache.clear();
120
123
  };
121
- const _resetProviderListCache = () => {
122
- providerListPromiseCache.clear();
124
+ var _resetProviderListCache = () => {
125
+ providerListPromiseCache.clear();
123
126
  };
124
- const _setHealthzRetryPolicy = (opts) => {
125
- if (opts.maxAttempts !== void 0) healthzMaxAttempts = opts.maxAttempts;
126
- if (opts.baseDelayMs !== void 0)
127
- healthzRetryBaseDelayMs = opts.baseDelayMs;
128
- if (opts.maxDelayMs !== void 0) healthzRetryMaxDelayMs = opts.maxDelayMs;
127
+ var _setHealthzRetryPolicy = (opts) => {
128
+ if (opts.maxAttempts !== void 0) healthzMaxAttempts = opts.maxAttempts;
129
+ if (opts.baseDelayMs !== void 0) healthzRetryBaseDelayMs = opts.baseDelayMs;
130
+ if (opts.maxDelayMs !== void 0) healthzRetryMaxDelayMs = opts.maxDelayMs;
129
131
  };
130
- const _resetHealthzRetryPolicy = () => {
131
- healthzMaxAttempts = HEALTHZ_MAX_ATTEMPTS;
132
- healthzRetryBaseDelayMs = HEALTHZ_RETRY_BASE_DELAY_MS;
133
- healthzRetryMaxDelayMs = HEALTHZ_RETRY_MAX_DELAY_MS;
132
+ var _resetHealthzRetryPolicy = () => {
133
+ healthzMaxAttempts = HEALTHZ_MAX_ATTEMPTS;
134
+ healthzRetryBaseDelayMs = HEALTHZ_RETRY_BASE_DELAY_MS;
135
+ healthzRetryMaxDelayMs = HEALTHZ_RETRY_MAX_DELAY_MS;
134
136
  };
137
+ //#endregion
135
138
  exports._resetHealthzRetryPolicy = _resetHealthzRetryPolicy;
136
139
  exports._resetPinCache = _resetPinCache;
137
140
  exports._resetProviderListCache = _resetProviderListCache;