@molecule/app-react-native 3.0.4 → 3.0.6
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 +195 -90
- package/package.json +2 -2
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-11-
|
|
6
|
+
Generated: 2026-11-08T06:24:49.442Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-react-native
|
|
@@ -78,25 +78,30 @@ interface AuthState<T = UserProfile> {
|
|
|
78
78
|
* never signs out. See {@link AuthStatus}.
|
|
79
79
|
*/
|
|
80
80
|
status: AuthStatus
|
|
81
|
+
|
|
81
82
|
/**
|
|
82
83
|
* Whether auth state has been initialized.
|
|
83
84
|
*/
|
|
84
85
|
initialized: boolean
|
|
86
|
+
|
|
85
87
|
/**
|
|
86
88
|
* Whether the client has an authenticated session. This is not a server
|
|
87
89
|
* confirmation flag: during `'unavailable'` it can be false for a retained
|
|
88
90
|
* token/cookie-only candidate with no cached profile. Use `status` for redirects.
|
|
89
91
|
*/
|
|
90
92
|
authenticated: boolean
|
|
93
|
+
|
|
91
94
|
/**
|
|
92
95
|
* Current user, or null when none is cached. In particular, an `'unavailable'`
|
|
93
96
|
* token/cookie-only restore has a retained candidate but no profile yet.
|
|
94
97
|
*/
|
|
95
98
|
user: T | null
|
|
99
|
+
|
|
96
100
|
/**
|
|
97
101
|
* Whether an auth operation is in progress.
|
|
98
102
|
*/
|
|
99
103
|
loading: boolean
|
|
104
|
+
|
|
100
105
|
/**
|
|
101
106
|
* Last auth error (if any).
|
|
102
107
|
*/
|
|
@@ -117,58 +122,82 @@ interface AuthClient<
|
|
|
117
122
|
> {
|
|
118
123
|
/** Returns the current authentication state snapshot. */
|
|
119
124
|
getState(): AuthState<T>
|
|
125
|
+
|
|
120
126
|
/** Returns whether the user is currently authenticated. */
|
|
121
127
|
isAuthenticated(): boolean
|
|
128
|
+
|
|
122
129
|
/** Gets the current user. */
|
|
123
130
|
getUser(): T | null
|
|
131
|
+
|
|
124
132
|
/** Optional ownership marker for the current session. */
|
|
125
133
|
getSessionRevision?(): number
|
|
134
|
+
|
|
126
135
|
/** Updates the cached user object (state + persistent storage) without hitting the network. */
|
|
127
136
|
setUser(user: T | null): void
|
|
137
|
+
|
|
128
138
|
/** Gets the current access token. */
|
|
129
139
|
getAccessToken(): string | null
|
|
140
|
+
|
|
130
141
|
/** Stores the access token in the configured token storage adapter (in a browser, Web Storage; `'memory'` where no browser store exists). */
|
|
131
142
|
setAccessToken(token: string | null): void
|
|
143
|
+
|
|
132
144
|
/** Adopts a session an out-of-band exchange already established: stores the access token (and the refresh token when given), caches the user, and sets the COMPLET… */
|
|
133
145
|
setSession(session: AuthSessionSeed<T>): void
|
|
146
|
+
|
|
134
147
|
/** Gets the refresh token. */
|
|
135
148
|
getRefreshToken(): string | null
|
|
149
|
+
|
|
136
150
|
/** Logs in with credentials. */
|
|
137
151
|
login(credentials: LoginCredentials): Promise<AuthResult<T>>
|
|
152
|
+
|
|
138
153
|
/** Logs out the current user. */
|
|
139
154
|
logout(): Promise<void>
|
|
155
|
+
|
|
140
156
|
/** Registers a new user. */
|
|
141
157
|
register(data: RegisterData<TRegister>): Promise<AuthResult<T>>
|
|
158
|
+
|
|
142
159
|
/** Refreshes the access token. */
|
|
143
160
|
refresh(): Promise<AuthResult<T>>
|
|
161
|
+
|
|
144
162
|
/** Requests a password reset. */
|
|
145
163
|
requestPasswordReset(data: PasswordResetRequest): Promise<void>
|
|
164
|
+
|
|
146
165
|
/** Confirms a password reset. */
|
|
147
166
|
confirmPasswordReset(data: PasswordResetConfirm): Promise<void>
|
|
167
|
+
|
|
148
168
|
/** Updates the current user's profile. */
|
|
149
169
|
updateProfile(data: Partial<T>): Promise<T>
|
|
170
|
+
|
|
150
171
|
/** Changes the current user's password. */
|
|
151
172
|
changePassword(oldPassword: string, newPassword: string): Promise<void>
|
|
173
|
+
|
|
152
174
|
/** Initializes auth state (e.g., from stored tokens). */
|
|
153
175
|
initialize(): Promise<void>
|
|
176
|
+
|
|
154
177
|
/** Re-checks a restored session against the server, in the background — the boot-time validation an app with a stored token needs when a revoked or expired token… */
|
|
155
178
|
validateSession?(): Promise<void>
|
|
179
|
+
|
|
156
180
|
/** Resolves when the session restore started by `initialize()` has settled — the point after which the client knows whether this visitor is signed in. */
|
|
157
181
|
whenRestored?(): Promise<void>
|
|
182
|
+
|
|
158
183
|
/** Subscribes to auth state changes. */
|
|
159
184
|
subscribe(callback: (state: AuthState<T>) => void): () => void
|
|
185
|
+
|
|
160
186
|
/** Subscribes to auth state changes (alias for subscribe). */
|
|
161
187
|
onAuthChange(callback: (state: AuthState<T>) => void): () => void
|
|
188
|
+
|
|
162
189
|
/** Gets the current access token (alias for getAccessToken). */
|
|
163
190
|
getToken?(): string | null
|
|
191
|
+
|
|
164
192
|
/** Adds an auth event listener. */
|
|
165
193
|
addEventListener(listener: AuthEventListener<T>): () => void
|
|
194
|
+
|
|
166
195
|
/** Destroys the auth client. */
|
|
167
196
|
destroy(): void
|
|
168
197
|
}
|
|
169
198
|
```
|
|
170
199
|
|
|
171
|
-
_(Member comments are shortened to their first sentence to fit; the full declaration is in `node_modules/@molecule/app-
|
|
200
|
+
_(Member comments are shortened to their first sentence to fit; the full declaration is in `node_modules/@molecule/app-auth/dist/types.d.ts`.)_
|
|
172
201
|
|
|
173
202
|
#### `FormController`
|
|
174
203
|
|
|
@@ -182,72 +211,77 @@ interface FormController<T extends FormValuesConstraint<T> = Record<string, unkn
|
|
|
182
211
|
* Gets the current form state.
|
|
183
212
|
*/
|
|
184
213
|
getState(): FormState<T>
|
|
214
|
+
|
|
185
215
|
/**
|
|
186
216
|
* Gets the value of a specific field.
|
|
187
217
|
*/
|
|
188
218
|
getValue(name: string): unknown
|
|
189
219
|
getValue<K extends keyof T>(name: K): T[K]
|
|
220
|
+
|
|
190
221
|
/**
|
|
191
222
|
* Gets all form values.
|
|
192
223
|
*/
|
|
193
224
|
getValues(): T
|
|
225
|
+
|
|
194
226
|
/**
|
|
195
227
|
* Sets the value of a specific field.
|
|
196
228
|
*/
|
|
197
229
|
setValue(
|
|
198
230
|
name: string,
|
|
199
231
|
value: unknown,
|
|
200
|
-
options?: {
|
|
201
|
-
shouldValidate?: boolean
|
|
202
|
-
shouldDirty?: boolean
|
|
203
|
-
shouldTouch?: boolean
|
|
204
|
-
},
|
|
232
|
+
options?: { shouldValidate?: boolean; shouldDirty?: boolean; shouldTouch?: boolean },
|
|
205
233
|
): void
|
|
234
|
+
|
|
206
235
|
/**
|
|
207
236
|
* Sets multiple values at once.
|
|
208
237
|
*/
|
|
209
|
-
setValues(
|
|
210
|
-
|
|
211
|
-
options?: {
|
|
212
|
-
shouldValidate?: boolean
|
|
213
|
-
},
|
|
214
|
-
): void
|
|
238
|
+
setValues(values: Partial<T>, options?: { shouldValidate?: boolean }): void
|
|
239
|
+
|
|
215
240
|
/**
|
|
216
241
|
* Gets the error for a specific field.
|
|
217
242
|
*/
|
|
218
243
|
getError(name: string): string | undefined
|
|
244
|
+
|
|
219
245
|
/**
|
|
220
246
|
* Sets the error for a specific field.
|
|
221
247
|
*/
|
|
222
248
|
setError(name: string, error: string | undefined): void
|
|
249
|
+
|
|
223
250
|
/**
|
|
224
251
|
* Clears the error for a specific field.
|
|
225
252
|
*/
|
|
226
253
|
clearError<K extends keyof T>(name: K): void
|
|
254
|
+
|
|
227
255
|
/**
|
|
228
256
|
* Clears all errors.
|
|
229
257
|
*/
|
|
230
258
|
clearErrors(): void
|
|
259
|
+
|
|
231
260
|
/**
|
|
232
261
|
* Gets the field state for a specific field.
|
|
233
262
|
*/
|
|
234
263
|
getFieldState<K extends keyof T>(name: K): FieldState<T[K]>
|
|
264
|
+
|
|
235
265
|
/**
|
|
236
266
|
* Registers a field for form management.
|
|
237
267
|
*/
|
|
238
268
|
register(nameOrOptions: string | RegisterOptions, options?: RegisterOptions): FieldRegistration
|
|
269
|
+
|
|
239
270
|
/**
|
|
240
271
|
* Unregisters a field.
|
|
241
272
|
*/
|
|
242
273
|
unregister(name: string): void
|
|
274
|
+
|
|
243
275
|
/**
|
|
244
276
|
* Validates a specific field.
|
|
245
277
|
*/
|
|
246
278
|
validateField<K extends keyof T>(name: K): Promise<boolean>
|
|
279
|
+
|
|
247
280
|
/**
|
|
248
281
|
* Validates all fields.
|
|
249
282
|
*/
|
|
250
283
|
validate(): Promise<boolean>
|
|
284
|
+
|
|
251
285
|
/**
|
|
252
286
|
* Resets the form and clears errors, touched fields and submission state.
|
|
253
287
|
*
|
|
@@ -259,6 +293,7 @@ interface FormController<T extends FormValuesConstraint<T> = Record<string, unkn
|
|
|
259
293
|
* record and cancels a pending submit.
|
|
260
294
|
*/
|
|
261
295
|
reset(values?: Partial<T>): void
|
|
296
|
+
|
|
262
297
|
/**
|
|
263
298
|
* Applies externally loaded values without clearing submission state.
|
|
264
299
|
*
|
|
@@ -269,6 +304,7 @@ interface FormController<T extends FormValuesConstraint<T> = Record<string, unkn
|
|
|
269
304
|
* submit. Equal-content baselines cause no update.
|
|
270
305
|
*/
|
|
271
306
|
updateValues(values: Partial<T>, resetOptions?: FormResetOptions): void
|
|
307
|
+
|
|
272
308
|
/**
|
|
273
309
|
* Handles form submission.
|
|
274
310
|
*/
|
|
@@ -276,14 +312,17 @@ interface FormController<T extends FormValuesConstraint<T> = Record<string, unkn
|
|
|
276
312
|
onSubmit: (values: T) => void | Promise<void>,
|
|
277
313
|
onError?: (errors: Partial<Record<keyof T, string>>) => void,
|
|
278
314
|
): (event?: { preventDefault?: () => void }) => Promise<void>
|
|
315
|
+
|
|
279
316
|
/**
|
|
280
317
|
* Sets focus to a field.
|
|
281
318
|
*/
|
|
282
319
|
setFocus(name: keyof T): void
|
|
320
|
+
|
|
283
321
|
/**
|
|
284
322
|
* Subscribes to form state changes.
|
|
285
323
|
*/
|
|
286
324
|
subscribe(callback: (state: FormState<T>) => void): () => void
|
|
325
|
+
|
|
287
326
|
/**
|
|
288
327
|
* Destroys the form controller.
|
|
289
328
|
*/
|
|
@@ -317,26 +356,32 @@ interface FormOptions<T extends FormValuesConstraint<T>> {
|
|
|
317
356
|
* is created. Mutating this object afterwards does not change the baseline.
|
|
318
357
|
*/
|
|
319
358
|
defaultValues?: Partial<T>
|
|
359
|
+
|
|
320
360
|
/**
|
|
321
361
|
* Externally loaded values, merged over `defaultValues` as the clean
|
|
322
362
|
* baseline. Framework bindings also apply later content changes; use
|
|
323
363
|
* `resetOptions.keepDirtyValues` to preserve edits while pristine fields fill.
|
|
324
364
|
*/
|
|
325
365
|
values?: Partial<T>
|
|
366
|
+
|
|
326
367
|
/** Controls how framework bindings apply changed `values`. */
|
|
327
368
|
resetOptions?: FormResetOptions
|
|
369
|
+
|
|
328
370
|
/**
|
|
329
371
|
* Validation mode.
|
|
330
372
|
*/
|
|
331
373
|
mode?: 'onSubmit' | 'onChange' | 'onBlur' | 'all'
|
|
374
|
+
|
|
332
375
|
/**
|
|
333
376
|
* Revalidation mode.
|
|
334
377
|
*/
|
|
335
378
|
reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit'
|
|
379
|
+
|
|
336
380
|
/**
|
|
337
381
|
* Whether to focus the first error field on submit.
|
|
338
382
|
*/
|
|
339
383
|
shouldFocusError?: boolean
|
|
384
|
+
|
|
340
385
|
/**
|
|
341
386
|
* Form-level validation function.
|
|
342
387
|
*/
|
|
@@ -358,54 +403,65 @@ interface HttpClient {
|
|
|
358
403
|
* Base URL for all requests.
|
|
359
404
|
*/
|
|
360
405
|
baseURL: string
|
|
406
|
+
|
|
361
407
|
/**
|
|
362
408
|
* Default headers for all requests.
|
|
363
409
|
*/
|
|
364
410
|
defaultHeaders: Record<string, string>
|
|
411
|
+
|
|
365
412
|
/**
|
|
366
413
|
* Makes a generic HTTP request. `data` is a field of THIS config object — the same body
|
|
367
414
|
* `post(url, data, config)` takes as its second argument.
|
|
368
415
|
*/
|
|
369
416
|
request<T = unknown>(config: FullRequestConfig): Promise<HttpResponse<T>>
|
|
417
|
+
|
|
370
418
|
/**
|
|
371
419
|
* Makes a GET request.
|
|
372
420
|
*/
|
|
373
421
|
get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
422
|
+
|
|
374
423
|
/**
|
|
375
424
|
* Makes a POST request. `data` is the request BODY, not a config object: the wire body is
|
|
376
425
|
* `data` itself, so `post(url, { data: body })` sends `{"data":body}` — pass `body` directly.
|
|
377
426
|
* A config (headers, params) is the THIRD argument.
|
|
378
427
|
*/
|
|
379
428
|
post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
429
|
+
|
|
380
430
|
/**
|
|
381
431
|
* Makes a PUT request. `data` is the request BODY (second argument) — never `{ data: body }`,
|
|
382
432
|
* which sends `{"data":body}`; a config is the THIRD argument.
|
|
383
433
|
*/
|
|
384
434
|
put<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
435
|
+
|
|
385
436
|
/**
|
|
386
437
|
* Makes a PATCH request. `data` is the request BODY (second argument) — never `{ data: body }`,
|
|
387
438
|
* which sends `{"data":body}`; a config is the THIRD argument.
|
|
388
439
|
*/
|
|
389
440
|
patch<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
441
|
+
|
|
390
442
|
/**
|
|
391
443
|
* Makes a DELETE request.
|
|
392
444
|
*/
|
|
393
445
|
delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
446
|
+
|
|
394
447
|
/**
|
|
395
448
|
* Adds a request interceptor.
|
|
396
449
|
* Returns a function to remove the interceptor.
|
|
397
450
|
*/
|
|
398
451
|
addRequestInterceptor(interceptor: RequestInterceptor): () => void
|
|
452
|
+
|
|
399
453
|
/**
|
|
400
454
|
* Adds a response interceptor.
|
|
401
455
|
* Returns a function to remove the interceptor.
|
|
402
456
|
*/
|
|
403
457
|
addResponseInterceptor(interceptor: ResponseInterceptor): () => void
|
|
458
|
+
|
|
404
459
|
/**
|
|
405
460
|
* Adds an error interceptor.
|
|
406
461
|
* Returns a function to remove the interceptor.
|
|
407
462
|
*/
|
|
408
463
|
addErrorInterceptor(interceptor: ErrorInterceptor): () => void
|
|
464
|
+
|
|
409
465
|
/**
|
|
410
466
|
* Sets the authorization token.
|
|
411
467
|
*
|
|
@@ -417,11 +473,13 @@ interface HttpClient {
|
|
|
417
473
|
* the resolver is removed, the static token is sent again.
|
|
418
474
|
*/
|
|
419
475
|
setAuthToken(token: string | null): void
|
|
476
|
+
|
|
420
477
|
/**
|
|
421
478
|
* Returns the token the client applies to its next request: the resolver's answer when one
|
|
422
479
|
* is registered, else the static token from `setAuthToken`.
|
|
423
480
|
*/
|
|
424
481
|
getAuthToken(): string | null
|
|
482
|
+
|
|
425
483
|
/**
|
|
426
484
|
* Registers the LIVE token resolver every request of this client reads, or clears it with
|
|
427
485
|
* `null`.
|
|
@@ -452,6 +510,7 @@ interface HttpClient {
|
|
|
452
510
|
* @param resolver - Returns the current access token (or null/undefined), or `null` to clear.
|
|
453
511
|
*/
|
|
454
512
|
setAuthTokenResolver?(resolver: AuthTokenResolver | null): void
|
|
513
|
+
|
|
455
514
|
/**
|
|
456
515
|
* Registers a handler for authentication errors (401).
|
|
457
516
|
*
|
|
@@ -473,26 +532,32 @@ interface Router {
|
|
|
473
532
|
* Returns the current route location (pathname, search, hash, state).
|
|
474
533
|
*/
|
|
475
534
|
getLocation(): RouteLocation
|
|
535
|
+
|
|
476
536
|
/**
|
|
477
537
|
* Gets the current route params.
|
|
478
538
|
*/
|
|
479
539
|
getParams<T extends RouteParams = RouteParams>(): T
|
|
540
|
+
|
|
480
541
|
/**
|
|
481
542
|
* Gets the current query params.
|
|
482
543
|
*/
|
|
483
544
|
getQuery(): QueryParams
|
|
545
|
+
|
|
484
546
|
/**
|
|
485
547
|
* Gets a specific query parameter.
|
|
486
548
|
*/
|
|
487
549
|
getQueryParam(key: string): string | undefined
|
|
550
|
+
|
|
488
551
|
/**
|
|
489
552
|
* Gets the current hash.
|
|
490
553
|
*/
|
|
491
554
|
getHash(): string
|
|
555
|
+
|
|
492
556
|
/**
|
|
493
557
|
* Navigates to a path.
|
|
494
558
|
*/
|
|
495
559
|
navigate(path: string, options?: NavigateOptions): void
|
|
560
|
+
|
|
496
561
|
/**
|
|
497
562
|
* Navigates to a named route.
|
|
498
563
|
*/
|
|
@@ -502,36 +567,44 @@ interface Router {
|
|
|
502
567
|
query?: QueryParams,
|
|
503
568
|
options?: NavigateOptions,
|
|
504
569
|
): void
|
|
570
|
+
|
|
505
571
|
/**
|
|
506
572
|
* Goes back in history.
|
|
507
573
|
*/
|
|
508
574
|
back(): void
|
|
575
|
+
|
|
509
576
|
/**
|
|
510
577
|
* Goes forward in history.
|
|
511
578
|
*/
|
|
512
579
|
forward(): void
|
|
580
|
+
|
|
513
581
|
/**
|
|
514
582
|
* Goes to a specific point in history.
|
|
515
583
|
*/
|
|
516
584
|
go(delta: number): void
|
|
585
|
+
|
|
517
586
|
/**
|
|
518
587
|
* Updates the current query params.
|
|
519
588
|
*/
|
|
520
589
|
setQuery(params: QueryParams, options?: NavigateOptions): void
|
|
590
|
+
|
|
521
591
|
/**
|
|
522
592
|
* Updates a specific query parameter.
|
|
523
593
|
*/
|
|
524
594
|
setQueryParam(key: string, value: string | undefined, options?: NavigateOptions): void
|
|
595
|
+
|
|
525
596
|
/**
|
|
526
597
|
* Updates the current hash.
|
|
527
598
|
*/
|
|
528
599
|
setHash(hash: string, options?: NavigateOptions): void
|
|
600
|
+
|
|
529
601
|
/**
|
|
530
602
|
* Checks if a path matches the current location.
|
|
531
603
|
*
|
|
532
604
|
* @returns `true` if the path matches the current route.
|
|
533
605
|
*/
|
|
534
606
|
isActive(path: string, exact?: boolean): boolean
|
|
607
|
+
|
|
535
608
|
/**
|
|
536
609
|
* Matches a path pattern against a pathname.
|
|
537
610
|
*/
|
|
@@ -539,26 +612,32 @@ interface Router {
|
|
|
539
612
|
pattern: string,
|
|
540
613
|
pathname: string,
|
|
541
614
|
): RouteMatch<Params> | null
|
|
615
|
+
|
|
542
616
|
/**
|
|
543
617
|
* Generates a URL from a named route.
|
|
544
618
|
*/
|
|
545
619
|
generatePath(name: string, params?: RouteParams, query?: QueryParams): string
|
|
620
|
+
|
|
546
621
|
/**
|
|
547
622
|
* Subscribes to route changes.
|
|
548
623
|
*/
|
|
549
624
|
subscribe(listener: RouteChangeListener): () => void
|
|
625
|
+
|
|
550
626
|
/**
|
|
551
627
|
* Adds a navigation guard.
|
|
552
628
|
*/
|
|
553
629
|
addGuard(guard: NavigationGuard): () => void
|
|
630
|
+
|
|
554
631
|
/**
|
|
555
632
|
* Registers route definitions.
|
|
556
633
|
*/
|
|
557
634
|
registerRoutes(routes: RouteDefinition[]): void
|
|
635
|
+
|
|
558
636
|
/**
|
|
559
637
|
* Gets all registered routes.
|
|
560
638
|
*/
|
|
561
639
|
getRoutes(): RouteDefinition[]
|
|
640
|
+
|
|
562
641
|
/**
|
|
563
642
|
* Destroys the router.
|
|
564
643
|
*/
|
|
@@ -576,10 +655,12 @@ interface RouterConfig {
|
|
|
576
655
|
* Router mode.
|
|
577
656
|
*/
|
|
578
657
|
mode?: 'history' | 'hash' | 'memory'
|
|
658
|
+
|
|
579
659
|
/**
|
|
580
660
|
* Base path.
|
|
581
661
|
*/
|
|
582
662
|
basePath?: string
|
|
663
|
+
|
|
583
664
|
/**
|
|
584
665
|
* Initial routes.
|
|
585
666
|
*/
|
|
@@ -597,10 +678,12 @@ interface StoreConfig<T> {
|
|
|
597
678
|
* Initial state value.
|
|
598
679
|
*/
|
|
599
680
|
initialState: T
|
|
681
|
+
|
|
600
682
|
/**
|
|
601
683
|
* Optional name for debugging.
|
|
602
684
|
*/
|
|
603
685
|
name?: string
|
|
686
|
+
|
|
604
687
|
/**
|
|
605
688
|
* Optional middleware functions.
|
|
606
689
|
*/
|
|
@@ -620,15 +703,18 @@ interface Store<T> {
|
|
|
620
703
|
* Gets the current state.
|
|
621
704
|
*/
|
|
622
705
|
getState(): T
|
|
706
|
+
|
|
623
707
|
/**
|
|
624
708
|
* Sets the state (partial or via updater function).
|
|
625
709
|
*/
|
|
626
710
|
setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
|
|
711
|
+
|
|
627
712
|
/**
|
|
628
713
|
* Subscribes to state changes.
|
|
629
714
|
* Returns an unsubscribe function.
|
|
630
715
|
*/
|
|
631
716
|
subscribe(listener: StateListener<T>): () => void
|
|
717
|
+
|
|
632
718
|
/**
|
|
633
719
|
* Destroys the store and cleans up subscriptions.
|
|
634
720
|
*/
|
|
@@ -786,21 +872,24 @@ Result of useForm hook.
|
|
|
786
872
|
|
|
787
873
|
```typescript
|
|
788
874
|
interface UseFormResult<T extends FormValuesConstraint<T>> {
|
|
875
|
+
// State
|
|
789
876
|
formState: FormState<T>
|
|
790
877
|
isValid: boolean
|
|
791
878
|
isDirty: boolean
|
|
792
879
|
isSubmitting: boolean
|
|
880
|
+
|
|
881
|
+
// Field methods
|
|
793
882
|
register: (
|
|
794
883
|
name: keyof T,
|
|
795
|
-
options?: Omit<RegisterOptions, 'name'> & {
|
|
796
|
-
name?: string
|
|
797
|
-
},
|
|
884
|
+
options?: Omit<RegisterOptions, 'name'> & { name?: string },
|
|
798
885
|
) => FieldRegistration
|
|
799
886
|
getValue: <K extends keyof T>(name: K) => T[K]
|
|
800
887
|
setValue: <K extends keyof T>(name: K, value: T[K]) => void
|
|
801
888
|
getError: (name: keyof T) => string | undefined
|
|
802
889
|
setError: (name: keyof T, error: string | undefined) => void
|
|
803
890
|
clearErrors: () => void
|
|
891
|
+
|
|
892
|
+
// Form methods
|
|
804
893
|
handleSubmit: (
|
|
805
894
|
onSubmit: (values: T) => void | Promise<void>,
|
|
806
895
|
) => (event?: React.FormEvent) => Promise<void>
|
|
@@ -916,6 +1005,7 @@ interface UseOptimisticValueResult<T> extends OptimisticValueState<T> {
|
|
|
916
1005
|
* @param next - The value the person chose.
|
|
917
1006
|
*/
|
|
918
1007
|
set: (next: T) => void
|
|
1008
|
+
|
|
919
1009
|
/**
|
|
920
1010
|
* Like `set`, computed from the value shown now (`update((on) => !on)`).
|
|
921
1011
|
*
|
|
@@ -1018,13 +1108,9 @@ interface UseProfileFormResult<TUser, TValues extends FormValuesConstraint<TValu
|
|
|
1018
1108
|
register: <K extends keyof TValues>(
|
|
1019
1109
|
name: K,
|
|
1020
1110
|
options?: Parameters<UseFormResult<TValues>['register']>[1],
|
|
1021
|
-
) => Omit<FieldRegistration, 'value'> & {
|
|
1022
|
-
value: TValues[K]
|
|
1023
|
-
}
|
|
1111
|
+
) => Omit<FieldRegistration, 'value'> & { value: TValues[K] }
|
|
1024
1112
|
/** Bind to the native form, with a type="submit" button inside it. */
|
|
1025
|
-
formProps: {
|
|
1026
|
-
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void
|
|
1027
|
-
}
|
|
1113
|
+
formProps: { onSubmit: (event: React.FormEvent<HTMLFormElement>) => void }
|
|
1028
1114
|
/**
|
|
1029
1115
|
* Validates and saves one submit-time snapshot. Concurrent submits share the
|
|
1030
1116
|
* same promise. Resolves undefined on validation, save or propagation failure.
|
|
@@ -1178,16 +1264,20 @@ interface UseVerifyPaymentReturnOptions {
|
|
|
1178
1264
|
* query parameter. Leave unset to verify only what the URL names.
|
|
1179
1265
|
*/
|
|
1180
1266
|
provider?: string
|
|
1267
|
+
|
|
1181
1268
|
/** Set `false` to skip verification entirely (e.g. behind a feature flag). */
|
|
1182
1269
|
enabled?: boolean
|
|
1270
|
+
|
|
1183
1271
|
/**
|
|
1184
1272
|
* Remove the provider's query parameters from the address bar once the
|
|
1185
1273
|
* purchase is verified, so a reload (or a shared link) cannot replay the
|
|
1186
1274
|
* verification. Defaults to `true`.
|
|
1187
1275
|
*/
|
|
1188
1276
|
cleanUrl?: boolean
|
|
1277
|
+
|
|
1189
1278
|
/** Called once, after the purchase verifies. */
|
|
1190
1279
|
onVerified?: () => void
|
|
1280
|
+
|
|
1191
1281
|
/** Called when verification fails. */
|
|
1192
1282
|
onError?: (error: Error) => void
|
|
1193
1283
|
}
|
|
@@ -1205,14 +1295,19 @@ interface UseVerifyPaymentReturnResult {
|
|
|
1205
1295
|
* flight; then `verified` or `failed`.
|
|
1206
1296
|
*/
|
|
1207
1297
|
status: VerifyPaymentReturnStatus
|
|
1298
|
+
|
|
1208
1299
|
/** `true` when the URL identifies a purchase to verify. */
|
|
1209
1300
|
isReturn: boolean
|
|
1301
|
+
|
|
1210
1302
|
/** The provider named by the URL (or the `provider` option). */
|
|
1211
1303
|
provider: string | null
|
|
1304
|
+
|
|
1212
1305
|
/** The provider transaction/session id read from the URL. */
|
|
1213
1306
|
transactionId: string | null
|
|
1307
|
+
|
|
1214
1308
|
/** Why verification failed, when it did. */
|
|
1215
1309
|
error: Error | null
|
|
1310
|
+
|
|
1216
1311
|
/** Re-run the verification — wire this to a retry button. */
|
|
1217
1312
|
retry: () => void
|
|
1218
1313
|
}
|
|
@@ -1700,10 +1795,7 @@ interface UseChatResult {
|
|
|
1700
1795
|
* once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
|
|
1701
1796
|
* limit/quota, and signup-required errors never auto-retry.
|
|
1702
1797
|
*/
|
|
1703
|
-
retryCountdown: {
|
|
1704
|
-
secondsRemaining: number
|
|
1705
|
-
attempt: number
|
|
1706
|
-
} | null
|
|
1798
|
+
retryCountdown: { secondsRemaining: number; attempt: number } | null
|
|
1707
1799
|
/** Update the local mode state (for instant mode toggle without an AI turn). */
|
|
1708
1800
|
setMode: (mode: 'plan' | 'execute') => void
|
|
1709
1801
|
/** Update the local fast-mode state (for instant toggle without an AI turn). */
|
|
@@ -1981,6 +2073,18 @@ function useAIModels(projectId?: string): UseAIModelsResult
|
|
|
1981
2073
|
|
|
1982
2074
|
**Returns:** Models, free-tier model, loading flag, and error.
|
|
1983
2075
|
|
|
2076
|
+
#### `useAsyncState(initialState)`
|
|
2077
|
+
|
|
2078
|
+
Hook like useState but accepts Promises and supports partial state extension.
|
|
2079
|
+
|
|
2080
|
+
```typescript
|
|
2081
|
+
function useAsyncState<T>(initialState: T): [T, AsyncSetState<T>, AsyncExtendState<T>]
|
|
2082
|
+
```
|
|
2083
|
+
|
|
2084
|
+
- `initialState` — Initial state value
|
|
2085
|
+
|
|
2086
|
+
**Returns:** Tuple of [state, asyncSetState, asyncExtendState]
|
|
2087
|
+
|
|
1984
2088
|
#### `useAuthClient()`
|
|
1985
2089
|
|
|
1986
2090
|
Hook to access the auth client from context.
|
|
@@ -2025,7 +2129,7 @@ client's `AuthResult<MyUser>`; there is no separate `useRegister` hook.
|
|
|
2025
2129
|
An app whose API takes its OWN registration fields passes the client's
|
|
2026
2130
|
second generic here too — `useAuth<MyUser, { username: string }>()` — so
|
|
2027
2131
|
`register({ email, password, username })` is typed exactly like the client
|
|
2028
|
-
call (and `
|
|
2132
|
+
call (and `mapRequestBody` receives that payload as its first argument). Without it, `register`
|
|
2029
2133
|
accepts only the base fields.
|
|
2030
2134
|
|
|
2031
2135
|
```typescript
|
|
@@ -2440,6 +2544,40 @@ function useOAuth(config?: {
|
|
|
2440
2544
|
|
|
2441
2545
|
**Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
|
|
2442
2546
|
|
|
2547
|
+
#### `useOptimisticValue(options)`
|
|
2548
|
+
|
|
2549
|
+
A server-backed value — a favorite, follow, like or bookmark button, a rating, a quantity, a
|
|
2550
|
+
setting switch — that changes on the first render after a tap and is saved one change at a
|
|
2551
|
+
time, in order. Taps during a save update the desired value; the newest waiting value is
|
|
2552
|
+
saved after it (intermediate waiting values coalesce). Only a failure of the newest
|
|
2553
|
+
change puts the server value back. See `createOptimisticValue` in `@molecule/app-state`.
|
|
2554
|
+
|
|
2555
|
+
`value` is the server's value from props or a query. A new `value` is taken only when it
|
|
2556
|
+
differs (by `equals`) from the one the hook last received, and only while nothing is being
|
|
2557
|
+
saved, so a parent re-render or a refetch of older data never flips the button mid-save. The
|
|
2558
|
+
latest `commit` and `onError` are always used. Give the component a `key` per record, so one
|
|
2559
|
+
record's pending change never shows on another.
|
|
2560
|
+
Keep related fields, such as a favorite flag and its count, in the SAME value. Return both
|
|
2561
|
+
from the server response in `commit`, and publish that response to parent/query caches there
|
|
2562
|
+
if needed. Let commit reject on failure: a catch that returns old data hides the failure.
|
|
2563
|
+
Replace display-state setters and prop-copy effects with this hook's value and `update`.
|
|
2564
|
+
`pending` is for feedback, never a reason to disable the toggle or drop a tap.
|
|
2565
|
+
|
|
2566
|
+
Render/enable the keyed control only once its initial record exists. Keep that control
|
|
2567
|
+
mounted through refetches of the same record. This hook does not fix a click handler that
|
|
2568
|
+
returns on a still-null profile, or a remount that throws its controller away. Refetches
|
|
2569
|
+
during a save cannot replace pending intent; changed server snapshots arriving AFTER saving
|
|
2570
|
+
finishes are accepted and need query-layer ordering if they can be stale. See the module
|
|
2571
|
+
quickstart for a complete favorite button with a server-confirmed count.
|
|
2572
|
+
|
|
2573
|
+
```typescript
|
|
2574
|
+
function useOptimisticValue<T>(options: OptimisticValueOptions<T>): UseOptimisticValueResult<T>
|
|
2575
|
+
```
|
|
2576
|
+
|
|
2577
|
+
- `options` — The server's current value and how to save a change.
|
|
2578
|
+
|
|
2579
|
+
**Returns:** The value to render, whether a save is pending, the newest failure, and `set`/`update`.
|
|
2580
|
+
|
|
2443
2581
|
#### `usePasswordReset()`
|
|
2444
2582
|
|
|
2445
2583
|
Hook for password reset flow with async state tracking.
|
|
@@ -2508,6 +2646,34 @@ function useProfileForm<TUser, TValues extends FormValuesConstraint<TValues>>(
|
|
|
2508
2646
|
|
|
2509
2647
|
**Returns:** Form state, typed control bindings, native submit binding and save error.
|
|
2510
2648
|
|
|
2649
|
+
#### `usePromise(asyncFn)`
|
|
2650
|
+
|
|
2651
|
+
Hook that wraps an async function with state tracking.
|
|
2652
|
+
|
|
2653
|
+
For one UI action, pass `state.status === 'pending'` to `Button loading`
|
|
2654
|
+
from `@molecule/app-ui-react` (or to a native control's `disabled` prop).
|
|
2655
|
+
The control then refuses input while the request is pending and re-enables
|
|
2656
|
+
when the tracked call settles. Handle the returned promise's rejection;
|
|
2657
|
+
the hook also records the failure in `state.error`.
|
|
2658
|
+
|
|
2659
|
+
This hook tracks the latest call: it does not serialize invocations or
|
|
2660
|
+
cancel their network requests. An explicit reset/cancel changes the tracked
|
|
2661
|
+
state, so it is not proof that an outstanding request has stopped. Use an
|
|
2662
|
+
app-owned queue when every click must be accepted in order.
|
|
2663
|
+
|
|
2664
|
+
```typescript
|
|
2665
|
+
function usePromise<T extends (...args: any[]) => Promise<any>>(
|
|
2666
|
+
asyncFn: T,
|
|
2667
|
+
): [
|
|
2668
|
+
UsePromiseState<Awaited<ReturnType<T>>>,
|
|
2669
|
+
(...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>,
|
|
2670
|
+
]
|
|
2671
|
+
```
|
|
2672
|
+
|
|
2673
|
+
- `asyncFn` — The async function to wrap
|
|
2674
|
+
|
|
2675
|
+
**Returns:** Tuple of [state, wrappedFunction]
|
|
2676
|
+
|
|
2511
2677
|
#### `usePush(options)`
|
|
2512
2678
|
|
|
2513
2679
|
Hook for push notification state and actions.
|
|
@@ -3111,7 +3277,7 @@ function MoleculeProvider({
|
|
|
3111
3277
|
workspace,
|
|
3112
3278
|
editor,
|
|
3113
3279
|
preview,
|
|
3114
|
-
awaitSession,
|
|
3280
|
+
awaitSession = false,
|
|
3115
3281
|
sessionFallback,
|
|
3116
3282
|
}: MoleculeProviderProps): React.ReactElement
|
|
3117
3283
|
```
|
|
@@ -3145,7 +3311,7 @@ client before rendering to include its decided content, or leave the hold disabl
|
|
|
3145
3311
|
Route-level redirects for signed-in-only pages stay with `AuthGuard` (`@molecule/app-ui-react`).
|
|
3146
3312
|
|
|
3147
3313
|
```typescript
|
|
3148
|
-
function SessionReady({ children, fallback }: SessionReadyProps): ReactNode
|
|
3314
|
+
function SessionReady({ children, fallback = null }: SessionReadyProps): ReactNode
|
|
3149
3315
|
```
|
|
3150
3316
|
|
|
3151
3317
|
- `props` — {@link SessionReadyProps}.
|
|
@@ -3276,67 +3442,6 @@ Context for live preview provider.
|
|
|
3276
3442
|
const PreviewContext: Context<PreviewProvider | null>
|
|
3277
3443
|
```
|
|
3278
3444
|
|
|
3279
|
-
#### `useAsyncState`
|
|
3280
|
-
|
|
3281
|
-
Hook like useState but accepts Promises and supports partial state extension.
|
|
3282
|
-
|
|
3283
|
-
```typescript
|
|
3284
|
-
const useAsyncState: <T>(initialState: T) => [T, AsyncSetState<T>, AsyncExtendState<T>]
|
|
3285
|
-
```
|
|
3286
|
-
|
|
3287
|
-
- `initialState` — Initial state value
|
|
3288
|
-
|
|
3289
|
-
**Returns:** Tuple of [state, asyncSetState, asyncExtendState]
|
|
3290
|
-
|
|
3291
|
-
#### `useOptimisticValue`
|
|
3292
|
-
|
|
3293
|
-
A server-backed value — a favorite, follow, like or bookmark button, a rating, a quantity, a
|
|
3294
|
-
setting switch — that changes on the first render after a tap and is saved one change at a
|
|
3295
|
-
time, in order. A tap during a save is saved right after it; only a failure of the newest
|
|
3296
|
-
change puts the server value back. See `createOptimisticValue` in `@molecule/app-state`.
|
|
3297
|
-
|
|
3298
|
-
`value` is the server's value from props or a query. A new `value` is taken only when it
|
|
3299
|
-
differs (by `equals`) from the one the hook last received, and only while nothing is being
|
|
3300
|
-
saved, so a parent re-render or a refetch of older data never flips the button mid-save. The
|
|
3301
|
-
latest `commit` and `onError` are always used. Give the component a `key` per record, so one
|
|
3302
|
-
record's pending change never shows on another.
|
|
3303
|
-
|
|
3304
|
-
```typescript
|
|
3305
|
-
const useOptimisticValue: <T>(options: OptimisticValueOptions<T>) => UseOptimisticValueResult<T>
|
|
3306
|
-
```
|
|
3307
|
-
|
|
3308
|
-
- `options` — The server's current value and how to save a change.
|
|
3309
|
-
|
|
3310
|
-
**Returns:** The value to render, whether a save is pending, the newest failure, and `set`/`update`.
|
|
3311
|
-
|
|
3312
|
-
#### `usePromise`
|
|
3313
|
-
|
|
3314
|
-
Hook that wraps an async function with state tracking.
|
|
3315
|
-
|
|
3316
|
-
For one UI action, pass `state.status === 'pending'` to `Button loading`
|
|
3317
|
-
from `@molecule/app-ui-react` (or to a native control's `disabled` prop).
|
|
3318
|
-
The control then refuses input while the request is pending and re-enables
|
|
3319
|
-
when the tracked call settles. Handle the returned promise's rejection;
|
|
3320
|
-
the hook also records the failure in `state.error`.
|
|
3321
|
-
|
|
3322
|
-
This hook tracks the latest call: it does not serialize invocations or
|
|
3323
|
-
cancel their network requests. An explicit reset/cancel changes the tracked
|
|
3324
|
-
state, so it is not proof that an outstanding request has stopped. Use an
|
|
3325
|
-
app-owned queue when every click must be accepted in order.
|
|
3326
|
-
|
|
3327
|
-
```typescript
|
|
3328
|
-
const usePromise: <T extends (...args: any[]) => Promise<any>>(
|
|
3329
|
-
asyncFn: T,
|
|
3330
|
-
) => [
|
|
3331
|
-
UsePromiseState<Awaited<ReturnType<T>>>,
|
|
3332
|
-
(...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>,
|
|
3333
|
-
]
|
|
3334
|
-
```
|
|
3335
|
-
|
|
3336
|
-
- `asyncFn` — The async function to wrap
|
|
3337
|
-
|
|
3338
|
-
**Returns:** Tuple of [state, wrappedFunction]
|
|
3339
|
-
|
|
3340
3445
|
## Injection Notes
|
|
3341
3446
|
|
|
3342
3447
|
### Requirements
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-react-native",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6",
|
|
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,7 +33,7 @@
|
|
|
33
33
|
"directory": "packages/app/frameworks/react-native"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@molecule/app-react": "3.4.
|
|
36
|
+
"@molecule/app-react": "3.4.4",
|
|
37
37
|
"@types/node": "26.6.5",
|
|
38
38
|
"react": "19.3.1",
|
|
39
39
|
"typescript": "6.0.3",
|