@prosopo/procaptcha-frictionless 2.13.0 → 2.13.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/procaptcha-frictionless@2.13.0 build:cjs
2
+ > @prosopo/procaptcha-frictionless@2.13.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: .
@@ -53,13 +53,14 @@ ViteCommonJSConfig: .
53
53
  vite v8.1.5 building ssr environment for production...
54
54
  Bundle build started
55
55
  
56
- 6 modules transformed.
56
+ 7 modules transformed.
57
57
  rendering chunks...
58
58
  computing gzip size...
59
- dist/cjs/index.cjs 0.24 kB │ gzip: 0.15 kB
59
+ dist/cjs/index.cjs 0.54 kB │ gzip: 0.21 kB
60
60
  dist/cjs/detectorLoader.cjs 0.62 kB │ gzip: 0.40 kB
61
61
  dist/cjs/sessionInvalidatedRecovery.cjs 2.07 kB │ gzip: 0.99 kB
62
- dist/cjs/customDetectBot.cjs 5.06 kB │ gzip: 1.58 kB
62
+ dist/cjs/detectorPrefetch.cjs 2.98 kB │ gzip: 1.35 kB
63
+ dist/cjs/customDetectBot.cjs 5.50 kB │ gzip: 1.67 kB
63
64
  dist/cjs/ProcaptchaFrictionless.cjs 7.00 kB │ gzip: 2.02 kB
64
65
 
65
- ✓ built in 59ms
66
+ ✓ built in 44ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/procaptcha-frictionless@2.13.0 build:tsc
2
+ > @prosopo/procaptcha-frictionless@2.13.1 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 11:10:41 AM - Projects in this build:
5
+ 12:44:41 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -25,47 +25,47 @@
25
25
  * ../procaptcha-react/tsconfig.json
26
26
  * tsconfig.json
27
27
 
28
- 11:10:41 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'
28
+ 12:44:41 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/index.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
29
29
 
30
- 11:10:41 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
30
+ 12:44:41 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
31
31
 
32
- 11:10:41 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
32
+ 12:44:41 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
33
33
 
34
- 11:10:41 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'
34
+ 12:44: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'
35
35
 
36
- 11:10:41 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'
36
+ 12:44:41 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
37
37
 
38
- 11:10:41 AM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
38
+ 12:44:41 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
39
39
 
40
- 11:10:41 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
40
+ 12:44:41 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
41
41
 
42
- 11:10:41 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'
42
+ 12:44:41 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
43
43
 
44
- 11:10:41 AM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
44
+ 12:44:41 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
45
45
 
46
- 11:10:41 AM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
46
+ 12:44:41 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
47
47
 
48
- 11:10:41 AM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/tests/providers.unit.test.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
48
+ 12:44:41 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/index.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
49
49
 
50
- 11:10:41 AM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/webComponent/createWidget.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
50
+ 12:44:41 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/index.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
51
51
 
52
- 11:10:41 AM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
52
+ 12:44:41 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/pair/decode.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
53
53
 
54
- 11:10:41 AM - Project '../account/tsconfig.json' is up to date because newest input '../account/src/workers/cryptoWorker.ts' is older than output '../account/tsconfig.tsbuildinfo'
54
+ 12:44:41 PM - Project '../account/tsconfig.json' is up to date because newest input '../account/src/custom.d.ts' is older than output '../account/tsconfig.tsbuildinfo'
55
55
 
56
- 11:10:41 AM - Project '../procaptcha-common/tsconfig.json' is up to date because newest input '../procaptcha-common/src/extensionLoader.ts' is older than output '../procaptcha-common/tsconfig.tsbuildinfo'
56
+ 12:44:41 PM - Project '../procaptcha-common/tsconfig.json' is up to date because newest input '../procaptcha-common/src/extensionLoader.ts' is older than output '../procaptcha-common/tsconfig.tsbuildinfo'
57
57
 
