@schibsted/pulse-sdk 8.0.0-rc.1 → 8.0.0-rc.10
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/cjs/Tracker.js +169 -216
- package/dist/cjs/Tracker.test-d.js +2 -2
- package/dist/cjs/builders/actor.js +3 -3
- package/dist/cjs/builders/consents.js +2 -2
- package/dist/cjs/builders/events-node.js +3 -3
- package/dist/cjs/builders/experiments.js +1 -0
- package/dist/cjs/identity/actor.js +18 -6
- package/dist/cjs/identity/cis.js +2 -1
- package/dist/cjs/leaveTrackingTpaas/constants.js +2 -7
- package/dist/cjs/leaveTrackingTpaas/index.js +52 -40
- package/dist/cjs/tracker-proxy/consts.js +12 -6
- package/dist/cjs/tracker-proxy/proxy-provider.js +6 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/visibility-observer/index.js +9 -7
- package/dist/cjs/wrapper/types/event.js +5 -0
- package/dist/ejs/Tracker.js +171 -218
- package/dist/ejs/Tracker.test-d.js +2 -2
- package/dist/ejs/builders/actor.js +2 -2
- package/dist/ejs/builders/consents.js +2 -2
- package/dist/ejs/builders/events-node.js +3 -3
- package/dist/ejs/builders/experiments.js +1 -1
- package/dist/ejs/identity/actor.js +19 -7
- package/dist/ejs/identity/cis.js +2 -1
- package/dist/ejs/leaveTrackingTpaas/constants.js +1 -5
- package/dist/ejs/leaveTrackingTpaas/index.js +53 -41
- package/dist/ejs/tracker-proxy/consts.js +12 -6
- package/dist/ejs/tracker-proxy/proxy-provider.js +6 -0
- package/dist/ejs/version.js +1 -1
- package/dist/ejs/visibility-observer/index.js +9 -7
- package/dist/ejs/wrapper/types/event.js +4 -1
- package/dist/types/Tracker.d.ts +86 -92
- package/dist/types/builders/actor.d.ts +3 -2
- package/dist/types/builders/consents.d.ts +2 -2
- package/dist/types/builders/experiments.d.ts +1 -0
- package/dist/types/builders/index.d.ts +1 -1
- package/dist/types/identity/actor.d.ts +2 -2
- package/dist/types/identity/cis.d.ts +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/leaveTrackingTpaas/constants.d.ts +1 -5
- package/dist/types/leaveTrackingTpaas/index.d.ts +6 -6
- package/dist/types/leaveTrackingTpaas/types.d.ts +1 -9
- package/dist/types/tracker-proxy/consts.d.ts +1 -1
- package/dist/types/types.d.ts +19 -13
- package/dist/types/version.d.ts +1 -1
- package/dist/types/visibility-observer/index.d.ts +6 -1
- package/dist/types/wrapper/types/event.d.ts +3 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.d.ts +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.js +17 -3
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.js +15 -5
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.d.ts +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.js +5 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.d.ts +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.js +16 -2
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.js +12 -3
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.d.ts +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.js +5 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.js.map +1 -1
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/cis-browser.d.ts +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/storage/pulseStorage.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/storage/storage.d.ts +1 -0
- package/node_modules/@schibsted/pulse-utils/package.json +1 -1
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/catalogVersion.js +9 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/device.js +8 -2
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/provider.js +3 -1
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/session.js +19 -6
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders.js +69 -78
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/guards.js +7 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/index.js +3 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/catalogVersion.js +6 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/device.js +8 -2
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/provider.js +3 -1
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/session.js +19 -6
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders.js +70 -73
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/guards.js +4 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/index.js +1 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/index.d.ts +1561 -1190
- package/node_modules/@schibsted/tpaas-event-builder/package.json +3 -2
- package/node_modules/@schibsted/tpaas-schemas/dist/cjs/constants.js +93 -107
- package/node_modules/@schibsted/tpaas-schemas/dist/cjs/index.js +1 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/cjs/types.js +2 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/ejs/constants.js +91 -105
- package/node_modules/@schibsted/tpaas-schemas/dist/ejs/index.js +1 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/ejs/types.js +1 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/index.d.ts +1654 -1288
- package/node_modules/@schibsted/tpaas-schemas/package.json +1 -1
- package/package.json +6 -6
|
@@ -10,6 +10,8 @@ const ARTICLE_PAYLOAD = {
|
|
|
10
10
|
{
|
|
11
11
|
name: 'test-experiment',
|
|
12
12
|
variant: 'test-variant',
|
|
13
|
+
platform: 'web',
|
|
14
|
+
experimentSdrn: 'sdrn:the-standard:experiment:test-experiment',
|
|
13
15
|
},
|
|
14
16
|
],
|
|
15
17
|
object: {
|
|
@@ -35,8 +37,6 @@ const ARTICLE_PAYLOAD = {
|
|
|
35
37
|
},
|
|
36
38
|
},
|
|
37
39
|
provider: {
|
|
38
|
-
component: 'test-component',
|
|
39
|
-
componentVersion: '1.0.0',
|
|
40
40
|
product: 'test-product',
|
|
41
41
|
stage: 'Dev',
|
|
42
42
|
version: '1.0.0',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultValue = void 0;
|
|
4
4
|
exports.generateActorSDRN = generateActorSDRN;
|
|
5
|
-
exports.
|
|
5
|
+
exports.hasActorBuilder = hasActorBuilder;
|
|
6
6
|
exports.default = actor;
|
|
7
7
|
const pulse_utils_1 = require("@schibsted/pulse-utils");
|
|
8
8
|
/**
|
|
@@ -18,11 +18,11 @@ function generateActorSDRN(id, realm = '__REALM_NOT_SET__') {
|
|
|
18
18
|
return `sdrn:${realm}:user:${outputId}`;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Type guard to check if the input
|
|
21
|
+
* Type guard to check if the input has an Actor Builder
|
|
22
22
|
* @param input
|
|
23
23
|
* @internal
|
|
24
24
|
*/
|
|
25
|
-
function
|
|
25
|
+
function hasActorBuilder(input) {
|
|
26
26
|
// biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is not available in ES2020
|
|
27
27
|
return (0, pulse_utils_1.isPlainObject)(input) && Object.prototype.hasOwnProperty.call(input, 'actor');
|
|
28
28
|
}
|
|
@@ -14,7 +14,7 @@ const pulse_utils_1 = require("@schibsted/pulse-utils");
|
|
|
14
14
|
const warnOnce_1 = __importDefault(require("../warnOnce"));
|
|
15
15
|
const consent_manager_1 = require("./consent-manager");
|
|
16
16
|
/**
|
|
17
|
-
* @enum
|
|
17
|
+
* @enum ConsentsCategory
|
|
18
18
|
*/
|
|
19
19
|
var ConsentsCategory;
|
|
20
20
|
(function (ConsentsCategory) {
|
|
@@ -23,7 +23,7 @@ var ConsentsCategory;
|
|
|
23
23
|
ConsentsCategory["CMP_ADVERTISING"] = "CMP_ADVERTISING";
|
|
24
24
|
ConsentsCategory["CMP_PERSONALIZATION"] = "CMP_PERSONALIZATION";
|
|
25
25
|
})(ConsentsCategory || (exports.ConsentsCategory = ConsentsCategory = {}));
|
|
26
|
-
exports.ConsentsSourceValues = ['default', 'cmp', 'cache'];
|
|
26
|
+
exports.ConsentsSourceValues = ['default', 'cmp', 'cache', 'url'];
|
|
27
27
|
exports.ConsentsPurposeCategoryStatusValues = ['accepted', 'rejected', 'unknown'];
|
|
28
28
|
const isLegacyConsentsPurpose = (consentsPurposeCategory) => {
|
|
29
29
|
return !consentsPurposeCategory?.status;
|
|
@@ -65,7 +65,7 @@ function routableEventDefaults(eventInput) {
|
|
|
65
65
|
function routableEvent({ eventInput, sdkConfig } = {}) {
|
|
66
66
|
return Object.assign({}, eventInput, {
|
|
67
67
|
schema: eventInput?.schema ||
|
|
68
|
-
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/base-routable-event.json/
|
|
68
|
+
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/base-routable-event.json/248.json#`,
|
|
69
69
|
provider: (0, provider_1.default)(eventInput),
|
|
70
70
|
actor: (0, actor_1.default)(eventInput),
|
|
71
71
|
});
|
|
@@ -98,7 +98,7 @@ function trackerEvent({ eventInput, sdkConfig } = {}) {
|
|
|
98
98
|
'@type': eventInput?.type || 'View',
|
|
99
99
|
pageViewId: pageViewIdInput || pageViewIdSdk,
|
|
100
100
|
schema: eventInput?.schema ||
|
|
101
|
-
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/tracker-event.json/
|
|
101
|
+
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/tracker-event.json/361.json`,
|
|
102
102
|
actor: (0, actor_1.default)(parentInput),
|
|
103
103
|
consents: (0, consents_1.default)(parentInput),
|
|
104
104
|
experiments: (0, experiments_1.default)(parentInput),
|
|
@@ -116,7 +116,7 @@ trackerEvent.defaults = trackerEventInput;
|
|
|
116
116
|
function engagementEvent({ eventInput, sdkConfig } = {}) {
|
|
117
117
|
return Object.assign(trackerEvent({ eventInput, sdkConfig }), {
|
|
118
118
|
schema: eventInput?.schema ||
|
|
119
|
-
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/engagement-event.json/
|
|
119
|
+
`http://${sdkConfig?.schemaLocation || exports.DEFAULT_SCHEMA_LOCATION}/events/engagement-event.json/388.json`,
|
|
120
120
|
'@type': 'Engagement',
|
|
121
121
|
});
|
|
122
122
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultValue = void 0;
|
|
4
|
+
exports.generateExperimentSDRN = generateExperimentSDRN;
|
|
4
5
|
exports.default = experiments;
|
|
5
6
|
function generateExperimentSDRN(id, experimentationPlatform) {
|
|
6
7
|
return `sdrn:${experimentationPlatform}:experiment:${id}`;
|
|
@@ -10,9 +10,7 @@ const warnOnce_1 = __importDefault(require("../warnOnce"));
|
|
|
10
10
|
/**
|
|
11
11
|
* @internal exported for testing
|
|
12
12
|
*/
|
|
13
|
-
exports.WARN_CIS_SYNC_LOGIN_UNDEFINED = '
|
|
14
|
-
' this using tracker.update({ actor: undefined }), otherwise do tracker.update({ actor: somePromise }) with a' +
|
|
15
|
-
' promise that resolves to the login state.';
|
|
13
|
+
exports.WARN_CIS_SYNC_LOGIN_UNDEFINED = 'No Actor Builder found in event input or tracker builders. Please provide an Actor Builder to ensure the SDK resolves logged-in and logged-out scenarios correctly.';
|
|
16
14
|
/**
|
|
17
15
|
* Get the actor id (userId) from the current browser. A promise is returned
|
|
18
16
|
* because a call may be made to complete the login process.
|
|
@@ -33,6 +31,19 @@ const getActor = async (builders) => {
|
|
|
33
31
|
return await evaluateActor(builders);
|
|
34
32
|
};
|
|
35
33
|
exports.getActor = getActor;
|
|
34
|
+
/**
|
|
35
|
+
* Pinpoints the Actor Builder from the Event payload or the available Builders
|
|
36
|
+
* @param eventInput - The event input which may contain an `actor` property
|
|
37
|
+
* @param builders - The builders managed by the SDK.
|
|
38
|
+
*/
|
|
39
|
+
function getActorSource(eventInput = {}, builders = {}) {
|
|
40
|
+
if ((0, actor_1.hasActorBuilder)(eventInput)) {
|
|
41
|
+
return eventInput.actor;
|
|
42
|
+
}
|
|
43
|
+
if ((0, actor_1.hasActorBuilder)(builders)) {
|
|
44
|
+
return builders.actor;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
36
47
|
const userIsLoggedIn = async (builders) => {
|
|
37
48
|
const actor = await getActor(builders);
|
|
38
49
|
return !!actor?.id;
|
|
@@ -45,8 +56,9 @@ exports.userIsLoggedIn = userIsLoggedIn;
|
|
|
45
56
|
* @private
|
|
46
57
|
*/
|
|
47
58
|
const evaluateActor = async (eventInput = {}, builders = {}) => {
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
const actorSource = getActorSource(eventInput, builders);
|
|
60
|
+
if (actorSource) {
|
|
61
|
+
const evaluatedActor = await (0, pulse_utils_1.evaluateAndFlatten)(actorSource);
|
|
50
62
|
if (evaluatedActor) {
|
|
51
63
|
return evaluatedActor;
|
|
52
64
|
}
|
|
@@ -54,7 +66,7 @@ const evaluateActor = async (eventInput = {}, builders = {}) => {
|
|
|
54
66
|
// We allow an empty actor object, because it is a sign that the application is not setting nor updating Actor correctly.
|
|
55
67
|
// Inferring "id: undefined" as a fallback would mask that bug.
|
|
56
68
|
// Hence, the warning below.
|
|
57
|
-
(0, warnOnce_1.default)('no-actor-builder
|
|
69
|
+
(0, warnOnce_1.default)('no-actor-builder', exports.WARN_CIS_SYNC_LOGIN_UNDEFINED);
|
|
58
70
|
return {};
|
|
59
71
|
};
|
|
60
72
|
exports.evaluateActor = evaluateActor;
|
package/dist/cjs/identity/cis.js
CHANGED
|
@@ -45,7 +45,7 @@ const cisSync = async (data, builders, config) => {
|
|
|
45
45
|
// _pulse2data cookie, or just not do the sync.
|
|
46
46
|
//
|
|
47
47
|
const actorPromise = (0, actor_1.evaluateActor)(data, builders);
|
|
48
|
-
const { cisBaseUrl, cisEnabled, includeAdvertising: includeAdvertisingPromise, isHybrid, nativeJwe, providerId, trackerId, vendors, } = config || {};
|
|
48
|
+
const { adChoicesEnabled, cisBaseUrl, cisEnabled, includeAdvertising: includeAdvertisingPromise, isHybrid, nativeJwe, providerId, trackerId, vendors, } = config || {};
|
|
49
49
|
const [includeAdvertising, actor] = await Promise.all([includeAdvertisingPromise, actorPromise]);
|
|
50
50
|
const { id, realm } = actor;
|
|
51
51
|
if (cisEnabled) {
|
|
@@ -53,6 +53,7 @@ const cisSync = async (data, builders, config) => {
|
|
|
53
53
|
return (0, pulse_cis_sync_1.syncWithCis)(
|
|
54
54
|
// @ts-expect-error
|
|
55
55
|
id, nativeJwe, cisBaseUrl, realm, providerId, isHybrid ? 'Hybrid' : 'Web', version_1.SDK_VERSION, {
|
|
56
|
+
adChoicesEnabled,
|
|
56
57
|
includeAdvertising,
|
|
57
58
|
vendors,
|
|
58
59
|
trackerId,
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const DEFAULT_ACTIVITY_DURATION = () => ({
|
|
5
|
-
value: 0,
|
|
6
|
-
interval: undefined,
|
|
7
|
-
timeSinceLastActivity: 0,
|
|
8
|
-
});
|
|
9
|
-
exports.DEFAULT_ACTIVITY_DURATION = DEFAULT_ACTIVITY_DURATION;
|
|
3
|
+
exports.ACTIVITY_DURATION_LIMIT_MS = exports.DEFAULT_PAGE_LEAVE_EVENT = void 0;
|
|
10
4
|
const DEFAULT_PAGE_LEAVE_EVENT = () => ({
|
|
11
5
|
objectViewPercentage: 0,
|
|
12
6
|
maxObjectViewPercentage: 0,
|
|
@@ -16,3 +10,4 @@ const DEFAULT_PAGE_LEAVE_EVENT = () => ({
|
|
|
16
10
|
maxPageScrollPosition: 0,
|
|
17
11
|
});
|
|
18
12
|
exports.DEFAULT_PAGE_LEAVE_EVENT = DEFAULT_PAGE_LEAVE_EVENT;
|
|
13
|
+
exports.ACTIVITY_DURATION_LIMIT_MS = 30000;
|
|
@@ -56,19 +56,42 @@ let updateViewedContentListeners = [];
|
|
|
56
56
|
let activityListeners = [];
|
|
57
57
|
let resizeObserver = null;
|
|
58
58
|
let throttledUpdateFn = (0, pulse_utils_1.throttle)(() => undefined, 0);
|
|
59
|
-
let
|
|
60
|
-
let
|
|
59
|
+
let durationStartTime = 0;
|
|
60
|
+
let activityStartTime = 0;
|
|
61
61
|
let currentLeaveEvent = (0, constants_1.DEFAULT_PAGE_LEAVE_EVENT)();
|
|
62
62
|
let additionalHeightBuilder;
|
|
63
|
+
/**
|
|
64
|
+
* Resolves a DOM element from either a CSS selector string or an Element instance.
|
|
65
|
+
*/
|
|
66
|
+
function resolveDomElement(element) {
|
|
67
|
+
try {
|
|
68
|
+
return typeof element === 'string' ? document.querySelector(element) : element || null;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
logger.error('Error while resolving DOM element', e);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
63
75
|
/*
|
|
64
76
|
Add leave tracking
|
|
65
77
|
*/
|
|
66
78
|
function addTpaasLeaveTracking({ objectElement, pageElement, schema, objectResizable, heightBuilder, trackMethod, }) {
|
|
67
79
|
function _addLeaveTracking() {
|
|
80
|
+
const objectDomElement = resolveDomElement(objectElement);
|
|
81
|
+
if (objectDomElement == null) {
|
|
82
|
+
logger.error('Could not find object element for leave tracking');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let pageDomElement = resolveDomElement(pageElement);
|
|
86
|
+
if (pageDomElement == null) {
|
|
87
|
+
logger.warn('Could not find page element for leave tracking, defaulting to document.body');
|
|
88
|
+
pageDomElement = document.body;
|
|
89
|
+
}
|
|
68
90
|
additionalHeightBuilder = heightBuilder;
|
|
69
91
|
addTpaasLeaveListeners();
|
|
70
|
-
addUpdateEventListeners(
|
|
71
|
-
|
|
92
|
+
addUpdateEventListeners(objectDomElement, pageDomElement, objectResizable);
|
|
93
|
+
activityStartTime = resetTime();
|
|
94
|
+
durationStartTime = resetTime();
|
|
72
95
|
currentLeaveSchema = schema;
|
|
73
96
|
currentTrackMethod = trackMethod;
|
|
74
97
|
logger.debug('addLeaveTracking:after:state', currentLeaveEvent);
|
|
@@ -160,12 +183,8 @@ function removeUpdateEventListeners() {
|
|
|
160
183
|
*/
|
|
161
184
|
const resetEventDefaults = () => {
|
|
162
185
|
currentLeaveEvent = (0, constants_1.DEFAULT_PAGE_LEAVE_EVENT)();
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
};
|
|
166
|
-
const resetActivityDuration = () => {
|
|
167
|
-
clearInterval(activityDuration.interval);
|
|
168
|
-
return (0, constants_1.DEFAULT_ACTIVITY_DURATION)();
|
|
186
|
+
durationStartTime = resetTime();
|
|
187
|
+
activityStartTime = resetTime();
|
|
169
188
|
};
|
|
170
189
|
const resetTpaasViewedContent = () => {
|
|
171
190
|
currentLeaveEvent = (0, constants_1.DEFAULT_PAGE_LEAVE_EVENT)();
|
|
@@ -174,34 +193,41 @@ exports.resetTpaasViewedContent = resetTpaasViewedContent;
|
|
|
174
193
|
const resetTime = () => Date.now();
|
|
175
194
|
/*
|
|
176
195
|
Send a Leave event only if Page Leave tracking is active in the SDK
|
|
177
|
-
The event that is ultimately sent is
|
|
178
|
-
|
|
179
|
-
to the brand event. After the event has been sent, leave page tracking is removed
|
|
196
|
+
The event that is ultimately sent is the View event saved in the currentTrackMethod callback.
|
|
197
|
+
After the event has been sent, leave page tracking is removed
|
|
180
198
|
and must be explicitly re-added if needed.
|
|
181
199
|
*/
|
|
182
|
-
function trackTpaasActiveLeave() {
|
|
200
|
+
async function trackTpaasActiveLeave() {
|
|
183
201
|
if (leaveTpaasTrackingIsActive()) {
|
|
184
|
-
trackTpaasLeave();
|
|
202
|
+
await trackTpaasLeave();
|
|
185
203
|
}
|
|
186
204
|
}
|
|
187
205
|
/*
|
|
188
206
|
Send a Leave event regardless of whether Page Leave tracking is active in the SDK
|
|
189
|
-
The event that is ultimately sent is
|
|
190
|
-
|
|
191
|
-
to the brand event. After the event has been sent, leave page tracking is removed
|
|
207
|
+
The event that is ultimately sent is the View event saved in the currentTrackMethod callback.
|
|
208
|
+
After the event has been sent, leave page tracking is removed
|
|
192
209
|
and must be explicitly re-added if needed.
|
|
193
210
|
*/
|
|
194
|
-
function trackTpaasLeave() {
|
|
211
|
+
async function trackTpaasLeave() {
|
|
195
212
|
const leave = getTpaasLeaveObject();
|
|
196
|
-
currentTrackMethod
|
|
213
|
+
// Capture currentTrackMethod and remove tracking synchronously before awaiting.
|
|
214
|
+
// If removal happened after the await, a new trackView* call arriving during the async
|
|
215
|
+
// gap would see tracking still active with the same schema and silently discard its
|
|
216
|
+
// new callback (e.g. a fresh leaveAudioBuilder), causing the next leave event to
|
|
217
|
+
// never fire or to use the wrong builder.
|
|
218
|
+
const trackMethod = currentTrackMethod;
|
|
197
219
|
removeTpaasLeaveTracking();
|
|
220
|
+
await trackMethod(leave);
|
|
198
221
|
}
|
|
199
222
|
function getTpaasLeaveObject() {
|
|
200
223
|
const endTime = Date.now();
|
|
201
|
-
|
|
224
|
+
// TPaaS leave event requires duration/activity to be at least 1ms, otherwise the event is rejected
|
|
225
|
+
// also, in practice, it's almost impossible to have an activity or duration of 0ms
|
|
226
|
+
const durationMs = Math.max(endTime - durationStartTime, 1);
|
|
227
|
+
const activityDurationMs = Math.max(Math.min(endTime - activityStartTime, constants_1.ACTIVITY_DURATION_LIMIT_MS), 1);
|
|
202
228
|
const leave = {
|
|
203
|
-
durationMs
|
|
204
|
-
activityDurationMs
|
|
229
|
+
durationMs,
|
|
230
|
+
activityDurationMs,
|
|
205
231
|
...currentLeaveEvent,
|
|
206
232
|
};
|
|
207
233
|
logger.debug('trackTpaasLeave: event', leave);
|
|
@@ -276,18 +302,10 @@ exports.calculateScrollPosition = calculateScrollPosition;
|
|
|
276
302
|
'mousedown', 'mousemove', 'keydown', 'scroll' and/or 'touchstart' browser events.
|
|
277
303
|
*/
|
|
278
304
|
function addUpdateActivityDurationListeners() {
|
|
279
|
-
if
|
|
280
|
-
|
|
305
|
+
// if there are already listeners for activity, do not add more
|
|
306
|
+
if (activityListeners.length > 0) {
|
|
281
307
|
return;
|
|
282
308
|
}
|
|
283
|
-
const interval = 1000;
|
|
284
|
-
const activityTimeout = 30 * 1000;
|
|
285
|
-
activityDuration.interval = window.setInterval(() => {
|
|
286
|
-
activityDuration.timeSinceLastActivity += interval;
|
|
287
|
-
if (activityDuration.timeSinceLastActivity < activityTimeout) {
|
|
288
|
-
activityDuration.value += interval;
|
|
289
|
-
}
|
|
290
|
-
}, interval);
|
|
291
309
|
const activityEvents = [
|
|
292
310
|
types_1.BrowserEvents.SCROLL,
|
|
293
311
|
types_1.BrowserEvents.MOUSEDOWN,
|
|
@@ -296,15 +314,9 @@ function addUpdateActivityDurationListeners() {
|
|
|
296
314
|
types_1.BrowserEvents.TOUCHSTART,
|
|
297
315
|
];
|
|
298
316
|
activityListeners = addEventListeners(activityEvents, () => {
|
|
299
|
-
|
|
317
|
+
activityStartTime = resetTime();
|
|
300
318
|
}, { passive: true });
|
|
301
319
|
}
|
|
302
|
-
function resetLastActivity(activityDuration) {
|
|
303
|
-
return {
|
|
304
|
-
...activityDuration,
|
|
305
|
-
timeSinceLastActivity: 0,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
320
|
/*
|
|
309
321
|
Add listeners to a set of browser events.
|
|
310
322
|
*/
|
|
@@ -37,15 +37,13 @@ exports.TPAAS_ALLOWED_METHODS = [
|
|
|
37
37
|
'trackLeaveLandingpage',
|
|
38
38
|
'trackLeaveListing',
|
|
39
39
|
'trackLeaveLockedArticle',
|
|
40
|
-
'trackLeaveLockedAudio',
|
|
41
40
|
'trackLeaveLockedAudioPage',
|
|
42
|
-
'trackLeaveLockedVideo',
|
|
43
41
|
'trackLeaveLockedVideoPage',
|
|
44
42
|
'trackLeavePage',
|
|
43
|
+
'trackLeaveSportsPage',
|
|
45
44
|
'trackLeaveVideoPage',
|
|
46
45
|
'trackLeaveWeather',
|
|
47
46
|
'trackViewArticle',
|
|
48
|
-
'trackViewAudio',
|
|
49
47
|
'trackViewAudioPage',
|
|
50
48
|
'trackViewError',
|
|
51
49
|
'trackViewFrontpage',
|
|
@@ -53,15 +51,23 @@ exports.TPAAS_ALLOWED_METHODS = [
|
|
|
53
51
|
'trackViewLandingpage',
|
|
54
52
|
'trackViewListing',
|
|
55
53
|
'trackViewLockedArticle',
|
|
56
|
-
'trackViewLockedAudio',
|
|
57
54
|
'trackViewLockedAudioPage',
|
|
58
|
-
'trackViewLockedVideo',
|
|
59
55
|
'trackViewLockedVideoPage',
|
|
60
56
|
'trackViewPage',
|
|
57
|
+
'trackViewSportsPage',
|
|
61
58
|
'trackViewTitle',
|
|
62
|
-
'trackViewVideo',
|
|
63
59
|
'trackViewVideoPage',
|
|
64
60
|
'trackViewWeather',
|
|
61
|
+
// these are not TPaaS methods,
|
|
62
|
+
// but they're part of this list to not have to duplicate the tracker-tpaas-proxy.ts implementation in tracker-proxy.ts
|
|
63
|
+
'trackLegacyViewArticle',
|
|
64
|
+
'trackLegacyViewLoginPoster',
|
|
65
|
+
'trackLegacyViewSalesPoster',
|
|
66
|
+
'trackLegacyViewListing',
|
|
67
|
+
'trackLegacyViewFrontpage',
|
|
68
|
+
'trackLegacyViewPage',
|
|
69
|
+
'trackLegacyViewUIElement',
|
|
70
|
+
'trackLegacyClickUIElement',
|
|
65
71
|
];
|
|
66
72
|
function isPulseProxyMessage(message) {
|
|
67
73
|
return (message !== null &&
|
|
@@ -13,6 +13,11 @@ function startProxyProviderListener(tracker) {
|
|
|
13
13
|
loglevel_1.default.debug('Proxy Provider - Not in browser environment, skipping message listener');
|
|
14
14
|
return () => { };
|
|
15
15
|
}
|
|
16
|
+
if (tracker.hasProxyListener) {
|
|
17
|
+
loglevel_1.default.debug('Proxy Provider - Message listener already registered for this tracker, skipping');
|
|
18
|
+
return () => { };
|
|
19
|
+
}
|
|
20
|
+
tracker.hasProxyListener = true;
|
|
16
21
|
loglevel_1.default.debug('Proxy Provider - Added message listener for proxy provider');
|
|
17
22
|
const listener = async (event) => {
|
|
18
23
|
loglevel_1.default.debug('Proxy Provider - message received', event.data);
|
|
@@ -64,5 +69,6 @@ function startProxyProviderListener(tracker) {
|
|
|
64
69
|
window.addEventListener('message', listener);
|
|
65
70
|
return () => {
|
|
66
71
|
window.removeEventListener('message', listener);
|
|
72
|
+
tracker.hasProxyListener = false;
|
|
67
73
|
};
|
|
68
74
|
}
|
package/dist/cjs/version.js
CHANGED
|
@@ -16,14 +16,16 @@ class VisibilityObserver {
|
|
|
16
16
|
* Uses {@link https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver | MutationObserver} to monitor the DOM for dynamically loaded content.
|
|
17
17
|
* Callback is invoked only once per element.
|
|
18
18
|
* @param selector The CSS selector for elements to track.
|
|
19
|
+
* @param options {ObserverOptions} Optional configuration for the observer.
|
|
20
|
+
* @param options.threshold Which ratio triggers the Observer callback.
|
|
19
21
|
* @throws Error if called more than once.
|
|
20
22
|
*/
|
|
21
|
-
observe(selector) {
|
|
23
|
+
observe(selector, { threshold = 0.67 }) {
|
|
22
24
|
if (this.selector) {
|
|
23
25
|
throw new Error(`Cannot observe selector ${selector}. A visibility observer has already been set up for selector ${this.selector}.`);
|
|
24
26
|
}
|
|
25
27
|
this.selector = selector;
|
|
26
|
-
this.setupObservers();
|
|
28
|
+
this.setupObservers({ threshold });
|
|
27
29
|
// biome-ignore lint/suspicious/useIterableCallbackReturn: -
|
|
28
30
|
this.elements().forEach((elementToTrack) => this.observeIntersection(elementToTrack));
|
|
29
31
|
}
|
|
@@ -33,14 +35,14 @@ class VisibilityObserver {
|
|
|
33
35
|
elements() {
|
|
34
36
|
return Array.from(document.querySelectorAll(this.selector));
|
|
35
37
|
}
|
|
36
|
-
//
|
|
37
|
-
setupObservers() {
|
|
38
|
-
this.setupIntersectionObserver();
|
|
38
|
+
// Initialise both observers and start watching for DOM changes
|
|
39
|
+
setupObservers({ threshold }) {
|
|
40
|
+
this.setupIntersectionObserver({ threshold });
|
|
39
41
|
this.setupMutationObserver();
|
|
40
42
|
this.observeMutations();
|
|
41
43
|
}
|
|
42
44
|
// Create observer to detect when elements become visible in the viewport
|
|
43
|
-
setupIntersectionObserver() {
|
|
45
|
+
setupIntersectionObserver({ threshold }) {
|
|
44
46
|
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
45
47
|
entries.forEach((entry) => {
|
|
46
48
|
if (entry.isIntersecting) {
|
|
@@ -49,7 +51,7 @@ class VisibilityObserver {
|
|
|
49
51
|
this.intersectionObserver.unobserve(node);
|
|
50
52
|
}
|
|
51
53
|
});
|
|
52
|
-
}, { threshold
|
|
54
|
+
}, { threshold });
|
|
53
55
|
}
|
|
54
56
|
// Create observer to detect DOM changes that may add/remove tracked elements
|
|
55
57
|
setupMutationObserver() {
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isLegacyPageType = isLegacyPageType;
|
|
4
|
+
const LEGACY_PAGE_TYPE_VALUES = ['Article', 'Listing', 'Frontpage', 'SalesPoster', 'Page', 'LoginPoster'];
|
|
5
|
+
function isLegacyPageType(value) {
|
|
6
|
+
return LEGACY_PAGE_TYPE_VALUES.includes(value);
|
|
7
|
+
}
|