@molecule/app-react 1.7.1 → 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/README.md CHANGED
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-21T17:02:37.827Z
6
+ Generated: 2026-10-22T07:22:55.793Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-react
@@ -365,7 +365,13 @@ interface FormController<T extends Record<string, unknown> = Record<string, unkn
365
365
  */
366
366
  validate(): Promise<boolean>
367
367
  /**
368
- * Resets the form to initial values.
368
+ * Resets the form and clears errors, touched fields and submission state.
369
+ *
370
+ * With no argument it restores the current baseline — the initial
371
+ * `defaultValues`, or the values a previous `reset(values)` established.
372
+ * Passing `values` merges them over the current baseline and makes the
373
+ * result the new baseline, so a form reset to freshly loaded or saved data
374
+ * reads clean (`isDirty === false`).
369
375
  */
370
376
  reset(values?: Partial<T>): void
371
377
  /**
@@ -397,7 +403,8 @@ Form creation options.
397
403
  ```typescript
398
404
  interface FormOptions<T extends Record<string, unknown>> {
399
405
  /**
400
- * Default values.
406
+ * Default values, captured as the form's clean baseline when the controller
407
+ * is created. Mutating this object afterwards does not change the baseline.
401
408
  */
402
409
  defaultValues?: Partial<T>
403
410
  /**
@@ -765,12 +772,18 @@ interface UseDeviceResult {
765
772
 
766
773
  Options for useForm hook.
767
774
 
775
+ Every `FormOptions` field is supported. `createForm` is only an override —
776
+ omit it and the hook creates the controller through the bonded forms
777
+ provider (`createForm` from `@molecule/app-forms`), which uses the built-in
778
+ native provider until the app bonds its own.
779
+
768
780
  ```typescript
769
781
  interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
770
782
  /**
771
- * Form provider's createForm function.
783
+ * Explicit form factory for this one form. Defaults to the bonded forms
784
+ * provider; pass it only to pin a specific provider instance.
772
785
  */
773
- createForm: (options: FormOptions<T>) => FormController<T>
786
+ createForm?: (options: FormOptions<T>) => FormController<T>
774
787
  }
775
788
  ```
776
789
 
@@ -822,6 +835,13 @@ Result of useHttp hook.
822
835
 
823
836
  ```typescript
824
837
  interface UseHttpResult<T> extends UseHttpState<T> {
838
+ /**
839
+ * Runs the request and resolves with its data, or `null` on failure.
840
+ *
841
+ * This function is IDENTITY-STABLE for as long as `method`, `url` and the HTTP
842
+ * client do not change, so it is safe in a `useEffect` dependency array. Its
843
+ * request options are read when it is CALLED, from the latest committed render.
844
+ */
825
845
  execute: () => Promise<T | null>
826
846
  reset: () => void
827
847
  }
