@molecule/app-react-native 1.0.4 → 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.
Files changed (2) hide show
  1. package/README.md +99 -16
  2. package/package.json +3 -3
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-23T14:59:33.332Z
6
+ Generated: 2026-10-25T20:03:36.978Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-react-native
@@ -208,9 +208,12 @@ interface AuthClient<T = UserProfile, TRegister extends RegisterExtraShape<TRegi
208
208
  confirmPasswordReset(data: PasswordResetConfirm): Promise<void>;
209
209
  /**
210
210
  * Updates the current user's profile.
211
- * Returns the saved response. If the session is explicitly replaced or ended
212
- * while the request is pending, that response does not replace the current
213
- * session's user or persisted cache.
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.
214
217
  */
215
218
  updateProfile(data: Partial<T>): Promise<T>;
216
219
  /**
@@ -266,9 +269,6 @@ interface AuthClient<T = UserProfile, TRegister extends RegisterExtraShape<TRegi
266
269
  * Resolves when the session restore started by `initialize()` has settled — the point
267
270
  * after which the client knows whether this visitor is signed in.
268
271
  *
269
- * Resolves IMMEDIATELY when no restore is in flight: before `initialize()` is ever
270
- * called, and after it has finished. A restore that failed resolves too (it settled the
271
- * question), so an HTTP client can await this before every request without risking one
272
272
  // … truncated — the full declaration is in node_modules/@molecule/app-react-native/dist
273
273
  ```
274
274
 
@@ -476,12 +476,50 @@ interface HttpClient {
476
476
  addErrorInterceptor(interceptor: ErrorInterceptor): () => void
477
477
  /**
478
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.
479
486
  */
480
487
  setAuthToken(token: string | null): void
481
488
  /**
482
- * Returns the current authorization token, or `null` if not set.
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`.
483
491
  */
484
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
485
523
  /**
486
524
  * Registers a handler for authentication errors (401).
487
525
  *
@@ -1405,7 +1443,7 @@ interface UseAuthResult<
1405
1443
  *
1406
1444
  * `setUser` alone does NOT sign the client in, and `setAccessToken` changes
1407
1445
  * storage only — using those two for a caller-issued session leaves every
1408
- * `authenticated` read signed out (xr-molecule-flash-m178).
1446
+ * `authenticated` read signed out.
1409
1447
  */
1410
1448
  setSession: AuthClient<T>['setSession']
1411
1449
  isAuthenticated: boolean
@@ -1806,6 +1844,34 @@ How far the return-page verification has got.
1806
1844
  type VerifyPaymentReturnStatus = 'idle' | 'verifying' | 'verified' | 'failed'
1807
1845
  ```
1808
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
+
1809
1875
  ### Functions
1810
1876
 
1811
1877
  #### `useAppState()`
@@ -2665,15 +2731,32 @@ function useTranslation(): UseTranslationResult
2665
2731
 
2666
2732
  Hook to get just the translation function.
2667
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
+
2668
2755
  ```typescript
2669
- function useT(): (
2670
- key: string,
2671
- values?: InterpolationValues,
2672
- options?: { defaultValue?: string; count?: number },
2673
- ) => string
2756
+ function useT(): UseTFunction
2674
2757
  ```
2675
2758
 
2676
- **Returns:** The translation function
2759
+ **Returns:** The translation function (stable identity while the provider is unchanged).
2677
2760
 
2678
2761
  #### `useLocale()`
2679
2762
 
@@ -3148,7 +3231,7 @@ Peer dependencies:
3148
3231
 
3149
3232
  - `@molecule/app-keyboard` ^1.0.1
3150
3233
  - `@molecule/app-lifecycle` ^1.0.1
3151
- - `@molecule/app-react` ^1.0.1
3234
+ - `@molecule/app-react` ^2.0.0
3152
3235
  - `react` ^18.0.0 || ^19.0.0
3153
3236
  - `react-native` >=0.72.0
3154
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": "1.0.4",
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,7 +33,7 @@
33
33
  "directory": "packages/app/frameworks/react-native"
34
34
  },
35
35
  "devDependencies": {
36
- "@molecule/app-react": "1.10.1",
36
+ "@molecule/app-react": "2.0.0",
37
37
  "@types/node": "26.6.5",
38
38
  "react": "19.3.1",
39
39
  "typescript": "6.0.3",
@@ -42,7 +42,7 @@
42
42
  "peerDependencies": {
43
43
  "@molecule/app-keyboard": "^1.0.1",
44
44
  "@molecule/app-lifecycle": "^1.0.1",
45
- "@molecule/app-react": "^1.0.1",
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"