58
- 11:10:41 AM - Project '../procaptcha-pow/tsconfig.json' is up to date because newest input '../procaptcha-pow/src/tests/managerHarness.ts' is older than output '../procaptcha-pow/tsconfig.tsbuildinfo'
58
+ 12:44:41 PM - Project '../procaptcha-pow/tsconfig.json' is up to date because newest input '../procaptcha-pow/src/tests/manager.unit.test.ts' is older than output '../procaptcha-pow/tsconfig.tsbuildinfo'
59
59
 
60
- 11:10:41 AM - Project '../procaptcha-puzzle/tsconfig.json' is up to date because newest input '../procaptcha-puzzle/src/tests/managerHarness.ts' is older than output '../procaptcha-puzzle/tsconfig.tsbuildinfo'
60
+ 12:44:41 PM - Project '../procaptcha-puzzle/tsconfig.json' is up to date because newest input '../procaptcha-puzzle/src/index.ts' is older than output '../procaptcha-puzzle/tsconfig.tsbuildinfo'
61
61
 
62
- 11:10:41 AM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/index.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
62
+ 12:44:41 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/tests/mocks/data/captchas.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
63
63
 
64
- 11:10:41 AM - Project '../procaptcha/tsconfig.json' is up to date because newest input '../procaptcha/src/modules/Manager.ts' is older than output '../procaptcha/tsconfig.tsbuildinfo'
64
+ 12:44:41 PM - Project '../procaptcha/tsconfig.json' is up to date because newest input '../procaptcha/src/modules/Manager.ts' is older than output '../procaptcha/tsconfig.tsbuildinfo'
65
65
 
66
- 11:10:42 AM - Project '../procaptcha-react/tsconfig.json' is up to date because newest input '../procaptcha-react/src/index.ts' is older than output '../procaptcha-react/tsconfig.tsbuildinfo'
66
+ 12:44:41 PM - Project '../procaptcha-react/tsconfig.json' is up to date because newest input '../procaptcha-react/src/tests/procaptcha.unit.test.tsx' is older than output '../procaptcha-react/tsconfig.tsbuildinfo'
67
67
 
68
- 11:10:42 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
68
+ 12:44:41 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
69
69
 
70
- 11:10:42 AM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-frictionless/tsconfig.json'...
70
+ 12:44:41 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-frictionless/tsconfig.json'...
71
71
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/procaptcha-frictionless@2.13.0 build
2
+ > @prosopo/procaptcha-frictionless@2.13.1 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/procaptcha-frictionless@2.13.0 build:cross-env
6
+ > @prosopo/procaptcha-frictionless@2.13.1 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -57,14 +57,15 @@ ViteEsmConfig: .
57
57
  vite v8.1.5 building ssr environment for production...
58
58
  Bundle build started
59
59
  
60
- 6 modules transformed.
60
+ 7 modules transformed.
61
61
  rendering chunks...
62
62
  computing gzip size...
63
63
  dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
64
- dist/index.js 0.14 kB │ gzip: 0.10 kB
64
+ dist/index.js 0.32 kB │ gzip: 0.15 kB
65
65
  dist/detectorLoader.js 0.60 kB │ gzip: 0.39 kB
66
66
  dist/sessionInvalidatedRecovery.js 2.01 kB │ gzip: 0.98 kB
67
- dist/customDetectBot.js 4.92 kB │ gzip: 1.55 kB
67
+ dist/detectorPrefetch.js 2.86 kB │ gzip: 1.32 kB
68
+ dist/customDetectBot.js 5.33 kB │ gzip: 1.65 kB
68
69
  dist/ProcaptchaFrictionless.js 6.49 kB │ gzip: 1.97 kB
69
70
 
70
- ✓ built in 47ms
71
+ ✓ built in 45ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @prosopo/procaptcha-frictionless
2
2
 
