@prosopo/load-balancer 2.9.21 → 2.10.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/load-balancer@2.9.21 build:cjs
2
+ > @prosopo/load-balancer@2.10.1 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -29,7 +29,7 @@ transforming...
29
29
  Build end
30
30
  ✓ 3 modules transformed.
31
31
  rendering chunks...
32
- dist/cjs/index.cjs 0.64 kB
33
- dist/cjs/balancer.cjs 1.67 kB
34
- dist/cjs/providers.cjs 2.10 kB
35
- ✓ built in 156ms
32
+ dist/cjs/index.cjs 0.70 kB
33
+ dist/cjs/balancer.cjs 2.21 kB
34
+ dist/cjs/providers.cjs 2.76 kB
35
+ ✓ built in 144ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/load-balancer@2.9.21 build:tsc
2
+ > @prosopo/load-balancer@2.10.1 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 1:01:30 PM - Projects in this build:
5
+ 3:24:41 PM - 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
- 1:01:30 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
+ 3:24:41 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'
16
16
 
17
- 1:01:30 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
17
+ 3:24:41 PM - 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
- 1:01:30 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
19
+ 3:24:41 PM - 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
- 1:01:30 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
21
+ 3:24:41 PM - 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
- 1:01:30 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
+ 3:24:41 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'
24
24
 
25
- 1:01:30 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
25
+ 3:24:41 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
26
26
 
27
- 1:01:30 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/objectUtils.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
27
+ 3:24:41 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
28
28
 
29
- 1:01:30 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
29
+ 3:24:41 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
30
30
 
31
- 1:01:30 PM - Building project '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'...
31
+ 3:24:41 PM - 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.9.21 build
2
+ > @prosopo/load-balancer@2.10.1 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/load-balancer@2.9.21 build:cross-env
6
+ > @prosopo/load-balancer@2.10.1 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -33,7 +33,7 @@ transforming...
33
33
  Build end
34
34
  ✓ 3 modules transformed.
35
35
  rendering chunks...
36
- dist/index.js 0.41 kB
37
- dist/balancer.js 1.50 kB
38
- dist/providers.js 1.88 kB
39
- ✓ built in 122ms
36
+ dist/index.js 0.45 kB
37
+ dist/balancer.js 1.98 kB
38
+ dist/providers.js 2.57 kB
39
+ ✓ built in 153ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # @prosopo/load-balancer
2
2
 
