From 9ad7eb4e69e6e7763d96a7ed1ec35951b02a6e5e Mon Sep 17 00:00:00 2001 From: Jacek Date: Tue, 4 Nov 2025 20:22:35 -0600 Subject: [PATCH 1/2] feat(clerk-js): Enhance BroadcastChannel logging --- packages/clerk-js/src/core/tokenCache.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/clerk-js/src/core/tokenCache.ts b/packages/clerk-js/src/core/tokenCache.ts index f2003d7f9a2..ddf54e06c0a 100644 --- a/packages/clerk-js/src/core/tokenCache.ts +++ b/packages/clerk-js/src/core/tokenCache.ts @@ -131,6 +131,10 @@ interface SessionTokenEvent { traceId: string; } +const generateTabId = (): string => { + return Math.random().toString(36).slice(2); +}; + /** * Creates an in-memory token cache with optional BroadcastChannel synchronization across tabs. * Automatically manages token expiration and cleanup via scheduled timeouts. @@ -138,6 +142,7 @@ interface SessionTokenEvent { */ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { const cache = new Map(); + const tabId = generateTabId(); let broadcastChannel: BroadcastChannel | null = null; @@ -213,6 +218,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { expectedTokenId, organizationId: data.organizationId, receivedTokenId: data.tokenId, + tabId, template: data.template, traceId: data.traceId, }, @@ -227,7 +233,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { } catch (error) { debugLogger.warn( 'Failed to parse token from broadcast, skipping cache update', - { error, tokenId: data.tokenId, traceId: data.traceId }, + { error, tabId, tokenId: data.tokenId, traceId: data.traceId }, 'tokenCache', ); return; @@ -238,7 +244,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { if (!iat || !exp) { debugLogger.warn( 'Token missing iat/exp claim, skipping cache update', - { tokenId: data.tokenId, traceId: data.traceId }, + { tabId, tokenId: data.tokenId, traceId: data.traceId }, 'tokenCache', ); return; @@ -252,7 +258,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { if (existingIat && existingIat >= iat) { debugLogger.debug( 'Ignoring older token broadcast', - { existingIat, incomingIat: iat, tokenId: data.tokenId, traceId: data.traceId }, + { existingIat, incomingIat: iat, tabId, tokenId: data.tokenId, traceId: data.traceId }, 'tokenCache', ); return; @@ -261,7 +267,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { } catch (error) { debugLogger.warn( 'Existing entry compare failed; proceeding with broadcast update', - { error, tokenId: data.tokenId, traceId: data.traceId }, + { error, tabId, tokenId: data.tokenId, traceId: data.traceId }, 'tokenCache', ); } @@ -271,6 +277,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { { iat, organizationId: data.organizationId, + tabId, template: data.template, tokenId: data.tokenId, traceId: data.traceId, @@ -362,6 +369,7 @@ const MemoryTokenCache = (prefix = KEY_PREFIX): TokenCache => { { organizationId, sessionId, + tabId, template, tokenId: entry.tokenId, traceId, From 032b06b3e713cd53574602f50f389185d12a7503 Mon Sep 17 00:00:00 2001 From: Jacek Date: Thu, 20 Nov 2025 10:08:47 -0600 Subject: [PATCH 2/2] changeset --- .changeset/steady-tabs-log.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/steady-tabs-log.md diff --git a/.changeset/steady-tabs-log.md b/.changeset/steady-tabs-log.md new file mode 100644 index 00000000000..3b9f778dd4f --- /dev/null +++ b/.changeset/steady-tabs-log.md @@ -0,0 +1,6 @@ +--- +'@clerk/clerk-js': patch +--- + +Generate a stable tab identifier in `MemoryTokenCache` so multi-tab token broadcasts can be traced via consistent debug logs. +