@grafana/faro-web-sdk 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/faro-web-sdk.iife.js +1 -1
- package/dist/bundle/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/performance/types.d.ts +1 -0
- package/dist/bundle/types/instrumentations/session/instrumentation.d.ts +2 -2
- package/dist/bundle/types/instrumentations/session/sessionManager/sessionManagerUtils.d.ts +3 -1
- package/dist/bundle/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
- package/dist/bundle/types/transports/console/transport.d.ts +1 -1
- package/dist/bundle/types/transports/fetch/transport.d.ts +1 -1
- package/dist/cjs/instrumentations/performance/performanceUtils.js +1 -0
- package/dist/cjs/instrumentations/performance/performanceUtils.js.map +1 -1
- package/dist/cjs/instrumentations/performance/performanceUtilsTestData.js +2 -0
- package/dist/cjs/instrumentations/performance/performanceUtilsTestData.js.map +1 -1
- package/dist/cjs/instrumentations/performance/types.js.map +1 -1
- package/dist/cjs/instrumentations/session/instrumentation.js +32 -25
- package/dist/cjs/instrumentations/session/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js +11 -5
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/esm/instrumentations/performance/performanceUtils.js +1 -0
- package/dist/esm/instrumentations/performance/performanceUtils.js.map +1 -1
- package/dist/esm/instrumentations/performance/performanceUtilsTestData.js +2 -0
- package/dist/esm/instrumentations/performance/performanceUtilsTestData.js.map +1 -1
- package/dist/esm/instrumentations/performance/types.js.map +1 -1
- package/dist/esm/instrumentations/session/instrumentation.js +32 -25
- package/dist/esm/instrumentations/session/instrumentation.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js +11 -5
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/performance/types.d.ts +1 -0
- package/dist/types/instrumentations/session/instrumentation.d.ts +2 -2
- package/dist/types/instrumentations/session/sessionManager/sessionManagerUtils.d.ts +3 -1
- package/dist/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/webVitals/instrumentation.d.ts +1 -1
- package/dist/types/transports/console/transport.d.ts +1 -1
- package/dist/types/transports/fetch/transport.d.ts +1 -1
- package/package.json +3 -3
|
@@ -56,10 +56,9 @@ var SessionInstrumentation = /** @class */ (function (_super) {
|
|
|
56
56
|
this.api.pushEvent(faro_core_1.EVENT_SESSION_START, {}, undefined, { skipDedupe: true });
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
SessionInstrumentation.prototype.
|
|
60
|
-
var _a, _b, _c;
|
|
61
|
-
var
|
|
62
|
-
var userSession = sessionManager.fetchUserSession();
|
|
59
|
+
SessionInstrumentation.prototype.createInitialSession = function (SessionManager, sessionsConfig) {
|
|
60
|
+
var _a, _b, _c, _d, _e;
|
|
61
|
+
var userSession = SessionManager.fetchUserSession();
|
|
63
62
|
if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {
|
|
64
63
|
var now = (0, faro_core_1.dateNow)();
|
|
65
64
|
var shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;
|
|
@@ -68,23 +67,36 @@ var SessionInstrumentation = /** @class */ (function (_super) {
|
|
|
68
67
|
userSession = null;
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
|
-
var sessionId = (_a = sessionsConfig.session) === null || _a === void 0 ? void 0 : _a.id;
|
|
72
|
-
var sessionAttributes = (_b = sessionsConfig.session) === null || _b === void 0 ? void 0 : _b.attributes;
|
|
73
70
|
var lifecycleType;
|
|
71
|
+
var initialSession;
|
|
74
72
|
if ((0, sessionManagerUtils_1.isUserSessionValid)(userSession)) {
|
|
75
|
-
sessionId = userSession === null || userSession === void 0 ? void 0 : userSession.sessionId;
|
|
76
|
-
|
|
73
|
+
var sessionId = userSession === null || userSession === void 0 ? void 0 : userSession.sessionId;
|
|
74
|
+
initialSession = (0, sessionManagerUtils_1.createUserSessionObject)({
|
|
75
|
+
sessionId: sessionId,
|
|
76
|
+
isSampled: userSession.isSampled || false,
|
|
77
|
+
started: userSession === null || userSession === void 0 ? void 0 : userSession.started,
|
|
78
|
+
});
|
|
79
|
+
initialSession.sessionMeta = {
|
|
80
|
+
id: sessionId,
|
|
81
|
+
attributes: __assign(__assign(__assign({}, (_a = sessionsConfig.session) === null || _a === void 0 ? void 0 : _a.attributes), (_b = userSession === null || userSession === void 0 ? void 0 : userSession.sessionMeta) === null || _b === void 0 ? void 0 : _b.attributes), {
|
|
82
|
+
// For valid resumed sessions we do not want to recalculate the sampling decision on each init phase.
|
|
83
|
+
isSampled: initialSession.isSampled.toString() }),
|
|
84
|
+
};
|
|
77
85
|
lifecycleType = faro_core_1.EVENT_SESSION_RESUME;
|
|
78
86
|
}
|
|
79
87
|
else {
|
|
80
|
-
sessionId =
|
|
88
|
+
var sessionId = (_d = (_c = sessionsConfig.session) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : (0, metas_1.createSession)().id;
|
|
89
|
+
initialSession = (0, sessionManagerUtils_1.createUserSessionObject)({
|
|
90
|
+
sessionId: sessionId,
|
|
91
|
+
isSampled: (0, sessionManager_1.isSampled)(),
|
|
92
|
+
});
|
|
93
|
+
initialSession.sessionMeta = {
|
|
94
|
+
id: sessionId,
|
|
95
|
+
attributes: __assign({ isSampled: initialSession.isSampled.toString() }, (_e = sessionsConfig.session) === null || _e === void 0 ? void 0 : _e.attributes),
|
|
96
|
+
};
|
|
81
97
|
lifecycleType = faro_core_1.EVENT_SESSION_START;
|
|
82
98
|
}
|
|
83
|
-
|
|
84
|
-
id: sessionId,
|
|
85
|
-
attributes: __assign({ isSampled: (0, sessionManager_1.isSampled)().toString() }, sessionAttributes),
|
|
86
|
-
};
|
|
87
|
-
return { sessionMeta: sessionMeta, lifecycleType: lifecycleType };
|
|
99
|
+
return { initialSession: initialSession, lifecycleType: lifecycleType };
|
|
88
100
|
};
|
|
89
101
|
SessionInstrumentation.prototype.registerBeforeSendHook = function (SessionManager) {
|
|
90
102
|
var _a;
|
|
@@ -114,19 +126,14 @@ var SessionInstrumentation = /** @class */ (function (_super) {
|
|
|
114
126
|
});
|
|
115
127
|
};
|
|
116
128
|
SessionInstrumentation.prototype.initialize = function () {
|
|
117
|
-
var _a, _b;
|
|
118
129
|
this.logDebug('init session instrumentation');
|
|
119
|
-
var
|
|
120
|
-
if (
|
|
121
|
-
var SessionManager = (
|
|
122
|
-
? PersistentSessionsManager_1.PersistentSessionsManager
|
|
123
|
-
: VolatileSessionManager_1.VolatileSessionsManager;
|
|
130
|
+
var sessionTrackingConfig = this.config.sessionTracking;
|
|
131
|
+
if (sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.enabled) {
|
|
132
|
+
var SessionManager = (sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.persistent) ? PersistentSessionsManager_1.PersistentSessionsManager : VolatileSessionManager_1.VolatileSessionsManager;
|
|
124
133
|
this.registerBeforeSendHook(SessionManager);
|
|
125
|
-
var
|
|
126
|
-
SessionManager.storeUserSession(
|
|
127
|
-
|
|
128
|
-
isSampled: ((_b = initialSessionMeta.attributes) === null || _b === void 0 ? void 0 : _b['isSampled']) === 'true',
|
|
129
|
-
})), { sessionMeta: initialSessionMeta }));
|
|
134
|
+
var _a = this.createInitialSession(SessionManager, sessionTrackingConfig), initialSession = _a.initialSession, lifecycleType = _a.lifecycleType;
|
|
135
|
+
SessionManager.storeUserSession(initialSession);
|
|
136
|
+
var initialSessionMeta = initialSession.sessionMeta;
|
|
130
137
|
this.notifiedSession = initialSessionMeta;
|
|
131
138
|
this.api.setSession(initialSessionMeta);
|
|
132
139
|
if (lifecycleType === faro_core_1.EVENT_SESSION_START) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/session/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseInstrumentation,\n dateNow,\n EVENT_SESSION_EXTEND,\n EVENT_SESSION_RESUME,\n EVENT_SESSION_START,\n Meta,\n MetaSession,\n VERSION,\n} from '@grafana/faro-core';\nimport type { Config } from '@grafana/faro-core';\n\nimport type { TransportItem } from '../..';\nimport { createSession } from '../../metas';\n\nimport { type FaroUserSession, isSampled } from './sessionManager';\nimport { PersistentSessionsManager } from './sessionManager/PersistentSessionsManager';\nimport { createUserSessionObject, isUserSessionValid } from './sessionManager/sessionManagerUtils';\nimport { VolatileSessionsManager } from './sessionManager/VolatileSessionManager';\n\ntype LifecycleType = typeof EVENT_SESSION_RESUME | typeof EVENT_SESSION_START;\n\nexport class SessionInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-session';\n readonly version = VERSION;\n\n // previously notified session, to ensure we don't send session start\n // event twice for the same session\n private notifiedSession: MetaSession | undefined;\n\n private sendSessionStartEvent(meta: Meta): void {\n const session = meta.session;\n\n if (session && session.id !== this.notifiedSession?.id) {\n if (this.notifiedSession && this.notifiedSession.id === session.attributes?.['previousSession']) {\n this.api.pushEvent(EVENT_SESSION_EXTEND, {}, undefined, { skipDedupe: true });\n this.notifiedSession = session;\n return;\n }\n\n this.notifiedSession = session;\n // no need to add attributes and session id, they are included as part of meta\n // automatically\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n }\n\n private createInitialSessionMeta(sessionsConfig: Required<Config>['sessionTracking']): {\n sessionMeta: MetaSession;\n lifecycleType: LifecycleType;\n } {\n const sessionManager = sessionsConfig.persistent ? PersistentSessionsManager : VolatileSessionsManager;\n\n let userSession: FaroUserSession | null = sessionManager.fetchUserSession();\n\n if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {\n const now = dateNow();\n const shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;\n\n if (shouldClearPersistentSession) {\n PersistentSessionsManager.removeUserSession();\n userSession = null;\n }\n }\n\n let sessionId = sessionsConfig.session?.id;\n let sessionAttributes = sessionsConfig.session?.attributes;\n\n let lifecycleType: LifecycleType;\n\n if (isUserSessionValid(userSession)) {\n sessionId = userSession?.sessionId;\n sessionAttributes = {\n ...sessionAttributes,\n ...userSession?.sessionMeta?.attributes,\n isSampled: (userSession!.isSampled || false).toString(),\n };\n\n lifecycleType = EVENT_SESSION_RESUME;\n } else {\n sessionId = sessionId ?? createSession().id;\n lifecycleType = EVENT_SESSION_START;\n }\n\n const sessionMeta: MetaSession = {\n id: sessionId,\n attributes: {\n isSampled: isSampled().toString(),\n // We do not want to recalculate the sampling decision on each init phase.\n // If session from web-storage has a isSampled attribute we will use that instead.\n ...sessionAttributes,\n },\n };\n\n return { sessionMeta, lifecycleType };\n }\n\n private registerBeforeSendHook(SessionManager: typeof VolatileSessionsManager | typeof PersistentSessionsManager) {\n const { updateSession } = new SessionManager();\n\n this.transports?.addBeforeSendHooks((item) => {\n updateSession();\n\n const attributes = item.meta.session?.attributes;\n\n if (attributes && attributes?.['isSampled'] === 'true') {\n let newItem: TransportItem;\n\n // Structured clone is supported in all major browsers\n // but for old browsers we need a fallback\n if ('structuredClone' in window) {\n newItem = structuredClone(item);\n } else {\n newItem = JSON.parse(JSON.stringify(item));\n }\n\n const newAttributes = newItem.meta.session?.attributes;\n delete newAttributes?.['isSampled'];\n\n if (Object.keys(newAttributes ?? {}).length === 0) {\n delete newItem.meta.session?.attributes;\n }\n\n return newItem;\n }\n\n return null;\n });\n }\n\n initialize() {\n this.logDebug('init session instrumentation');\n\n const sessionTracking = this.config.sessionTracking;\n\n if (sessionTracking?.enabled) {\n const SessionManager = this.config.sessionTracking?.persistent\n ? PersistentSessionsManager\n : VolatileSessionsManager;\n\n this.registerBeforeSendHook(SessionManager);\n\n const { sessionMeta: initialSessionMeta, lifecycleType } = this.createInitialSessionMeta(sessionTracking);\n\n SessionManager.storeUserSession({\n ...createUserSessionObject({\n sessionId: initialSessionMeta.id,\n isSampled: initialSessionMeta.attributes?.['isSampled'] === 'true',\n }),\n sessionMeta: initialSessionMeta,\n });\n\n this.notifiedSession = initialSessionMeta;\n this.api.setSession(initialSessionMeta);\n\n if (lifecycleType === EVENT_SESSION_START) {\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n\n if (lifecycleType === EVENT_SESSION_RESUME) {\n this.api.pushEvent(EVENT_SESSION_RESUME, {}, undefined, { skipDedupe: true });\n }\n }\n\n this.metas.addListener(this.sendSessionStartEvent.bind(this));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/session/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseInstrumentation,\n dateNow,\n EVENT_SESSION_EXTEND,\n EVENT_SESSION_RESUME,\n EVENT_SESSION_START,\n Meta,\n MetaSession,\n VERSION,\n} from '@grafana/faro-core';\nimport type { Config } from '@grafana/faro-core';\n\nimport type { TransportItem } from '../..';\nimport { createSession } from '../../metas';\n\nimport { type FaroUserSession, isSampled } from './sessionManager';\nimport { PersistentSessionsManager } from './sessionManager/PersistentSessionsManager';\nimport { createUserSessionObject, isUserSessionValid } from './sessionManager/sessionManagerUtils';\nimport { VolatileSessionsManager } from './sessionManager/VolatileSessionManager';\n\ntype LifecycleType = typeof EVENT_SESSION_RESUME | typeof EVENT_SESSION_START;\ntype SessionManager = typeof VolatileSessionsManager | typeof PersistentSessionsManager;\n\nexport class SessionInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-session';\n readonly version = VERSION;\n\n // previously notified session, to ensure we don't send session start\n // event twice for the same session\n private notifiedSession: MetaSession | undefined;\n\n private sendSessionStartEvent(meta: Meta): void {\n const session = meta.session;\n\n if (session && session.id !== this.notifiedSession?.id) {\n if (this.notifiedSession && this.notifiedSession.id === session.attributes?.['previousSession']) {\n this.api.pushEvent(EVENT_SESSION_EXTEND, {}, undefined, { skipDedupe: true });\n this.notifiedSession = session;\n return;\n }\n\n this.notifiedSession = session;\n // no need to add attributes and session id, they are included as part of meta\n // automatically\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n }\n\n private createInitialSession(\n SessionManager: SessionManager,\n sessionsConfig: Required<Config>['sessionTracking']\n ): {\n initialSession: FaroUserSession;\n lifecycleType: LifecycleType;\n } {\n let userSession: FaroUserSession | null = SessionManager.fetchUserSession();\n\n if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {\n const now = dateNow();\n const shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;\n\n if (shouldClearPersistentSession) {\n PersistentSessionsManager.removeUserSession();\n userSession = null;\n }\n }\n\n let lifecycleType: LifecycleType;\n let initialSession: FaroUserSession;\n\n if (isUserSessionValid(userSession)) {\n const sessionId = userSession?.sessionId;\n\n initialSession = createUserSessionObject({\n sessionId,\n isSampled: userSession!.isSampled || false,\n started: userSession?.started,\n });\n\n initialSession.sessionMeta = {\n id: sessionId,\n attributes: {\n ...sessionsConfig.session?.attributes,\n ...userSession?.sessionMeta?.attributes,\n // For valid resumed sessions we do not want to recalculate the sampling decision on each init phase.\n isSampled: initialSession.isSampled.toString(),\n },\n };\n\n lifecycleType = EVENT_SESSION_RESUME;\n } else {\n const sessionId = sessionsConfig.session?.id ?? createSession().id;\n\n initialSession = createUserSessionObject({\n sessionId,\n isSampled: isSampled(),\n });\n\n initialSession.sessionMeta = {\n id: sessionId,\n attributes: {\n isSampled: initialSession.isSampled.toString(),\n ...sessionsConfig.session?.attributes,\n },\n };\n\n lifecycleType = EVENT_SESSION_START;\n }\n\n return { initialSession, lifecycleType };\n }\n\n private registerBeforeSendHook(SessionManager: SessionManager) {\n const { updateSession } = new SessionManager();\n\n this.transports?.addBeforeSendHooks((item) => {\n updateSession();\n\n const attributes = item.meta.session?.attributes;\n\n if (attributes && attributes?.['isSampled'] === 'true') {\n let newItem: TransportItem;\n\n // Structured clone is supported in all major browsers\n // but for old browsers we need a fallback\n if ('structuredClone' in window) {\n newItem = structuredClone(item);\n } else {\n newItem = JSON.parse(JSON.stringify(item));\n }\n\n const newAttributes = newItem.meta.session?.attributes;\n delete newAttributes?.['isSampled'];\n\n if (Object.keys(newAttributes ?? {}).length === 0) {\n delete newItem.meta.session?.attributes;\n }\n\n return newItem;\n }\n\n return null;\n });\n }\n\n initialize() {\n this.logDebug('init session instrumentation');\n\n const sessionTrackingConfig = this.config.sessionTracking;\n\n if (sessionTrackingConfig?.enabled) {\n const SessionManager = sessionTrackingConfig?.persistent ? PersistentSessionsManager : VolatileSessionsManager;\n\n this.registerBeforeSendHook(SessionManager);\n\n const { initialSession, lifecycleType } = this.createInitialSession(SessionManager, sessionTrackingConfig);\n\n SessionManager.storeUserSession(initialSession);\n\n const initialSessionMeta = initialSession.sessionMeta;\n\n this.notifiedSession = initialSessionMeta;\n this.api.setSession(initialSessionMeta);\n\n if (lifecycleType === EVENT_SESSION_START) {\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n\n if (lifecycleType === EVENT_SESSION_RESUME) {\n this.api.pushEvent(EVENT_SESSION_RESUME, {}, undefined, { skipDedupe: true });\n }\n }\n\n this.metas.addListener(this.sendSessionStartEvent.bind(this));\n }\n}\n"]}
|
|
@@ -13,11 +13,12 @@ var __assign = (this && this.__assign) || function () {
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.addSessionMetadataToNextSession = exports.getUserSessionUpdater = exports.isUserSessionValid = exports.createUserSessionObject = void 0;
|
|
15
15
|
var faro_core_1 = require("@grafana/faro-core");
|
|
16
|
+
var utils_1 = require("../../../utils");
|
|
16
17
|
var sampling_1 = require("./sampling");
|
|
17
18
|
var sessionConstants_1 = require("./sessionConstants");
|
|
18
19
|
function createUserSessionObject(_a) {
|
|
19
20
|
var _b, _c;
|
|
20
|
-
var _d = _a === void 0 ? {} : _a, sessionId = _d.sessionId, _e = _d.isSampled, isSampled = _e === void 0 ? true : _e;
|
|
21
|
+
var _d = _a === void 0 ? {} : _a, sessionId = _d.sessionId, started = _d.started, lastActivity = _d.lastActivity, _e = _d.isSampled, isSampled = _e === void 0 ? true : _e;
|
|
21
22
|
var now = (0, faro_core_1.dateNow)();
|
|
22
23
|
var generateSessionId = (_c = (_b = faro_core_1.faro.config) === null || _b === void 0 ? void 0 : _b.sessionTracking) === null || _c === void 0 ? void 0 : _c.generateSessionId;
|
|
23
24
|
if (sessionId == null) {
|
|
@@ -25,8 +26,8 @@ function createUserSessionObject(_a) {
|
|
|
25
26
|
}
|
|
26
27
|
return {
|
|
27
28
|
sessionId: sessionId,
|
|
28
|
-
lastActivity: now,
|
|
29
|
-
started: now,
|
|
29
|
+
lastActivity: lastActivity !== null && lastActivity !== void 0 ? lastActivity : now,
|
|
30
|
+
started: started !== null && started !== void 0 ? started : now,
|
|
30
31
|
isSampled: isSampled,
|
|
31
32
|
};
|
|
32
33
|
}
|
|
@@ -47,10 +48,15 @@ exports.isUserSessionValid = isUserSessionValid;
|
|
|
47
48
|
function getUserSessionUpdater(_a) {
|
|
48
49
|
var fetchUserSession = _a.fetchUserSession, storeUserSession = _a.storeUserSession;
|
|
49
50
|
return function updateSession() {
|
|
50
|
-
var _a, _b, _c
|
|
51
|
+
var _a, _b, _c;
|
|
51
52
|
if (!fetchUserSession || !storeUserSession) {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
55
|
+
var sessionTrackingConfig = faro_core_1.faro.config.sessionTracking;
|
|
56
|
+
var isPersistentSessions = sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.persistent;
|
|
57
|
+
if ((isPersistentSessions && !utils_1.isLocalStorageAvailable) || (!isPersistentSessions && !utils_1.isSessionStorageAvailable)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
54
60
|
var sessionFromStorage = fetchUserSession();
|
|
55
61
|
if (isUserSessionValid(sessionFromStorage)) {
|
|
56
62
|
storeUserSession(__assign(__assign({}, sessionFromStorage), { lastActivity: (0, faro_core_1.dateNow)() }));
|
|
@@ -59,7 +65,7 @@ function getUserSessionUpdater(_a) {
|
|
|
59
65
|
var newSession = addSessionMetadataToNextSession(createUserSessionObject({ isSampled: (0, sampling_1.isSampled)() }), sessionFromStorage);
|
|
60
66
|
storeUserSession(newSession);
|
|
61
67
|
(_a = faro_core_1.faro.api) === null || _a === void 0 ? void 0 : _a.setSession(newSession.sessionMeta);
|
|
62
|
-
(
|
|
68
|
+
(_b = sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.onSessionChange) === null || _b === void 0 ? void 0 : _b.call(sessionTrackingConfig, (_c = sessionFromStorage === null || sessionFromStorage === void 0 ? void 0 : sessionFromStorage.sessionMeta) !== null && _c !== void 0 ? _c : null, newSession.sessionMeta);
|
|
63
69
|
}
|
|
64
70
|
};
|
|
65
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionManagerUtils.js","sourceRoot":"","sources":["../../../../../src/instrumentations/session/sessionManager/sessionManagerUtils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,gDAA+D;AAE/D,uCAAuC;AACvC,uDAAsF;
|
|
1
|
+
{"version":3,"file":"sessionManagerUtils.js","sourceRoot":"","sources":["../../../../../src/instrumentations/session/sessionManager/sessionManagerUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { dateNow, faro, genShortID } from '@grafana/faro-core';\n\nimport { isLocalStorageAvailable, isSessionStorageAvailable } from '../../../utils';\n\nimport { isSampled } from './sampling';\nimport { SESSION_EXPIRATION_TIME, SESSION_INACTIVITY_TIME } from './sessionConstants';\nimport type { FaroUserSession } from './types';\n\ntype CreateUserSessionObjectParams = {\n sessionId?: string;\n started?: number;\n lastActivity?: number;\n isSampled?: boolean;\n};\n\nexport function createUserSessionObject({\n sessionId,\n started,\n lastActivity,\n isSampled = true,\n}: CreateUserSessionObjectParams = {}): FaroUserSession {\n const now = dateNow();\n\n const generateSessionId = faro.config?.sessionTracking?.generateSessionId;\n\n if (sessionId == null) {\n sessionId = typeof generateSessionId === 'function' ? generateSessionId() : genShortID();\n }\n\n return {\n sessionId,\n lastActivity: lastActivity ?? now,\n started: started ?? now,\n isSampled: isSampled,\n };\n}\n\nexport function isUserSessionValid(session: FaroUserSession | null): boolean {\n if (session == null) {\n return false;\n }\n\n const now = dateNow();\n const lifetimeValid = now - session.started < SESSION_EXPIRATION_TIME;\n\n if (!lifetimeValid) {\n return false;\n }\n\n const inactivityPeriodValid = now - session.lastActivity < SESSION_INACTIVITY_TIME;\n return inactivityPeriodValid;\n}\n\ntype GetUserSessionUpdaterParams = {\n storeUserSession: (session: FaroUserSession) => void;\n fetchUserSession: () => FaroUserSession | null;\n};\n\nexport function getUserSessionUpdater({ fetchUserSession, storeUserSession }: GetUserSessionUpdaterParams): () => void {\n return function updateSession(): void {\n if (!fetchUserSession || !storeUserSession) {\n return;\n }\n\n const sessionTrackingConfig = faro.config.sessionTracking;\n const isPersistentSessions = sessionTrackingConfig?.persistent;\n\n if ((isPersistentSessions && !isLocalStorageAvailable) || (!isPersistentSessions && !isSessionStorageAvailable)) {\n return;\n }\n\n const sessionFromStorage = fetchUserSession();\n\n if (isUserSessionValid(sessionFromStorage)) {\n storeUserSession({ ...sessionFromStorage!, lastActivity: dateNow() });\n } else {\n let newSession = addSessionMetadataToNextSession(\n createUserSessionObject({ isSampled: isSampled() }),\n sessionFromStorage\n );\n\n storeUserSession(newSession);\n\n faro.api?.setSession(newSession.sessionMeta);\n sessionTrackingConfig?.onSessionChange?.(sessionFromStorage?.sessionMeta ?? null, newSession.sessionMeta!);\n }\n };\n}\n\nexport function addSessionMetadataToNextSession(newSession: FaroUserSession, previousSession: FaroUserSession | null) {\n const sessionWithMeta: Required<FaroUserSession> = {\n ...newSession,\n sessionMeta: {\n id: newSession.sessionId,\n attributes: {\n ...faro.config.sessionTracking?.session?.attributes,\n ...(faro.metas.value.session?.attributes ?? {}),\n ...(previousSession != null ? { previousSession: previousSession.sessionId } : {}),\n isSampled: newSession.isSampled.toString(),\n },\n },\n };\n\n return sessionWithMeta;\n}\n"]}
|
|
@@ -30,6 +30,7 @@ export function calculateFaroResourceTiming(resourceEntryRaw) {
|
|
|
30
30
|
tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),
|
|
31
31
|
dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),
|
|
32
32
|
tlsNegotiationTime: toFaroPerformanceTimingString(requestStart - secureConnectionStart),
|
|
33
|
+
responseStatus: toFaroPerformanceTimingString(responseStatus),
|
|
33
34
|
redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),
|
|
34
35
|
requestTime: toFaroPerformanceTimingString(responseStart - requestStart),
|
|
35
36
|
responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function entryUrlIsIgnored(ignoredUrls: Array<string | RegExp> = [], entryName: string): boolean {\n return ignoredUrls.some((url) => entryName.match(url) != null);\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\nexport function calculateFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(requestStart - secureConnectionStart),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function calculateFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n return {\n visibilityState: document.visibilityState,\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n\n type: type,\n\n ...calculateFaroResourceTiming(navigationEntryRaw),\n };\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return 'unknown';\n }\n\n if (typeof v === 'number') {\n return Math.round(v).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function entryUrlIsIgnored(ignoredUrls: Array<string | RegExp> = [], entryName: string): boolean {\n return ignoredUrls.some((url) => entryName.match(url) != null);\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\nexport function calculateFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(requestStart - secureConnectionStart),\n responseStatus: toFaroPerformanceTimingString(responseStatus),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function calculateFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n return {\n visibilityState: document.visibilityState,\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n\n type: type,\n\n ...calculateFaroResourceTiming(navigationEntryRaw),\n };\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return 'unknown';\n }\n\n if (typeof v === 'number') {\n return Math.round(v).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
@@ -17,6 +17,7 @@ export const performanceNavigationEntry = {
|
|
|
17
17
|
secureConnectionStart: 400,
|
|
18
18
|
requestStart: 433,
|
|
19
19
|
responseStart: 542,
|
|
20
|
+
responseStatus: 200,
|
|
20
21
|
responseEnd: 542,
|
|
21
22
|
transferSize: 127601,
|
|
22
23
|
encodedBodySize: 126111,
|
|
@@ -51,6 +52,7 @@ export const performanceResourceEntry = {
|
|
|
51
52
|
secureConnectionStart: 778,
|
|
52
53
|
requestStart: 789,
|
|
53
54
|
responseStart: 1148,
|
|
55
|
+
responseStatus: '200',
|
|
54
56
|
responseEnd: 1148,
|
|
55
57
|
transferSize: 11459,
|
|
56
58
|
encodedBodySize: 10526,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceUtilsTestData.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtilsTestData.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,oBAAoB;IAC1B,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,CAAC;IACnB,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE,IAAI;IACpB,0BAA0B,EAAE,IAAI;IAChC,wBAAwB,EAAE,IAAI;IAC9B,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,UAAU;IAChB,aAAa,EAAE,CAAC;CACyB,CAAC;AAE5C,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,kCAAkC;IACxC,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;IACb,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,IAAI;IACnB,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,KAAK;IACtB,eAAe,EAAE,KAAK;IACtB,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,KAAK;YACX,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,KAAK;SACnB;KACF;CACsC,CAAC","sourcesContent":["// the values of this timings are contrived for testing.They do not necessarily reflect reality.\nexport const performanceNavigationEntry = {\n name: 'http://example.com',\n entryType: 'navigation',\n startTime: 0,\n duration: 2700,\n initiatorType: 'navigation',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 1,\n redirectEnd: 2,\n fetchStart: 237,\n domainLookupStart: 241,\n domainLookupEnd: 380,\n connectStart: 380,\n connectEnd: 433,\n secureConnectionStart: 400,\n requestStart: 433,\n responseStart: 542,\n responseEnd: 542,\n transferSize: 127601,\n encodedBodySize: 126111,\n decodedBodySize: 530675,\n serverTiming: [],\n unloadEventStart: 0,\n unloadEventEnd: 0,\n domInteractive: 1247,\n domContentLoadedEventStart: 1247,\n domContentLoadedEventEnd: 1250,\n domComplete: 2678,\n loadEventStart: 2678,\n loadEventEnd: 2700,\n type: 'navigate',\n redirectCount: 0,\n} as unknown as PerformanceNavigationTiming;\n\nexport const performanceResourceEntry = {\n name: 'http://example.com/awesome-image',\n entryType: 'resource',\n startTime: 778,\n duration: 370,\n initiatorType: 'img',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 0,\n redirectEnd: 0,\n fetchStart: 778,\n domainLookupStart: 778,\n domainLookupEnd: 778,\n connectStart: 778,\n connectEnd: 778,\n secureConnectionStart: 778,\n requestStart: 789,\n responseStart: 1148,\n responseEnd: 1148,\n transferSize: 11459,\n encodedBodySize: 10526,\n decodedBodySize: 10526,\n serverTiming: [\n {\n name: 'foo',\n duration: 0,\n description: 'bar',\n },\n ],\n} as unknown as PerformanceResourceTiming;\n"]}
|
|
1
|
+
{"version":3,"file":"performanceUtilsTestData.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtilsTestData.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,oBAAoB;IAC1B,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,cAAc,EAAE,GAAG;IACnB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,CAAC;IACnB,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE,IAAI;IACpB,0BAA0B,EAAE,IAAI;IAChC,wBAAwB,EAAE,IAAI;IAC9B,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,UAAU;IAChB,aAAa,EAAE,CAAC;CACyB,CAAC;AAE5C,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,kCAAkC;IACxC,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;IACb,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,KAAK;IACrB,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,KAAK;IACtB,eAAe,EAAE,KAAK;IACtB,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,KAAK;YACX,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,KAAK;SACnB;KACF;CACsC,CAAC","sourcesContent":["// the values of this timings are contrived for testing.They do not necessarily reflect reality.\nexport const performanceNavigationEntry = {\n name: 'http://example.com',\n entryType: 'navigation',\n startTime: 0,\n duration: 2700,\n initiatorType: 'navigation',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 1,\n redirectEnd: 2,\n fetchStart: 237,\n domainLookupStart: 241,\n domainLookupEnd: 380,\n connectStart: 380,\n connectEnd: 433,\n secureConnectionStart: 400,\n requestStart: 433,\n responseStart: 542,\n responseStatus: 200,\n responseEnd: 542,\n transferSize: 127601,\n encodedBodySize: 126111,\n decodedBodySize: 530675,\n serverTiming: [],\n unloadEventStart: 0,\n unloadEventEnd: 0,\n domInteractive: 1247,\n domContentLoadedEventStart: 1247,\n domContentLoadedEventEnd: 1250,\n domComplete: 2678,\n loadEventStart: 2678,\n loadEventEnd: 2700,\n type: 'navigate',\n redirectCount: 0,\n} as unknown as PerformanceNavigationTiming;\n\nexport const performanceResourceEntry = {\n name: 'http://example.com/awesome-image',\n entryType: 'resource',\n startTime: 778,\n duration: 370,\n initiatorType: 'img',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 0,\n redirectEnd: 0,\n fetchStart: 778,\n domainLookupStart: 778,\n domainLookupEnd: 778,\n connectStart: 778,\n connectEnd: 778,\n secureConnectionStart: 778,\n requestStart: 789,\n responseStart: 1148,\n responseStatus: '200',\n responseEnd: 1148,\n transferSize: 11459,\n encodedBodySize: 10526,\n decodedBodySize: 10526,\n serverTiming: [\n {\n name: 'foo',\n duration: 0,\n description: 'bar',\n },\n ],\n} as unknown as PerformanceResourceTiming;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FaroNavigationTiming = Readonly<\n {\n duration: string;\n visibilityState: DocumentVisibilityState;\n domProcessingTime: string;\n pageLoadTime: string;\n domContentLoadHandlerTime: string;\n onLoadTime: string;\n ttfb: string;\n type: NavigationTimingType;\n } & FaroResourceTiming\n>;\n\nexport type FaroResourceTiming = Readonly<{\n name: string;\n duration: string;\n protocol: string;\n tcpHandshakeTime: string;\n dnsLookupTime: string;\n tlsNegotiationTime: string;\n redirectTime: string;\n requestTime: string;\n fetchTime: string;\n responseTime: string;\n serviceWorkerTime: string;\n decodedBodySize: string;\n encodedBodySize: string;\n cacheHitStatus: 'cache' | 'conditionalFetch' | 'fullLoad';\n renderBlockingStatus: 'blocking' | 'non-blocking' | 'unknown';\n initiatorType: string;\n // serverTiming: PerformanceServerTiming[];\n}>;\n\nexport type FaroNavigationItem = {\n faroNavigationId: string;\n faroPreviousNavigationId: string;\n} & FaroNavigationTiming &\n FaroResourceTiming;\n\nexport type FaroResourceItem = {\n faroNavigationId: string;\n faroResourceId: string;\n} & FaroResourceTiming;\n\nexport type CacheType = 'cache' | 'conditionalFetch' | 'fullLoad';\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FaroNavigationTiming = Readonly<\n {\n duration: string;\n visibilityState: DocumentVisibilityState;\n domProcessingTime: string;\n pageLoadTime: string;\n domContentLoadHandlerTime: string;\n onLoadTime: string;\n ttfb: string;\n type: NavigationTimingType;\n } & FaroResourceTiming\n>;\n\nexport type FaroResourceTiming = Readonly<{\n name: string;\n duration: string;\n protocol: string;\n tcpHandshakeTime: string;\n dnsLookupTime: string;\n tlsNegotiationTime: string;\n responseStatus: string;\n redirectTime: string;\n requestTime: string;\n fetchTime: string;\n responseTime: string;\n serviceWorkerTime: string;\n decodedBodySize: string;\n encodedBodySize: string;\n cacheHitStatus: 'cache' | 'conditionalFetch' | 'fullLoad';\n renderBlockingStatus: 'blocking' | 'non-blocking' | 'unknown';\n initiatorType: string;\n // serverTiming: PerformanceServerTiming[];\n}>;\n\nexport type FaroNavigationItem = {\n faroNavigationId: string;\n faroPreviousNavigationId: string;\n} & FaroNavigationTiming &\n FaroResourceTiming;\n\nexport type FaroResourceItem = {\n faroNavigationId: string;\n faroResourceId: string;\n} & FaroResourceTiming;\n\nexport type CacheType = 'cache' | 'conditionalFetch' | 'fullLoad';\n"]}
|
|
@@ -25,10 +25,9 @@ export class SessionInstrumentation extends BaseInstrumentation {
|
|
|
25
25
|
this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
var _a, _b, _c;
|
|
30
|
-
|
|
31
|
-
let userSession = sessionManager.fetchUserSession();
|
|
28
|
+
createInitialSession(SessionManager, sessionsConfig) {
|
|
29
|
+
var _a, _b, _c, _d, _e;
|
|
30
|
+
let userSession = SessionManager.fetchUserSession();
|
|
32
31
|
if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {
|
|
33
32
|
const now = dateNow();
|
|
34
33
|
const shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;
|
|
@@ -37,23 +36,36 @@ export class SessionInstrumentation extends BaseInstrumentation {
|
|
|
37
36
|
userSession = null;
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
|
-
let sessionId = (_a = sessionsConfig.session) === null || _a === void 0 ? void 0 : _a.id;
|
|
41
|
-
let sessionAttributes = (_b = sessionsConfig.session) === null || _b === void 0 ? void 0 : _b.attributes;
|
|
42
39
|
let lifecycleType;
|
|
40
|
+
let initialSession;
|
|
43
41
|
if (isUserSessionValid(userSession)) {
|
|
44
|
-
sessionId = userSession === null || userSession === void 0 ? void 0 : userSession.sessionId;
|
|
45
|
-
|
|
42
|
+
const sessionId = userSession === null || userSession === void 0 ? void 0 : userSession.sessionId;
|
|
43
|
+
initialSession = createUserSessionObject({
|
|
44
|
+
sessionId,
|
|
45
|
+
isSampled: userSession.isSampled || false,
|
|
46
|
+
started: userSession === null || userSession === void 0 ? void 0 : userSession.started,
|
|
47
|
+
});
|
|
48
|
+
initialSession.sessionMeta = {
|
|
49
|
+
id: sessionId,
|
|
50
|
+
attributes: Object.assign(Object.assign(Object.assign({}, (_a = sessionsConfig.session) === null || _a === void 0 ? void 0 : _a.attributes), (_b = userSession === null || userSession === void 0 ? void 0 : userSession.sessionMeta) === null || _b === void 0 ? void 0 : _b.attributes), {
|
|
51
|
+
// For valid resumed sessions we do not want to recalculate the sampling decision on each init phase.
|
|
52
|
+
isSampled: initialSession.isSampled.toString() }),
|
|
53
|
+
};
|
|
46
54
|
lifecycleType = EVENT_SESSION_RESUME;
|
|
47
55
|
}
|
|
48
56
|
else {
|
|
49
|
-
sessionId =
|
|
57
|
+
const sessionId = (_d = (_c = sessionsConfig.session) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : createSession().id;
|
|
58
|
+
initialSession = createUserSessionObject({
|
|
59
|
+
sessionId,
|
|
60
|
+
isSampled: isSampled(),
|
|
61
|
+
});
|
|
62
|
+
initialSession.sessionMeta = {
|
|
63
|
+
id: sessionId,
|
|
64
|
+
attributes: Object.assign({ isSampled: initialSession.isSampled.toString() }, (_e = sessionsConfig.session) === null || _e === void 0 ? void 0 : _e.attributes),
|
|
65
|
+
};
|
|
50
66
|
lifecycleType = EVENT_SESSION_START;
|
|
51
67
|
}
|
|
52
|
-
|
|
53
|
-
id: sessionId,
|
|
54
|
-
attributes: Object.assign({ isSampled: isSampled().toString() }, sessionAttributes),
|
|
55
|
-
};
|
|
56
|
-
return { sessionMeta, lifecycleType };
|
|
68
|
+
return { initialSession, lifecycleType };
|
|
57
69
|
}
|
|
58
70
|
registerBeforeSendHook(SessionManager) {
|
|
59
71
|
var _a;
|
|
@@ -83,19 +95,14 @@ export class SessionInstrumentation extends BaseInstrumentation {
|
|
|
83
95
|
});
|
|
84
96
|
}
|
|
85
97
|
initialize() {
|
|
86
|
-
var _a, _b;
|
|
87
98
|
this.logDebug('init session instrumentation');
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
const SessionManager = (
|
|
91
|
-
? PersistentSessionsManager
|
|
92
|
-
: VolatileSessionsManager;
|
|
99
|
+
const sessionTrackingConfig = this.config.sessionTracking;
|
|
100
|
+
if (sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.enabled) {
|
|
101
|
+
const SessionManager = (sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.persistent) ? PersistentSessionsManager : VolatileSessionsManager;
|
|
93
102
|
this.registerBeforeSendHook(SessionManager);
|
|
94
|
-
const {
|
|
95
|
-
SessionManager.storeUserSession(
|
|
96
|
-
|
|
97
|
-
isSampled: ((_b = initialSessionMeta.attributes) === null || _b === void 0 ? void 0 : _b['isSampled']) === 'true',
|
|
98
|
-
})), { sessionMeta: initialSessionMeta }));
|
|
103
|
+
const { initialSession, lifecycleType } = this.createInitialSession(SessionManager, sessionTrackingConfig);
|
|
104
|
+
SessionManager.storeUserSession(initialSession);
|
|
105
|
+
const initialSessionMeta = initialSession.sessionMeta;
|
|
99
106
|
this.notifiedSession = initialSessionMeta;
|
|
100
107
|
this.api.setSession(initialSessionMeta);
|
|
101
108
|
if (lifecycleType === EVENT_SESSION_START) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/session/instrumentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,OAAO,EACP,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EAGnB,OAAO,GACR,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAwB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAIlF,MAAM,OAAO,sBAAuB,SAAQ,mBAAmB;IAA/D;;QACW,SAAI,GAAG,+CAA+C,CAAC;QACvD,YAAO,GAAG,OAAO,CAAC;IA8I7B,CAAC;IAxIS,qBAAqB,CAAC,IAAU;;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAE7B,IAAI,OAAO,IAAI,OAAO,CAAC,EAAE,MAAK,MAAA,IAAI,CAAC,eAAe,0CAAE,EAAE,CAAA,EAAE;YACtD,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,EAAE,MAAK,MAAA,OAAO,CAAC,UAAU,0CAAG,iBAAiB,CAAC,CAAA,EAAE;gBAC/F,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9E,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;gBAC/B,OAAO;aACR;YAED,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;YAC/B,8EAA8E;YAC9E,gBAAgB;YAChB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;SAC9E;IACH,CAAC;IAEO,wBAAwB,CAAC,cAAmD;;QAIlF,MAAM,cAAc,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAEvG,IAAI,WAAW,GAA2B,cAAc,CAAC,gBAAgB,EAAE,CAAC;QAE5E,IAAI,cAAc,CAAC,UAAU,IAAI,cAAc,CAAC,yBAAyB,IAAI,WAAW,EAAE;YACxF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;YACtB,MAAM,4BAA4B,GAAG,WAAW,CAAC,YAAY,GAAG,GAAG,GAAG,cAAc,CAAC,yBAAyB,CAAC;YAE/G,IAAI,4BAA4B,EAAE;gBAChC,yBAAyB,CAAC,iBAAiB,EAAE,CAAC;gBAC9C,WAAW,GAAG,IAAI,CAAC;aACpB;SACF;QAED,IAAI,SAAS,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,EAAE,CAAC;QAC3C,IAAI,iBAAiB,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,UAAU,CAAC;QAE3D,IAAI,aAA4B,CAAC;QAEjC,IAAI,kBAAkB,CAAC,WAAW,CAAC,EAAE;YACnC,SAAS,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,SAAS,CAAC;YACnC,iBAAiB,iDACZ,iBAAiB,GACjB,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,WAAW,0CAAE,UAAU,KACvC,SAAS,EAAE,CAAC,WAAY,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,GACxD,CAAC;YAEF,aAAa,GAAG,oBAAoB,CAAC;SACtC;aAAM;YACL,SAAS,GAAG,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,aAAa,EAAE,CAAC,EAAE,CAAC;YAC5C,aAAa,GAAG,mBAAmB,CAAC;SACrC;QAED,MAAM,WAAW,GAAgB;YAC/B,EAAE,EAAE,SAAS;YACb,UAAU,kBACR,SAAS,EAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,IAG9B,iBAAiB,CACrB;SACF,CAAC;QAEF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;IACxC,CAAC;IAEO,sBAAsB,CAAC,cAAiF;;QAC9G,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;QAE/C,MAAA,IAAI,CAAC,UAAU,0CAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE,EAAE;;YAC3C,aAAa,EAAE,CAAC;YAEhB,MAAM,UAAU,GAAG,MAAA,IAAI,CAAC,IAAI,CAAC,OAAO,0CAAE,UAAU,CAAC;YAEjD,IAAI,UAAU,IAAI,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,WAAW,CAAC,MAAK,MAAM,EAAE;gBACtD,IAAI,OAAsB,CAAC;gBAE3B,sDAAsD;gBACtD,0CAA0C;gBAC1C,IAAI,iBAAiB,IAAI,MAAM,EAAE;oBAC/B,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;iBACjC;qBAAM;oBACL,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;iBAC5C;gBAED,MAAM,aAAa,GAAG,MAAA,OAAO,CAAC,IAAI,CAAC,OAAO,0CAAE,UAAU,CAAC;gBAChD,aAAa,aAAb,aAAa,4BAAb,aAAa,CAAG,WAAW,CAAC,CAAC;gBAEpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC1C,MAAA,OAAO,CAAC,IAAI,CAAC,OAAO,+CAAE,UAAU,CAAC;iBACzC;gBAED,OAAO,OAAO,CAAC;aAChB;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,UAAU;;QACR,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;QAE9C,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QAEpD,IAAI,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,OAAO,EAAE;YAC5B,MAAM,cAAc,GAAG,CAAA,MAAA,IAAI,CAAC,MAAM,CAAC,eAAe,0CAAE,UAAU;gBAC5D,CAAC,CAAC,yBAAyB;gBAC3B,CAAC,CAAC,uBAAuB,CAAC;YAE5B,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;YAE5C,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;YAE1G,cAAc,CAAC,gBAAgB,iCAC1B,uBAAuB,CAAC;gBACzB,SAAS,EAAE,kBAAkB,CAAC,EAAE;gBAChC,SAAS,EAAE,CAAA,MAAA,kBAAkB,CAAC,UAAU,0CAAG,WAAW,CAAC,MAAK,MAAM;aACnE,CAAC,KACF,WAAW,EAAE,kBAAkB,IAC/B,CAAC;YAEH,IAAI,CAAC,eAAe,GAAG,kBAAkB,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;YAExC,IAAI,aAAa,KAAK,mBAAmB,EAAE;gBACzC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;aAC9E;YAED,IAAI,aAAa,KAAK,oBAAoB,EAAE;gBAC1C,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;aAC/E;SACF;QAED,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;CACF","sourcesContent":["import {\n BaseInstrumentation,\n dateNow,\n EVENT_SESSION_EXTEND,\n EVENT_SESSION_RESUME,\n EVENT_SESSION_START,\n Meta,\n MetaSession,\n VERSION,\n} from '@grafana/faro-core';\nimport type { Config } from '@grafana/faro-core';\n\nimport type { TransportItem } from '../..';\nimport { createSession } from '../../metas';\n\nimport { type FaroUserSession, isSampled } from './sessionManager';\nimport { PersistentSessionsManager } from './sessionManager/PersistentSessionsManager';\nimport { createUserSessionObject, isUserSessionValid } from './sessionManager/sessionManagerUtils';\nimport { VolatileSessionsManager } from './sessionManager/VolatileSessionManager';\n\ntype LifecycleType = typeof EVENT_SESSION_RESUME | typeof EVENT_SESSION_START;\n\nexport class SessionInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-session';\n readonly version = VERSION;\n\n // previously notified session, to ensure we don't send session start\n // event twice for the same session\n private notifiedSession: MetaSession | undefined;\n\n private sendSessionStartEvent(meta: Meta): void {\n const session = meta.session;\n\n if (session && session.id !== this.notifiedSession?.id) {\n if (this.notifiedSession && this.notifiedSession.id === session.attributes?.['previousSession']) {\n this.api.pushEvent(EVENT_SESSION_EXTEND, {}, undefined, { skipDedupe: true });\n this.notifiedSession = session;\n return;\n }\n\n this.notifiedSession = session;\n // no need to add attributes and session id, they are included as part of meta\n // automatically\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n }\n\n private createInitialSessionMeta(sessionsConfig: Required<Config>['sessionTracking']): {\n sessionMeta: MetaSession;\n lifecycleType: LifecycleType;\n } {\n const sessionManager = sessionsConfig.persistent ? PersistentSessionsManager : VolatileSessionsManager;\n\n let userSession: FaroUserSession | null = sessionManager.fetchUserSession();\n\n if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {\n const now = dateNow();\n const shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;\n\n if (shouldClearPersistentSession) {\n PersistentSessionsManager.removeUserSession();\n userSession = null;\n }\n }\n\n let sessionId = sessionsConfig.session?.id;\n let sessionAttributes = sessionsConfig.session?.attributes;\n\n let lifecycleType: LifecycleType;\n\n if (isUserSessionValid(userSession)) {\n sessionId = userSession?.sessionId;\n sessionAttributes = {\n ...sessionAttributes,\n ...userSession?.sessionMeta?.attributes,\n isSampled: (userSession!.isSampled || false).toString(),\n };\n\n lifecycleType = EVENT_SESSION_RESUME;\n } else {\n sessionId = sessionId ?? createSession().id;\n lifecycleType = EVENT_SESSION_START;\n }\n\n const sessionMeta: MetaSession = {\n id: sessionId,\n attributes: {\n isSampled: isSampled().toString(),\n // We do not want to recalculate the sampling decision on each init phase.\n // If session from web-storage has a isSampled attribute we will use that instead.\n ...sessionAttributes,\n },\n };\n\n return { sessionMeta, lifecycleType };\n }\n\n private registerBeforeSendHook(SessionManager: typeof VolatileSessionsManager | typeof PersistentSessionsManager) {\n const { updateSession } = new SessionManager();\n\n this.transports?.addBeforeSendHooks((item) => {\n updateSession();\n\n const attributes = item.meta.session?.attributes;\n\n if (attributes && attributes?.['isSampled'] === 'true') {\n let newItem: TransportItem;\n\n // Structured clone is supported in all major browsers\n // but for old browsers we need a fallback\n if ('structuredClone' in window) {\n newItem = structuredClone(item);\n } else {\n newItem = JSON.parse(JSON.stringify(item));\n }\n\n const newAttributes = newItem.meta.session?.attributes;\n delete newAttributes?.['isSampled'];\n\n if (Object.keys(newAttributes ?? {}).length === 0) {\n delete newItem.meta.session?.attributes;\n }\n\n return newItem;\n }\n\n return null;\n });\n }\n\n initialize() {\n this.logDebug('init session instrumentation');\n\n const sessionTracking = this.config.sessionTracking;\n\n if (sessionTracking?.enabled) {\n const SessionManager = this.config.sessionTracking?.persistent\n ? PersistentSessionsManager\n : VolatileSessionsManager;\n\n this.registerBeforeSendHook(SessionManager);\n\n const { sessionMeta: initialSessionMeta, lifecycleType } = this.createInitialSessionMeta(sessionTracking);\n\n SessionManager.storeUserSession({\n ...createUserSessionObject({\n sessionId: initialSessionMeta.id,\n isSampled: initialSessionMeta.attributes?.['isSampled'] === 'true',\n }),\n sessionMeta: initialSessionMeta,\n });\n\n this.notifiedSession = initialSessionMeta;\n this.api.setSession(initialSessionMeta);\n\n if (lifecycleType === EVENT_SESSION_START) {\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n\n if (lifecycleType === EVENT_SESSION_RESUME) {\n this.api.pushEvent(EVENT_SESSION_RESUME, {}, undefined, { skipDedupe: true });\n }\n }\n\n this.metas.addListener(this.sendSessionStartEvent.bind(this));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/session/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseInstrumentation,\n dateNow,\n EVENT_SESSION_EXTEND,\n EVENT_SESSION_RESUME,\n EVENT_SESSION_START,\n Meta,\n MetaSession,\n VERSION,\n} from '@grafana/faro-core';\nimport type { Config } from '@grafana/faro-core';\n\nimport type { TransportItem } from '../..';\nimport { createSession } from '../../metas';\n\nimport { type FaroUserSession, isSampled } from './sessionManager';\nimport { PersistentSessionsManager } from './sessionManager/PersistentSessionsManager';\nimport { createUserSessionObject, isUserSessionValid } from './sessionManager/sessionManagerUtils';\nimport { VolatileSessionsManager } from './sessionManager/VolatileSessionManager';\n\ntype LifecycleType = typeof EVENT_SESSION_RESUME | typeof EVENT_SESSION_START;\ntype SessionManager = typeof VolatileSessionsManager | typeof PersistentSessionsManager;\n\nexport class SessionInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-web-sdk:instrumentation-session';\n readonly version = VERSION;\n\n // previously notified session, to ensure we don't send session start\n // event twice for the same session\n private notifiedSession: MetaSession | undefined;\n\n private sendSessionStartEvent(meta: Meta): void {\n const session = meta.session;\n\n if (session && session.id !== this.notifiedSession?.id) {\n if (this.notifiedSession && this.notifiedSession.id === session.attributes?.['previousSession']) {\n this.api.pushEvent(EVENT_SESSION_EXTEND, {}, undefined, { skipDedupe: true });\n this.notifiedSession = session;\n return;\n }\n\n this.notifiedSession = session;\n // no need to add attributes and session id, they are included as part of meta\n // automatically\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n }\n\n private createInitialSession(\n SessionManager: SessionManager,\n sessionsConfig: Required<Config>['sessionTracking']\n ): {\n initialSession: FaroUserSession;\n lifecycleType: LifecycleType;\n } {\n let userSession: FaroUserSession | null = SessionManager.fetchUserSession();\n\n if (sessionsConfig.persistent && sessionsConfig.maxSessionPersistenceTime && userSession) {\n const now = dateNow();\n const shouldClearPersistentSession = userSession.lastActivity < now - sessionsConfig.maxSessionPersistenceTime;\n\n if (shouldClearPersistentSession) {\n PersistentSessionsManager.removeUserSession();\n userSession = null;\n }\n }\n\n let lifecycleType: LifecycleType;\n let initialSession: FaroUserSession;\n\n if (isUserSessionValid(userSession)) {\n const sessionId = userSession?.sessionId;\n\n initialSession = createUserSessionObject({\n sessionId,\n isSampled: userSession!.isSampled || false,\n started: userSession?.started,\n });\n\n initialSession.sessionMeta = {\n id: sessionId,\n attributes: {\n ...sessionsConfig.session?.attributes,\n ...userSession?.sessionMeta?.attributes,\n // For valid resumed sessions we do not want to recalculate the sampling decision on each init phase.\n isSampled: initialSession.isSampled.toString(),\n },\n };\n\n lifecycleType = EVENT_SESSION_RESUME;\n } else {\n const sessionId = sessionsConfig.session?.id ?? createSession().id;\n\n initialSession = createUserSessionObject({\n sessionId,\n isSampled: isSampled(),\n });\n\n initialSession.sessionMeta = {\n id: sessionId,\n attributes: {\n isSampled: initialSession.isSampled.toString(),\n ...sessionsConfig.session?.attributes,\n },\n };\n\n lifecycleType = EVENT_SESSION_START;\n }\n\n return { initialSession, lifecycleType };\n }\n\n private registerBeforeSendHook(SessionManager: SessionManager) {\n const { updateSession } = new SessionManager();\n\n this.transports?.addBeforeSendHooks((item) => {\n updateSession();\n\n const attributes = item.meta.session?.attributes;\n\n if (attributes && attributes?.['isSampled'] === 'true') {\n let newItem: TransportItem;\n\n // Structured clone is supported in all major browsers\n // but for old browsers we need a fallback\n if ('structuredClone' in window) {\n newItem = structuredClone(item);\n } else {\n newItem = JSON.parse(JSON.stringify(item));\n }\n\n const newAttributes = newItem.meta.session?.attributes;\n delete newAttributes?.['isSampled'];\n\n if (Object.keys(newAttributes ?? {}).length === 0) {\n delete newItem.meta.session?.attributes;\n }\n\n return newItem;\n }\n\n return null;\n });\n }\n\n initialize() {\n this.logDebug('init session instrumentation');\n\n const sessionTrackingConfig = this.config.sessionTracking;\n\n if (sessionTrackingConfig?.enabled) {\n const SessionManager = sessionTrackingConfig?.persistent ? PersistentSessionsManager : VolatileSessionsManager;\n\n this.registerBeforeSendHook(SessionManager);\n\n const { initialSession, lifecycleType } = this.createInitialSession(SessionManager, sessionTrackingConfig);\n\n SessionManager.storeUserSession(initialSession);\n\n const initialSessionMeta = initialSession.sessionMeta;\n\n this.notifiedSession = initialSessionMeta;\n this.api.setSession(initialSessionMeta);\n\n if (lifecycleType === EVENT_SESSION_START) {\n this.api.pushEvent(EVENT_SESSION_START, {}, undefined, { skipDedupe: true });\n }\n\n if (lifecycleType === EVENT_SESSION_RESUME) {\n this.api.pushEvent(EVENT_SESSION_RESUME, {}, undefined, { skipDedupe: true });\n }\n }\n\n this.metas.addListener(this.sendSessionStartEvent.bind(this));\n }\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { dateNow, faro, genShortID } from '@grafana/faro-core';
|
|
2
|
+
import { isLocalStorageAvailable, isSessionStorageAvailable } from '../../../utils';
|
|
2
3
|
import { isSampled } from './sampling';
|
|
3
4
|
import { SESSION_EXPIRATION_TIME, SESSION_INACTIVITY_TIME } from './sessionConstants';
|
|
4
|
-
export function createUserSessionObject({ sessionId, isSampled = true, } = {}) {
|
|
5
|
+
export function createUserSessionObject({ sessionId, started, lastActivity, isSampled = true, } = {}) {
|
|
5
6
|
var _a, _b;
|
|
6
7
|
const now = dateNow();
|
|
7
8
|
const generateSessionId = (_b = (_a = faro.config) === null || _a === void 0 ? void 0 : _a.sessionTracking) === null || _b === void 0 ? void 0 : _b.generateSessionId;
|
|
@@ -10,8 +11,8 @@ export function createUserSessionObject({ sessionId, isSampled = true, } = {}) {
|
|
|
10
11
|
}
|
|
11
12
|
return {
|
|
12
13
|
sessionId,
|
|
13
|
-
lastActivity: now,
|
|
14
|
-
started: now,
|
|
14
|
+
lastActivity: lastActivity !== null && lastActivity !== void 0 ? lastActivity : now,
|
|
15
|
+
started: started !== null && started !== void 0 ? started : now,
|
|
15
16
|
isSampled: isSampled,
|
|
16
17
|
};
|
|
17
18
|
}
|
|
@@ -29,10 +30,15 @@ export function isUserSessionValid(session) {
|
|
|
29
30
|
}
|
|
30
31
|
export function getUserSessionUpdater({ fetchUserSession, storeUserSession }) {
|
|
31
32
|
return function updateSession() {
|
|
32
|
-
var _a, _b, _c
|
|
33
|
+
var _a, _b, _c;
|
|
33
34
|
if (!fetchUserSession || !storeUserSession) {
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
37
|
+
const sessionTrackingConfig = faro.config.sessionTracking;
|
|
38
|
+
const isPersistentSessions = sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.persistent;
|
|
39
|
+
if ((isPersistentSessions && !isLocalStorageAvailable) || (!isPersistentSessions && !isSessionStorageAvailable)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
36
42
|
const sessionFromStorage = fetchUserSession();
|
|
37
43
|
if (isUserSessionValid(sessionFromStorage)) {
|
|
38
44
|
storeUserSession(Object.assign(Object.assign({}, sessionFromStorage), { lastActivity: dateNow() }));
|
|
@@ -41,7 +47,7 @@ export function getUserSessionUpdater({ fetchUserSession, storeUserSession }) {
|
|
|
41
47
|
let newSession = addSessionMetadataToNextSession(createUserSessionObject({ isSampled: isSampled() }), sessionFromStorage);
|
|
42
48
|
storeUserSession(newSession);
|
|
43
49
|
(_a = faro.api) === null || _a === void 0 ? void 0 : _a.setSession(newSession.sessionMeta);
|
|
44
|
-
(
|
|
50
|
+
(_b = sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.onSessionChange) === null || _b === void 0 ? void 0 : _b.call(sessionTrackingConfig, (_c = sessionFromStorage === null || sessionFromStorage === void 0 ? void 0 : sessionFromStorage.sessionMeta) !== null && _c !== void 0 ? _c : null, newSession.sessionMeta);
|
|
45
51
|
}
|
|
46
52
|
};
|
|
47
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionManagerUtils.js","sourceRoot":"","sources":["../../../../../src/instrumentations/session/sessionManager/sessionManagerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionManagerUtils.js","sourceRoot":"","sources":["../../../../../src/instrumentations/session/sessionManager/sessionManagerUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { dateNow, faro, genShortID } from '@grafana/faro-core';\n\nimport { isLocalStorageAvailable, isSessionStorageAvailable } from '../../../utils';\n\nimport { isSampled } from './sampling';\nimport { SESSION_EXPIRATION_TIME, SESSION_INACTIVITY_TIME } from './sessionConstants';\nimport type { FaroUserSession } from './types';\n\ntype CreateUserSessionObjectParams = {\n sessionId?: string;\n started?: number;\n lastActivity?: number;\n isSampled?: boolean;\n};\n\nexport function createUserSessionObject({\n sessionId,\n started,\n lastActivity,\n isSampled = true,\n}: CreateUserSessionObjectParams = {}): FaroUserSession {\n const now = dateNow();\n\n const generateSessionId = faro.config?.sessionTracking?.generateSessionId;\n\n if (sessionId == null) {\n sessionId = typeof generateSessionId === 'function' ? generateSessionId() : genShortID();\n }\n\n return {\n sessionId,\n lastActivity: lastActivity ?? now,\n started: started ?? now,\n isSampled: isSampled,\n };\n}\n\nexport function isUserSessionValid(session: FaroUserSession | null): boolean {\n if (session == null) {\n return false;\n }\n\n const now = dateNow();\n const lifetimeValid = now - session.started < SESSION_EXPIRATION_TIME;\n\n if (!lifetimeValid) {\n return false;\n }\n\n const inactivityPeriodValid = now - session.lastActivity < SESSION_INACTIVITY_TIME;\n return inactivityPeriodValid;\n}\n\ntype GetUserSessionUpdaterParams = {\n storeUserSession: (session: FaroUserSession) => void;\n fetchUserSession: () => FaroUserSession | null;\n};\n\nexport function getUserSessionUpdater({ fetchUserSession, storeUserSession }: GetUserSessionUpdaterParams): () => void {\n return function updateSession(): void {\n if (!fetchUserSession || !storeUserSession) {\n return;\n }\n\n const sessionTrackingConfig = faro.config.sessionTracking;\n const isPersistentSessions = sessionTrackingConfig?.persistent;\n\n if ((isPersistentSessions && !isLocalStorageAvailable) || (!isPersistentSessions && !isSessionStorageAvailable)) {\n return;\n }\n\n const sessionFromStorage = fetchUserSession();\n\n if (isUserSessionValid(sessionFromStorage)) {\n storeUserSession({ ...sessionFromStorage!, lastActivity: dateNow() });\n } else {\n let newSession = addSessionMetadataToNextSession(\n createUserSessionObject({ isSampled: isSampled() }),\n sessionFromStorage\n );\n\n storeUserSession(newSession);\n\n faro.api?.setSession(newSession.sessionMeta);\n sessionTrackingConfig?.onSessionChange?.(sessionFromStorage?.sessionMeta ?? null, newSession.sessionMeta!);\n }\n };\n}\n\nexport function addSessionMetadataToNextSession(newSession: FaroUserSession, previousSession: FaroUserSession | null) {\n const sessionWithMeta: Required<FaroUserSession> = {\n ...newSession,\n sessionMeta: {\n id: newSession.sessionId,\n attributes: {\n ...faro.config.sessionTracking?.session?.attributes,\n ...(faro.metas.value.session?.attributes ?? {}),\n ...(previousSession != null ? { previousSession: previousSession.sessionId } : {}),\n isSampled: newSession.isSampled.toString(),\n },\n },\n };\n\n return sessionWithMeta;\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type { ConsoleInstrumentationOptions } from './types';
|
|
|
3
3
|
export declare class ConsoleInstrumentation extends BaseInstrumentation {
|
|
4
4
|
private options;
|
|
5
5
|
readonly name = "@grafana/faro-web-sdk:instrumentation-console";
|
|
6
|
-
readonly version = "1.
|
|
6
|
+
readonly version = "1.5.0";
|
|
7
7
|
static defaultDisabledLevels: LogLevel[];
|
|
8
8
|
constructor(options?: ConsoleInstrumentationOptions);
|
|
9
9
|
initialize(): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseInstrumentation } from '@grafana/faro-core';
|
|
2
2
|
export declare class ErrorsInstrumentation extends BaseInstrumentation {
|
|
3
3
|
readonly name = "@grafana/faro-web-sdk:instrumentation-errors";
|
|
4
|
-
readonly version = "1.
|
|
4
|
+
readonly version = "1.5.0";
|
|
5
5
|
initialize(): void;
|
|
6
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseInstrumentation } from '@grafana/faro-core';
|
|
2
2
|
export declare class PerformanceInstrumentation extends BaseInstrumentation {
|
|
3
3
|
readonly name = "@grafana/faro-web-sdk:instrumentation-performance";
|
|
4
|
-
readonly version = "1.
|
|
4
|
+
readonly version = "1.5.0";
|
|
5
5
|
initialize(): void;
|
|
6
6
|
private getIgnoreUrls;
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BaseInstrumentation } from '@grafana/faro-core';
|
|
2
2
|
export declare class SessionInstrumentation extends BaseInstrumentation {
|
|
3
3
|
readonly name = "@grafana/faro-web-sdk:instrumentation-session";
|
|
4
|
-
readonly version = "1.
|
|
4
|
+
readonly version = "1.5.0";
|
|
5
5
|
private notifiedSession;
|
|
6
6
|
private sendSessionStartEvent;
|
|
7
|
-
private
|
|
7
|
+
private createInitialSession;
|
|
8
8
|
private registerBeforeSendHook;
|
|
9
9
|
initialize(): void;
|
|
10
10
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { FaroUserSession } from './types';
|
|
2
2
|
type CreateUserSessionObjectParams = {
|
|
3
3
|
sessionId?: string;
|
|
4
|
+
started?: number;
|
|
5
|
+
lastActivity?: number;
|
|
4
6
|
isSampled?: boolean;
|
|
5
7
|
};
|
|
6
|
-
export declare function createUserSessionObject({ sessionId, isSampled, }?: CreateUserSessionObjectParams): FaroUserSession;
|
|
8
|
+
export declare function createUserSessionObject({ sessionId, started, lastActivity, isSampled, }?: CreateUserSessionObjectParams): FaroUserSession;
|
|
7
9
|
export declare function isUserSessionValid(session: FaroUserSession | null): boolean;
|
|
8
10
|
type GetUserSessionUpdaterParams = {
|
|
9
11
|
storeUserSession: (session: FaroUserSession) => void;
|