talizen 0.2.20 → 0.2.22

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 (4) hide show
  1. package/auth.d.ts +3 -0
  2. package/auth.js +22 -4
  3. package/i18n.js +3 -2
  4. package/package.json +1 -1
package/auth.d.ts CHANGED
@@ -73,6 +73,9 @@ export interface UseAuthResult {
73
73
  *
74
74
  * The hook reloads `/auth/me` whenever `setTalizenConfig()` changes runtime
75
75
  * config, which lets preview auth headers update the page without remounting.
76
+ *
77
+ * The returned object and its `user` keep stable references until the auth
78
+ * state actually changes, so both are safe to use in React dependency arrays.
76
79
  */
77
80
  export declare function useAuth(options?: TalizenRequestOptions): UseAuthResult;
78
81
  export declare function updateProfile(profile: AuthProfile, options?: TalizenRequestOptions): Promise<AuthUser>;
package/auth.js CHANGED
@@ -76,6 +76,14 @@ function normalizeRegisterInput(input, password, name) {
76
76
  function isUnauthenticatedError(error) {
77
77
  return error instanceof TalizenHttpError && error.status === 401;
78
78
  }
79
+ // AuthUser is plain JSON response data, so serialize-compare is sufficient.
80
+ function isSameAuthUser(a, b) {
81
+ if (a === b)
82
+ return true;
83
+ if (!a || !b)
84
+ return false;
85
+ return JSON.stringify(a) === JSON.stringify(b);
86
+ }
79
87
  async function refreshAuthState(options) {
80
88
  const requestId = authRequestId + 1;
81
89
  authRequestId = requestId;
@@ -83,8 +91,13 @@ async function refreshAuthState(options) {
83
91
  authErrorState = null;
84
92
  emitAuthChange();
85
93
  try {
86
- const user = await fetchCurrentUser(options);
94
+ let user = await fetchCurrentUser(options);
87
95
  if (authRequestId === requestId) {
96
+ // Keep the previous reference when the payload is unchanged so `user`
97
+ // stays stable for React dependency arrays.
98
+ if (isSameAuthUser(currentUserState, user)) {
99
+ user = currentUserState;
100
+ }
88
101
  currentUserState = user;
89
102
  authErrorState = null;
90
103
  isAuthInitialized = true;
@@ -109,7 +122,9 @@ async function refreshAuthState(options) {
109
122
  }
110
123
  function setAuthUser(user) {
111
124
  authRequestId += 1;
112
- currentUserState = user;
125
+ if (!isSameAuthUser(currentUserState, user)) {
126
+ currentUserState = user;
127
+ }
113
128
  authErrorState = null;
114
129
  isAuthInitialized = true;
115
130
  isAuthLoading = false;
@@ -120,6 +135,9 @@ function setAuthUser(user) {
120
135
  *
121
136
  * The hook reloads `/auth/me` whenever `setTalizenConfig()` changes runtime
122
137
  * config, which lets preview auth headers update the page without remounting.
138
+ *
139
+ * The returned object and its `user` keep stable references until the auth
140
+ * state actually changes, so both are safe to use in React dependency arrays.
123
141
  */
124
142
  export function useAuth(options) {
125
143
  const snapshot = React.useSyncExternalStore(subscribeAuth, () => authSnapshot, () => authSnapshot);
@@ -153,14 +171,14 @@ export function useAuth(options) {
153
171
  setAuthUser(nextUser);
154
172
  return nextUser;
155
173
  }, []);
156
- return {
174
+ return React.useMemo(() => ({
157
175
  ...snapshot,
158
176
  refresh,
159
177
  login: loginAndRefresh,
160
178
  register: registerAndRefresh,
161
179
  logout: logoutAndRefresh,
162
180
  updateProfile: updateProfileAndRefresh,
163
- };
181
+ }), [snapshot, refresh, loginAndRefresh, registerAndRefresh, logoutAndRefresh, updateProfileAndRefresh]);
164
182
  }
165
183
  async function logoutRequest(options) {
166
184
  await requestJson("/auth/logout", {
package/i18n.js CHANGED
@@ -6,10 +6,11 @@ let lastSnapshotI18n;
6
6
  let lastSnapshotMessages;
7
7
  function readI18nRuntimeConfig() {
8
8
  const config = getTalizenConfig();
9
+ const globalConfig = typeof globalThis !== "undefined" ? globalThis.TalizenConfig : undefined;
9
10
  const fallbackI18n = typeof globalThis !== "undefined" ? globalThis.__TALIZEN_I18N__ : undefined;
10
11
  const fallbackMessages = typeof globalThis !== "undefined" ? globalThis.__TALIZEN_MESSAGES__ : undefined;
11
- const i18n = config.i18n ?? fallbackI18n;
12
- const messages = config.messages ?? fallbackMessages ?? emptyMessages;
12
+ const i18n = config.i18n ?? globalConfig?.i18n ?? fallbackI18n;
13
+ const messages = config.messages ?? globalConfig?.messages ?? fallbackMessages ?? emptyMessages;
13
14
  if (lastSnapshot && lastSnapshotI18n === i18n && lastSnapshotMessages === messages) {
14
15
  return lastSnapshot;
15
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talizen",
3
- "version": "0.2.20",
3
+ "version": "0.2.22",
4
4
  "description": "Talizen frontend SDK types for cms, form and core.",
5
5
  "type": "module",
6
6
  "license": "MIT",