@molecule/app-react-native 1.0.3 → 2.0.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 +282 -39
- package/package.json +6 -6
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-
|
|
6
|
+
Generated: 2026-10-25T20:03:36.978Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-react-native
|
|
@@ -105,7 +105,7 @@ Provides login/logout/register flows, token management, profile
|
|
|
105
105
|
updates, and auth state subscription.
|
|
106
106
|
|
|
107
107
|
```typescript
|
|
108
|
-
interface AuthClient<T = UserProfile, TRegister extends
|
|
108
|
+
interface AuthClient<T = UserProfile, TRegister extends RegisterExtraShape<TRegister> = Record<never, never>> {
|
|
109
109
|
/**
|
|
110
110
|
* Returns the current authentication state snapshot.
|
|
111
111
|
*
|
|
@@ -125,6 +125,15 @@ interface AuthClient<T = UserProfile, TRegister extends Record<string, unknown>
|
|
|
125
125
|
* Gets the current user.
|
|
126
126
|
*/
|
|
127
127
|
getUser(): T | null;
|
|
128
|
+
/**
|
|
129
|
+
* Optional ownership marker for the current session. Compare values only within
|
|
130
|
+
* this client: replacing or ending a session changes it, including re-adopting
|
|
131
|
+
* the same token and user. Profile updates and same-session refreshes keep it.
|
|
132
|
+
* Consumers can use it to discard stale async work without treating editable
|
|
133
|
+
* user fields as an immutable account identifier. Providers without this
|
|
134
|
+
* capability require the consumer's own stable identity check.
|
|
135
|
+
*/
|
|
136
|
+
getSessionRevision?(): number;
|
|
128
137
|
/**
|
|
129
138
|
* Updates the cached user object (state + persistent storage) without
|
|
130
139
|
* hitting the network. Intended for local refreshes after a per-app
|
|
@@ -199,6 +208,12 @@ interface AuthClient<T = UserProfile, TRegister extends Record<string, unknown>
|
|
|
199
208
|
confirmPasswordReset(data: PasswordResetConfirm): Promise<void>;
|
|
200
209
|
/**
|
|
201
210
|
* Updates the current user's profile.
|
|
211
|
+
* Returns the saved profile: the answer applied onto the signed-in user field
|
|
212
|
+
* by field, with or without an `id` — a field it carries replaces the value
|
|
213
|
+
* (`null` clears it), one it omits or leaves `undefined` is kept, so a field
|
|
214
|
+
* cleared by omission must arrive as `null`. A non-object answer is returned
|
|
215
|
+
* as it came. An answer for a replaced or ended session leaves the current one
|
|
216
|
+
* untouched.
|
|
202
217
|
*/
|
|
203
218
|
updateProfile(data: Partial<T>): Promise<T>;
|
|
204
219
|
/**
|
|
@@ -254,19 +269,6 @@ interface AuthClient<T = UserProfile, TRegister extends Record<string, unknown>
|
|
|
254
269
|
* Resolves when the session restore started by `initialize()` has settled — the point
|
|
255
270
|
* after which the client knows whether this visitor is signed in.
|
|
256
271
|
*
|
|
257
|
-
* Resolves IMMEDIATELY when no restore is in flight: before `initialize()` is ever
|
|
258
|
-
* called, and after it has finished. A restore that failed resolves too (it settled the
|
|
259
|
-
* question), so an HTTP client can await this before every request without risking one
|
|
260
|
-
* held forever. That is what makes the fetch-before-restore race impossible: a page that
|
|
261
|
-
* fetches viewer-dependent data on mount waits here instead of going out anonymously
|
|
262
|
-
* (see `setAuthGate` in `@molecule/app-http`).
|
|
263
|
-
*
|
|
264
|
-
* Optional: a provider that restores no session has nothing to wait for. Without it, an
|
|
265
|
-
* HTTP client bonded to that provider sends first-paint requests unauthenticated.
|
|
266
|
-
*
|
|
267
|
-
* A provider whose restore sends a request THROUGH the gated HTTP client must send that
|
|
268
|
-
* request with `skipAuthGate: true` (`RequestConfig` in `@molecule/app-http`): the gate
|
|
269
|
-
* waits on this promise, so holding the restore's own request makes the gate wait on
|
|
270
272
|
// … truncated — the full declaration is in node_modules/@molecule/app-react-native/dist
|
|
271
273
|
```
|
|
272
274
|
|
|
@@ -349,7 +351,13 @@ interface FormController<T extends Record<string, unknown> = Record<string, unkn
|
|
|
349
351
|
*/
|
|
350
352
|
validate(): Promise<boolean>
|
|
351
353
|
/**
|
|
352
|
-
* Resets the form
|
|
354
|
+
* Resets the form and clears errors, touched fields and submission state.
|
|
355
|
+
*
|
|
356
|
+
* With no argument it restores the current baseline — the initial
|
|
357
|
+
* `defaultValues`, or the values a previous `reset(values)` established.
|
|
358
|
+
* Passing `values` merges them over the current baseline and makes the
|
|
359
|
+
* result the new baseline, so a form reset to freshly loaded or saved data
|
|
360
|
+
* reads clean (`isDirty === false`).
|
|
353
361
|
*/
|
|
354
362
|
reset(values?: Partial<T>): void
|
|
355
363
|
/**
|
|
@@ -381,7 +389,8 @@ Form creation options.
|
|
|
381
389
|
```typescript
|
|
382
390
|
interface FormOptions<T extends Record<string, unknown>> {
|
|
383
391
|
/**
|
|
384
|
-
* Default values
|
|
392
|
+
* Default values, captured as the form's clean baseline when the controller
|
|
393
|
+
* is created. Mutating this object afterwards does not change the baseline.
|
|
385
394
|
*/
|
|
386
395
|
defaultValues?: Partial<T>
|
|
387
396
|
/**
|
|
@@ -467,12 +476,50 @@ interface HttpClient {
|
|
|
467
476
|
addErrorInterceptor(interceptor: ErrorInterceptor): () => void
|
|
468
477
|
/**
|
|
469
478
|
* Sets the authorization token.
|
|
479
|
+
*
|
|
480
|
+
* A static token: every request carries it until the next `setAuthToken` call. A client
|
|
481
|
+
* that has a {@link HttpClient.setAuthTokenResolver | resolver} (registered through
|
|
482
|
+
* `@molecule/app-http`'s `setAuthTokenSource`) ignores this value when it assembles a
|
|
483
|
+
* request — the resolver IS the session, and reading it per request is what keeps a
|
|
484
|
+
* session adopted without an auth event from sending the previous account's bearer. Once
|
|
485
|
+
* the resolver is removed, the static token is sent again.
|
|
470
486
|
*/
|
|
471
487
|
setAuthToken(token: string | null): void
|
|
472
488
|
/**
|
|
473
|
-
* Returns the
|
|
489
|
+
* Returns the token the client applies to its next request: the resolver's answer when one
|
|
490
|
+
* is registered, else the static token from `setAuthToken`.
|
|
474
491
|
*/
|
|
475
492
|
getAuthToken(): string | null
|
|
493
|
+
/**
|
|
494
|
+
* Registers the LIVE token resolver every request of this client reads, or clears it with
|
|
495
|
+
* `null`.
|
|
496
|
+
*
|
|
497
|
+
* `@molecule/app-http`'s `setAuthTokenSource()` calls this on every client it bonds, and the
|
|
498
|
+
* client MUST consult the resolver again each time it assembles a request (and report it from
|
|
499
|
+
* `getAuthToken()`). A session can change with no auth event and no observable state change —
|
|
500
|
+
* `authClient.setSession()` with the same profile data, or the OAuth callback's
|
|
501
|
+
* `setAccessToken()` — so a token pushed only at bond time or on `login`/`logout` events
|
|
502
|
+
* leaves every later request carrying the PREVIOUS session's bearer while the UI shows the
|
|
503
|
+
* new one.
|
|
504
|
+
*
|
|
505
|
+
* The resolved token takes the static token's place, with the same precedence: an
|
|
506
|
+
* `Authorization` header passed per request or in the client's default headers wins over it
|
|
507
|
+
* exactly where it won over a static token in this transport.
|
|
508
|
+
*
|
|
509
|
+
* A resolver that returns `null` (or `undefined`) means "this session has no body token": the
|
|
510
|
+
* request carries no `Authorization` header of the client's own. A cookie-session API issues
|
|
511
|
+
* no bearer, and the server prefers the header over the fresh cookie, so a kept bearer
|
|
512
|
+
* authenticates as the prior — possibly deleted — session.
|
|
513
|
+
*
|
|
514
|
+
* Optional, so an implementation written against the previous interface still conforms.
|
|
515
|
+
* `setAuthTokenSource()` follows such a client through a request interceptor instead, pushing
|
|
516
|
+
* the source with `setAuthToken` before each request: that request carries the change only
|
|
517
|
+
* when the transport applies its token after running its interceptors, so a transport that
|
|
518
|
+
* applies it earlier sends a session adopted mid-page from the following request on.
|
|
519
|
+
*
|
|
520
|
+
* @param resolver - Returns the current access token (or null/undefined), or `null` to clear.
|
|
521
|
+
*/
|
|
522
|
+
setAuthTokenResolver?(resolver: AuthTokenResolver | null): void
|
|
476
523
|
/**
|
|
477
524
|
* Registers a handler for authentication errors (401).
|
|
478
525
|
*
|
|
@@ -786,12 +833,18 @@ interface UseDeviceResult {
|
|
|
786
833
|
|
|
787
834
|
Options for useForm hook.
|
|
788
835
|
|
|
836
|
+
Every `FormOptions` field is supported. `createForm` is only an override —
|
|
837
|
+
omit it and the hook creates the controller through the bonded forms
|
|
838
|
+
provider (`createForm` from `@molecule/app-forms`), which uses the built-in
|
|
839
|
+
native provider until the app bonds its own.
|
|
840
|
+
|
|
789
841
|
```typescript
|
|
790
842
|
interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
|
|
791
843
|
/**
|
|
792
|
-
*
|
|
844
|
+
* Explicit form factory for this one form. Defaults to the bonded forms
|
|
845
|
+
* provider; pass it only to pin a specific provider instance.
|
|
793
846
|
*/
|
|
794
|
-
createForm
|
|
847
|
+
createForm?: (options: FormOptions<T>) => FormController<T>
|
|
795
848
|
}
|
|
796
849
|
```
|
|
797
850
|
|
|
@@ -805,7 +858,12 @@ interface UseFormResult<T extends Record<string, unknown>> {
|
|
|
805
858
|
isValid: boolean
|
|
806
859
|
isDirty: boolean
|
|
807
860
|
isSubmitting: boolean
|
|
808
|
-
register: (
|
|
861
|
+
register: (
|
|
862
|
+
name: keyof T,
|
|
863
|
+
options?: Omit<RegisterOptions, 'name'> & {
|
|
864
|
+
name?: string
|
|
865
|
+
},
|
|
866
|
+
) => FieldRegistration
|
|
809
867
|
getValue: <K extends keyof T>(name: K) => T[K]
|
|
810
868
|
setValue: <K extends keyof T>(name: K, value: T[K]) => void
|
|
811
869
|
getError: (name: keyof T) => string | undefined
|
|
@@ -835,6 +893,13 @@ Result of useHttp hook.
|
|
|
835
893
|
|
|
836
894
|
```typescript
|
|
837
895
|
interface UseHttpResult<T> extends UseHttpState<T> {
|
|
896
|
+
/**
|
|
897
|
+
* Runs the request and resolves with its data, or `null` on failure.
|
|
898
|
+
*
|
|
899
|
+
* This function is IDENTITY-STABLE for as long as `method`, `url` and the HTTP
|
|
900
|
+
* client do not change, so it is safe in a `useEffect` dependency array. Its
|
|
901
|
+
* request options are read when it is CALLED, from the latest committed render.
|
|
902
|
+
*/
|
|
838
903
|
execute: () => Promise<T | null>
|
|
839
904
|
reset: () => void
|
|
840
905
|
}
|
|
@@ -844,6 +909,11 @@ interface UseHttpResult<T> extends UseHttpState<T> {
|
|
|
844
909
|
|
|
845
910
|
Options for useHttp hook.
|
|
846
911
|
|
|
912
|
+
Every request option — headers, params, body `data`, `signal`, `onSuccess`,
|
|
913
|
+
`onError` — is read at the moment `execute` runs, not when the hook rendered,
|
|
914
|
+
so an inline object or callback needs no memoizing. Only `immediate` is read
|
|
915
|
+
on mount.
|
|
916
|
+
|
|
847
917
|
```typescript
|
|
848
918
|
interface UseHttpOptions<T> extends RequestConfig {
|
|
849
919
|
/**
|
|
@@ -928,6 +998,80 @@ interface UsePlatformResult {
|
|
|
928
998
|
}
|
|
929
999
|
```
|
|
930
1000
|
|
|
1001
|
+
#### `UseProfileFormOptions`
|
|
1002
|
+
|
|
1003
|
+
Configuration for a profile form; transport stays in the auth bond.
|
|
1004
|
+
|
|
1005
|
+
```typescript
|
|
1006
|
+
interface UseProfileFormOptions<TUser, TValues extends Record<string, unknown>> extends Omit<
|
|
1007
|
+
UseFormOptions<TValues>,
|
|
1008
|
+
'defaultValues'
|
|
1009
|
+
> {
|
|
1010
|
+
/** Complete controlled-field defaults, including blank write-only fields. */
|
|
1011
|
+
defaultValues: TValues
|
|
1012
|
+
/**
|
|
1013
|
+
* Optional additional account identity check; changing it discards prior edits.
|
|
1014
|
+
* By default ownership follows the auth client's session revision, so editable
|
|
1015
|
+
* fields can change during a save. Providers without getSessionRevision must
|
|
1016
|
+
* supply this callback with an identity that remains stable across profile edits.
|
|
1017
|
+
*/
|
|
1018
|
+
getIdentity?: (user: TUser) => string
|
|
1019
|
+
/** Maps the current/saved user into controlled values, e.g. nullable text to ''. */
|
|
1020
|
+
toValues: (user: TUser) => TValues
|
|
1021
|
+
/**
|
|
1022
|
+
* Maps ONLY changed fields into an API patch. Omit blank optional credentials
|
|
1023
|
+
* here; preserve undefined/absent fields rather than turning them into null.
|
|
1024
|
+
* The second argument is the complete value snapshot taken at submit time.
|
|
1025
|
+
*/
|
|
1026
|
+
toPatch: (changes: Partial<TValues>, values: Readonly<TValues>) => Partial<TUser>
|
|
1027
|
+
/**
|
|
1028
|
+
* Propagates the server's saved user to other caches, then navigates if needed.
|
|
1029
|
+
* Awaited before submission finishes. The auth client already persists and
|
|
1030
|
+
* publishes the saved user; never seed caches from the submitted patch.
|
|
1031
|
+
*/
|
|
1032
|
+
onSaved?: (user: TUser) => void | Promise<void>
|
|
1033
|
+
}
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
#### `UseProfileFormResult`
|
|
1037
|
+
|
|
1038
|
+
Controlled profile form state and native form bindings.
|
|
1039
|
+
|
|
1040
|
+
```typescript
|
|
1041
|
+
interface UseProfileFormResult<TUser, TValues extends Record<string, unknown>> extends Omit<
|
|
1042
|
+
UseFormResult<TValues>,
|
|
1043
|
+
'register' | 'handleSubmit' | 'reset'
|
|
1044
|
+
> {
|
|
1045
|
+
/** The shared auth user's current profile. */
|
|
1046
|
+
user: TUser | null
|
|
1047
|
+
/** A user has been loaded; disable submission until this is true. */
|
|
1048
|
+
ready: boolean
|
|
1049
|
+
/**
|
|
1050
|
+
* The latest save/propagation failure. Rejected saves retain edits; a failed
|
|
1051
|
+
* onSaved callback can be retried by submit without repeating the mutation.
|
|
1052
|
+
*/
|
|
1053
|
+
error: unknown
|
|
1054
|
+
/** Native input/textarea bindings with the field's concrete value type. */
|
|
1055
|
+
register: <K extends keyof TValues>(
|
|
1056
|
+
name: K,
|
|
1057
|
+
options?: Parameters<UseFormResult<TValues>['register']>[1],
|
|
1058
|
+
) => Omit<FieldRegistration, 'value'> & {
|
|
1059
|
+
value: TValues[K]
|
|
1060
|
+
}
|
|
1061
|
+
/** Bind to the native form, with a type="submit" button inside it. */
|
|
1062
|
+
formProps: {
|
|
1063
|
+
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Validates and saves one submit-time snapshot. Concurrent submits share the
|
|
1067
|
+
* same promise. Resolves undefined on validation, save or propagation failure.
|
|
1068
|
+
*/
|
|
1069
|
+
submit: () => Promise<TUser | undefined>
|
|
1070
|
+
/** Discards edits and restores the newest loaded/saved profile baseline. */
|
|
1071
|
+
reset: () => void
|
|
1072
|
+
}
|
|
1073
|
+
```
|
|
1074
|
+
|
|
931
1075
|
#### `UsePromiseState`
|
|
932
1076
|
|
|
933
1077
|
Extended promise state with actions.
|
|
@@ -980,11 +1124,14 @@ interface UsePushOptions {
|
|
|
980
1124
|
Return type for useSignup hook.
|
|
981
1125
|
|
|
982
1126
|
```typescript
|
|
983
|
-
interface UseSignupReturn<
|
|
1127
|
+
interface UseSignupReturn<
|
|
1128
|
+
T = unknown,
|
|
1129
|
+
TRegister extends RegisterExtraShape<TRegister> = Record<never, never>,
|
|
1130
|
+
> {
|
|
984
1131
|
status: UsePromiseState<AuthResult<T>>['status']
|
|
985
1132
|
value: UsePromiseState<AuthResult<T>>['value']
|
|
986
1133
|
error: UsePromiseState<AuthResult<T>>['error']
|
|
987
|
-
signup: (data: RegisterData) => Promise<AuthResult<T>>
|
|
1134
|
+
signup: (data: RegisterData<TRegister>) => Promise<AuthResult<T>>
|
|
988
1135
|
reset: () => void
|
|
989
1136
|
}
|
|
990
1137
|
```
|
|
@@ -1271,7 +1418,10 @@ interface UseAuthOptions {
|
|
|
1271
1418
|
Hook result for useAuth.
|
|
1272
1419
|
|
|
1273
1420
|
```typescript
|
|
1274
|
-
interface UseAuthResult<
|
|
1421
|
+
interface UseAuthResult<
|
|
1422
|
+
T = unknown,
|
|
1423
|
+
TRegister extends RegisterExtraShape<TRegister> = Record<never, never>,
|
|
1424
|
+
> {
|
|
1275
1425
|
/**
|
|
1276
1426
|
* The session state as one value — render from this instead of combining
|
|
1277
1427
|
* `initialized`/`authenticated`/`loading`. A stored token AND user make it
|
|
@@ -1282,7 +1432,7 @@ interface UseAuthResult<T = unknown> {
|
|
|
1282
1432
|
state: AuthState<T>
|
|
1283
1433
|
login: AuthClient<T>['login']
|
|
1284
1434
|
logout: AuthClient<T>['logout']
|
|
1285
|
-
register: AuthClient<T>['register']
|
|
1435
|
+
register: AuthClient<T, TRegister>['register']
|
|
1286
1436
|
refresh: AuthClient<T>['refresh']
|
|
1287
1437
|
setUser: AuthClient<T>['setUser']
|
|
1288
1438
|
/**
|
|
@@ -1293,7 +1443,7 @@ interface UseAuthResult<T = unknown> {
|
|
|
1293
1443
|
*
|
|
1294
1444
|
* `setUser` alone does NOT sign the client in, and `setAccessToken` changes
|
|
1295
1445
|
* storage only — using those two for a caller-issued session leaves every
|
|
1296
|
-
* `authenticated` read signed out
|
|
1446
|
+
* `authenticated` read signed out.
|
|
1297
1447
|
*/
|
|
1298
1448
|
setSession: AuthClient<T>['setSession']
|
|
1299
1449
|
isAuthenticated: boolean
|
|
@@ -1394,6 +1544,8 @@ Options for {@link UseChatResult.sendMessage}.
|
|
|
1394
1544
|
|
|
1395
1545
|
```typescript
|
|
1396
1546
|
interface SendMessageOptions {
|
|
1547
|
+
/** Reuse a queued message's UUID when delivering it after reconnecting. */
|
|
1548
|
+
messageId?: string
|
|
1397
1549
|
/**
|
|
1398
1550
|
* Skip the optimistic local user-message bubble. The text is still sent to
|
|
1399
1551
|
* the server. Used for ask_user responses: the answer is folded into the
|
|
@@ -1692,6 +1844,34 @@ How far the return-page verification has got.
|
|
|
1692
1844
|
type VerifyPaymentReturnStatus = 'idle' | 'verifying' | 'verified' | 'failed'
|
|
1693
1845
|
```
|
|
1694
1846
|
|
|
1847
|
+
#### `UseTShorthandOptions`
|
|
1848
|
+
|
|
1849
|
+
Options for the shorthand form of {@link UseTFunction}: the fallback text is
|
|
1850
|
+
passed positionally, so only `count` remains here.
|
|
1851
|
+
|
|
1852
|
+
```typescript
|
|
1853
|
+
type UseTShorthandOptions = Omit<TranslateOptions, 'defaultValue'>
|
|
1854
|
+
```
|
|
1855
|
+
|
|
1856
|
+
#### `UseTFunction`
|
|
1857
|
+
|
|
1858
|
+
Translation function returned by `useT()`.
|
|
1859
|
+
|
|
1860
|
+
Two compatible call forms:
|
|
1861
|
+
|
|
1862
|
+
- `t(key, values?, options?)` — the {@link I18nProvider.t} signature.
|
|
1863
|
+
- `t(key, fallback, options?)` — a string second argument is the inline
|
|
1864
|
+
English `defaultValue`, with optional `count` for pluralization.
|
|
1865
|
+
|
|
1866
|
+
Its identity is stable while the i18n provider instance is unchanged, so it
|
|
1867
|
+
can be used directly as an effect dependency.
|
|
1868
|
+
|
|
1869
|
+
```typescript
|
|
1870
|
+
type UseTFunction = I18nProvider['t'] & {
|
|
1871
|
+
(key: string, fallback: string, options?: UseTShorthandOptions): string
|
|
1872
|
+
}
|
|
1873
|
+
```
|
|
1874
|
+
|
|
1695
1875
|
### Functions
|
|
1696
1876
|
|
|
1697
1877
|
#### `useAppState()`
|
|
@@ -1774,8 +1954,12 @@ function useAIModels(projectId?: string): UseAIModelsResult
|
|
|
1774
1954
|
|
|
1775
1955
|
Hook to access the auth client from context.
|
|
1776
1956
|
|
|
1957
|
+
Pass the same generics the client was created with —
|
|
1958
|
+
`useAuthClient<MyUser, { username: string }>()` — so `register()` accepts
|
|
1959
|
+
the app's own fields.
|
|
1960
|
+
|
|
1777
1961
|
```typescript
|
|
1778
|
-
function useAuthClient(): AuthClient<T,
|
|
1962
|
+
function useAuthClient(): AuthClient<T, TRegister>
|
|
1779
1963
|
```
|
|
1780
1964
|
|
|
1781
1965
|
**Returns:** The auth client from context
|
|
@@ -1798,8 +1982,14 @@ To create an account, use `const { register } = useAuth<MyUser>()` and
|
|
|
1798
1982
|
`await register({ email, password, name })`. Registration returns the auth
|
|
1799
1983
|
client's `AuthResult<MyUser>`; there is no separate `useRegister` hook.
|
|
1800
1984
|
|
|
1985
|
+
An app whose API takes its OWN registration fields passes the client's
|
|
1986
|
+
second generic here too — `useAuth<MyUser, { username: string }>()` — so
|
|
1987
|
+
`register({ email, password, username })` is typed exactly like the client
|
|
1988
|
+
call (and `requestBody` receives the same payload). Without it, `register`
|
|
1989
|
+
accepts only the base fields.
|
|
1990
|
+
|
|
1801
1991
|
```typescript
|
|
1802
|
-
function useAuth(options?: UseAuthOptions): UseAuthResult<T>
|
|
1992
|
+
function useAuth(options?: UseAuthOptions): UseAuthResult<T, TRegister>
|
|
1803
1993
|
```
|
|
1804
1994
|
|
|
1805
1995
|
- `options` — Hook options
|
|
@@ -1968,11 +2158,15 @@ function useEditor(): UseEditorResult
|
|
|
1968
2158
|
|
|
1969
2159
|
Hook for form state management.
|
|
1970
2160
|
|
|
2161
|
+
Creates its controller through the bonded forms provider, so a React app
|
|
2162
|
+
wires a form library once (`setProvider` from `@molecule/app-forms`) and
|
|
2163
|
+
every form picks it up. Passing `createForm` overrides that for one form.
|
|
2164
|
+
|
|
1971
2165
|
```typescript
|
|
1972
|
-
function useForm(options
|
|
2166
|
+
function useForm(options?: UseFormOptions<T>): UseFormResult<T>
|
|
1973
2167
|
```
|
|
1974
2168
|
|
|
1975
|
-
- `options` — Form options
|
|
2169
|
+
- `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.
|
|
1976
2170
|
|
|
1977
2171
|
**Returns:** Form state and methods
|
|
1978
2172
|
|
|
@@ -2016,6 +2210,15 @@ function useHttpClient(): HttpClient
|
|
|
2016
2210
|
|
|
2017
2211
|
Hook for making HTTP requests with state management.
|
|
2018
2212
|
|
|
2213
|
+
`execute` keeps one identity while `method`, `url` and the HTTP client stay the
|
|
2214
|
+
same — across the hook's own loading/data updates, parent rerenders, and inline
|
|
2215
|
+
options or callbacks — so `useEffect(() => { void execute() }, [execute])`
|
|
2216
|
+
runs once per request target instead of looping. The current headers, body,
|
|
2217
|
+
`signal` and callbacks are read when `execute` is called, so a later manual
|
|
2218
|
+
call always sends what the latest committed render passed. Changing `method`, `url` or
|
|
2219
|
+
the client does replace `execute` (it selects a different request) and
|
|
2220
|
+
re-runs such an effect.
|
|
2221
|
+
|
|
2019
2222
|
```typescript
|
|
2020
2223
|
function useHttp(
|
|
2021
2224
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
|
|
@@ -2026,7 +2229,7 @@ function useHttp(
|
|
|
2026
2229
|
|
|
2027
2230
|
- `method` — HTTP method
|
|
2028
2231
|
- `url` — Request URL
|
|
2029
|
-
- `options` — Request options
|
|
2232
|
+
- `options` — Request options, read at call time
|
|
2030
2233
|
|
|
2031
2234
|
**Returns:** Request state and execute function
|
|
2032
2235
|
|
|
@@ -2231,6 +2434,29 @@ function usePreview(): UsePreviewResult
|
|
|
2231
2434
|
|
|
2232
2435
|
**Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
|
|
2233
2436
|
|
|
2437
|
+
#### `useProfileForm(options)`
|
|
2438
|
+
|
|
2439
|
+
Owns load → edit → submit → publish for the signed-in user's profile.
|
|
2440
|
+
|
|
2441
|
+
Same-account background updates refresh untouched fields but preserve dirty
|
|
2442
|
+
controls. Session ownership comes from the auth client, independently of mutable
|
|
2443
|
+
profile fields; an explicit getIdentity adds the caller's identity check.
|
|
2444
|
+
Submission snapshots the registered values before asynchronous
|
|
2445
|
+
validation, sends only changed fields through `toPatch`, and uses the auth
|
|
2446
|
+
client's configured updateProfile transport. The saved server response becomes
|
|
2447
|
+
the clean baseline; edits made while saving remain dirty. No request is made
|
|
2448
|
+
for a patch with no fields. A failed request retains the edits and shared user.
|
|
2449
|
+
|
|
2450
|
+
```typescript
|
|
2451
|
+
function useProfileForm(
|
|
2452
|
+
options: UseProfileFormOptions<TUser, TValues>,
|
|
2453
|
+
): UseProfileFormResult<TUser, TValues>
|
|
2454
|
+
```
|
|
2455
|
+
|
|
2456
|
+
- `options` — Controlled defaults, identity and wire adapters, optional cache/navigation callback.
|
|
2457
|
+
|
|
2458
|
+
**Returns:** Form state, typed control bindings, native submit binding and save error.
|
|
2459
|
+
|
|
2234
2460
|
#### `usePush(options)`
|
|
2235
2461
|
|
|
2236
2462
|
Hook for push notification state and actions.
|
|
@@ -2323,7 +2549,7 @@ function useIsActive(path: string, exact?: boolean): boolean
|
|
|
2323
2549
|
Hook for user registration with async state tracking.
|
|
2324
2550
|
|
|
2325
2551
|
```typescript
|
|
2326
|
-
function useSignup(): UseSignupReturn<T>
|
|
2552
|
+
function useSignup(): UseSignupReturn<T, TRegister>
|
|
2327
2553
|
```
|
|
2328
2554
|
|
|
2329
2555
|
**Returns:** Signup state and action
|
|
@@ -2505,15 +2731,32 @@ function useTranslation(): UseTranslationResult
|
|
|
2505
2731
|
|
|
2506
2732
|
Hook to get just the translation function.
|
|
2507
2733
|
|
|
2734
|
+
The returned function keeps ONE identity for as long as the provider
|
|
2735
|
+
instance is unchanged, so it is safe as an effect dependency: an effect
|
|
2736
|
+
written as `useEffect(..., [t])` does not re-run on ordinary re-renders or on
|
|
2737
|
+
a locale change. The hook still re-renders the calling component on every
|
|
2738
|
+
locale notification (including `addTranslations` for the active locale), so
|
|
2739
|
+
text it reads while rendering is current. A value memoized on `[t]` alone
|
|
2740
|
+
keeps the old text after a locale switch: `useMemo(() => t(...), [t])`, or a
|
|
2741
|
+
`React.memo` child that receives `t` as a prop. Call `useT()` inside that
|
|
2742
|
+
child, or add `useLocale()` to the dependencies.
|
|
2743
|
+
|
|
2744
|
+
Call it in either of two compatible forms:
|
|
2745
|
+
|
|
2746
|
+
- `t(key, values?, options?)` — the provider signature from
|
|
2747
|
+
`@molecule/app-i18n`, e.g. `t('cart.total', { total })`.
|
|
2748
|
+
- `t(key, fallback, options?)` — a shorthand for the common inline-English
|
|
2749
|
+
call: a string second argument is the `defaultValue`, so
|
|
2750
|
+
`t('cart.empty', 'Your cart is empty')` equals
|
|
2751
|
+
`t('cart.empty', undefined, { defaultValue: 'Your cart is empty' })`.
|
|
2752
|
+
Interpolation and pluralization still work:
|
|
2753
|
+
`t('cart.items', '{{count}} items', { count: 3 })`.
|
|
2754
|
+
|
|
2508
2755
|
```typescript
|
|
2509
|
-
function useT():
|
|
2510
|
-
key: string,
|
|
2511
|
-
values?: InterpolationValues,
|
|
2512
|
-
options?: { defaultValue?: string; count?: number },
|
|
2513
|
-
) => string
|
|
2756
|
+
function useT(): UseTFunction
|
|
2514
2757
|
```
|
|
2515
2758
|
|
|
2516
|
-
**Returns:** The translation function
|
|
2759
|
+
**Returns:** The translation function (stable identity while the provider is unchanged).
|
|
2517
2760
|
|
|
2518
2761
|
#### `useLocale()`
|
|
2519
2762
|
|
|
@@ -2988,7 +3231,7 @@ Peer dependencies:
|
|
|
2988
3231
|
|
|
2989
3232
|
- `@molecule/app-keyboard` ^1.0.1
|
|
2990
3233
|
- `@molecule/app-lifecycle` ^1.0.1
|
|
2991
|
-
- `@molecule/app-react` ^
|
|
3234
|
+
- `@molecule/app-react` ^2.0.0
|
|
2992
3235
|
- `react` ^18.0.0 || ^19.0.0
|
|
2993
3236
|
- `react-native` >=0.72.0
|
|
2994
3237
|
- `react-native-safe-area-context` >=4.0.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-react-native",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "React Native framework bindings for molecule.dev",
|
|
5
5
|
"homepage": "https://www.molecule.dev/packages/app-react-native",
|
|
6
6
|
"type": "module",
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"directory": "packages/app/frameworks/react-native"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@molecule/app-react": "
|
|
37
|
-
"@types/node": "26.
|
|
38
|
-
"react": "19.
|
|
36
|
+
"@molecule/app-react": "2.0.0",
|
|
37
|
+
"@types/node": "26.6.5",
|
|
38
|
+
"react": "19.3.1",
|
|
39
39
|
"typescript": "6.0.3",
|
|
40
|
-
"vitest": "4.1.
|
|
40
|
+
"vitest": "4.1.12"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@molecule/app-keyboard": "^1.0.1",
|
|
44
44
|
"@molecule/app-lifecycle": "^1.0.1",
|
|
45
|
-
"@molecule/app-react": "^
|
|
45
|
+
"@molecule/app-react": "^2.0.0",
|
|
46
46
|
"react": "^18.0.0 || ^19.0.0",
|
|
47
47
|
"react-native": ">=0.72.0",
|
|
48
48
|
"react-native-safe-area-context": ">=4.0.0"
|