Skip to content
85 changes: 45 additions & 40 deletions src/sessionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,24 @@ export default function SessionManager(

this.initialize = function (): void {
if (mpInstance._Store.sessionId) {
const sessionTimeoutInMilliseconds: number =
mpInstance._Store.SDKConfig.sessionTimeout * 60000;

if (
new Date() >
new Date(
mpInstance._Store.dateLastEventSent.getTime() +
sessionTimeoutInMilliseconds
)
) {
const { dateLastEventSent, SDKConfig } = mpInstance._Store;
const { sessionTimeout } = SDKConfig;

Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactoring changes the behavior of session timeout in the initialize() method. Previously, the code used a strictly-greater-than comparison, meaning sessions would only expire AFTER the timeout period (e.g., at 30:00.001, not at 30:00.000). The new code uses greater-than-or-equal, so sessions expire AT the timeout period. While this seems more correct and matches the behavior that endSession() originally had, this is technically a breaking change that could affect existing applications relying on the previous behavior. Consider documenting this change in release notes.

Suggested change
// Note: hasSessionTimedOut() expires sessions AT the configured timeout
// boundary (using a >= comparison), whereas older versions of initialize()
// only expired sessions AFTER the timeout period using a > comparison.
// This aligns initialize() with endSession() but is a behavioral change that
// can affect applications that relied on the previous "grace" past timeout.

Copilot uses AI. Check for mistakes.
if (hasSessionTimedOut(dateLastEventSent?.getTime(), sessionTimeout)) {
self.endSession();
self.startNewSession();
} else {
// https://go.mparticle.com/work/SQDSDKS-6045
// https://go.mparticle.com/work/SQDSDKS-6323
const currentUser = mpInstance.Identity.getCurrentUser();
const sdkIdentityRequest =
mpInstance._Store.SDKConfig.identifyRequest;
const sdkIdentityRequest = SDKConfig.identifyRequest;

if (
hasIdentityRequestChanged(currentUser, sdkIdentityRequest)
) {
mpInstance.Identity.identify(
mpInstance._Store.SDKConfig.identifyRequest,
mpInstance._Store.SDKConfig.identityCallback
sdkIdentityRequest,
SDKConfig.identityCallback
);
mpInstance._Store.identifyCalled = true;
mpInstance._Store.SDKConfig.identityCallback = null;
Expand Down Expand Up @@ -134,12 +127,7 @@ export default function SessionManager(
);

if (override) {
mpInstance._Events.logEvent({
messageType: Types.MessageType.SessionEnd,
});

mpInstance._Store.nullifySession();
mpInstance._timeOnSiteTimer?.resetTimer();
performSessionEnd();
return;
}

Expand All @@ -152,13 +140,9 @@ export default function SessionManager(
Messages.InformationMessages.AbandonEndSession
);
mpInstance._timeOnSiteTimer?.resetTimer();

return;
}

let sessionTimeoutInMilliseconds: number;
let timeSinceLastEventSent: number;

const cookies: IPersistenceMinified =
mpInstance._Persistence.getPersistence();

Expand All @@ -167,7 +151,6 @@ export default function SessionManager(
Messages.InformationMessages.NoSessionToEnd
);
mpInstance._timeOnSiteTimer?.resetTimer();

return;
}

Expand All @@ -177,24 +160,15 @@ export default function SessionManager(
}

if (cookies?.gs?.les) {
sessionTimeoutInMilliseconds =
mpInstance._Store.SDKConfig.sessionTimeout * 60000;
const newDate: number = new Date().getTime();
timeSinceLastEventSent = newDate - cookies.gs.les;

if (timeSinceLastEventSent < sessionTimeoutInMilliseconds) {
self.setSessionTimer();
const sessionTimeout = mpInstance._Store.SDKConfig.sessionTimeout;

if (hasSessionTimedOut(cookies.gs.les, sessionTimeout)) {
performSessionEnd();
} else {
mpInstance._Events.logEvent({
messageType: Types.MessageType.SessionEnd,
});

mpInstance._Store.sessionStartDate = null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed we're not including this line in the performSessionEnd function. Can it be used there? If not, can it be safely removed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaissica12 Did you address this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like she added it to nullify session which happens inside of performSessionEnd

mpInstance._Store.nullifySession();
self.setSessionTimer();
mpInstance._timeOnSiteTimer?.resetTimer();
}
}

mpInstance._timeOnSiteTimer?.resetTimer();
};

this.setSessionTimer = function (): void {
Expand Down Expand Up @@ -234,4 +208,35 @@ export default function SessionManager(
}
}
};

/**
* Checks if the session has expired based on the last event timestamp
* @param lastEventTimestamp - Unix timestamp in milliseconds of the last event
* @param sessionTimeout - Session timeout in minutes
* @returns true if the session has expired, false otherwise
*/
function hasSessionTimedOut(lastEventTimestamp: number, sessionTimeout: number): boolean {
if (!lastEventTimestamp || !sessionTimeout || sessionTimeout <= 0) {
return false;
}

const sessionTimeoutInMilliseconds: number = sessionTimeout * 60000;
const timeSinceLastEvent: number = Date.now() - lastEventTimestamp;

return timeSinceLastEvent >= sessionTimeoutInMilliseconds;
}

/**
* Performs session end operations:
* - Logs a SessionEnd event
* - Nullifies the session ID and related data
* - Resets the time-on-site timer
*/
function performSessionEnd(): void {
mpInstance._Events.logEvent({
messageType: Types.MessageType.SessionEnd,
});
mpInstance._Store.nullifySession();
mpInstance._timeOnSiteTimer?.resetTimer();
}
}
1 change: 1 addition & 0 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ export default function Store(
this.nullifySession = (): void => {
this.sessionId = null;
this.dateLastEventSent = null;
this.sessionStartDate = null;
this.sessionAttributes = {};
this.localSessionAttributes = {};
mpInstance._Persistence.update();
Expand Down
Loading
Loading