@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
@@ -45,7 +45,7 @@ var import_results = require("@stackframe/stack-shared/dist/utils/results");
45
45
  var import_react2 = require("@stackframe/stack-shared/dist/utils/react");
46
46
  var import_stores = require("@stackframe/stack-shared/dist/utils/stores");
47
47
  var import_clientInterface = require("@stackframe/stack-shared/dist/interface/clientInterface");
48
- var import_next = require("../utils/next");
48
+ var import_env = require("@stackframe/stack-shared/src/utils/env");
49
49
  var import_auth = require("./auth");
50
50
  var NextNavigationUnscrambled = __toESM(require("next/navigation"));
51
51
  var import_url = require("../utils/url");
@@ -56,8 +56,10 @@ var import_react3 = require("@stackframe/stack-shared/dist/utils/react");
56
56
  var import_compile_time = require("@stackframe/stack-shared/dist/utils/compile-time");
57
57
  var import_stack_sc = require("@stackframe/stack-sc");
58
58
  var cookie = __toESM(require("cookie"));
59
+ var import_sessions = require("@stackframe/stack-shared/dist/sessions");
60
+ var import_use_trigger = require("@stackframe/stack-shared/dist/hooks/use-trigger");
59
61
  var NextNavigation = (0, import_compile_time.scrambleDuringCompileTime)(NextNavigationUnscrambled);
60
- var clientVersion = "js @stackframe/stack@2.4.17";
62
+ var clientVersion = "js @stackframe/stack@2.4.18";
61
63
  function permissionDefinitionScopeToType(scope) {
62
64
  return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
63
65
  }
@@ -98,45 +100,50 @@ function getDefaultBaseUrl() {
98
100
  }
99
101
  var defaultBaseUrl = "https://app.stack-auth.com";
