@schibsted/pulse-sdk 8.0.0-alpha.16 → 8.0.0-alpha.18
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/EventBus/EventBus.js +146 -0
- package/dist/cjs/Tracker.js +2499 -0
- package/dist/cjs/Tracker.test-d.js +76 -0
- package/dist/cjs/app-integration.js +40 -0
- package/dist/cjs/builders/actor.js +60 -0
- package/dist/cjs/builders/consent-manager.js +134 -0
- package/dist/cjs/builders/consents.js +149 -0
- package/dist/cjs/builders/device-browser.js +89 -0
- package/dist/cjs/builders/device-node.js +63 -0
- package/dist/cjs/builders/device.js +23 -0
- package/dist/cjs/builders/events-anonymous-browser.js +6 -0
- package/dist/cjs/builders/events-anonymous-node.js +88 -0
- package/dist/cjs/builders/events-anonymous.js +17 -0
- package/dist/cjs/builders/events-browser.js +8 -0
- package/dist/cjs/builders/events-node.js +127 -0
- package/dist/cjs/builders/events.js +17 -0
- package/dist/cjs/builders/experimentMetadata.js +25 -0
- package/dist/cjs/builders/experiments.js +32 -0
- package/dist/cjs/builders/index.js +52 -0
- package/dist/cjs/builders/location.js +38 -0
- package/dist/cjs/builders/objects/objects-anonymous-browser.js +36 -0
- package/dist/cjs/builders/objects/objects-anonymous-node.js +95 -0
- package/dist/cjs/builders/objects/objects-anonymous.js +23 -0
- package/dist/cjs/builders/objects/objects-browser.js +36 -0
- package/dist/cjs/builders/objects/objects-node.js +126 -0
- package/dist/cjs/builders/objects/objects.js +23 -0
- package/dist/cjs/builders/objects/utils.js +23 -0
- package/dist/cjs/builders/origin-browser.js +28 -0
- package/dist/cjs/builders/origin-node.js +29 -0
- package/dist/cjs/builders/origin.js +23 -0
- package/dist/cjs/builders/provider.js +24 -0
- package/dist/cjs/builders/session-browser.js +97 -0
- package/dist/cjs/builders/session-node.js +9 -0
- package/dist/cjs/builders/session.js +23 -0
- package/dist/cjs/builders/tracker-browser.js +34 -0
- package/dist/cjs/builders/tracker-node.js +22 -0
- package/dist/cjs/builders/trackerBuilder.js +23 -0
- package/dist/cjs/config-browser.js +26 -0
- package/dist/cjs/config.js +9 -0
- package/dist/cjs/createPulseTracker.js +50 -0
- package/dist/cjs/defer.js +20 -0
- package/dist/cjs/getPulseTracker.js +74 -0
- package/dist/cjs/identity/actor.js +60 -0
- package/dist/cjs/identity/advertising.js +62 -0
- package/dist/cjs/identity/cis.js +66 -0
- package/dist/cjs/identity/device.js +20 -0
- package/dist/cjs/identity/index.js +20 -0
- package/dist/cjs/index.js +57 -0
- package/dist/cjs/leaveTracking/constants.js +26 -0
- package/dist/cjs/leaveTracking/index.js +368 -0
- package/dist/cjs/leaveTracking/types.js +19 -0
- package/dist/cjs/leaveTrackingTpaas/constants.js +18 -0
- package/dist/cjs/leaveTrackingTpaas/index.js +341 -0
- package/dist/cjs/leaveTrackingTpaas/types.js +19 -0
- package/dist/cjs/network-browser.js +35 -0
- package/dist/cjs/network.js +15 -0
- package/dist/cjs/remoteConfig/index.js +124 -0
- package/dist/cjs/tracker-proxy/consts.js +72 -0
- package/dist/cjs/tracker-proxy/proxy-provider.js +68 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/version.json +1 -0
- package/dist/cjs/visibility-observer/index.js +101 -0
- package/dist/cjs/warnOnce.js +11 -0
- package/dist/cjs/wrapper/engagement/ui-element/event-builder.js +21 -0
- package/dist/cjs/wrapper/engagement/ui-element/types.js +2 -0
- package/dist/cjs/wrapper/types/base-event.js +2 -0
- package/dist/cjs/wrapper/types/engagement-event.js +2 -0
- package/dist/cjs/wrapper/types/event.js +2 -0
- package/dist/cjs/wrapper/types/index.js +19 -0
- package/dist/cjs/wrapper/types/utils.js +2 -0
- package/dist/cjs/wrapper/utils/get-navigation-type.js +32 -0
- package/dist/cjs/wrapper/utils/page-from-page-view.js +9 -0
- package/dist/cjs/wrapper/view/article/event-builder.js +19 -0
- package/dist/cjs/wrapper/view/article/types.js +2 -0
- package/dist/cjs/wrapper/view/frontpage/event-builder.js +16 -0
- package/dist/cjs/wrapper/view/frontpage/types.js +2 -0
- package/dist/cjs/wrapper/view/listing/event-builder.js +14 -0
- package/dist/cjs/wrapper/view/listing/types.js +2 -0
- package/dist/cjs/wrapper/view/loginposter/event-builder.js +11 -0
- package/dist/cjs/wrapper/view/loginposter/types.js +2 -0
- package/dist/cjs/wrapper/view/page/event-builder.js +18 -0
- package/dist/cjs/wrapper/view/page/types.js +2 -0
- package/dist/cjs/wrapper/view/salesposter/event-builder.js +18 -0
- package/dist/cjs/wrapper/view/salesposter/types.js +2 -0
- package/dist/cjs/wrapper/view/ui-element/event-builder.js +15 -0
- package/dist/cjs/wrapper/view/ui-element/types.js +2 -0
- package/dist/ejs/EventBus/EventBus.js +140 -0
- package/dist/ejs/Tracker.js +2455 -0
- package/dist/ejs/Tracker.test-d.js +71 -0
- package/dist/ejs/app-integration.js +33 -0
- package/dist/ejs/builders/actor.js +53 -0
- package/dist/ejs/builders/consent-manager.js +125 -0
- package/dist/ejs/builders/consents.js +138 -0
- package/dist/ejs/builders/device-browser.js +69 -0
- package/dist/ejs/builders/device-node.js +57 -0
- package/dist/ejs/builders/device.js +2 -0
- package/dist/ejs/builders/events-anonymous-browser.js +1 -0
- package/dist/ejs/builders/events-anonymous-node.js +48 -0
- package/dist/ejs/builders/events-anonymous.js +1 -0
- package/dist/ejs/builders/events-browser.js +1 -0
- package/dist/ejs/builders/events-node.js +84 -0
- package/dist/ejs/builders/events.js +1 -0
- package/dist/ejs/builders/experimentMetadata.js +21 -0
- package/dist/ejs/builders/experiments.js +27 -0
- package/dist/ejs/builders/index.js +12 -0
- package/dist/ejs/builders/location.js +34 -0
- package/dist/ejs/builders/objects/objects-anonymous-browser.js +14 -0
- package/dist/ejs/builders/objects/objects-anonymous-node.js +90 -0
- package/dist/ejs/builders/objects/objects-anonymous.js +2 -0
- package/dist/ejs/builders/objects/objects-browser.js +14 -0
- package/dist/ejs/builders/objects/objects-node.js +121 -0
- package/dist/ejs/builders/objects/objects.js +2 -0
- package/dist/ejs/builders/objects/utils.js +20 -0
- package/dist/ejs/builders/origin-browser.js +6 -0
- package/dist/ejs/builders/origin-node.js +24 -0
- package/dist/ejs/builders/origin.js +2 -0
- package/dist/ejs/builders/provider.js +18 -0
- package/dist/ejs/builders/session-browser.js +90 -0
- package/dist/ejs/builders/session-node.js +4 -0
- package/dist/ejs/builders/session.js +2 -0
- package/dist/ejs/builders/tracker-browser.js +13 -0
- package/dist/ejs/builders/tracker-node.js +14 -0
- package/dist/ejs/builders/trackerBuilder.js +2 -0
- package/dist/ejs/config-browser.js +23 -0
- package/dist/ejs/config.js +6 -0
- package/dist/ejs/createPulseTracker.js +44 -0
- package/dist/ejs/defer.js +17 -0
- package/dist/ejs/getPulseTracker.js +71 -0
- package/dist/ejs/identity/actor.js +51 -0
- package/dist/ejs/identity/advertising.js +57 -0
- package/dist/ejs/identity/cis.js +58 -0
- package/dist/ejs/identity/device.js +17 -0
- package/dist/ejs/identity/index.js +4 -0
- package/dist/ejs/index.js +9 -0
- package/dist/ejs/leaveTracking/constants.js +19 -0
- package/dist/ejs/leaveTracking/index.js +319 -0
- package/dist/ejs/leaveTracking/types.js +16 -0
- package/dist/ejs/leaveTrackingTpaas/constants.js +13 -0
- package/dist/ejs/leaveTrackingTpaas/index.js +291 -0
- package/dist/ejs/leaveTrackingTpaas/types.js +16 -0
- package/dist/ejs/network-browser.js +32 -0
- package/dist/ejs/network.js +12 -0
- package/dist/ejs/remoteConfig/index.js +111 -0
- package/dist/ejs/tracker-proxy/consts.js +68 -0
- package/dist/ejs/tracker-proxy/proxy-provider.js +62 -0
- package/dist/ejs/types.js +1 -0
- package/dist/ejs/version.json +1 -0
- package/dist/ejs/visibility-observer/index.js +97 -0
- package/dist/ejs/warnOnce.js +9 -0
- package/dist/ejs/wrapper/engagement/ui-element/event-builder.js +17 -0
- package/dist/ejs/wrapper/engagement/ui-element/types.js +1 -0
- package/dist/ejs/wrapper/types/base-event.js +1 -0
- package/dist/ejs/wrapper/types/engagement-event.js +1 -0
- package/dist/ejs/wrapper/types/event.js +1 -0
- package/dist/ejs/wrapper/types/index.js +3 -0
- package/dist/ejs/wrapper/types/utils.js +1 -0
- package/dist/ejs/wrapper/utils/get-navigation-type.js +29 -0
- package/dist/ejs/wrapper/utils/page-from-page-view.js +6 -0
- package/dist/ejs/wrapper/view/article/event-builder.js +15 -0
- package/dist/ejs/wrapper/view/article/types.js +1 -0
- package/dist/ejs/wrapper/view/frontpage/event-builder.js +12 -0
- package/dist/ejs/wrapper/view/frontpage/types.js +1 -0
- package/dist/ejs/wrapper/view/listing/event-builder.js +10 -0
- package/dist/ejs/wrapper/view/listing/types.js +1 -0
- package/dist/ejs/wrapper/view/loginposter/event-builder.js +7 -0
- package/dist/ejs/wrapper/view/loginposter/types.js +1 -0
- package/dist/ejs/wrapper/view/page/event-builder.js +14 -0
- package/dist/ejs/wrapper/view/page/types.js +1 -0
- package/dist/ejs/wrapper/view/salesposter/event-builder.js +14 -0
- package/dist/ejs/wrapper/view/salesposter/types.js +1 -0
- package/dist/ejs/wrapper/view/ui-element/event-builder.js +11 -0
- package/dist/ejs/wrapper/view/ui-element/types.js +1 -0
- package/dist/types/EventBus/EventBus.d.ts +106 -0
- package/dist/types/Tracker.d.ts +1418 -0
- package/dist/types/Tracker.test-d.d.ts +1 -0
- package/dist/types/app-integration.d.ts +10 -0
- package/dist/types/builders/actor.d.ts +39 -0
- package/dist/types/builders/consent-manager.d.ts +49 -0
- package/dist/types/builders/consents.d.ts +107 -0
- package/dist/types/builders/device-browser.d.ts +6 -0
- package/dist/types/builders/device-node.d.ts +65 -0
- package/dist/types/builders/device.d.ts +2 -0
- package/dist/types/builders/events-anonymous-browser.d.ts +1 -0
- package/dist/types/builders/events-anonymous-node.d.ts +82 -0
- package/dist/types/builders/events-anonymous.d.ts +1 -0
- package/dist/types/builders/events-browser.d.ts +1 -0
- package/dist/types/builders/events-node.d.ts +130 -0
- package/dist/types/builders/events.d.ts +1 -0
- package/dist/types/builders/experimentMetadata.d.ts +25 -0
- package/dist/types/builders/experiments.d.ts +24 -0
- package/dist/types/builders/index.d.ts +23 -0
- package/dist/types/builders/location.d.ts +34 -0
- package/dist/types/builders/objects/objects-anonymous-browser.d.ts +11 -0
- package/dist/types/builders/objects/objects-anonymous-node.d.ts +52 -0
- package/dist/types/builders/objects/objects-anonymous.d.ts +2 -0
- package/dist/types/builders/objects/objects-browser.d.ts +11 -0
- package/dist/types/builders/objects/objects-node.d.ts +60 -0
- package/dist/types/builders/objects/objects.d.ts +2 -0
- package/dist/types/builders/objects/utils.d.ts +1 -0
- package/dist/types/builders/origin-browser.d.ts +5 -0
- package/dist/types/builders/origin-node.d.ts +18 -0
- package/dist/types/builders/origin.d.ts +2 -0
- package/dist/types/builders/provider.d.ts +14 -0
- package/dist/types/builders/session-browser.d.ts +20 -0
- package/dist/types/builders/session-node.d.ts +3 -0
- package/dist/types/builders/session.d.ts +2 -0
- package/dist/types/builders/tracker-browser.d.ts +2 -0
- package/dist/types/builders/tracker-node.d.ts +14 -0
- package/dist/types/builders/trackerBuilder.d.ts +2 -0
- package/dist/types/config-browser.d.ts +23 -0
- package/dist/types/config.d.ts +6 -0
- package/dist/types/createPulseTracker.d.ts +21 -0
- package/dist/types/defer.d.ts +28 -0
- package/dist/types/getPulseTracker.d.ts +59 -0
- package/dist/types/identity/actor.d.ts +28 -0
- package/dist/types/identity/advertising.d.ts +30 -0
- package/dist/types/identity/cis.d.ts +21 -0
- package/dist/types/identity/device.d.ts +12 -0
- package/dist/types/identity/index.d.ts +4 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/leaveTracking/constants.d.ts +26 -0
- package/dist/types/leaveTracking/index.d.ts +23 -0
- package/dist/types/leaveTracking/types.d.ts +78 -0
- package/dist/types/leaveTrackingTpaas/constants.d.ts +13 -0
- package/dist/types/leaveTrackingTpaas/index.d.ts +28 -0
- package/dist/types/leaveTrackingTpaas/types.d.ts +45 -0
- package/dist/types/network-browser.d.ts +5 -0
- package/dist/types/network.d.ts +4 -0
- package/dist/types/remoteConfig/index.d.ts +32 -0
- package/dist/types/tracker-proxy/consts.d.ts +45 -0
- package/dist/types/tracker-proxy/proxy-provider.d.ts +2 -0
- package/dist/types/types.d.ts +93 -0
- package/dist/types/visibility-observer/index.d.ts +38 -0
- package/dist/types/warnOnce.d.ts +2 -0
- package/dist/types/wrapper/engagement/ui-element/event-builder.d.ts +3 -0
- package/dist/types/wrapper/engagement/ui-element/types.d.ts +29 -0
- package/dist/types/wrapper/types/base-event.d.ts +74 -0
- package/dist/types/wrapper/types/engagement-event.d.ts +5 -0
- package/dist/types/wrapper/types/event.d.ts +41 -0
- package/dist/types/wrapper/types/index.d.ts +3 -0
- package/dist/types/wrapper/types/utils.d.ts +5 -0
- package/dist/types/wrapper/utils/get-navigation-type.d.ts +3 -0
- package/dist/types/wrapper/utils/page-from-page-view.d.ts +3 -0
- package/dist/types/wrapper/view/article/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/article/types.d.ts +27 -0
- package/dist/types/wrapper/view/frontpage/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/frontpage/types.d.ts +18 -0
- package/dist/types/wrapper/view/listing/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/listing/types.d.ts +27 -0
- package/dist/types/wrapper/view/loginposter/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/loginposter/types.d.ts +14 -0
- package/dist/types/wrapper/view/page/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/page/types.d.ts +16 -0
- package/dist/types/wrapper/view/salesposter/event-builder.d.ts +2 -0
- package/dist/types/wrapper/view/salesposter/types.d.ts +15 -0
- package/dist/types/wrapper/view/ui-element/event-builder.d.ts +3 -0
- package/dist/types/wrapper/view/ui-element/types.d.ts +28 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.d.ts +26 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.js +273 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis-browser.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis.d.ts +10 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis.js +7 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/cis.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/eventEmitter.d.ts +14 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/eventEmitter.js +39 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/eventEmitter.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/index.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/index.js +12 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/index.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/pulse-cookie.d.ts +55 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/pulse-cookie.js +276 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/pulse-cookie.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.d.ts +36 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.js +87 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/pulseStorage.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.d.ts +6 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.js +21 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/storage/storage.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/types.d.ts +24 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/types.js +3 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/cjs/types.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.d.ts +26 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.js +203 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis-browser.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis.d.ts +10 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis.js +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/cis.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/eventEmitter.d.ts +14 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/eventEmitter.js +35 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/eventEmitter.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/index.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/index.js +3 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/index.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/pulse-cookie.d.ts +55 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/pulse-cookie.js +254 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/pulse-cookie.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.d.ts +36 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.js +50 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/pulseStorage.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.d.ts +6 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.js +17 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/storage/storage.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/types.d.ts +24 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/types.js +2 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/ejs/types.js.map +1 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/cis-browser.d.ts +26 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/cis.d.ts +10 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/eventEmitter.d.ts +14 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/index.d.ts +4 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/pulse-cookie.d.ts +55 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/storage/pulseStorage.d.ts +36 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/storage/storage.d.ts +6 -0
- package/node_modules/@schibsted/pulse-cis-sync/dist/types/types.d.ts +24 -0
- package/node_modules/@schibsted/pulse-cis-sync/package.json +44 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/cookie-config.js +10 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/cookie.js +86 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/events.js +109 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/get.js +18 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/getRootDomain.js +54 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/index.js +38 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/merge.js +38 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/objects.js +34 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/omit.js +9 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/randomString.js +18 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/throttle.js +34 -0
- package/node_modules/@schibsted/pulse-utils/dist/cjs/webApi.js +21 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/cookie-config.js +7 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/cookie.js +81 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/events.js +103 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/get.js +15 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/getRootDomain.js +49 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/index.js +11 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/merge.js +35 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/objects.js +26 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/omit.js +6 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/randomString.js +15 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/throttle.js +31 -0
- package/node_modules/@schibsted/pulse-utils/dist/ejs/webApi.js +17 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/cookie-config.d.ts +7 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/cookie.d.ts +23 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/events.d.ts +17 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/get.d.ts +1 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/getRootDomain.d.ts +13 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/index.d.ts +11 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/merge.d.ts +4 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/objects.d.ts +6 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/omit.d.ts +3 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/randomString.d.ts +1 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/throttle.d.ts +3 -0
- package/node_modules/@schibsted/pulse-utils/dist/types/webApi.d.ts +10 -0
- package/node_modules/@schibsted/pulse-utils/package.json +36 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/anonymous.js +8 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/baseEvent.js +9 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/consents.js +15 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/device.js +211 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/experiments.js +11 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/navigationType.js +52 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/pageInfo.js +24 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/pageviewId.js +11 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/provider.js +12 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/referrer.js +19 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/session.js +114 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/time.js +15 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/trackerBuilder.js +15 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/user.js +26 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders/utm.js +35 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/builders.js +264 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/index.js +17 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/cjs/types.js +2 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/anonymous.js +5 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/baseEvent.js +6 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/consents.js +12 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/device.js +174 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/experiments.js +7 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/navigationType.js +48 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/pageInfo.js +20 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/pageviewId.js +7 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/provider.js +9 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/referrer.js +15 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/session.js +108 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/time.js +11 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/trackerBuilder.js +11 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/user.js +22 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders/utm.js +31 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/builders.js +209 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/index.js +1 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/ejs/types.js +1 -0
- package/node_modules/@schibsted/tpaas-event-builder/dist/index.d.ts +5171 -0
- package/node_modules/@schibsted/tpaas-event-builder/package.json +40 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/cjs/constants.js +62 -1
- package/node_modules/@schibsted/tpaas-schemas/dist/ejs/constants.js +61 -0
- package/node_modules/@schibsted/tpaas-schemas/dist/index.d.ts +128 -0
- package/package.json +58 -13
- package/CHANGELOG.md +0 -1035
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -47
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,2455 @@
|
|
|
1
|
+
import { parsePulseCookies } from '@schibsted/pulse-cis-sync';
|
|
2
|
+
import { evaluateAndFlatten, isBrowser, isFunction, isPromise, isString, pulseMerge, throttle, } from '@schibsted/pulse-utils';
|
|
3
|
+
import { buildAnonymousViewUIElementEvent, buildCompletedHealthActionEvent, buildEngagementAudioEvent, buildEngagementFormEvent, buildEngagementHealthUIElementEvent, buildEngagementOfferEvent, buildEngagementTeaserEvent, buildEngagementUIElementEvent, buildEngagementVideoAdEvent, buildEngagementVideoEvent, buildEngagementWidgetEvent, buildImpressionAdSlotEvent, buildImpressionFormEvent, buildImpressionHealthUIElementEvent, buildImpressionOfferEvent, buildImpressionPlayerEvent, buildImpressionTeaserEvent, buildImpressionUIElementEvent, buildImpressionWidgetEvent, buildLeaveArticleEvent, buildLeaveAudioPageEvent, buildLeaveErrorEvent, buildLeaveFrontpageEvent, buildLeaveLandingpageEvent, buildLeaveListingEvent, buildLeaveLockedArticleEvent, buildLeaveLockedAudioEvent, buildLeaveLockedAudioPageEvent, buildLeaveLockedVideoEvent, buildLeaveLockedVideoPageEvent, buildLeavePageEvent, buildLeaveVideoPageEvent, buildLeaveWeatherEvent, buildViewArticleEvent, buildViewAudioEvent, buildViewAudioPageEvent, buildViewErrorEvent, buildViewFrontpageEvent, buildViewHealthPageEvent, buildViewLandingpageEvent, buildViewListingEvent, buildViewLockedArticleEvent, buildViewLockedAudioEvent, buildViewLockedAudioPageEvent, buildViewLockedVideoEvent, buildViewLockedVideoPageEvent, buildViewPageEvent, buildViewTitleEvent, buildViewVideoEvent, buildViewVideoPageEvent, buildViewWeatherEvent, getCommonBuildersOutput, } from '@schibsted/tpaas-event-builder';
|
|
4
|
+
import { LeaveArticle, LeaveAudioPage, LeaveError, LeaveFrontpage, LeaveLandingpage, LeaveListing, LeaveLockedArticle, LeaveLockedAudioPage, LeaveLockedVideoPage, LeavePage, LeaveVideoPage, LeaveWeather, ViewArticle, ViewError, ViewFrontpage, ViewListing, ViewLockedArticle, ViewLockedVideo, ViewPage, ViewTitle, } from '@schibsted/tpaas-schemas';
|
|
5
|
+
import logger from 'loglevel';
|
|
6
|
+
import { v4 } from 'uuid';
|
|
7
|
+
import { getDefaultAltHandler, getDefaultNativeJwe } from './app-integration';
|
|
8
|
+
import { provider, session as sessionBuilder } from './builders';
|
|
9
|
+
import { getConsentsWaitForAnalytics, getFallbackConsents } from './builders/consent-manager';
|
|
10
|
+
import { applyAdvertisingConsent, applyAdvertisingConsentSync, } from './builders/consents';
|
|
11
|
+
import { engagementEvent, identityEvent, routableEvent, trackerEvent } from './builders/events';
|
|
12
|
+
import { anonymousEngagementEvent, anonymousTrackerEvent } from './builders/events-anonymous-node';
|
|
13
|
+
import { readSession } from './builders/session-browser';
|
|
14
|
+
import { baseConfig as defaultConfig } from './config';
|
|
15
|
+
import { CISEndpoints, collectorEndpoints, remoteConfig } from './config-browser';
|
|
16
|
+
import defer from './defer';
|
|
17
|
+
import { createEventBus } from './EventBus/EventBus';
|
|
18
|
+
import * as identity from './identity';
|
|
19
|
+
import { addPageLeaveTracking, leaveTrackingIsActive, removePageLeaveTracking, resetViewedContent, trackActivePageLeave, trackPageLeave, updatePageLeaveEvent, updatePageLeaveTracking, updateViewedContent, } from './leaveTracking';
|
|
20
|
+
import { addTpaasLeaveTracking, getTpaasLeaveObject, leaveTpaasTrackingIsActive, resetTpaasViewedContent, shouldEnableLeaveTracking, trackTpaasActiveLeave, updateTpaasLeaveTracking, updateTpaasViewedContent, } from './leaveTrackingTpaas';
|
|
21
|
+
import send from './network';
|
|
22
|
+
import * as config from './remoteConfig';
|
|
23
|
+
import { startProxyProviderListener } from './tracker-proxy/proxy-provider';
|
|
24
|
+
import version from './version.json';
|
|
25
|
+
import { VisibilityObserver } from './visibility-observer';
|
|
26
|
+
import warnOnce from './warnOnce';
|
|
27
|
+
import { buildClickUIElementEvent } from './wrapper/engagement/ui-element/event-builder';
|
|
28
|
+
import { pageFromPageView } from './wrapper/utils/page-from-page-view';
|
|
29
|
+
import { buildLegacyViewArticleEvent } from './wrapper/view/article/event-builder';
|
|
30
|
+
import { buildLegacyViewFrontpageEvent } from './wrapper/view/frontpage/event-builder';
|
|
31
|
+
import { buildLegacyViewListingEvent } from './wrapper/view/listing/event-builder';
|
|
32
|
+
import { buildViewLoginPosterEvent } from './wrapper/view/loginposter/event-builder';
|
|
33
|
+
import { buildLegacyViewPageEvent } from './wrapper/view/page/event-builder';
|
|
34
|
+
import { buildViewSalesPosterEvent } from './wrapper/view/salesposter/event-builder';
|
|
35
|
+
import { buildLegacyViewUIElementEvent } from './wrapper/view/ui-element/event-builder';
|
|
36
|
+
const { generateProviderSDRN: providerSdrn } = provider;
|
|
37
|
+
/**
|
|
38
|
+
* Event Builder lookup
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
const events = {
|
|
42
|
+
identity: identityEvent,
|
|
43
|
+
trackerEvent: trackerEvent,
|
|
44
|
+
engagementEvent: engagementEvent,
|
|
45
|
+
routableEvent: routableEvent,
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* @typeParam T Type of event to track
|
|
49
|
+
* @param name
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
function getEventBuilder(name) {
|
|
53
|
+
return name in events ? events[name] : events.trackerEvent;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Event Builder lookup for anonymous events
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
const anonymousEvents = {
|
|
60
|
+
trackerEvent: anonymousTrackerEvent,
|
|
61
|
+
engagementEvent: anonymousEngagementEvent,
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* @typeParam T Type of event to track
|
|
65
|
+
* @param name
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
function getAnonymousEventBuilder(name) {
|
|
69
|
+
return name in anonymousEvents ? anonymousEvents[name] : anonymousEvents.trackerEvent;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Determines if the SDK is running in a Hybrid (WebView) environment.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
*
|
|
76
|
+
* Historically, we have detected the presence of "nativeJwe" config coming from the native app to flag that setup.
|
|
77
|
+
* Additionally, a config param can be passed to explicitly indicate that the tracker was initialised in a mobile WebView.
|
|
78
|
+
*
|
|
79
|
+
* @param config {SDKConfigInput}
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
const isHybrid = (config) => Boolean(config?.isHybrid) || Boolean(config?.nativeJwe);
|
|
83
|
+
/**
|
|
84
|
+
* @internal
|
|
85
|
+
* Used to register whether the Collector and CIS base urls are set in the config params, before the state is populated
|
|
86
|
+
* with the default values.
|
|
87
|
+
*/
|
|
88
|
+
let isCollectorInConfig = false;
|
|
89
|
+
let isCisInConfig = false;
|
|
90
|
+
/**
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
export const BookmarkKeys = {
|
|
94
|
+
PAGE_VIEW: 'page-view',
|
|
95
|
+
};
|
|
96
|
+
const eventBus = createEventBus({
|
|
97
|
+
namespace: 'pulse',
|
|
98
|
+
domBridge: true,
|
|
99
|
+
preventBridgeEcho: true,
|
|
100
|
+
});
|
|
101
|
+
export function subscribe(eventName, callback) {
|
|
102
|
+
return eventBus.on(eventName, callback);
|
|
103
|
+
}
|
|
104
|
+
export function subscribeOnce(eventName, callback) {
|
|
105
|
+
return eventBus.once(eventName, callback);
|
|
106
|
+
}
|
|
107
|
+
export function subscribeWithState(eventName, callback) {
|
|
108
|
+
return eventBus.onWithState(eventName, callback);
|
|
109
|
+
}
|
|
110
|
+
export function unsubscribe(eventName, callback) {
|
|
111
|
+
eventBus.off(eventName, callback);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @class Tracker
|
|
115
|
+
*/
|
|
116
|
+
export default class Tracker {
|
|
117
|
+
/**
|
|
118
|
+
* > [!WARNING]
|
|
119
|
+
* >
|
|
120
|
+
* > For legacy reasons the `providerId` parameter is called so, but it is actually the
|
|
121
|
+
* > `CLIENT-ID` of the site or app.
|
|
122
|
+
* > Do not mix it up with a full `SDRN` Provider ID. Ex:<br/>
|
|
123
|
+
* > * `PROVIDER-ID` = `sdrn:schibsted:client:my-client-id`<br/>
|
|
124
|
+
* > * `CLIENT-ID` = `my-client-id` = `config.providerId`
|
|
125
|
+
*
|
|
126
|
+
* @param providerId `CLIENT-ID` of the site or app.
|
|
127
|
+
* @param config Options to set the SDK with
|
|
128
|
+
* @param builders Initial values for event properties that will be persisted across events
|
|
129
|
+
*/
|
|
130
|
+
constructor(providerId, config, builders) {
|
|
131
|
+
// we have separated observers for legacy and tpaas events in order to allow
|
|
132
|
+
// the tracking of the same element with both old and new events at the same time
|
|
133
|
+
this.legacyVisibilityObservers = new Map();
|
|
134
|
+
this.visibilityObservers = new Map();
|
|
135
|
+
this.legacyCurrentPage = {
|
|
136
|
+
id: 'undefined-id',
|
|
137
|
+
type: 'Page',
|
|
138
|
+
url: typeof window !== 'undefined' ? window.location.href : '',
|
|
139
|
+
};
|
|
140
|
+
this.currentPage = undefined;
|
|
141
|
+
/**
|
|
142
|
+
* Promise that resolves when a session ID becomes available
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
this.sessionIdPromise = null;
|
|
146
|
+
this.setPageDefaults = (pageViewEvent) => {
|
|
147
|
+
this.legacyCurrentPage = pageFromPageView(pageViewEvent);
|
|
148
|
+
if (pageViewEvent.origin) {
|
|
149
|
+
const pageDefaults = { origin: pageViewEvent.origin };
|
|
150
|
+
this.update(pageDefaults, true);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
this.setCurrentPage = (id, type) => {
|
|
154
|
+
this.currentPage = {
|
|
155
|
+
pageId: id,
|
|
156
|
+
pageType: type,
|
|
157
|
+
url: isBrowser ? window.location.href : undefined,
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
logger.setLevel(config?.logLevel ?? logger.levels.ERROR);
|
|
161
|
+
// runtime check for providerId inconsistency
|
|
162
|
+
if (!providerId || !(typeof providerId === 'string')) {
|
|
163
|
+
throw new Error('Required parameter `providerId` missing');
|
|
164
|
+
}
|
|
165
|
+
let includeAdvertising;
|
|
166
|
+
if (isBrowser && config?.autoCreateConsents) {
|
|
167
|
+
config.consents = getConsentsWaitForAnalytics((consents) => {
|
|
168
|
+
logger.debug('Consents received from CMP', consents);
|
|
169
|
+
return this.setConsentsInternal(consents);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (isPromise(config?.consents)) {
|
|
173
|
+
includeAdvertising = applyAdvertisingConsent(config?.consents, config?.requireAdvertisingOptIn);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
includeAdvertising = applyAdvertisingConsentSync(config?.consents, config?.requireAdvertisingOptIn);
|
|
177
|
+
}
|
|
178
|
+
// TODO: this check should not be necessary. The config should be mandatory as a type, fix it in the future
|
|
179
|
+
if (config) {
|
|
180
|
+
config.nativeJwe = getDefaultNativeJwe(config);
|
|
181
|
+
config.altEventHandler = getDefaultAltHandler(config);
|
|
182
|
+
}
|
|
183
|
+
isCisInConfig = Boolean(config?.cisBaseUrl);
|
|
184
|
+
isCollectorInConfig = Boolean(config?.collectorBaseUrl);
|
|
185
|
+
identity.clearCookieJweIfStale(config?.nativeJwe);
|
|
186
|
+
const deployStage = config?.deployStage || 'pro';
|
|
187
|
+
const deployStageTpaas = config?.deployStageTpaas || 'pre';
|
|
188
|
+
this.state = pulseMerge({}, defaultConfig, {
|
|
189
|
+
collectorBaseUrl: collectorEndpoints[deployStage],
|
|
190
|
+
deployStage,
|
|
191
|
+
deployStageTpaas,
|
|
192
|
+
fallbackCisBaseUrl: CISEndpoints[deployStage],
|
|
193
|
+
fallbackCollectorBaseUrl: collectorEndpoints[deployStage],
|
|
194
|
+
includeAdvertising,
|
|
195
|
+
isHybrid: isHybrid(config),
|
|
196
|
+
pageViewId: v4(),
|
|
197
|
+
providerId,
|
|
198
|
+
remoteConfigurationUrl: remoteConfig[deployStage],
|
|
199
|
+
schemaLocation: 'schema.schibsted.com',
|
|
200
|
+
tpaasCollectorBaseUrl: collectorEndpoints[deployStageTpaas],
|
|
201
|
+
trackerId: v4(),
|
|
202
|
+
vendors: config?.vendors?.length ? [] : ['xandr'],
|
|
203
|
+
}, config);
|
|
204
|
+
// Move to default config?
|
|
205
|
+
this.builders = pulseMerge({}, builders, {
|
|
206
|
+
provider: {
|
|
207
|
+
id: providerId,
|
|
208
|
+
},
|
|
209
|
+
tracker: {
|
|
210
|
+
version: version.SDK_VERSION,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
this.bookmark = new Map();
|
|
214
|
+
// Replace with a linked list of Promises?
|
|
215
|
+
this.eventQueue = [];
|
|
216
|
+
this.retryEventQueue = [];
|
|
217
|
+
this.tpaasEventQueue = [];
|
|
218
|
+
this.anonymousEventQueue = [];
|
|
219
|
+
this.retryAnonymousEventQueue = [];
|
|
220
|
+
this.retryTpaasEventQueue = [];
|
|
221
|
+
if (this.state.environment === 'browser') {
|
|
222
|
+
// @ts-expect-error
|
|
223
|
+
if (isBrowser && window.navigator?.sendBeacon) {
|
|
224
|
+
const originalUseBeacon = this.state.useBeacon;
|
|
225
|
+
window.addEventListener('pagehide', () => {
|
|
226
|
+
this.state.useBeacon = true;
|
|
227
|
+
this._sendImmediately().then(() => {
|
|
228
|
+
void 0;
|
|
229
|
+
});
|
|
230
|
+
}, { capture: true });
|
|
231
|
+
window.addEventListener('pageshow', () => {
|
|
232
|
+
this.state.useBeacon = originalUseBeacon;
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// @ts-expect-error
|
|
237
|
+
this.debouncedSend = throttle(async () => {
|
|
238
|
+
try {
|
|
239
|
+
return await this._sendImmediately();
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
return err;
|
|
243
|
+
}
|
|
244
|
+
}, this.state.eventDebounce);
|
|
245
|
+
// @ts-expect-error
|
|
246
|
+
this.debouncedSendAnonymous = throttle(async () => {
|
|
247
|
+
try {
|
|
248
|
+
return await this._sendImmediatelyAnonymous();
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
return err;
|
|
252
|
+
}
|
|
253
|
+
}, this.state.eventDebounce);
|
|
254
|
+
// @ts-expect-error
|
|
255
|
+
this.debouncedSendTpaas = throttle(async () => {
|
|
256
|
+
try {
|
|
257
|
+
return await this._sendImmediatelyTpaas();
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
return err;
|
|
261
|
+
}
|
|
262
|
+
}, this.state.eventDebounce);
|
|
263
|
+
eventBus.emit('tracker:ready', { tracker: this });
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Add event to the tracker event queue
|
|
267
|
+
*
|
|
268
|
+
* The input can be objects, arrays, primitives or promises. The
|
|
269
|
+
* order of calls to the method is not guaranteed to be sent in the same
|
|
270
|
+
* sequence.
|
|
271
|
+
*
|
|
272
|
+
* ```
|
|
273
|
+
* tracker.track('trackerEvent', {
|
|
274
|
+
* actor: new Promise(resolve => setTimeout(() => resolve('person@example.org'), 2000))
|
|
275
|
+
* });
|
|
276
|
+
* tracker.track('trackerEvent', { type: 'Engagement '});
|
|
277
|
+
*
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* The second call to `track` will be added to the event queue before the
|
|
281
|
+
* first since all input to events are resolved before being added to the
|
|
282
|
+
* internal queue. Setting the future value in the SDK state will block all
|
|
283
|
+
* events and events will be added to the queue in order.
|
|
284
|
+
*
|
|
285
|
+
* ```
|
|
286
|
+
* tracker.update({
|
|
287
|
+
* actor: new Promise(resolve =>
|
|
288
|
+
* setTimeout(() => resolve('person@example.org'), 2000)) })
|
|
289
|
+
* tracker.track('trackerEvent', { type: 'View' });
|
|
290
|
+
* tracker.track('trackerEvent', { type: 'Engagement' });
|
|
291
|
+
* ```
|
|
292
|
+
*
|
|
293
|
+
* Both of these events will be blocked for two seconds and executed in order.
|
|
294
|
+
*
|
|
295
|
+
* @typeParam T Type of event to track
|
|
296
|
+
* @param eventType. See [spt-tracking/pulse-event-builders]() for
|
|
297
|
+
* available event types
|
|
298
|
+
* @param input. input input to the given event. The given input and the
|
|
299
|
+
* persisted input in the tracker will be merged before passing it to the event
|
|
300
|
+
* function.
|
|
301
|
+
* @param {TrackOptions} options
|
|
302
|
+
* @category Legacy Tracking
|
|
303
|
+
*/
|
|
304
|
+
track(eventType, input, options) {
|
|
305
|
+
const currentBuilders = { ...this.builders };
|
|
306
|
+
const _track = async (trackResponse) => {
|
|
307
|
+
const createdEvent = this.createEvent(input);
|
|
308
|
+
return this.evaluateEvent(eventType, createdEvent, currentBuilders, options).then(async (event) => {
|
|
309
|
+
if (options?.bookmarkKey) {
|
|
310
|
+
this.bookmark.set(options.bookmarkKey, event);
|
|
311
|
+
}
|
|
312
|
+
// if we have an alternative handler defined, send events there
|
|
313
|
+
// instead of pushing them onto the queue.
|
|
314
|
+
if (this.state.altEventHandler) {
|
|
315
|
+
const handler = this.state.altEventHandler;
|
|
316
|
+
handler(JSON.stringify(event));
|
|
317
|
+
return Promise.resolve(trackResponse);
|
|
318
|
+
}
|
|
319
|
+
const queuedEvent = this._push(event, options).then(() => void 0);
|
|
320
|
+
await this.send();
|
|
321
|
+
return queuedEvent.then((result) => result);
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
return this.syncRemoteResources(input, currentBuilders).then(_track, _track);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Add anonymous event to the tracker anonymous event queue
|
|
328
|
+
*
|
|
329
|
+
* The input can be objects, arrays, primitives or promises. The
|
|
330
|
+
* order of calls to the method is not guaranteed to be sent in the same
|
|
331
|
+
* sequence.
|
|
332
|
+
*
|
|
333
|
+
* ```
|
|
334
|
+
* tracker.trackAnonymous('trackerEvent', { type: 'Engagement'});
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* Anonymous events will not contain: `session`, `actor`, `device`, `location`, `pageViewId`.
|
|
338
|
+
*
|
|
339
|
+
* Anonymous events will always have the `isAnonymous` field set to true.
|
|
340
|
+
*
|
|
341
|
+
* Anonymous events will not await for consents. They will be applied if available, otherwise it will fall back to `unknown`.
|
|
342
|
+
*
|
|
343
|
+
* Considering the above, you should *not* add custom fields that can break anonymity.
|
|
344
|
+
*
|
|
345
|
+
* If you are missing consents, you're also not allowed to interact with storage or cookies for the purpose of these events.
|
|
346
|
+
* @typeParam T Type of event to track
|
|
347
|
+
* @param eventType.
|
|
348
|
+
* @param input. input input to the given event. The given input and the
|
|
349
|
+
* persisted input in the tracker will be merged before passing it to the event
|
|
350
|
+
* function.
|
|
351
|
+
* @param {TrackOptions} options
|
|
352
|
+
* @category Tracking Anonymous
|
|
353
|
+
*/
|
|
354
|
+
async trackAnonymous(eventType, input, options) {
|
|
355
|
+
// We must create the event as soon as possible, as it defines the creationDate.
|
|
356
|
+
const newEvent = this.createAnonymousEvent(input);
|
|
357
|
+
// Remote config values ----------------
|
|
358
|
+
await this._applyRemoteConfigEndpoints();
|
|
359
|
+
// Resolve all available properties ----------------
|
|
360
|
+
const resolvedOutput = await Promise.all([this.resolveTrackInput(newEvent), this.resolveTrackGlobals()]);
|
|
361
|
+
let eventOutput = resolvedOutput.reduce((acc, p) => pulseMerge(acc, p), {});
|
|
362
|
+
eventOutput = this.applyAnonymousEventTypeDefaults(eventOutput, eventType);
|
|
363
|
+
// Leave Events ----------------
|
|
364
|
+
// they require (most) properties of the previous PageView event, which was saved under a bookmark key when tracked
|
|
365
|
+
eventOutput = this.applyBookmarkedEvent(eventOutput, options?.applyBookmarkKey);
|
|
366
|
+
// TCF Consents ----------------
|
|
367
|
+
eventOutput = this.applyConsentsAnonymous(eventOutput);
|
|
368
|
+
// Build the entire event----------------
|
|
369
|
+
// Depending on the event type, like Tracker or Engagement.
|
|
370
|
+
eventOutput = getAnonymousEventBuilder(eventType)({
|
|
371
|
+
eventInput: eventOutput,
|
|
372
|
+
sdkConfig: this.state,
|
|
373
|
+
});
|
|
374
|
+
if (options?.bookmarkKey) {
|
|
375
|
+
this.bookmark.set(options.bookmarkKey, eventOutput);
|
|
376
|
+
}
|
|
377
|
+
// Dispatch ----------------
|
|
378
|
+
// The Hybrid use case implements a "bridged" event method, injected into the window scope,
|
|
379
|
+
// which is used to send events through the native app.
|
|
380
|
+
if (this.state.altEventHandler) {
|
|
381
|
+
this.state.altEventHandler(JSON.stringify(eventOutput));
|
|
382
|
+
return eventOutput;
|
|
383
|
+
}
|
|
384
|
+
const queuedEvent = this._pushAnonymous(eventOutput, options);
|
|
385
|
+
await this.sendAnonymous();
|
|
386
|
+
return queuedEvent;
|
|
387
|
+
}
|
|
388
|
+
async adaptExperiments(baseExperiments = []) {
|
|
389
|
+
return baseExperiments.map((exp) => {
|
|
390
|
+
return {
|
|
391
|
+
name: exp.name || exp.id,
|
|
392
|
+
variant: exp.variant || '',
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
*
|
|
398
|
+
* @private
|
|
399
|
+
* @category TPaaS Tracking
|
|
400
|
+
*/
|
|
401
|
+
async prepareAnonymousTpaasEvent() {
|
|
402
|
+
try {
|
|
403
|
+
await this._applyRemoteConfigEndpoints();
|
|
404
|
+
}
|
|
405
|
+
catch (ex) {
|
|
406
|
+
logger.trace('Failed to sync remote config', ex);
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
autoTrackerVersion: this.builders.tracker?.autoTrackerVersion,
|
|
410
|
+
version: version.SDK_VERSION,
|
|
411
|
+
isHybrid: !!this.state.isHybrid,
|
|
412
|
+
pageviewId: this.state.pageViewId,
|
|
413
|
+
providerId: this.state.providerId,
|
|
414
|
+
experiments: await this.adaptExperiments(this.builders.experiments),
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
*
|
|
419
|
+
* @private
|
|
420
|
+
* @category TPaaS Tracking
|
|
421
|
+
*/
|
|
422
|
+
async prepareTpaasEvent() {
|
|
423
|
+
try {
|
|
424
|
+
await this.syncRemoteResources(undefined, { ...this.builders });
|
|
425
|
+
}
|
|
426
|
+
catch (ex) {
|
|
427
|
+
logger.trace('Failed to sync remote resources', ex);
|
|
428
|
+
// remote config and CIS failures are also ignored for the old track() method. doing the same here
|
|
429
|
+
}
|
|
430
|
+
function adaptActorToNewFormat(actor) {
|
|
431
|
+
// this is a temporary solution to adapt the actor to the new format
|
|
432
|
+
// it should be removed once we have new methods in place to get the actor
|
|
433
|
+
if (!actor) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
return {
|
|
437
|
+
id: actor.id?.toString() || '',
|
|
438
|
+
realm: actor.realm || '',
|
|
439
|
+
hasAnySubscription: !!actor.hasAnySubscription,
|
|
440
|
+
region: isString(actor.region) ? actor.region : undefined,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function adaptConsentsToNewFormat(consents) {
|
|
444
|
+
if (!consents) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const { purposes, source } = consents;
|
|
448
|
+
const { CMP_ADVERTISING, CMP_ANALYTICS, CMP_MARKETING, CMP_PERSONALIZATION } = purposes;
|
|
449
|
+
function adaptStatusOrOptIn({ status, optIn }) {
|
|
450
|
+
// doing an unnecessary check for status here
|
|
451
|
+
// because otherwise the code after the switch will be marked as unreachable in the IDE
|
|
452
|
+
if (status) {
|
|
453
|
+
switch (status) {
|
|
454
|
+
case 'accepted':
|
|
455
|
+
return 'Accepted';
|
|
456
|
+
case 'rejected':
|
|
457
|
+
return 'Rejected';
|
|
458
|
+
case 'unknown':
|
|
459
|
+
return 'Unknown';
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (optIn === true) {
|
|
463
|
+
return 'Accepted';
|
|
464
|
+
}
|
|
465
|
+
if (optIn === false) {
|
|
466
|
+
return 'Rejected';
|
|
467
|
+
}
|
|
468
|
+
return 'Unknown';
|
|
469
|
+
}
|
|
470
|
+
return {
|
|
471
|
+
advertising: adaptStatusOrOptIn(CMP_ADVERTISING),
|
|
472
|
+
analytics: adaptStatusOrOptIn(CMP_ANALYTICS),
|
|
473
|
+
marketing: adaptStatusOrOptIn(CMP_MARKETING),
|
|
474
|
+
personalization: adaptStatusOrOptIn(CMP_PERSONALIZATION),
|
|
475
|
+
source: source || 'unknown',
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
const [actor, consents, experiments] = await Promise.all([
|
|
479
|
+
this.getActor(),
|
|
480
|
+
this.getConsents(),
|
|
481
|
+
this.adaptExperiments(this.builders.experiments),
|
|
482
|
+
]);
|
|
483
|
+
const { environmentId, jwe } = parsePulseCookies();
|
|
484
|
+
return {
|
|
485
|
+
autoTrackerVersion: this.builders.tracker?.autoTrackerVersion,
|
|
486
|
+
version: version.SDK_VERSION,
|
|
487
|
+
isHybrid: !!this.state.isHybrid,
|
|
488
|
+
user: adaptActorToNewFormat(actor),
|
|
489
|
+
consents: adaptConsentsToNewFormat(consents),
|
|
490
|
+
providerId: this.state.providerId,
|
|
491
|
+
pageviewId: this.state.pageViewId,
|
|
492
|
+
currentPage: this.currentPage,
|
|
493
|
+
experiments,
|
|
494
|
+
environmentId,
|
|
495
|
+
jwe,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Generate a generic TPaaS event with common builders output
|
|
500
|
+
* The method should be used for experiments, not for real production work.
|
|
501
|
+
* It doesn't have any real TPaaS schema associated with it.
|
|
502
|
+
* The method doesn't queue or send the event, it just returns the merged object.
|
|
503
|
+
* The method can be removed at any time in the future, so use it with caution.
|
|
504
|
+
*
|
|
505
|
+
* @param input - The input object to merge with the common builders output
|
|
506
|
+
* @returns A promise that resolves to the merged object
|
|
507
|
+
* @private
|
|
508
|
+
* @category TPaaS Tracking
|
|
509
|
+
*/
|
|
510
|
+
async generateGenericTpaasEvent(input) {
|
|
511
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
512
|
+
return pulseMerge({}, input, getCommonBuildersOutput(new Date(), dependencies));
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* This method extends the list of base experiments that will be automatically included in every event sent by the tracker.
|
|
516
|
+
*
|
|
517
|
+
* It accepts:
|
|
518
|
+
* - An array of experiments and/or promises resolving to the experiments
|
|
519
|
+
* - A Promise resolving to an array of experiments
|
|
520
|
+
*
|
|
521
|
+
* This allows to easily manage experiments without having to repeat them in every tracking call. For example:
|
|
522
|
+
*
|
|
523
|
+
* ```ts
|
|
524
|
+
* const experiments = [{ id: 'experiment-A', variant: 'blue-button' }];
|
|
525
|
+
*
|
|
526
|
+
* tracker.addExperiments(experiments);
|
|
527
|
+
* ```
|
|
528
|
+
|
|
529
|
+
Calling the method multiple times concatenates all given experiments and stores them as base experiments. Experiments can be either direct values or Promises, and they will be included in all future tracking events.
|
|
530
|
+
|
|
531
|
+
* @param experiments
|
|
532
|
+
* @category Tracking
|
|
533
|
+
*/
|
|
534
|
+
addExperiments(experiments) {
|
|
535
|
+
this.update({ experiments }, true);
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* The `addUIElementVisibilityTracking` function provides an interface for sending tracking events when specific UI elements become visible within the viewport.
|
|
539
|
+
* It is built on the `VisibilityObserver` class, which efficiently detects visibility changes in DOM elements.
|
|
540
|
+
* When an element becomes at least 2/3 visible, a callback is triggered to process the element and create a tracking event.
|
|
541
|
+
* It leverages the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) for viewport tracking
|
|
542
|
+
* and the [Mutation Observer API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to monitor lazy-loaded elements.
|
|
543
|
+
*
|
|
544
|
+
* Example usage:
|
|
545
|
+
*
|
|
546
|
+
* ```ts
|
|
547
|
+
* addUIElementVisibilityTracking('[data-pulse-entity-id]', (element) => {
|
|
548
|
+
* const target = createPulseTarget(element);
|
|
549
|
+
* const object = createPulseObject(element);
|
|
550
|
+
*
|
|
551
|
+
* return { object, target };
|
|
552
|
+
* });
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @param {string} selector - CSS selector for elements to track.
|
|
556
|
+
* @param {Function} buildEventFromElement - Function to build event object when element is visible.
|
|
557
|
+
* @deprecated This only works for legacy events. For TPaaS events, use `addUIElementVisibilityTracking` instead.
|
|
558
|
+
* @category Legacy Tracking
|
|
559
|
+
*/
|
|
560
|
+
addLegacyUIElementVisibilityTracking(selector, buildEventFromElement) {
|
|
561
|
+
if (this.legacyVisibilityObservers.has(selector)) {
|
|
562
|
+
console.warn(`Cannot add UI Element visibility tracking for selector "${selector}" as it is already being tracked.`);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
this.legacyVisibilityObservers.set(selector, new VisibilityObserver((element) => {
|
|
566
|
+
const viewUIElementInputProperties = buildEventFromElement(element);
|
|
567
|
+
this.trackLegacyViewUIElement(viewUIElementInputProperties);
|
|
568
|
+
}));
|
|
569
|
+
this.legacyVisibilityObservers.get(selector)?.observe(selector);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* The `addUIElementVisibilityTracking` function provides an interface for sending tracking events when specific UI elements become visible within the viewport.
|
|
573
|
+
* It is built on the `VisibilityObserver` class, which efficiently detects visibility changes in DOM elements.
|
|
574
|
+
* When an element becomes at least 2/3 visible, a callback is triggered to process the element and create a tracking event.
|
|
575
|
+
* It leverages the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) for viewport tracking
|
|
576
|
+
* and the [Mutation Observer API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to monitor lazy-loaded elements.
|
|
577
|
+
*
|
|
578
|
+
* Example usage:
|
|
579
|
+
*
|
|
580
|
+
* ```ts
|
|
581
|
+
* addUIElementVisibilityTracking('[data-pulse-entity-id]', (element) => {
|
|
582
|
+
* const eventInput = createEventInput(element);
|
|
583
|
+
*
|
|
584
|
+
* return eventInput;
|
|
585
|
+
* });
|
|
586
|
+
* ```
|
|
587
|
+
*
|
|
588
|
+
* @param {string} selector - CSS selector for elements to track.
|
|
589
|
+
* @param {Function} buildEventFromElement - Function to build event object when element is visible.
|
|
590
|
+
* @category Tracking
|
|
591
|
+
*/
|
|
592
|
+
addUIElementVisibilityTracking(selector, buildEventFromElement) {
|
|
593
|
+
if (this.visibilityObservers.has(selector)) {
|
|
594
|
+
console.warn(`Cannot add UI Element visibility tracking for selector "${selector}" as it is already being tracked.`);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
this.visibilityObservers.set(selector, new VisibilityObserver((element) => {
|
|
598
|
+
const eventInput = buildEventFromElement(element);
|
|
599
|
+
this.trackImpressionUIElement(eventInput);
|
|
600
|
+
}));
|
|
601
|
+
this.visibilityObservers.get(selector)?.observe(selector);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* The old trackViewArticle method from the Media Wrapper.
|
|
605
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
606
|
+
* will be stored and re-used across subsequent events.
|
|
607
|
+
*
|
|
608
|
+
* @param inputProperties
|
|
609
|
+
* @param trackOptions
|
|
610
|
+
* @category Legacy Tracking
|
|
611
|
+
*/
|
|
612
|
+
trackLegacyViewArticle(inputProperties, trackOptions) {
|
|
613
|
+
const viewArticleEventData = buildLegacyViewArticleEvent(inputProperties);
|
|
614
|
+
this.setPageDefaults(viewArticleEventData);
|
|
615
|
+
return this.trackPageView(viewArticleEventData, trackOptions);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* The old trackViewLoginPoster method from the Media Wrapper.
|
|
619
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
620
|
+
* will be stored and re-used across subsequent events.
|
|
621
|
+
*
|
|
622
|
+
* @param inputProperties
|
|
623
|
+
* @param trackOptions
|
|
624
|
+
* @category Legacy Tracking
|
|
625
|
+
*/
|
|
626
|
+
trackLegacyViewLoginPoster(inputProperties, trackOptions) {
|
|
627
|
+
const viewLoginPosterEventData = buildViewLoginPosterEvent(inputProperties);
|
|
628
|
+
this.setPageDefaults(viewLoginPosterEventData);
|
|
629
|
+
return this.trackPageView(viewLoginPosterEventData, trackOptions);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* The old trackViewSalesPoster method from the Media Wrapper.
|
|
633
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
634
|
+
* will be stored and re-used across subsequent events.
|
|
635
|
+
*
|
|
636
|
+
* @param inputProperties
|
|
637
|
+
* @param trackOptions
|
|
638
|
+
* @category Legacy Tracking
|
|
639
|
+
*/
|
|
640
|
+
trackLegacyViewSalesPoster(inputProperties, trackOptions) {
|
|
641
|
+
const viewSalesposterEventData = buildViewSalesPosterEvent(inputProperties);
|
|
642
|
+
this.setPageDefaults(viewSalesposterEventData);
|
|
643
|
+
return this.trackPageView(viewSalesposterEventData, trackOptions);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* The old trackViewListing method from the Media Wrapper.
|
|
647
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
648
|
+
* will be stored and re-used across subsequent events.
|
|
649
|
+
*
|
|
650
|
+
* @param inputProperties
|
|
651
|
+
* @param trackOptions
|
|
652
|
+
* @category Legacy Tracking
|
|
653
|
+
*/
|
|
654
|
+
trackLegacyViewListing(inputProperties, trackOptions) {
|
|
655
|
+
const viewListingEventData = buildLegacyViewListingEvent(inputProperties);
|
|
656
|
+
this.setPageDefaults(viewListingEventData);
|
|
657
|
+
return this.trackPageView(viewListingEventData, trackOptions);
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* The old trackViewFrontpage method from the Media Wrapper.
|
|
661
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
662
|
+
* will be stored and re-used across subsequent events.
|
|
663
|
+
*
|
|
664
|
+
* @param inputProperties
|
|
665
|
+
* @param trackOptions
|
|
666
|
+
* @category Legacy Tracking
|
|
667
|
+
*/
|
|
668
|
+
trackLegacyViewFrontpage(inputProperties, trackOptions) {
|
|
669
|
+
const viewFrontpageEventData = buildLegacyViewFrontpageEvent(inputProperties);
|
|
670
|
+
this.setPageDefaults(viewFrontpageEventData);
|
|
671
|
+
return this.trackPageView(viewFrontpageEventData, trackOptions);
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* The old trackViewPage method from the Media Wrapper.
|
|
675
|
+
* When triggering this page-view function, both the "page" object and "origin"
|
|
676
|
+
* will be stored and re-used across subsequent events.
|
|
677
|
+
*
|
|
678
|
+
* @param inputProperties
|
|
679
|
+
* @param trackOptions
|
|
680
|
+
* @category Legacy Tracking
|
|
681
|
+
*/
|
|
682
|
+
trackLegacyViewPage(inputProperties, trackOptions) {
|
|
683
|
+
const pageViewEventData = buildLegacyViewPageEvent(inputProperties);
|
|
684
|
+
this.setPageDefaults(pageViewEventData);
|
|
685
|
+
return this.trackPageView(pageViewEventData, trackOptions);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* The old trackViewUIElement method from the Media Wrapper.
|
|
689
|
+
*
|
|
690
|
+
* @param inputProperties
|
|
691
|
+
* @param trackOptions
|
|
692
|
+
* @category Legacy Tracking
|
|
693
|
+
*/
|
|
694
|
+
trackLegacyViewUIElement(inputProperties, trackOptions) {
|
|
695
|
+
const viewUIElementEventData = buildLegacyViewUIElementEvent(inputProperties, this.legacyCurrentPage);
|
|
696
|
+
return this.track('trackerEvent', viewUIElementEventData, trackOptions);
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* The old trackClickUIElement method from the Media Wrapper.
|
|
700
|
+
*
|
|
701
|
+
* @param inputProperties
|
|
702
|
+
* @param trackOptions
|
|
703
|
+
* @category Legacy Tracking
|
|
704
|
+
*/
|
|
705
|
+
trackLegacyClickUIElement(inputProperties, trackOptions) {
|
|
706
|
+
const clickUIElementEventData = buildClickUIElementEvent(inputProperties, this.legacyCurrentPage);
|
|
707
|
+
return this.track('trackerEvent', clickUIElementEventData, trackOptions);
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* The following methods are the track methods specific for the TPaaS schemas
|
|
711
|
+
*/
|
|
712
|
+
/**
|
|
713
|
+
* @param input
|
|
714
|
+
* @category TPaaS Tracking
|
|
715
|
+
*/
|
|
716
|
+
async trackAnonymousViewUIElement(input) {
|
|
717
|
+
const dependencies = await this.prepareAnonymousTpaasEvent();
|
|
718
|
+
const event = buildAnonymousViewUIElementEvent(input, dependencies);
|
|
719
|
+
return this.sendTpaasEvent(event);
|
|
720
|
+
}
|
|
721
|
+
async trackCompletedHealthAction(input) {
|
|
722
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
723
|
+
const event = buildCompletedHealthActionEvent(input, dependencies);
|
|
724
|
+
return this.sendTpaasEvent(event);
|
|
725
|
+
}
|
|
726
|
+
async trackEngagementHealthUIElement(input) {
|
|
727
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
728
|
+
const event = buildEngagementHealthUIElementEvent(input, dependencies);
|
|
729
|
+
return this.sendTpaasEvent(event);
|
|
730
|
+
}
|
|
731
|
+
async trackViewHealthPage(input, options) {
|
|
732
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
733
|
+
this.setCurrentPage(input.object.objectId, 'Page'); // ViewHealthPage.object.objectType is HealthPage, which is not allowed as a pageType
|
|
734
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
735
|
+
const event = buildViewHealthPageEvent(input, dependencies);
|
|
736
|
+
const result = this.sendTpaasEvent(event);
|
|
737
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
738
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
739
|
+
// HealthView Page is a bit special, in the sense that in doesn't have a dedicated Leave event.
|
|
740
|
+
// Instead, we need to reuse the generic Leave Page event, but adapt the input accordingly.
|
|
741
|
+
// This means omitting some fields from HealthView Page that are not part of Leave Page schema.
|
|
742
|
+
const { experiments, metrics, object, ...restInput } = input;
|
|
743
|
+
const { category, custom, intent, name, tags, ...restObject } = input.object;
|
|
744
|
+
const leavePageCallback = (leave) => {
|
|
745
|
+
this.trackLeavePage({
|
|
746
|
+
leave,
|
|
747
|
+
...restInput,
|
|
748
|
+
object: {
|
|
749
|
+
...restObject,
|
|
750
|
+
title: restObject.title || '',
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
};
|
|
754
|
+
addTpaasLeaveTracking({
|
|
755
|
+
objectElement,
|
|
756
|
+
pageElement,
|
|
757
|
+
objectResizable,
|
|
758
|
+
heightBuilder,
|
|
759
|
+
schema: LeavePage.object.objectType,
|
|
760
|
+
trackMethod: leavePageCallback,
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
return result;
|
|
764
|
+
}
|
|
765
|
+
async trackImpressionHealthUIElement(input) {
|
|
766
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
767
|
+
const event = buildImpressionHealthUIElementEvent(input, dependencies);
|
|
768
|
+
return this.sendTpaasEvent(event);
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* @param input
|
|
772
|
+
* @param options
|
|
773
|
+
* @category TPaaS Tracking
|
|
774
|
+
*/
|
|
775
|
+
async trackViewPage(input, options) {
|
|
776
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
777
|
+
this.setCurrentPage(input.object.objectId, ViewPage.object.objectType);
|
|
778
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
779
|
+
const event = buildViewPageEvent(input, dependencies);
|
|
780
|
+
const result = this.sendTpaasEvent(event);
|
|
781
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
782
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
783
|
+
const leavePageCallback = (leave) => {
|
|
784
|
+
this.trackLeavePage({
|
|
785
|
+
leave,
|
|
786
|
+
...input,
|
|
787
|
+
});
|
|
788
|
+
};
|
|
789
|
+
addTpaasLeaveTracking({
|
|
790
|
+
objectElement,
|
|
791
|
+
pageElement,
|
|
792
|
+
objectResizable,
|
|
793
|
+
heightBuilder,
|
|
794
|
+
schema: LeavePage.object.objectType,
|
|
795
|
+
trackMethod: leavePageCallback,
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
return result;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* @param input
|
|
802
|
+
* @category TPaaS Tracking
|
|
803
|
+
*/
|
|
804
|
+
async trackViewTitle(input) {
|
|
805
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
806
|
+
this.setCurrentPage(input.object.objectId, ViewTitle.object.objectType);
|
|
807
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
808
|
+
const event = buildViewTitleEvent(input, dependencies);
|
|
809
|
+
return this.sendTpaasEvent(event);
|
|
810
|
+
// there's no Leave Title event
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* @param input
|
|
814
|
+
* @category TPaaS Tracking
|
|
815
|
+
*/
|
|
816
|
+
async trackImpressionWidget(input) {
|
|
817
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
818
|
+
const event = buildImpressionWidgetEvent(input, dependencies);
|
|
819
|
+
return this.sendTpaasEvent(event);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* @param input
|
|
823
|
+
* @category TPaaS Tracking
|
|
824
|
+
*/
|
|
825
|
+
async trackImpressionAdSlot(input) {
|
|
826
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
827
|
+
const event = buildImpressionAdSlotEvent(input, dependencies);
|
|
828
|
+
return this.sendTpaasEvent(event);
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* @param input
|
|
832
|
+
* @param options
|
|
833
|
+
* @category TPaaS Tracking
|
|
834
|
+
*/
|
|
835
|
+
async trackViewArticle(input, options) {
|
|
836
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
837
|
+
this.setCurrentPage(input.object.objectId, ViewArticle.object.objectType);
|
|
838
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
839
|
+
const event = buildViewArticleEvent(input, dependencies);
|
|
840
|
+
const result = this.sendTpaasEvent(event);
|
|
841
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
842
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
843
|
+
const leaveArticleCallback = (leave) => {
|
|
844
|
+
this.trackLeaveArticle({
|
|
845
|
+
leave,
|
|
846
|
+
...input,
|
|
847
|
+
});
|
|
848
|
+
};
|
|
849
|
+
addTpaasLeaveTracking({
|
|
850
|
+
objectElement,
|
|
851
|
+
pageElement,
|
|
852
|
+
heightBuilder,
|
|
853
|
+
objectResizable,
|
|
854
|
+
schema: LeaveArticle.object.objectType,
|
|
855
|
+
trackMethod: leaveArticleCallback,
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
return result;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* @param input
|
|
862
|
+
* @param options
|
|
863
|
+
* @category TPaaS Tracking
|
|
864
|
+
*/
|
|
865
|
+
async trackViewAudio(input) {
|
|
866
|
+
// despite the View event type, this is not a page view event, but rather a media object view event
|
|
867
|
+
// so we shouldn't reset the page view ID here or enable leave tracking
|
|
868
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
869
|
+
const event = buildViewAudioEvent(input, dependencies);
|
|
870
|
+
return this.sendTpaasEvent(event);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Tracks a View AudioPage event and automatically fires a Leave AudioPage event when the user
|
|
874
|
+
* navigates away.
|
|
875
|
+
*
|
|
876
|
+
* The Leave AudioPage event requires audio engagement statistics (`leaveAudio`) that the SDK
|
|
877
|
+
* cannot compute on its own. Provide a `leaveAudioBuilder` callback in the `leaveTracking`
|
|
878
|
+
* options — it is called at leave time (not at registration time), so it always captures the
|
|
879
|
+
* latest state. If no builder is supplied all audio engagement fields default to `0`.
|
|
880
|
+
*
|
|
881
|
+
* `activityDurationMs` and `durationMs` are computed by the leave tracking system and must
|
|
882
|
+
* **not** be included in the value returned by `leaveAudioBuilder`.
|
|
883
|
+
*
|
|
884
|
+
* @example
|
|
885
|
+
* ```ts
|
|
886
|
+
* // Minimal — leave fires with zeroed audio stats
|
|
887
|
+
* await tracker.trackViewAudioPage(input, {
|
|
888
|
+
* leaveTracking: { objectElement: document.getElementById('audio-player')! },
|
|
889
|
+
* });
|
|
890
|
+
*
|
|
891
|
+
* // With leaveAudioBuilder — capture live playback stats at leave time
|
|
892
|
+
* await tracker.trackViewAudioPage(input, {
|
|
893
|
+
* leaveTracking: {
|
|
894
|
+
* objectElement: document.getElementById('audio-player')!,
|
|
895
|
+
* leaveAudioBuilder: () => ({
|
|
896
|
+
* audioStarted: player.tracksStarted,
|
|
897
|
+
* audioCompleted: player.tracksCompleted,
|
|
898
|
+
* maxPlaylistPosition: player.maxPosition,
|
|
899
|
+
* playlistPositionPercentage: player.positionPercentage,
|
|
900
|
+
* }),
|
|
901
|
+
* },
|
|
902
|
+
* });
|
|
903
|
+
*
|
|
904
|
+
* // Disable leave tracking entirely
|
|
905
|
+
* await tracker.trackViewAudioPage(input, { leaveTracking: false });
|
|
906
|
+
* ```
|
|
907
|
+
*
|
|
908
|
+
* @param input
|
|
909
|
+
* @param options
|
|
910
|
+
* @category TPaaS Tracking
|
|
911
|
+
*/
|
|
912
|
+
async trackViewAudioPage(input, options) {
|
|
913
|
+
this.newPageView();
|
|
914
|
+
this.setCurrentPage(input.object.objectId, 'Audio'); // ViewAudioPage.object.objectType is AudioPage, which is not allowed as a pageType
|
|
915
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
916
|
+
const event = buildViewAudioPageEvent(input, dependencies);
|
|
917
|
+
const result = this.sendTpaasEvent(event);
|
|
918
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
919
|
+
const { objectElement, pageElement, heightBuilder, objectResizable, leaveAudioBuilder } = options.leaveTracking;
|
|
920
|
+
const leaveAudioPageCallback = (leave) => {
|
|
921
|
+
const leaveAudioInput = leaveAudioBuilder?.() ?? {
|
|
922
|
+
audioCompleted: 0,
|
|
923
|
+
audioStarted: 0,
|
|
924
|
+
maxPlaylistPosition: 0,
|
|
925
|
+
playlistPositionPercentage: 0,
|
|
926
|
+
};
|
|
927
|
+
this.trackLeaveAudioPage({
|
|
928
|
+
leave,
|
|
929
|
+
leaveAudio: {
|
|
930
|
+
...leaveAudioInput,
|
|
931
|
+
activityDurationMs: leave.activityDurationMs,
|
|
932
|
+
durationMs: leave.durationMs,
|
|
933
|
+
},
|
|
934
|
+
...input,
|
|
935
|
+
});
|
|
936
|
+
};
|
|
937
|
+
addTpaasLeaveTracking({
|
|
938
|
+
objectElement,
|
|
939
|
+
pageElement,
|
|
940
|
+
heightBuilder,
|
|
941
|
+
objectResizable,
|
|
942
|
+
schema: LeaveAudioPage.object.objectType,
|
|
943
|
+
trackMethod: leaveAudioPageCallback,
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
return result;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* @param input
|
|
950
|
+
* @param options
|
|
951
|
+
* @category TPaaS Tracking
|
|
952
|
+
*/
|
|
953
|
+
async trackViewError(input, options) {
|
|
954
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
955
|
+
this.setCurrentPage(input.object.objectId, ViewError.object.objectType);
|
|
956
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
957
|
+
const event = buildViewErrorEvent(input, dependencies);
|
|
958
|
+
const result = this.sendTpaasEvent(event);
|
|
959
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
960
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
961
|
+
const leaveErrorCallback = (leave) => {
|
|
962
|
+
this.trackLeaveError({
|
|
963
|
+
leave,
|
|
964
|
+
...input,
|
|
965
|
+
});
|
|
966
|
+
};
|
|
967
|
+
addTpaasLeaveTracking({
|
|
968
|
+
objectElement,
|
|
969
|
+
pageElement,
|
|
970
|
+
heightBuilder,
|
|
971
|
+
objectResizable,
|
|
972
|
+
schema: LeaveError.object.objectType,
|
|
973
|
+
trackMethod: leaveErrorCallback,
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
return result;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* @param input
|
|
980
|
+
* @category TPaaS Tracking
|
|
981
|
+
*/
|
|
982
|
+
async trackImpressionForm(input) {
|
|
983
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
984
|
+
const event = buildImpressionFormEvent(input, dependencies);
|
|
985
|
+
return this.sendTpaasEvent(event);
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* @param input
|
|
989
|
+
* @category TPaaS Tracking
|
|
990
|
+
*/
|
|
991
|
+
async trackImpressionOffer(input) {
|
|
992
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
993
|
+
const event = buildImpressionOfferEvent(input, dependencies);
|
|
994
|
+
return this.sendTpaasEvent(event);
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* @param input
|
|
998
|
+
* @category TPaaS Tracking
|
|
999
|
+
*/
|
|
1000
|
+
async trackImpressionPlayer(input) {
|
|
1001
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1002
|
+
const event = buildImpressionPlayerEvent(input, dependencies);
|
|
1003
|
+
return this.sendTpaasEvent(event);
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* @param input
|
|
1007
|
+
* @category TPaaS Tracking
|
|
1008
|
+
*/
|
|
1009
|
+
async trackImpressionTeaser(input) {
|
|
1010
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1011
|
+
const event = buildImpressionTeaserEvent(input, dependencies);
|
|
1012
|
+
return this.sendTpaasEvent(event);
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* @param input
|
|
1016
|
+
* @category TPaaS Tracking
|
|
1017
|
+
*/
|
|
1018
|
+
async trackImpressionUIElement(input) {
|
|
1019
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1020
|
+
const event = buildImpressionUIElementEvent(input, dependencies);
|
|
1021
|
+
return this.sendTpaasEvent(event);
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* @param input
|
|
1025
|
+
* @param options
|
|
1026
|
+
* @category TPaaS Tracking
|
|
1027
|
+
*/
|
|
1028
|
+
async trackViewFrontpage(input, options) {
|
|
1029
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1030
|
+
this.setCurrentPage(input.object.objectId, ViewFrontpage.object.objectType);
|
|
1031
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1032
|
+
const event = buildViewFrontpageEvent(input, dependencies);
|
|
1033
|
+
const result = this.sendTpaasEvent(event);
|
|
1034
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1035
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1036
|
+
const leaveFrontpageCallback = (leave) => {
|
|
1037
|
+
this.trackLeaveFrontpage({
|
|
1038
|
+
leave,
|
|
1039
|
+
...input,
|
|
1040
|
+
});
|
|
1041
|
+
};
|
|
1042
|
+
addTpaasLeaveTracking({
|
|
1043
|
+
objectElement,
|
|
1044
|
+
pageElement,
|
|
1045
|
+
objectResizable,
|
|
1046
|
+
heightBuilder,
|
|
1047
|
+
schema: LeaveFrontpage.object.objectType,
|
|
1048
|
+
trackMethod: leaveFrontpageCallback,
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
return result;
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* @param input
|
|
1055
|
+
* @param options
|
|
1056
|
+
* @category TPaaS Tracking
|
|
1057
|
+
*/
|
|
1058
|
+
async trackViewLandingpage(input, options) {
|
|
1059
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1060
|
+
this.setCurrentPage(input.object.objectId, 'LandingPage' /* TODO: ViewLandingpage.object.type once the schema is fixed */);
|
|
1061
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1062
|
+
const event = buildViewLandingpageEvent(input, dependencies);
|
|
1063
|
+
const result = this.sendTpaasEvent(event);
|
|
1064
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1065
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1066
|
+
const leaveLandingpageCallback = (leave) => {
|
|
1067
|
+
this.trackLeaveLandingpage({
|
|
1068
|
+
leave,
|
|
1069
|
+
...input,
|
|
1070
|
+
});
|
|
1071
|
+
};
|
|
1072
|
+
addTpaasLeaveTracking({
|
|
1073
|
+
objectElement,
|
|
1074
|
+
pageElement,
|
|
1075
|
+
heightBuilder,
|
|
1076
|
+
objectResizable,
|
|
1077
|
+
schema: LeaveLandingpage.object.objectType,
|
|
1078
|
+
trackMethod: leaveLandingpageCallback,
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
return result;
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* @param input
|
|
1085
|
+
* @param options
|
|
1086
|
+
* @category TPaaS Tracking
|
|
1087
|
+
*/
|
|
1088
|
+
async trackViewListing(input, options) {
|
|
1089
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1090
|
+
this.setCurrentPage(input.object.objectId, ViewListing.object.objectType);
|
|
1091
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1092
|
+
const event = buildViewListingEvent(input, dependencies);
|
|
1093
|
+
const result = this.sendTpaasEvent(event);
|
|
1094
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1095
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1096
|
+
const leaveListingCallback = (leave) => {
|
|
1097
|
+
this.trackLeaveListing({
|
|
1098
|
+
leave,
|
|
1099
|
+
...input,
|
|
1100
|
+
});
|
|
1101
|
+
};
|
|
1102
|
+
addTpaasLeaveTracking({
|
|
1103
|
+
objectElement,
|
|
1104
|
+
pageElement,
|
|
1105
|
+
heightBuilder,
|
|
1106
|
+
objectResizable,
|
|
1107
|
+
schema: LeaveListing.object.objectType,
|
|
1108
|
+
trackMethod: leaveListingCallback,
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
return result;
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* @param input
|
|
1115
|
+
* @param options
|
|
1116
|
+
* @category TPaaS Tracking
|
|
1117
|
+
*/
|
|
1118
|
+
async trackViewLockedArticle(input, options) {
|
|
1119
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1120
|
+
this.setCurrentPage(input.object.objectId, ViewLockedArticle.object.objectType);
|
|
1121
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1122
|
+
const event = buildViewLockedArticleEvent(input, dependencies);
|
|
1123
|
+
const result = this.sendTpaasEvent(event);
|
|
1124
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1125
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1126
|
+
const leaveLockedArticleCallback = (leave) => {
|
|
1127
|
+
this.trackLeaveLockedArticle({
|
|
1128
|
+
leave,
|
|
1129
|
+
...input,
|
|
1130
|
+
});
|
|
1131
|
+
};
|
|
1132
|
+
addTpaasLeaveTracking({
|
|
1133
|
+
objectElement,
|
|
1134
|
+
pageElement,
|
|
1135
|
+
objectResizable,
|
|
1136
|
+
heightBuilder,
|
|
1137
|
+
schema: LeaveLockedArticle.object.objectType,
|
|
1138
|
+
trackMethod: leaveLockedArticleCallback,
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
return result;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* @param input
|
|
1145
|
+
* @param options
|
|
1146
|
+
* @category TPaaS Tracking
|
|
1147
|
+
*/
|
|
1148
|
+
async trackViewLockedAudio(input) {
|
|
1149
|
+
// despite the View event type, this is not a page view event, but rather a media object view event
|
|
1150
|
+
// so we shouldn't reset the page view ID here or enable leave tracking
|
|
1151
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1152
|
+
const event = buildViewLockedAudioEvent(input, dependencies);
|
|
1153
|
+
return this.sendTpaasEvent(event);
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* @param input
|
|
1157
|
+
* @param options
|
|
1158
|
+
* @category TPaaS Tracking
|
|
1159
|
+
*/
|
|
1160
|
+
async trackViewLockedAudioPage(input, options) {
|
|
1161
|
+
this.newPageView();
|
|
1162
|
+
this.setCurrentPage(input.object.objectId, 'Audio'); // ViewLockedAudioPage.object.objectType is AudioPage, which is not allowed as a pageType
|
|
1163
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1164
|
+
const event = buildViewLockedAudioPageEvent(input, dependencies);
|
|
1165
|
+
const result = this.sendTpaasEvent(event);
|
|
1166
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1167
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1168
|
+
const leaveLockedAudioPageCallback = (leave) => {
|
|
1169
|
+
this.trackLeaveLockedAudioPage({
|
|
1170
|
+
leave,
|
|
1171
|
+
...input,
|
|
1172
|
+
});
|
|
1173
|
+
};
|
|
1174
|
+
addTpaasLeaveTracking({
|
|
1175
|
+
objectElement,
|
|
1176
|
+
pageElement,
|
|
1177
|
+
heightBuilder,
|
|
1178
|
+
objectResizable,
|
|
1179
|
+
schema: LeaveLockedAudioPage.object.objectType,
|
|
1180
|
+
trackMethod: leaveLockedAudioPageCallback,
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
return result;
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* @param input
|
|
1187
|
+
* @category TPaaS Tracking
|
|
1188
|
+
*/
|
|
1189
|
+
async trackViewLockedVideo(input) {
|
|
1190
|
+
// despite the name, this is not a page-level event. trackViewLockedVideoPage is a page-level event
|
|
1191
|
+
// as such, we don't support (yet) automatic leave event enabling
|
|
1192
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1193
|
+
const event = buildViewLockedVideoEvent(input, dependencies);
|
|
1194
|
+
return this.sendTpaasEvent(event);
|
|
1195
|
+
}
|
|
1196
|
+
/**
|
|
1197
|
+
* @param input
|
|
1198
|
+
* @param options
|
|
1199
|
+
* @category TPaaS Tracking
|
|
1200
|
+
*/
|
|
1201
|
+
async trackViewLockedVideoPage(input, options) {
|
|
1202
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1203
|
+
this.setCurrentPage(input.object.objectId, ViewLockedVideo.object.objectType);
|
|
1204
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1205
|
+
const event = buildViewLockedVideoPageEvent(input, dependencies);
|
|
1206
|
+
const result = this.sendTpaasEvent(event);
|
|
1207
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1208
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1209
|
+
const leaveLockedVideoPageCallback = (leave) => {
|
|
1210
|
+
this.trackLeaveLockedVideoPage({
|
|
1211
|
+
leave,
|
|
1212
|
+
...input,
|
|
1213
|
+
});
|
|
1214
|
+
};
|
|
1215
|
+
addTpaasLeaveTracking({
|
|
1216
|
+
objectElement,
|
|
1217
|
+
pageElement,
|
|
1218
|
+
heightBuilder,
|
|
1219
|
+
objectResizable,
|
|
1220
|
+
schema: LeaveLockedVideoPage.object.objectType,
|
|
1221
|
+
trackMethod: leaveLockedVideoPageCallback,
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
return result;
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* @param input
|
|
1228
|
+
* @category TPaaS Tracking
|
|
1229
|
+
*/
|
|
1230
|
+
async trackViewVideo(input) {
|
|
1231
|
+
// despite the View event type, this is not a page view event, but rather a media object view event
|
|
1232
|
+
// so we shouldn't reset the page view ID here or enable leave tracking
|
|
1233
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1234
|
+
const event = buildViewVideoEvent(input, dependencies);
|
|
1235
|
+
return this.sendTpaasEvent(event);
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Tracks a View VideoPage event and automatically fires a Leave VideoPage event when the user
|
|
1239
|
+
* navigates away.
|
|
1240
|
+
*
|
|
1241
|
+
* The Leave VideoPage event supports an optional `leaveStories` field containing story carousel
|
|
1242
|
+
* statistics that the SDK cannot compute. Provide a `leaveStoriesBuilder` callback in the
|
|
1243
|
+
* `leaveTracking` options — it is called at leave time (not at registration time), so it always
|
|
1244
|
+
* captures the latest state. If no builder is supplied `leaveStories` is omitted from the Leave
|
|
1245
|
+
* VideoPage event.
|
|
1246
|
+
*
|
|
1247
|
+
* `activityDurationMs` and `durationMs` are computed by the leave tracking system and must
|
|
1248
|
+
* **not** be included in the value returned by `leaveStoriesBuilder`.
|
|
1249
|
+
*
|
|
1250
|
+
* @example
|
|
1251
|
+
* ```ts
|
|
1252
|
+
* // Without story stats — leaveStories is omitted from the Leave VideoPage event
|
|
1253
|
+
* await tracker.trackViewVideoPage(input, {
|
|
1254
|
+
* leaveTracking: { objectElement: document.getElementById('video-player')! },
|
|
1255
|
+
* });
|
|
1256
|
+
*
|
|
1257
|
+
* // With leaveStoriesBuilder — capture live story stats at leave time
|
|
1258
|
+
* await tracker.trackViewVideoPage(input, {
|
|
1259
|
+
* leaveTracking: {
|
|
1260
|
+
* objectElement: document.getElementById('video-player')!,
|
|
1261
|
+
* leaveStoriesBuilder: () => ({
|
|
1262
|
+
* storiesCompleted: stories.completed,
|
|
1263
|
+
* storiesStarted: stories.started,
|
|
1264
|
+
* maxPlaylistPosition: stories.maxPosition,
|
|
1265
|
+
* playlistPositionPercentage: stories.positionPercentage,
|
|
1266
|
+
* adCount: stories.adCount,
|
|
1267
|
+
* }),
|
|
1268
|
+
* },
|
|
1269
|
+
* });
|
|
1270
|
+
*
|
|
1271
|
+
* // Disable leave tracking entirely
|
|
1272
|
+
* await tracker.trackViewVideoPage(input, { leaveTracking: false });
|
|
1273
|
+
* ```
|
|
1274
|
+
*
|
|
1275
|
+
* @param input
|
|
1276
|
+
* @param options
|
|
1277
|
+
* @category TPaaS Tracking
|
|
1278
|
+
*/
|
|
1279
|
+
async trackViewVideoPage(input, options) {
|
|
1280
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1281
|
+
this.setCurrentPage(input.object.objectId, 'Video'); // ViewVideoPage.object.type is VideoPage, which is not allowed as a pageType
|
|
1282
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1283
|
+
const event = buildViewVideoPageEvent(input, dependencies);
|
|
1284
|
+
const result = this.sendTpaasEvent(event);
|
|
1285
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1286
|
+
const { objectElement, pageElement, heightBuilder, objectResizable, leaveStoriesBuilder } = options.leaveTracking;
|
|
1287
|
+
const leaveVideoCallback = (leave) => {
|
|
1288
|
+
const leaveStoriesInput = leaveStoriesBuilder?.();
|
|
1289
|
+
this.trackLeaveVideoPage({
|
|
1290
|
+
leave,
|
|
1291
|
+
leaveStories: leaveStoriesInput && {
|
|
1292
|
+
...leaveStoriesInput,
|
|
1293
|
+
activityDurationMs: leave.activityDurationMs,
|
|
1294
|
+
durationMs: leave.durationMs,
|
|
1295
|
+
},
|
|
1296
|
+
...input,
|
|
1297
|
+
});
|
|
1298
|
+
};
|
|
1299
|
+
addTpaasLeaveTracking({
|
|
1300
|
+
objectElement,
|
|
1301
|
+
pageElement,
|
|
1302
|
+
heightBuilder,
|
|
1303
|
+
objectResizable,
|
|
1304
|
+
schema: LeaveVideoPage.object.objectType,
|
|
1305
|
+
trackMethod: leaveVideoCallback,
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
return result;
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* @param input
|
|
1312
|
+
* @param options
|
|
1313
|
+
* @category TPaaS Tracking
|
|
1314
|
+
*/
|
|
1315
|
+
async trackViewWeather(input, options) {
|
|
1316
|
+
this.newPageView(); // Reset the page view ID if it is not set, to ensure a new page view is tracked
|
|
1317
|
+
this.setCurrentPage(input.object.objectId, 'Page' /* TODO: ViewWeather.object.type once the schema is fixed */);
|
|
1318
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1319
|
+
const event = buildViewWeatherEvent(input, dependencies);
|
|
1320
|
+
const result = this.sendTpaasEvent(event);
|
|
1321
|
+
if (shouldEnableLeaveTracking(options.leaveTracking)) {
|
|
1322
|
+
const { objectElement, pageElement, heightBuilder, objectResizable } = options.leaveTracking;
|
|
1323
|
+
const leaveWeatherCallback = (leave) => {
|
|
1324
|
+
this.trackLeaveWeather({
|
|
1325
|
+
leave,
|
|
1326
|
+
...input,
|
|
1327
|
+
});
|
|
1328
|
+
};
|
|
1329
|
+
addTpaasLeaveTracking({
|
|
1330
|
+
objectElement,
|
|
1331
|
+
pageElement,
|
|
1332
|
+
heightBuilder,
|
|
1333
|
+
objectResizable,
|
|
1334
|
+
schema: LeaveWeather.object.objectType,
|
|
1335
|
+
trackMethod: leaveWeatherCallback,
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
return result;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* @param input
|
|
1342
|
+
* @category TPaaS Tracking
|
|
1343
|
+
*/
|
|
1344
|
+
async trackLeaveArticle(input) {
|
|
1345
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1346
|
+
const event = buildLeaveArticleEvent(input, dependencies);
|
|
1347
|
+
return this.sendTpaasEvent(event);
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* @param input
|
|
1351
|
+
* @category TPaaS Tracking
|
|
1352
|
+
*/
|
|
1353
|
+
async trackLeaveAudioPage(input) {
|
|
1354
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1355
|
+
const event = buildLeaveAudioPageEvent(input, dependencies);
|
|
1356
|
+
return this.sendTpaasEvent(event);
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* @param input
|
|
1360
|
+
* @category TPaaS Tracking
|
|
1361
|
+
*/
|
|
1362
|
+
async trackLeaveError(input) {
|
|
1363
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1364
|
+
const event = buildLeaveErrorEvent(input, dependencies);
|
|
1365
|
+
return this.sendTpaasEvent(event);
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* @param input
|
|
1369
|
+
* @category TPaaS Tracking
|
|
1370
|
+
*/
|
|
1371
|
+
async trackLeaveFrontpage(input) {
|
|
1372
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1373
|
+
const event = buildLeaveFrontpageEvent(input, dependencies);
|
|
1374
|
+
return this.sendTpaasEvent(event);
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* @param input
|
|
1378
|
+
* @category TPaaS Tracking
|
|
1379
|
+
*/
|
|
1380
|
+
async trackLeaveLandingpage(input) {
|
|
1381
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1382
|
+
const event = buildLeaveLandingpageEvent(input, dependencies);
|
|
1383
|
+
return this.sendTpaasEvent(event);
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* @param input
|
|
1387
|
+
* @category TPaaS Tracking
|
|
1388
|
+
*/
|
|
1389
|
+
async trackLeaveListing(input) {
|
|
1390
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1391
|
+
const event = buildLeaveListingEvent(input, dependencies);
|
|
1392
|
+
return this.sendTpaasEvent(event);
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
* @param input
|
|
1396
|
+
* @category TPaaS Tracking
|
|
1397
|
+
*/
|
|
1398
|
+
async trackLeaveLockedArticle(input) {
|
|
1399
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1400
|
+
const event = buildLeaveLockedArticleEvent(input, dependencies);
|
|
1401
|
+
return this.sendTpaasEvent(event);
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* @param input
|
|
1405
|
+
* @category TPaaS Tracking
|
|
1406
|
+
*/
|
|
1407
|
+
async trackLeaveLockedAudio(input) {
|
|
1408
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1409
|
+
const event = buildLeaveLockedAudioEvent(input, dependencies);
|
|
1410
|
+
return this.sendTpaasEvent(event);
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* @param input
|
|
1414
|
+
* @category TPaaS Tracking
|
|
1415
|
+
*/
|
|
1416
|
+
async trackLeaveLockedAudioPage(input) {
|
|
1417
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1418
|
+
const event = buildLeaveLockedAudioPageEvent(input, dependencies);
|
|
1419
|
+
return this.sendTpaasEvent(event);
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* @param input
|
|
1423
|
+
* @category TPaaS Tracking
|
|
1424
|
+
*/
|
|
1425
|
+
async trackLeaveLockedVideo(input) {
|
|
1426
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1427
|
+
const event = buildLeaveLockedVideoEvent(input, dependencies);
|
|
1428
|
+
return this.sendTpaasEvent(event);
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* @param input
|
|
1432
|
+
* @category TPaaS Tracking
|
|
1433
|
+
*/
|
|
1434
|
+
async trackLeaveLockedVideoPage(input) {
|
|
1435
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1436
|
+
const event = buildLeaveLockedVideoPageEvent(input, dependencies);
|
|
1437
|
+
return this.sendTpaasEvent(event);
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* @param input
|
|
1441
|
+
* @category TPaaS Tracking
|
|
1442
|
+
*/
|
|
1443
|
+
async trackLeavePage(input) {
|
|
1444
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1445
|
+
const event = buildLeavePageEvent(input, dependencies);
|
|
1446
|
+
return this.sendTpaasEvent(event);
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* @param input
|
|
1450
|
+
* @category TPaaS Tracking
|
|
1451
|
+
*/
|
|
1452
|
+
async trackLeaveVideoPage(input) {
|
|
1453
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1454
|
+
const event = buildLeaveVideoPageEvent(input, dependencies);
|
|
1455
|
+
return this.sendTpaasEvent(event);
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* @param input
|
|
1459
|
+
* @category TPaaS Tracking
|
|
1460
|
+
*/
|
|
1461
|
+
async trackLeaveWeather(input) {
|
|
1462
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1463
|
+
const event = buildLeaveWeatherEvent(input, dependencies);
|
|
1464
|
+
return this.sendTpaasEvent(event);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* @param input
|
|
1468
|
+
* @category TPaaS Tracking
|
|
1469
|
+
*/
|
|
1470
|
+
async trackEngagementAudio(input) {
|
|
1471
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1472
|
+
const event = buildEngagementAudioEvent(input, dependencies);
|
|
1473
|
+
return this.sendTpaasEvent(event);
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* @param input
|
|
1477
|
+
* @category TPaaS Tracking
|
|
1478
|
+
*/
|
|
1479
|
+
async trackEngagementForm(input) {
|
|
1480
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1481
|
+
const event = buildEngagementFormEvent(input, dependencies);
|
|
1482
|
+
return this.sendTpaasEvent(event);
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* @param input
|
|
1486
|
+
* @category TPaaS Tracking
|
|
1487
|
+
*/
|
|
1488
|
+
async trackEngagementOffer(input) {
|
|
1489
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1490
|
+
const event = buildEngagementOfferEvent(input, dependencies);
|
|
1491
|
+
return this.sendTpaasEvent(event);
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* @param input
|
|
1495
|
+
* @category TPaaS Tracking
|
|
1496
|
+
*/
|
|
1497
|
+
async trackEngagementTeaser(input) {
|
|
1498
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1499
|
+
const event = buildEngagementTeaserEvent(input, dependencies);
|
|
1500
|
+
return this.sendTpaasEvent(event);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* @param input
|
|
1504
|
+
* @category TPaaS Tracking
|
|
1505
|
+
*/
|
|
1506
|
+
async trackEngagementUIElement(input) {
|
|
1507
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1508
|
+
const event = buildEngagementUIElementEvent(input, dependencies);
|
|
1509
|
+
return this.sendTpaasEvent(event);
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* @param input
|
|
1513
|
+
* @category TPaaS Tracking
|
|
1514
|
+
*/
|
|
1515
|
+
async trackEngagementVideo(input) {
|
|
1516
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1517
|
+
const event = buildEngagementVideoEvent(input, dependencies);
|
|
1518
|
+
return this.sendTpaasEvent(event);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* @param input
|
|
1522
|
+
* @category TPaaS Tracking
|
|
1523
|
+
*/
|
|
1524
|
+
async trackEngagementVideoAd(input) {
|
|
1525
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1526
|
+
const event = buildEngagementVideoAdEvent(input, dependencies);
|
|
1527
|
+
return this.sendTpaasEvent(event);
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* @param input
|
|
1531
|
+
* @category TPaaS Tracking
|
|
1532
|
+
*/
|
|
1533
|
+
async trackEngagementWidget(input) {
|
|
1534
|
+
const dependencies = await this.prepareTpaasEvent();
|
|
1535
|
+
const event = buildEngagementWidgetEvent(input, dependencies);
|
|
1536
|
+
return this.sendTpaasEvent(event);
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* this is the method that actually sends the event to the server
|
|
1540
|
+
* @private
|
|
1541
|
+
* @category TPaaS Tracking
|
|
1542
|
+
*/
|
|
1543
|
+
async sendTpaasEvent(event) {
|
|
1544
|
+
// Resolve any pending session ID promises
|
|
1545
|
+
// (session was created when the event was built)
|
|
1546
|
+
this.resolveSessionIdPromise();
|
|
1547
|
+
// The Hybrid use case implements a "bridged" event method, injected into the window scope,
|
|
1548
|
+
// which is used to send events through the native app.
|
|
1549
|
+
if (isFunction(this.state.altEventHandler)) {
|
|
1550
|
+
this.state.altEventHandler(JSON.stringify(event));
|
|
1551
|
+
return event;
|
|
1552
|
+
}
|
|
1553
|
+
this.tpaasEventQueue.push(event);
|
|
1554
|
+
if (this.state.useBeacon) {
|
|
1555
|
+
try {
|
|
1556
|
+
return await this._sendImmediatelyTpaas();
|
|
1557
|
+
}
|
|
1558
|
+
catch (err) {
|
|
1559
|
+
return err;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
return this.debouncedSendTpaas();
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Send all events that are in the internal event queue.
|
|
1566
|
+
*
|
|
1567
|
+
* The returned Promise will resolve with the array of events that was
|
|
1568
|
+
* successfully transmitted. These events will have been removed from the event
|
|
1569
|
+
* queue. If the promise rejects, it means that the event queue could not be
|
|
1570
|
+
* sent and the promise rejection will contain the events that failed (will be
|
|
1571
|
+
* the entire queue initial call). Events that are unsuccessfully sent will
|
|
1572
|
+
* remain in the event queue.
|
|
1573
|
+
*
|
|
1574
|
+
* @internal
|
|
1575
|
+
* @category TPaaS Tracking
|
|
1576
|
+
*/
|
|
1577
|
+
async _sendImmediatelyTpaas() {
|
|
1578
|
+
if (this.tpaasEventQueue.length + this.retryTpaasEventQueue.length <= 0) {
|
|
1579
|
+
return [];
|
|
1580
|
+
}
|
|
1581
|
+
return this.prepareQueuesAndSendTpaas(this.tpaasEventQueue, this.retryTpaasEventQueue);
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Prepares the received event queue and handles success / failure after sending.
|
|
1585
|
+
*
|
|
1586
|
+
* @param eventQueue
|
|
1587
|
+
* @param retryEventQueue
|
|
1588
|
+
* @private
|
|
1589
|
+
* @category TPaaS Tracking
|
|
1590
|
+
*/
|
|
1591
|
+
async prepareQueuesAndSendTpaas(eventQueue, retryEventQueue) {
|
|
1592
|
+
const eventsToBeSent = eventQueue.splice(0);
|
|
1593
|
+
const eventsToRetry = retryEventQueue.splice(0);
|
|
1594
|
+
eventQueue.length = 0;
|
|
1595
|
+
retryEventQueue.length = 0;
|
|
1596
|
+
const url = this._getTpaasCollectorPath();
|
|
1597
|
+
const data = [...eventsToBeSent, ...eventsToRetry];
|
|
1598
|
+
async function onFailedSend() {
|
|
1599
|
+
// We retry an event once, but discard already retried events
|
|
1600
|
+
retryEventQueue.push(...eventsToBeSent);
|
|
1601
|
+
return Promise.reject(eventsToBeSent);
|
|
1602
|
+
}
|
|
1603
|
+
try {
|
|
1604
|
+
// for TPaaS events, we set the sentAt time to the current date, just before sending the events
|
|
1605
|
+
const currentDate = new Date().toISOString();
|
|
1606
|
+
for (const event of data) {
|
|
1607
|
+
event.time.sentAt = currentDate;
|
|
1608
|
+
}
|
|
1609
|
+
const response = await send(url, data, this.state);
|
|
1610
|
+
if (response.status >= 400) {
|
|
1611
|
+
onFailedSend();
|
|
1612
|
+
}
|
|
1613
|
+
return eventsToBeSent;
|
|
1614
|
+
}
|
|
1615
|
+
catch (_ex) {
|
|
1616
|
+
return onFailedSend();
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Evaluate all input given to the sdk/this method and pass it through the
|
|
1621
|
+
* appropriate event formatter.
|
|
1622
|
+
* @internal
|
|
1623
|
+
* @category Legacy Tracking
|
|
1624
|
+
*/
|
|
1625
|
+
async evaluateEvent(eventType, input, builders = this.builders, options) {
|
|
1626
|
+
const eventBuilder = getEventBuilder(eventType);
|
|
1627
|
+
return this.evaluateEventInputs(eventType, input, builders, options).then((evaluatedInput) => {
|
|
1628
|
+
const data = eventBuilder({
|
|
1629
|
+
eventInput: evaluatedInput,
|
|
1630
|
+
sdkConfig: this.state,
|
|
1631
|
+
});
|
|
1632
|
+
return evaluateAndFlatten(data);
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* @param eventType
|
|
1637
|
+
* @param eventInput
|
|
1638
|
+
* @param builders
|
|
1639
|
+
* @param options
|
|
1640
|
+
* @internal
|
|
1641
|
+
* @category Legacy Tracking
|
|
1642
|
+
*/
|
|
1643
|
+
async evaluateEventInputs(eventType, eventInput, builders = this.builders, options) {
|
|
1644
|
+
const buildersOutput = await Promise.all([evaluateAndFlatten(builders), evaluateAndFlatten(eventInput)]);
|
|
1645
|
+
let eventOutput = buildersOutput.reduce((acc, p) => pulseMerge(acc, p), {});
|
|
1646
|
+
eventOutput = this.applyEventTypeDefaults(eventOutput, eventType);
|
|
1647
|
+
eventOutput = this.applyBookmarkedEvent(eventOutput, options?.applyBookmarkKey);
|
|
1648
|
+
eventOutput = await this.applyConsents(eventOutput);
|
|
1649
|
+
return eventOutput;
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Gets user consents from the tracker's state.
|
|
1653
|
+
* @returns {Consents}
|
|
1654
|
+
* @category Consents
|
|
1655
|
+
*/
|
|
1656
|
+
async getConsents() {
|
|
1657
|
+
return (await this.evaluateConsents()).consents;
|
|
1658
|
+
}
|
|
1659
|
+
/**
|
|
1660
|
+
* Sets user consents to be sent with each event.
|
|
1661
|
+
* Given that User's consent for Advertising changed, the next call to get Advertising Identifiers must be forced, and
|
|
1662
|
+
* not retrieve values from cache. The flag is passed with the trackers state, and updated to a "non-forcing" state
|
|
1663
|
+
* right after, characterising the "force once" behaviour.
|
|
1664
|
+
* accessing Advertising Identifiers directly must clear this flag.
|
|
1665
|
+
* Not usable with autoCreateConsents option
|
|
1666
|
+
* @param consentsInput
|
|
1667
|
+
* @returns {Consents}
|
|
1668
|
+
* @category Consents
|
|
1669
|
+
*/
|
|
1670
|
+
setConsents(consentsInput) {
|
|
1671
|
+
if (this.state.autoCreateConsents) {
|
|
1672
|
+
warnOnce('setConsents', 'setConsents is not allowed when autoCreateConsents is enabled');
|
|
1673
|
+
return { ...this.state.consents };
|
|
1674
|
+
}
|
|
1675
|
+
return this.setConsentsInternal(consentsInput);
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Return a new Tracker with the current state
|
|
1679
|
+
* @category Tracking
|
|
1680
|
+
*/
|
|
1681
|
+
clone({ trackerId } = {}) {
|
|
1682
|
+
return new Tracker(this.state.providerId, {
|
|
1683
|
+
...this.state,
|
|
1684
|
+
trackerId: trackerId || v4(),
|
|
1685
|
+
}, {
|
|
1686
|
+
...this.builders,
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
/**
|
|
1690
|
+
* Update the persisted state that is passed to all events
|
|
1691
|
+
*
|
|
1692
|
+
* Calling
|
|
1693
|
+
* ```
|
|
1694
|
+
* tracker.update({ actor: 'person@example.org' });
|
|
1695
|
+
* tracker.trackPageView();
|
|
1696
|
+
* tracker.trackPageView();
|
|
1697
|
+
* ```
|
|
1698
|
+
*
|
|
1699
|
+
* is equivalent of doing
|
|
1700
|
+
*
|
|
1701
|
+
* ```
|
|
1702
|
+
* tracker.trackPageView({ actor: 'person@example.org' });
|
|
1703
|
+
* tracker.trackPageView({ actor: 'person@example.org' });
|
|
1704
|
+
* ```
|
|
1705
|
+
*
|
|
1706
|
+
* @param builder data passed to event functions
|
|
1707
|
+
* @param mergeBuilder the given data will be merged deeply with the
|
|
1708
|
+
* existing state. False will result in the previous state being overwritten
|
|
1709
|
+
* @category Legacy Tracking
|
|
1710
|
+
*/
|
|
1711
|
+
update(builder, mergeBuilder = false) {
|
|
1712
|
+
if (mergeBuilder) {
|
|
1713
|
+
this.builders = pulseMerge({}, this.builders, builder);
|
|
1714
|
+
}
|
|
1715
|
+
else {
|
|
1716
|
+
this.builders = Object.assign({}, this.builders, builder);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Get the actor id (userId) from the current browser. A promise is returned
|
|
1721
|
+
* because a call may be made to complete the login process.
|
|
1722
|
+
*
|
|
1723
|
+
* *Note*: This method will return a Promise that is always rejected on node
|
|
1724
|
+
environments.
|
|
1725
|
+
@category Identifiers
|
|
1726
|
+
*/
|
|
1727
|
+
async getUserId() {
|
|
1728
|
+
await this._applyRemoteConfigEndpoints();
|
|
1729
|
+
return identity.getUserId(this.builders);
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Get the advertisement id (adId) from the current browser. A promise is returned
|
|
1733
|
+
* because a CIS call is done to generate a new adId if no cookie is
|
|
1734
|
+
* found.
|
|
1735
|
+
*
|
|
1736
|
+
* *Note*: This method will return a Promise that is always rejected on node
|
|
1737
|
+
* environments.
|
|
1738
|
+
* @category Identifiers
|
|
1739
|
+
* @deprecated Advertising Identifiers methods will be removed in the next major version.
|
|
1740
|
+
*/
|
|
1741
|
+
async getAdId() {
|
|
1742
|
+
warnOnce('getAdId', 'Deprecated method: getAdId');
|
|
1743
|
+
await this._applyRemoteConfigEndpoints();
|
|
1744
|
+
return identity.getAdId(this.builders, this.state);
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* @category Identifiers
|
|
1748
|
+
* @deprecated moving away from "Actor" terminology, in favor of "User"
|
|
1749
|
+
*/
|
|
1750
|
+
async getActor() {
|
|
1751
|
+
await this._applyRemoteConfigEndpoints();
|
|
1752
|
+
return identity.getActor(this.builders);
|
|
1753
|
+
}
|
|
1754
|
+
/**
|
|
1755
|
+
* Get the environment id from the current browser. A promise is returned
|
|
1756
|
+
* because a CIS call is done to generate a new environmentId if no cookie is
|
|
1757
|
+
* found.
|
|
1758
|
+
*
|
|
1759
|
+
* *Note*: This method will return a Promise that is always rejected on node
|
|
1760
|
+
* environments.
|
|
1761
|
+
* @category Identifiers
|
|
1762
|
+
*/
|
|
1763
|
+
async getEnvironmentId() {
|
|
1764
|
+
await this._applyRemoteConfigEndpoints();
|
|
1765
|
+
return identity.getEnvironmentId(this.builders, this.state);
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* Returns the PPID1 value for Xandr integration.
|
|
1769
|
+
* This is the "logged in identifier".
|
|
1770
|
+
* @category Identifiers
|
|
1771
|
+
* @deprecated Advertising Identifiers methods will be removed in the next major version.
|
|
1772
|
+
*/
|
|
1773
|
+
async getXandrPPID1() {
|
|
1774
|
+
warnOnce('getXandrPPID1', 'Deprecated method: getXandrPPID1');
|
|
1775
|
+
const { xandr } = await identity.getAdvertisingIdentifiers(this.builders, { ...this.state });
|
|
1776
|
+
return xandr?.ppId1;
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Returns the PPID2 value for Xandr integration.
|
|
1780
|
+
* This is the "not logged in identifier".
|
|
1781
|
+
* @category Identifiers
|
|
1782
|
+
* @deprecated Advertising Identifiers methods will be removed in the next major version.
|
|
1783
|
+
*/
|
|
1784
|
+
async getXandrPPID2() {
|
|
1785
|
+
warnOnce('getXandrPPID2', 'Deprecated method: getXandrPPID2');
|
|
1786
|
+
const { xandr } = await identity.getAdvertisingIdentifiers(this.builders, { ...this.state });
|
|
1787
|
+
return xandr?.ppId2;
|
|
1788
|
+
}
|
|
1789
|
+
async getAdvertisingIdentifiers(_vendor) {
|
|
1790
|
+
warnOnce('getAdvertisingIdentifiers', 'Deprecated method: getAdvertisingIdentifiers');
|
|
1791
|
+
if (_vendor) {
|
|
1792
|
+
warnOnce('getAdvertisingIdentifiers-no-vendor', 'getAdvertisingIdentifiers no longer accepts vendors as input, the vendors given in SDK constructor is used');
|
|
1793
|
+
}
|
|
1794
|
+
await this._applyRemoteConfigEndpoints();
|
|
1795
|
+
return identity.getAdvertisingIdentifiers(this.builders, { ...this.state });
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* Returns the UUID currently used as the page view (will be muted by `newPageView` and `trackPageView`).
|
|
1799
|
+
* @category Tracking
|
|
1800
|
+
*/
|
|
1801
|
+
getPageViewId() {
|
|
1802
|
+
return this.state.pageViewId;
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Returns the current session ID.
|
|
1806
|
+
* If a session exists, returns the session ID immediately.
|
|
1807
|
+
* If no session exists yet, returns a promise that resolves with the session ID
|
|
1808
|
+
* when it gets created (typically when the first non-anonymous tracking event is sent).
|
|
1809
|
+
*
|
|
1810
|
+
* Note: Anonymous events (such as those sent via {@link trackAnonymous} or {@link trackAnonymousViewUIElement})
|
|
1811
|
+
* do not create sessions and will not resolve pending session ID promises. The promise will only resolve when a
|
|
1812
|
+
* non-anonymous tracking event is sent.
|
|
1813
|
+
*
|
|
1814
|
+
* It is possible the promise will never get resolved if there are no non-anonymous events being tracked after calling this method.
|
|
1815
|
+
*
|
|
1816
|
+
* @category Tracking
|
|
1817
|
+
* @returns The session ID, or a promise that resolves to the session ID
|
|
1818
|
+
*/
|
|
1819
|
+
getSessionId() {
|
|
1820
|
+
const session = readSession();
|
|
1821
|
+
if (session?.id) {
|
|
1822
|
+
return Promise.resolve(session.id);
|
|
1823
|
+
}
|
|
1824
|
+
// No session exists yet, create or return existing promise
|
|
1825
|
+
if (!this.sessionIdPromise) {
|
|
1826
|
+
this.sessionIdPromise = new Promise((resolve) => {
|
|
1827
|
+
const callback = ({ sessionId }) => {
|
|
1828
|
+
resolve(sessionId);
|
|
1829
|
+
this.sessionIdPromise = null; // reset the promise so that future calls to getSessionId will create a new one if needed
|
|
1830
|
+
eventBus.off('tracker:session:new', callback);
|
|
1831
|
+
};
|
|
1832
|
+
eventBus.on('tracker:session:new', callback);
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1835
|
+
return this.sessionIdPromise;
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Generate a new page view id. Will be attached to all events until a new id is generated.
|
|
1839
|
+
* @category Tracking
|
|
1840
|
+
*/
|
|
1841
|
+
newPageView() {
|
|
1842
|
+
this.state.pageViewId = v4();
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Fetches the Remote Configuration, setting the CIS and Collector base urls
|
|
1846
|
+
* @internal
|
|
1847
|
+
* @category Configuration
|
|
1848
|
+
*/
|
|
1849
|
+
async _applyRemoteConfigEndpoints() {
|
|
1850
|
+
const { fallbackCisBaseUrl, fallbackCollectorBaseUrl, environment, configurationTag, remoteConfigurationUrl } = this.state;
|
|
1851
|
+
if (environment === 'browser') {
|
|
1852
|
+
const remoteServiceConfig = await config.syncRemoteConfig(configurationTag, remoteConfigurationUrl);
|
|
1853
|
+
if (!isCollectorInConfig) {
|
|
1854
|
+
this.state.collectorBaseUrl = remoteServiceConfig?.collector || fallbackCollectorBaseUrl;
|
|
1855
|
+
}
|
|
1856
|
+
if (!isCisInConfig) {
|
|
1857
|
+
this.state.cisBaseUrl = remoteServiceConfig?.cis || fallbackCisBaseUrl;
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
/**
|
|
1862
|
+
* @param input
|
|
1863
|
+
* @param builders
|
|
1864
|
+
* @internal
|
|
1865
|
+
* @category Configuration
|
|
1866
|
+
*/
|
|
1867
|
+
async syncRemoteResources(input, builders) {
|
|
1868
|
+
await this._applyRemoteConfigEndpoints();
|
|
1869
|
+
return identity.cisSync(input, builders, { ...this.state });
|
|
1870
|
+
}
|
|
1871
|
+
/**
|
|
1872
|
+
* @internal
|
|
1873
|
+
* @category Configuration
|
|
1874
|
+
*/
|
|
1875
|
+
_getCollectorPath() {
|
|
1876
|
+
const { providerId, environment } = this.state;
|
|
1877
|
+
let { collectorPath, collectorBaseUrl } = this.state;
|
|
1878
|
+
/**
|
|
1879
|
+
* We want to support all of these cases:
|
|
1880
|
+
* collectorPath: /api/v1/track, baseUrl: domain.tld => domain.tld/api/v1/track
|
|
1881
|
+
* collectorPath: api/v1/track, baseUrl: domain.tld => domain.tld/api/v1/track
|
|
1882
|
+
* collectorPath: /api/v1/track, baseUrl: domain.tld/ => domain.tld/api/v1/track
|
|
1883
|
+
* collectorPath: api/v1/track, baseUrl: domain.tld/ => domain.tld/api/v1/track
|
|
1884
|
+
* collectorPath: /api/v1/track, baseUrl: domain.tld/something => domain.tld/something/api/v1/track
|
|
1885
|
+
* collectorPath: api/v1/track, baseUrl: domain.tld/something => domain.tld/something/api/v1/track
|
|
1886
|
+
* collectorPath: /api/v1/track, baseUrl: domain.tld/something/ => domain.tld/something/api/v1/track
|
|
1887
|
+
* collectorPath: api/v1/track, baseUrl: domain.tld/something/ => domain.tld/something/api/v1/track
|
|
1888
|
+
* The collectorPath and collectorBaseUrl manipulating below is to support all these cases
|
|
1889
|
+
*/
|
|
1890
|
+
if (collectorPath.startsWith('/')) {
|
|
1891
|
+
// Remove leading slash
|
|
1892
|
+
collectorPath = collectorPath.slice(1);
|
|
1893
|
+
}
|
|
1894
|
+
if (!collectorBaseUrl?.endsWith('/')) {
|
|
1895
|
+
// Add trailing slash
|
|
1896
|
+
collectorBaseUrl = `${collectorBaseUrl}/`;
|
|
1897
|
+
}
|
|
1898
|
+
if (environment === 'node') {
|
|
1899
|
+
return new URL(collectorPath, collectorBaseUrl).toString();
|
|
1900
|
+
}
|
|
1901
|
+
const _provider = providerId || this.state.providerId;
|
|
1902
|
+
if (typeof _provider === 'string' && _provider.indexOf('sdrn') === 0) {
|
|
1903
|
+
return new URL(`${collectorPath}/${_provider}`, collectorBaseUrl).toString();
|
|
1904
|
+
}
|
|
1905
|
+
return new URL(`${collectorPath}/${providerSdrn(_provider)}`, collectorBaseUrl).toString();
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Returns the collector URL for TPaaS events.
|
|
1909
|
+
* Uses the tpaasCollectorBaseUrl when available (driven by deployStageTpaas),
|
|
1910
|
+
*
|
|
1911
|
+
* @internal
|
|
1912
|
+
* @category Configuration
|
|
1913
|
+
*/
|
|
1914
|
+
_getTpaasCollectorPath() {
|
|
1915
|
+
const { providerId } = this.state;
|
|
1916
|
+
let { collectorPath, tpaasCollectorBaseUrl } = this.state;
|
|
1917
|
+
if (collectorPath.startsWith('/')) {
|
|
1918
|
+
// Remove leading slash
|
|
1919
|
+
collectorPath = collectorPath.slice(1);
|
|
1920
|
+
}
|
|
1921
|
+
if (!tpaasCollectorBaseUrl.endsWith('/')) {
|
|
1922
|
+
// Add trailing slash
|
|
1923
|
+
tpaasCollectorBaseUrl = `${tpaasCollectorBaseUrl}/`;
|
|
1924
|
+
}
|
|
1925
|
+
if (typeof providerId === 'string' && providerId.indexOf('sdrn') === 0) {
|
|
1926
|
+
return new URL(`${collectorPath}/${providerId}`, tpaasCollectorBaseUrl).toString();
|
|
1927
|
+
}
|
|
1928
|
+
return new URL(`${collectorPath}/${providerSdrn(providerId)}`, tpaasCollectorBaseUrl).toString();
|
|
1929
|
+
}
|
|
1930
|
+
/**
|
|
1931
|
+
* Send all events that are in the internal event queue.
|
|
1932
|
+
*
|
|
1933
|
+
* The returned Promise will resolve with the array of events that was
|
|
1934
|
+
* successfully transmitted. These events will have been removed from the event
|
|
1935
|
+
* queue. If the promise rejects, it means that the event queue could not be
|
|
1936
|
+
* sent and the promise rejection will contain the events that failed (will be
|
|
1937
|
+
* the entire queue initial call). Events that are unsuccessfully sent will
|
|
1938
|
+
* remain in the event queue.
|
|
1939
|
+
*
|
|
1940
|
+
* @internal
|
|
1941
|
+
* @category Legacy Tracking
|
|
1942
|
+
*
|
|
1943
|
+
*/
|
|
1944
|
+
async _sendImmediately() {
|
|
1945
|
+
if (this.eventQueue.length + this.retryEventQueue.length <= 0) {
|
|
1946
|
+
return [];
|
|
1947
|
+
}
|
|
1948
|
+
const { doTracking } = await identity.cisSync({}, this.builders, this.state);
|
|
1949
|
+
if (!doTracking) {
|
|
1950
|
+
return [];
|
|
1951
|
+
}
|
|
1952
|
+
return this.prepareQueuesAndSend(this.eventQueue, this.retryEventQueue);
|
|
1953
|
+
}
|
|
1954
|
+
/**
|
|
1955
|
+
* @param event
|
|
1956
|
+
* @param options
|
|
1957
|
+
* @internal
|
|
1958
|
+
* @category Legacy Tracking
|
|
1959
|
+
*/
|
|
1960
|
+
_push(event, options = {}) {
|
|
1961
|
+
const deferredEvent = defer(event);
|
|
1962
|
+
this.eventQueue.push(deferredEvent);
|
|
1963
|
+
if (options.resolveOnQueued) {
|
|
1964
|
+
deferredEvent.resolve(event);
|
|
1965
|
+
}
|
|
1966
|
+
return deferredEvent.promise;
|
|
1967
|
+
}
|
|
1968
|
+
/**
|
|
1969
|
+
* @param bookmarkKey
|
|
1970
|
+
* @internal
|
|
1971
|
+
* @category Legacy Tracking
|
|
1972
|
+
*/
|
|
1973
|
+
getBookmarkedEvent(bookmarkKey) {
|
|
1974
|
+
return this.bookmark.get(bookmarkKey);
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Send the current event queue to the back end event receiver. This event is
|
|
1978
|
+
* debounced, @see {SDKConfigInput} to override the default timing.
|
|
1979
|
+
*
|
|
1980
|
+
* This method is called by `track()` so it is not necessary to call after
|
|
1981
|
+
* adding events to the queue.
|
|
1982
|
+
* @internal
|
|
1983
|
+
* @category Legacy Tracking
|
|
1984
|
+
*/
|
|
1985
|
+
async send() {
|
|
1986
|
+
if (this.state.useBeacon) {
|
|
1987
|
+
try {
|
|
1988
|
+
return await this._sendImmediately();
|
|
1989
|
+
}
|
|
1990
|
+
catch (err) {
|
|
1991
|
+
return err;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
return this.debouncedSend();
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* A convenience method which first updates the current pageViewId in the
|
|
1998
|
+
* tracker state and then sends a `tracker-event` with `@type: View` and the
|
|
1999
|
+
* merged result of the given data and the data saved in the tracker.
|
|
2000
|
+
*
|
|
2001
|
+
* Equivalent to
|
|
2002
|
+
*
|
|
2003
|
+
* ```ts
|
|
2004
|
+
* tracker.newPageView();
|
|
2005
|
+
* tracker.track('trackerEvent', { type: 'View', ...data });
|
|
2006
|
+
* ```
|
|
2007
|
+
* @category Legacy Tracking
|
|
2008
|
+
*/
|
|
2009
|
+
trackPageView(data = {}, options = {}) {
|
|
2010
|
+
this.newPageView();
|
|
2011
|
+
return this.track('trackerEvent', { type: 'View', ...data }, { ...options, bookmarkKey: BookmarkKeys.PAGE_VIEW });
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Start sending events when users leave a page.
|
|
2015
|
+
* This will register handlers on the browser events 'pagehide', 'popstate', 'beforeunload' and 'visibilitychange'
|
|
2016
|
+
* and will send a Leave event when these are triggered. The leave event will be a copy of the last sent view-event
|
|
2017
|
+
* + engagement values. The fields in the default
|
|
2018
|
+
* event can be found here: https://pages.github.schibsted.io/mpt-data/pulse-standard/#leave-article.
|
|
2019
|
+
* The Leave event can be expanded further by passing an event-builder as the third param, but this is not recommended.
|
|
2020
|
+
*
|
|
2021
|
+
* Example usage:
|
|
2022
|
+
*
|
|
2023
|
+
* ```ts
|
|
2024
|
+
* const pageElement = document.querySelector('#application') || document.body;
|
|
2025
|
+
* const articleElement = document.getElementById('article-element');
|
|
2026
|
+
* tracker.addPageLeaveTracking(articleElement, pageElement);
|
|
2027
|
+
* ```
|
|
2028
|
+
*
|
|
2029
|
+
* Passing '\{ objectResizable: true \}' as the 4th param makes the SDK re-calculate the object height whenever it changes,
|
|
2030
|
+
* which is useful for when the page or object changes size after loading, by ex
|
|
2031
|
+
* ```
|
|
2032
|
+
* ...
|
|
2033
|
+
* tracker.addPageLeaveTracking(articleElement, pageElement, undefined, {
|
|
2034
|
+
* objectResizable: true,
|
|
2035
|
+
* });
|
|
2036
|
+
* ```
|
|
2037
|
+
*
|
|
2038
|
+
* Keep in mind that the Beacon API is used to send events to page leave, and in order to guarantee as good as
|
|
2039
|
+
* possible that these events are sent, the event creator parameter should be synchronous.
|
|
2040
|
+
*
|
|
2041
|
+
* For the same reasons, we advise that the event creator parameter returns an event that does not contain any promises.
|
|
2042
|
+
*
|
|
2043
|
+
* @param {Element} objectElement The DOM element that is used to calculate various view-related fields in the default event.
|
|
2044
|
+
* @param {Element} pageElement The DOM element that represents the page that the user is currently on.
|
|
2045
|
+
* @param {LeaveEventBuilder} eventBuilder Function that returns an event to send when user leaves the page.
|
|
2046
|
+
* @param {LeaveEventOptions} options
|
|
2047
|
+
* @returns {(leaveEvent: LeaveEvent) => void} A function to update the event to send on page leave.
|
|
2048
|
+
* @category Leave Event
|
|
2049
|
+
*/
|
|
2050
|
+
addPageLeaveTracking(objectElement, pageElement, eventBuilder, options = {}) {
|
|
2051
|
+
addPageLeaveTracking(this, objectElement, pageElement, eventBuilder, options);
|
|
2052
|
+
return updatePageLeaveEvent;
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* Stop sending events when users leave a page.
|
|
2056
|
+
* Removes all event handlers, meaning that to event will be sent if the user leaves the page.
|
|
2057
|
+
* @category Leave Event
|
|
2058
|
+
*/
|
|
2059
|
+
removePageLeaveTracking() {
|
|
2060
|
+
removePageLeaveTracking(this);
|
|
2061
|
+
}
|
|
2062
|
+
/**
|
|
2063
|
+
* Update leave tracking.
|
|
2064
|
+
* Updates the DOM element used to calculate the default fields in the Leave event.
|
|
2065
|
+
* @param objectElement The DOM element that is used to calculate various view-related fields in the default event.
|
|
2066
|
+
* @param pageElement The DOM element that represents the page that the user is currently on.
|
|
2067
|
+
* @param resetProperties A flag that decided whether the engagement properties of the Leave event should
|
|
2068
|
+
* be reset when the tracking is updated. Defaults to false.
|
|
2069
|
+
* @category Leave Event
|
|
2070
|
+
*/
|
|
2071
|
+
updatePageLeaveTracking(objectElement, pageElement, resetProperties = false) {
|
|
2072
|
+
updatePageLeaveTracking(objectElement, pageElement, resetProperties);
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Manually trigger a viewed content recalculation including resetting max-values
|
|
2076
|
+
* @param objectElement The DOM element that is used to calculate various view-related fields in the
|
|
2077
|
+
* default event.
|
|
2078
|
+
* @param pageElement The DOM element that represents the page that the user is currently on.
|
|
2079
|
+
* @category Leave Event
|
|
2080
|
+
*/
|
|
2081
|
+
resetPageLeaveViewedContent(objectElement, pageElement) {
|
|
2082
|
+
resetViewedContent();
|
|
2083
|
+
updateViewedContent(objectElement, pageElement);
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* Manually trigger a viewed content recalculation without resetting max-values
|
|
2087
|
+
* @param objectElement The DOM element that is used to calculate various view-related fields in the
|
|
2088
|
+
* default event.
|
|
2089
|
+
* @param pageElement The DOM element that represents the page that the user is currently on.
|
|
2090
|
+
* @category Leave Event
|
|
2091
|
+
*/
|
|
2092
|
+
updatePageLeaveViewedContent(objectElement, pageElement) {
|
|
2093
|
+
updateViewedContent(objectElement, pageElement);
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Manually trigger a Leave event
|
|
2097
|
+
* Useful if for example the consuming website is an SPA and the normal browser events are not triggered.
|
|
2098
|
+
* is generated internally in the SDK.
|
|
2099
|
+
* @param eventInput
|
|
2100
|
+
* @param eventName The optional name of the browser event to simulate.
|
|
2101
|
+
* @category Leave Event
|
|
2102
|
+
*/
|
|
2103
|
+
async trackPageLeave(eventInput, eventName) {
|
|
2104
|
+
await trackPageLeave(this, eventInput, eventName);
|
|
2105
|
+
}
|
|
2106
|
+
/**
|
|
2107
|
+
* Manually trigger a Leave event only if Page Leave tracking is active in the SDK
|
|
2108
|
+
* This method works similarly to
|
|
2109
|
+
* ```
|
|
2110
|
+
* trackPageLeave(event: LeaveEvent, eventName?: string)
|
|
2111
|
+
* ```
|
|
2112
|
+
* with the added guarantee that a second Leave event will not be triggered if one already has been sent.
|
|
2113
|
+
* is generated internally in the SDK.
|
|
2114
|
+
* @param eventInput
|
|
2115
|
+
* @param eventName The optional name of the browser event to simulate.
|
|
2116
|
+
* @category Leave Event
|
|
2117
|
+
*/
|
|
2118
|
+
trackActivePageLeave(eventInput, eventName) {
|
|
2119
|
+
trackActivePageLeave(this, eventInput, eventName);
|
|
2120
|
+
}
|
|
2121
|
+
/**
|
|
2122
|
+
* Check if leave tracking is enabled (if an event will be sent when the user leaves the page)
|
|
2123
|
+
* ```
|
|
2124
|
+
* isLeaveTrackingActive()
|
|
2125
|
+
* ```
|
|
2126
|
+
* @category Leave Event
|
|
2127
|
+
*/
|
|
2128
|
+
isLeaveTrackingActive() {
|
|
2129
|
+
return leaveTrackingIsActive();
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Update leave tracking.
|
|
2133
|
+
* Updates the DOM element used to calculate the default fields in the Leave event.
|
|
2134
|
+
* @param {Element} objectElement The DOM element that is used to calculate various view-related fields in the default event.
|
|
2135
|
+
* @param {Element} pageElement The DOM element that represents the page that the user is currently on.
|
|
2136
|
+
* @param {boolean} resetProperties A flag that decided whether the engagement properties of the Leave event should
|
|
2137
|
+
* be reset when the tracking is updated. Defaults to false.
|
|
2138
|
+
* @category TPaaS Leave Tracking
|
|
2139
|
+
*/
|
|
2140
|
+
updateTpaasLeaveTracking(objectElement, pageElement, resetProperties = false) {
|
|
2141
|
+
updateTpaasLeaveTracking(objectElement, pageElement, resetProperties);
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Manually trigger a viewed content recalculation including resetting max-values
|
|
2145
|
+
* @param {Element} objectElement The DOM element that is used to calculate various view-related fields in the
|
|
2146
|
+
* default event.
|
|
2147
|
+
* @param {Element} pageElement The DOM element that represents the page that the user is currently on.
|
|
2148
|
+
* @category TPaaS Leave Tracking
|
|
2149
|
+
*/
|
|
2150
|
+
resetTpaasLeaveViewedContent(objectElement, pageElement) {
|
|
2151
|
+
resetTpaasViewedContent();
|
|
2152
|
+
updateTpaasViewedContent(objectElement, pageElement);
|
|
2153
|
+
}
|
|
2154
|
+
/**
|
|
2155
|
+
* Manually trigger a viewed content recalculation without resetting max-values
|
|
2156
|
+
* @param {Element} objectElement The DOM element that is used to calculate various view-related fields in the
|
|
2157
|
+
* default event.
|
|
2158
|
+
* @param {Element} pageElement The DOM element that represents the page that the user is currently on.
|
|
2159
|
+
* @category TPaaS Leave Tracking
|
|
2160
|
+
*/
|
|
2161
|
+
updateTpaasLeaveViewedContent(objectElement, pageElement) {
|
|
2162
|
+
updateTpaasViewedContent(objectElement, pageElement);
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Get the current Leave object. Useful to fetch before manually sending a leave event using one of the trackLeaveX TPaaS methods.
|
|
2166
|
+
* @returns {ILeave} The current Leave event object.
|
|
2167
|
+
* @category TPaaS Leave Tracking
|
|
2168
|
+
*/
|
|
2169
|
+
getTpaasLeaveObject() {
|
|
2170
|
+
return getTpaasLeaveObject();
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Manually trigger a Leave event only if Page Leave tracking is active in the SDK
|
|
2174
|
+
* This method works similarly to the track TPaaS methods trackLeaveX
|
|
2175
|
+
* ```
|
|
2176
|
+
* trackLeavePage(input: InputParams<ILeavePage>)
|
|
2177
|
+
* ```
|
|
2178
|
+
* with the added guarantee that a second Leave event will not be triggered if one already has been sent.
|
|
2179
|
+
* @category TPaaS Leave Tracking
|
|
2180
|
+
*/
|
|
2181
|
+
trackTpaasActiveLeave() {
|
|
2182
|
+
trackTpaasActiveLeave();
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Check if leave tracking is enabled (if an event will be sent when the user leaves the page)
|
|
2186
|
+
* ```
|
|
2187
|
+
* isLeaveTpaasTrackingActive()
|
|
2188
|
+
* ```
|
|
2189
|
+
* @category TPaaS Leave Tracking
|
|
2190
|
+
*/
|
|
2191
|
+
isLeaveTpaasTrackingActive() {
|
|
2192
|
+
return leaveTpaasTrackingIsActive();
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Start listening for events from the Tracker Proxy clients.
|
|
2196
|
+
* @returns teardown function that stops the listener
|
|
2197
|
+
*/
|
|
2198
|
+
exposeToProxyClients() {
|
|
2199
|
+
return startProxyProviderListener(this);
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* @param input
|
|
2203
|
+
* @private
|
|
2204
|
+
*/
|
|
2205
|
+
async resolveTrackInput(input) {
|
|
2206
|
+
return evaluateAndFlatten(input);
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* @private
|
|
2210
|
+
*/
|
|
2211
|
+
async resolveTrackGlobals() {
|
|
2212
|
+
return evaluateAndFlatten({ ...this.builders });
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* Send all anonymous events that are in the internal anonymous event queue.
|
|
2216
|
+
*
|
|
2217
|
+
* The returned Promise will resolve with the array of anonymous events that was
|
|
2218
|
+
* successfully transmitted. These anonymous events will have been removed from the anonymous event
|
|
2219
|
+
* queue. If the promise rejects, it means that the anonymous event queue could not be
|
|
2220
|
+
* sent and the promise rejection will contain the anonymous events that failed.
|
|
2221
|
+
* Anonymous events that are unsuccessfully sent will remain in the anonymous event queue.
|
|
2222
|
+
*
|
|
2223
|
+
* @internal
|
|
2224
|
+
*
|
|
2225
|
+
*/
|
|
2226
|
+
async _sendImmediatelyAnonymous() {
|
|
2227
|
+
if (this.anonymousEventQueue.length + this.retryAnonymousEventQueue.length <= 0) {
|
|
2228
|
+
return [];
|
|
2229
|
+
}
|
|
2230
|
+
// Anonymous events are sent without any user identifiers, independently of CIS, so no waiting for CIS sync here
|
|
2231
|
+
return this.prepareQueuesAndSend(this.anonymousEventQueue, this.retryAnonymousEventQueue);
|
|
2232
|
+
}
|
|
2233
|
+
/**
|
|
2234
|
+
* @param event
|
|
2235
|
+
* @param options
|
|
2236
|
+
* @internal
|
|
2237
|
+
*/
|
|
2238
|
+
_pushAnonymous(event, options = {}) {
|
|
2239
|
+
const deferredEvent = defer(event);
|
|
2240
|
+
this.anonymousEventQueue.push(deferredEvent);
|
|
2241
|
+
if (options.resolveOnQueued) {
|
|
2242
|
+
deferredEvent.resolve(event);
|
|
2243
|
+
}
|
|
2244
|
+
return deferredEvent.promise;
|
|
2245
|
+
}
|
|
2246
|
+
/**
|
|
2247
|
+
* Send the current anonymous event queue to the back end event receiver. This event is
|
|
2248
|
+
* debounced, @see {SDKConfigInput} to override the default timing.
|
|
2249
|
+
*
|
|
2250
|
+
* This method is called by `trackAnonymous()` so it is not necessary to call after
|
|
2251
|
+
* adding events to the queue.
|
|
2252
|
+
*
|
|
2253
|
+
* @internal
|
|
2254
|
+
*/
|
|
2255
|
+
async sendAnonymous() {
|
|
2256
|
+
if (this.state.useBeacon) {
|
|
2257
|
+
try {
|
|
2258
|
+
return await this._sendImmediatelyAnonymous();
|
|
2259
|
+
}
|
|
2260
|
+
catch (err) {
|
|
2261
|
+
return err;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
return this.debouncedSendAnonymous();
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Prepares the received event queue and handles success / failure after sending.
|
|
2268
|
+
*
|
|
2269
|
+
* @param eventQueue
|
|
2270
|
+
* @param retryEventQueue
|
|
2271
|
+
* @private
|
|
2272
|
+
*/
|
|
2273
|
+
async prepareQueuesAndSend(eventQueue, retryEventQueue) {
|
|
2274
|
+
const promisesToBeSent = eventQueue.splice(0);
|
|
2275
|
+
const eventsToBeSent = promisesToBeSent.map((p) => p.inputValue);
|
|
2276
|
+
const eventsToRetry = retryEventQueue;
|
|
2277
|
+
eventQueue.length = 0;
|
|
2278
|
+
retryEventQueue.length = 0;
|
|
2279
|
+
const evaluatedEvents = await Promise.all(eventsToBeSent);
|
|
2280
|
+
const url = this._getCollectorPath();
|
|
2281
|
+
const data = [...evaluatedEvents, ...eventsToRetry];
|
|
2282
|
+
// biome-ignore lint/suspicious/noExplicitAny: -
|
|
2283
|
+
async function onFailedSend(response) {
|
|
2284
|
+
// We retry an event once, but discard already retried events
|
|
2285
|
+
retryEventQueue.push(...evaluatedEvents);
|
|
2286
|
+
for (const promise of promisesToBeSent) {
|
|
2287
|
+
promise.reject(response);
|
|
2288
|
+
}
|
|
2289
|
+
return Promise.reject(evaluatedEvents);
|
|
2290
|
+
}
|
|
2291
|
+
try {
|
|
2292
|
+
const response = await send(url, data, this.state);
|
|
2293
|
+
if (response.status >= 400) {
|
|
2294
|
+
return onFailedSend(response);
|
|
2295
|
+
}
|
|
2296
|
+
for (const promise of promisesToBeSent) {
|
|
2297
|
+
promise.resolve(response);
|
|
2298
|
+
}
|
|
2299
|
+
return evaluatedEvents;
|
|
2300
|
+
}
|
|
2301
|
+
catch (error) {
|
|
2302
|
+
return onFailedSend(error);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
/**
|
|
2306
|
+
* Creates a new event with values that are global to all event types, and are resolved internally by the sdk.
|
|
2307
|
+
* `creationDate` and `session` are defined as early as possible in the event lifecycle, ensuring they are aligned
|
|
2308
|
+
* and consistent across all events.
|
|
2309
|
+
*
|
|
2310
|
+
* @category Tracker
|
|
2311
|
+
* @private
|
|
2312
|
+
*/
|
|
2313
|
+
createEvent(eventInput) {
|
|
2314
|
+
const creationDate = new Date();
|
|
2315
|
+
const session = sessionBuilder({}, creationDate);
|
|
2316
|
+
// Resolve any pending session ID promises
|
|
2317
|
+
this.resolveSessionIdPromise();
|
|
2318
|
+
return pulseMerge({}, eventInput, {
|
|
2319
|
+
'@id': v4(),
|
|
2320
|
+
creationDate: creationDate.toISOString(),
|
|
2321
|
+
session,
|
|
2322
|
+
});
|
|
2323
|
+
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Helper method to resolve any pending session ID promise
|
|
2326
|
+
* @private
|
|
2327
|
+
*/
|
|
2328
|
+
resolveSessionIdPromise() {
|
|
2329
|
+
const session = readSession();
|
|
2330
|
+
if (session?.id) {
|
|
2331
|
+
eventBus.emit('tracker:session:new', {
|
|
2332
|
+
sessionId: session.id,
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Creates a new anonymous event with values that are global to all event types, and are resolved internally by the sdk.
|
|
2338
|
+
* `creationDate` is defined as early as possible in the event lifecycle, ensuring it is aligned and consistent across all events.
|
|
2339
|
+
*
|
|
2340
|
+
* Note: anonymous events do not have a `session` object.
|
|
2341
|
+
*
|
|
2342
|
+
* @category Tracker
|
|
2343
|
+
* @private
|
|
2344
|
+
*/
|
|
2345
|
+
createAnonymousEvent(eventInput) {
|
|
2346
|
+
const creationDate = new Date();
|
|
2347
|
+
return pulseMerge({}, eventInput, {
|
|
2348
|
+
'@id': v4(),
|
|
2349
|
+
creationDate: creationDate.toISOString(),
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
/**
|
|
2353
|
+
* applyEventTypeDefaults
|
|
2354
|
+
* @param eventInput
|
|
2355
|
+
* @param eventType
|
|
2356
|
+
* @private
|
|
2357
|
+
*/
|
|
2358
|
+
applyEventTypeDefaults(eventInput, eventType) {
|
|
2359
|
+
const eventDefaults = getEventBuilder(eventType).defaults;
|
|
2360
|
+
return pulseMerge({}, eventDefaults(), eventInput);
|
|
2361
|
+
}
|
|
2362
|
+
/**
|
|
2363
|
+
* @param eventInput
|
|
2364
|
+
* @param eventType
|
|
2365
|
+
* @private
|
|
2366
|
+
*/
|
|
2367
|
+
applyAnonymousEventTypeDefaults(eventInput, eventType) {
|
|
2368
|
+
const eventDefaults = getAnonymousEventBuilder(eventType).defaults;
|
|
2369
|
+
return pulseMerge({}, eventDefaults(), eventInput);
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* applyBookmarkedEvent
|
|
2373
|
+
* @param eventInput
|
|
2374
|
+
* @param bookmarkKey
|
|
2375
|
+
* @private
|
|
2376
|
+
*/
|
|
2377
|
+
applyBookmarkedEvent(eventInput, bookmarkKey) {
|
|
2378
|
+
if (!bookmarkKey) {
|
|
2379
|
+
return eventInput;
|
|
2380
|
+
}
|
|
2381
|
+
const eventOutput = Object.assign({}, eventInput);
|
|
2382
|
+
const bookmarkedPageViewEvent = this.bookmark.get(bookmarkKey) ?? {};
|
|
2383
|
+
const { '@id': _id, '@type': _type, creationDate: _creationDate, ...coreEvent } = bookmarkedPageViewEvent;
|
|
2384
|
+
return pulseMerge({}, eventOutput, coreEvent);
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* applyConsents
|
|
2388
|
+
* @param eventInput
|
|
2389
|
+
* @private
|
|
2390
|
+
*/
|
|
2391
|
+
async applyConsents(eventInput) {
|
|
2392
|
+
return pulseMerge({}, eventInput, await this.evaluateConsents());
|
|
2393
|
+
}
|
|
2394
|
+
/**
|
|
2395
|
+
* applyConsentsAnonymous
|
|
2396
|
+
* @param eventInput
|
|
2397
|
+
* @private
|
|
2398
|
+
*/
|
|
2399
|
+
applyConsentsAnonymous(eventInput) {
|
|
2400
|
+
return pulseMerge({}, eventInput, this.evaluateConsentsAnonymous());
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Enriches the event with consent data saved in state.
|
|
2404
|
+
* @private
|
|
2405
|
+
* @category Consents
|
|
2406
|
+
*/
|
|
2407
|
+
async evaluateConsents() {
|
|
2408
|
+
const consents = await this.state.consents;
|
|
2409
|
+
this.state.consents = consents; // replace state consents with resolved value; helps anonymous tracking, because that doesn't await consent promises
|
|
2410
|
+
return {
|
|
2411
|
+
...(consents && { consents }),
|
|
2412
|
+
};
|
|
2413
|
+
}
|
|
2414
|
+
/**
|
|
2415
|
+
* Enriches the anonymous event with consent data saved in state.
|
|
2416
|
+
*
|
|
2417
|
+
* If the consents are a promise, it will return a fallback consent object, instead of waiting for consents to resolve
|
|
2418
|
+
* @private
|
|
2419
|
+
* @category Consents
|
|
2420
|
+
*/
|
|
2421
|
+
evaluateConsentsAnonymous() {
|
|
2422
|
+
const consents = isPromise(this.state.consents) ? getFallbackConsents() : this.state.consents;
|
|
2423
|
+
return {
|
|
2424
|
+
...(consents && { consents }),
|
|
2425
|
+
};
|
|
2426
|
+
}
|
|
2427
|
+
/**
|
|
2428
|
+
* Private version of {@link setConsents} that works with autoCreateConsents
|
|
2429
|
+
* @param consentsInput
|
|
2430
|
+
* @private
|
|
2431
|
+
* @category Consents
|
|
2432
|
+
*/
|
|
2433
|
+
setConsentsInternal(consentsInput) {
|
|
2434
|
+
const currentIncludeAdvertising = this.state.includeAdvertising;
|
|
2435
|
+
const updatedIncludeAdvertising = applyAdvertisingConsentSync(consentsInput, this.state.requireAdvertisingOptIn);
|
|
2436
|
+
this.state.includeAdvertising = updatedIncludeAdvertising;
|
|
2437
|
+
this.state.consents = consentsInput;
|
|
2438
|
+
// Only require a CIS sync if the user has changed their advertising consent
|
|
2439
|
+
if (currentIncludeAdvertising !== updatedIncludeAdvertising) {
|
|
2440
|
+
identity.requireCisSyncCallForAdvertisingIds();
|
|
2441
|
+
}
|
|
2442
|
+
logger.debug('Consents set', consentsInput);
|
|
2443
|
+
return { ...this.state.consents };
|
|
2444
|
+
}
|
|
2445
|
+
/**
|
|
2446
|
+
* Get the includeAdvertising flag, set on initialisation.
|
|
2447
|
+
* @see constructor
|
|
2448
|
+
* @private
|
|
2449
|
+
* @category Identifiers
|
|
2450
|
+
*/
|
|
2451
|
+
async getIncludeAdvertising() {
|
|
2452
|
+
await this._applyRemoteConfigEndpoints();
|
|
2453
|
+
return identity.getIncludeAdvertising(this.state);
|
|
2454
|
+
}
|
|
2455
|
+
}
|