3
+ ## 2.13.1
4
+ ### Patch Changes
5
+
6
+ - fa4fedb: Start the detector-bundle assignment at page load instead of after the widget mounts.
7
+
8
+ Since the detector moved into the provider-served pool, the frictionless flow cannot begin until `/detector/assign` returns. That request was issued by `customDetectBot`, which only runs once React has mounted the widget — so it queued behind the bundle's dynamic-import chain. Measured on the staging demo, `assign` did not leave the browser until **1513 ms**, of which ~700 ms was purely waiting for chunks to arrive in sequence.
9
+
10
+ Nothing in that request depends on React, i18n or the widget config: it needs the site key (a DOM attribute), the environment (a build-time constant) and the IP-mode flags (DOM attributes). The bundle entry now kicks it off as soon as it has read those, and `customDetectBot` claims the in-flight promise instead of starting its own.
11
+
12
+ The prefetch is loaded by dynamic import so the provider selector and API client do not land in the entry chunk and delay first paint; the entry grows by ~400 bytes. It is fire-and-forget — a failed prefetch is indistinguishable from no prefetch, and the existing fallback path still resolves a provider itself.
13
+
14
+ The cache is single-use and keyed on `(environment, ipMode, siteKey)`, so a retry — which is retrying precisely because the pinned pronode failed — re-resolves rather than reusing a stale pin, and a second widget with different flags cannot claim another's assignment.
15
+
3
16
  ## 2.13.0
4
17
  ### Minor Changes
5
18
 
@@ -1,4 +1,5 @@
1
1
  const require_detectorLoader = require("./detectorLoader.cjs");
2
+ const require_detectorPrefetch = require("./detectorPrefetch.cjs");
2
3
  let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
3
4
  let _prosopo_api = require("@prosopo/api");
4
5
  let _prosopo_common = require("@prosopo/common");
@@ -67,12 +68,19 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
67
68
  if (!config.account.address) throw new _prosopo_common.ProsopoEnvError("GENERAL.SITE_KEY_MISSING");
68
69
  const ipMode = (0, _prosopo_procaptcha_common.pickIpMode)(config);
69
70
  const extClassPromise = (0, _prosopo_procaptcha_common.ExtensionLoader)(config.web2);
70
- const provider = await (0, _prosopo_procaptcha_common.getProcaptchaRandomActiveProvider)(config.defaultEnvironment, ipMode, retryContext);
71
+ const prefetched = !retryContext || retryContext.attempt <= 1 ? require_detectorPrefetch.takePrefetchedDetector(config.defaultEnvironment, ipMode, config.account.address) : void 0;
72
+ let prefetchedResult;
73
+ if (prefetched) try {
74
+ prefetchedResult = await prefetched;
75
+ } catch {
76
+ prefetchedResult = void 0;
77
+ }
78
+ const provider = prefetchedResult?.provider ?? await (0, _prosopo_procaptcha_common.getProcaptchaRandomActiveProvider)(config.defaultEnvironment, ipMode, retryContext);
71
79
  const providerApi = new _prosopo_api.ProviderApi(provider.provider.url, config.account.address);
72
80
  let detectorSessionId;
73
81
  let providerDetect;
