Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/curly-dingos-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@clerk/clerk-js': minor
---

Optimized session token poller to share token with other open tabs

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { createTestUtils, testAgainstRunningApps } from '../../testUtils';
* token fetches in one tab are automatically broadcast and cached in other tabs,
* eliminating redundant network requests.
*/
testAgainstRunningApps({ withEnv: [appConfigs.envs.withBroadcastChannel] })(
testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes] })(
'MemoryTokenCache Multi-Tab Integration @generic',
({ app }) => {
test.describe.configure({ mode: 'serial' });
Expand Down
18 changes: 8 additions & 10 deletions packages/clerk-js/src/core/tokenCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const generateTabId = (): string => {
/**
* Creates an in-memory token cache with optional BroadcastChannel synchronization across tabs.
* Automatically manages token expiration and cleanup via scheduled timeouts.
* BroadcastChannel support is enabled only in the channel build variant.
* BroadcastChannel support is enabled whenever the environment provides it.
*/
const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => {
const cache = new Map<string, TokenCacheValue>();
Expand All @@ -147,21 +147,19 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => {
let broadcastChannel: BroadcastChannel | null = null;

const ensureBroadcastChannel = (): BroadcastChannel | null => {
if (!__BUILD_VARIANT_CHANNEL__) {
return null;
}

if (broadcastChannel) {
return broadcastChannel;
}

if (typeof BroadcastChannel !== 'undefined') {
broadcastChannel = new BroadcastChannel('clerk:session_token');
broadcastChannel.addEventListener('message', (e: MessageEvent<SessionTokenEvent>) => {
void handleBroadcastMessage(e);
});
if (typeof BroadcastChannel === 'undefined') {
return null;
}

broadcastChannel = new BroadcastChannel('clerk:session_token');
broadcastChannel.addEventListener('message', (e: MessageEvent<SessionTokenEvent>) => {
void handleBroadcastMessage(e);
});

return broadcastChannel;
};

Expand Down
Loading