@faasjs/react 8.0.0-beta.13 → 8.0.0-beta.15

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/README.md CHANGED
@@ -1,46 +1,5 @@
1
1
  # @faasjs/react
2
2
 
3
- React plugin for FaasJS.
4
-
5
- [![License: MIT](https://img.shields.io/npm/l/@faasjs/react.svg)](https://github.com/faasjs/faasjs/blob/main/packages/react/LICENSE)
6
- [![NPM Version](https://img.shields.io/npm/v/@faasjs/react.svg)](https://www.npmjs.com/package/@faasjs/react)
7
-
8
- Includes browser client utilities (`FaasBrowserClient`, `ResponseError`, `setMock`) and React helpers.
9
-
10
- ## Features
11
-
12
- - Support [FaasJS Request Specifications](https://faasjs.com/guide/request-spec.html).
13
- - Support global and per-request configurations.
14
- - Compatible with [why-did-you-render](https://github.com/welldone-software/why-did-you-render).
15
- - Additional React functions:
16
- - Utils:
17
- - `equal`: Compare two values for deep equality.
18
- - `createSplittingContext`: Create a context for code splitting.
19
- - `useSplittingState`: Create splitting states.
20
- - Hooks:
21
- - `useEqualMemoize`: Memoize a value with deep equality.
22
- - `useEqualEffect`: Run an effect with deep equality.
23
- - `useEqualMemo`: Memoize a value with deep equality.
24
- - `useEqualCallback`: Memoize a callback with deep equality.
25
- - `useConstant`: Create a constant value with hooks.
26
- - `usePrevious`: Get the previous value of a state.
27
- - `useStateRef`: Create a state with a ref.
28
- - Components:
29
- - `OptionalWrapper`: Render a component optionally.
30
- - `ErrorBoundary`: Catch errors in the component tree.
31
- - Fetch Data:
32
- - `faas`: Fetch data from FaasJS.
33
- - `useFaas`: Fetch data from FaasJS with hooks.
34
- - `useFaasStream`: Fetch streaming data from FaasJS with hooks.
35
- - `FaasDataWrapper`: Fetch data from FaasJS with a wrapper component.
36
- - `withFaasData`: Fetch data from FaasJS using a higher-order component (HOC).
37
-
38
- ## Install
39
-
40
- ```sh
41
- npm install @faasjs/react react
42
- ```
43
-
44
3
  ## Functions
45
4
 
46
5
  - [createSplittingContext](functions/createSplittingContext.md)
package/dist/index.cjs CHANGED
@@ -1,7 +1,6 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let react = require("react");
3
3
  let react_jsx_runtime = require("react/jsx-runtime");
4
-
5
4
  //#region src/generateId.ts
6
5
  /**
7
6
  * Generate random id with prefix
@@ -18,7 +17,6 @@ function generateId(prefix = "", length = 18) {
18
17
  if (length < 8 || length > 18) throw new Error("Length must be 8 ~ 18");
19
18
  return `${prefix}${Date.now().toString(36).padStart(8, "0")}${Math.random().toString(36).substring(2, length - 6).padEnd(length - 8, "0")}`;
20
19
  }
21
-
22
20
  //#endregion
23
21
  //#region src/browser.ts
24
22
  /**
@@ -41,7 +39,7 @@ function generateId(prefix = "", length = 18) {
41
39
  * @param {ResponseProps<T>} [props] - Response properties including status, headers, body, and data.
42
40
  * All properties are optional with sensible defaults.
43
41
  *
44
- * @remarks
42
+ * Notes:
45
43
  * - status defaults to 200 if data or body is present, 204 otherwise
46
44
  * - body is automatically populated from data if not explicitly provided
47
45
  * - headers defaults to an empty object if not provided
@@ -159,7 +157,7 @@ var Response = class {
159
157
  * including HTTP status code, response headers, response body, and the original error.
160
158
  *
161
159
  * @class ResponseError
162
- * @extends {Error}
160
+ * @augments Error
163
161
  *
164
162
  * @property {number} status - The HTTP status code of the failed response. Defaults to 500 if not provided.
165
163
  * @property {ResponseHeaders} headers - The response headers from the failed request.
@@ -240,7 +238,7 @@ var Response = class {
240
238
  * })
241
239
  * ```
242
240
  *
243
- * @remarks
241
+ * Notes:
244
242
  * - ResponseError is automatically thrown by the action method when the server returns an error (status >= 400)
245
243
  * - The error message from server responses is extracted from body.error.message if available
246
244
  * - When created from an Error object, the original error is preserved in the originalError property
@@ -263,7 +261,7 @@ var ResponseError = class extends Error {
263
261
  message: data,
264
262
  ...options
265
263
  };
266
- else if (data instanceof Error || data?.constructor?.name?.includes("Error")) props = {
264
+ else if (data instanceof Error || typeof data === "object" && data !== null && typeof data.constructor?.name === "string" && data.constructor.name.includes("Error")) props = {
267
265
  message: data.message,
268
266
  originalError: data,
269
267
  ...options
@@ -346,7 +344,7 @@ function setMock(handler) {
346
344
  * - Streaming support for large responses
347
345
  * - Multiple instance support with unique IDs
348
346
  *
349
- * @remarks
347
+ * Notes:
350
348
  * - All requests are POST requests by default
351
349
  * - Automatically adds X-FaasJS-Request-Id header for request tracking
352
350
  * - baseUrl must end with '/' (will throw Error if not)
@@ -490,7 +488,7 @@ var FaasBrowserClient = class {
490
488
  * @throws {ResponseError} When the server returns an error response (status >= 400 or body.error exists)
491
489
  * @throws {NetworkError} When network request fails
492
490
  *
493
- * @remarks
491
+ * Notes:
494
492
  * - All requests are POST requests by default
495
493
  * - Action path is automatically converted to lowercase
496
494
  * - A unique request ID is generated for each request and sent in X-FaasJS-Request-Id header
@@ -649,7 +647,7 @@ var FaasBrowserClient = class {
649
647
  headers,
650
648
  body
651
649
  }));
652
- } catch (_) {
650
+ } catch {
653
651
  return Promise.reject(new ResponseError({
654
652
  message: res,
655
653
  status: response.status,
@@ -661,7 +659,6 @@ var FaasBrowserClient = class {
661
659
  });
662
660
  }
663
661
  };
664
-
665
662
  //#endregion
666
663
  //#region src/faas.ts
667
664
  /**
@@ -687,7 +684,6 @@ async function faas(action, params, options) {
687
684
  });
688
685
  return client.browserClient.action(action, params, options);
689
686
  }
690
-
691
687
  //#endregion
692
688
  //#region src/equal.ts
693
689
  const AsyncFunction = (async () => {}).constructor;
@@ -737,13 +733,18 @@ function equal(a, b) {
737
733
  * @returns The memoized value.
738
734
  */
739
735
  function useEqualMemoize(value) {
736
+ const ref = (0, react.useRef)(value);
737
+ if (!equal(value, ref.current)) ref.current = value;
738
+ return ref.current;
739
+ }
740
+ function useEqualSignal(value) {
740
741
  const ref = (0, react.useRef)(value);
741
742
  const signalRef = (0, react.useRef)(0);
742
743
  if (!equal(value, ref.current)) {
743
744
  ref.current = value;
744
745
  signalRef.current += 1;
745
746
  }
746
- return (0, react.useMemo)(() => ref.current, [signalRef.current]);
747
+ return signalRef.current;
747
748
  }
748
749
  /**
749
750
  * Custom hook that works like `useEffect` but uses deep comparison on dependencies.
@@ -753,7 +754,7 @@ function useEqualMemoize(value) {
753
754
  * @returns The result of the `useEffect` hook with memoized dependencies.
754
755
  */
755
756
  function useEqualEffect(callback, dependencies) {
756
- return (0, react.useEffect)(callback, useEqualMemoize(dependencies));
757
+ return (0, react.useEffect)(callback, [useEqualSignal(dependencies)]);
757
758
  }
758
759
  /**
759
760
  * Custom hook that works like `useMemo` but uses deep comparison on dependencies.
@@ -763,7 +764,12 @@ function useEqualEffect(callback, dependencies) {
763
764
  * @returns The result of the `useMemo` hook with memoized dependencies.
764
765
  */
765
766
  function useEqualMemo(callback, dependencies) {
766
- return (0, react.useMemo)(callback, useEqualMemoize(dependencies));
767
+ const signal = useEqualSignal(dependencies);
768
+ const callbackRef = (0, react.useRef)(callback);
769
+ callbackRef.current = callback;
770
+ return (0, react.useMemo)(() => {
771
+ return callbackRef.current();
772
+ }, [signal]);
767
773
  }
768
774
  /**
769
775
  * Custom hook that works like `useCallback` but uses deep comparison on dependencies.
@@ -773,9 +779,8 @@ function useEqualMemo(callback, dependencies) {
773
779
  * @returns The result of the `useCallback` hook with memoized dependencies.
774
780
  */
775
781
  function useEqualCallback(callback, dependencies) {
776
- return (0, react.useCallback)((...args) => callback(...args), useEqualMemoize(dependencies));
782
+ return (0, react.useCallback)((...args) => callback(...args), [useEqualSignal(dependencies)]);
777
783
  }
778
-
779
784
  //#endregion
780
785
  //#region src/FaasDataWrapper.tsx
781
786
  const fixedForwardRef = react.forwardRef;
@@ -823,7 +828,6 @@ function withFaasData(Component, faasProps) {
823
828
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...props })
824
829
  });
825
830
  }
826
-
827
831
  //#endregion
828
832
  //#region src/useFaas.tsx
829
833
  /**
@@ -877,7 +881,8 @@ function useFaas(action, defaultParams, options = {}) {
877
881
  const nextData = r.data;
878
882
  setFails(0);
879
883
  setError(null);
880
- options.setData ? options.setData(nextData) : localSetData(nextData);
884
+ if (options.setData) options.setData(nextData);
885
+ else localSetData(nextData);
881
886
  setLoading(false);
882
887
  for (const { resolve } of pendingReloadsRef.current.values()) resolve(nextData);
883
888
  pendingReloadsRef.current.clear();
@@ -951,7 +956,6 @@ function useFaas(action, defaultParams, options = {}) {
951
956
  setError
952
957
  };
953
958
  }
954
-
955
959
  //#endregion
956
960
  //#region src/client.tsx
957
961
  const clients = {};
@@ -1012,7 +1016,6 @@ function getClient(host) {
1012
1016
  }
1013
1017
  return client;
1014
1018
  }
1015
-
1016
1019
  //#endregion
1017
1020
  //#region src/constant.ts
1018
1021
  /**
@@ -1023,7 +1026,6 @@ function useConstant(fn) {
1023
1026
  if (!ref.current) ref.current = { v: fn() };
1024
1027
  return ref.current.v;
1025
1028
  }
1026
-
1027
1029
  //#endregion
1028
1030
  //#region src/ErrorBoundary.tsx
1029
1031
  var ErrorBoundary = class extends react.Component {
@@ -1058,7 +1060,6 @@ var ErrorBoundary = class extends react.Component {
1058
1060
  return this.props.children ?? null;
1059
1061
  }
1060
1062
  };
1061
-
1062
1063
  //#endregion
1063
1064
  //#region src/useStateRef.ts
1064
1065
  /**
@@ -1095,7 +1096,6 @@ function useStateRef(initialValue) {
1095
1096
  ref
1096
1097
  ];
1097
1098
  }
1098
-
1099
1099
  //#endregion
1100
1100
  //#region src/splittingState.tsx
1101
1101
  /**
@@ -1124,7 +1124,6 @@ function useSplittingState(initialStates) {
1124
1124
  }
1125
1125
  return states;
1126
1126
  }
1127
-
1128
1127
  //#endregion
1129
1128
  //#region src/splittingContext.tsx
1130
1129
  /**
@@ -1207,7 +1206,6 @@ function createSplittingContext(defaultValue) {
1207
1206
  use
1208
1207
  };
1209
1208
  }
1210
-
1211
1209
  //#endregion
1212
1210
  //#region src/Form/context.tsx
1213
1211
  const FormContext = createSplittingContext([
@@ -1226,7 +1224,6 @@ const FormContext = createSplittingContext([
1226
1224
  ]);
1227
1225
  const FormContextProvider = FormContext.Provider;
1228
1226
  const useFormContext = FormContext.use;
1229
-
1230
1227
  //#endregion
1231
1228
  //#region src/Form/Input.tsx
1232
1229
  function processValue(input, rules) {
@@ -1259,7 +1256,6 @@ function FormInput({ name, rules, ...rest }) {
1259
1256
  });
1260
1257
  }
1261
1258
  FormInput.displayName = "FormInput";
1262
-
1263
1259
  //#endregion
1264
1260
  //#region src/Form/Item.tsx
1265
1261
  function FormItem(props) {
@@ -1276,7 +1272,6 @@ function FormItem(props) {
1276
1272
  });
1277
1273
  }
1278
1274
  FormItem.displayName = "FormItem";
1279
-
1280
1275
  //#endregion
1281
1276
  //#region src/Form/Body.tsx
1282
1277
  function FormBody() {
@@ -1284,7 +1279,6 @@ function FormBody() {
1284
1279
  return items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FormItem, { ...item }, item.name));
1285
1280
  }
1286
1281
  FormBody.displayName = "FormBody";
1287
-
1288
1282
  //#endregion
1289
1283
  //#region src/Form/elements/Button.tsx
1290
1284
  const FormButtonElement = (0, react.forwardRef)(({ children, submit, submitting, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -1296,7 +1290,6 @@ const FormButtonElement = (0, react.forwardRef)(({ children, submit, submitting,
1296
1290
  children
1297
1291
  }));
1298
1292
  FormButtonElement.displayName = "FormButtonElement";
1299
-
1300
1293
  //#endregion
1301
1294
  //#region src/Form/elements/Input.tsx
1302
1295
  const FormInputElement = (0, react.forwardRef)(({ onChange, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -1305,7 +1298,6 @@ const FormInputElement = (0, react.forwardRef)(({ onChange, ...props }, ref) =>
1305
1298
  ref
1306
1299
  }));
1307
1300
  FormInputElement.displayName = "FormInputElement";
1308
-
1309
1301
  //#endregion
1310
1302
  //#region src/Form/elements/Label.tsx
1311
1303
  const FormLabelElement = ({ name, title, description, error, children }) => {
@@ -1320,7 +1312,6 @@ const FormLabelElement = ({ name, title, description, error, children }) => {
1320
1312
  ] });
1321
1313
  };
1322
1314
  FormLabelElement.displayName = "FormLabelElement";
1323
-
1324
1315
  //#endregion
1325
1316
  //#region src/Form/elements/index.ts
1326
1317
  const FormDefaultElements = {
@@ -1328,7 +1319,6 @@ const FormDefaultElements = {
1328
1319
  Input: FormInputElement,
1329
1320
  Button: FormButtonElement
1330
1321
  };
1331
-
1332
1322
  //#endregion
1333
1323
  //#region src/Form/rules.ts
1334
1324
  /**
@@ -1366,42 +1356,36 @@ async function validValues(rules, items, values, lang) {
1366
1356
  }
1367
1357
  return errors;
1368
1358
  }
1369
-
1370
1359
  //#endregion
1371
1360
  //#region src/Form/Footer.tsx
1372
1361
  function FormFooter() {
1373
1362
  const { submitting, setSubmitting, onSubmit, valuesRef, Elements, items, setErrors, lang, rules } = useFormContext();
1374
- const handleSubmit = (0, react.useCallback)(async () => {
1375
- setSubmitting(true);
1376
- setErrors({});
1377
- const errors = await validValues(rules, items, valuesRef.current, lang);
1378
- if (Object.keys(errors).length) {
1379
- setErrors(errors);
1380
- setSubmitting(false);
1381
- return;
1382
- }
1383
- onSubmit(valuesRef.current).finally(() => setSubmitting(false));
1384
- }, [
1385
- setSubmitting,
1386
- setErrors,
1387
- rules,
1388
- items,
1389
- lang,
1390
- onSubmit
1391
- ]);
1392
- return (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Elements.Button, {
1363
+ const Button = Elements.Button;
1364
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
1393
1365
  submitting,
1394
- submit: handleSubmit,
1366
+ submit: (0, react.useCallback)(async () => {
1367
+ setSubmitting(true);
1368
+ setErrors({});
1369
+ const errors = await validValues(rules, items, valuesRef.current, lang);
1370
+ if (Object.keys(errors).length) {
1371
+ setErrors(errors);
1372
+ setSubmitting(false);
1373
+ return;
1374
+ }
1375
+ onSubmit(valuesRef.current).finally(() => setSubmitting(false));
1376
+ }, [
1377
+ setSubmitting,
1378
+ setErrors,
1379
+ rules,
1380
+ items,
1381
+ valuesRef,
1382
+ lang,
1383
+ onSubmit
1384
+ ]),
1395
1385
  children: lang.submit
1396
- }), [
1397
- submitting,
1398
- handleSubmit,
1399
- lang.submit,
1400
- Elements.Button
1401
- ]);
1386
+ });
1402
1387
  }
1403
1388
  FormFooter.displayName = "FormFooter";
1404
-
1405
1389
  //#endregion
1406
1390
  //#region src/Form/lang.ts
1407
1391
  const FormDefaultLang = {
@@ -1410,7 +1394,6 @@ const FormDefaultLang = {
1410
1394
  string: "This field must be a string",
1411
1395
  number: "This field must be a number"
1412
1396
  };
1413
-
1414
1397
  //#endregion
1415
1398
  //#region src/Form/Container.tsx
1416
1399
  function mergeValues(items, defaultValues = {}) {
@@ -1470,7 +1453,6 @@ function FormContainer({ defaultValues, Elements, rules, lang, items, ...props }
1470
1453
  });
1471
1454
  }
1472
1455
  FormContainer.displayName = "FormContainer";
1473
-
1474
1456
  //#endregion
1475
1457
  //#region src/OptionalWrapper.tsx
1476
1458
  /**
@@ -1499,7 +1481,6 @@ function OptionalWrapper({ condition, Wrapper, wrapperProps, children }) {
1499
1481
  return children;
1500
1482
  }
1501
1483
  OptionalWrapper.displayName = "OptionalWrapper";
1502
-
1503
1484
  //#endregion
1504
1485
  //#region src/useFaasStream.tsx
1505
1486
  /**
@@ -1645,7 +1626,6 @@ function useFaasStream(action, defaultParams, options = {}) {
1645
1626
  setError
1646
1627
  };
1647
1628
  }
1648
-
1649
1629
  //#endregion
1650
1630
  //#region src/usePrevious.ts
1651
1631
  /**
@@ -1662,7 +1642,6 @@ function usePrevious(value) {
1662
1642
  });
1663
1643
  return ref.current;
1664
1644
  }
1665
-
1666
1645
  //#endregion
1667
1646
  exports.ErrorBoundary = ErrorBoundary;
1668
1647
  exports.FaasBrowserClient = FaasBrowserClient;
@@ -1696,4 +1675,4 @@ exports.usePrevious = usePrevious;
1696
1675
  exports.useSplittingState = useSplittingState;
1697
1676
  exports.useStateRef = useStateRef;
1698
1677
  exports.validValues = validValues;
1699
- exports.withFaasData = withFaasData;
1678
+ exports.withFaasData = withFaasData;
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ declare function generateId(prefix?: string, length?: number): string;
24
24
  * Ensures that base URLs used in FaasJS requests always have a trailing '/' character,
25
25
  * which is required for proper URL construction when appending action paths.
26
26
  *
27
- * @remarks
27
+ * Notes:
28
28
  * - Type only accepts strings ending with '/' (e.g., 'https://api.example.com/', '/')
29
29
  * - Strings without trailing '/' will fail TypeScript type checking
30
30
  * - Used by FaasBrowserClient constructor and Options type
@@ -41,7 +41,7 @@ type BaseUrl = `${string}/`;
41
41
  * Extends the standard RequestInit interface with FaasJS-specific options for
42
42
  * customizing request behavior, adding request hooks, and overriding defaults.
43
43
  *
44
- * @remarks
44
+ * Notes:
45
45
  * - Options can be provided at client creation (defaultOptions) or per-request
46
46
  * - Per-request options override client default options
47
47
  * - headers are merged: per-request headers override default headers
@@ -73,7 +73,7 @@ type BaseUrl = `${string}/`;
73
73
  * Useful for processing large data incrementally or working with binary data streams.
74
74
  * When false or undefined, returns a wrapped Response with automatic JSON parsing.
75
75
  *
76
- * @extends RequestInit
76
+ * @augments RequestInit
77
77
  * @see FaasBrowserClient for client creation
78
78
  * @see Response for response object structure
79
79
  */
@@ -103,7 +103,7 @@ type Options = RequestInit & {
103
103
  * @property {string} [key] - Dynamic string keys for header names (e.g., 'Content-Type', 'Authorization').
104
104
  * Values must be strings. Multiple values for the same key are not supported.
105
105
  *
106
- * @remarks
106
+ * Notes:
107
107
  * - Headers are case-insensitive in HTTP but stored with exact casing in this object
108
108
  * - Common headers include: Content-Type, Authorization, X-Request-Id, X-Custom-Header
109
109
  * - No support for multi-value headers (use comma-separated values instead)
@@ -131,7 +131,7 @@ type ResponseHeaders = {
131
131
  *
132
132
  * @returns {Promise<Response<FaasData<PathOrData>> | Response>} - A Promise resolving to a Response object
133
133
  *
134
- * @remarks
134
+ * Notes:
135
135
  * - Used internally by FaasBrowserClient.action method
136
136
  * - Provides type-safe action method signature
137
137
  * - Return type includes both typed and untyped Response variants
@@ -163,7 +163,7 @@ type FaasBrowserClientAction = <PathOrData extends FaasActionUnionType$1>(action
163
163
  * @property {T} [data] - The parsed JSON data to include in the response.
164
164
  * Optional: contains the response payload when JSON data is provided.
165
165
  *
166
- * @remarks
166
+ * Notes:
167
167
  * - All properties are optional
168
168
  * - At least one of data or body should be provided for meaningful responses
169
169
  * - The Response class automatically defaults status to 200 or 204 based on content
@@ -199,7 +199,7 @@ type ResponseProps<T = any> = {
199
199
  * @param {ResponseProps<T>} [props] - Response properties including status, headers, body, and data.
200
200
  * All properties are optional with sensible defaults.
201
201
  *
202
- * @remarks
202
+ * Notes:
203
203
  * - status defaults to 200 if data or body is present, 204 otherwise
204
204
  * - body is automatically populated from data if not explicitly provided
205
205
  * - headers defaults to an empty object if not provided
@@ -318,7 +318,7 @@ type ResponseErrorProps = {
318
318
  * including HTTP status code, response headers, response body, and the original error.
319
319
  *
320
320
  * @class ResponseError
321
- * @extends {Error}
321
+ * @augments Error
322
322
  *
323
323
  * @property {number} status - The HTTP status code of the failed response. Defaults to 500 if not provided.
324
324
  * @property {ResponseHeaders} headers - The response headers from the failed request.
@@ -399,7 +399,7 @@ type ResponseErrorProps = {
399
399
  * })
400
400
  * ```
401
401
  *
402
- * @remarks
402
+ * Notes:
403
403
  * - ResponseError is automatically thrown by the action method when the server returns an error (status >= 400)
404
404
  * - The error message from server responses is extracted from body.error.message if available
405
405
  * - When created from an Error object, the original error is preserved in the originalError property
@@ -441,7 +441,7 @@ declare class ResponseError extends Error {
441
441
  * - void: Returns an empty response (204 No Content)
442
442
  * - Error: Throws ResponseError when returning an Error object
443
443
  *
444
- * @remarks
444
+ * Notes:
445
445
  * - Used by setMock() function to mock API calls during tests
446
446
  * - Affects all FaasBrowserClient instances when set globally
447
447
  * - Can return different responses based on action or params
@@ -568,7 +568,7 @@ declare function setMock(handler: MockHandler | ResponseProps | Response | null)
568
568
  * - Streaming support for large responses
569
569
  * - Multiple instance support with unique IDs
570
570
  *
571
- * @remarks
571
+ * Notes:
572
572
  * - All requests are POST requests by default
573
573
  * - Automatically adds X-FaasJS-Request-Id header for request tracking
574
574
  * - baseUrl must end with '/' (will throw Error if not)
@@ -706,7 +706,7 @@ declare class FaasBrowserClient {
706
706
  * @throws {ResponseError} When the server returns an error response (status >= 400 or body.error exists)
707
707
  * @throws {NetworkError} When network request fails
708
708
  *
709
- * @remarks
709
+ * Notes:
710
710
  * - All requests are POST requests by default
711
711
  * - Action path is automatically converted to lowercase
712
712
  * - A unique request ID is generated for each request and sent in X-FaasJS-Request-Id header
@@ -971,7 +971,7 @@ declare class ErrorBoundary extends Component<ErrorBoundaryProps, {
971
971
  static displayName: string;
972
972
  constructor(props: ErrorBoundaryProps);
973
973
  componentDidCatch(error: Error, info: ErrorInfo): void;
974
- render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime0.JSX.Element | null;
974
+ render(): string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null;
975
975
  }
976
976
  //#endregion
977
977
  //#region src/equal.d.ts
@@ -1228,13 +1228,13 @@ type FormContextProps<Values extends Record<string, any> = Record<string, any>,
1228
1228
  setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
1229
1229
  valuesRef: RefObject<Values>;
1230
1230
  };
1231
- declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>(props: {
1231
+ declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>(this: void, props: {
1232
1232
  value?: Partial<NewT>;
1233
1233
  children: react.ReactNode;
1234
1234
  memo?: true | any[];
1235
1235
  initializeStates?: Partial<NewT>;
1236
1236
  }) => react.ReactNode;
1237
- declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>() => Readonly<NewT>;
1237
+ declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>(this: void) => Readonly<NewT>;
1238
1238
  //#endregion
1239
1239
  //#region src/OptionalWrapper.d.ts
1240
1240
  type OptionalWrapperProps<TWrapper extends ComponentType<{
@@ -1268,7 +1268,7 @@ declare function OptionalWrapper({
1268
1268
  Wrapper,
1269
1269
  wrapperProps,
1270
1270
  children
1271
- }: OptionalWrapperProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime0.JSX.Element | null | undefined;
1271
+ }: OptionalWrapperProps): string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
1272
1272
  declare namespace OptionalWrapper {
1273
1273
  var displayName: string;
1274
1274
  }
@@ -1337,7 +1337,7 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
1337
1337
  * }
1338
1338
  * ```
1339
1339
  */
1340
- Provider<NewT extends T = T>(props: {
1340
+ Provider<NewT extends T = T>(this: void, props: {
1341
1341
  value?: Partial<NewT>;
1342
1342
  children: ReactNode;
1343
1343
  /**
@@ -1378,7 +1378,7 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
1378
1378
  * }
1379
1379
  * ```
1380
1380
  */
1381
- use: <NewT extends T = T>() => Readonly<NewT>;
1381
+ use: <NewT extends T = T>(this: void) => Readonly<NewT>;
1382
1382
  };
1383
1383
  //#endregion
1384
1384
  //#region src/splittingState.d.ts
@@ -1487,4 +1487,4 @@ declare function usePrevious<T = any>(value: T): T | undefined;
1487
1487
  */
1488
1488
  declare function useStateRef<T = any>(initialValue?: T): [T | null, Dispatch<SetStateAction<T | null>>, RefObject<T | null>];
1489
1489
  //#endregion
1490
- export { BaseUrl, ErrorBoundary, ErrorBoundaryProps, ErrorChildrenProps, type FaasAction, type FaasActionUnionType, FaasBrowserClient, FaasBrowserClientAction, type FaasData, FaasDataInjection, FaasDataWrapper, FaasDataWrapperProps, FaasDataWrapperRef, type FaasParams, FaasReactClient, FaasReactClientInstance, FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, FormContextProps, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, FormDefaultRulesOptions, FormElementTypes, FormInput, type FormInputElementProps, FormInputProps, FormItem, FormItemName, FormItemProps, type FormLabelElementProps, FormLang, type FormProps, FormRule, FormRules, InferFormInputProps, InferFormRulesOptions, InferRuleOption, MockHandler, OnError, OptionalWrapper, OptionalWrapperProps, Options, Response, ResponseError, ResponseErrorProps, ResponseHeaders, ResponseProps, StateSetters, StatesWithSetters, UseFaasStreamOptions, UseFaasStreamResult, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasOptions, useFaasStream, useFormContext, usePrevious, useSplittingState, useStateRef, validValues, withFaasData };
1490
+ export { BaseUrl, ErrorBoundary, ErrorBoundaryProps, ErrorChildrenProps, type FaasAction, type FaasActionUnionType, FaasBrowserClient, FaasBrowserClientAction, type FaasData, FaasDataInjection, FaasDataWrapper, FaasDataWrapperProps, FaasDataWrapperRef, type FaasParams, FaasReactClient, FaasReactClientInstance, FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, FormContextProps, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, FormDefaultRulesOptions, FormElementTypes, FormInput, type FormInputElementProps, FormInputProps, FormItem, FormItemName, FormItemProps, type FormLabelElementProps, FormLang, FormProps, FormRule, FormRules, InferFormInputProps, InferFormRulesOptions, InferRuleOption, MockHandler, OnError, OptionalWrapper, OptionalWrapperProps, Options, Response, ResponseError, ResponseErrorProps, ResponseHeaders, ResponseProps, StateSetters, StatesWithSetters, UseFaasStreamOptions, UseFaasStreamResult, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasOptions, useFaasStream, useFormContext, usePrevious, useSplittingState, useStateRef, validValues, withFaasData };
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Component, cloneElement, createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
-
4
3
  //#region src/generateId.ts
5
4
  /**
6
5
  * Generate random id with prefix
@@ -17,7 +16,6 @@ function generateId(prefix = "", length = 18) {
17
16
  if (length < 8 || length > 18) throw new Error("Length must be 8 ~ 18");
18
17
  return `${prefix}${Date.now().toString(36).padStart(8, "0")}${Math.random().toString(36).substring(2, length - 6).padEnd(length - 8, "0")}`;
19
18
  }
20
-
21
19
  //#endregion
22
20
  //#region src/browser.ts
23
21
  /**
@@ -40,7 +38,7 @@ function generateId(prefix = "", length = 18) {
40
38
  * @param {ResponseProps<T>} [props] - Response properties including status, headers, body, and data.
41
39
  * All properties are optional with sensible defaults.
42
40
  *
43
- * @remarks
41
+ * Notes:
44
42
  * - status defaults to 200 if data or body is present, 204 otherwise
45
43
  * - body is automatically populated from data if not explicitly provided
46
44
  * - headers defaults to an empty object if not provided
@@ -158,7 +156,7 @@ var Response = class {
158
156
  * including HTTP status code, response headers, response body, and the original error.
159
157
  *
160
158
  * @class ResponseError
161
- * @extends {Error}
159
+ * @augments Error
162
160
  *
163
161
  * @property {number} status - The HTTP status code of the failed response. Defaults to 500 if not provided.
164
162
  * @property {ResponseHeaders} headers - The response headers from the failed request.
@@ -239,7 +237,7 @@ var Response = class {
239
237
  * })
240
238
  * ```
241
239
  *
242
- * @remarks
240
+ * Notes:
243
241
  * - ResponseError is automatically thrown by the action method when the server returns an error (status >= 400)
244
242
  * - The error message from server responses is extracted from body.error.message if available
245
243
  * - When created from an Error object, the original error is preserved in the originalError property
@@ -262,7 +260,7 @@ var ResponseError = class extends Error {
262
260
  message: data,
263
261
  ...options
264
262
  };
265
- else if (data instanceof Error || data?.constructor?.name?.includes("Error")) props = {
263
+ else if (data instanceof Error || typeof data === "object" && data !== null && typeof data.constructor?.name === "string" && data.constructor.name.includes("Error")) props = {
266
264
  message: data.message,
267
265
  originalError: data,
268
266
  ...options
@@ -345,7 +343,7 @@ function setMock(handler) {
345
343
  * - Streaming support for large responses
346
344
  * - Multiple instance support with unique IDs
347
345
  *
348
- * @remarks
346
+ * Notes:
349
347
  * - All requests are POST requests by default
350
348
  * - Automatically adds X-FaasJS-Request-Id header for request tracking
351
349
  * - baseUrl must end with '/' (will throw Error if not)
@@ -489,7 +487,7 @@ var FaasBrowserClient = class {
489
487
  * @throws {ResponseError} When the server returns an error response (status >= 400 or body.error exists)
490
488
  * @throws {NetworkError} When network request fails
491
489
  *
492
- * @remarks
490
+ * Notes:
493
491
  * - All requests are POST requests by default
494
492
  * - Action path is automatically converted to lowercase
495
493
  * - A unique request ID is generated for each request and sent in X-FaasJS-Request-Id header
@@ -648,7 +646,7 @@ var FaasBrowserClient = class {
648
646
  headers,
649
647
  body
650
648
  }));
651
- } catch (_) {
649
+ } catch {
652
650
  return Promise.reject(new ResponseError({
653
651
  message: res,
654
652
  status: response.status,
@@ -660,7 +658,6 @@ var FaasBrowserClient = class {
660
658
  });
661
659
  }
662
660
  };
663
-
664
661
  //#endregion
665
662
  //#region src/faas.ts
666
663
  /**
@@ -686,7 +683,6 @@ async function faas(action, params, options) {
686
683
  });
687
684
  return client.browserClient.action(action, params, options);
688
685
  }
689
-
690
686
  //#endregion
691
687
  //#region src/equal.ts
692
688
  const AsyncFunction = (async () => {}).constructor;
@@ -736,13 +732,18 @@ function equal(a, b) {
736
732
  * @returns The memoized value.
737
733
  */
738
734
  function useEqualMemoize(value) {
735
+ const ref = useRef(value);
736
+ if (!equal(value, ref.current)) ref.current = value;
737
+ return ref.current;
738
+ }
739
+ function useEqualSignal(value) {
739
740
  const ref = useRef(value);
740
741
  const signalRef = useRef(0);
741
742
  if (!equal(value, ref.current)) {
742
743
  ref.current = value;
743
744
  signalRef.current += 1;
744
745
  }
745
- return useMemo(() => ref.current, [signalRef.current]);
746
+ return signalRef.current;
746
747
  }
747
748
  /**
748
749
  * Custom hook that works like `useEffect` but uses deep comparison on dependencies.
@@ -752,7 +753,7 @@ function useEqualMemoize(value) {
752
753
  * @returns The result of the `useEffect` hook with memoized dependencies.
753
754
  */
754
755
  function useEqualEffect(callback, dependencies) {
755
- return useEffect(callback, useEqualMemoize(dependencies));
756
+ return useEffect(callback, [useEqualSignal(dependencies)]);
756
757
  }
757
758
  /**
758
759
  * Custom hook that works like `useMemo` but uses deep comparison on dependencies.
@@ -762,7 +763,12 @@ function useEqualEffect(callback, dependencies) {
762
763
  * @returns The result of the `useMemo` hook with memoized dependencies.
763
764
  */
764
765
  function useEqualMemo(callback, dependencies) {
765
- return useMemo(callback, useEqualMemoize(dependencies));
766
+ const signal = useEqualSignal(dependencies);
767
+ const callbackRef = useRef(callback);
768
+ callbackRef.current = callback;
769
+ return useMemo(() => {
770
+ return callbackRef.current();
771
+ }, [signal]);
766
772
  }
767
773
  /**
768
774
  * Custom hook that works like `useCallback` but uses deep comparison on dependencies.
@@ -772,13 +778,9 @@ function useEqualMemo(callback, dependencies) {
772
778
  * @returns The result of the `useCallback` hook with memoized dependencies.
773
779
  */
774
780
  function useEqualCallback(callback, dependencies) {
775
- return useCallback((...args) => callback(...args), useEqualMemoize(dependencies));
781
+ return useCallback((...args) => callback(...args), [useEqualSignal(dependencies)]);
776
782
  }
777
-
778
- //#endregion
779
- //#region src/FaasDataWrapper.tsx
780
- const fixedForwardRef = forwardRef;
781
- const FaasDataWrapper = fixedForwardRef((props, ref) => {
783
+ const FaasDataWrapper = forwardRef((props, ref) => {
782
784
  const requestOptions = {
783
785
  ...props.data !== void 0 ? { data: props.data } : {},
784
786
  ...props.setData ? { setData: props.setData } : {}
@@ -822,7 +824,6 @@ function withFaasData(Component, faasProps) {
822
824
  children: /* @__PURE__ */ jsx(Component, { ...props })
823
825
  });
824
826
  }
825
-
826
827
  //#endregion
827
828
  //#region src/useFaas.tsx
828
829
  /**
@@ -876,7 +877,8 @@ function useFaas(action, defaultParams, options = {}) {
876
877
  const nextData = r.data;
877
878
  setFails(0);
878
879
  setError(null);
879
- options.setData ? options.setData(nextData) : localSetData(nextData);
880
+ if (options.setData) options.setData(nextData);
881
+ else localSetData(nextData);
880
882
  setLoading(false);
881
883
  for (const { resolve } of pendingReloadsRef.current.values()) resolve(nextData);
882
884
  pendingReloadsRef.current.clear();
@@ -950,7 +952,6 @@ function useFaas(action, defaultParams, options = {}) {
950
952
  setError
951
953
  };
952
954
  }
953
-
954
955
  //#endregion
955
956
  //#region src/client.tsx
956
957
  const clients = {};
@@ -1011,7 +1012,6 @@ function getClient(host) {
1011
1012
  }
1012
1013
  return client;
1013
1014
  }
1014
-
1015
1015
  //#endregion
1016
1016
  //#region src/constant.ts
1017
1017
  /**
@@ -1022,7 +1022,6 @@ function useConstant(fn) {
1022
1022
  if (!ref.current) ref.current = { v: fn() };
1023
1023
  return ref.current.v;
1024
1024
  }
1025
-
1026
1025
  //#endregion
1027
1026
  //#region src/ErrorBoundary.tsx
1028
1027
  var ErrorBoundary = class extends Component {
@@ -1057,7 +1056,6 @@ var ErrorBoundary = class extends Component {
1057
1056
  return this.props.children ?? null;
1058
1057
  }
1059
1058
  };
1060
-
1061
1059
  //#endregion
1062
1060
  //#region src/useStateRef.ts
1063
1061
  /**
@@ -1094,7 +1092,6 @@ function useStateRef(initialValue) {
1094
1092
  ref
1095
1093
  ];
1096
1094
  }
1097
-
1098
1095
  //#endregion
1099
1096
  //#region src/splittingState.tsx
1100
1097
  /**
@@ -1123,7 +1120,6 @@ function useSplittingState(initialStates) {
1123
1120
  }
1124
1121
  return states;
1125
1122
  }
1126
-
1127
1123
  //#endregion
1128
1124
  //#region src/splittingContext.tsx
1129
1125
  /**
@@ -1206,7 +1202,6 @@ function createSplittingContext(defaultValue) {
1206
1202
  use
1207
1203
  };
1208
1204
  }
1209
-
1210
1205
  //#endregion
1211
1206
  //#region src/Form/context.tsx
1212
1207
  const FormContext = createSplittingContext([
@@ -1225,7 +1220,6 @@ const FormContext = createSplittingContext([
1225
1220
  ]);
1226
1221
  const FormContextProvider = FormContext.Provider;
1227
1222
  const useFormContext = FormContext.use;
1228
-
1229
1223
  //#endregion
1230
1224
  //#region src/Form/Input.tsx
1231
1225
  function processValue(input, rules) {
@@ -1258,7 +1252,6 @@ function FormInput({ name, rules, ...rest }) {
1258
1252
  });
1259
1253
  }
1260
1254
  FormInput.displayName = "FormInput";
1261
-
1262
1255
  //#endregion
1263
1256
  //#region src/Form/Item.tsx
1264
1257
  function FormItem(props) {
@@ -1275,7 +1268,6 @@ function FormItem(props) {
1275
1268
  });
1276
1269
  }
1277
1270
  FormItem.displayName = "FormItem";
1278
-
1279
1271
  //#endregion
1280
1272
  //#region src/Form/Body.tsx
1281
1273
  function FormBody() {
@@ -1283,7 +1275,6 @@ function FormBody() {
1283
1275
  return items.map((item) => /* @__PURE__ */ jsx(FormItem, { ...item }, item.name));
1284
1276
  }
1285
1277
  FormBody.displayName = "FormBody";
1286
-
1287
1278
  //#endregion
1288
1279
  //#region src/Form/elements/Button.tsx
1289
1280
  const FormButtonElement = forwardRef(({ children, submit, submitting, ...props }, ref) => /* @__PURE__ */ jsx("button", {
@@ -1295,7 +1286,6 @@ const FormButtonElement = forwardRef(({ children, submit, submitting, ...props }
1295
1286
  children
1296
1287
  }));
1297
1288
  FormButtonElement.displayName = "FormButtonElement";
1298
-
1299
1289
  //#endregion
1300
1290
  //#region src/Form/elements/Input.tsx
1301
1291
  const FormInputElement = forwardRef(({ onChange, ...props }, ref) => /* @__PURE__ */ jsx("input", {
@@ -1304,7 +1294,6 @@ const FormInputElement = forwardRef(({ onChange, ...props }, ref) => /* @__PURE_
1304
1294
  ref
1305
1295
  }));
1306
1296
  FormInputElement.displayName = "FormInputElement";
1307
-
1308
1297
  //#endregion
1309
1298
  //#region src/Form/elements/Label.tsx
1310
1299
  const FormLabelElement = ({ name, title, description, error, children }) => {
@@ -1319,7 +1308,6 @@ const FormLabelElement = ({ name, title, description, error, children }) => {
1319
1308
  ] });
1320
1309
  };
1321
1310
  FormLabelElement.displayName = "FormLabelElement";
1322
-
1323
1311
  //#endregion
1324
1312
  //#region src/Form/elements/index.ts
1325
1313
  const FormDefaultElements = {
@@ -1327,7 +1315,6 @@ const FormDefaultElements = {
1327
1315
  Input: FormInputElement,
1328
1316
  Button: FormButtonElement
1329
1317
  };
1330
-
1331
1318
  //#endregion
1332
1319
  //#region src/Form/rules.ts
1333
1320
  /**
@@ -1365,42 +1352,36 @@ async function validValues(rules, items, values, lang) {
1365
1352
  }
1366
1353
  return errors;
1367
1354
  }
1368
-
1369
1355
  //#endregion
1370
1356
  //#region src/Form/Footer.tsx
1371
1357
  function FormFooter() {
1372
1358
  const { submitting, setSubmitting, onSubmit, valuesRef, Elements, items, setErrors, lang, rules } = useFormContext();
1373
- const handleSubmit = useCallback(async () => {
1374
- setSubmitting(true);
1375
- setErrors({});
1376
- const errors = await validValues(rules, items, valuesRef.current, lang);
1377
- if (Object.keys(errors).length) {
1378
- setErrors(errors);
1379
- setSubmitting(false);
1380
- return;
1381
- }
1382
- onSubmit(valuesRef.current).finally(() => setSubmitting(false));
1383
- }, [
1384
- setSubmitting,
1385
- setErrors,
1386
- rules,
1387
- items,
1388
- lang,
1389
- onSubmit
1390
- ]);
1391
- return useMemo(() => /* @__PURE__ */ jsx(Elements.Button, {
1359
+ const Button = Elements.Button;
1360
+ return /* @__PURE__ */ jsx(Button, {
1392
1361
  submitting,
1393
- submit: handleSubmit,
1362
+ submit: useCallback(async () => {
1363
+ setSubmitting(true);
1364
+ setErrors({});
1365
+ const errors = await validValues(rules, items, valuesRef.current, lang);
1366
+ if (Object.keys(errors).length) {
1367
+ setErrors(errors);
1368
+ setSubmitting(false);
1369
+ return;
1370
+ }
1371
+ onSubmit(valuesRef.current).finally(() => setSubmitting(false));
1372
+ }, [
1373
+ setSubmitting,
1374
+ setErrors,
1375
+ rules,
1376
+ items,
1377
+ valuesRef,
1378
+ lang,
1379
+ onSubmit
1380
+ ]),
1394
1381
  children: lang.submit
1395
- }), [
1396
- submitting,
1397
- handleSubmit,
1398
- lang.submit,
1399
- Elements.Button
1400
- ]);
1382
+ });
1401
1383
  }
1402
1384
  FormFooter.displayName = "FormFooter";
1403
-
1404
1385
  //#endregion
1405
1386
  //#region src/Form/lang.ts
1406
1387
  const FormDefaultLang = {
@@ -1409,7 +1390,6 @@ const FormDefaultLang = {
1409
1390
  string: "This field must be a string",
1410
1391
  number: "This field must be a number"
1411
1392
  };
1412
-
1413
1393
  //#endregion
1414
1394
  //#region src/Form/Container.tsx
1415
1395
  function mergeValues(items, defaultValues = {}) {
@@ -1469,7 +1449,6 @@ function FormContainer({ defaultValues, Elements, rules, lang, items, ...props }
1469
1449
  });
1470
1450
  }
1471
1451
  FormContainer.displayName = "FormContainer";
1472
-
1473
1452
  //#endregion
1474
1453
  //#region src/OptionalWrapper.tsx
1475
1454
  /**
@@ -1498,7 +1477,6 @@ function OptionalWrapper({ condition, Wrapper, wrapperProps, children }) {
1498
1477
  return children;
1499
1478
  }
1500
1479
  OptionalWrapper.displayName = "OptionalWrapper";
1501
-
1502
1480
  //#endregion
1503
1481
  //#region src/useFaasStream.tsx
1504
1482
  /**
@@ -1644,7 +1622,6 @@ function useFaasStream(action, defaultParams, options = {}) {
1644
1622
  setError
1645
1623
  };
1646
1624
  }
1647
-
1648
1625
  //#endregion
1649
1626
  //#region src/usePrevious.ts
1650
1627
  /**
@@ -1661,6 +1638,5 @@ function usePrevious(value) {
1661
1638
  });
1662
1639
  return ref.current;
1663
1640
  }
1664
-
1665
1641
  //#endregion
1666
- export { ErrorBoundary, FaasBrowserClient, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, FormInput, FormItem, OptionalWrapper, Response, ResponseError, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasStream, useFormContext, usePrevious, useSplittingState, useStateRef, validValues, withFaasData };
1642
+ export { ErrorBoundary, FaasBrowserClient, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, FormInput, FormItem, OptionalWrapper, Response, ResponseError, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasStream, useFormContext, usePrevious, useSplittingState, useStateRef, validValues, withFaasData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faasjs/react",
3
- "version": "8.0.0-beta.13",
3
+ "version": "8.0.0-beta.15",
4
4
  "homepage": "https://faasjs.com/doc/react/",
5
5
  "bugs": {
6
6
  "url": "https://github.com/faasjs/faasjs/issues"
@@ -26,16 +26,13 @@
26
26
  "require": "./dist/index.cjs"
27
27
  }
28
28
  },
29
- "scripts": {
30
- "build": "tsdown src/index.ts --config ../../tsdown.config.ts --external react --dts.eager --no-sourcemap --no-dts.sourcemap"
31
- },
32
29
  "devDependencies": {
33
- "@faasjs/types": ">=8.0.0-beta.13",
30
+ "@faasjs/types": ">=8.0.0-beta.15",
34
31
  "@types/react": "^19.0.0",
35
32
  "react": "^19.0.0"
36
33
  },
37
34
  "peerDependencies": {
38
- "@faasjs/types": ">=8.0.0-beta.13"
35
+ "@faasjs/types": ">=8.0.0-beta.15"
39
36
  },
40
37
  "engines": {
41
38
  "node": ">=24.0.0",