@captchafox/react 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -52,13 +52,20 @@ var __async = (__this, __arguments, generator) => {
52
52
  var src_exports = {};
53
53
  __export(src_exports, {
54
54
  CAPTCHA_RESPONSE_KEY: () => CAPTCHA_RESPONSE_KEY,
55
- CaptchaFox: () => CaptchaFox
55
+ CaptchaFox: () => CaptchaFox,
56
+ RetryError: () => RetryError,
57
+ TimeoutError: () => TimeoutError
56
58
  });
57
59
  module.exports = __toCommonJS(src_exports);
58
60
 
59
61
  // ../internal/dist/index.mjs
62
+ var RetryError = class extends Error {
63
+ };
64
+ var TimeoutError = class extends Error {
65
+ };
60
66
  var backoff = (retryCount) => Math.exp(retryCount) * 150;
61
67
  var withRetry = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (callback, { attempts = 4 } = {}) {
68
+ var _a;
62
69
  let error;
63
70
  for (let i = 0; i < attempts; i++) {
64
71
  try {
@@ -68,7 +75,7 @@ var withRetry = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (callback,
68
75
  yield new Promise((r) => setTimeout(r, backoff(i)));
69
76
  }
70
77
  }
71
- throw error != null ? error : new Error("Exhausted all retries");
78
+ throw new RetryError((_a = error == null ? void 0 : error.message) != null ? _a : "Exhausted all retries");
72
79
  });
73
80
  var mountInstance;
74
81
  var LOAD_FUNC_KEY = "captchaFoxOnLoad";
@@ -108,6 +115,7 @@ var isApiReady = () => typeof (window == null ? void 0 : window.captchafox) !==
108
115
  var import_react = __toESM(require("react"), 1);
109
116
  var CaptchaFox = (0, import_react.forwardRef)(
110
117
  ({
118
+ executeTimeoutSeconds = 30,
111
119
  sitekey,
112
120
  lang,
113
121
  mode,
@@ -124,6 +132,8 @@ var CaptchaFox = (0, import_react.forwardRef)(
124
132
  const [containerRef, setContainerRef] = (0, import_react.useState)();
125
133
  const [widgetId, setWidgetId] = (0, import_react.useState)();
126
134
  const firstRendered = (0, import_react.useRef)(false);
135
+ const onReady = (0, import_react.useRef)();
136
+ const executeTimeout = (0, import_react.useRef)();
127
137
  (0, import_react.useImperativeHandle)(
128
138
  ref,
129
139
  () => {
@@ -150,12 +160,18 @@ var CaptchaFox = (0, import_react.forwardRef)(
150
160
  setWidgetId(void 0);
151
161
  window.captchafox.remove(widgetId);
152
162
  },
153
- execute: () => {
163
+ execute: () => __async(void 0, null, function* () {
154
164
  if (!isApiReady() || !widgetId) {
155
- return Promise.reject("[CaptchaFox] Widget has not been loaded");
165
+ return waitAndExecute();
156
166
  }
157
- return window.captchafox.execute(widgetId);
158
- }
167
+ try {
168
+ const token = yield window.captchafox.execute(widgetId);
169
+ return token;
170
+ } catch (error) {
171
+ const errorType = getErrorType(error);
172
+ return Promise.reject(errorType);
173
+ }
174
+ })
159
175
  };
160
176
  },
161
177
  [widgetId]
@@ -165,23 +181,9 @@ var CaptchaFox = (0, import_react.forwardRef)(
165
181
  onLoad == null ? void 0 : onLoad();
166
182
  }
167
183
  }, [widgetId]);
168
- const renderCaptcha = () => __async(void 0, null, function* () {
169
- var _a, _b, _c;
170
- (_a = window.captchafox) == null ? void 0 : _a.remove(widgetId);
171
- if (!containerRef || ((_b = containerRef == null ? void 0 : containerRef.children) == null ? void 0 : _b.length) === 1) return;
172
- const newWidgetId = yield (_c = window.captchafox) == null ? void 0 : _c.render(containerRef, {
173
- lang,
174
- sitekey,
175
- mode,
176
- theme,
177
- i18n,
178
- onError,
179
- onFail,
180
- onClose,
181
- onVerify
182
- });
183
- setWidgetId(newWidgetId);
184
- });
184
+ (0, import_react.useEffect)(() => {
185
+ return () => clearTimeout(executeTimeout.current);
186
+ }, []);
185
187
  (0, import_react.useEffect)(() => {
186
188
  if (!containerRef) return;
187
189
  if (firstRendered.current) {
@@ -200,6 +202,50 @@ var CaptchaFox = (0, import_react.forwardRef)(
200
202
  });
201
203
  }
202
204
  }, [containerRef, sitekey, lang, mode]);
205
+ const waitAndExecute = () => {
206
+ return new Promise((resolve, reject) => {
207
+ executeTimeout.current = setTimeout(() => {
208
+ reject(new TimeoutError("Execute timed out"));
209
+ }, executeTimeoutSeconds * 1e3);
210
+ onReady.current = (id) => {
211
+ clearTimeout(executeTimeout.current);
212
+ window.captchafox.execute(id).then(resolve).catch((error) => {
213
+ const errorType = getErrorType(error);
214
+ reject(errorType);
215
+ });
216
+ };
217
+ });
218
+ };
219
+ const getErrorType = (error) => {
220
+ if (error !== "challenge-aborted" && error !== "rate-limited") {
221
+ return new RetryError();
222
+ }
223
+ return error;
224
+ };
225
+ const renderCaptcha = () => __async(void 0, null, function* () {
226
+ var _a, _b, _c;
227
+ (_a = window.captchafox) == null ? void 0 : _a.remove(widgetId);
228
+ if (!containerRef || ((_b = containerRef == null ? void 0 : containerRef.children) == null ? void 0 : _b.length) === 1) return;
229
+ const newWidgetId = yield (_c = window.captchafox) == null ? void 0 : _c.render(containerRef, {
230
+ lang,
231
+ sitekey,
232
+ mode,
233
+ theme,
234
+ i18n,
235
+ onError,
236
+ onFail,
237
+ onClose,
238
+ onVerify
239
+ });
240
+ if (!newWidgetId) {
241
+ return;
242
+ }
243
+ setWidgetId(newWidgetId);
244
+ if (onReady.current) {
245
+ onReady.current(newWidgetId);
246
+ onReady.current = void 0;
247
+ }
248
+ });
203
249
  return /* @__PURE__ */ import_react.default.createElement("div", { ref: setContainerRef, id: widgetId, className });
204
250
  }
205
251
  );