100
102
  function createEmptyTokenStore() {
101
- return new import_stores.AsyncStore({
103
+ return new import_stores.Store({
102
104
  refreshToken: null,
103
105
  accessToken: null
104
106
  });
105
107
  }
106
- var cookieTokenStore = null;
107
- var cookieTokenStoreInitializer = () => {
108
- if (!(0, import_next.isClient)()) {
108
+ var storedCookieTokenStore = null;
109
+ var getCookieTokenStore = () => {
110
+ if (!(0, import_env.isBrowserLike)()) {
109
111
  throw new Error("Cannot use cookie token store on the server!");
110
112
  }
111
- if (cookieTokenStore === null) {
112
- cookieTokenStore = new import_stores.AsyncStore();
113
+ if (storedCookieTokenStore === null) {
114
+ const getCurrentValue = () => ({
115
+ refreshToken: (0, import_cookie.getCookie)("stack-refresh"),
116
+ accessToken: (0, import_cookie.getCookie)("stack-access")
117
+ });
118
+ storedCookieTokenStore = new import_stores.Store(getCurrentValue());
113
119
  let hasSucceededInWriting = true;
114
120
  setInterval(() => {
115
121
  if (hasSucceededInWriting) {
116
- const newValue = {
117
- refreshToken: (0, import_cookie.getCookie)("stack-refresh"),
118
- accessToken: (0, import_cookie.getCookie)("stack-access")
119
- };
120
- const res = cookieTokenStore.get();
121
- if (res.status !== "ok" || res.data.refreshToken !== newValue.refreshToken || res.data.accessToken !== newValue.accessToken) {
122
- cookieTokenStore.set(newValue);
122
+ const currentValue = getCurrentValue();
123
+ const oldValue = storedCookieTokenStore.get();
124
+ if (JSON.stringify(currentValue) !== JSON.stringify(oldValue)) {
125
+ storedCookieTokenStore.set(currentValue);
123
126
  }
124
127
  }
125
- }, 10);
126
- cookieTokenStore.onChange((value) => {
128
+ }, 100);
129
+ storedCookieTokenStore.onChange((value) => {
127
130
  try {
128
131
  (0, import_cookie.setOrDeleteCookie)("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
129
132
  (0, import_cookie.setOrDeleteCookie)("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
130
133
  hasSucceededInWriting = true;
131
134
  } catch (e) {
132
- hasSucceededInWriting = false;
135
+ if (!(0, import_env.isBrowserLike)()) {
136
+ hasSucceededInWriting = false;
137
+ } else {
138
+ throw e;
139
+ }
133
140
  }
134
141
  });
135
142
  }
136
- return cookieTokenStore;
143
+ return storedCookieTokenStore;
137
144
  };
138
145
  var loadingSentinel = Symbol("stackAppCacheLoadingSentinel");
139
- function useCache(cache, dependencies, caller) {
146
+ function useAsyncCache(cache, dependencies, caller) {
140
147
  (0, import_react2.suspendIfSsr)(caller);
141
148
  const subscribe = (0, import_react.useCallback)((cb) => {
142
149
  const { unsubscribe } = cache.onChange(dependencies, () => cb());
@@ -160,17 +167,13 @@ var createCache = (fetcher) => {
160
167
  {}
161
168
  );
162
169
  };
163
- var createCacheByTokenStore = (fetcher) => {
170
+ var createCacheBySession = (fetcher) => {
164
171
  return new import_caches.AsyncCache(
165
- async ([tokenStore, ...extraDependencies]) => await fetcher(tokenStore, extraDependencies),
172
+ async ([session, ...extraDependencies]) => await fetcher(session, extraDependencies),
166
173
  {
167
- onSubscribe: ([tokenStore], refresh) => {
168
- const handlerObj = tokenStore.onChange((newValue, oldValue) => {
169
- if (newValue.refreshToken === oldValue?.refreshToken)
170
- return;
171
- refresh();
172
- });
173
- return () => handlerObj.unsubscribe();
174
+ onSubscribe: ([session], refresh) => {
175
+ const handler = session.onInvalidate(() => refresh());
176
+ return () => handler.unsubscribe();
174
177
  }
175
178
  }
176
179
  );
@@ -197,7 +200,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
197
200
  }
198
201
  numberOfAppsCreated++;
199
202
  if (numberOfAppsCreated > 10) {
200
- 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).`);
203
+ (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).`);
201
204
  }
202
205
  }
203
206
  _uniqueIdentifier = void 0;
@@ -205,24 +208,24 @@ var _StackClientAppImpl = class __StackClientAppImpl {
205
208
  _tokenStoreInit;
206
209
  _urlOptions;
207
210
  __DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
208
- _currentUserCache = createCacheByTokenStore(async (tokenStore) => {
211
+ _currentUserCache = createCacheBySession(async (session) => {
209
212
  if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
210
213
  await (0, import_promises.wait)(2e3);
211
214
  }
212
- const user = await this._interface.getClientUserByToken(tokenStore);
215
+ const user = await this._interface.getClientUserByToken(session);
213
216
  return import_results.Result.or(user, null);
214
217
  });
215
218
  _currentProjectCache = createCache(async () => {
216
219
  return import_results.Result.orThrow(await this._interface.getClientProject());
217
220
  });
218
- _ownedProjectsCache = createCacheByTokenStore(async (tokenStore) => {
219
- return await this._interface.listProjects(tokenStore);
221
+ _ownedProjectsCache = createCacheBySession(async (session) => {
222
+ return await this._interface.listProjects(session);
220
223
  });
221
- _currentUserPermissionsCache = createCacheByTokenStore(async (tokenStore, [teamId, type, direct]) => {
222
- return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, tokenStore);
224
+ _currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
225
+ return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
223
226
  });
224
- _currentUserTeamsCache = createCacheByTokenStore(async (tokenStore) => {
225
- return await this._interface.listClientUserTeams(tokenStore);
227
+ _currentUserTeamsCache = createCacheBySession(async (session) => {
228
+ return await this._interface.listClientUserTeams(session);
226
229
  });
227
230
  _initUniqueIdentifier() {
228
231
  if (!this._uniqueIdentifier) {
@@ -245,19 +248,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
245
248
  return this._uniqueIdentifier;
246
249
  }
247
250
  _memoryTokenStore = createEmptyTokenStore();
248
- _requestTokenStores = /* @__PURE__ */ new Map();
249
- _getTokenStore(overrideTokenStoreInit) {
251
+ _requestTokenStores = /* @__PURE__ */ new WeakMap();
252
+ _getOrCreateTokenStore(overrideTokenStoreInit) {
250
253
  const tokenStoreInit = overrideTokenStoreInit === void 0 ? this._tokenStoreInit : overrideTokenStoreInit;
251
254
  switch (tokenStoreInit) {
252
255
  case "cookie": {
253
- return cookieTokenStoreInitializer();
256
+ return getCookieTokenStore();
254
257
  }
255
258
  case "nextjs-cookie": {
256
- if ((0, import_next.isClient)()) {
257
- return cookieTokenStoreInitializer();
259
+ if ((0, import_env.isBrowserLike)()) {
260
+ return getCookieTokenStore();
258
261
  } else {
259
- const store = new import_stores.AsyncStore();
260
- store.set({
262
+ const store = new import_stores.Store({
261
263
  refreshToken: (0, import_cookie.getCookie)("stack-refresh"),
262
264
  accessToken: (0, import_cookie.getCookie)("stack-access")
263
265
  });
@@ -278,12 +280,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
278
280
  return createEmptyTokenStore();
279
281
  }
280
282
  default: {
281
- if (tokenStoreInit && typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
283
+ if (tokenStoreInit !== null && typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
282
284
  if (this._requestTokenStores.has(tokenStoreInit))
283
285
  return this._requestTokenStores.get(tokenStoreInit);
284
286
  const cookieHeader = tokenStoreInit.headers.get("cookie");
285
287
  const parsed = cookie.parse(cookieHeader || "");
286
- const res = new import_stores.AsyncStore({
288
+ const res = new import_stores.Store({
287
289
  refreshToken: parsed["stack-refresh"] || null,
288
290
  accessToken: parsed["stack-access"] || null
289
291
  });
@@ -294,6 +296,60 @@ var _StackClientAppImpl = class __StackClientAppImpl {
294
296
  }
295
297
  }
296
298
  }
299
+ /**
300
+ * A map from token stores and session keys to sessions.
301
+ *
302
+ * This isn't just a map from session keys to sessions for two reasons:
303
+ *
304
+ * - So we can garbage-collect Session objects when the token store is garbage-collected
305
+ * - 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
306
+ */
307
+ _sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
308
+ _getSessionFromTokenStore(tokenStore) {
309
+ const tokenObj = tokenStore.get();
310
+ const sessionKey = import_sessions.Session.calculateSessionKey(tokenObj);
311
+ const existing = sessionKey ? this._sessionsByTokenStoreAndSessionKey.get(tokenStore)?.get(sessionKey) : null;
312
+ if (existing)
313
+ return existing;
314
+ const session = this._interface.createSession({
315
+ refreshToken: tokenObj.refreshToken,
316
+ accessToken: tokenObj.accessToken
317
+ });
318
+ session.onAccessTokenChange((newAccessToken) => {
319
+ tokenStore.update((old) => ({
320
+ ...old,
321
+ accessToken: newAccessToken?.token ?? null
322
+ }));
323
+ });
324
+ session.onInvalidate(() => {
325
+ tokenStore.update((old) => ({
326
+ ...old,
327
+ accessToken: null,
328
+ refreshToken: null
329
+ }));
330
+ });
331
+ let sessionsBySessionKey = this._sessionsByTokenStoreAndSessionKey.get(tokenStore) ?? /* @__PURE__ */ new Map();
332
+ this._sessionsByTokenStoreAndSessionKey.set(tokenStore, sessionsBySessionKey);
333
+ sessionsBySessionKey.set(sessionKey, session);
334
+ return session;
335
+ }
336
+ _getSession(overrideTokenStoreInit) {
337
+ const tokenStore = this._getOrCreateTokenStore(overrideTokenStoreInit);
338
+ return this._getSessionFromTokenStore(tokenStore);
339
+ }
340
+ _useSession(overrideTokenStoreInit) {
341
+ const tokenStore = this._getOrCreateTokenStore(overrideTokenStoreInit);
342
+ const subscribe = (0, import_react.useCallback)((cb) => {
343
+ const { unsubscribe } = tokenStore.onChange(() => cb());
344
+ return unsubscribe;
345
+ }, [tokenStore]);
346
+ const getSnapshot = (0, import_react.useCallback)(() => this._getSessionFromTokenStore(tokenStore), [tokenStore]);
347
+ return import_react.default.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
348
+ }
349
+ async _signInToAccountWithTokens(tokens) {
350
+ const tokenStore = this._getOrCreateTokenStore();
351
+ tokenStore.set(tokens);
352
+ }
297
353
  _hasPersistentTokenStore(overrideTokenStoreInit) {
298
354
  return (overrideTokenStoreInit !== void 0 ? overrideTokenStoreInit : this._tokenStoreInit) !== null;
299
355
  }
@@ -373,24 +429,25 @@ var _StackClientAppImpl = class __StackClientAppImpl {
373
429
  });
374
430
  },
375
431
  async listTeams() {
376
- const teams = await app._currentUserTeamsCache.getOrWait([app._getTokenStore()], "write-only");
432
+ const teams = await app._currentUserTeamsCache.getOrWait([app._getSession()], "write-only");
377
433
  return teams.map((json2) => app._teamFromJson(json2));
378
434
  },
379
435
  useTeams() {
380
- const teams = useCache(app._currentUserTeamsCache, [app._getTokenStore()], "user.useTeams()");
436
+ const session = app._useSession();
437
+ const teams = useAsyncCache(app._currentUserTeamsCache, [session], "user.useTeams()");
381
438
  return (0, import_react.useMemo)(() => teams.map((json2) => app._teamFromJson(json2)), [teams]);
382
439
  },
383
440
  onTeamsChange(callback) {
384
- return app._currentUserTeamsCache.onChange([app._getTokenStore()], (value, oldValue) => {
441
+ return app._currentUserTeamsCache.onChange([app._getSession()], (value, oldValue) => {
385
442
  callback(value.map((json2) => app._teamFromJson(json2)), oldValue?.map((json2) => app._teamFromJson(json2)));
386
443
  });
387
444
  },
388
445
  async listPermissions(scope, options) {
389
- const permissions = await app._currentUserPermissionsCache.getOrWait([app._getTokenStore(), scope.id, "team", !!options?.direct], "write-only");
446
+ const permissions = await app._currentUserPermissionsCache.getOrWait([app._getSession(), scope.id, "team", !!options?.direct], "write-only");
390
447
  return permissions.map((json2) => app._permissionFromJson(json2));
391
448
  },
392
449
  usePermissions(scope, options) {
393
- const permissions = useCache(app._currentUserPermissionsCache, [app._getTokenStore(), scope.id, "team", !!options?.direct], "user.usePermissions()");
450
+ const permissions = useAsyncCache(app._currentUserPermissionsCache, [app._getSession(), scope.id, "team", !!options?.direct], "user.usePermissions()");
394
451
  return (0, import_react.useMemo)(() => permissions.map((json2) => app._permissionFromJson(json2)), [permissions]);
395
452
  },
396
453
  usePermission(scope, permissionId) {
@@ -418,30 +475,27 @@ var _StackClientAppImpl = class __StackClientAppImpl {
418
475
  displayName: json.displayName
419
476
  };
420
477
  }
421
- _currentUserFromJson(json, tokenStore) {
478
+ _currentUserFromJson(json, session) {
422
479
  if (json === null)
423
480
  return null;
424
481
  const app = this;
425
482
  const currentUser = {
426
483
  ...this._userFromJson(json),
427
- tokenStore,
428
- async refreshAccessToken() {
429
- await app._interface.refreshAccessToken(tokenStore);
430
- },
484
+ session,
431
485
  async updateSelectedTeam(team) {
432
- await app._updateUser({ selectedTeamId: team?.id ?? null }, tokenStore);
486
+ await app._updateUser({ selectedTeamId: team?.id ?? null }, session);
433
487
  },
434
488
  update(update) {
435
- return app._updateUser(update, tokenStore);
489
+ return app._updateUser(update, session);
436
490
  },
437
491
  signOut() {
438
- return app._signOut(tokenStore);
492
+ return app._signOut(session);
439
493
  },
440
494
  sendVerificationEmail() {
441
- return app._sendVerificationEmail(tokenStore);
495
+ return app._sendVerificationEmail(session);
442
496
  },
443
497
  updatePassword(options) {
444
- return app._updatePassword(options, tokenStore);
498
+ return app._updatePassword(options, session);
445
499
  }
446
500
  };
447
501
  if (this._isInternalProject()) {
@@ -500,13 +554,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
500
554
  }
501
555
  };
502
556
  }
503
- _createAdminInterface(forProjectId, tokenStore) {
557
+ _createAdminInterface(forProjectId, session) {
504
558
  return new import_stack_shared.StackAdminInterface({
505
559
  baseUrl: this._interface.options.baseUrl,
506
560
  projectId: forProjectId,
507
561
  clientVersion,
508
- projectOwnerTokens: tokenStore,
509
- refreshProjectOwnerTokens: async () => await this._interface.refreshAccessToken(tokenStore)
562
+ projectOwnerSession: session
510
563
  });
511
564
  }
512
565
  get projectId() {
@@ -592,8 +645,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
592
645
  }
593
646
  async getUser(options) {
594
647
  this._ensurePersistentTokenStore(options?.tokenStore);
595
- const tokenStore = this._getTokenStore(options?.tokenStore);
596
- const userJson = await this._currentUserCache.getOrWait([tokenStore], "write-only");
648
+ const session = this._getSession(options?.tokenStore);
649
+ const userJson = await this._currentUserCache.getOrWait([session], "write-only");
597
650
  if (userJson === null) {
598
651
  switch (options?.or) {
599
652
  case "redirect": {
@@ -608,20 +661,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
608
661
  }
609
662
  }
610
663
  }
611
- return this._currentUserFromJson(userJson, tokenStore);
664
+ return this._currentUserFromJson(userJson, session);
612
665
  }
613
666
  useUser(options) {
614
667
  this._ensurePersistentTokenStore(options?.tokenStore);
615
668
  const router = NextNavigation.useRouter();
616
- const tokenStore = this._getTokenStore(options?.tokenStore);
617
- const userJson = useCache(this._currentUserCache, [tokenStore], "useUser()");
669
+ const session = this._getSession(options?.tokenStore);
670
+ const userJson = useAsyncCache(this._currentUserCache, [session], "useUser()");
671
+ const triggerRedirectToSignIn = (0, import_use_trigger.useTrigger)(() => router.replace(this.urls.signIn));
618
672
  if (userJson === null) {
619
673
  switch (options?.or) {
620
674
  case "redirect": {
621
- (0, import_promises.runAsynchronously)(async () => {
622
- await (0, import_promises.wait)(0);
623
- router.replace(this.urls.signIn);
624
- });
675
+ triggerRedirectToSignIn();
625
676
  (0, import_react3.suspend)();
626
677
  throw new import_errors.StackAssertionError("suspend should never return");
627
678
  }
@@ -634,19 +685,19 @@ var _StackClientAppImpl = class __StackClientAppImpl {
634
685
  }
635
686
  }
636
687
  return (0, import_react.useMemo)(() => {
637
- return this._currentUserFromJson(userJson, tokenStore);
638
- }, [userJson, tokenStore, options?.or]);
688
+ return this._currentUserFromJson(userJson, session);
689
+ }, [userJson, session, options?.or]);
639
690
  }
640
691
  onUserChange(callback) {
641
692
  this._ensurePersistentTokenStore();
642
- const tokenStore = this._getTokenStore();
643
- return this._currentUserCache.onChange([tokenStore], (userJson) => {
644
- callback(this._currentUserFromJson(userJson, tokenStore));
693
+ const session = this._getSession();
694
+ return this._currentUserCache.onChange([session], (userJson) => {
695
+ callback(this._currentUserFromJson(userJson, session));
645
696
  });
646
697
  }
647
- async _updateUser(update, tokenStore) {
648
- const res = await this._interface.setClientUserCustomizableData(update, tokenStore);
649
- await this._refreshUser(tokenStore);
698
+ async _updateUser(update, session) {
699
+ const res = await this._interface.setClientUserCustomizableData(update, session);
700
+ await this._refreshUser(session);
650
701
  return res;
651
702
  }
652
703
  async signInWithOAuth(provider) {
@@ -655,35 +706,38 @@ var _StackClientAppImpl = class __StackClientAppImpl {
655
706
  }
656
707
  async signInWithCredential(options) {
657
708
  this._ensurePersistentTokenStore();
658
- const tokenStore = this._getTokenStore();
659
- const errorCode = await this._interface.signInWithCredential(options.email, options.password, tokenStore);
660
- if (!errorCode) {
661
- await this.redirectToAfterSignIn({ replace: true });
709
+ const session = this._getSession();
710
+ const result = await this._interface.signInWithCredential(options.email, options.password, session);
711
+ if (!(result instanceof import_stack_shared.KnownError)) {
712
+ await this._signInToAccountWithTokens(result);
713
+ return await this.redirectToAfterSignIn({ replace: true });
662
714
  }
663
- return errorCode;
715
+ return result;
664
716
  }
665
717
  async signUpWithCredential(options) {
666
718
  this._ensurePersistentTokenStore();
667
- const tokenStore = this._getTokenStore();
719
+ const session = this._getSession();
668
720
  const emailVerificationRedirectUrl = (0, import_url.constructRedirectUrl)(this.urls.emailVerification);
669
- const errorCode = await this._interface.signUpWithCredential(
721
+ const result = await this._interface.signUpWithCredential(
670
722
  options.email,
671
723
  options.password,
672
724
  emailVerificationRedirectUrl,
673
- tokenStore
725
+ session
674
726
  );
675
- if (!errorCode) {
676
- await this.redirectToAfterSignUp({ replace: true });
727
+ if (!(result instanceof import_stack_shared.KnownError)) {
728
+ await this._signInToAccountWithTokens(result);
729
+ return await this.redirectToAfterSignUp({ replace: true });
677
730
  }
678
- return errorCode;
731
+ return result;
679
732
  }
680
733
  async signInWithMagicLink(code) {
681
734
  this._ensurePersistentTokenStore();
682
- const tokenStore = this._getTokenStore();
683
- const result = await this._interface.signInWithMagicLink(code, tokenStore);
735
+ const session = this._getSession();
736
+ const result = await this._interface.signInWithMagicLink(code, session);
684
737
  if (result instanceof import_stack_shared.KnownError) {
685
738
  return result;
686
739
  }
740
+ await this._signInToAccountWithTokens(result);
687
741
  if (result.newUser) {
688
742
  await this.redirectToAfterSignUp({ replace: true });
689
743
  } else {
@@ -692,9 +746,9 @@ var _StackClientAppImpl = class __StackClientAppImpl {
692
746
  }
693
747
  async callOAuthCallback() {
694
748
  this._ensurePersistentTokenStore();
695
- const tokenStore = this._getTokenStore();
696
- const result = await (0, import_auth.callOAuthCallback)(this._interface, tokenStore, this.urls.oauthCallback);
749
+ const result = await (0, import_auth.callOAuthCallback)(this._interface, this.urls.oauthCallback);
697
750
  if (result) {
751
+ await this._signInToAccountWithTokens(result);
698
752
  if (result.newUser) {
699
753
  await this.redirectToAfterSignUp({ replace: true });
700
754
  return true;
@@ -705,16 +759,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
705
759
  }
706
760
  return false;
707
761
  }
708
- async _signOut(tokenStore) {
709
- await this._interface.signOut(tokenStore);
762
+ async _signOut(session) {
763
+ await this._interface.signOut(session);
710
764
  await this.redirectToAfterSignOut();
711
765
  }
712
- async _sendVerificationEmail(tokenStore) {
766
+ async _sendVerificationEmail(session) {
713
767
  const emailVerificationRedirectUrl = (0, import_url.constructRedirectUrl)(this.urls.emailVerification);
714
- return await this._interface.sendVerificationEmail(emailVerificationRedirectUrl, tokenStore);
768
+ return await this._interface.sendVerificationEmail(emailVerificationRedirectUrl, session);
715
769
  }
716
- async _updatePassword(options, tokenStore) {
717
- return await this._interface.updatePassword(options, tokenStore);
770
+ async _updatePassword(options, session) {
771
+ return await this._interface.updatePassword(options, session);
718
772
  }
719
773
  async signOut() {
720
774
  const user = await this.getUser();
@@ -726,64 +780,64 @@ var _StackClientAppImpl = class __StackClientAppImpl {
726
780
  return await this._currentProjectCache.getOrWait([], "write-only");
727
781
  }
728
782
  useProject() {
729
- return useCache(this._currentProjectCache, [], "useProject()");
783
+ return useAsyncCache(this._currentProjectCache, [], "useProject()");
730
784
  }
731
785
  onProjectChange(callback) {
732
786
  return this._currentProjectCache.onChange([], callback);
733
787
  }
734
788
  async _listOwnedProjects() {
735
789
  this._ensureInternalProject();
736
- const tokenStore = this._getTokenStore();
737
- const json = await this._ownedProjectsCache.getOrWait([tokenStore], "write-only");
790
+ const session = this._getSession();
791
+ const json = await this._ownedProjectsCache.getOrWait([session], "write-only");
738
792
  return json.map((j) => this._projectAdminFromJson(
739
793
  j,
740
- this._createAdminInterface(j.id, tokenStore),
741
- () => this._refreshOwnedProjects(tokenStore)
794
+ this._createAdminInterface(j.id, session),
795
+ () => this._refreshOwnedProjects(session)
742
796
  ));
743
797
  }
744
798
  _useOwnedProjects() {
745
799
  this._ensureInternalProject();
746
- const tokenStore = this._getTokenStore();
747
- const json = useCache(this._ownedProjectsCache, [tokenStore], "useOwnedProjects()");
800
+ const session = this._getSession();
801
+ const json = useAsyncCache(this._ownedProjectsCache, [session], "useOwnedProjects()");
748
802
  return (0, import_react.useMemo)(() => json.map((j) => this._projectAdminFromJson(
749
803
  j,
750
- this._createAdminInterface(j.id, tokenStore),
751
- () => this._refreshOwnedProjects(tokenStore)
804
+ this._createAdminInterface(j.id, session),
805
+ () => this._refreshOwnedProjects(session)
752
806
  )), [json]);
753
807
  }
754
808
  _onOwnedProjectsChange(callback) {
755
809
  this._ensureInternalProject();
756
- const tokenStore = this._getTokenStore();
757
- return this._ownedProjectsCache.onChange([tokenStore], (projects) => {
810
+ const session = this._getSession();
811
+ return this._ownedProjectsCache.onChange([session], (projects) => {
758
812
  callback(projects.map((j) => this._projectAdminFromJson(
759
813
  j,
760
- this._createAdminInterface(j.id, tokenStore),
761
- () => this._refreshOwnedProjects(tokenStore)
814
+ this._createAdminInterface(j.id, session),
815
+ () => this._refreshOwnedProjects(session)
762
816
  )));
763
817
  });
764
818
  }
765
819
  async _createProject(newProject) {
766
820
  this._ensureInternalProject();
767
- const tokenStore = this._getTokenStore();
768
- const json = await this._interface.createProject(newProject, tokenStore);
821
+ const session = this._getSession();
822
+ const json = await this._interface.createProject(newProject, session);
769
823
  const res = this._projectAdminFromJson(
770
824
  json,
771
- this._createAdminInterface(json.id, tokenStore),
772
- () => this._refreshOwnedProjects(tokenStore)
825
+ this._createAdminInterface(json.id, session),
826
+ () => this._refreshOwnedProjects(session)
773
827
  );
774
- await this._refreshOwnedProjects(tokenStore);
828
+ await this._refreshOwnedProjects(session);
775
829
  return res;
776
830
  }
777
- async _refreshUser(tokenStore) {
778
- await this._currentUserCache.refresh([tokenStore]);
831
+ async _refreshUser(session) {
832
+ await this._currentUserCache.refresh([session]);
779
833
  }
780
834
  async _refreshUsers() {
781
835
  }
782
836
  async _refreshProject() {
783
837
  await this._currentProjectCache.refresh([]);
784
838
  }
785
- async _refreshOwnedProjects(tokenStore) {
786
- await this._ownedProjectsCache.refresh([tokenStore]);
839
+ async _refreshOwnedProjects(session) {
840
+ await this._ownedProjectsCache.refresh([session]);
787
841
  }
788
842
  static get [stackAppInternalsSymbol]() {
789
843
  return {
@@ -822,15 +876,15 @@ var _StackClientAppImpl = class __StackClientAppImpl {
822
876
  };
823
877
  },
824
878
  setCurrentUser: (userJsonPromise) => {
825
- (0, import_promises.runAsynchronously)(this._currentUserCache.forceSetCachedValueAsync([this._getTokenStore()], userJsonPromise));
879
+ (0, import_promises.runAsynchronously)(this._currentUserCache.forceSetCachedValueAsync([this._getSession()], userJsonPromise));
826
880
  }
827
881
  };
828
882
  }
829
883
  };
830
884
  var _StackServerAppImpl = class extends _StackClientAppImpl {
831
885
  // TODO override the client user cache to use the server user cache, so we save some requests
832
- _currentServerUserCache = createCacheByTokenStore(async (tokenStore) => {
833
- const user = await this._interface.getServerUserByToken(tokenStore);
886
+ _currentServerUserCache = createCacheBySession(async (session) => {
887
+ const user = await this._interface.getServerUserByToken(session);
834
888
  return import_results.Result.or(user, null);
835
889
  });
836
890
  _serverUsersCache = createCache(async () => {
@@ -921,15 +975,15 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
921
975
  });
922
976
  },
923
977
  async listTeams() {
924
- const teams = await app._serverTeamsCache.getOrWait([app._getTokenStore()], "write-only");
978
+ const teams = await app._serverTeamsCache.getOrWait([app._getSession()], "write-only");
925
979
  return teams.map((json2) => app._serverTeamFromJson(json2));
926
980
  },
927
981
  useTeams() {
928
- const teams = useCache(app._serverTeamsCache, [app._getTokenStore()], "user.useTeams()");
982
+ const teams = useAsyncCache(app._serverTeamsCache, [app._getSession()], "user.useTeams()");
929
983
  return (0, import_react.useMemo)(() => teams.map((json2) => app._serverTeamFromJson(json2)), [teams]);
930
984
  },
931
985
  onTeamsChange(callback) {
932
- return app._serverTeamsCache.onChange([app._getTokenStore()], (value, oldValue) => {
986
+ return app._serverTeamsCache.onChange([app._getSession()], (value, oldValue) => {
933
987
  callback(value.map((json2) => app._serverTeamFromJson(json2)), oldValue?.map((json2) => app._serverTeamFromJson(json2)));
934
988
  });
935
989
  },
@@ -938,7 +992,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
938
992
  return permissions.map((json2) => app._serverPermissionFromJson(json2));
939
993
  },
940
994
  usePermissions(scope, options) {
941
- const permissions = useCache(app._serverTeamUserPermissionsCache, [scope.id, json.id, "team", !!options?.direct], "user.usePermissions()");
995
+ const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, json.id, "team", !!options?.direct], "user.usePermissions()");
942
996
  return (0, import_react.useMemo)(() => permissions.map((json2) => app._serverPermissionFromJson(json2)), [permissions]);
943
997
  },
944
998
  usePermission(scope, permissionId) {
@@ -958,20 +1012,17 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
958
1012
  }
959
1013
  };
960
1014
  }
961
- _currentServerUserFromJson(json, tokenStore) {
1015
+ _currentServerUserFromJson(json, session) {
962
1016
  if (json === null)
963
1017
  return null;
964
1018
  const app = this;
965
1019
  const nonCurrentServerUser = this._serverUserFromJson(json);
966
1020
  const currentUser = {
967
1021
  ...nonCurrentServerUser,
968
- tokenStore,
969
- async refreshAccessToken() {
970
- await app._interface.refreshAccessToken(tokenStore);
971
- },
1022
+ session,
972
1023
  async delete() {
973
1024
  const res = await nonCurrentServerUser.delete();
974
- await app._refreshUser(tokenStore);
1025
+ await app._refreshUser(session);
975
1026
  return res;
976
1027
  },
977
1028
  async updateSelectedTeam(team) {
@@ -979,20 +1030,20 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
979
1030
  },
980
1031
  async update(update) {
981
1032
  const res = await nonCurrentServerUser.update(update);
982
- await app._refreshUser(tokenStore);
1033
+ await app._refreshUser(session);
983
1034
  return res;
984
1035
  },
985
1036
  signOut() {
986
- return app._signOut(tokenStore);
1037
+ return app._signOut(session);
987
1038
  },
988
1039
  getClientUser() {
989
- return app._currentUserFromJson(json, tokenStore);
1040
+ return app._currentUserFromJson(json, session);
990
1041
  },
991
1042
  sendVerificationEmail() {
992
- return app._sendVerificationEmail(tokenStore);
1043
+ return app._sendVerificationEmail(session);
993
1044
  },
994
1045
  updatePassword(options) {
995
- return app._updatePassword(options, tokenStore);
1046
+ return app._updatePassword(options, session);
996
1047
  }
997
1048
  };
998
1049
  if (this._isInternalProject()) {
@@ -1050,7 +1101,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1050
1101
  await app._serverTeamsCache.refresh([]);
1051
1102
  },
1052
1103
  useMembers() {
1053
- const result = useCache(app._serverTeamMembersCache, [json.id], "team.useUsers()");
1104
+ const result = useAsyncCache(app._serverTeamMembersCache, [json.id], "team.useUsers()");
1054
1105
  return (0, import_react.useMemo)(() => result.map((u) => app._serverTeamMemberFromJson(u)), [result]);
1055
1106
  },
1056
1107
  async addUser(userId) {
@@ -1074,9 +1125,9 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1074
1125
  }
1075
1126
  async getServerUser() {
1076
1127
  this._ensurePersistentTokenStore();
1077
- const tokenStore = this._getTokenStore();
1078
- const userJson = await this._currentServerUserCache.getOrWait([tokenStore], "write-only");
1079
- return this._currentServerUserFromJson(userJson, tokenStore);
1128
+ const session = this._getSession();
1129
+ const userJson = await this._currentServerUserCache.getOrWait([session], "write-only");
1130
+ return this._currentServerUserFromJson(userJson, session);
1080
1131
  }
1081
1132
  async getServerUserById(userId) {
1082
1133
  const json = await this._serverUserCache.getOrWait([userId], "write-only");
@@ -1084,20 +1135,20 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1084
1135
  }
1085
1136
  useServerUser(options) {
1086
1137
  this._ensurePersistentTokenStore();
1087
- const tokenStore = this._getTokenStore();
1088
- const userJson = useCache(this._currentServerUserCache, [tokenStore], "useServerUser()");
1138
+ const session = this._getSession();
1139
+ const userJson = useAsyncCache(this._currentServerUserCache, [session], "useServerUser()");
1089
1140
  return (0, import_react.useMemo)(() => {
1090
1141
  if (options?.required && userJson === null) {
1091
1142
  (0, import_react.use)(this.redirectToSignIn());
1092
1143
  }
1093
- return this._currentServerUserFromJson(userJson, tokenStore);
1094
- }, [userJson, tokenStore, options?.required]);
1144
+ return this._currentServerUserFromJson(userJson, session);
1145
+ }, [userJson, session, options?.required]);
1095
1146
  }
1096
1147
  onServerUserChange(callback) {
1097
1148
  this._ensurePersistentTokenStore();
1098
- const tokenStore = this._getTokenStore();
1099
- return this._currentServerUserCache.onChange([tokenStore], (userJson) => {
1100
- callback(this._currentServerUserFromJson(userJson, tokenStore));
1149
+ const session = this._getSession();
1150
+ return this._currentServerUserCache.onChange([session], (userJson) => {
1151
+ callback(this._currentServerUserFromJson(userJson, session));
1101
1152
  });
1102
1153
  }
1103
1154
  async listServerUsers() {
@@ -1105,7 +1156,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1105
1156
  return json.map((j) => this._serverUserFromJson(j));
1106
1157
  }
1107
1158
  useServerUsers() {
1108
- const json = useCache(this._serverUsersCache, [], "useServerUsers()");
1159
+ const json = useAsyncCache(this._serverUsersCache, [], "useServerUsers()");
1109
1160
  return (0, import_react.useMemo)(() => {
1110
1161
  return json.map((j) => this._serverUserFromJson(j));
1111
1162
  }, [json]);
@@ -1119,7 +1170,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1119
1170
  return await this._serverTeamPermissionDefinitionsCache.getOrWait([], "write-only");
1120
1171
  }
1121
1172
  usePermissionDefinitions() {
1122
- return useCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
1173
+ return useAsyncCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
1123
1174
  }
1124
1175
  _serverPermissionFromJson(json) {
1125
1176
  return {
@@ -1130,7 +1181,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1130
1181
  };
1131
1182
  }
1132
1183
  async createPermissionDefinition(data) {
1133
- const permission = await this._serverPermissionFromJson(await this._interface.createPermissionDefinition(data));
1184
+ const permission = this._serverPermissionFromJson(await this._interface.createPermissionDefinition(data));
1134
1185
  await this._serverTeamPermissionDefinitionsCache.refresh([]);
1135
1186
  return permission;
1136
1187
  }
@@ -1152,7 +1203,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1152
1203
  return this._serverTeamFromJson(team);
1153
1204
  }
1154
1205
  useTeams() {
1155
- const teams = useCache(this._serverTeamsCache, [], "useServerTeams()");
1206
+ const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1156
1207
  return (0, import_react.useMemo)(() => {
1157
1208
  return teams.map((t) => this._serverTeamFromJson(t));
1158
1209
  }, [teams]);
@@ -1167,10 +1218,10 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1167
1218
  return teams.find((t) => t.id === teamId) ?? null;
1168
1219
  }, [teams, teamId]);
1169
1220
  }
1170
- async _refreshUser(tokenStore) {
1221
+ async _refreshUser(session) {
1171
1222
  await Promise.all([
1172
- super._refreshUser(tokenStore),
1173
- this._currentServerUserCache.refresh([tokenStore])
1223
+ super._refreshUser(session),
1224
+ this._currentServerUserCache.refresh([session])
1174
1225
  ]);
1175
1226
  }
1176
1227
  async _refreshUsers() {
@@ -1180,7 +1231,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1180
1231
  ]);
1181
1232
  }
1182
1233
  useEmailTemplates() {
1183
- return useCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
1234
+ return useAsyncCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
1184
1235
  }
1185
1236
  async listEmailTemplates() {
1186
1237
  return await this._serverEmailTemplatesCache.getOrWait([], "write-only");
@@ -1207,9 +1258,8 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1207
1258
  baseUrl: options.baseUrl ?? getDefaultBaseUrl(),
1208
1259
  projectId: options.projectId ?? getDefaultProjectId(),
1209
1260
  clientVersion,
1210
- ..."projectOwnerTokens" in options ? {
1211
- projectOwnerTokens: options.projectOwnerTokens,
1212
- refreshProjectOwnerTokens: options.refreshProjectOwnerTokens
1261
+ ..."projectOwnerSession" in options ? {
1262
+ projectOwnerSession: options.projectOwnerSession
1213
1263
  } : {
1214
1264
  publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
1215
1265
  secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey(),
@@ -1269,7 +1319,7 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1269
1319
  );
1270
1320
  }
1271
1321
  useProjectAdmin() {
1272
- const json = useCache(this._adminProjectCache, [], "useProjectAdmin()");
1322
+ const json = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
1273
1323
  return (0, import_react.useMemo)(() => this._projectAdminFromJson(
1274
1324
  json,
1275
1325
  this._interface,
@@ -1290,7 +1340,7 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1290
1340
  return json.map((j) => this._createApiKeySetFromJson(j));
1291
1341
  }
1292
1342
  useApiKeySets() {
1293
- const json = useCache(this._apiKeySetsCache, [], "useApiKeySets()");
1343
+ const json = useAsyncCache(this._apiKeySetsCache, [], "useApiKeySets()");
1294
1344
  return (0, import_react.useMemo)(() => {
1295
1345
  return json.map((j) => this._createApiKeySetFromJson(j));
1296
1346
  }, [json]);