♻️ Rewrite session storage with CookieAccessor and native Web Locks#4252
Draft
thomas-lebeau wants to merge 25 commits intov7from
Draft
♻️ Rewrite session storage with CookieAccessor and native Web Locks#4252thomas-lebeau wants to merge 25 commits intov7from
thomas-lebeau wants to merge 25 commits intov7from
Conversation
…b to core SessionManager - Add findTrackedSession(sampleRate, startTime, options) to the SessionManager interface so sampling is computed on demand - Add TrackedSession type with id, anonymousId, and isReplayForced fields - Add startSessionManagerStub for event bridge scenarios - Rebuild session context on state update to reflect forcedReplay changes
…ionReplayState.ts - Move SessionType, SessionReplayState enums and computeSessionReplayState function out of rumSessionManager.ts - computeSessionReplayState takes a TrackedSession and RumConfiguration, computing replay state on demand
…ogs package - Delete logsSessionManager.ts, replacing LogsSessionManager with core SessionManager throughout - Pass sampleRate to findTrackedSession at each call site - Update logs mock to implement full SessionManager interface
…m-core package - Delete rumSessionManager.ts, replacing RumSessionManager/RumSession with core SessionManager/TrackedSession - Move session replay state tests to computeSessionReplayState unit tests - Pass sampleRate to findTrackedSession at each call site - Update rum-core mock to implement full SessionManager interface - Re-export SessionReplayState and computeSessionReplayState from sessionReplayState.ts
…playState - Replace RumSessionManager with SessionManager and RumSession with TrackedSession across recorder, profiler, and segment collection - Use computeSessionReplayState for replay state checks in postStartStrategy and getSessionReplayLink - Pass sampleRate to findTrackedSession at each call site
- Remove logsSessionManager.spec.ts and rumSessionManager.spec.ts (now redundant) - Move session manager stub, deterministic sampling, and returnInactive tests into core sessionManager.spec.ts - Extract computeSessionReplayState tests into sessionReplayState.spec.ts
- Extract repeated session manager callback into a named variable in both preStartLogs.ts and preStartRum.ts, cleaning up the if/else branching
- Collapse multi-line imports into single-line in profilerApi.ts and profiler.ts - Expand long single-line import into multi-line in sessionManager.spec.ts
SessionManager now reads sessionSampleRate directly from the configuration object, eliminating the need for every call site to pass it explicitly. This simplifies the API and removes a source of potential inconsistency.
- Remove separate TrackedSession interface and unify with SessionContext - Make anonymousId and isReplayForced optional on SessionContext - Update findTrackedSession return type to SessionContext - Update all references across rum-core and rum packages
- Remove intermediate object wrapping findTrackedSession - Pass sessionManager directly, consistent with other context starters
- Merge two guard conditions into a single check in findTrackedSession - Use spread operator in stub's updateSessionState for generic state updates - Add clarifying comments on session state mutation and TODO for review
- Replace package-specific mockLogsSessionManager and mockRumSessionManager with a single createSessionManagerMock in core/test - Add createStartSessionManagerMock helper for mocking startSessionManager - Update all spec files across logs, rum-core and rum to use the shared mock
- Extract `canStartRecording` and `shouldForceReplay` helper functions to improve readability of the `start()` function - Remove redundant comment in sessionReplayState spec
- Return SAMPLED when bridge supports RECORDS capability, OFF otherwise - Skip sample rate logic entirely in bridge environments - Add unit tests for bridge capability scenarios
|
All contributors have signed the CLA ✍️ ✅ |
Bundles Sizes Evolution
🚀 CPU Performance
🧠 Memory Performance
|
|
✨ Fix all issues with BitsAI or with Cursor
|
…dSession - Return full session object from findTrackedSession instead of a subset of properties - Remove redundant session parameter from canStartRecording, derive recording eligibility from replayState alone - Update tests to call setupRecorderApi in describe blocks closer to where configuration is needed
- Replace runtime mutation of sessionReplaySampleRate with LOW_HASH_UUID and HIGH_HASH_UUID to control whether a session gets replay, reflecting that configuration does not change across session renewals - Reset sample decision cache in cleanup to avoid cross-test leakage - Remove now-unnecessary local `configuration` variables
- Guard three test suites that rely on deterministic hash-based sampling (HIGH_HASH_UUID / sessionReplaySampleRate) with a BigInt availability check, marking them as pending in environments that lack support
- Remove sessionStoreOperations and its cookie-based lock mechanism - Introduce sessionLock module using navigator.locks for concurrency - Simplify sessionStore by inlining retrieve/persist logic within lock - Remove isLockEnabled from SessionStoreStrategy interface - Clean up related tests and fake session store strategy
The cookieObservable only depends on browser-core types and will be needed by the session cookie strategy in core. Move it to core and re-export from rum-core to keep existing imports working.
Introduce a CookieAccessor interface that abstracts cookie operations. Uses the CookieStore API when available for async native cookie access, and falls back to document.cookie with Promise wrappers. Also add set() and delete() to the CookieStore type definition.
Make the SessionStoreStrategy interface async (methods return Promises) to support the CookieStore API which is inherently asynchronous. Key changes: - SessionStoreStrategy methods return Promises - sessionLock supports async callbacks with promise-chain fallback when navigator.locks is unavailable - sessionStore lock callbacks are async, expire() runs inside lock - Replace polling-based session watching with onExternalChange: cookie strategy uses CookieStore events or interval polling, localStorage strategy uses native storage events - Cookie strategy uses CookieAccessor for read/write operations - All test suites updated with flushLock() async drain pattern
…change - Update `previousCookieValue` after each change notification so consecutive changes are correctly detected and the callback is not called on every interval tick when the value is stable - Consolidate `onExternalChange` in sessionInCookie to always use `createCookieObservable` (CookieStore vs. polling is now handled internally by the observable) - Deduplicate `CookieStoreWindow` interface by re-exporting it from `cookieObservable` and importing it where needed - Replace `isEmptyObject` check with `isSessionInNotStartedState` for clearer intent when deciding whether to encode cookie options
7fcd324 to
2dc8eb7
Compare
Base automatically changed from
thomas.lebeau/v7-simplify-session-managers
to
v7
March 9, 2026 10:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The session management layer had accumulated complexity: custom cookie locking logic, duplicated session managers across packages (rum, logs), tightly coupled session store strategies, and synchronous cookie access patterns. This PR rewrites the session storage stack to be simpler, more robust, and aligned with v7 goals.
Changes
CookieAccessorabstraction layer that decouples session logic from raw cookie I/OSessionStoreStrategyfully async with event-driven change detection instead of pollingcookieObservablefrom rum-core to core for proper shared ownershiprumSessionManagerandlogsSessionManagerinto a single coreSessionManagerTrackedSessionintoSessionContext, extractSessionReplayStateandcomputeSessionReplayStatecomputeSessionReplayStatepostStartStrategyTest instructions
yarn test:unit— all unit tests should passyarn test:e2e— session store and tracking consent scenarios updatedChecklist