@mparticle/web-sdk 2.75.1 → 2.77.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/mparticle.common.js +22 -15
- package/dist/mparticle.esm.js +22 -15
- package/dist/mparticle.js +214 -15
- package/dist/types/src/kitBlocking.d.ts +2 -0
- package/dist/types/src/mp-instance.d.ts +2 -0
- package/dist/types/src/pageViewTracker.d.ts +21 -0
- package/dist/types/src/sdkRuntimeModels.d.ts +1 -0
- package/dist/types/src/store.d.ts +1 -0
- package/package.json +3 -3
- package/src/batchUploader.ts +1 -0
- package/src/mockBatchCreator.ts +1 -0
- package/src/mp-instance.ts +9 -0
- package/src/pageViewTracker.ts +267 -0
- package/src/roktManager.ts +2 -0
- package/src/sdkRuntimeModels.ts +1 -0
- package/src/sdkToEventsApiConverter.ts +1 -0
- package/src/serverModel.ts +1 -0
- package/src/store.ts +6 -0
|
@@ -66,6 +66,7 @@ export default class KitBlocker {
|
|
|
66
66
|
LaunchReferral?: string;
|
|
67
67
|
ExpandedEventCount: number;
|
|
68
68
|
ActiveTimeOnSite: number;
|
|
69
|
+
TotalTimeOnSite: number;
|
|
69
70
|
PageUrl?: string;
|
|
70
71
|
IsBackgroundAST?: boolean;
|
|
71
72
|
AlreadySentToForwarders?: boolean;
|
|
@@ -111,6 +112,7 @@ export default class KitBlocker {
|
|
|
111
112
|
LaunchReferral?: string;
|
|
112
113
|
ExpandedEventCount: number;
|
|
113
114
|
ActiveTimeOnSite: number;
|
|
115
|
+
TotalTimeOnSite: number;
|
|
114
116
|
PageUrl?: string;
|
|
115
117
|
IsBackgroundAST?: boolean;
|
|
116
118
|
AlreadySentToForwarders?: boolean;
|
|
@@ -20,6 +20,7 @@ import RoktManager from './roktManager';
|
|
|
20
20
|
import { ICookieConsentManager } from './cookieConsentManager';
|
|
21
21
|
import { ErrorReportingDispatcher } from './reporting/errorReportingDispatcher';
|
|
22
22
|
import { LoggingDispatcher } from './reporting/loggingDispatcher';
|
|
23
|
+
import { PageViewTracker } from './pageViewTracker';
|
|
23
24
|
export interface IErrorLogMessage {
|
|
24
25
|
message?: string;
|
|
25
26
|
name?: string;
|
|
@@ -44,6 +45,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
|
|
|
44
45
|
_IdentityAPIClient: typeof IdentityAPIClient;
|
|
45
46
|
_IntegrationCapture: IntegrationCapture;
|
|
46
47
|
_NativeSdkHelpers: INativeSdkHelpers;
|
|
48
|
+
_PageViewTracker?: PageViewTracker;
|
|
47
49
|
_Persistence: IPersistence;
|
|
48
50
|
_CookieConsentManager: ICookieConsentManager;
|
|
49
51
|
_ErrorReportingDispatcher: ErrorReportingDispatcher;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IMParticleWebSDKInstance } from './mp-instance';
|
|
2
|
+
export declare class PageViewTracker {
|
|
3
|
+
mpInstance: IMParticleWebSDKInstance;
|
|
4
|
+
private lastPath;
|
|
5
|
+
private isActive;
|
|
6
|
+
private originalPushState;
|
|
7
|
+
private originalReplaceState;
|
|
8
|
+
private pushStateWrapper;
|
|
9
|
+
private replaceStateWrapper;
|
|
10
|
+
private popStateListener;
|
|
11
|
+
constructor(mpInstance: IMParticleWebSDKInstance);
|
|
12
|
+
private isSupportedEnvironment;
|
|
13
|
+
init(): void;
|
|
14
|
+
private patchHistoryMethods;
|
|
15
|
+
private addNavigationListeners;
|
|
16
|
+
private safeHandleNavigation;
|
|
17
|
+
private getCurrentKey;
|
|
18
|
+
private handleNavigation;
|
|
19
|
+
private firePageView;
|
|
20
|
+
teardown(): void;
|
|
21
|
+
}
|
|
@@ -146,6 +146,7 @@ export interface IStore {
|
|
|
146
146
|
getRoktAccountId?(): string;
|
|
147
147
|
setRoktAccountId?(accountId: string): void;
|
|
148
148
|
getTimeOnSite?(): number | undefined;
|
|
149
|
+
getTotalTimeOnSite?(): number | undefined;
|
|
149
150
|
getIntegrationName?(): string;
|
|
150
151
|
setIntegrationName?(integrationName: string): void;
|
|
151
152
|
addMpidToSessionHistory?(mpid: MPID, previousMpid?: MPID): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mparticle/web-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.77.0",
|
|
4
4
|
"description": "mParticle core SDK for web applications",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"@babel/preset-env": "^7.6.0",
|
|
104
104
|
"@babel/preset-typescript": "^7.6.0",
|
|
105
105
|
"@mparticle/data-planning-models": "^0.1.0",
|
|
106
|
-
"@mparticle/event-models": "^1.3.
|
|
106
|
+
"@mparticle/event-models": "^1.3.1",
|
|
107
107
|
"@rollup/plugin-babel": "6.0.3",
|
|
108
108
|
"@rollup/plugin-commonjs": "25.0.4",
|
|
109
109
|
"@rollup/plugin-json": "^5.0.2",
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"webpack-cli": "^5.0.2"
|
|
160
160
|
},
|
|
161
161
|
"peerDependencies": {
|
|
162
|
-
"@mparticle/event-models": "^1.3.
|
|
162
|
+
"@mparticle/event-models": "^1.3.1"
|
|
163
163
|
},
|
|
164
164
|
"dependencies": {
|
|
165
165
|
"@babel/runtime": "^7.23.2"
|
package/src/batchUploader.ts
CHANGED
|
@@ -197,6 +197,7 @@ export class BatchUploader {
|
|
|
197
197
|
SessionStartDate: sessionStartDate?.getTime() || now,
|
|
198
198
|
Debug: SDKConfig.isDevelopmentMode,
|
|
199
199
|
ActiveTimeOnSite: _timeOnSiteTimer?.getTimeInForeground() || 0,
|
|
200
|
+
TotalTimeOnSite: _Store.getTotalTimeOnSite?.() || 0,
|
|
200
201
|
PageUrl: getHref() || null,
|
|
201
202
|
IsBackgroundAST: true
|
|
202
203
|
} as SDKEvent;
|
package/src/mockBatchCreator.ts
CHANGED
package/src/mp-instance.ts
CHANGED
|
@@ -57,6 +57,7 @@ import { LoggingDispatcher } from './reporting/loggingDispatcher';
|
|
|
57
57
|
import { IErrorReportingService, ILoggingService } from './reporting/types';
|
|
58
58
|
import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger';
|
|
59
59
|
import { normalizeRoktLauncherOptions } from './roktLauncherOptions';
|
|
60
|
+
import { PageViewTracker } from './pageViewTracker';
|
|
60
61
|
|
|
61
62
|
export interface IErrorLogMessage {
|
|
62
63
|
message?: string;
|
|
@@ -87,6 +88,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
|
|
|
87
88
|
_IdentityAPIClient: typeof IdentityAPIClient;
|
|
88
89
|
_IntegrationCapture: IntegrationCapture;
|
|
89
90
|
_NativeSdkHelpers: INativeSdkHelpers;
|
|
91
|
+
_PageViewTracker?: PageViewTracker;
|
|
90
92
|
_Persistence: IPersistence;
|
|
91
93
|
_CookieConsentManager: ICookieConsentManager;
|
|
92
94
|
_ErrorReportingDispatcher: ErrorReportingDispatcher;
|
|
@@ -1585,6 +1587,13 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
|
|
|
1585
1587
|
|
|
1586
1588
|
if (getFeatureFlag(AutoLogPageView)) {
|
|
1587
1589
|
mpInstance._Events.logPageView();
|
|
1590
|
+
|
|
1591
|
+
if (!mpInstance._PageViewTracker) {
|
|
1592
|
+
mpInstance._PageViewTracker = new PageViewTracker(mpInstance);
|
|
1593
|
+
}
|
|
1594
|
+
mpInstance._PageViewTracker.init();
|
|
1595
|
+
} else if (mpInstance._PageViewTracker) {
|
|
1596
|
+
mpInstance._PageViewTracker.teardown();
|
|
1588
1597
|
}
|
|
1589
1598
|
|
|
1590
1599
|
processIdentityCallback(
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { IMParticleWebSDKInstance } from './mp-instance';
|
|
2
|
+
import { EventType, MessageType } from './types';
|
|
3
|
+
|
|
4
|
+
type HistoryStateMethod = History['pushState'];
|
|
5
|
+
|
|
6
|
+
const WRAPPED_MARKER = '__mpApvWrapped__';
|
|
7
|
+
|
|
8
|
+
type MarkedHistoryMethod = HistoryStateMethod & {
|
|
9
|
+
[WRAPPED_MARKER]?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export class PageViewTracker {
|
|
13
|
+
mpInstance: IMParticleWebSDKInstance;
|
|
14
|
+
|
|
15
|
+
private lastPath: string | null = null;
|
|
16
|
+
private isActive = false;
|
|
17
|
+
|
|
18
|
+
private originalPushState: HistoryStateMethod | null = null;
|
|
19
|
+
private originalReplaceState: HistoryStateMethod | null = null;
|
|
20
|
+
|
|
21
|
+
private pushStateWrapper: HistoryStateMethod | null = null;
|
|
22
|
+
private replaceStateWrapper: HistoryStateMethod | null = null;
|
|
23
|
+
|
|
24
|
+
private popStateListener: (() => void) | null = null;
|
|
25
|
+
|
|
26
|
+
constructor(mpInstance: IMParticleWebSDKInstance) {
|
|
27
|
+
this.mpInstance = mpInstance;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private isSupportedEnvironment(): boolean {
|
|
31
|
+
return (
|
|
32
|
+
typeof window !== 'undefined' &&
|
|
33
|
+
typeof window.history !== 'undefined' &&
|
|
34
|
+
typeof window.history.pushState === 'function' &&
|
|
35
|
+
typeof window.addEventListener === 'function'
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public init(): void {
|
|
40
|
+
this.mpInstance.Logger.verbose(
|
|
41
|
+
'mParticle APV: [init] PageViewTracker Init'
|
|
42
|
+
);
|
|
43
|
+
if (!this.isSupportedEnvironment()) {
|
|
44
|
+
this.mpInstance.Logger.verbose(
|
|
45
|
+
'mParticle APV: [init] unsupported environment (no History API), not starting'
|
|
46
|
+
);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (this.isActive) {
|
|
51
|
+
this.mpInstance.Logger.verbose(
|
|
52
|
+
'mParticle APV: [init] starting (teardown-first for idempotency)'
|
|
53
|
+
);
|
|
54
|
+
this.teardown();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.isActive = true;
|
|
58
|
+
|
|
59
|
+
this.lastPath = this.getCurrentKey();
|
|
60
|
+
|
|
61
|
+
this.mpInstance.Logger.verbose(
|
|
62
|
+
`mParticle APV: [init] seeded lastPath: ${this.lastPath}`
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
this.patchHistoryMethods();
|
|
66
|
+
this.addNavigationListeners();
|
|
67
|
+
|
|
68
|
+
this.mpInstance.Logger.verbose(
|
|
69
|
+
'mParticle APV: [init] patched pushState/replaceState + listening for popstate'
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private patchHistoryMethods(): void {
|
|
74
|
+
const self = this;
|
|
75
|
+
|
|
76
|
+
const installed = window.history.pushState as MarkedHistoryMethod;
|
|
77
|
+
if (installed[WRAPPED_MARKER]) {
|
|
78
|
+
this.mpInstance.Logger.verbose(
|
|
79
|
+
'mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap'
|
|
80
|
+
);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const originalPushState = window.history.pushState;
|
|
85
|
+
const originalReplaceState = window.history.replaceState;
|
|
86
|
+
this.originalPushState = originalPushState;
|
|
87
|
+
this.originalReplaceState = originalReplaceState;
|
|
88
|
+
|
|
89
|
+
const pushStateWrapper = function(
|
|
90
|
+
this: History,
|
|
91
|
+
...args: Parameters<HistoryStateMethod>
|
|
92
|
+
): void {
|
|
93
|
+
const result = originalPushState.apply(this, args);
|
|
94
|
+
self.safeHandleNavigation('pushState');
|
|
95
|
+
return result;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const replaceStateWrapper = function(
|
|
99
|
+
this: History,
|
|
100
|
+
...args: Parameters<HistoryStateMethod>
|
|
101
|
+
): void {
|
|
102
|
+
const result = originalReplaceState.apply(this, args);
|
|
103
|
+
self.safeHandleNavigation('replaceState');
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
Object.defineProperty(pushStateWrapper, WRAPPED_MARKER, {
|
|
108
|
+
value: true,
|
|
109
|
+
enumerable: false,
|
|
110
|
+
});
|
|
111
|
+
Object.defineProperty(replaceStateWrapper, WRAPPED_MARKER, {
|
|
112
|
+
value: true,
|
|
113
|
+
enumerable: false,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.pushStateWrapper = pushStateWrapper;
|
|
117
|
+
this.replaceStateWrapper = replaceStateWrapper;
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
window.history.pushState = pushStateWrapper;
|
|
121
|
+
window.history.replaceState = replaceStateWrapper;
|
|
122
|
+
} catch (e) {
|
|
123
|
+
this.mpInstance.Logger.verbose(
|
|
124
|
+
`mParticle APV: [error] failed to patch history methods (frozen/sealed), rolling back: ${e}`
|
|
125
|
+
);
|
|
126
|
+
try {
|
|
127
|
+
if (window.history.pushState === pushStateWrapper) {
|
|
128
|
+
window.history.pushState = originalPushState;
|
|
129
|
+
}
|
|
130
|
+
if (window.history.replaceState === replaceStateWrapper) {
|
|
131
|
+
window.history.replaceState = originalReplaceState;
|
|
132
|
+
}
|
|
133
|
+
} catch (restoreError) {
|
|
134
|
+
this.mpInstance.Logger.verbose(
|
|
135
|
+
`mParticle APV: [error] failed to restore history methods after patch failure: ${restoreError}`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
this.pushStateWrapper = null;
|
|
139
|
+
this.replaceStateWrapper = null;
|
|
140
|
+
this.originalPushState = null;
|
|
141
|
+
this.originalReplaceState = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private addNavigationListeners(): void {
|
|
146
|
+
this.popStateListener = () => this.safeHandleNavigation('popstate');
|
|
147
|
+
window.addEventListener('popstate', this.popStateListener);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private safeHandleNavigation(source: string): void {
|
|
151
|
+
try {
|
|
152
|
+
this.handleNavigation(source);
|
|
153
|
+
} catch (e) {
|
|
154
|
+
this.mpInstance.Logger.verbose(
|
|
155
|
+
`mParticle APV: [error] navigation handler threw (${source}), page view skipped: ${e}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private getCurrentKey(): string {
|
|
161
|
+
return window.location.pathname;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private handleNavigation(source: string): void {
|
|
165
|
+
const candidatePath = this.getCurrentKey();
|
|
166
|
+
|
|
167
|
+
this.mpInstance.Logger.verbose(
|
|
168
|
+
`mParticle APV: [detect] navigation signal (source: ${source}, candidatePath: ${candidatePath}, lastPath: ${this.lastPath})`
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
if (candidatePath === this.lastPath) {
|
|
172
|
+
this.mpInstance.Logger.verbose(
|
|
173
|
+
`mParticle APV: [dedupe] pathname unchanged, skipping (source: ${source}, path: ${candidatePath})`
|
|
174
|
+
);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this.mpInstance.Logger.verbose(
|
|
179
|
+
`mParticle APV: [accept] pathname changed, scheduling fire (source: ${source}, from: ${this.lastPath}, to: ${candidatePath})`
|
|
180
|
+
);
|
|
181
|
+
this.lastPath = candidatePath;
|
|
182
|
+
|
|
183
|
+
// Snapshot the path now: it is already settled at this point, and a
|
|
184
|
+
// same-tick navigation would otherwise overwrite window.location
|
|
185
|
+
// before the deferred flush reads it. The title is intentionally read
|
|
186
|
+
// later (in the deferred flush) so the router's post-navigation render
|
|
187
|
+
// commit has a chance to update document.title first.
|
|
188
|
+
const capturedPath = candidatePath;
|
|
189
|
+
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
if (!this.isActive) {
|
|
192
|
+
this.mpInstance.Logger.verbose(
|
|
193
|
+
'mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)'
|
|
194
|
+
);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.mpInstance._SessionManager.resetSessionTimer();
|
|
199
|
+
this.firePageView(capturedPath);
|
|
200
|
+
}, 0);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Mirrors the event shape of the public mParticle.logPageView(), but carries
|
|
204
|
+
// the captured SPA path rather than reading the live location.
|
|
205
|
+
private firePageView(path: string): void {
|
|
206
|
+
const title = window.document.title;
|
|
207
|
+
|
|
208
|
+
this.mpInstance.Logger.verbose(
|
|
209
|
+
`mParticle APV: [fire] deferred flush -> _Events.logEvent(PageView) (path: ${path}, title: ${title})`
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
this.mpInstance._Events.logEvent({
|
|
213
|
+
messageType: MessageType.PageView,
|
|
214
|
+
name: 'PageView',
|
|
215
|
+
data: {
|
|
216
|
+
hostname: window.location.hostname,
|
|
217
|
+
title,
|
|
218
|
+
path,
|
|
219
|
+
},
|
|
220
|
+
eventType: EventType.Unknown,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public teardown(): void {
|
|
225
|
+
if (this.popStateListener) {
|
|
226
|
+
window.removeEventListener('popstate', this.popStateListener);
|
|
227
|
+
this.popStateListener = null;
|
|
228
|
+
}
|
|
229
|
+
const pushStateStillOurs =
|
|
230
|
+
this.pushStateWrapper !== null &&
|
|
231
|
+
window.history.pushState === this.pushStateWrapper;
|
|
232
|
+
if (this.originalPushState) {
|
|
233
|
+
if (pushStateStillOurs) {
|
|
234
|
+
window.history.pushState = this.originalPushState;
|
|
235
|
+
this.mpInstance.Logger.verbose(
|
|
236
|
+
'mParticle APV: [teardown] restored original pushState'
|
|
237
|
+
);
|
|
238
|
+
} else {
|
|
239
|
+
this.mpInstance.Logger.verbose(
|
|
240
|
+
'mParticle APV: [teardown] pushState no longer ours; leaving in place, gating callback to no-op'
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
this.originalPushState = null;
|
|
244
|
+
this.pushStateWrapper = null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const replaceStateStillOurs =
|
|
248
|
+
this.replaceStateWrapper !== null &&
|
|
249
|
+
window.history.replaceState === this.replaceStateWrapper;
|
|
250
|
+
if (this.originalReplaceState) {
|
|
251
|
+
if (replaceStateStillOurs) {
|
|
252
|
+
window.history.replaceState = this.originalReplaceState;
|
|
253
|
+
this.mpInstance.Logger.verbose(
|
|
254
|
+
'mParticle APV: [teardown] restored original replaceState'
|
|
255
|
+
);
|
|
256
|
+
} else {
|
|
257
|
+
this.mpInstance.Logger.verbose(
|
|
258
|
+
'mParticle APV: [teardown] replaceState no longer ours; leaving in place, gating callback to no-op'
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
this.originalReplaceState = null;
|
|
262
|
+
this.replaceStateWrapper = null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
this.isActive = false;
|
|
266
|
+
}
|
|
267
|
+
}
|
package/src/roktManager.ts
CHANGED
|
@@ -355,11 +355,13 @@ export default class RoktManager {
|
|
|
355
355
|
this.setUserAttributes(mappedAttributes);
|
|
356
356
|
|
|
357
357
|
const timeOnSite = this.store?.getTimeOnSite?.();
|
|
358
|
+
const totalTimeOnSite = this.store?.getTotalTimeOnSite?.();
|
|
358
359
|
|
|
359
360
|
const enrichedAttributes: RoktAttributes = {
|
|
360
361
|
...mappedAttributes,
|
|
361
362
|
...(sandboxValue !== null ? { sandbox: sandboxValue } : {}),
|
|
362
363
|
...(timeOnSite ? { active_time_on_site_ms: timeOnSite } : {}),
|
|
364
|
+
...(totalTimeOnSite ? { total_time_on_site_ms: totalTimeOnSite } : {}),
|
|
363
365
|
};
|
|
364
366
|
|
|
365
367
|
// Propagate email from current user identities if not already in attributes
|
package/src/sdkRuntimeModels.ts
CHANGED
|
@@ -664,6 +664,7 @@ export function convertBaseEventData(
|
|
|
664
664
|
location: convertSDKLocation(sdkEvent.Location),
|
|
665
665
|
source_message_id: sdkEvent.SourceMessageId,
|
|
666
666
|
active_time_on_site_ms: sdkEvent.ActiveTimeOnSite,
|
|
667
|
+
total_time_on_site_ms: sdkEvent.TotalTimeOnSite,
|
|
667
668
|
page_url: sdkEvent.PageUrl,
|
|
668
669
|
};
|
|
669
670
|
|
package/src/serverModel.ts
CHANGED
|
@@ -311,6 +311,7 @@ export default function ServerModel(
|
|
|
311
311
|
event.name
|
|
312
312
|
),
|
|
313
313
|
ActiveTimeOnSite: mpInstance._timeOnSiteTimer?.getTimeInForeground(),
|
|
314
|
+
TotalTimeOnSite: mpInstance._Store.getTotalTimeOnSite?.(),
|
|
314
315
|
PageUrl: getHref() || null,
|
|
315
316
|
SourceMessageId:
|
|
316
317
|
event.sourceMessageId ||
|
package/src/store.ts
CHANGED
|
@@ -233,6 +233,7 @@ export interface IStore {
|
|
|
233
233
|
getRoktAccountId?(): string;
|
|
234
234
|
setRoktAccountId?(accountId: string): void;
|
|
235
235
|
getTimeOnSite?(): number | undefined;
|
|
236
|
+
getTotalTimeOnSite?(): number | undefined;
|
|
236
237
|
getIntegrationName?(): string;
|
|
237
238
|
setIntegrationName?(integrationName: string): void;
|
|
238
239
|
|
|
@@ -687,6 +688,11 @@ export default function Store(
|
|
|
687
688
|
this.getTimeOnSite = () =>
|
|
688
689
|
mpInstance._timeOnSiteTimer?.getTimeInForeground();
|
|
689
690
|
|
|
691
|
+
this.getTotalTimeOnSite = () =>
|
|
692
|
+
this.sessionStartDate
|
|
693
|
+
? Date.now() - this.sessionStartDate.getTime()
|
|
694
|
+
: undefined;
|
|
695
|
+
|
|
690
696
|
this.addMpidToSessionHistory = (mpid: MPID, previousMPID?: MPID): void => {
|
|
691
697
|
const indexOfMPID = this.currentSessionMPIDs.indexOf(mpid);
|
|
692
698
|
|