@@ -831,6 +851,11 @@ interface UseHttpResult<T> extends UseHttpState<T> {
831
851
 
832
852
  Options for useHttp hook.
833
853
 
854
+ Every request option — headers, params, body `data`, `signal`, `onSuccess`,
855
+ `onError` — is read at the moment `execute` runs, not when the hook rendered,
856
+ so an inline object or callback needs no memoizing. Only `immediate` is read
857
+ on mount.
858
+
834
859
  ```typescript
835
860
  interface UseHttpOptions<T> extends RequestConfig {
836
861
  /**
@@ -1938,11 +1963,15 @@ function useEditor(): UseEditorResult
1938
1963
 
1939
1964
  Hook for form state management.
1940
1965
 
1966
+ Creates its controller through the bonded forms provider, so a React app
1967
+ wires a form library once (`setProvider` from `@molecule/app-forms`) and
1968
+ every form picks it up. Passing `createForm` overrides that for one form.
1969
+
1941
1970
  ```typescript
1942
- function useForm(options: UseFormOptions<T>): UseFormResult<T>
1971
+ function useForm(options?: UseFormOptions<T>): UseFormResult<T>
1943
1972
  ```
1944
1973
 
1945
- - `options` — Form options including createForm from a forms provider
1974
+ - `options` — Form options. `defaultValues`, `mode` and the form-level `validate` are forwarded to the provider; omit the options entirely for a form whose fields are registered with their own defaults.
1946
1975
 
1947
1976
  **Returns:** Form state and methods
1948
1977
 
@@ -1986,6 +2015,15 @@ function useHttpClient(): HttpClient
1986
2015
 
1987
2016
  Hook for making HTTP requests with state management.
1988
2017
 
2018
+ `execute` keeps one identity while `method`, `url` and the HTTP client stay the
2019
+ same — across the hook's own loading/data updates, parent rerenders, and inline
2020
+ options or callbacks — so `useEffect(() => { void execute() }, [execute])`
2021
+ runs once per request target instead of looping. The current headers, body,
2022
+ `signal` and callbacks are read when `execute` is called, so a later manual
2023
+ call always sends what the latest committed render passed. Changing `method`, `url` or
2024
+ the client does replace `execute` (it selects a different request) and
2025
+ re-runs such an effect.
2026
+
1989
2027
  ```typescript
1990
2028
  function useHttp(
1991
2029
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
@@ -1996,7 +2034,7 @@ function useHttp(
1996
2034
 
1997
2035
  - `method` — HTTP method
1998
2036
  - `url` — Request URL
1999
- - `options` — Request options
2037
+ - `options` — Request options, read at call time
2000
2038
 
2001
2039
  **Returns:** Request state and execute function
2002
2040
 
@@ -6,12 +6,18 @@
6
6
  import type { FieldRegistration, FieldState, FormController, FormOptions, FormState, RegisterOptions } from '@molecule/app-forms';
7
7
  /**
8
8
  * Options for useForm hook.
9
+ *
10
+ * Every `FormOptions` field is supported. `createForm` is only an override —
11
+ * omit it and the hook creates the controller through the bonded forms
12
+ * provider (`createForm` from `@molecule/app-forms`), which uses the built-in
13
+ * native provider until the app bonds its own.
9
14
  */
10
15
  export interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
11
16
  /**
12
- * Form provider's createForm function.
17
+ * Explicit form factory for this one form. Defaults to the bonded forms
18
+ * provider; pass it only to pin a specific provider instance.
13
19
  */
14
- createForm: (options: FormOptions<T>) => FormController<T>;
20
+ createForm?: (options: FormOptions<T>) => FormController<T>;
15
21
  }
16
22
  /**
17
23
  * Result of useForm hook.
@@ -36,16 +42,21 @@ export interface UseFormResult<T extends Record<string, unknown>> {
36
42
  /**
37
43
  * Hook for form state management.
38
44
  *
39
- * @param options - Form options including createForm from a forms provider
45
+ * Creates its controller through the bonded forms provider, so a React app
46
+ * wires a form library once (`setProvider` from `@molecule/app-forms`) and
47
+ * every form picks it up. Passing `createForm` overrides that for one form.
48
+ *
49
+ * @param options - Form options. `defaultValues`, `mode` and the form-level
50
+ * `validate` are forwarded to the provider; omit the options entirely for a
51
+ * form whose fields are registered with their own defaults.
40
52
  * @returns Form state and methods
41
53
  *
42
54
  * @example
43
55
  * ```tsx
44
- * import { createForm } from '@molecule/app-forms'
56
+ * import { useForm } from '@molecule/app-react'
45
57
  *
46
58
  * function LoginForm() {
47
59
  * const { register, handleSubmit, formState, isSubmitting } = useForm({
48
- * createForm,
49
60
  * defaultValues: { email: '', password: '' },
50
61
  * })
51
62
  *
@@ -69,7 +80,7 @@ export interface UseFormResult<T extends Record<string, unknown>> {
69
80
  * }
70
81
  * ```
71
82
  */
72
- export declare function useForm<T extends Record<string, unknown>>(options: UseFormOptions<T>): UseFormResult<T>;
83
+ export declare function useForm<T extends Record<string, unknown>>(options?: UseFormOptions<T>): UseFormResult<T>;
73
84
  /**
74
85
  * Hook to watch a specific field value.
75
86
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAkC5B;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,CAAC;IACvF;;OAEG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,CAAA;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE9D,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IAGrB,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,CAAC,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KACxD,iBAAiB,CAAA;IACtB,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9C,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC3D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,GAAG,SAAS,CAAA;IAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;IAC5D,WAAW,EAAE,MAAM,IAAI,CAAA;IAGvB,YAAY,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;IAClG,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,aAAa,CAAC,CAAC,CAAC,CAwElB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,EAC3E,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,CAAC,GACN,CAAC,CAAC,CAAC,CAAC,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,MAAM,CAAC,GACZ,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAGxB"}
1
+ {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAmC5B;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,CAAC;IACvF;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,CAAA;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE9D,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IAGrB,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,CAAC,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KACxD,iBAAiB,CAAA;IACtB,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9C,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC3D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,GAAG,SAAS,CAAA;IAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;IAC5D,WAAW,EAAE,MAAM,IAAI,CAAA;IAGvB,YAAY,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;IAClG,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,OAAO,GAAE,cAAc,CAAC,CAAC,CAAM,GAC9B,aAAa,CAAC,CAAC,CAAC,CAwElB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,EAC3E,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,CAAC,GACN,CAAC,CAAC,CAAC,CAAC,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,MAAM,CAAC,GACZ,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAGxB"}
@@ -4,6 +4,7 @@
4
4
  * @module
5
5
  */
6
6
  import { useCallback, useMemo, useRef, useSyncExternalStore } from 'react';
7
+ import { createForm as createBondedForm } from '@molecule/app-forms';
7
8
  /**
8
9
  * Adapt controller notifications to React's stable snapshot contract. Providers
9
10
  * may return fresh objects from their getters; reads between notifications must
@@ -35,16 +36,21 @@ function useFormSnapshot(form, read) {
35
36
  /**
36
37
  * Hook for form state management.
37
38
  *
38
- * @param options - Form options including createForm from a forms provider
39
+ * Creates its controller through the bonded forms provider, so a React app
40
+ * wires a form library once (`setProvider` from `@molecule/app-forms`) and
41
+ * every form picks it up. Passing `createForm` overrides that for one form.
42
+ *
43
+ * @param options - Form options. `defaultValues`, `mode` and the form-level
44
+ * `validate` are forwarded to the provider; omit the options entirely for a
45
+ * form whose fields are registered with their own defaults.
39
46
  * @returns Form state and methods
40
47
  *
41
48
  * @example
42
49
  * ```tsx
43
- * import { createForm } from '@molecule/app-forms'
50
+ * import { useForm } from '@molecule/app-react'
44
51
  *
45
52
  * function LoginForm() {
46
53
  * const { register, handleSubmit, formState, isSubmitting } = useForm({
47
- * createForm,
48
54
  * defaultValues: { email: '', password: '' },
49
55
  * })
50
56
  *
@@ -68,8 +74,8 @@ function useFormSnapshot(form, read) {
68
74
  * }
69
75
  * ```
70
76
  */
71
- export function useForm(options) {
72
- const { createForm, ...formOptions } = options;
77
+ export function useForm(options = {}) {
78
+ const { createForm = createBondedForm, ...formOptions } = options;
73
79
  // Create form controller once
74
80
  const formRef = useRef(null);
75
81
  if (!formRef.current) {
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.js","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useForm.js","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"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"}
@@ -23,11 +23,23 @@ export interface UseHttpState<T> {
23
23
  * Result of useHttp hook.
24
24
  */
25
25
  export interface UseHttpResult<T> extends UseHttpState<T> {
26
+ /**
27
+ * Runs the request and resolves with its data, or `null` on failure.
28
+ *
29
+ * This function is IDENTITY-STABLE for as long as `method`, `url` and the HTTP
30
+ * client do not change, so it is safe in a `useEffect` dependency array. Its
31
+ * request options are read when it is CALLED, from the latest committed render.
32
+ */
26
33
  execute: () => Promise<T | null>;
27
34
  reset: () => void;
28
35
  }
29
36
  /**
30
37
  * Options for useHttp hook.
38
+ *
39
+ * Every request option — headers, params, body `data`, `signal`, `onSuccess`,
40
+ * `onError` — is read at the moment `execute` runs, not when the hook rendered,
41
+ * so an inline object or callback needs no memoizing. Only `immediate` is read
42
+ * on mount.
31
43
  */
32
44
  export interface UseHttpOptions<T> extends RequestConfig {
33
45
  /**
@@ -46,9 +58,18 @@ export interface UseHttpOptions<T> extends RequestConfig {
46
58
  /**
47
59
  * Hook for making HTTP requests with state management.
48
60
  *
61
+ * `execute` keeps one identity while `method`, `url` and the HTTP client stay the
62
+ * same — across the hook's own loading/data updates, parent rerenders, and inline
63
+ * options or callbacks — so `useEffect(() => { void execute() }, [execute])`
64
+ * runs once per request target instead of looping. The current headers, body,
65
+ * `signal` and callbacks are read when `execute` is called, so a later manual
66
+ * call always sends what the latest committed render passed. Changing `method`, `url` or
67
+ * the client does replace `execute` (it selects a different request) and
68
+ * re-runs such an effect.
69
+ *
49
70
  * @param method - HTTP method
50
71
  * @param url - Request URL
51
- * @param options - Request options
72
+ * @param options - Request options, read at call time
52
73
  * @returns Request state and execute function
53
74
  *
54
75
  * @example
@@ -56,8 +77,8 @@ export interface UseHttpOptions<T> extends RequestConfig {
56
77
  * const { data, loading, error, execute } = useHttp<User[]>('GET', '/api/users')
57
78
  *
58
79
  * useEffect(() => {
59
- * execute()
60
- * }, [])
80
+ * void execute()
81
+ * }, [execute])
61
82
  *
62
83
  * if (loading) return <Spinner />
63
84
  * if (error) return <Error message={error.message} />
@@ -1 +1 @@
1
- {"version":3,"file":"useHttp.d.ts","sourceRoot":"","sources":["../../src/hooks/useHttp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAgB,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAKjF;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAU1C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IACvD,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,aAAa;IACtD;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;IAC7B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAC1B,aAAa,CAAC,CAAC,CAAC,CAqFlB;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEtF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEvF"}
1
+ {"version":3,"file":"useHttp.d.ts","sourceRoot":"","sources":["../../src/hooks/useHttp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAgB,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAKjF;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAU1C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IACvD;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,aAAa;IACtD;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;IAC7B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAC1B,aAAa,CAAC,CAAC,CAAC,CAqGlB;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEtF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAEvF"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { useCallback, useContext, useEffect, useRef, useState } from 'react';
6
+ import { useCallback, useContext, useEffect, useInsertionEffect, useRef, useState } from 'react';
7
7
  import { t } from '@molecule/app-i18n';
8
8
  import { HttpContext } from '../contexts.js';
9
9
  /**
@@ -24,9 +24,18 @@ export function useHttpClient() {
24
24
  /**
25
25
  * Hook for making HTTP requests with state management.
26
26
  *
27
+ * `execute` keeps one identity while `method`, `url` and the HTTP client stay the
28
+ * same — across the hook's own loading/data updates, parent rerenders, and inline
29
+ * options or callbacks — so `useEffect(() => { void execute() }, [execute])`
30
+ * runs once per request target instead of looping. The current headers, body,
31
+ * `signal` and callbacks are read when `execute` is called, so a later manual
32
+ * call always sends what the latest committed render passed. Changing `method`, `url` or
33
+ * the client does replace `execute` (it selects a different request) and
34
+ * re-runs such an effect.
35
+ *
27
36
  * @param method - HTTP method
28
37
  * @param url - Request URL
29
- * @param options - Request options
38
+ * @param options - Request options, read at call time
30
39
  * @returns Request state and execute function
31
40
  *
32
41
  * @example
@@ -34,8 +43,8 @@ export function useHttpClient() {
34
43
  * const { data, loading, error, execute } = useHttp<User[]>('GET', '/api/users')
35
44
  *
36
45
  * useEffect(() => {
37
- * execute()
38
- * }, [])
46
+ * void execute()
47
+ * }, [execute])
39
48
  *
40
49
  * if (loading) return <Spinner />
41
50
  * if (error) return <Error message={error.message} />
@@ -44,12 +53,12 @@ export function useHttpClient() {
44
53
  */
45
54
  export function useHttp(method, url, options) {
46
55
  const client = useHttpClient();
47
- const { immediate = false, onSuccess, onError, ...requestConfig } = options ?? {};
48
- const [state, setState] = useState({
56
+ const immediate = options?.immediate ?? false;
57
+ const [state, setState] = useState(() => ({
49
58
  data: null,
50
59
  loading: immediate,
51
60
  error: null,
52
- });
61
+ }));
53
62
  // Track mounted state to avoid state updates after unmount
54
63
  const mountedRef = useRef(true);
55
64
  useEffect(() => {
@@ -58,9 +67,20 @@ export function useHttp(method, url, options) {
58
67
  mountedRef.current = false;
59
68
  };
60
69
  }, []);
70
+ // Publish options during commit, before consumers' layout effects. A render
71
+ // that suspends or is discarded must not change a mounted action's request.
72
+ // This only updates our own ref: no DOM access or state update is involved.
73
+ const optionsRef = useRef(options);
74
+ useInsertionEffect(() => {
75
+ optionsRef.current = options;
76
+ }, [options]);
61
77
  const execute = useCallback(async () => {
62
78
  if (!mountedRef.current)
63
79
  return null;
80
+ // Deliberately NOT a dependency of this callback: options describe the
81
+ // request being sent, while method/url/client decide WHICH request execute
82
+ // performs. Reading them here keeps this action stable for effect deps.
83
+ const { immediate: _immediate, onSuccess, onError, ...requestConfig } = optionsRef.current ?? {};
64
84
  setState((prev) => ({ ...prev, loading: true, error: null }));
65
85
  try {
66
86
  let response;
@@ -97,11 +117,14 @@ export function useHttp(method, url, options) {
97
117
  }
98
118
  return null;
99
119
  }
100
- }, [client, method, url, requestConfig, onSuccess, onError]);
120
+ }, [client, method, url]);
101
121
  const reset = useCallback(() => {
102
122
  setState({ data: null, loading: false, error: null });
103
123
  }, []);
104
- // Execute immediately if requested
124
+ // Execute immediately if requested — mount only, as it has always been.
125
+ // `immediate` and `execute` are deliberately not dependencies: re-running this
126
+ // would turn a state update into a second request, which is the historical
127
+ // contract of this option (and every useGet(url, { immediate: true })'s).
105
128
  useEffect(() => {
106
129
  if (immediate) {
107
130
  execute();
@@ -1 +1 @@
1
- {"version":3,"file":"useHttp.js","sourceRoot":"","sources":["../../src/hooks/useHttp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useHttp.js","sourceRoot":"","sources":["../../src/hooks/useHttp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/app-react",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "React framework bindings for molecule.dev",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -58,7 +58,7 @@
58
58
  }
59
59
  },
60
60
  "devDependencies": {
61
- "@molecule/app-ai-models": "1.4.0",
61
+ "@molecule/app-ai-models": "1.4.1",
62
62
  "@molecule/app-bonds-default-react": "1.1.5",
63
63
  "@molecule/app-i18n": "1.0.3",
64
64
  "@testing-library/dom": "10.4.1",
@@ -68,7 +68,7 @@
68
68
  "react": "19.2.8",
69
69
  "react-dom": "19.2.8",
70
70
  "typescript": "6.0.3",
71
- "vitest": "4.1.11"
71
+ "vitest": "4.1.12"
72
72
  },
73
73
  "repository": {
74
74
  "type": "git",