@@ -210,5 +256,7 @@ var CAPTCHA_RESPONSE_KEY = "cf-captcha-response";
210
256
  // Annotate the CommonJS export names for ESM import in node:
211
257
  0 && (module.exports = {
212
258
  CAPTCHA_RESPONSE_KEY,
213
- CaptchaFox
259
+ CaptchaFox,
260
+ RetryError,
261
+ TimeoutError
214
262
  });
package/dist/index.d.cts CHANGED
@@ -1,14 +1,20 @@
1
1
  import { WidgetApi, WidgetOptions } from '@captchafox/types';
2
2
  import React from 'react';
3
3
 
4
+ declare class RetryError extends Error {
5
+ }
6
+ declare class TimeoutError extends Error {
7
+ }
8
+
4
9
  type CaptchaFoxInstance = Omit<WidgetApi, 'render'>;
5
10
  declare const CaptchaFox: React.ForwardRefExoticComponent<WidgetOptions & {
6
11
  /** Called after the widget has been loaded */
7
12
  onLoad?: (() => void) | undefined;
8
13
  className?: string | undefined;
9
14
  nonce?: string | undefined;
15
+ executeTimeoutSeconds?: number | undefined;
10
16
  } & React.RefAttributes<CaptchaFoxInstance>>;
11
17
 