3
+ ## 2.10.1
4
+ ### Patch Changes
5
+
6
+ - 6a7b122: Allow a client to send a captcha verify request to any pronode: a provider that did not issue the token now forwards the verification to the issuing provider (decoded from the token's providerUrl, SSRF-guarded against the known provider list) and returns its response, mirroring the AWS Lambda verify endpoint. Falls back to local verification when this node is the issuer, the provider list can't be loaded, or the issuer can't be determined.
7
+ - Updated dependencies [dfb0c53]
8
+ - Updated dependencies [11f1e8c]
9
+ - Updated dependencies [b166037]
10
+ - Updated dependencies [1111ff2]
11
+ - @prosopo/common@3.1.41
12
+ - @prosopo/types@4.9.0
13
+
14
+ ## 2.10.0
15
+ ### Minor Changes
16
+
17
+ - 12cd0a6: Replace client-side weighted-random provider selection with static DNS endpoints.
18
+
19
+ - Removed the `providerSelectEntropy` field from `DetectorResult`, `Session`, the
20
+ Mongoose `SessionRecordSchema` (including its standalone index), and every
21
+ call-site that threaded it through frictionless / image / pow / puzzle flows.
22
+ - Removed `FrictionlessManager.hostVerified` and its decision-machine call site
23
+ — there's nothing to verify when the DNS layer picks the host.
24
+ - `getRandomActiveProvider(env)` now returns the per-environment static DNS
25
+ endpoint (`pronode.prosopo.io` family) instead of fetching the provider list
26
+ and weighted-selecting. The entropy parameter is gone.
27
+ - `getProcaptchaRandomActiveProvider` is now a thin re-export so widget packages
28
+ keep importing from `procaptcha-common`.
29
+ - `FrontendProvider.datasetId` is dropped; `CaptchaRequestBody.datasetId` is
30
+ optional. The server falls back to its own most-recently-uploaded dataset
31
+ (`env.datasetId`, populated from `db.getMostRecentDatasetId()` at startup) —
32
+ clients can't pin a dataset under DNS routing because they don't know which
33
+ pronode they'll hit.
34
+ - Removed dead `setProviderLoader` / `prefetchProviders` / `selectWeightedProvider`
35
+ plumbing from `@prosopo/load-balancer`. The server's cacheFile-based loader
36
+ setup in `startProviderApi` goes with them.
37
+ - `getRandomActiveProvider` now hits `/healthz` on the global hostname once per
38
+ page load, reads the responding pronode's identity from the JSON body, and
39
+ pins subsequent captcha calls to that pronode (`https://pronodeN.prosopo.io`)
40
+ so session creation and submission land on the same backend. Falls back to
41
+ the dual-stack global hostname when `/healthz` is unreachable.
42
+ - `/healthz` now returns `{ ok: true, host: <pronode-identity> }` instead of
43
+ `"OK"` to support the above pinning.
44
+ - CORS preflight is now cached for 24h (`maxAge: 86400`) — previously the
45
+ browser refired an OPTIONS preflight before every captcha call because
46
+ the custom `Prosopo-Site-Key` / `Prosopo-User` headers make the request
47
+ non-simple and the default `maxAge` is 5s.
48
+ - 12cd0a6: Add ipv4-only / ipv6-only provider DNS routing via `data-ipv4` / `data-ipv6`.
49
+
50
+ Dapps that need to pin captcha traffic to a single IP stack can now do so:
51
+
52
+ ```html
53
+ <div class="procaptcha" data-sitekey="..." data-ipv4="true"></div>
54
+ ```
55
+
56
+ What happens under the hood:
57
+
58
+ - The widget reads `data-ipv4` / `data-ipv6` (or the matching `ipv4` / `ipv6`
59
+ booleans on `ProcaptchaRenderOptions` / explicit `render(...)`) and threads
60
+ them through `ProcaptchaConfigSchema`.
61
+ - `pickIpMode(config)` resolves them into an `IpMode` (`"ipv4"` / `"ipv6"` /
62
+ `undefined`); `ipv4` wins if both are set.
63
+ - The frictionless / image / pow / puzzle managers pass the `IpMode` into
64
+ `getProcaptchaRandomActiveProvider`, which calls `/healthz` on the matching
65
+ single-stack global hostname (`ipv4.pronode.prosopo.io` or
66
+ `ipv6.pronode.prosopo.io`) and pins subsequent captcha calls to
67
+ `ipv4.pronodeN.prosopo.io` / `ipv6.pronodeN.prosopo.io`. The dual-stack
68
+ cache and the single-stack caches are kept separate.
69
+ - `convertHostedProvider` now accepts an optional `IpMode` and, when set,
70
+ selects the matching `ipv4` / `ipv6` sub-object from the provider-list JSON.
71
+ Top-level `ipv4` / `ipv6` keys are skipped by default so existing dual-stack
72
+ callers keep working.
73
+ - New helpers in `@prosopo/load-balancer`: `IpMode`, `stripIpModeLabel`,
74
+ `getProviderHostname`.
75
+
76
+ Coordinated with the matching `captcha-private` change that publishes the
77
+ `ipv4` / `ipv6` sub-objects to S3.
78
+
79
+ ### Patch Changes
80
+
81
+ - Updated dependencies [12cd0a6]
82
+ - Updated dependencies [12cd0a6]
83
+ - @prosopo/types@4.8.0
84
+
3
85
  ## 2.9.21
4
86
  ### Patch Changes
5
87
 
@@ -17,8 +17,11 @@ declare const HardcodedProviderSchema: z.ZodObject<{
17
17
  weight?: number | undefined;
18
18
  }>;
19
19
  export type HardcodedProvider = z.infer<typeof HardcodedProviderSchema>;
20
+ export type IpMode = "ipv4" | "ipv6";
20
21
  type hostedProviders = Record<string, unknown>;
21
- export declare const convertHostedProvider: (provider: hostedProviders) => HardcodedProvider[];
22
+ export declare const convertHostedProvider: (provider: hostedProviders, ipMode?: IpMode) => HardcodedProvider[];
23
+ export declare const stripIpModeLabel: (hostname: string) => string;
24
+ export declare const getProviderHostname: (provider: HardcodedProvider) => string;
22
25
  export declare const getLoadBalancerUrl: (environment: EnvironmentTypes) => string;
23
26
  export declare const loadBalancer: (environment: EnvironmentTypes) => Promise<HardcodedProvider[]>;
24
27
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"balancer.d.ts","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;EAa3B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,eAAO,MAAM,qBAAqB,aACvB,eAAe,KACvB,iBAAiB,EAKnB,CAAC;AAEF,eAAO,MAAM,kBAAkB,gBAAiB,gBAAgB,KAAG,MAUlE,CAAC;AAEF,eAAO,MAAM,YAAY,gBACX,gBAAgB,KAC3B,OAAO,CAAC,iBAAiB,EAAE,CAqB7B,CAAC"}
1
+ {"version":3,"file":"balancer.d.ts","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;EAa3B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAQrC,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAK/C,eAAO,MAAM,qBAAqB,aACvB,eAAe,WAChB,MAAM,KACb,iBAAiB,EAUnB,CAAC;AAKF,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MACjB,CAAC;AAEpC,eAAO,MAAM,mBAAmB,aAAc,iBAAiB,KAAG,MACjB,CAAC;AAElD,eAAO,MAAM,kBAAkB,gBAAiB,gBAAgB,KAAG,MAUlE,CAAC;AAEF,eAAO,MAAM,YAAY,gBACX,gBAAgB,KAC3B,OAAO,CAAC,iBAAiB,EAAE,CAqB7B,CAAC"}
package/dist/balancer.js CHANGED
@@ -9,12 +9,15 @@ const HardcodedProviderSchema = z.object({
9
9
  return Math.max(1, Math.min(100, weight));
10
10
  })
