Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 1x 1x 1x 1x 1x 1x 1x 23x 23x 1x 11x 11x 11x 9x 9x 9x 9x 11x 52x 27x 2x 27x 1x 9x 9x 7x 5x 7x 2x 9x 1x 34x 27x 7x 7x 7x 7x 7x 1x 9x 9x 1x 11x 11x 1x | /*
* SessionManager.ts
* @author Abhilash Panwar (abpanwar) Hector Hernandez (hectorh)
* @copyright Microsoft 2020
* File containing apis to help manage session.
*/
import { Utils, IExtendedTelemetryItem, EventLatency } from '@microsoft/1ds-core-js';
import StorageManager from './StorageManager';
import { _emptyString, _Extensions, _SessionExtKeys, _EISessionKey, _SignalExtKeys, _UserExtKeys, _UserStateValues } from './Constants';
const delimitter = ';';
const extendTime = 1800000; //30 mins
const maxTime = 86400000; //24 hours
const p = parseInt; // for minimization purpose
/**
* Store the session details. <Internal>
*/
interface Session {
/**
* Id.
*/
i: string;
/**
* Expiry time.
*/
e: number;
/**
* Start time.
*/
s: number;
/**
* Max expiry time.
*/
m?: number;
/**
* Is user new.
*/
n?: boolean;
}
/**
* Class to manage session
*/
export default class SessionManager {
private _session: Session;
private _storageManager: StorageManager;
/**
* Creates an instance of the session manager.
* @param storageManager storage manager to store session details.
*/
constructor(storageManager: StorageManager) {
this._storageManager = storageManager;
this._session = this._parseSessionString(this._storageManager._getProperty(_EISessionKey));
}
/**
* Process the session state based on the recieved event and add the session fields.
* @param event Event to add session fields to.
* @param userCookieExists Indicates if the user cookie was created.
*/
_processEvent(event: IExtendedTelemetryItem, userCookieCreated: boolean, isHit: boolean) {
//Add session properties
event.data[_Extensions._SignalExt][_SignalExtKeys._Session] = {};
const eventTime = this._parseISOString(event.time);
//Extend or start session for view events
if (isHit) {
//Add latency to make it high
event.latency = EventLatency.RealTime;
this._extendOrStartSession(eventTime, event, userCookieCreated);
event.data[_Extensions._SignalExt][_SignalExtKeys._User][_UserExtKeys._State] = this._session.n ? _UserStateValues._New : _UserStateValues._Returning;
event.data[_Extensions._SignalExt][_SignalExtKeys._Session][_SessionExtKeys._Duration] = eventTime - this._session.s;
}
event.data[_Extensions._SignalExt][_SignalExtKeys._Session][_SessionExtKeys._Id] = this._isSessionActive(eventTime) ? this._session.i : _emptyString;
}
/**
* Returns true if a session is active. False otherwise.
* @param time The event time for the signal that is used to extend or start the session.
* @param reload Set to true, if we should reload from storage before checking. For view events this should be true.
*/
_isSessionActive(time: number, reload = false): boolean {
if (reload) {
this._session = this._parseSessionString(this._storageManager._getProperty(_EISessionKey));
}
return this._session && Utils.isObject(this._session) && time <= this._session.e;
}
/**
* Extends an ongoing session or starts a new one.
* @param time The event time for the signal that is used to extend or start the session.
* @param event The event that is being processed.
* @param userCookieCreated Indicates if the user user cookie is created.
*/
private _extendOrStartSession(time: number, event: IExtendedTelemetryItem, userCookieCreated: boolean) {
this._session = this._parseSessionString(this._storageManager._getProperty(_EISessionKey));
if (!this._session || this._session.e < time) {
if (!userCookieCreated) {
event.data[_Extensions._SignalExt][_SignalExtKeys._User][_UserExtKeys._TimeSinceVisit] = this._session ? time - this._session.e : _emptyString;
}
//start new session
this._session = {
i: Utils.createGuid(),
s: time,
e: time + extendTime,
m: time + maxTime,
n: userCookieCreated
};
} else {
//extend existing session
this._session.e = time + extendTime < this._session.m ? time + extendTime : this._session.m;
}
this._storageManager._setProperty(_EISessionKey, this._getSessionString(this._session));
}
private _parseSessionString(sessionString: string): Session {
if (!Utils.isString(sessionString)) {
return null;
}
const sessionArr = sessionString.split(delimitter);
const session: Session = { i: sessionArr[0], s: p(sessionArr[1], 10), e: p(sessionArr[2], 10) };
session.m = session.s + maxTime;
session.n = sessionArr.length === 4; // Has new user part of the session.
return session;
}
private _getSessionString(session: Session): string {
var sessionString = session.i + delimitter + session.s + delimitter + session.e;
return session.n ? sessionString + delimitter + session.n : sessionString;
}
private _parseISOString(timeString: string): number {
const b = timeString.split(/\D+/);
return Date.UTC(p(b[0], 10), p(b[1], 10)-1, p(b[2], 10), p(b[3], 10), p(b[4], 10), p(b[5], 10), p(b[6], 10));
}
}
|