@@ -2,7 +2,7 @@ import { Observable } from '../../tools/observable'
22import type { Context } from '../../tools/serialisation/context'
33import { createValueHistory } from '../../tools/valueHistory'
44import type { RelativeTime } from '../../tools/utils/timeUtils'
5- import { clocksOrigin , ONE_MINUTE , relativeNow } from '../../tools/utils/timeUtils'
5+ import { clocksOrigin , dateNow , ONE_MINUTE , relativeNow } from '../../tools/utils/timeUtils'
66import { addEventListener , addEventListeners , DOM_EVENT } from '../../browser/addEventListener'
77import { clearInterval , setInterval } from '../../tools/timer'
88import type { Configuration } from '../configuration'
@@ -11,10 +11,14 @@ import { addTelemetryDebug } from '../telemetry'
1111import { isSyntheticsTest } from '../synthetics/syntheticsWorkerValues'
1212import type { CookieStore } from '../../browser/browser.types'
1313import { getCurrentSite } from '../../browser/cookie'
14+ import { ExperimentalFeature , isExperimentalFeatureEnabled } from '../../tools/experimentalFeatures'
15+ import { findLast } from '../../tools/utils/polyfills'
1416import { SESSION_NOT_TRACKED , SESSION_TIME_OUT_DELAY } from './sessionConstants'
1517import { startSessionStore } from './sessionStore'
1618import type { SessionState } from './sessionState'
19+ import { toSessionState } from './sessionState'
1720import { retrieveSessionCookie } from './storeStrategies/sessionInCookie'
21+ import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy'
1822
1923export interface SessionManager < TrackingType extends string > {
2024 findSession : (
@@ -75,6 +79,12 @@ export function startSessionManager<TrackingType extends string>(
7579 // manager is started.
7680 sessionStore . expandOrRenewSession ( )
7781 sessionContextHistory . add ( buildSessionContext ( ) , clocksOrigin ( ) . relative )
82+ if ( isExperimentalFeatureEnabled ( ExperimentalFeature . SHORT_SESSION_INVESTIGATION ) ) {
83+ const session = sessionStore . getSession ( )
84+ if ( session ) {
85+ detectSessionIdChange ( configuration , session )
86+ }
87+ }
7888
7989 trackingConsentState . observable . subscribe ( ( ) => {
8090 if ( trackingConsentState . isGranted ( ) ) {
@@ -166,9 +176,9 @@ async function reportUnexpectedSessionState() {
166176 let sessionCookies : string [ ] | Awaited < ReturnType < CookieStore [ 'getAll' ] > > = [ ]
167177
168178 if ( 'cookieStore' in window ) {
169- sessionCookies = await ( window as { cookieStore : CookieStore } ) . cookieStore . getAll ( '_dd_s' )
179+ sessionCookies = await ( window as { cookieStore : CookieStore } ) . cookieStore . getAll ( SESSION_STORE_KEY )
170180 } else {
171- sessionCookies = document . cookie . split ( / \s * ; \s * / ) . filter ( ( cookie ) => cookie . startsWith ( '_dd_s' ) )
181+ sessionCookies = document . cookie . split ( / \s * ; \s * / ) . filter ( ( cookie ) => cookie . startsWith ( SESSION_STORE_KEY ) )
172182 }
173183
174184 addTelemetryDebug ( 'Unexpected session state' , {
@@ -184,3 +194,39 @@ async function reportUnexpectedSessionState() {
184194 currentDomain : `${ window . location . protocol } //${ window . location . hostname } ` ,
185195 } )
186196}
197+
198+ function detectSessionIdChange ( configuration : Configuration , initialSessionState : SessionState ) {
199+ if ( ! window . cookieStore || ! initialSessionState . created ) {
200+ return
201+ }
202+
203+ const sessionCreatedTime = Number ( initialSessionState . created )
204+ const sdkInitTime = dateNow ( )
205+
206+ const { stop } = addEventListener ( configuration , cookieStore as CookieStore , DOM_EVENT . CHANGE , listener )
207+ stopCallbacks . push ( stop )
208+
209+ function listener ( event : CookieChangeEvent ) {
210+ const changed = findLast ( event . changed , ( change ) : change is CookieListItem => change . name === SESSION_STORE_KEY )
211+ if ( ! changed ) {
212+ return
213+ }
214+
215+ const sessionAge = dateNow ( ) - sessionCreatedTime
216+ if ( sessionAge > 14 * ONE_MINUTE ) {
217+ // The session might have expired just because it's too old or lack activity
218+ stop ( )
219+ } else {
220+ const newSessionState = toSessionState ( changed . value )
221+ if ( newSessionState . id !== initialSessionState . id ) {
222+ addTelemetryDebug ( 'Session cookie changed' , {
223+ time : dateNow ( ) - sdkInitTime ,
224+ session_age : sessionAge ,
225+ old : initialSessionState ,
226+ new : newSessionState ,
227+ } )
228+ stop ( )
229+ }
230+ }
231+ }
232+ }
0 commit comments