12
18
  declare const CAPTCHA_RESPONSE_KEY = "cf-captcha-response";
13
19
 
14
- export { CAPTCHA_RESPONSE_KEY, CaptchaFox, type CaptchaFoxInstance };
20
+ export { CAPTCHA_RESPONSE_KEY, CaptchaFox, type CaptchaFoxInstance, RetryError, TimeoutError };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,20 @@
1
1
  import { WidgetApi, WidgetOptions } from '@captchafox/types';
2
2
  import React from 'react';
3
3
 
4
+ declare class RetryError extends Error {
5
+ }
6
+ declare class TimeoutError extends Error {
7
+ }
8
+
4
9
  type CaptchaFoxInstance = Omit<WidgetApi, 'render'>;
5
10
  declare const CaptchaFox: React.ForwardRefExoticComponent<WidgetOptions & {
6
11
  /** Called after the widget has been loaded */
7
12
  onLoad?: (() => void) | undefined;
8
13
  className?: string | undefined;
9
14
  nonce?: string | undefined;
15
+ executeTimeoutSeconds?: number | undefined;
10
16
  } & React.RefAttributes<CaptchaFoxInstance>>;
11
17
 
12
18
  declare const CAPTCHA_RESPONSE_KEY = "cf-captcha-response";
13
19
 
14
- export { CAPTCHA_RESPONSE_KEY, CaptchaFox, type CaptchaFoxInstance };
20
+ export { CAPTCHA_RESPONSE_KEY, CaptchaFox, type CaptchaFoxInstance, RetryError, TimeoutError };
package/dist/index.js CHANGED
@@ -21,8 +21,13 @@ var __async = (__this, __arguments, generator) => {
21
21
  };
22
22
 
23
23
  // ../internal/dist/index.mjs
24
+ var RetryError = class extends Error {
25
+ };
26
+ var TimeoutError = class extends Error {
27
+ };
24
28
  var backoff = (retryCount) => Math.exp(retryCount) * 150;
25
29
  var withRetry = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (callback, { attempts = 4 } = {}) {
30
+ var _a;
26
31
  let error;
27
32
  for (let i = 0; i < attempts; i++) {
28
33
  try {
@@ -32,7 +37,7 @@ var withRetry = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (callback,
32
37
  yield new Promise((r) => setTimeout(r, backoff(i)));
33
38
  }
34
39
  }
35
- throw error != null ? error : new Error("Exhausted all retries");
40
+ throw new RetryError((_a = error == null ? void 0 : error.message) != null ? _a : "Exhausted all retries");
36
41
  });
37
42
  var mountInstance;
38
43
  var LOAD_FUNC_KEY = "captchaFoxOnLoad";
@@ -72,6 +77,7 @@ var isApiReady = () => typeof (window == null ? void 0 : window.captchafox) !==
72
77
  import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
