@hexclave/js 1.0.9 → 1.0.11

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 (48) hide show
  1. package/dist/config.d.ts +2 -0
  2. package/dist/config.js +22 -0
  3. package/dist/esm/config.d.ts +2 -0
  4. package/dist/esm/config.js +3 -0
  5. package/dist/esm/index.js +1 -1
  6. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  7. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js +4 -4
  8. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  9. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  10. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +3 -2
  11. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  12. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +1 -1
  13. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  14. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +2 -1
  15. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  16. package/dist/esm/lib/hexclave-app/url-targets.d.ts.map +1 -1
  17. package/dist/esm/lib/hexclave-app/url-targets.js +1 -0
  18. package/dist/esm/lib/hexclave-app/url-targets.js.map +1 -1
  19. package/dist/esm/lib/hexclave-app/url-targets.test.js +1 -0
  20. package/dist/esm/lib/hexclave-app/url-targets.test.js.map +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/integrations/convex/component/convex.config.d.ts +1 -1
  23. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  24. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +4 -4
  25. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  26. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  27. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +3 -2
  28. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  29. package/dist/lib/hexclave-app/apps/implementations/common.js +1 -1
  30. package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  31. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +2 -1
  32. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  33. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  34. package/dist/lib/hexclave-app/common.d.ts +1 -1
  35. package/dist/lib/hexclave-app/url-targets.d.ts.map +1 -1
  36. package/dist/lib/hexclave-app/url-targets.js +1 -0
  37. package/dist/lib/hexclave-app/url-targets.js.map +1 -1
  38. package/dist/lib/hexclave-app/url-targets.test.js +1 -0
  39. package/dist/lib/hexclave-app/url-targets.test.js.map +1 -1
  40. package/dist/{storage-CKsyME2q.d.ts → storage-CG8QLF8G.d.ts} +1 -1
  41. package/dist/{storage-CKsyME2q.d.ts.map → storage-CG8QLF8G.d.ts.map} +1 -1
  42. package/package.json +11 -2
  43. package/src/config.ts +17 -0
  44. package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +7 -4
  45. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +8 -4
  46. package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +1 -0
  47. package/src/lib/hexclave-app/url-targets.test.ts +1 -0
  48. package/src/lib/hexclave-app/url-targets.ts +1 -0
@@ -102,8 +102,12 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
102
102
  private readonly _svixTokenCache = createCache(async () => {
103
103
  return await this._interface.getSvixToken();
104
104
  });
105
- private readonly _metricsCache = createCache(async ([includeAnonymous]: [boolean]) => {
106
- return await this._interface.getMetrics(includeAnonymous);
105
+ // Cache key serializes filters via URLSearchParams (sorted keys) so
106
+ // DependenciesMap (identity-keyed per array slot) treats two equal
107
+ // filter objects as the same deterministic string entry.
108
+ private readonly _metricsCache = createCache(async ([includeAnonymous, filtersKey]: [boolean, string]) => {
109
+ const filters = filtersKey ? Object.fromEntries(new URLSearchParams(filtersKey)) : undefined;
110
+ return await this._interface.getMetrics(includeAnonymous, filters);
107
111
  });
108
112
  private readonly _userActivityCache = createCache(async ([userId]: [string]) => {
109
113
  return await this._interface.getUserActivity(userId);
@@ -486,8 +490,7 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
486
490
  protected override async _refreshUsers() {
487
491
  await Promise.all([
488
492
  super._refreshUsers(),
489
- this._metricsCache.refresh([false]),
490
- this._metricsCache.refresh([true]),
493
+ this._metricsCache.refreshWhere(() => true),
491
494
  this._metricsUserCountsCache.refresh([]),
492
495
  ]);
493
496
  }
@@ -1443,10 +1443,14 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
1443
1443
  const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper());
1444
1444
  tokenStore.set(tokens);
1445
1445
 
1446
- // Pre-fetch the current user for the new session so the cache is already
1447
- // populated when useUser() re-renders, avoiding a stale-cache render cycle.
1448
- const newSession = this._getSessionFromTokenStore(tokenStore);
1449
- this._currentUserCache.getOrWait([newSession], "write-only").catch(() => {});
1446
+ // If these tokens resolve to a session we already have (eg. the RDE dashboard re-installing a freshly minted
1447
+ // access token for the same access-only session), push the new token into it in place; constructing a new
1448
+ // session here would cold-invalidate every session-scoped cache and suspend the UI on each refresh.
1449
+ const session = this._getSessionFromTokenStore(tokenStore);
1450
+ session.updateAccessToken(tokens);
1451
+
1452
+ // Pre-fetch the current user so the cache is warm when useUser() re-renders (write-only, so it never suspends).
1453
+ runAsynchronously(this._currentUserCache.getOrWait([session], "write-only"));
1450
1454
  }
1451
1455
 
1452
1456
  protected _getTokenStoreInitForFreshTokens(tokens: { accessToken: string | null, refreshToken: string }): TokenStoreInit | undefined {
@@ -128,6 +128,7 @@ export class EventTracker {
128
128
  viewport_height: window.innerHeight,
129
129
  screen_width: screenObject.width,
130
130
  screen_height: screenObject.height,
131
+ user_agent: typeof navigator !== "undefined" ? navigator.userAgent : null,
131
132
  },
132
133
  });
133
134
  }
@@ -112,6 +112,7 @@ describe("handler URL targets", () => {
112
112
 
113
113
  expect(urls.signIn).toBe("https://project-id.example-stack-hosted.test/handler/sign-in");
114
114
  expect(urls.signOut).toBe("https://project-id.example-stack-hosted.test/handler/sign-out");
115
+ expect(urls.home).toBe("/");
115
116
  expect(urls.afterSignIn).toBe("/");
116
117
  expect(urls.afterSignUp).toBe("/");
117
118
  expect(urls.afterSignOut).toBe("/");
@@ -125,6 +125,7 @@ const isRelativeUrlString = (url: string): boolean => {
125
125
  };
126
126
 
127
127
  const nonHostedHandlerNames = new Set<keyof HandlerUrls>([
128
+ "home",
128
129
  "afterSignIn",
129
130
  "afterSignUp",
130
131
  "afterSignOut",