11
11
  });
12
- const convertHostedProvider = (provider) => {
13
- const providers = Object.values(provider).map(
14
- (p) => HardcodedProviderSchema.parse(p)
15
- );
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));
16
17
  return providers.sort((a, b) => a.url.localeCompare(b.url));
17
18
  };
19
+ const stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
20
+ const getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
18
21
  const getLoadBalancerUrl = (environment) => {
19
22
  if (environment === "production") {
20
23
  return "https://provider-list.prosopo.io/";
@@ -49,5 +52,7 @@ const loadBalancer = async (environment) => {
49
52
  export {
50
53
  convertHostedProvider,
51
54
  getLoadBalancerUrl,
52
- loadBalancer
55
+ getProviderHostname,
56
+ loadBalancer,
57
+ stripIpModeLabel
53
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"balancer.js","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,OAAO,CAAC,CAAC,CAAC;SACV,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;QAElB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC;CACH,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,QAAyB,EACH,EAAE;IACxB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAChC,CAAC;IACF,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,WAA6B,EAAU,EAAE;IAC3E,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO,mCAAmC,CAAC;IAC5C,CAAC;IACD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,+CAA+C,CAAC;IACxD,CAAC;IACD,MAAM,IAAI,eAAe,CAAC,4BAA4B,EAAE;QACvD,OAAO,EAAE,EAAE,WAAW,EAAE;KACxB,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAChC,WAA6B,EACE,EAAE;IACjC,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;QACnC,OAAO;YACN;gBACC,OAAO,EAAE,kDAAkD;gBAC3D,GAAG,EAAE,wBAAwB;gBAC7B,SAAS,EACR,oEAAoE;gBACrE,MAAM,EAAE,CAAC;aACT;SACD,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAoB,MAAM,KAAK,CAC7C,kBAAkB,CAAC,WAAW,CAAC,EAC/B;QACC,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,MAAM;KACZ,CACD,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5B,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC,CAAC"}
1
+ {"version":3,"file":"balancer.js","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"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"}
@@ -11,12 +11,15 @@ const HardcodedProviderSchema = zod.z.object({
11
11
  return Math.max(1, Math.min(100, weight));
12
12
  })
13
13
  });
14
- const convertHostedProvider = (provider) => {
15
- const providers = Object.values(provider).map(
16
- (p) => HardcodedProviderSchema.parse(p)
17
- );
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));
18
19
  return providers.sort((a, b) => a.url.localeCompare(b.url));
19
20
  };
