@molecule/app-bonds-default-react 1.1.1 → 1.1.3
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 +28 -10
- package/dist/auth.d.ts +37 -8
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +43 -12
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -3,15 +3,11 @@ 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-18T09:50:35.607Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-bonds-default-react
|
|
10
10
|
|
|
11
|
-
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
-
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
-
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
-
|
|
15
11
|
`@molecule/app-bonds-default-react` — default app-side bond wirings for the
|
|
16
12
|
React fleet stack, replacing the byte-identical per-app files:
|
|
17
13
|
|
|
@@ -39,6 +35,10 @@ React fleet stack, replacing the byte-identical per-app files:
|
|
|
39
35
|
`...WithFetchClient` variants also keep the bonded http client's bearer
|
|
40
36
|
token in sync with auth events.
|
|
41
37
|
|
|
38
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
39
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
40
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
41
|
+
|
|
42
42
|
## Quick Start
|
|
43
43
|
|
|
44
44
|
```tsx
|
|
@@ -105,7 +105,11 @@ stripping a leading `/api/` from request URLs.
|
|
|
105
105
|
Replaces ~20 per-app `bonds/http-default.ts` files that hand-roll
|
|
106
106
|
this same wiring. Pass `stripApiPrefix: true` when the app uses
|
|
107
107
|
`baseURL: '/api'` to handle pages that pass `/api/`-prefixed paths
|
|
108
|
-
(would otherwise resolve to `/api/api/...` and 404).
|
|
108
|
+
(would otherwise resolve to `/api/api/...` and 404). Pass `authScheme`
|
|
109
|
+
when the API reads another scheme than `Bearer`: it is an option of THIS
|
|
110
|
+
constructor (`createDefaultHttpClientWithAuthBearer({ authScheme: 'Token', … })`,
|
|
111
|
+
or `createFetchClient({ baseURL, authScheme: 'Token' })` directly), never a
|
|
112
|
+
property of the client it returns.
|
|
109
113
|
|
|
110
114
|
```typescript
|
|
111
115
|
function createDefaultHttpClientWithAuthBearer(opts: {
|
|
@@ -113,6 +117,7 @@ function createDefaultHttpClientWithAuthBearer(opts: {
|
|
|
113
117
|
withCredentials?: boolean
|
|
114
118
|
stripApiPrefix?: boolean
|
|
115
119
|
getToken: () => string | null | undefined
|
|
120
|
+
authScheme?: string
|
|
116
121
|
}): { httpClient: HttpClient; setupHttpDefault: () => void }
|
|
117
122
|
```
|
|
118
123
|
|
|
@@ -126,7 +131,7 @@ apps shipped byte-identically. Apps pass their own `authConfig`
|
|
|
126
131
|
|
|
127
132
|
```typescript
|
|
128
133
|
function createDefaultAuthClient(authConfig: AuthClientConfig): {
|
|
129
|
-
authClient: AuthClient<TUser>
|
|
134
|
+
authClient: AuthClient<TUser, TRegister>
|
|
130
135
|
setupAuthDefault: () => void
|
|
131
136
|
}
|
|
132
137
|
```
|
|
@@ -140,11 +145,20 @@ client must carry the JWT on every request — without this wiring,
|
|
|
140
145
|
authed endpoints return 401 after page reloads or token refresh.
|
|
141
146
|
|
|
142
147
|
Hydrates the HTTP client's token from the persisted auth state
|
|
143
|
-
on setup, then listens for auth events to keep them aligned
|
|
148
|
+
on setup, then listens for auth events to keep them aligned, and holds
|
|
149
|
+
requests until the session restore settles so a page effect that fetches
|
|
150
|
+
viewer-dependent data on mount cannot race it (see {@link registerAuthGate}).
|
|
151
|
+
|
|
152
|
+
The hydrated token is delivered through `@molecule/app-http`'s token source, not
|
|
153
|
+
through a client read at setup: the scaffold wires auth BEFORE http, so a client
|
|
154
|
+
read here is the unbonded fallback and the restored session's token would land on a
|
|
155
|
+
client nothing sends through (xr-molecule-flash-m156 — a reload sent every request
|
|
156
|
+
with no `Authorization` header). The source is applied to the client WHENEVER it is
|
|
157
|
+
bonded, so setup order no longer decides whether the first request is authorized.
|
|
144
158
|
|
|
145
159
|
```typescript
|
|
146
160
|
function createDefaultAuthClientWithHttpSync(authConfig: AuthClientConfig): {
|
|
147
|
-
authClient: AuthClient<TUser>
|
|
161
|
+
authClient: AuthClient<TUser, TRegister>
|
|
148
162
|
setupAuthDefault: () => void
|
|
149
163
|
}
|
|
150
164
|
```
|
|
@@ -159,11 +173,15 @@ its bearer token in sync with auth events.
|
|
|
159
173
|
Used by apps where molecule packages render pricing / billing /
|
|
160
174
|
other authed JSON-fetching screens that need both behaviors.
|
|
161
175
|
|
|
176
|
+
Requests are also held until the session restore settles (see
|
|
177
|
+
{@link registerAuthGate}), so a page that fetches viewer-dependent data on
|
|
178
|
+
mount cannot race it and answer for an anonymous viewer.
|
|
179
|
+
|
|
162
180
|
```typescript
|
|
163
181
|
function createDefaultAuthClientWithFetchClient(
|
|
164
182
|
authConfig: AuthClientConfig,
|
|
165
183
|
fetchClientOptions: { baseURL: string; withCredentials?: boolean },
|
|
166
|
-
): { authClient: AuthClient<TUser>; setupAuthDefault: () => void }
|
|
184
|
+
): { authClient: AuthClient<TUser, TRegister>; setupAuthDefault: () => void }
|
|
167
185
|
```
|
|
168
186
|
|
|
169
187
|
#### `bootstrapApp(opts)`
|
package/dist/auth.d.ts
CHANGED
|
@@ -26,13 +26,25 @@ export declare function createDefaultHttpClient(baseURL: string): {
|
|
|
26
26
|
* Replaces ~20 per-app `bonds/http-default.ts` files that hand-roll
|
|
27
27
|
* this same wiring. Pass `stripApiPrefix: true` when the app uses
|
|
28
28
|
* `baseURL: '/api'` to handle pages that pass `/api/`-prefixed paths
|
|
29
|
-
* (would otherwise resolve to `/api/api/...` and 404).
|
|
29
|
+
* (would otherwise resolve to `/api/api/...` and 404). Pass `authScheme`
|
|
30
|
+
* when the API reads another scheme than `Bearer`: it is an option of THIS
|
|
31
|
+
* constructor (`createDefaultHttpClientWithAuthBearer({ authScheme: 'Token', … })`,
|
|
32
|
+
* or `createFetchClient({ baseURL, authScheme: 'Token' })` directly), never a
|
|
33
|
+
* property of the client it returns.
|
|
30
34
|
*/
|
|
31
35
|
export declare function createDefaultHttpClientWithAuthBearer(opts: {
|
|
32
36
|
baseURL: string;
|
|
33
37
|
withCredentials?: boolean;
|
|
34
38
|
stripApiPrefix?: boolean;
|
|
35
39
|
getToken: () => string | null | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The scheme of the `Authorization` header the token from `getToken()` is sent
|
|
42
|
+
* with: `Bearer` (default), or what the API expects, e.g. `Token` for an API
|
|
43
|
+
* that reads `Authorization: Token <jwt>`. Pass it to this constructor — the
|
|
44
|
+
* same option `@molecule/app-http`'s client config calls `authScheme`, and not
|
|
45
|
+
* a property of the client that comes back.
|
|
46
|
+
*/
|
|
47
|
+
authScheme?: string;
|
|
36
48
|
}): {
|
|
37
49
|
httpClient: HttpClient;
|
|
38
50
|
setupHttpDefault: () => void;
|
|
@@ -53,9 +65,13 @@ export declare function createDefaultHttpClientWithAuthBearer(opts: {
|
|
|
53
65
|
* export const { authClient, setupAuthDefault } =
|
|
54
66
|
* createDefaultAuthClient(authConfig)
|
|
55
67
|
* ```
|
|
68
|
+
*
|
|
69
|
+
* `TRegister` is the app's own registration fields (`{ username: string }` for a
|
|
70
|
+
* RealWorld-shaped API), passed on to `@molecule/app-auth`'s factory so
|
|
71
|
+
* `authClient.register({ username, email, password })` type-checks with no cast.
|
|
56
72
|
*/
|
|
57
|
-
export declare function createDefaultAuthClient<TUser extends UserProfile = UserProfile>(authConfig: AuthClientConfig): {
|
|
58
|
-
authClient: AuthClient<TUser>;
|
|
73
|
+
export declare function createDefaultAuthClient<TUser extends UserProfile = UserProfile, TRegister extends Record<string, unknown> = Record<never, never>>(authConfig: AuthClientConfig): {
|
|
74
|
+
authClient: AuthClient<TUser, TRegister>;
|
|
59
75
|
setupAuthDefault: () => void;
|
|
60
76
|
};
|
|
61
77
|
/**
|
|
@@ -66,10 +82,19 @@ export declare function createDefaultAuthClient<TUser extends UserProfile = User
|
|
|
66
82
|
* authed endpoints return 401 after page reloads or token refresh.
|
|
67
83
|
*
|
|
68
84
|
* Hydrates the HTTP client's token from the persisted auth state
|
|
69
|
-
* on setup, then listens for auth events to keep them aligned
|
|
85
|
+
* on setup, then listens for auth events to keep them aligned, and holds
|
|
86
|
+
* requests until the session restore settles so a page effect that fetches
|
|
87
|
+
* viewer-dependent data on mount cannot race it (see {@link registerAuthGate}).
|
|
88
|
+
*
|
|
89
|
+
* The hydrated token is delivered through `@molecule/app-http`'s token source, not
|
|
90
|
+
* through a client read at setup: the scaffold wires auth BEFORE http, so a client
|
|
91
|
+
* read here is the unbonded fallback and the restored session's token would land on a
|
|
92
|
+
* client nothing sends through (xr-molecule-flash-m156 — a reload sent every request
|
|
93
|
+
* with no `Authorization` header). The source is applied to the client WHENEVER it is
|
|
94
|
+
* bonded, so setup order no longer decides whether the first request is authorized.
|
|
70
95
|
*/
|
|
71
|
-
export declare function createDefaultAuthClientWithHttpSync<TUser extends UserProfile = UserProfile>(authConfig: AuthClientConfig): {
|
|
72
|
-
authClient: AuthClient<TUser>;
|
|
96
|
+
export declare function createDefaultAuthClientWithHttpSync<TUser extends UserProfile = UserProfile, TRegister extends Record<string, unknown> = Record<never, never>>(authConfig: AuthClientConfig): {
|
|
97
|
+
authClient: AuthClient<TUser, TRegister>;
|
|
73
98
|
setupAuthDefault: () => void;
|
|
74
99
|
};
|
|
75
100
|
/**
|
|
@@ -80,12 +105,16 @@ export declare function createDefaultAuthClientWithHttpSync<TUser extends UserPr
|
|
|
80
105
|
*
|
|
81
106
|
* Used by apps where molecule packages render pricing / billing /
|
|
82
107
|
* other authed JSON-fetching screens that need both behaviors.
|
|
108
|
+
*
|
|
109
|
+
* Requests are also held until the session restore settles (see
|
|
110
|
+
* {@link registerAuthGate}), so a page that fetches viewer-dependent data on
|
|
111
|
+
* mount cannot race it and answer for an anonymous viewer.
|
|
83
112
|
*/
|
|
84
|
-
export declare function createDefaultAuthClientWithFetchClient<TUser extends UserProfile = UserProfile>(authConfig: AuthClientConfig, fetchClientOptions: {
|
|
113
|
+
export declare function createDefaultAuthClientWithFetchClient<TUser extends UserProfile = UserProfile, TRegister extends Record<string, unknown> = Record<never, never>>(authConfig: AuthClientConfig, fetchClientOptions: {
|
|
85
114
|
baseURL: string;
|
|
86
115
|
withCredentials?: boolean;
|
|
87
116
|
}): {
|
|
88
|
-
authClient: AuthClient<TUser>;
|
|
117
|
+
authClient: AuthClient<TUser, TRegister>;
|
|
89
118
|
setupAuthDefault: () => void;
|
|
90
119
|
};
|
|
91
120
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAuCpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,UAAU,EAAE,UAAU,CAAA;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B,CAMA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qCAAqC,CAAC,IAAI,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACzC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG;IACF,UAAU,EAAE,UAAU,CAAA;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B,CAoBA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,SAAS,WAAW,GAAG,WAAW,EACvC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAEhE,UAAU,EAAE,gBAAgB,GAC3B;IACD,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACxC,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B,CAMA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mCAAmC,CACjD,KAAK,SAAS,WAAW,GAAG,WAAW,EACvC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAEhE,UAAU,EAAE,gBAAgB,GAC3B;IACD,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACxC,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B,CA4BA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sCAAsC,CACpD,KAAK,SAAS,WAAW,GAAG,WAAW,EACvC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAEhE,UAAU,EAAE,gBAAgB,EAC5B,kBAAkB,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GACjE;IACD,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACxC,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B,CA2BA"}
|
package/dist/auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createJWTAuthClient, setClient } from '@molecule/app-auth';
|
|
2
|
-
import { createFetchClient, getClient as getHttpClient, setAuthGate, setClient as setHttpClient, } from '@molecule/app-http';
|
|
2
|
+
import { createFetchClient, getClient as getHttpClient, setAuthGate, setAuthTokenSource as setHttpAuthTokenSource, setClient as setHttpClient, } from '@molecule/app-http';
|
|
3
3
|
/**
|
|
4
4
|
* Holds every HTTP request until this auth client's session restore has settled.
|
|
5
5
|
*
|
|
@@ -16,6 +16,14 @@ import { createFetchClient, getClient as getHttpClient, setAuthGate, setClient a
|
|
|
16
16
|
* running. A provider without `whenRestored` (a bond that restores nothing) leaves
|
|
17
17
|
* requests ungated.
|
|
18
18
|
*
|
|
19
|
+
* The restore this gate waits for does NOT go through the gated client — both default auth
|
|
20
|
+
* bonds' `createJWTAuthClient` restores with `fetch` — so the scaffold's own wiring cannot
|
|
21
|
+
* deadlock. An app that registers its own gate over a restore made through the bonded client
|
|
22
|
+
* must exempt that request with `skipAuthGate: true`
|
|
23
|
+
* (`setAuthGate(() => store.whenSettled())` + `http.get(currentUserEndpoint, { skipAuthGate: true })`
|
|
24
|
+
* in the store); otherwise the gate holds the request it is waiting for and every request it
|
|
25
|
+
* holds stalls until the gate times out. See `RequestConfig.skipAuthGate` in `@molecule/app-http`.
|
|
26
|
+
*
|
|
19
27
|
* @param authClient - The bonded auth client.
|
|
20
28
|
*/
|
|
21
29
|
function registerAuthGate(authClient) {
|
|
@@ -50,9 +58,14 @@ export function createDefaultHttpClient(baseURL) {
|
|
|
50
58
|
* Replaces ~20 per-app `bonds/http-default.ts` files that hand-roll
|
|
51
59
|
* this same wiring. Pass `stripApiPrefix: true` when the app uses
|
|
52
60
|
* `baseURL: '/api'` to handle pages that pass `/api/`-prefixed paths
|
|
53
|
-
* (would otherwise resolve to `/api/api/...` and 404).
|
|
61
|
+
* (would otherwise resolve to `/api/api/...` and 404). Pass `authScheme`
|
|
62
|
+
* when the API reads another scheme than `Bearer`: it is an option of THIS
|
|
63
|
+
* constructor (`createDefaultHttpClientWithAuthBearer({ authScheme: 'Token', … })`,
|
|
64
|
+
* or `createFetchClient({ baseURL, authScheme: 'Token' })` directly), never a
|
|
65
|
+
* property of the client it returns.
|
|
54
66
|
*/
|
|
55
67
|
export function createDefaultHttpClientWithAuthBearer(opts) {
|
|
68
|
+
const authScheme = opts.authScheme ?? 'Bearer';
|
|
56
69
|
const httpClient = createFetchClient({
|
|
57
70
|
baseURL: opts.baseURL,
|
|
58
71
|
withCredentials: opts.withCredentials,
|
|
@@ -63,7 +76,7 @@ export function createDefaultHttpClientWithAuthBearer(opts) {
|
|
|
63
76
|
}
|
|
64
77
|
const token = opts.getToken();
|
|
65
78
|
if (token) {
|
|
66
|
-
config.headers = { ...config.headers, Authorization:
|
|
79
|
+
config.headers = { ...config.headers, Authorization: `${authScheme} ${token}` };
|
|
67
80
|
}
|
|
68
81
|
return config;
|
|
69
82
|
});
|
|
@@ -88,6 +101,10 @@ export function createDefaultHttpClientWithAuthBearer(opts) {
|
|
|
88
101
|
* export const { authClient, setupAuthDefault } =
|
|
89
102
|
* createDefaultAuthClient(authConfig)
|
|
90
103
|
* ```
|
|
104
|
+
*
|
|
105
|
+
* `TRegister` is the app's own registration fields (`{ username: string }` for a
|
|
106
|
+
* RealWorld-shaped API), passed on to `@molecule/app-auth`'s factory so
|
|
107
|
+
* `authClient.register({ username, email, password })` type-checks with no cast.
|
|
91
108
|
*/
|
|
92
109
|
export function createDefaultAuthClient(authConfig) {
|
|
93
110
|
const authClient = createJWTAuthClient(authConfig);
|
|
@@ -104,7 +121,16 @@ export function createDefaultAuthClient(authConfig) {
|
|
|
104
121
|
* authed endpoints return 401 after page reloads or token refresh.
|
|
105
122
|
*
|
|
106
123
|
* Hydrates the HTTP client's token from the persisted auth state
|
|
107
|
-
* on setup, then listens for auth events to keep them aligned
|
|
124
|
+
* on setup, then listens for auth events to keep them aligned, and holds
|
|
125
|
+
* requests until the session restore settles so a page effect that fetches
|
|
126
|
+
* viewer-dependent data on mount cannot race it (see {@link registerAuthGate}).
|
|
127
|
+
*
|
|
128
|
+
* The hydrated token is delivered through `@molecule/app-http`'s token source, not
|
|
129
|
+
* through a client read at setup: the scaffold wires auth BEFORE http, so a client
|
|
130
|
+
* read here is the unbonded fallback and the restored session's token would land on a
|
|
131
|
+
* client nothing sends through (xr-molecule-flash-m156 — a reload sent every request
|
|
132
|
+
* with no `Authorization` header). The source is applied to the client WHENEVER it is
|
|
133
|
+
* bonded, so setup order no longer decides whether the first request is authorized.
|
|
108
134
|
*/
|
|
109
135
|
export function createDefaultAuthClientWithHttpSync(authConfig) {
|
|
110
136
|
const authClient = createJWTAuthClient(authConfig);
|
|
@@ -115,10 +141,11 @@ export function createDefaultAuthClientWithHttpSync(authConfig) {
|
|
|
115
141
|
// Requests made while the session is still restoring wait for it, so a page
|
|
116
142
|
// effect that fetches viewer-dependent data on mount cannot race the restore.
|
|
117
143
|
registerAuthGate(authClient);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
144
|
+
// Resolve the HTTP client per sync, never once here. `setClient` runs this
|
|
145
|
+
// source, so the token reaches the client the scaffold bonds later as well as
|
|
146
|
+
// one already bonded; a client kept from this moment would be the throwaway
|
|
147
|
+
// fallback the later `setHttpDefault()` replaces.
|
|
148
|
+
setHttpAuthTokenSource(() => authClient.getAccessToken());
|
|
122
149
|
authClient.addEventListener((event) => {
|
|
123
150
|
if (event.type === 'login' || event.type === 'register' || event.type === 'refresh') {
|
|
124
151
|
// Mirror the auth client's token EXACTLY — including null. Cookie-session
|
|
@@ -143,6 +170,10 @@ export function createDefaultAuthClientWithHttpSync(authConfig) {
|
|
|
143
170
|
*
|
|
144
171
|
* Used by apps where molecule packages render pricing / billing /
|
|
145
172
|
* other authed JSON-fetching screens that need both behaviors.
|
|
173
|
+
*
|
|
174
|
+
* Requests are also held until the session restore settles (see
|
|
175
|
+
* {@link registerAuthGate}), so a page that fetches viewer-dependent data on
|
|
176
|
+
* mount cannot race it and answer for an anonymous viewer.
|
|
146
177
|
*/
|
|
147
178
|
export function createDefaultAuthClientWithFetchClient(authConfig, fetchClientOptions) {
|
|
148
179
|
const authClient = createJWTAuthClient(authConfig);
|
|
@@ -153,13 +184,13 @@ export function createDefaultAuthClientWithFetchClient(authConfig, fetchClientOp
|
|
|
153
184
|
baseURL: fetchClientOptions.baseURL,
|
|
154
185
|
withCredentials: fetchClientOptions.withCredentials ?? true,
|
|
155
186
|
});
|
|
187
|
+
// Registered BEFORE the bond: `setHttpClient` applies the restored session's
|
|
188
|
+
// token, and the same source reaches any client an app bonds later instead of
|
|
189
|
+
// this one (xr-molecule-flash-m156 — a client captured at setup cannot).
|
|
190
|
+
setHttpAuthTokenSource(() => authClient.getAccessToken());
|
|
156
191
|
setHttpClient(httpClient);
|
|
157
192
|
setClient(authClient);
|
|
158
193
|
registerAuthGate(authClient);
|
|
159
|
-
const initialToken = authClient.getAccessToken();
|
|
160
|
-
if (initialToken) {
|
|
161
|
-
httpClient.setAuthToken(initialToken);
|
|
162
|
-
}
|
|
163
194
|
authClient.addEventListener((event) => {
|
|
164
195
|
if (event.type === 'login' || event.type === 'register' || event.type === 'refresh') {
|
|
165
196
|
// Mirror the token exactly, including null — see the identical note in
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-bonds-default-react",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Default app-side bond wirings for React+Tailwind+react-router+localStorage+Arimo font+molecule icons. 5 setup functions consolidating 665 byte-identical per-app bond wiring files across the fleet.",
|
|
5
5
|
"homepage": "https://www.molecule.dev/packages/app-bonds-default-react",
|
|
6
6
|
"type": "module",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"directory": "packages/app/infrastructure/bonds-default-react"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@molecule/app-auth": "1.
|
|
41
|
+
"@molecule/app-auth": "1.5.2",
|
|
42
42
|
"@molecule/app-charts-chartjs": "1.0.2",
|
|
43
43
|
"@molecule/app-client-search": "1.0.2",
|
|
44
44
|
"@molecule/app-client-search-minisearch": "1.0.3",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"@molecule/app-command-palette-cmdk": "1.0.2",
|
|
49
49
|
"@molecule/app-drag-drop": "1.0.2",
|
|
50
50
|
"@molecule/app-drag-drop-dndkit": "1.0.2",
|
|
51
|
-
"@molecule/app-fonts": "1.1
|
|
52
|
-
"@molecule/app-fonts-arimo": "1.0.
|
|
53
|
-
"@molecule/app-http": "1.
|
|
51
|
+
"@molecule/app-fonts": "1.2.1",
|
|
52
|
+
"@molecule/app-fonts-arimo": "1.0.3",
|
|
53
|
+
"@molecule/app-http": "1.2.0",
|
|
54
54
|
"@molecule/app-icons": "1.0.2",
|
|
55
55
|
"@molecule/app-icons-molecule": "1.0.2",
|
|
56
56
|
"@molecule/app-keyboard-shortcuts": "1.0.2",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@molecule/app-storage-localstorage": "1.0.2",
|
|
66
66
|
"@molecule/app-theme": "1.0.3",
|
|
67
67
|
"@molecule/app-theme-css-variables": "1.0.3",
|
|
68
|
-
"@molecule/app-ui": "1.3.
|
|
68
|
+
"@molecule/app-ui": "1.3.7",
|
|
69
69
|
"@molecule/app-ui-tailwind": "1.2.6",
|
|
70
70
|
"@molecule/app-video-hls": "1.0.2",
|
|
71
71
|
"@molecule/app-virtual-scroll": "1.0.2",
|