@stackframe/stack 2.4.17 → 2.4.18

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 (86) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/components/credential-sign-in.js +1 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.js +1 -1
  5. package/dist/components/credential-sign-up.js.map +1 -1
  6. package/dist/components/forgot-password.js +1 -1
  7. package/dist/components/forgot-password.js.map +1 -1
  8. package/dist/components/magic-link-sign-in.js +1 -1
  9. package/dist/components/magic-link-sign-in.js.map +1 -1
  10. package/dist/components/maybe-full-page.js +1 -1
  11. package/dist/components/maybe-full-page.js.map +1 -1
  12. package/dist/components/password-reset-inner.js +1 -1
  13. package/dist/components/password-reset-inner.js.map +1 -1
  14. package/dist/components/user-avatar.d.mts +1 -0
  15. package/dist/components/user-avatar.d.ts +1 -0
  16. package/dist/components/user-avatar.js +1 -1
  17. package/dist/components/user-avatar.js.map +1 -1
  18. package/dist/components/user-button.js +4 -4
  19. package/dist/components/user-button.js.map +1 -1
  20. package/dist/components-core/button.js.map +1 -1
  21. package/dist/components-core/index.d.mts +3 -3
  22. package/dist/components-core/index.d.ts +3 -3
  23. package/dist/components-core-joy/button.js +1 -1
  24. package/dist/components-core-joy/button.js.map +1 -1
  25. package/dist/components-page/account-settings.js +1 -1
  26. package/dist/components-page/account-settings.js.map +1 -1
  27. package/dist/components-page/stack-handler.d.mts +1 -0
  28. package/dist/components-page/stack-handler.d.ts +1 -0
  29. package/dist/esm/components/credential-sign-in.js +2 -2
  30. package/dist/esm/components/credential-sign-in.js.map +1 -1
  31. package/dist/esm/components/credential-sign-up.js +2 -2
  32. package/dist/esm/components/credential-sign-up.js.map +1 -1
  33. package/dist/esm/components/forgot-password.js +2 -2
  34. package/dist/esm/components/forgot-password.js.map +1 -1
  35. package/dist/esm/components/magic-link-sign-in.js +2 -2
  36. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  37. package/dist/esm/components/maybe-full-page.js +1 -1
  38. package/dist/esm/components/maybe-full-page.js.map +1 -1
  39. package/dist/esm/components/password-reset-inner.js +2 -2
  40. package/dist/esm/components/password-reset-inner.js.map +1 -1
  41. package/dist/esm/components/user-avatar.js +1 -1
  42. package/dist/esm/components/user-avatar.js.map +1 -1
  43. package/dist/esm/components/user-button.js +5 -5
  44. package/dist/esm/components/user-button.js.map +1 -1
  45. package/dist/esm/components-core/button.js.map +1 -1
  46. package/dist/esm/components-core-joy/button.js +1 -1
  47. package/dist/esm/components-core-joy/button.js.map +1 -1
  48. package/dist/esm/components-page/account-settings.js +1 -1
  49. package/dist/esm/components-page/account-settings.js.map +1 -1
  50. package/dist/esm/lib/auth.js +2 -3
  51. package/dist/esm/lib/auth.js.map +1 -1
  52. package/dist/esm/lib/stack-app.js +218 -168
  53. package/dist/esm/lib/stack-app.js.map +1 -1
  54. package/dist/esm/providers/stack-provider-client.js +2 -1
  55. package/dist/esm/providers/stack-provider-client.js.map +1 -1
  56. package/dist/esm/providers/styled-components-registry.js +2 -1
  57. package/dist/esm/providers/styled-components-registry.js.map +1 -1
  58. package/dist/index.d.mts +1 -0
  59. package/dist/index.d.ts +1 -0
  60. package/dist/lib/auth.d.mts +5 -3
  61. package/dist/lib/auth.d.ts +5 -3
  62. package/dist/lib/auth.js +2 -3
  63. package/dist/lib/auth.js.map +1 -1
  64. package/dist/lib/hooks.d.mts +1 -0
  65. package/dist/lib/hooks.d.ts +1 -0
  66. package/dist/lib/stack-app.d.mts +23 -16
  67. package/dist/lib/stack-app.d.ts +23 -16
  68. package/dist/lib/stack-app.js +217 -167
  69. package/dist/lib/stack-app.js.map +1 -1
  70. package/dist/providers/component-provider.d.mts +4 -4
  71. package/dist/providers/component-provider.d.ts +4 -4
  72. package/dist/providers/stack-provider-client.d.mts +1 -0
  73. package/dist/providers/stack-provider-client.d.ts +1 -0
  74. package/dist/providers/stack-provider-client.js +2 -1
  75. package/dist/providers/stack-provider-client.js.map +1 -1
  76. package/dist/providers/stack-provider.d.mts +1 -0
  77. package/dist/providers/stack-provider.d.ts +1 -0
  78. package/dist/providers/styled-components-registry.js +2 -1
  79. package/dist/providers/styled-components-registry.js.map +1 -1
  80. package/package.json +2 -2
  81. package/dist/esm/utils/next.js +0 -8
  82. package/dist/esm/utils/next.js.map +0 -1
  83. package/dist/utils/next.d.mts +0 -3
  84. package/dist/utils/next.d.ts +0 -3
  85. package/dist/utils/next.js +0 -33
  86. package/dist/utils/next.js.map +0 -1
@@ -6,9 +6,9 @@ import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/uti
6
6
  import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids";
7
7
  import { AsyncResult, Result } from "@stackframe/stack-shared/dist/utils/results";