74
82
  try {
75
- const assigned = await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
83
+ const assigned = prefetchedResult?.assigned ?? await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
76
84
  if (assigned.useProviderBundle && assigned.detectorScript) {
77
85
  detectorSessionId = assigned.detectorSessionId;
78
86
  providerDetect = await withTimeout(require_detectorLoader.DetectorLoaderFromScript(assigned.detectorScript), ASSIGN_TIMEOUT_MS);
@@ -0,0 +1,65 @@
1
+ let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
2
+ let _prosopo_api = require("@prosopo/api");
3
+ //#region src/detectorPrefetch.ts
4
+ /**
5
+ * Detector bundle prefetch.
6
+ *
7
+ * Since the detector moved into the provider-served pool, the frictionless flow
8
+ * cannot start until `/detector/assign` has returned. That request is issued by
9
+ * `customDetectBot`, which only runs once React has mounted the widget — and
10
+ * that mount sits behind the bundle's dynamic-import chain. Measured on a
11
+ * staging demo page the assign request did not leave the browser until 1513 ms,
12
+ * of which ~700 ms was purely waiting for chunks to arrive in sequence.
13
+ *
14
+ * Nothing in the request depends on React, i18n or the widget config: it needs
15
+ * the site key (a DOM attribute, readable immediately), the environment (a
16
+ * build-time constant) and the IP-mode flags (DOM attributes). So the entry
17
+ * point kicks it off as soon as it has read those, and `customDetectBot` picks
18
+ * up the in-flight promise instead of starting its own.
19
+ *
20
+ * The cache is deliberately single-use. A provider pin is only valid for the
21
+ * attempt it was made for — on a retry the previous pronode is the one that
22
+ * just failed — so a consumed entry is dropped and the retry re-resolves.
23
+ */
24
+ var inFlight = /* @__PURE__ */ new Map();
25
+ var keyOf = (environment, ipMode, siteKey) => `${environment}|${ipMode ?? "auto"}|${siteKey}`;
26
+ /**
27
+ * Start resolving a provider and assigning a detector bundle. Safe to call more
28
+ * than once for the same key — subsequent calls join the in-flight request.
29
+ *
30
+ * Never rejects to the caller: a failed prefetch is indistinguishable from
31
+ * never having prefetched, and `customDetectBot` already handles assign failure
32
+ * by falling back to PoW. Returning a rejected promise here would surface as an
33
+ * unhandled rejection in the host page.
34
+ */
35
+ var prefetchDetector = (environment, ipMode, siteKey) => {
36
+ const key = keyOf(environment, ipMode, siteKey);
37
+ if (inFlight.has(key)) return;
38
+ const promise = (async () => {
39
+ const provider = await (0, _prosopo_procaptcha_common.getProcaptchaRandomActiveProvider)(environment, ipMode);
40
+ return {
41
+ provider,
42
+ assigned: await new _prosopo_api.ProviderApi(provider.provider.url, siteKey).assignDetectorBundle(siteKey)
43
+ };
44
+ })();
45
+ promise.catch(() => void 0);
46
+ inFlight.set(key, promise);
47
+ };
48
+ /**
49
+ * Claim a prefetched assignment, if one was started for this exact key. The
50
+ * entry is removed, so a retry does not reuse a pin that may have just failed.
51
+ */
52
+ var takePrefetchedDetector = (environment, ipMode, siteKey) => {
53
+ const key = keyOf(environment, ipMode, siteKey);
54
+ const promise = inFlight.get(key);
55
+ if (promise) inFlight.delete(key);
56
+ return promise;
57
+ };
58
+ /** Test seam — drops any in-flight prefetches. */
59
+ var clearPrefetchedDetectors = () => {
60
+ inFlight.clear();
61
+ };
62
+ //#endregion
63
+ exports.clearPrefetchedDetectors = clearPrefetchedDetectors;
64
+ exports.prefetchDetector = prefetchDetector;
65
+ exports.takePrefetchedDetector = takePrefetchedDetector;
@@ -1,3 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_detectorPrefetch = require("./detectorPrefetch.cjs");
2
3
  const require_ProcaptchaFrictionless = require("./ProcaptchaFrictionless.cjs");
3
4
  exports.ProcaptchaFrictionless = require_ProcaptchaFrictionless.ProcaptchaFrictionless;
5
+ exports.clearPrefetchedDetectors = require_detectorPrefetch.clearPrefetchedDetectors;
6
+ exports.prefetchDetector = require_detectorPrefetch.prefetchDetector;
7
+ exports.takePrefetchedDetector = require_detectorPrefetch.takePrefetchedDetector;
@@ -1 +1 @@
1
- {"version":3,"file":"customDetectBot.d.ts","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACX,oBAAoB,EAGpB,MAAM,gBAAgB,CAAC;AAoFxB,eAAO,MAAM,WAAW,GAAU,CAAC,WACzB,OAAO,CAAC,CAAC,CAAC,MACf,MAAM,KACR,OAAO,CAAC,CAAC,CAoBX,CAAC;AAEF,QAAA,MAAM,eAAe,EAAE,oBA2LtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"customDetectBot.d.ts","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACX,oBAAoB,EAGpB,MAAM,gBAAgB,CAAC;AAwFxB,eAAO,MAAM,WAAW,GAAU,CAAC,WACzB,OAAO,CAAC,CAAC,CAAC,MACf,MAAM,KACR,OAAO,CAAC,CAAC,CAoBX,CAAC;AAEF,QAAA,MAAM,eAAe,EAAE,oBA2NtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { DetectorLoaderFromScript } from "./detectorLoader.js";
2
+ import { takePrefetchedDetector } from "./detectorPrefetch.js";
2
3
  import { ExtensionLoader, getProcaptchaRandomActiveProvider, pickIpMode } from "@prosopo/procaptcha-common";
3
4
  import { ProviderApi } from "@prosopo/api";
4
5
  import { ProsopoEnvError } from "@prosopo/common";
@@ -67,12 +68,19 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
67
68
  if (!config.account.address) throw new ProsopoEnvError("GENERAL.SITE_KEY_MISSING");
68
69
  const ipMode = pickIpMode(config);
69
70
  const extClassPromise = ExtensionLoader(config.web2);
70
- const provider = await getProcaptchaRandomActiveProvider(config.defaultEnvironment, ipMode, retryContext);
71
+ const prefetched = !retryContext || retryContext.attempt <= 1 ? takePrefetchedDetector(config.defaultEnvironment, ipMode, config.account.address) : void 0;
72
+ let prefetchedResult;
73
+ if (prefetched) try {
74
+ prefetchedResult = await prefetched;
75
+ } catch {
76
+ prefetchedResult = void 0;
77
+ }
78
+ const provider = prefetchedResult?.provider ?? await getProcaptchaRandomActiveProvider(config.defaultEnvironment, ipMode, retryContext);
71
79
  const providerApi = new ProviderApi(provider.provider.url, config.account.address);
72
80
  let detectorSessionId;
73
81
  let providerDetect;
74
82
  try {
75
- const assigned = await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
83
+ const assigned = prefetchedResult?.assigned ?? await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
76
84
  if (assigned.useProviderBundle && assigned.detectorScript) {
77
85
  detectorSessionId = assigned.detectorSessionId;
78
86
  providerDetect = await withTimeout(DetectorLoaderFromScript(assigned.detectorScript), ASSIGN_TIMEOUT_MS);
@@ -1 +1 @@
1
- {"version":3,"file":"customDetectBot.js","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"customDetectBot.js","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { getProcaptchaRandomActiveProvider } from "@prosopo/procaptcha-common";
2
+ import type { AssignDetectorBundleResponse, EnvironmentTypes, RandomProvider } from "@prosopo/types";
3
+ type IpModeParam = Parameters<typeof getProcaptchaRandomActiveProvider>[1];
4
+ export interface PrefetchedDetector {
5
+ provider: RandomProvider;
6
+ assigned: AssignDetectorBundleResponse;
7
+ }
8
+ export declare const prefetchDetector: (environment: EnvironmentTypes, ipMode: IpModeParam, siteKey: string) => void;
9
+ export declare const takePrefetchedDetector: (environment: EnvironmentTypes, ipMode: IpModeParam, siteKey: string) => Promise<PrefetchedDetector> | undefined;
10
+ export declare const clearPrefetchedDetectors: () => void;
11
+ export {};
12
+ //# sourceMappingURL=detectorPrefetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectorPrefetch.d.ts","sourceRoot":"","sources":["../src/detectorPrefetch.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EACX,4BAA4B,EAC5B,gBAAgB,EAChB,cAAc,EACd,MAAM,gBAAgB,CAAC;AAMxB,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iCAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,4BAA4B,CAAC;CACvC;AAmBD,eAAO,MAAM,gBAAgB,gBACf,gBAAgB,UACrB,WAAW,WACV,MAAM,KACb,IAmBF,CAAC;AAMF,eAAO,MAAM,sBAAsB,gBACrB,gBAAgB,UACrB,WAAW,WACV,MAAM,KACb,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAKhC,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAO,IAE3C,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { getProcaptchaRandomActiveProvider } from "@prosopo/procaptcha-common";
2
+ import { ProviderApi } from "@prosopo/api";
3
+ //#region src/detectorPrefetch.ts
4
+ /**
5
+ * Detector bundle prefetch.
6
+ *
7
+ * Since the detector moved into the provider-served pool, the frictionless flow
8
+ * cannot start until `/detector/assign` has returned. That request is issued by
9
+ * `customDetectBot`, which only runs once React has mounted the widget — and
10
+ * that mount sits behind the bundle's dynamic-import chain. Measured on a
11
+ * staging demo page the assign request did not leave the browser until 1513 ms,
12
+ * of which ~700 ms was purely waiting for chunks to arrive in sequence.
13
+ *
14
+ * Nothing in the request depends on React, i18n or the widget config: it needs
15
+ * the site key (a DOM attribute, readable immediately), the environment (a
16
+ * build-time constant) and the IP-mode flags (DOM attributes). So the entry
17
+ * point kicks it off as soon as it has read those, and `customDetectBot` picks
18
+ * up the in-flight promise instead of starting its own.
19
+ *
20
+ * The cache is deliberately single-use. A provider pin is only valid for the
21
+ * attempt it was made for — on a retry the previous pronode is the one that
22
+ * just failed — so a consumed entry is dropped and the retry re-resolves.
23
+ */
24
+ var inFlight = /* @__PURE__ */ new Map();
25
+ var keyOf = (environment, ipMode, siteKey) => `${environment}|${ipMode ?? "auto"}|${siteKey}`;
26
+ /**
27
+ * Start resolving a provider and assigning a detector bundle. Safe to call more
28
+ * than once for the same key — subsequent calls join the in-flight request.
29
+ *
30
+ * Never rejects to the caller: a failed prefetch is indistinguishable from
31
+ * never having prefetched, and `customDetectBot` already handles assign failure
32
+ * by falling back to PoW. Returning a rejected promise here would surface as an
33
+ * unhandled rejection in the host page.
34
+ */
35
+ var prefetchDetector = (environment, ipMode, siteKey) => {
36
+ const key = keyOf(environment, ipMode, siteKey);
37
+ if (inFlight.has(key)) return;
38
+ const promise = (async () => {
39
+ const provider = await getProcaptchaRandomActiveProvider(environment, ipMode);
40
+ return {
41
+ provider,
42
+ assigned: await new ProviderApi(provider.provider.url, siteKey).assignDetectorBundle(siteKey)
43
+ };
44
+ })();
45
+ promise.catch(() => void 0);
46
+ inFlight.set(key, promise);
47
+ };
48
+ /**
49
+ * Claim a prefetched assignment, if one was started for this exact key. The
50
+ * entry is removed, so a retry does not reuse a pin that may have just failed.
51
+ */
52
+ var takePrefetchedDetector = (environment, ipMode, siteKey) => {
53
+ const key = keyOf(environment, ipMode, siteKey);
54
+ const promise = inFlight.get(key);
55
+ if (promise) inFlight.delete(key);
56
+ return promise;
57
+ };
58
+ /** Test seam — drops any in-flight prefetches. */
59
+ var clearPrefetchedDetectors = () => {
60
+ inFlight.clear();
61
+ };
62
+ //#endregion
63
+ export { clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectorPrefetch.js","sourceRoot":"","sources":["../src/detectorPrefetch.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAkB/E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuC,CAAC;AAEhE,MAAM,KAAK,GAAG,CACb,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EACN,EAAE,CAAC,GAAG,WAAW,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;AAW7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EACR,EAAE;IACT,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAE9B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAiC,EAAE;QACxD,MAAM,QAAQ,GAAG,MAAM,iCAAiC,CACvD,WAAW,EACX,MAAM,CACN,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC;IAKL,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACrC,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EAC2B,EAAE;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO;QAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAS,EAAE;IAClD,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./ProcaptchaFrictionless.js";
2
+ export * from "./detectorPrefetch.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  import "./_virtual/_rolldown/runtime.js";
2
+ import { clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector } from "./detectorPrefetch.js";
2
3
  import { ProcaptchaFrictionless } from "./ProcaptchaFrictionless.js";
3
- export { ProcaptchaFrictionless };
4
+ export { ProcaptchaFrictionless, clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=detectorPrefetch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectorPrefetch.test.d.ts","sourceRoot":"","sources":["../../src/tests/detectorPrefetch.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ const assignDetectorBundle = vi.fn();
3
+ const getProcaptchaRandomActiveProvider = vi.fn();
4
+ vi.mock("@prosopo/api", () => ({
5
+ ProviderApi: class {
6
+ constructor() {
7
+ this.assignDetectorBundle = assignDetectorBundle;
8
+ }
9
+ },
10
+ }));
11
+ vi.mock("@prosopo/procaptcha-common", () => ({
12
+ getProcaptchaRandomActiveProvider: (...args) => getProcaptchaRandomActiveProvider(...args),
13
+ }));
14
+ const { prefetchDetector, takePrefetchedDetector, clearPrefetchedDetectors } = await import("../detectorPrefetch.js");
15
+ const ENV = "staging";
16
+ const SITE_KEY = "5CcNvLUdiXFpzKDMjThGLSK9rhWHA1H4EF3zrgkpkjAdqmuP";
17
+ const provider = { provider: { url: "https://pronode.example" } };
18
+ afterEach(() => {
19
+ clearPrefetchedDetectors();
20
+ vi.clearAllMocks();
21
+ });
22
+ describe("detectorPrefetch", () => {
23
+ it("returns undefined when nothing was prefetched", () => {
24
+ expect(takePrefetchedDetector(ENV, undefined, SITE_KEY)).toBeUndefined();
25
+ });
26
+ it("resolves the provider and assigns a bundle", async () => {
27
+ getProcaptchaRandomActiveProvider.mockResolvedValue(provider);
28
+ assignDetectorBundle.mockResolvedValue({ useProviderBundle: true });
29
+ prefetchDetector(ENV, undefined, SITE_KEY);
30
+ const claimed = takePrefetchedDetector(ENV, undefined, SITE_KEY);
31
+ expect(claimed).toBeDefined();
32
+ const result = await claimed;
33
+ expect(result).toStrictEqual({
34
+ provider,
35
+ assigned: { useProviderBundle: true },
36
+ });
37
+ expect(assignDetectorBundle).toHaveBeenCalledWith(SITE_KEY);
38
+ });
39
+ it("is single-use, so a retry does not reuse a stale provider pin", async () => {
40
+ getProcaptchaRandomActiveProvider.mockResolvedValue(provider);
41
+ assignDetectorBundle.mockResolvedValue({ useProviderBundle: true });
42
+ prefetchDetector(ENV, undefined, SITE_KEY);
43
+ const first = takePrefetchedDetector(ENV, undefined, SITE_KEY);
44
+ await first;
45
+ expect(takePrefetchedDetector(ENV, undefined, SITE_KEY)).toBeUndefined();
46
+ });
47
+ it("does not start a second request for the same key", () => {
48
+ getProcaptchaRandomActiveProvider.mockResolvedValue(provider);
49
+ assignDetectorBundle.mockResolvedValue({ useProviderBundle: true });
50
+ prefetchDetector(ENV, undefined, SITE_KEY);
51
+ prefetchDetector(ENV, undefined, SITE_KEY);
52
+ expect(getProcaptchaRandomActiveProvider).toHaveBeenCalledTimes(1);
53
+ });
54
+ it("keys on site key and ip mode, so a different widget does not claim it", () => {
55
+ getProcaptchaRandomActiveProvider.mockResolvedValue(provider);
56
+ assignDetectorBundle.mockResolvedValue({ useProviderBundle: true });
57
+ prefetchDetector(ENV, "ipv4", SITE_KEY);
58
+ expect(takePrefetchedDetector(ENV, "ipv6", SITE_KEY)).toBeUndefined();
59
+ expect(takePrefetchedDetector(ENV, undefined, SITE_KEY)).toBeUndefined();
60
+ expect(takePrefetchedDetector(ENV, "ipv4", "other-key")).toBeUndefined();
61
+ expect(takePrefetchedDetector(ENV, "ipv4", SITE_KEY)).toBeDefined();
62
+ });
63
+ it("surfaces failure to the claimant without an unhandled rejection", async () => {
64
+ getProcaptchaRandomActiveProvider.mockRejectedValue(new Error("no providers"));
65
+ prefetchDetector(ENV, undefined, SITE_KEY);
66
+ const claimed = takePrefetchedDetector(ENV, undefined, SITE_KEY);
67
+ expect(claimed).toBeDefined();
68
+ await expect(claimed).rejects.toThrow("no providers");
69
+ });
70
+ });
71
+ //# sourceMappingURL=detectorPrefetch.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectorPrefetch.test.js","sourceRoot":"","sources":["../../src/tests/detectorPrefetch.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/procaptcha-frictionless",
3
- "version": "2.13.0",
3
+ "version": "2.13.1",
4
4
  "author": "PROSOPO LIMITED <info@prosopo.io>",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -29,6 +29,10 @@ import {
29
29
  DetectorLoaderFromScript,
30
30
  type DetectorType,
31
31
  } from "./detectorLoader.js";
32
+ import {
33
+ type PrefetchedDetector,
34
+ takePrefetchedDetector,
35
+ } from "./detectorPrefetch.js";
32
36
 
33
37
  // Upper bound on the detector-bundle assignment + load probe. The detector
34
38
  // lives ONLY in the provider-served pool bundles, so if the provider is
@@ -168,11 +172,39 @@ const customDetectBot: BotDetectionFunction = async (
168
172
  // preference so frictionless and the subsequent captcha hops stay on the
169
173
  // same stack. Resolved up front — before detection rather than alongside it —
170
174
  // because the detector bundle is served BY this provider.
171
- const provider = await getProcaptchaRandomActiveProvider(
172
- config.defaultEnvironment,
173
- ipMode,
174
- retryContext,
175
- );
175
+ // The bundle entry starts provider resolution + assign as soon as it has read
176
+ // the site key off the DOM, which is well before React has mounted this
177
+ // widget. Claim that in-flight work if it exists rather than repeating it.
178
+ // Only valid on a first attempt: a retry is retrying *because* the pinned
179
+ // pronode failed, so it must re-resolve.
180
+ const isFirstAttempt = !retryContext || retryContext.attempt <= 1;
181
+ const prefetched = isFirstAttempt
182
+ ? takePrefetchedDetector(
183
+ config.defaultEnvironment,
184
+ ipMode,
185
+ config.account.address,
186
+ )
187
+ : undefined;
188
+
189
+ // A prefetch that failed must not fail the flow — it is an optimisation, and
190
+ // the normal path below handles provider selection and assign failure
191
+ // already. So swallow it and re-resolve.
192
+ let prefetchedResult: PrefetchedDetector | undefined;
193
+ if (prefetched) {
194
+ try {
195
+ prefetchedResult = await prefetched;
196
+ } catch {
197
+ prefetchedResult = undefined;
198
+ }
199
+ }
200
+
201
+ const provider =
202
+ prefetchedResult?.provider ??
203
+ (await getProcaptchaRandomActiveProvider(
204
+ config.defaultEnvironment,
205
+ ipMode,
206
+ retryContext,
207
+ ));
176
208
 
177
209
  const providerApi = new ProviderApi(
178
210
  provider.provider.url,
@@ -188,10 +220,14 @@ const customDetectBot: BotDetectionFunction = async (
188
220
  let detectorSessionId: string | undefined;
189
221
  let providerDetect: DetectorType | undefined;
190
222
  try {
191
- const assigned = await withTimeout(
192
- providerApi.assignDetectorBundle(config.account.address),
193
- ASSIGN_TIMEOUT_MS,
194
- );
223
+ // Reuse the prefetched assignment when the entry already fetched one for
224
+ // this provider; otherwise issue it now.
225
+ const assigned =
226
+ prefetchedResult?.assigned ??
227
+ (await withTimeout(
228
+ providerApi.assignDetectorBundle(config.account.address),
229
+ ASSIGN_TIMEOUT_MS,
230
+ ));
195
231
  if (assigned.useProviderBundle && assigned.detectorScript) {
196
232
  detectorSessionId = assigned.detectorSessionId;
197
233
  providerDetect = await withTimeout(