73
78
  var CaptchaFox = forwardRef(
74
79
  ({
80
+ executeTimeoutSeconds = 30,
75
81
  sitekey,
76
82
  lang,
77
83
  mode,
@@ -88,6 +94,8 @@ var CaptchaFox = forwardRef(
88
94
  const [containerRef, setContainerRef] = useState();
89
95
  const [widgetId, setWidgetId] = useState();
90
96
  const firstRendered = useRef(false);
97
+ const onReady = useRef();
98
+ const executeTimeout = useRef();
91
99
  useImperativeHandle(
92
100
  ref,
93
101
  () => {
@@ -114,12 +122,18 @@ var CaptchaFox = forwardRef(
114
122
  setWidgetId(void 0);
115
123
  window.captchafox.remove(widgetId);
116
124
  },
117
- execute: () => {
125
+ execute: () => __async(void 0, null, function* () {
118
126
  if (!isApiReady() || !widgetId) {
119
- return Promise.reject("[CaptchaFox] Widget has not been loaded");
127
+ return waitAndExecute();
120
128
  }
121
- return window.captchafox.execute(widgetId);
122
- }
129
+ try {
130
+ const token = yield window.captchafox.execute(widgetId);
131
+ return token;
132
+ } catch (error) {
133
+ const errorType = getErrorType(error);
134
+ return Promise.reject(errorType);
135
+ }
136
+ })
123
137
  };
124
138
  },
125
139
  [widgetId]
@@ -129,23 +143,9 @@ var CaptchaFox = forwardRef(
129
143
  onLoad == null ? void 0 : onLoad();
130
144
  }
131
145
  }, [widgetId]);
132
- const renderCaptcha = () => __async(void 0, null, function* () {
133
- var _a, _b, _c;
134
- (_a = window.captchafox) == null ? void 0 : _a.remove(widgetId);
135
- if (!containerRef || ((_b = containerRef == null ? void 0 : containerRef.children) == null ? void 0 : _b.length) === 1) return;
136
- const newWidgetId = yield (_c = window.captchafox) == null ? void 0 : _c.render(containerRef, {
137
- lang,
138
- sitekey,
139
- mode,
140
- theme,
141
- i18n,
142
- onError,
143
- onFail,
144
- onClose,
145
- onVerify
146
- });
147
- setWidgetId(newWidgetId);
148
- });
146
+ useEffect(() => {
147
+ return () => clearTimeout(executeTimeout.current);
148
+ }, []);
149
149
  useEffect(() => {
150
150
  if (!containerRef) return;
151
151
  if (firstRendered.current) {
@@ -164,6 +164,50 @@ var CaptchaFox = forwardRef(
164
164
  });
165
165
  }
166
166
  }, [containerRef, sitekey, lang, mode]);
167
+ const waitAndExecute = () => {
168
+ return new Promise((resolve, reject) => {
169
+ executeTimeout.current = setTimeout(() => {
170
+ reject(new TimeoutError("Execute timed out"));
171
+ }, executeTimeoutSeconds * 1e3);
172
+ onReady.current = (id) => {
173
+ clearTimeout(executeTimeout.current);
174
+ window.captchafox.execute(id).then(resolve).catch((error) => {
175
+ const errorType = getErrorType(error);
176
+ reject(errorType);
177
+ });
178
+ };
179
+ });
180
+ };
181
+ const getErrorType = (error) => {
182
+ if (error !== "challenge-aborted" && error !== "rate-limited") {
183
+ return new RetryError();
184
+ }
185
+ return error;
186
+ };
187
+ const renderCaptcha = () => __async(void 0, null, function* () {
188
+ var _a, _b, _c;
189
+ (_a = window.captchafox) == null ? void 0 : _a.remove(widgetId);
190
+ if (!containerRef || ((_b = containerRef == null ? void 0 : containerRef.children) == null ? void 0 : _b.length) === 1) return;
191
+ const newWidgetId = yield (_c = window.captchafox) == null ? void 0 : _c.render(containerRef, {
192
+ lang,
193
+ sitekey,
194
+ mode,
195
+ theme,
196
+ i18n,
197
+ onError,
198
+ onFail,
199
+ onClose,
200
+ onVerify
201
+ });
202
+ if (!newWidgetId) {
203
+ return;
204
+ }
205
+ setWidgetId(newWidgetId);
206
+ if (onReady.current) {
207
+ onReady.current(newWidgetId);
208
+ onReady.current = void 0;
209
+ }
210
+ });
167
211
  return /* @__PURE__ */ React.createElement("div", { ref: setContainerRef, id: widgetId, className });
168
212
  }
169
213
  );
@@ -173,5 +217,7 @@ CaptchaFox.displayName = "CaptchaFox";
173
217
  var CAPTCHA_RESPONSE_KEY = "cf-captcha-response";
174
218
  export {
175
219
  CAPTCHA_RESPONSE_KEY,
176
- CaptchaFox
220
+ CaptchaFox,
221
+ RetryError,
222
+ TimeoutError
177
223
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@captchafox/react",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",