8
8
  import { suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
9
- import { AsyncStore } from "@stackframe/stack-shared/dist/utils/stores";
9
+ import { Store } from "@stackframe/stack-shared/dist/utils/stores";
10
10
  import { getProductionModeErrors } from "@stackframe/stack-shared/dist/interface/clientInterface";
11
- import { isClient } from "../utils/next";
11
+ import { isBrowserLike } from "@stackframe/stack-shared/src/utils/env";
12
12
  import { callOAuthCallback, signInWithOAuth } from "./auth";
13
13
  import * as NextNavigationUnscrambled from "next/navigation";
14
14
  import { constructRedirectUrl } from "../utils/url";
@@ -19,8 +19,10 @@ import { suspend } from "@stackframe/stack-shared/dist/utils/react";
19
19
  import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
20
20
  import { isReactServer } from "@stackframe/stack-sc";
21
21
  import * as cookie from "cookie";
22
+ import { Session } from "@stackframe/stack-shared/dist/sessions";
23
+ import { useTrigger } from "@stackframe/stack-shared/dist/hooks/use-trigger";
22
24
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
23
- var clientVersion = "js @stackframe/stack@2.4.17";
25
+ var clientVersion = "js @stackframe/stack@2.4.18";
24
26
  function permissionDefinitionScopeToType(scope) {
25
27
  return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
26
28
  }
@@ -61,45 +63,50 @@ function getDefaultBaseUrl() {
61
63
  }
62
64
  var defaultBaseUrl = "https://app.stack-auth.com";
63
65
  function createEmptyTokenStore() {
64
- return new AsyncStore({
66
+ return new Store({
65
67
  refreshToken: null,
66
68
  accessToken: null
67
69
  });
68
70
  }
69
- var cookieTokenStore = null;
70
- var cookieTokenStoreInitializer = () => {
71
- if (!isClient()) {
71
+ var storedCookieTokenStore = null;
72
+ var getCookieTokenStore = () => {
73
+ if (!isBrowserLike()) {
72
74
  throw new Error("Cannot use cookie token store on the server!");
73
75
  }
74
- if (cookieTokenStore === null) {
75
- cookieTokenStore = new AsyncStore();
76
+ if (storedCookieTokenStore === null) {
77
+ const getCurrentValue = () => ({
78
+ refreshToken: getCookie("stack-refresh"),
79
+ accessToken: getCookie("stack-access")
80
+ });
81
+ storedCookieTokenStore = new Store(getCurrentValue());
76
82
  let hasSucceededInWriting = true;
77
83
  setInterval(() => {
78
84
  if (hasSucceededInWriting) {
79
- const newValue = {
80
- refreshToken: getCookie("stack-refresh"),
81
- accessToken: getCookie("stack-access")
82
- };
83
- const res = cookieTokenStore.get();
84
- if (res.status !== "ok" || res.data.refreshToken !== newValue.refreshToken || res.data.accessToken !== newValue.accessToken) {
85
- cookieTokenStore.set(newValue);
85
+ const currentValue = getCurrentValue();
86
+ const oldValue = storedCookieTokenStore.get();
87
+ if (JSON.stringify(currentValue) !== JSON.stringify(oldValue)) {
88
+ storedCookieTokenStore.set(currentValue);
86
89
  }
87
90
  }
88
- }, 10);
89
- cookieTokenStore.onChange((value) => {
91
+ }, 100);
92
+ storedCookieTokenStore.onChange((value) => {
90
93
  try {
91
94
  setOrDeleteCookie("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
92
95
  setOrDeleteCookie("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
93
96
  hasSucceededInWriting = true;
94
97
  } catch (e) {
95
- hasSucceededInWriting = false;
98
+ if (!isBrowserLike()) {
99
+ hasSucceededInWriting = false;
100
+ } else {
101
+ throw e;
102
+ }
96
103
  }
97
104
  });
98
105
  }
99
- return cookieTokenStore;
106
+ return storedCookieTokenStore;
100
107
  };
101
108
  var loadingSentinel = Symbol("stackAppCacheLoadingSentinel");
102
- function useCache(cache, dependencies, caller) {
109
+ function useAsyncCache(cache, dependencies, caller) {
103
110
  suspendIfSsr(caller);
104
111
  const subscribe = useCallback((cb) => {
105
112
  const { unsubscribe } = cache.onChange(dependencies, () => cb());
@@ -123,17 +130,13 @@ var createCache = (fetcher) => {
123
130
  {}
124
131
  );
125
132
  };
126
- var createCacheByTokenStore = (fetcher) => {
133
+ var createCacheBySession = (fetcher) => {
127
134
  return new AsyncCache(
128
- async ([tokenStore, ...extraDependencies]) => await fetcher(tokenStore, extraDependencies),
135
+ async ([session, ...extraDependencies]) => await fetcher(session, extraDependencies),
129
136
  {
130
- onSubscribe: ([tokenStore], refresh) => {
131
- const handlerObj = tokenStore.onChange((newValue, oldValue) => {
132
- if (newValue.refreshToken === oldValue?.refreshToken)
133
- return;
134
- refresh();
135
- });
136
- return () => handlerObj.unsubscribe();
137
+ onSubscribe: ([session], refresh) => {
138
+ const handler = session.onInvalidate(() => refresh());
139
+ return () => handler.unsubscribe();
137
140
  }
138
141
  }
139
142
  );
@@ -160,7 +163,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
160
163
  }
161
164
  numberOfAppsCreated++;
162
165
  if (numberOfAppsCreated > 10) {
163
- console.warn(`You have created more than 10 Stack apps (${numberOfAppsCreated}). This is usually a sign of a memory leak. Make sure to minimize the number of Stack apps per page (usually, one per project).`);
166
+ (process.env.NODE_ENV === "development" ? console.log : console.warn)(`You have created more than 10 Stack apps (${numberOfAppsCreated}). This is usually a sign of a memory leak, but can sometimes be caused by hot reload of your tech stack. In production, make sure to minimize the number of Stack apps per page (usually, one per project).`);
164
167
  }
165
168
  }
166
169
  _uniqueIdentifier = void 0;
@@ -168,24 +171,24 @@ var _StackClientAppImpl = class __StackClientAppImpl {
168
171
  _tokenStoreInit;
169
172
  _urlOptions;
170
173
  __DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
171
- _currentUserCache = createCacheByTokenStore(async (tokenStore) => {
174
+ _currentUserCache = createCacheBySession(async (session) => {
172
175
  if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
173
176
  await wait(2e3);
174
177
  }
175
- const user = await this._interface.getClientUserByToken(tokenStore);
178
+ const user = await this._interface.getClientUserByToken(session);
176
179
  return Result.or(user, null);
177
180
  });
178
181
  _currentProjectCache = createCache(async () => {
179
182
  return Result.orThrow(await this._interface.getClientProject());
180
183
  });
181
- _ownedProjectsCache = createCacheByTokenStore(async (tokenStore) => {
182
- return await this._interface.listProjects(tokenStore);
184
+ _ownedProjectsCache = createCacheBySession(async (session) => {
185
+ return await this._interface.listProjects(session);
183
186
  });
184
- _currentUserPermissionsCache = createCacheByTokenStore(async (tokenStore, [teamId, type, direct]) => {
185
- return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, tokenStore);
187
+ _currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
188
+ return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
186
189
  });
187
- _currentUserTeamsCache = createCacheByTokenStore(async (tokenStore) => {
188
- return await this._interface.listClientUserTeams(tokenStore);
190
+ _currentUserTeamsCache = createCacheBySession(async (session) => {
191
+ return await this._interface.listClientUserTeams(session);
189
192
  });
190
193
  _initUniqueIdentifier() {
191
194
  if (!this._uniqueIdentifier) {
@@ -208,19 +211,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
208
211
  return this._uniqueIdentifier;
209
212
  }
210
213
  _memoryTokenStore = createEmptyTokenStore();
211
- _requestTokenStores = /* @__PURE__ */ new Map();
212
- _getTokenStore(overrideTokenStoreInit) {
214
+ _requestTokenStores = /* @__PURE__ */ new WeakMap();
215
+ _getOrCreateTokenStore(overrideTokenStoreInit) {
213
216
  const tokenStoreInit = overrideTokenStoreInit === void 0 ? this._tokenStoreInit : overrideTokenStoreInit;
214
217
  switch (tokenStoreInit) {
215
218
  case "cookie": {
216
- return cookieTokenStoreInitializer();
219
+ return getCookieTokenStore();
217
220
  }
218
221
  case "nextjs-cookie": {
219
- if (isClient()) {
220
- return cookieTokenStoreInitializer();
222
+ if (isBrowserLike()) {
223
+ return getCookieTokenStore();
221
224
  } else {
222
- const store = new AsyncStore();
223
- store.set({
225
+ const store = new Store({
224
226
  refreshToken: getCookie("stack-refresh"),
225
227
  accessToken: getCookie("stack-access")
226
228
  });
@@ -241,12 +243,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
241
243
  return createEmptyTokenStore();
242
244
  }
243
245
  default: {
244
- if (tokenStoreInit && typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
246
+ if (tokenStoreInit !== null && typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
245
247
  if (this._requestTokenStores.has(tokenStoreInit))
246
248
  return this._requestTokenStores.get(tokenStoreInit);
247
249
  const cookieHeader = tokenStoreInit.headers.get("cookie");
248
250
  const parsed = cookie.parse(cookieHeader || "");
249
- const res = new AsyncStore({
251
+ const res = new Store({
250
252
  refreshToken: parsed["stack-refresh"] || null,
251
253
  accessToken: parsed["stack-access"] || null
252
254
  });
@@ -257,6 +259,60 @@ var _StackClientAppImpl = class __StackClientAppImpl {
257
259
  }
258
260
  }
259
261
  }
262
+ /**
263
+ * A map from token stores and session keys to sessions.
264
+ *
265
+ * This isn't just a map from session keys to sessions for two reasons:
266
+ *
267
+ * - So we can garbage-collect Session objects when the token store is garbage-collected
268
+ * - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
269
+ */
270
+ _sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
271
+ _getSessionFromTokenStore(tokenStore) {
272
+ const tokenObj = tokenStore.get();
273
+ const sessionKey = Session.calculateSessionKey(tokenObj);
274
+ const existing = sessionKey ? this._sessionsByTokenStoreAndSessionKey.get(tokenStore)?.get(sessionKey) : null;
275
+ if (existing)
276
+ return existing;
277
+ const session = this._interface.createSession({
278
+ refreshToken: tokenObj.refreshToken,
279
+ accessToken: tokenObj.accessToken
280
+ });
281
+ session.onAccessTokenChange((newAccessToken) => {
282
+ tokenStore.update((old) => ({
283
+ ...old,
284
+ accessToken: newAccessToken?.token ?? null
285
+ }));
286
+ });
287
+ session.onInvalidate(() => {
288
+ tokenStore.update((old) => ({
289
+ ...old,
290
+ accessToken: null,
291
+ refreshToken: null
292
+ }));
293
+ });
294
+ let sessionsBySessionKey = this._sessionsByTokenStoreAndSessionKey.get(tokenStore) ?? /* @__PURE__ */ new Map();
295
+ this._sessionsByTokenStoreAndSessionKey.set(tokenStore, sessionsBySessionKey);
296
+ sessionsBySessionKey.set(sessionKey, session);
297
+ return session;
298
+ }
299
+ _getSession(overrideTokenStoreInit) {
300
+ const tokenStore = this._getOrCreateTokenStore(overrideTokenStoreInit);
301
+ return this._getSessionFromTokenStore(tokenStore);
302
+ }
303
+ _useSession(overrideTokenStoreInit) {
304
+ const tokenStore = this._getOrCreateTokenStore(overrideTokenStoreInit);
305
+ const subscribe = useCallback((cb) => {
306
+ const { unsubscribe } = tokenStore.onChange(() => cb());
307
+ return unsubscribe;
308
+ }, [tokenStore]);
309
+ const getSnapshot = useCallback(() => this._getSessionFromTokenStore(tokenStore), [tokenStore]);
310
+ return React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
311
+ }
312
+ async _signInToAccountWithTokens(tokens) {
313
+ const tokenStore = this._getOrCreateTokenStore();
314
+ tokenStore.set(tokens);
315
+ }
260
316
  _hasPersistentTokenStore(overrideTokenStoreInit) {
261
317
  return (overrideTokenStoreInit !== void 0 ? overrideTokenStoreInit : this._tokenStoreInit) !== null;
262
318
  }
@@ -336,24 +392,25 @@ var _StackClientAppImpl = class __StackClientAppImpl {
336
392
  });
337
393
  },
338
394
  async listTeams() {
339
- const teams = await app._currentUserTeamsCache.getOrWait([app._getTokenStore()], "write-only");
395
+ const teams = await app._currentUserTeamsCache.getOrWait([app._getSession()], "write-only");
340
396
  return teams.map((json2) => app._teamFromJson(json2));
341
397
  },
342
398
  useTeams() {
343
- const teams = useCache(app._currentUserTeamsCache, [app._getTokenStore()], "user.useTeams()");
399
+ const session = app._useSession();
400
+ const teams = useAsyncCache(app._currentUserTeamsCache, [session], "user.useTeams()");
344
401
  return useMemo(() => teams.map((json2) => app._teamFromJson(json2)), [teams]);
345
402
  },
346
403
  onTeamsChange(callback) {
347
- return app._currentUserTeamsCache.onChange([app._getTokenStore()], (value, oldValue) => {
404
+ return app._currentUserTeamsCache.onChange([app._getSession()], (value, oldValue) => {
348
405
  callback(value.map((json2) => app._teamFromJson(json2)), oldValue?.map((json2) => app._teamFromJson(json2)));
349
406
  });
350
407
  },
351
408
  async listPermissions(scope, options) {
352
- const permissions = await app._currentUserPermissionsCache.getOrWait([app._getTokenStore(), scope.id, "team", !!options?.direct], "write-only");
409
+ const permissions = await app._currentUserPermissionsCache.getOrWait([app._getSession(), scope.id, "team", !!options?.direct], "write-only");
353
410
  return permissions.map((json2) => app._permissionFromJson(json2));
354
411
  },
355
412
  usePermissions(scope, options) {
356
- const permissions = useCache(app._currentUserPermissionsCache, [app._getTokenStore(), scope.id, "team", !!options?.direct], "user.usePermissions()");
413
+ const permissions = useAsyncCache(app._currentUserPermissionsCache, [app._getSession(), scope.id, "team", !!options?.direct], "user.usePermissions()");
357
414
  return useMemo(() => permissions.map((json2) => app._permissionFromJson(json2)), [permissions]);
358
415
  },
359
416
  usePermission(scope, permissionId) {
@@ -381,30 +438,27 @@ var _StackClientAppImpl = class __StackClientAppImpl {
381
438
  displayName: json.displayName
382
439
  };
383
440
  }
384
- _currentUserFromJson(json, tokenStore) {
441
+ _currentUserFromJson(json, session) {
385
442
  if (json === null)
386
443
  return null;
387
444
  const app = this;
388
445
  const currentUser = {
389
446
  ...this._userFromJson(json),
390
- tokenStore,
391
- async refreshAccessToken() {
392
- await app._interface.refreshAccessToken(tokenStore);
393
- },
447
+ session,
394
448
  async updateSelectedTeam(team) {
395
- await app._updateUser({ selectedTeamId: team?.id ?? null }, tokenStore);
449
+ await app._updateUser({ selectedTeamId: team?.id ?? null }, session);
396
450
  },
397
451
  update(update) {
398
- return app._updateUser(update, tokenStore);
452
+ return app._updateUser(update, session);
399
453
  },
400
454
  signOut() {
401
- return app._signOut(tokenStore);
455
+ return app._signOut(session);
402
456
  },
403
457
  sendVerificationEmail() {
404
- return app._sendVerificationEmail(tokenStore);
458
+ return app._sendVerificationEmail(session);
405
459
  },
406
460
  updatePassword(options) {
407
- return app._updatePassword(options, tokenStore);
461
+ return app._updatePassword(options, session);
408
462
  }
409
463
  };
410
464
  if (this._isInternalProject()) {
@@ -463,13 +517,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
463
517
  }
464
518
  };
465
519
  }
466
- _createAdminInterface(forProjectId, tokenStore) {
520
+ _createAdminInterface(forProjectId, session) {
467
521
  return new StackAdminInterface({
468
522
  baseUrl: this._interface.options.baseUrl,
469
523
  projectId: forProjectId,
470
524
  clientVersion,
471
- projectOwnerTokens: tokenStore,
472
- refreshProjectOwnerTokens: async () => await this._interface.refreshAccessToken(tokenStore)
525
+ projectOwnerSession: session
473
526
  });
474
527
  }
475
528
  get projectId() {
@@ -555,8 +608,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
555
608
  }
556
609
  async getUser(options) {
557
610
  this._ensurePersistentTokenStore(options?.tokenStore);
558
- const tokenStore = this._getTokenStore(options?.tokenStore);
559
- const userJson = await this._currentUserCache.getOrWait([tokenStore], "write-only");
611
+ const session = this._getSession(options?.tokenStore);
612
+ const userJson = await this._currentUserCache.getOrWait([session], "write-only");
560
613
  if (userJson === null) {
561
614
  switch (options?.or) {
562
615
  case "redirect": {
@@ -571,20 +624,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
571
624
  }
572
625
  }
573
626
  }
574
- return this._currentUserFromJson(userJson, tokenStore);
627
+ return this._currentUserFromJson(userJson, session);
575
628
  }
576
629
  useUser(options) {
577
630
  this._ensurePersistentTokenStore(options?.tokenStore);
578
631
  const router = NextNavigation.useRouter();
579
- const tokenStore = this._getTokenStore(options?.tokenStore);
580
- const userJson = useCache(this._currentUserCache, [tokenStore], "useUser()");
632
+ const session = this._getSession(options?.tokenStore);
633
+ const userJson = useAsyncCache(this._currentUserCache, [session], "useUser()");
634
+ const triggerRedirectToSignIn = useTrigger(() => router.replace(this.urls.signIn));
581
635
  if (userJson === null) {
582
636
  switch (options?.or) {
583
637
  case "redirect": {
584
- runAsynchronously(async () => {
585
- await wait(0);
586
- router.replace(this.urls.signIn);
587
- });
638
+ triggerRedirectToSignIn();
588
639
  suspend();
589
640
  throw new StackAssertionError("suspend should never return");
590
641
  }
@@ -597,19 +648,19 @@ var _StackClientAppImpl = class __StackClientAppImpl {
597
648
  }
598
649
  }
599
650
  return useMemo(() => {
600
- return this._currentUserFromJson(userJson, tokenStore);
601
- }, [userJson, tokenStore, options?.or]);
651
+ return this._currentUserFromJson(userJson, session);
652
+ }, [userJson, session, options?.or]);
602
653
  }
603
654
  onUserChange(callback) {
604
655
  this._ensurePersistentTokenStore();
605
- const tokenStore = this._getTokenStore();
606
- return this._currentUserCache.onChange([tokenStore], (userJson) => {
607
- callback(this._currentUserFromJson(userJson, tokenStore));
656
+ const session = this._getSession();
657
+ return this._currentUserCache.onChange([session], (userJson) => {
658
+ callback(this._currentUserFromJson(userJson, session));
608
659
  });
609
660
  }
610
- async _updateUser(update, tokenStore) {
611
- const res = await this._interface.setClientUserCustomizableData(update, tokenStore);
612
- await this._refreshUser(tokenStore);
661
+ async _updateUser(update, session) {
662
+ const res = await this._interface.setClientUserCustomizableData(update, session);
663
+ await this._refreshUser(session);
613
664
  return res;
614
665
  }
615
666
  async signInWithOAuth(provider) {
@@ -618,35 +669,38 @@ var _StackClientAppImpl = class __StackClientAppImpl {
618
669
  }
619
670
  async signInWithCredential(options) {
620
671
  this._ensurePersistentTokenStore();
621
- const tokenStore = this._getTokenStore();
622
- const errorCode = await this._interface.signInWithCredential(options.email, options.password, tokenStore);
623
- if (!errorCode) {
624
- await this.redirectToAfterSignIn({ replace: true });
672
+ const session = this._getSession();
673
+ const result = await this._interface.signInWithCredential(options.email, options.password, session);
674
+ if (!(result instanceof KnownError)) {
675
+ await this._signInToAccountWithTokens(result);
676
+ return await this.redirectToAfterSignIn({ replace: true });
625
677
  }
626
- return errorCode;
678
+ return result;
627
679
  }
628
680
  async signUpWithCredential(options) {
629
681
  this._ensurePersistentTokenStore();
630
- const tokenStore = this._getTokenStore();
682
+ const session = this._getSession();
631
683
  const emailVerificationRedirectUrl = constructRedirectUrl(this.urls.emailVerification);
632
- const errorCode = await this._interface.signUpWithCredential(
684
+ const result = await this._interface.signUpWithCredential(
633
685
  options.email,
634
686
  options.password,
635
687
  emailVerificationRedirectUrl,
636
- tokenStore
688
+ session
637
689
  );
638
- if (!errorCode) {
639
- await this.redirectToAfterSignUp({ replace: true });
690
+ if (!(result instanceof KnownError)) {
691
+ await this._signInToAccountWithTokens(result);
692
+ return await this.redirectToAfterSignUp({ replace: true });
640
693
  }
641
- return errorCode;
694
+ return result;
642
695
  }
643
696
  async signInWithMagicLink(code) {
644
697
  this._ensurePersistentTokenStore();
645
- const tokenStore = this._getTokenStore();
646
- const result = await this._interface.signInWithMagicLink(code, tokenStore);
698
+ const session = this._getSession();
699
+ const result = await this._interface.signInWithMagicLink(code, session);
647
700
  if (result instanceof KnownError) {
648
701
  return result;
649
702
  }
703
+ await this._signInToAccountWithTokens(result);
650
704
  if (result.newUser) {
651
705
  await this.redirectToAfterSignUp({ replace: true });
652
706
  } else {
@@ -655,9 +709,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
655
709
  }
656
710
  async callOAuthCallback() {
657
711
  this._ensurePersistentTokenStore();
658
- const tokenStore = this._getTokenStore();
659
- const result = await callOAuthCallback(this._interface, tokenStore, this.urls.oauthCallback);
712
+ const result = await callOAuthCallback(this._interface, this.urls.oauthCallback);
660
713
  if (result) {
714
+ await this._signInToAccountWithTokens(result);
661
715
  if (result.newUser) {
662
716
  await this.redirectToAfterSignUp({ replace: true });
663
717
  return true;
@@ -668,16 +722,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
668
722
  }
669
723
  return false;
670
724
  }
671
- async _signOut(tokenStore) {
672
- await this._interface.signOut(tokenStore);
725
+ async _signOut(session) {
726
+ await this._interface.signOut(session);
673
727
  await this.redirectToAfterSignOut();
674
728
  }
675
- async _sendVerificationEmail(tokenStore) {
729
+ async _sendVerificationEmail(session) {
676
730
  const emailVerificationRedirectUrl = constructRedirectUrl(this.urls.emailVerification);
677
- return await this._interface.sendVerificationEmail(emailVerificationRedirectUrl, tokenStore);
731
+ return await this._interface.sendVerificationEmail(emailVerificationRedirectUrl, session);
678
732
  }
679
- async _updatePassword(options, tokenStore) {
680
- return await this._interface.updatePassword(options, tokenStore);
733
+ async _updatePassword(options, session) {
734
+ return await this._interface.updatePassword(options, session);
681
735
  }
682
736
  async signOut() {
683
737
  const user = await this.getUser();
@@ -689,64 +743,64 @@ var _StackClientAppImpl = class __StackClientAppImpl {
689
743
  return await this._currentProjectCache.getOrWait([], "write-only");
690
744
  }
691
745
  useProject() {
692
- return useCache(this._currentProjectCache, [], "useProject()");
746
+ return useAsyncCache(this._currentProjectCache, [], "useProject()");
693
747
  }
694
748
  onProjectChange(callback) {
695
749
  return this._currentProjectCache.onChange([], callback);
696
750
  }
697
751
  async _listOwnedProjects() {
698
752
  this._ensureInternalProject();
699
- const tokenStore = this._getTokenStore();
700
- const json = await this._ownedProjectsCache.getOrWait([tokenStore], "write-only");
753
+ const session = this._getSession();
754
+ const json = await this._ownedProjectsCache.getOrWait([session], "write-only");
701
755
  return json.map((j) => this._projectAdminFromJson(
702
756
  j,
703
- this._createAdminInterface(j.id, tokenStore),
704
- () => this._refreshOwnedProjects(tokenStore)
757
+ this._createAdminInterface(j.id, session),
758
+ () => this._refreshOwnedProjects(session)
705
759
  ));
706
760
  }
707
761
  _useOwnedProjects() {
708
762
  this._ensureInternalProject();
709
- const tokenStore = this._getTokenStore();
710
- const json = useCache(this._ownedProjectsCache, [tokenStore], "useOwnedProjects()");
763
+ const session = this._getSession();
764
+ const json = useAsyncCache(this._ownedProjectsCache, [session], "useOwnedProjects()");
711
765
  return useMemo(() => json.map((j) => this._projectAdminFromJson(
712
766
  j,
713
- this._createAdminInterface(j.id, tokenStore),
714
- () => this._refreshOwnedProjects(tokenStore)
767
+ this._createAdminInterface(j.id, session),
768
+ () => this._refreshOwnedProjects(session)
715
769
  )), [json]);
716
770
  }
717
771
  _onOwnedProjectsChange(callback) {
718
772
  this._ensureInternalProject();
719
- const tokenStore = this._getTokenStore();
720
- return this._ownedProjectsCache.onChange([tokenStore], (projects) => {
773
+ const session = this._getSession();
774
+ return this._ownedProjectsCache.onChange([session], (projects) => {
721
775
  callback(projects.map((j) => this._projectAdminFromJson(
722
776
  j,
723
- this._createAdminInterface(j.id, tokenStore),
724
- () => this._refreshOwnedProjects(tokenStore)
777
+ this._createAdminInterface(j.id, session),
778
+ () => this._refreshOwnedProjects(session)
725
779
  )));
726
780
  });
727
781
  }
728
782
  async _createProject(newProject) {
729
783
  this._ensureInternalProject();
730
- const tokenStore = this._getTokenStore();
731
- const json = await this._interface.createProject(newProject, tokenStore);
784
+ const session = this._getSession();
785
+ const json = await this._interface.createProject(newProject, session);
732
786
  const res = this._projectAdminFromJson(
733
787
  json,
734
- this._createAdminInterface(json.id, tokenStore),
735
- () => this._refreshOwnedProjects(tokenStore)
788
+ this._createAdminInterface(json.id, session),
789
+ () => this._refreshOwnedProjects(session)
736
790
  );
737
- await this._refreshOwnedProjects(tokenStore);
791
+ await this._refreshOwnedProjects(session);
738
792
  return res;
739
793
  }
740
- async _refreshUser(tokenStore) {
741
- await this._currentUserCache.refresh([tokenStore]);
794
+ async _refreshUser(session) {
795
+ await this._currentUserCache.refresh([session]);
742
796
  }
743
797
  async _refreshUsers() {
744
798
  }
745
799
  async _refreshProject() {
746
800
  await this._currentProjectCache.refresh([]);
747
801
  }
748
- async _refreshOwnedProjects(tokenStore) {
749
- await this._ownedProjectsCache.refresh([tokenStore]);
802
+ async _refreshOwnedProjects(session) {
803
+ await this._ownedProjectsCache.refresh([session]);
750
804
  }
751
805
  static get [stackAppInternalsSymbol]() {
752
806
  return {
@@ -785,15 +839,15 @@ var _StackClientAppImpl = class __StackClientAppImpl {
785
839
  };
786
840
  },
787
841
  setCurrentUser: (userJsonPromise) => {
788
- runAsynchronously(this._currentUserCache.forceSetCachedValueAsync([this._getTokenStore()], userJsonPromise));
842
+ runAsynchronously(this._currentUserCache.forceSetCachedValueAsync([this._getSession()], userJsonPromise));
789
843
  }
790
844
  };
791
845
  }
792
846
  };
793
847
  var _StackServerAppImpl = class extends _StackClientAppImpl {
794
848
  // TODO override the client user cache to use the server user cache, so we save some requests
795
- _currentServerUserCache = createCacheByTokenStore(async (tokenStore) => {
796
- const user = await this._interface.getServerUserByToken(tokenStore);
849
+ _currentServerUserCache = createCacheBySession(async (session) => {
850
+ const user = await this._interface.getServerUserByToken(session);
797
851
  return Result.or(user, null);
798
852
  });
799
853
  _serverUsersCache = createCache(async () => {
@@ -884,15 +938,15 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
884
938
  });
885
939
  },
886
940
  async listTeams() {
887
- const teams = await app._serverTeamsCache.getOrWait([app._getTokenStore()], "write-only");
941
+ const teams = await app._serverTeamsCache.getOrWait([app._getSession()], "write-only");
888
942
  return teams.map((json2) => app._serverTeamFromJson(json2));
889
943
  },
890
944
  useTeams() {
891
- const teams = useCache(app._serverTeamsCache, [app._getTokenStore()], "user.useTeams()");
945
+ const teams = useAsyncCache(app._serverTeamsCache, [app._getSession()], "user.useTeams()");
892
946
  return useMemo(() => teams.map((json2) => app._serverTeamFromJson(json2)), [teams]);
893
947
  },
894
948
  onTeamsChange(callback) {
895
- return app._serverTeamsCache.onChange([app._getTokenStore()], (value, oldValue) => {
949
+ return app._serverTeamsCache.onChange([app._getSession()], (value, oldValue) => {
896
950
  callback(value.map((json2) => app._serverTeamFromJson(json2)), oldValue?.map((json2) => app._serverTeamFromJson(json2)));
897
951
  });
898
952
  },
@@ -901,7 +955,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
901
955
  return permissions.map((json2) => app._serverPermissionFromJson(json2));
902
956
  },
903
957
  usePermissions(scope, options) {
904
- const permissions = useCache(app._serverTeamUserPermissionsCache, [scope.id, json.id, "team", !!options?.direct], "user.usePermissions()");
958
+ const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, json.id, "team", !!options?.direct], "user.usePermissions()");
905
959
  return useMemo(() => permissions.map((json2) => app._serverPermissionFromJson(json2)), [permissions]);
906
960
  },
907
961
  usePermission(scope, permissionId) {
@@ -921,20 +975,17 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
921
975
  }
922
976
  };
923
977
  }
924
- _currentServerUserFromJson(json, tokenStore) {
978
+ _currentServerUserFromJson(json, session) {
925
979
  if (json === null)
926
980
  return null;
927
981
  const app = this;
928
982
  const nonCurrentServerUser = this._serverUserFromJson(json);
929
983
  const currentUser = {
930
984
  ...nonCurrentServerUser,
931
- tokenStore,
932
- async refreshAccessToken() {
933
- await app._interface.refreshAccessToken(tokenStore);
934
- },
985
+ session,
935
986
  async delete() {
936
987
  const res = await nonCurrentServerUser.delete();
937
- await app._refreshUser(tokenStore);
988
+ await app._refreshUser(session);
938
989
  return res;
939
990
  },
940
991
  async updateSelectedTeam(team) {
@@ -942,20 +993,20 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
942
993
  },
943
994
  async update(update) {
944
995
  const res = await nonCurrentServerUser.update(update);
945
- await app._refreshUser(tokenStore);
996
+ await app._refreshUser(session);
946
997
  return res;
947
998
  },
948
999
  signOut() {
949
- return app._signOut(tokenStore);
1000
+ return app._signOut(session);
950
1001
  },
951
1002
  getClientUser() {
952
- return app._currentUserFromJson(json, tokenStore);
1003
+ return app._currentUserFromJson(json, session);
953
1004
  },
954
1005
  sendVerificationEmail() {
955
- return app._sendVerificationEmail(tokenStore);
1006
+ return app._sendVerificationEmail(session);
956
1007
  },
957
1008
  updatePassword(options) {
958
- return app._updatePassword(options, tokenStore);
1009
+ return app._updatePassword(options, session);
959
1010
  }
960
1011
  };
961
1012
  if (this._isInternalProject()) {
@@ -1013,7 +1064,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1013
1064
  await app._serverTeamsCache.refresh([]);
1014
1065
  },
1015
1066
  useMembers() {
1016
- const result = useCache(app._serverTeamMembersCache, [json.id], "team.useUsers()");
1067
+ const result = useAsyncCache(app._serverTeamMembersCache, [json.id], "team.useUsers()");
1017
1068
  return useMemo(() => result.map((u) => app._serverTeamMemberFromJson(u)), [result]);
1018
1069
  },
1019
1070
  async addUser(userId) {
@@ -1037,9 +1088,9 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1037
1088
  }
1038
1089
  async getServerUser() {
1039
1090
  this._ensurePersistentTokenStore();
1040
- const tokenStore = this._getTokenStore();
1041
- const userJson = await this._currentServerUserCache.getOrWait([tokenStore], "write-only");
1042
- return this._currentServerUserFromJson(userJson, tokenStore);
1091
+ const session = this._getSession();
1092
+ const userJson = await this._currentServerUserCache.getOrWait([session], "write-only");
1093
+ return this._currentServerUserFromJson(userJson, session);
1043
1094
  }
1044
1095
  async getServerUserById(userId) {
1045
1096
  const json = await this._serverUserCache.getOrWait([userId], "write-only");
@@ -1047,20 +1098,20 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1047
1098
  }
1048
1099
  useServerUser(options) {
1049
1100
  this._ensurePersistentTokenStore();
1050
- const tokenStore = this._getTokenStore();
1051
- const userJson = useCache(this._currentServerUserCache, [tokenStore], "useServerUser()");
1101
+ const session = this._getSession();
1102
+ const userJson = useAsyncCache(this._currentServerUserCache, [session], "useServerUser()");
1052
1103
  return useMemo(() => {
1053
1104
  if (options?.required && userJson === null) {
1054
1105
  use(this.redirectToSignIn());
1055
1106
  }
1056
- return this._currentServerUserFromJson(userJson, tokenStore);
1057
- }, [userJson, tokenStore, options?.required]);
1107
+ return this._currentServerUserFromJson(userJson, session);
1108
+ }, [userJson, session, options?.required]);
1058
1109
  }
1059
1110
  onServerUserChange(callback) {
1060
1111
  this._ensurePersistentTokenStore();
1061
- const tokenStore = this._getTokenStore();
1062
- return this._currentServerUserCache.onChange([tokenStore], (userJson) => {
1063
- callback(this._currentServerUserFromJson(userJson, tokenStore));
1112
+ const session = this._getSession();
1113
+ return this._currentServerUserCache.onChange([session], (userJson) => {
1114
+ callback(this._currentServerUserFromJson(userJson, session));
1064
1115
  });
1065
1116
  }
1066
1117
  async listServerUsers() {
@@ -1068,7 +1119,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1068
1119
  return json.map((j) => this._serverUserFromJson(j));
1069
1120
  }
1070
1121
  useServerUsers() {
1071
- const json = useCache(this._serverUsersCache, [], "useServerUsers()");
1122
+ const json = useAsyncCache(this._serverUsersCache, [], "useServerUsers()");
1072
1123
  return useMemo(() => {
1073
1124
  return json.map((j) => this._serverUserFromJson(j));
1074
1125
  }, [json]);
@@ -1082,7 +1133,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1082
1133
  return await this._serverTeamPermissionDefinitionsCache.getOrWait([], "write-only");
1083
1134
  }
1084
1135
  usePermissionDefinitions() {
1085
- return useCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
1136
+ return useAsyncCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
1086
1137
  }
1087
1138
  _serverPermissionFromJson(json) {
1088
1139
  return {
@@ -1093,7 +1144,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1093
1144
  };
1094
1145
  }
1095
1146
  async createPermissionDefinition(data) {
1096
- const permission = await this._serverPermissionFromJson(await this._interface.createPermissionDefinition(data));
1147
+ const permission = this._serverPermissionFromJson(await this._interface.createPermissionDefinition(data));
1097
1148
  await this._serverTeamPermissionDefinitionsCache.refresh([]);
1098
1149
  return permission;
1099
1150
  }
@@ -1115,7 +1166,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1115
1166
  return this._serverTeamFromJson(team);
1116
1167
  }
1117
1168
  useTeams() {
1118
- const teams = useCache(this._serverTeamsCache, [], "useServerTeams()");
1169
+ const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1119
1170
  return useMemo(() => {
1120
1171
  return teams.map((t) => this._serverTeamFromJson(t));
1121
1172
  }, [teams]);
@@ -1130,10 +1181,10 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1130
1181
  return teams.find((t) => t.id === teamId) ?? null;
1131
1182
  }, [teams, teamId]);
1132
1183
  }
1133
- async _refreshUser(tokenStore) {
1184
+ async _refreshUser(session) {
1134
1185
  await Promise.all([
1135
- super._refreshUser(tokenStore),
1136
- this._currentServerUserCache.refresh([tokenStore])
1186
+ super._refreshUser(session),
1187
+ this._currentServerUserCache.refresh([session])
1137
1188
  ]);
1138
1189
  }
1139
1190
  async _refreshUsers() {
@@ -1143,7 +1194,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1143
1194
  ]);
1144
1195
  }
1145
1196
  useEmailTemplates() {
1146
- return useCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
1197
+ return useAsyncCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
1147
1198
  }
1148
1199
  async listEmailTemplates() {
1149
1200
  return await this._serverEmailTemplatesCache.getOrWait([], "write-only");
@@ -1170,9 +1221,8 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1170
1221
  baseUrl: options.baseUrl ?? getDefaultBaseUrl(),
1171
1222
  projectId: options.projectId ?? getDefaultProjectId(),
1172
1223
  clientVersion,
1173
- ..."projectOwnerTokens" in options ? {
1174
- projectOwnerTokens: options.projectOwnerTokens,
1175
- refreshProjectOwnerTokens: options.refreshProjectOwnerTokens
1224
+ ..."projectOwnerSession" in options ? {
1225
+ projectOwnerSession: options.projectOwnerSession
1176
1226
  } : {
1177
1227
  publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
1178
1228
  secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey(),
@@ -1232,7 +1282,7 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1232
1282
  );
1233
1283
  }
1234
1284
  useProjectAdmin() {
1235
- const json = useCache(this._adminProjectCache, [], "useProjectAdmin()");
1285
+ const json = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
1236
1286
  return useMemo(() => this._projectAdminFromJson(
1237
1287
  json,
1238
1288
  this._interface,
@@ -1253,7 +1303,7 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1253
1303
  return json.map((j) => this._createApiKeySetFromJson(j));
1254
1304
  }
1255
1305
  useApiKeySets() {
1256
- const json = useCache(this._apiKeySetsCache, [], "useApiKeySets()");
1306
+ const json = useAsyncCache(this._apiKeySetsCache, [], "useApiKeySets()");
1257
1307
  return useMemo(() => {
1258
1308
  return json.map((j) => this._createApiKeySetFromJson(j));
1259
1309
  }, [json]);