21
+ const stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
22
+ const getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
20
23
  const getLoadBalancerUrl = (environment) => {
21
24
  if (environment === "production") {
22
25
  return "https://provider-list.prosopo.io/";
@@ -50,4 +53,6 @@ const loadBalancer = async (environment) => {
50
53
  };
51
54
  exports.convertHostedProvider = convertHostedProvider;
52
55
  exports.getLoadBalancerUrl = getLoadBalancerUrl;
56
+ exports.getProviderHostname = getProviderHostname;
53
57
  exports.loadBalancer = loadBalancer;
58
+ exports.stripIpModeLabel = stripIpModeLabel;
@@ -2,11 +2,12 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const providers = require("./providers.cjs");
4
4
  const balancer = require("./balancer.cjs");
5
- exports._resetCache = providers._resetCache;
5
+ exports._resetPinCache = providers._resetPinCache;
6
+ exports._resetProviderListCache = providers._resetProviderListCache;
7
+ exports.getProviders = providers.getProviders;
6
8
  exports.getRandomActiveProvider = providers.getRandomActiveProvider;
7
- exports.prefetchProviders = providers.prefetchProviders;
8
- exports.selectWeightedProvider = providers.selectWeightedProvider;
9
- exports.setProviderLoader = providers.setProviderLoader;
10
9
  exports.convertHostedProvider = balancer.convertHostedProvider;
11
10
  exports.getLoadBalancerUrl = balancer.getLoadBalancerUrl;
11
+ exports.getProviderHostname = balancer.getProviderHostname;
12
12
  exports.loadBalancer = balancer.loadBalancer;
13
+ exports.stripIpModeLabel = balancer.stripIpModeLabel;
@@ -1,66 +1,84 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- require("./index.cjs");
4
3
  const balancer = require("./balancer.cjs");
5
- const providerPromiseCache = /* @__PURE__ */ new Map();
6
- let customProviderLoader = null;
7
- function setProviderLoader(loader) {
8
- customProviderLoader = loader;
9
- }
10
- function _resetCache() {
11
- providerPromiseCache.clear();
12
- }
13
- function selectWeightedProvider(providers, entropy) {
14
- if (providers.length === 0) {
15
- throw new Error("No providers available");
16
- }
17
- const totalWeight = providers.reduce((sum, p) => sum + p.weight, 0);
18
- const randomValue = entropy % totalWeight;
19
- let cumulativeWeight = 0;
20
- for (const provider of providers) {
21
- cumulativeWeight += provider.weight;
22
- if (randomValue < cumulativeWeight) {
23
- return provider;
24
- }
4
+ const DNS_ENDPOINT = {
5
+ development: "https://localhost:9229",
6
+ staging: "https://staging.pronode.prosopo.io",
7
+ production: "https://pronode.prosopo.io"
8
+ };
9
+ const withIpModeLabel = (hostname, ipMode) => ipMode ? `${ipMode}.${hostname}` : hostname;
10
+ const 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;
25
18
  }
26
- const selectedProvider = providers[providers.length - 1];
27
- if (!selectedProvider) {
28
- throw new Error("No providers available");
19
+ };
20
+ const cacheKey = (env, ipMode) => `${env}|${ipMode ?? "dual"}`;
21
+ const pinPromiseCache = /* @__PURE__ */ new Map();
22
+ const fetchPinnedHost = async (baseUrl) => {
23
+ const res = await fetch(`${baseUrl}/healthz`, {
24
+ method: "GET",
25
+ cache: "no-store",
26
+ credentials: "omit"
27
+ });
28
+ if (!res.ok) {
29
+ throw new Error(`healthz responded with ${res.status}`);
29
30
  }
30
- return selectedProvider;
31
- }
32
- const loadProviders = async (env) => {
33
- if (customProviderLoader) {
34
- return customProviderLoader(env);
31
+ const body = await res.json();
32
+ if (typeof body.host !== "string" || body.host.length === 0) {
33
+ throw new Error("healthz response missing host field");
35
34
  }
36
- return balancer.loadBalancer(env);
35
+ return body.host;
36
+ };
37
+ const resolveBaseUrl = (env) => DNS_ENDPOINT[env] ?? DNS_ENDPOINT.development;
38
+ const resolvePinnedUrl = async (env, ipMode) => {
39
+ const base = applyIpModeToUrl(resolveBaseUrl(env), ipMode);
40
+ if (env === "development") return base;
41
+ const key = cacheKey(env, ipMode);
42
+ const cached = pinPromiseCache.get(key);
43
+ if (cached) return cached;
44
+ const promise = (async () => {
45
+ try {
46
+ const host = await fetchPinnedHost(base);
47
+ const parsed = new URL(base);
48
+ parsed.hostname = withIpModeLabel(host, ipMode);
49
+ return parsed.toString().replace(/\/$/, "");
50
+ } catch {
51
+ return base;
52
+ }
53
+ })();
54
+ pinPromiseCache.set(key, promise);
55
+ return promise;
37
56
  };
38
- const getProvidersPromise = (env) => {
39
- const existing = providerPromiseCache.get(env);
40
- if (existing) return existing;
41
- const promise = loadProviders(env).catch((err) => {
42
- providerPromiseCache.delete(env);
57
+ const providerListPromiseCache = /* @__PURE__ */ new Map();
58
+ const getProviders = async (env) => {
59
+ const cached = providerListPromiseCache.get(env);
60
+ if (cached) return cached;
61
+ const promise = balancer.loadBalancer(env).catch((err) => {
62
+ providerListPromiseCache.delete(env);
43
63
  throw err;
44
64
  });
45
- providerPromiseCache.set(env, promise);
65
+ providerListPromiseCache.set(env, promise);
46
66
  return promise;
47
67
  };
48
- const prefetchProviders = async (env) => {
49
- await getProvidersPromise(env);
50
- };
51
- const getRandomActiveProvider = async (env, entropy) => {
52
- const providers = await getProvidersPromise(env);
53
- const randomProviderObj = selectWeightedProvider(providers, entropy);
68
+ const getRandomActiveProvider = async (env, ipMode) => {
69
+ const url = await resolvePinnedUrl(env, ipMode);
54
70
  return {
55
- providerAccount: randomProviderObj.address,
56
- provider: {
57
- url: randomProviderObj.url,
58
- datasetId: randomProviderObj.datasetId
59
- }
71
+ providerAccount: "dns-routed",
72
+ provider: { url }
60
73
  };
61
74
  };
62
- exports._resetCache = _resetCache;
75
+ const _resetPinCache = () => {
76
+ pinPromiseCache.clear();
77
+ };
78
+ const _resetProviderListCache = () => {
79
+ providerListPromiseCache.clear();
80
+ };
81
+ exports._resetPinCache = _resetPinCache;
82
+ exports._resetProviderListCache = _resetProviderListCache;
83
+ exports.getProviders = getProviders;
63
84
  exports.getRandomActiveProvider = getRandomActiveProvider;
64
- exports.prefetchProviders = prefetchProviders;
65
- exports.selectWeightedProvider = selectWeightedProvider;
66
- exports.setProviderLoader = setProviderLoader;
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
- import { _resetCache, getRandomActiveProvider, prefetchProviders, selectWeightedProvider, setProviderLoader } from "./providers.js";
2
- import { convertHostedProvider, getLoadBalancerUrl, loadBalancer } from "./balancer.js";
1
+ import { _resetPinCache, _resetProviderListCache, getProviders, getRandomActiveProvider } from "./providers.js";
2
+ import { convertHostedProvider, getLoadBalancerUrl, getProviderHostname, loadBalancer, stripIpModeLabel } from "./balancer.js";
3
3
  export {
4
- _resetCache,
4
+ _resetPinCache,
5
+ _resetProviderListCache,
5
6
  convertHostedProvider,
6
7
  getLoadBalancerUrl,
8
+ getProviderHostname,
9
+ getProviders,
7
10
  getRandomActiveProvider,
8
11
  loadBalancer,
9
- prefetchProviders,
10
- selectWeightedProvider,
11
- setProviderLoader
12
+ stripIpModeLabel
12
13
  };
@@ -1,8 +1,7 @@
1
1
  import type { EnvironmentTypes, RandomProvider } from "@prosopo/types";
2
- import { type HardcodedProvider } from "./index.js";
3
- export declare function setProviderLoader(loader: (env: EnvironmentTypes) => Promise<HardcodedProvider[]>): void;
4
- export declare function _resetCache(): void;
5
- export declare function selectWeightedProvider(providers: HardcodedProvider[], entropy: number): HardcodedProvider;
6
- export declare const prefetchProviders: (env: EnvironmentTypes) => Promise<void>;
7
- export declare const getRandomActiveProvider: (env: EnvironmentTypes, entropy: number) => Promise<RandomProvider>;
2
+ import { type HardcodedProvider, type IpMode } from "./balancer.js";
3
+ export declare const getProviders: (env: EnvironmentTypes) => Promise<HardcodedProvider[]>;
4
+ export declare const getRandomActiveProvider: (env: EnvironmentTypes, ipMode?: IpMode) => Promise<RandomProvider>;
5
+ export declare const _resetPinCache: () => void;
6
+ export declare const _resetProviderListCache: () => void;
8
7
  //# sourceMappingURL=providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,KAAK,iBAAiB,EAAgB,MAAM,YAAY,CAAC;AAkBlE,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,GAC7D,IAAI,CAEN;AAED,wBAAgB,WAAW,SAE1B;AAUD,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,iBAAiB,EAAE,EAC9B,OAAO,EAAE,MAAM,GACb,iBAAiB,CAyBnB;AA+BD,eAAO,MAAM,iBAAiB,QACxB,gBAAgB,KACnB,OAAO,CAAC,IAAI,CAEd,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAC9B,gBAAgB,WACZ,MAAM,KACb,OAAO,CAAC,cAAc,CAWxB,CAAC"}
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,MAAM,EAEX,MAAM,eAAe,CAAC;AA4GvB,eAAO,MAAM,YAAY,QACnB,gBAAgB,KACnB,OAAO,CAAC,iBAAiB,EAAE,CAY7B,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAC9B,gBAAgB,WACZ,MAAM,KACb,OAAO,CAAC,cAAc,CAMxB,CAAC;AAIF,eAAO,MAAM,cAAc,YAE1B,CAAC;AAIF,eAAO,MAAM,uBAAuB,YAEnC,CAAC"}
package/dist/providers.js CHANGED
@@ -1,66 +1,84 @@
1
- import "./index.js";
2
1
  import { loadBalancer } from "./balancer.js";
3
- const providerPromiseCache = /* @__PURE__ */ new Map();
4
- let customProviderLoader = null;
5
- function setProviderLoader(loader) {
6
- customProviderLoader = loader;
7
- }
8
- function _resetCache() {
9
- providerPromiseCache.clear();
10
- }
11
- function selectWeightedProvider(providers, entropy) {
12
- if (providers.length === 0) {
13
- throw new Error("No providers available");
14
- }
15
- const totalWeight = providers.reduce((sum, p) => sum + p.weight, 0);
16
- const randomValue = entropy % totalWeight;
17
- let cumulativeWeight = 0;
18
- for (const provider of providers) {
19
- cumulativeWeight += provider.weight;
20
- if (randomValue < cumulativeWeight) {
21
- return provider;
22
- }
2
+ const DNS_ENDPOINT = {
3
+ development: "https://localhost:9229",
4
+ staging: "https://staging.pronode.prosopo.io",
5
+ production: "https://pronode.prosopo.io"
6
+ };
7
+ const withIpModeLabel = (hostname, ipMode) => ipMode ? `${ipMode}.${hostname}` : hostname;
8
+ const applyIpModeToUrl = (url, ipMode) => {
9
+ if (!ipMode) return url;
10
+ try {
11
+ const parsed = new URL(url);
12
+ parsed.hostname = withIpModeLabel(parsed.hostname, ipMode);
13
+ return parsed.toString().replace(/\/$/, "");
14
+ } catch {
15
+ return url;
23
16
  }
24
- const selectedProvider = providers[providers.length - 1];
25
- if (!selectedProvider) {
26
- throw new Error("No providers available");
17
+ };
18
+ const cacheKey = (env, ipMode) => `${env}|${ipMode ?? "dual"}`;
19
+ const pinPromiseCache = /* @__PURE__ */ new Map();
20
+ const fetchPinnedHost = async (baseUrl) => {
21
+ const res = await fetch(`${baseUrl}/healthz`, {
22
+ method: "GET",
23
+ cache: "no-store",
24
+ credentials: "omit"
25
+ });
26
+ if (!res.ok) {
27
+ throw new Error(`healthz responded with ${res.status}`);
27
28
  }
28
- return selectedProvider;
29
- }
30
- const loadProviders = async (env) => {
31
- if (customProviderLoader) {
32
- return customProviderLoader(env);
29
+ const body = await res.json();
30
+ if (typeof body.host !== "string" || body.host.length === 0) {
31
+ throw new Error("healthz response missing host field");
33
32
  }
34
- return loadBalancer(env);
33
+ return body.host;
34
+ };
35
+ const resolveBaseUrl = (env) => DNS_ENDPOINT[env] ?? DNS_ENDPOINT.development;
36
+ const resolvePinnedUrl = async (env, ipMode) => {
37
+ const base = applyIpModeToUrl(resolveBaseUrl(env), ipMode);
38
+ if (env === "development") return base;
39
+ const key = cacheKey(env, ipMode);
40
+ const cached = pinPromiseCache.get(key);
41
+ if (cached) return cached;
42
+ const promise = (async () => {
43
+ try {
44
+ const host = await fetchPinnedHost(base);
45
+ const parsed = new URL(base);
46
+ parsed.hostname = withIpModeLabel(host, ipMode);
47
+ return parsed.toString().replace(/\/$/, "");
48
+ } catch {
49
+ return base;
50
+ }
51
+ })();
52
+ pinPromiseCache.set(key, promise);
53
+ return promise;
35
54
  };
36
- const getProvidersPromise = (env) => {
37
- const existing = providerPromiseCache.get(env);
38
- if (existing) return existing;
39
- const promise = loadProviders(env).catch((err) => {
40
- providerPromiseCache.delete(env);
55
+ const providerListPromiseCache = /* @__PURE__ */ new Map();
56
+ const getProviders = async (env) => {
57
+ const cached = providerListPromiseCache.get(env);
58
+ if (cached) return cached;
59
+ const promise = loadBalancer(env).catch((err) => {
60
+ providerListPromiseCache.delete(env);
41
61
  throw err;
42
62
  });
43
- providerPromiseCache.set(env, promise);
63
+ providerListPromiseCache.set(env, promise);
44
64
  return promise;
45
65
  };
46
- const prefetchProviders = async (env) => {
47
- await getProvidersPromise(env);
48
- };
49
- const getRandomActiveProvider = async (env, entropy) => {
50
- const providers = await getProvidersPromise(env);
51
- const randomProviderObj = selectWeightedProvider(providers, entropy);
66
+ const getRandomActiveProvider = async (env, ipMode) => {
67
+ const url = await resolvePinnedUrl(env, ipMode);
52
68
  return {
53
- providerAccount: randomProviderObj.address,
54
- provider: {
55
- url: randomProviderObj.url,
56
- datasetId: randomProviderObj.datasetId
57
- }
69
+ providerAccount: "dns-routed",
70
+ provider: { url }
58
71
  };
59
72
  };
73
+ const _resetPinCache = () => {
74
+ pinPromiseCache.clear();
75
+ };
76
+ const _resetProviderListCache = () => {
77
+ providerListPromiseCache.clear();
78
+ };
60
79
  export {
61
- _resetCache,
62
- getRandomActiveProvider,
63
- prefetchProviders,
64
- selectWeightedProvider,
65
- setProviderLoader
80
+ _resetPinCache,
81
+ _resetProviderListCache,
82
+ getProviders,
83
+ getRandomActiveProvider
66
84
  };
@@ -1 +1 @@
1
- {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAeA,OAAO,EAA0B,YAAY,EAAE,MAAM,YAAY,CAAC;AAGlE,MAAM,oBAAoB,GAGtB,IAAI,GAAG,EAAE,CAAC;AAGd,IAAI,oBAAoB,GAEd,IAAI,CAAC;AAOf,MAAM,UAAU,iBAAiB,CAChC,MAA+D;IAE/D,oBAAoB,GAAG,MAAM,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW;IAC1B,oBAAoB,CAAC,KAAK,EAAE,CAAC;AAC9B,CAAC;AAUD,MAAM,UAAU,sBAAsB,CACrC,SAA8B,EAC9B,OAAe;IAEf,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAGpE,MAAM,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;IAG1C,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAClC,gBAAgB,IAAI,QAAQ,CAAC,MAAM,CAAC;QACpC,IAAI,WAAW,GAAG,gBAAgB,EAAE,CAAC;YACpC,OAAO,QAAQ,CAAC;QACjB,CAAC;IACF,CAAC;IAGD,MAAM,gBAAgB,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,gBAAgB,CAAC;AACzB,CAAC;AAGD,MAAM,aAAa,GAAG,KAAK,EAC1B,GAAqB,EACU,EAAE;IACjC,IAAI,oBAAoB,EAAE,CAAC;QAC1B,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC,CAAC;AAIF,MAAM,mBAAmB,GAAG,CAC3B,GAAqB,EACU,EAAE;IACjC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAChD,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,GAAG,CAAC;IACX,CAAC,CAAC,CAAC;IACH,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACrC,GAAqB,EACL,EAAE;IAClB,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC3C,GAAqB,EACrB,OAAe,EACW,EAAE;IAC5B,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAErE,OAAO;QACN,eAAe,EAAE,iBAAiB,CAAC,OAAO;QAC1C,QAAQ,EAAE;YACT,GAAG,EAAE,iBAAiB,CAAC,GAAG;YAC1B,SAAS,EAAE,iBAAiB,CAAC,SAAS;SACtC;KACD,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}