@metamask-previews/analytics-controller 2.1.0-preview-abca9bcea → 3.0.0-preview-0a30e47
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/CHANGELOG.md +19 -1
- package/dist/{AnalyticsController-method-action-types.d.mts → AnalyticsController-method-action-types.d.ts} +2 -2
- package/dist/AnalyticsController-method-action-types.d.ts.map +1 -0
- package/dist/{AnalyticsController-method-action-types.mjs → AnalyticsController-method-action-types.js} +1 -1
- package/dist/AnalyticsController-method-action-types.js.map +1 -0
- package/dist/{AnalyticsController.d.cts → AnalyticsController.d.ts} +9 -9
- package/dist/AnalyticsController.d.ts.map +1 -0
- package/dist/AnalyticsController.js +1193 -0
- package/dist/AnalyticsController.js.map +1 -0
- package/dist/AnalyticsLogger.d.ts +4 -0
- package/dist/AnalyticsLogger.d.ts.map +1 -0
- package/dist/{AnalyticsLogger.mjs → AnalyticsLogger.js} +2 -2
- package/dist/AnalyticsLogger.js.map +1 -0
- package/dist/{AnalyticsPlatformAdapter.types.d.mts → AnalyticsPlatformAdapter.types.d.ts} +2 -2
- package/dist/AnalyticsPlatformAdapter.types.d.ts.map +1 -0
- package/dist/AnalyticsPlatformAdapter.types.js +2 -0
- package/dist/AnalyticsPlatformAdapter.types.js.map +1 -0
- package/dist/{AnalyticsPlatformAdapterSetupError.d.cts → AnalyticsPlatformAdapterSetupError.d.ts} +1 -1
- package/dist/AnalyticsPlatformAdapterSetupError.d.ts.map +1 -0
- package/dist/{AnalyticsPlatformAdapterSetupError.mjs → AnalyticsPlatformAdapterSetupError.js} +2 -1
- package/dist/AnalyticsPlatformAdapterSetupError.js.map +1 -0
- package/dist/{EventFragment.types.d.cts → EventFragment.types.d.ts} +2 -2
- package/dist/EventFragment.types.d.ts.map +1 -0
- package/dist/EventFragment.types.js +2 -0
- package/dist/EventFragment.types.js.map +1 -0
- package/dist/{analyticsControllerStateValidator.d.mts → analyticsControllerStateValidator.d.ts} +2 -2
- package/dist/analyticsControllerStateValidator.d.ts.map +1 -0
- package/dist/{analyticsControllerStateValidator.mjs → analyticsControllerStateValidator.js} +1 -1
- package/dist/analyticsControllerStateValidator.js.map +1 -0
- package/dist/{index.d.cts → index.d.ts} +11 -11
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/{selectors.cjs → selectors.d.ts} +17 -18
- package/dist/selectors.d.ts.map +1 -0
- package/dist/{selectors.mjs → selectors.js} +1 -1
- package/dist/selectors.js.map +1 -0
- package/package.json +18 -22
- package/dist/AnalyticsController-method-action-types.cjs +0 -7
- package/dist/AnalyticsController-method-action-types.cjs.map +0 -1
- package/dist/AnalyticsController-method-action-types.d.cts +0 -185
- package/dist/AnalyticsController-method-action-types.d.cts.map +0 -1
- package/dist/AnalyticsController-method-action-types.d.mts.map +0 -1
- package/dist/AnalyticsController-method-action-types.mjs.map +0 -1
- package/dist/AnalyticsController.cjs +0 -991
- package/dist/AnalyticsController.cjs.map +0 -1
- package/dist/AnalyticsController.d.cts.map +0 -1
- package/dist/AnalyticsController.d.mts +0 -431
- package/dist/AnalyticsController.d.mts.map +0 -1
- package/dist/AnalyticsController.mjs +0 -987
- package/dist/AnalyticsController.mjs.map +0 -1
- package/dist/AnalyticsLogger.cjs +0 -8
- package/dist/AnalyticsLogger.cjs.map +0 -1
- package/dist/AnalyticsLogger.d.cts +0 -5
- package/dist/AnalyticsLogger.d.cts.map +0 -1
- package/dist/AnalyticsLogger.d.mts +0 -5
- package/dist/AnalyticsLogger.d.mts.map +0 -1
- package/dist/AnalyticsLogger.mjs.map +0 -1
- package/dist/AnalyticsPlatformAdapter.types.cjs +0 -3
- package/dist/AnalyticsPlatformAdapter.types.cjs.map +0 -1
- package/dist/AnalyticsPlatformAdapter.types.d.cts +0 -144
- package/dist/AnalyticsPlatformAdapter.types.d.cts.map +0 -1
- package/dist/AnalyticsPlatformAdapter.types.d.mts.map +0 -1
- package/dist/AnalyticsPlatformAdapter.types.mjs +0 -2
- package/dist/AnalyticsPlatformAdapter.types.mjs.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.cjs +0 -17
- package/dist/AnalyticsPlatformAdapterSetupError.cjs.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.d.cts.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.d.mts +0 -8
- package/dist/AnalyticsPlatformAdapterSetupError.d.mts.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.mjs.map +0 -1
- package/dist/EventFragment.types.cjs +0 -3
- package/dist/EventFragment.types.cjs.map +0 -1
- package/dist/EventFragment.types.d.cts.map +0 -1
- package/dist/EventFragment.types.d.mts +0 -111
- package/dist/EventFragment.types.d.mts.map +0 -1
- package/dist/EventFragment.types.mjs +0 -2
- package/dist/EventFragment.types.mjs.map +0 -1
- package/dist/analyticsControllerStateValidator.cjs +0 -36
- package/dist/analyticsControllerStateValidator.cjs.map +0 -1
- package/dist/analyticsControllerStateValidator.d.cts +0 -17
- package/dist/analyticsControllerStateValidator.d.cts.map +0 -1
- package/dist/analyticsControllerStateValidator.d.mts.map +0 -1
- package/dist/analyticsControllerStateValidator.mjs.map +0 -1
- package/dist/index.cjs +0 -15
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.mts +0 -11
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -7
- package/dist/index.mjs.map +0 -1
- package/dist/selectors.cjs.map +0 -1
- package/dist/selectors.d.cts +0 -15
- package/dist/selectors.d.cts.map +0 -1
- package/dist/selectors.d.mts +0 -15
- package/dist/selectors.d.mts.map +0 -1
- package/dist/selectors.mjs.map +0 -1
|
@@ -1,991 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
-
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _AnalyticsController_instances, _AnalyticsController_platformAdapter, _AnalyticsController_isAnonymousEventsFeatureEnabled, _AnalyticsController_isEventQueuePersistenceEnabled, _AnalyticsController_isPreConsentQueueEnabled, _AnalyticsController_isGeolocationEnabled, _AnalyticsController_isEventFragmentsEnabled, _AnalyticsController_initPromise, _AnalyticsController_locationResolvePromise, _AnalyticsController_locationContext, _AnalyticsController_performInit, _AnalyticsController_maybeResolveLocation, _AnalyticsController_resolveLocationContext, _AnalyticsController_withLocationContext, _AnalyticsController_sendOrQueueTrackEvent, _AnalyticsController_sendOrQueueIdentifyEvent, _AnalyticsController_sendOrQueueViewEvent, _AnalyticsController_enqueueEvent, _AnalyticsController_sendQueuedEvent, _AnalyticsController_replayQueuedEvents, _AnalyticsController_removeQueuedEvent, _AnalyticsController_clearQueuedEvents, _AnalyticsController_enqueuePreConsentEvent, _AnalyticsController_replayPreConsentEvents, _AnalyticsController_enrichPreConsentEvent, _AnalyticsController_clearPreConsentEvents, _AnalyticsController_reconcilePreConsentEvents, _AnalyticsController_reconcileEventFragments, _AnalyticsController_purgeStaleEventFragments, _AnalyticsController_getEventFragment, _AnalyticsController_setEventFragment, _AnalyticsController_removeEventFragment, _AnalyticsController_clearEventFragments, _AnalyticsController_shouldIgnoreEventFragmentCall, _AnalyticsController_emitEventFragment, _AnalyticsController_isAnalyticsCaptureAllowed;
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.AnalyticsController = exports.getDefaultAnalyticsControllerState = exports.EVENT_FRAGMENT_MAX_AGE = exports.controllerName = void 0;
|
|
16
|
-
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
-
const lodash_1 = require("lodash");
|
|
18
|
-
const uuid_1 = require("uuid");
|
|
19
|
-
const analyticsControllerStateValidator_js_1 = require("./analyticsControllerStateValidator.cjs");
|
|
20
|
-
const AnalyticsLogger_js_1 = require("./AnalyticsLogger.cjs");
|
|
21
|
-
const selectors_js_1 = require("./selectors.cjs");
|
|
22
|
-
// === GENERAL ===
|
|
23
|
-
/**
|
|
24
|
-
* The name of the {@link AnalyticsController}, used to namespace the
|
|
25
|
-
* controller's actions and events and to namespace the controller's state data
|
|
26
|
-
* when composed with other controllers.
|
|
27
|
-
*/
|
|
28
|
-
exports.controllerName = 'AnalyticsController';
|
|
29
|
-
/**
|
|
30
|
-
* Maximum age of a persisted event fragment, measured from
|
|
31
|
-
* {@link AnalyticsEventFragment.lastUpdated}.
|
|
32
|
-
*
|
|
33
|
-
* Fragments older than this are discarded during {@link AnalyticsController.init}
|
|
34
|
-
* without emitting a success or failure event. Confirmation journeys that span a
|
|
35
|
-
* restart are expected to resume within this window; abandoned ones must not keep
|
|
36
|
-
* `properties` or `sensitiveProperties` in storage indefinitely.
|
|
37
|
-
*/
|
|
38
|
-
exports.EVENT_FRAGMENT_MAX_AGE = 24 * 60 * 60 * 1000;
|
|
39
|
-
/**
|
|
40
|
-
* Returns default values for AnalyticsController state.
|
|
41
|
-
*
|
|
42
|
-
* Note: analyticsId is NOT included - it's an identity that must be
|
|
43
|
-
* provided by the platform (generated once on first run, then persisted).
|
|
44
|
-
*
|
|
45
|
-
* @returns Default state without analyticsId
|
|
46
|
-
*/
|
|
47
|
-
function getDefaultAnalyticsControllerState() {
|
|
48
|
-
return {
|
|
49
|
-
optedIn: false,
|
|
50
|
-
consentDecisionMade: false,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
exports.getDefaultAnalyticsControllerState = getDefaultAnalyticsControllerState;
|
|
54
|
-
/**
|
|
55
|
-
* The metadata for each property in {@link AnalyticsControllerState}.
|
|
56
|
-
*
|
|
57
|
-
* Both `optedIn` and `analyticsId` are persisted (`persist: true`).
|
|
58
|
-
* The platform must supply a valid UUIDv4 `analyticsId` on first run.
|
|
59
|
-
*/
|
|
60
|
-
const analyticsControllerMetadata = {
|
|
61
|
-
optedIn: {
|
|
62
|
-
includeInStateLogs: true,
|
|
63
|
-
persist: true,
|
|
64
|
-
includeInDebugSnapshot: true,
|
|
65
|
-
usedInUi: true,
|
|
66
|
-
},
|
|
67
|
-
analyticsId: {
|
|
68
|
-
includeInStateLogs: true,
|
|
69
|
-
persist: true,
|
|
70
|
-
includeInDebugSnapshot: true,
|
|
71
|
-
usedInUi: false,
|
|
72
|
-
},
|
|
73
|
-
eventQueue: {
|
|
74
|
-
includeInStateLogs: false,
|
|
75
|
-
persist: true,
|
|
76
|
-
includeInDebugSnapshot: false,
|
|
77
|
-
usedInUi: false,
|
|
78
|
-
},
|
|
79
|
-
consentDecisionMade: {
|
|
80
|
-
includeInStateLogs: true,
|
|
81
|
-
persist: true,
|
|
82
|
-
includeInDebugSnapshot: true,
|
|
83
|
-
usedInUi: true,
|
|
84
|
-
},
|
|
85
|
-
preConsentEventQueue: {
|
|
86
|
-
includeInStateLogs: false,
|
|
87
|
-
persist: true,
|
|
88
|
-
includeInDebugSnapshot: false,
|
|
89
|
-
usedInUi: false,
|
|
90
|
-
},
|
|
91
|
-
eventFragments: {
|
|
92
|
-
includeInStateLogs: false,
|
|
93
|
-
persist: true,
|
|
94
|
-
includeInDebugSnapshot: false,
|
|
95
|
-
usedInUi: false,
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
// === MESSENGER ===
|
|
99
|
-
const MESSENGER_EXPOSED_METHODS = [
|
|
100
|
-
'trackEvent',
|
|
101
|
-
'identify',
|
|
102
|
-
'trackView',
|
|
103
|
-
'optIn',
|
|
104
|
-
'optOut',
|
|
105
|
-
'resetConsentDecision',
|
|
106
|
-
'createEventFragment',
|
|
107
|
-
'upsertEventFragment',
|
|
108
|
-
'updateEventFragment',
|
|
109
|
-
'getEventFragmentById',
|
|
110
|
-
'deleteEventFragment',
|
|
111
|
-
'finalizeEventFragment',
|
|
112
|
-
];
|
|
113
|
-
/**
|
|
114
|
-
* Returns whether a value is a non-array object.
|
|
115
|
-
*
|
|
116
|
-
* @param value - The value to check.
|
|
117
|
-
* @returns True if the value is a record.
|
|
118
|
-
*/
|
|
119
|
-
function isRecord(value) {
|
|
120
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Returns whether a JSON value is a non-array object.
|
|
124
|
-
*
|
|
125
|
-
* @param value - The value to check.
|
|
126
|
-
* @returns True if the value is a JSON record.
|
|
127
|
-
*/
|
|
128
|
-
function isJsonRecord(value) {
|
|
129
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Builds the analytics location context from geolocation data, keeping only
|
|
133
|
-
* the fields the geolocation API was able to determine.
|
|
134
|
-
*
|
|
135
|
-
* @param geolocation - The geolocation data to convert.
|
|
136
|
-
* @returns The location context, or `undefined` when no field is known.
|
|
137
|
-
*/
|
|
138
|
-
function buildLocationContext(geolocation) {
|
|
139
|
-
const locationContext = {
|
|
140
|
-
...(geolocation.country === null
|
|
141
|
-
? {}
|
|
142
|
-
: { country_code: geolocation.country }),
|
|
143
|
-
...(geolocation.region === null ? {} : { region: geolocation.region }),
|
|
144
|
-
...(geolocation.timezone === null
|
|
145
|
-
? {}
|
|
146
|
-
: { timezone: geolocation.timezone }),
|
|
147
|
-
};
|
|
148
|
-
return Object.keys(locationContext).length === 0
|
|
149
|
-
? undefined
|
|
150
|
-
: locationContext;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Returns whether a value is a valid persisted analytics event.
|
|
154
|
-
*
|
|
155
|
-
* @param value - The value to check.
|
|
156
|
-
* @returns True if the value is a queued analytics event.
|
|
157
|
-
*/
|
|
158
|
-
function isAnalyticsQueuedEvent(value) {
|
|
159
|
-
if (!isRecord(value)) {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
if (typeof value.messageId !== 'string' ||
|
|
163
|
-
typeof value.timestamp !== 'string') {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
if (value.type === 'track') {
|
|
167
|
-
return (typeof value.eventName === 'string' &&
|
|
168
|
-
(value.properties === undefined || isRecord(value.properties)) &&
|
|
169
|
-
(value.context === undefined || isRecord(value.context)));
|
|
170
|
-
}
|
|
171
|
-
if (value.type === 'identify') {
|
|
172
|
-
return (typeof value.userId === 'string' &&
|
|
173
|
-
(value.traits === undefined || isRecord(value.traits)) &&
|
|
174
|
-
(value.context === undefined || isRecord(value.context)));
|
|
175
|
-
}
|
|
176
|
-
if (value.type === 'view') {
|
|
177
|
-
return (typeof value.name === 'string' &&
|
|
178
|
-
(value.properties === undefined || isRecord(value.properties)) &&
|
|
179
|
-
(value.context === undefined || isRecord(value.context)));
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Returns whether a value is a valid persisted event fragment.
|
|
185
|
-
*
|
|
186
|
-
* @param value - The value to check.
|
|
187
|
-
* @returns True if the value is an event fragment.
|
|
188
|
-
*/
|
|
189
|
-
function isAnalyticsEventFragment(value) {
|
|
190
|
-
if (!isRecord(value)) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
return (typeof value.id === 'string' &&
|
|
194
|
-
typeof value.createdAt === 'number' &&
|
|
195
|
-
typeof value.lastUpdated === 'number' &&
|
|
196
|
-
isRecord(value.properties) &&
|
|
197
|
-
isRecord(value.sensitiveProperties) &&
|
|
198
|
-
(value.initialEvent === undefined ||
|
|
199
|
-
typeof value.initialEvent === 'string') &&
|
|
200
|
-
(value.successEvent === undefined ||
|
|
201
|
-
typeof value.successEvent === 'string') &&
|
|
202
|
-
(value.failureEvent === undefined ||
|
|
203
|
-
typeof value.failureEvent === 'string') &&
|
|
204
|
-
(value.context === undefined || isRecord(value.context)) &&
|
|
205
|
-
(value.persist === undefined || typeof value.persist === 'boolean'));
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Merges a payload into an event fragment.
|
|
209
|
-
*
|
|
210
|
-
* `properties`, `sensitiveProperties` and `context` are merged one level deep,
|
|
211
|
-
* so a key written twice is replaced rather than combined. This keeps array
|
|
212
|
-
* values predictable: writing a shorter array replaces the longer one instead
|
|
213
|
-
* of leaving stale trailing entries behind.
|
|
214
|
-
*
|
|
215
|
-
* @param fragment - The fragment to merge into.
|
|
216
|
-
* @param payload - The payload to merge.
|
|
217
|
-
* @returns A new fragment with the payload applied.
|
|
218
|
-
*/
|
|
219
|
-
function mergeEventFragment(fragment, payload) {
|
|
220
|
-
const context = mergeEventFragmentContext(fragment.context, payload.context);
|
|
221
|
-
return {
|
|
222
|
-
...fragment,
|
|
223
|
-
properties: { ...fragment.properties, ...(payload.properties ?? {}) },
|
|
224
|
-
sensitiveProperties: {
|
|
225
|
-
...fragment.sensitiveProperties,
|
|
226
|
-
...(payload.sensitiveProperties ?? {}),
|
|
227
|
-
},
|
|
228
|
-
...(context === undefined ? {} : { context }),
|
|
229
|
-
lastUpdated: Date.now(),
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Merges two optional analytics contexts, preserving `undefined` when neither
|
|
234
|
-
* side has one so an empty context is never sent.
|
|
235
|
-
*
|
|
236
|
-
* @param base - The context to merge into.
|
|
237
|
-
* @param override - The context whose fields win.
|
|
238
|
-
* @returns The merged context, or `undefined` when both sides are unset.
|
|
239
|
-
*/
|
|
240
|
-
function mergeEventFragmentContext(base, override) {
|
|
241
|
-
if (base === undefined && override === undefined) {
|
|
242
|
-
return undefined;
|
|
243
|
-
}
|
|
244
|
-
return { ...(base ?? {}), ...(override ?? {}) };
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
|
|
248
|
-
* It provides a unified interface for tracking events, identifying users, and managing
|
|
249
|
-
* analytics preferences while delegating platform-specific implementation to an
|
|
250
|
-
* {@link AnalyticsPlatformAdapter}.
|
|
251
|
-
*
|
|
252
|
-
* This controller follows the MetaMask controller pattern and integrates with the
|
|
253
|
-
* messenger system to allow other controllers and components to track analytics events.
|
|
254
|
-
* It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.
|
|
255
|
-
*
|
|
256
|
-
* The controller persists `optedIn` and `analyticsId` when composed with a persisted
|
|
257
|
-
* store. The platform must supply a valid `analyticsId` on first launch.
|
|
258
|
-
*/
|
|
259
|
-
class AnalyticsController extends base_controller_1.BaseController {
|
|
260
|
-
/**
|
|
261
|
-
* Constructs an AnalyticsController instance.
|
|
262
|
-
*
|
|
263
|
-
* @param options - Controller options
|
|
264
|
-
* @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.
|
|
265
|
-
* Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.
|
|
266
|
-
* @param options.messenger - Messenger used to communicate with BaseController
|
|
267
|
-
* @param options.platformAdapter - Platform adapter implementation for tracking
|
|
268
|
-
* @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
|
|
269
|
-
* @param options.isEventQueuePersistenceEnabled - Whether analytics event queue persistence is enabled
|
|
270
|
-
* @param options.isPreConsentQueueEnabled - Whether the pre-consent event queue is enabled
|
|
271
|
-
* @param options.isGeolocationEnabled - Whether geolocation enrichment is enabled
|
|
272
|
-
* @param options.isEventFragmentsEnabled - Whether the event fragments feature is enabled
|
|
273
|
-
* @throws Error if state.analyticsId is missing or not a valid UUIDv4
|
|
274
|
-
* @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
|
|
275
|
-
*/
|
|
276
|
-
constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled = false, isEventQueuePersistenceEnabled = false, isPreConsentQueueEnabled = false, isGeolocationEnabled = false, isEventFragmentsEnabled = false, }) {
|
|
277
|
-
const initialState = {
|
|
278
|
-
...getDefaultAnalyticsControllerState(),
|
|
279
|
-
...state,
|
|
280
|
-
};
|
|
281
|
-
(0, analyticsControllerStateValidator_js_1.validateAnalyticsControllerState)(initialState, platformAdapter.skipUUIDv4Check === true);
|
|
282
|
-
super({
|
|
283
|
-
name: exports.controllerName,
|
|
284
|
-
metadata: analyticsControllerMetadata,
|
|
285
|
-
state: initialState,
|
|
286
|
-
messenger,
|
|
287
|
-
});
|
|
288
|
-
_AnalyticsController_instances.add(this);
|
|
289
|
-
_AnalyticsController_platformAdapter.set(this, void 0);
|
|
290
|
-
_AnalyticsController_isAnonymousEventsFeatureEnabled.set(this, void 0);
|
|
291
|
-
_AnalyticsController_isEventQueuePersistenceEnabled.set(this, void 0);
|
|
292
|
-
_AnalyticsController_isPreConsentQueueEnabled.set(this, void 0);
|
|
293
|
-
_AnalyticsController_isGeolocationEnabled.set(this, void 0);
|
|
294
|
-
_AnalyticsController_isEventFragmentsEnabled.set(this, void 0);
|
|
295
|
-
/**
|
|
296
|
-
* The in-flight (or settled) initialization promise. Set on the first
|
|
297
|
-
* {@link init} call and returned by subsequent calls so overlapping callers
|
|
298
|
-
* await the same work rather than observing a premature completion.
|
|
299
|
-
*/
|
|
300
|
-
_AnalyticsController_initPromise.set(this, void 0);
|
|
301
|
-
/**
|
|
302
|
-
* The in-flight (or settled) geolocation resolution, if any. Its presence
|
|
303
|
-
* marks that resolution has been started, so it runs at most once.
|
|
304
|
-
*/
|
|
305
|
-
_AnalyticsController_locationResolvePromise.set(this, void 0);
|
|
306
|
-
_AnalyticsController_locationContext.set(this, void 0);
|
|
307
|
-
__classPrivateFieldSet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, isAnonymousEventsFeatureEnabled, "f");
|
|
308
|
-
__classPrivateFieldSet(this, _AnalyticsController_isEventQueuePersistenceEnabled, isEventQueuePersistenceEnabled, "f");
|
|
309
|
-
__classPrivateFieldSet(this, _AnalyticsController_isPreConsentQueueEnabled, isPreConsentQueueEnabled, "f");
|
|
310
|
-
__classPrivateFieldSet(this, _AnalyticsController_isGeolocationEnabled, isGeolocationEnabled, "f");
|
|
311
|
-
__classPrivateFieldSet(this, _AnalyticsController_isEventFragmentsEnabled, isEventFragmentsEnabled, "f");
|
|
312
|
-
__classPrivateFieldSet(this, _AnalyticsController_platformAdapter, platformAdapter, "f");
|
|
313
|
-
__classPrivateFieldSet(this, _AnalyticsController_initPromise, undefined, "f");
|
|
314
|
-
__classPrivateFieldSet(this, _AnalyticsController_locationResolvePromise, undefined, "f");
|
|
315
|
-
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
316
|
-
(0, AnalyticsLogger_js_1.projectLogger)('AnalyticsController initialized and ready', {
|
|
317
|
-
enabled: selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state),
|
|
318
|
-
optedIn: this.state.optedIn,
|
|
319
|
-
consentDecisionMade: this.state.consentDecisionMade,
|
|
320
|
-
analyticsId: this.state.analyticsId,
|
|
321
|
-
eventQueuePersistenceEnabled: __classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f"),
|
|
322
|
-
preConsentQueueEnabled: __classPrivateFieldGet(this, _AnalyticsController_isPreConsentQueueEnabled, "f"),
|
|
323
|
-
geolocationEnabled: __classPrivateFieldGet(this, _AnalyticsController_isGeolocationEnabled, "f"),
|
|
324
|
-
eventFragmentsEnabled: __classPrivateFieldGet(this, _AnalyticsController_isEventFragmentsEnabled, "f"),
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Initialize the controller by calling the platform adapter's
|
|
329
|
-
* onSetupCompleted lifecycle hook and replaying any queued events. This
|
|
330
|
-
* method must be called after construction to complete the setup process.
|
|
331
|
-
*
|
|
332
|
-
* When geolocation enrichment is enabled (`isGeolocationEnabled`), geolocation
|
|
333
|
-
* is resolved only for a user who is already opted in; for undecided or
|
|
334
|
-
* opted-out users it is deferred until they opt in (see {@link optIn}), so a
|
|
335
|
-
* user's location is never requested before they consent to analytics. In
|
|
336
|
-
* either case the `GeolocationController` and its
|
|
337
|
-
* `GeolocationController:getGeolocationData` action must be registered before
|
|
338
|
-
* resolution occurs, or enrichment is skipped for the session (a message is
|
|
339
|
-
* logged, see {@link #resolveLocationContext}).
|
|
340
|
-
*
|
|
341
|
-
* Safe to call more than once: the first call performs initialization and
|
|
342
|
-
* subsequent calls return the same in-flight (or settled) promise.
|
|
343
|
-
*
|
|
344
|
-
* @returns A promise that resolves once initialization has completed.
|
|
345
|
-
*/
|
|
346
|
-
init() {
|
|
347
|
-
// Cache the in-flight promise so repeated or overlapping calls share a
|
|
348
|
-
// single initialization and all await the same completion (rather than an
|
|
349
|
-
// early call observing a finished init while work is still pending).
|
|
350
|
-
__classPrivateFieldSet(this, _AnalyticsController_initPromise, __classPrivateFieldGet(this, _AnalyticsController_initPromise, "f") ?? __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_performInit).call(this), "f");
|
|
351
|
-
return __classPrivateFieldGet(this, _AnalyticsController_initPromise, "f");
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Track an analytics event.
|
|
355
|
-
*
|
|
356
|
-
* Events are only tracked if analytics is enabled.
|
|
357
|
-
*
|
|
358
|
-
* @param event - Analytics event with properties and sensitive properties
|
|
359
|
-
* @param context - Optional platform-specific context forwarded to the platform adapter.
|
|
360
|
-
*/
|
|
361
|
-
trackEvent(event, context) {
|
|
362
|
-
// An event captured while the user is still undecided is held in the
|
|
363
|
-
// pre-consent queue (see #sendOrQueueTrackEvent) instead of being
|
|
364
|
-
// delivered, and replayed if they later opt in.
|
|
365
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_isAnalyticsCaptureAllowed).call(this)) {
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
// if event does not have properties, send event without properties
|
|
369
|
-
// and return to prevent any additional processing
|
|
370
|
-
if (!event.hasProperties) {
|
|
371
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, undefined, __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, context));
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
// Track regular properties first if anonymous events feature is enabled
|
|
375
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f")) {
|
|
376
|
-
// Note: Even if regular properties object is empty, we still send it to ensure
|
|
377
|
-
// an event with user ID is tracked.
|
|
378
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, {
|
|
379
|
-
...event.properties,
|
|
380
|
-
}, __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, context));
|
|
381
|
-
}
|
|
382
|
-
const hasSensitiveProperties = Object.keys(event.sensitiveProperties).length > 0;
|
|
383
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f") || hasSensitiveProperties) {
|
|
384
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, {
|
|
385
|
-
...event.properties,
|
|
386
|
-
...event.sensitiveProperties,
|
|
387
|
-
...(hasSensitiveProperties && { anonymous: true }),
|
|
388
|
-
},
|
|
389
|
-
// When the anonymous events feature is enabled, this payload is the
|
|
390
|
-
// anonymous one and must carry no geolocation. When the feature is
|
|
391
|
-
// disabled, this is the single identified payload, so it is enriched.
|
|
392
|
-
__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f")
|
|
393
|
-
? context
|
|
394
|
-
: __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, context));
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Identify a user for analytics.
|
|
399
|
-
*
|
|
400
|
-
* @param traits - User traits/properties
|
|
401
|
-
* @param context - Optional platform-specific context forwarded to the platform adapter.
|
|
402
|
-
*/
|
|
403
|
-
identify(traits, context) {
|
|
404
|
-
if (!selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
// Delegate to platform adapter using the current analytics ID
|
|
408
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueIdentifyEvent).call(this, this.state.analyticsId, traits, __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, context));
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Track a page or screen view.
|
|
412
|
-
*
|
|
413
|
-
* @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
|
|
414
|
-
* @param properties - Optional properties associated with the view
|
|
415
|
-
* @param context - Optional platform-specific context forwarded to the platform adapter.
|
|
416
|
-
*/
|
|
417
|
-
trackView(name, properties, context) {
|
|
418
|
-
if (!selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
// Delegate to platform adapter
|
|
422
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueViewEvent).call(this, name, properties, __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, context));
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Create an event fragment.
|
|
426
|
-
*
|
|
427
|
-
* A fragment accumulates properties across a user journey so that several
|
|
428
|
-
* parts of a client can contribute to the same set of events without
|
|
429
|
-
* re-deriving them. Declaring `successEvent` and `failureEvent` turns the
|
|
430
|
-
* fragment into a funnel that {@link finalizeEventFragment} closes. Declaring
|
|
431
|
-
* none of the event names makes it a pure property bag that the client reads
|
|
432
|
-
* back with {@link getEventFragmentById} when it emits its own events.
|
|
433
|
-
*
|
|
434
|
-
* Any existing fragment with the same ID is replaced, so a new journey never
|
|
435
|
-
* inherits properties from a stale one.
|
|
436
|
-
*
|
|
437
|
-
* Nothing is created unless the user is opted in, or undecided with the
|
|
438
|
-
* pre-consent queue enabled, so an opted-out user accumulates no fragment
|
|
439
|
-
* data.
|
|
440
|
-
*
|
|
441
|
-
* @param options - The fragment definition. An ID is generated when one is
|
|
442
|
-
* not supplied.
|
|
443
|
-
* @returns A read-only copy of the created fragment, or `undefined` when the
|
|
444
|
-
* event fragments feature is disabled or the consent state does not allow
|
|
445
|
-
* capture. Mutating the returned object does not change controller state.
|
|
446
|
-
* Use {@link updateEventFragment} or {@link upsertEventFragment} to write.
|
|
447
|
-
*/
|
|
448
|
-
createEventFragment(options = {}) {
|
|
449
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'createEventFragment')) {
|
|
450
|
-
return undefined;
|
|
451
|
-
}
|
|
452
|
-
const now = Date.now();
|
|
453
|
-
const fragment = {
|
|
454
|
-
id: options.id ?? (0, uuid_1.v4)(),
|
|
455
|
-
properties: { ...(options.properties ?? {}) },
|
|
456
|
-
sensitiveProperties: { ...(options.sensitiveProperties ?? {}) },
|
|
457
|
-
createdAt: now,
|
|
458
|
-
lastUpdated: now,
|
|
459
|
-
...(options.initialEvent === undefined
|
|
460
|
-
? {}
|
|
461
|
-
: { initialEvent: options.initialEvent }),
|
|
462
|
-
...(options.successEvent === undefined
|
|
463
|
-
? {}
|
|
464
|
-
: { successEvent: options.successEvent }),
|
|
465
|
-
...(options.failureEvent === undefined
|
|
466
|
-
? {}
|
|
467
|
-
: { failureEvent: options.failureEvent }),
|
|
468
|
-
...(options.context === undefined
|
|
469
|
-
? {}
|
|
470
|
-
: { context: { ...options.context } }),
|
|
471
|
-
...(options.persist === undefined ? {} : { persist: options.persist }),
|
|
472
|
-
};
|
|
473
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_setEventFragment).call(this, fragment);
|
|
474
|
-
if (fragment.initialEvent) {
|
|
475
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_emitEventFragment).call(this, fragment, fragment.initialEvent, fragment.context);
|
|
476
|
-
}
|
|
477
|
-
return (0, lodash_1.cloneDeep)(fragment);
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Write to an event fragment, creating a property bag if none exists.
|
|
481
|
-
*
|
|
482
|
-
* This is the ergonomic entry point for contributors that do not know
|
|
483
|
-
* whether the journey has been started yet, and it avoids the read then
|
|
484
|
-
* write race a caller would otherwise have to implement itself.
|
|
485
|
-
*
|
|
486
|
-
* @param id - The fragment ID.
|
|
487
|
-
* @param payload - The properties and context to merge in.
|
|
488
|
-
*/
|
|
489
|
-
upsertEventFragment(id, payload = {}) {
|
|
490
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'upsertEventFragment')) {
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
const fragment = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_getEventFragment).call(this, id);
|
|
494
|
-
if (!fragment) {
|
|
495
|
-
this.createEventFragment({ id, ...payload });
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_setEventFragment).call(this, mergeEventFragment(fragment, payload));
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Write to an existing event fragment.
|
|
502
|
-
*
|
|
503
|
-
* @param id - The fragment ID.
|
|
504
|
-
* @param payload - The properties and context to merge in.
|
|
505
|
-
* @throws Error if no fragment has that ID when the call is not ignored.
|
|
506
|
-
* Use {@link upsertEventFragment} when the fragment may not exist yet.
|
|
507
|
-
* When the event fragments feature is disabled or the consent state does not
|
|
508
|
-
* allow capture, the call is a logged no-op and does not throw.
|
|
509
|
-
*/
|
|
510
|
-
updateEventFragment(id, payload = {}) {
|
|
511
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'updateEventFragment')) {
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
const fragment = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_getEventFragment).call(this, id);
|
|
515
|
-
if (!fragment) {
|
|
516
|
-
throw new Error(`Event fragment with id ${id} does not exist.`);
|
|
517
|
-
}
|
|
518
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_setEventFragment).call(this, mergeEventFragment(fragment, payload));
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Read an event fragment.
|
|
522
|
-
*
|
|
523
|
-
* @param id - The fragment ID.
|
|
524
|
-
* @returns A read-only copy of the fragment, or `undefined` when no fragment
|
|
525
|
-
* has that ID, the event fragments feature is disabled, or the consent state
|
|
526
|
-
* does not allow capture. Mutating the returned object does not change
|
|
527
|
-
* controller state. Use {@link updateEventFragment} or
|
|
528
|
-
* {@link upsertEventFragment} to write.
|
|
529
|
-
*/
|
|
530
|
-
getEventFragmentById(id) {
|
|
531
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'getEventFragmentById')) {
|
|
532
|
-
return undefined;
|
|
533
|
-
}
|
|
534
|
-
const fragment = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_getEventFragment).call(this, id);
|
|
535
|
-
return fragment === undefined ? undefined : (0, lodash_1.cloneDeep)(fragment);
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Discard an event fragment without emitting anything.
|
|
539
|
-
*
|
|
540
|
-
* @param id - The fragment ID.
|
|
541
|
-
*/
|
|
542
|
-
deleteEventFragment(id) {
|
|
543
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'deleteEventFragment')) {
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeEventFragment).call(this, id);
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Close an event fragment, emitting its closing event and discarding it.
|
|
550
|
-
*
|
|
551
|
-
* The event emitted is `failureEvent` when the journey was abandoned and
|
|
552
|
-
* `successEvent` otherwise. A fragment that does not declare the relevant
|
|
553
|
-
* event name is discarded silently, which is what makes a pure property bag
|
|
554
|
-
* possible.
|
|
555
|
-
*
|
|
556
|
-
* @param id - The fragment ID.
|
|
557
|
-
* @param options - Finalization options.
|
|
558
|
-
* @param options.abandoned - Whether the journey was abandoned.
|
|
559
|
-
* @param options.context - Context merged over the fragment's own context.
|
|
560
|
-
* @throws Error if no fragment has that ID when the call is not ignored.
|
|
561
|
-
* When the event fragments feature is disabled or the consent state does not
|
|
562
|
-
* allow capture, the call is a logged no-op and does not throw.
|
|
563
|
-
*/
|
|
564
|
-
finalizeEventFragment(id, { abandoned = false, context } = {}) {
|
|
565
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_shouldIgnoreEventFragmentCall).call(this, 'finalizeEventFragment')) {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
const fragment = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_getEventFragment).call(this, id);
|
|
569
|
-
if (!fragment) {
|
|
570
|
-
throw new Error(`Event fragment with id ${id} does not exist.`);
|
|
571
|
-
}
|
|
572
|
-
const eventName = abandoned ? fragment.failureEvent : fragment.successEvent;
|
|
573
|
-
if (eventName) {
|
|
574
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_emitEventFragment).call(this, fragment, eventName, mergeEventFragmentContext(fragment.context, context));
|
|
575
|
-
}
|
|
576
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeEventFragment).call(this, id);
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Opt in to analytics.
|
|
580
|
-
*
|
|
581
|
-
* Records that a consent decision has been made and replays any events that
|
|
582
|
-
* were queued while the user was undecided.
|
|
583
|
-
*
|
|
584
|
-
* When geolocation enrichment is enabled, geolocation is resolved here (once
|
|
585
|
-
* the user has consented) and awaited before the queued events are replayed,
|
|
586
|
-
* so those events are enriched with the resolved location as they are sent.
|
|
587
|
-
*
|
|
588
|
-
* @returns A promise that resolves once opt-in processing has completed.
|
|
589
|
-
*/
|
|
590
|
-
async optIn() {
|
|
591
|
-
this.update((state) => {
|
|
592
|
-
state.optedIn = true;
|
|
593
|
-
state.consentDecisionMade = true;
|
|
594
|
-
});
|
|
595
|
-
// Now that the user has consented, resolve geolocation (once) and wait for
|
|
596
|
-
// it so the queued pre-consent events can be enriched as they replay.
|
|
597
|
-
await __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_maybeResolveLocation).call(this);
|
|
598
|
-
// Reconcile against the current state rather than replaying blindly: the
|
|
599
|
-
// consent decision may have changed while geolocation was resolving (e.g.
|
|
600
|
-
// resetConsentDecision ran during the await), and preserved pre-consent
|
|
601
|
-
// events must not be delivered once the user is no longer opted in.
|
|
602
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_reconcilePreConsentEvents).call(this);
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Opt out of analytics.
|
|
606
|
-
*
|
|
607
|
-
* Records that a consent decision has been made and discards any persisted
|
|
608
|
-
* events and in-progress event fragments so nothing captured before the
|
|
609
|
-
* decision is ever delivered.
|
|
610
|
-
*/
|
|
611
|
-
optOut() {
|
|
612
|
-
this.update((state) => {
|
|
613
|
-
state.optedIn = false;
|
|
614
|
-
state.consentDecisionMade = true;
|
|
615
|
-
});
|
|
616
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearQueuedEvents).call(this);
|
|
617
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearPreConsentEvents).call(this);
|
|
618
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearEventFragments).call(this);
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Reset the consent decision back to undecided.
|
|
622
|
-
*
|
|
623
|
-
* Intended for client flows that restart onboarding. Clears the opt-in
|
|
624
|
-
* preference and discards the delivery queue, but preserves any pre-consent
|
|
625
|
-
* events so they can still be replayed if the user opts in again. The user is
|
|
626
|
-
* treated as undecided again.
|
|
627
|
-
*
|
|
628
|
-
* In-progress event fragments are kept only while the undecided user can
|
|
629
|
-
* still accumulate them, and discarded otherwise, so no fragment outlives the
|
|
630
|
-
* consent state that allowed it.
|
|
631
|
-
*/
|
|
632
|
-
resetConsentDecision() {
|
|
633
|
-
this.update((state) => {
|
|
634
|
-
state.optedIn = false;
|
|
635
|
-
state.consentDecisionMade = false;
|
|
636
|
-
});
|
|
637
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearQueuedEvents).call(this);
|
|
638
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_isAnalyticsCaptureAllowed).call(this)) {
|
|
639
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearEventFragments).call(this);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
exports.AnalyticsController = AnalyticsController;
|
|
644
|
-
_AnalyticsController_platformAdapter = new WeakMap(), _AnalyticsController_isAnonymousEventsFeatureEnabled = new WeakMap(), _AnalyticsController_isEventQueuePersistenceEnabled = new WeakMap(), _AnalyticsController_isPreConsentQueueEnabled = new WeakMap(), _AnalyticsController_isGeolocationEnabled = new WeakMap(), _AnalyticsController_isEventFragmentsEnabled = new WeakMap(), _AnalyticsController_initPromise = new WeakMap(), _AnalyticsController_locationResolvePromise = new WeakMap(), _AnalyticsController_locationContext = new WeakMap(), _AnalyticsController_instances = new WeakSet(), _AnalyticsController_performInit =
|
|
645
|
-
/**
|
|
646
|
-
* Performs the one-time initialization work: resolve geolocation, run the
|
|
647
|
-
* platform adapter's onSetupCompleted lifecycle hook, then replay any queued
|
|
648
|
-
* and pre-consent events.
|
|
649
|
-
*/
|
|
650
|
-
async function _AnalyticsController_performInit() {
|
|
651
|
-
// Snapshot fragment IDs and createdAt before any awaited init work so
|
|
652
|
-
// reconciliation can tell previous-session leftovers from fragments
|
|
653
|
-
// created or replaced while init runs.
|
|
654
|
-
const initEventFragmentSnapshot = new Map();
|
|
655
|
-
for (const [id, fragment] of Object.entries(this.state.eventFragments ?? {})) {
|
|
656
|
-
if (isAnalyticsEventFragment(fragment) &&
|
|
657
|
-
fragment.id === id &&
|
|
658
|
-
typeof fragment.createdAt === 'number') {
|
|
659
|
-
initEventFragmentSnapshot.set(id, fragment.createdAt);
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
// Resolve geolocation only when the user is already opted in; for undecided
|
|
663
|
-
// or opted-out users it is deferred to {@link optIn}. Awaited so that an
|
|
664
|
-
// already-opted-in session has location available before events replay.
|
|
665
|
-
await __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_maybeResolveLocation).call(this);
|
|
666
|
-
// Call onSetupCompleted lifecycle hook after initialization
|
|
667
|
-
// State is already validated, so analyticsId is guaranteed to be a valid UUIDv4
|
|
668
|
-
try {
|
|
669
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").onSetupCompleted(this.state.analyticsId);
|
|
670
|
-
}
|
|
671
|
-
catch (error) {
|
|
672
|
-
// Log error but don't throw - adapter setup failure shouldn't break controller
|
|
673
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Error calling platformAdapter.onSetupCompleted', error);
|
|
674
|
-
}
|
|
675
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_replayQueuedEvents).call(this);
|
|
676
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_reconcilePreConsentEvents).call(this);
|
|
677
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_reconcileEventFragments).call(this, initEventFragmentSnapshot);
|
|
678
|
-
}, _AnalyticsController_maybeResolveLocation = function _AnalyticsController_maybeResolveLocation() {
|
|
679
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_isGeolocationEnabled, "f") &&
|
|
680
|
-
__classPrivateFieldGet(this, _AnalyticsController_locationResolvePromise, "f") === undefined &&
|
|
681
|
-
selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
682
|
-
__classPrivateFieldSet(this, _AnalyticsController_locationResolvePromise, __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_resolveLocationContext).call(this), "f");
|
|
683
|
-
}
|
|
684
|
-
return __classPrivateFieldGet(this, _AnalyticsController_locationResolvePromise, "f");
|
|
685
|
-
}, _AnalyticsController_resolveLocationContext = async function _AnalyticsController_resolveLocationContext() {
|
|
686
|
-
try {
|
|
687
|
-
const geolocation = await this.messenger.call('GeolocationController:getGeolocationData');
|
|
688
|
-
__classPrivateFieldSet(this, _AnalyticsController_locationContext, buildLocationContext(geolocation), "f");
|
|
689
|
-
}
|
|
690
|
-
catch (error) {
|
|
691
|
-
// A common cause is the GeolocationController not being registered before
|
|
692
|
-
// resolution runs (at init for an opted-in user, otherwise at opt-in).
|
|
693
|
-
// Name it here so the failure is diagnosable, since enrichment is
|
|
694
|
-
// otherwise skipped silently for the session.
|
|
695
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Failed to resolve geolocation for analytics enrichment; events will be sent without location. Ensure the GeolocationController is registered and initialized before the user opts in when geolocation is enabled.', error);
|
|
696
|
-
}
|
|
697
|
-
}, _AnalyticsController_withLocationContext = function _AnalyticsController_withLocationContext(context) {
|
|
698
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_locationContext, "f")) {
|
|
699
|
-
return context;
|
|
700
|
-
}
|
|
701
|
-
const callerLocation = context?.location;
|
|
702
|
-
return {
|
|
703
|
-
...context,
|
|
704
|
-
location: {
|
|
705
|
-
...(isJsonRecord(callerLocation) ? callerLocation : {}),
|
|
706
|
-
...__classPrivateFieldGet(this, _AnalyticsController_locationContext, "f"),
|
|
707
|
-
},
|
|
708
|
-
};
|
|
709
|
-
}, _AnalyticsController_sendOrQueueTrackEvent = function _AnalyticsController_sendOrQueueTrackEvent(eventName, properties, context) {
|
|
710
|
-
// Direct delivery: enabled and not persisting.
|
|
711
|
-
if (selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state) &&
|
|
712
|
-
!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
713
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(eventName, properties, context);
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
const queuedEvent = {
|
|
717
|
-
type: 'track',
|
|
718
|
-
eventName,
|
|
719
|
-
messageId: (0, uuid_1.v4)(),
|
|
720
|
-
timestamp: new Date().toISOString(),
|
|
721
|
-
...(properties === undefined ? {} : { properties }),
|
|
722
|
-
...(context === undefined ? {} : { context }),
|
|
723
|
-
};
|
|
724
|
-
// Not yet enabled (reached only while undecided with the pre-consent queue
|
|
725
|
-
// enabled): hold the event until the user opts in.
|
|
726
|
-
if (!selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
727
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueuePreConsentEvent).call(this, queuedEvent);
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
731
|
-
}, _AnalyticsController_sendOrQueueIdentifyEvent = function _AnalyticsController_sendOrQueueIdentifyEvent(userId, traits, context) {
|
|
732
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
733
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(userId, traits, context);
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
const queuedEvent = {
|
|
737
|
-
type: 'identify',
|
|
738
|
-
userId,
|
|
739
|
-
messageId: (0, uuid_1.v4)(),
|
|
740
|
-
timestamp: new Date().toISOString(),
|
|
741
|
-
...(traits === undefined ? {} : { traits }),
|
|
742
|
-
...(context === undefined ? {} : { context }),
|
|
743
|
-
};
|
|
744
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
745
|
-
}, _AnalyticsController_sendOrQueueViewEvent = function _AnalyticsController_sendOrQueueViewEvent(name, properties, context) {
|
|
746
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
747
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties, context);
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
750
|
-
const queuedEvent = {
|
|
751
|
-
type: 'view',
|
|
752
|
-
name,
|
|
753
|
-
messageId: (0, uuid_1.v4)(),
|
|
754
|
-
timestamp: new Date().toISOString(),
|
|
755
|
-
...(properties === undefined ? {} : { properties }),
|
|
756
|
-
...(context === undefined ? {} : { context }),
|
|
757
|
-
};
|
|
758
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
759
|
-
}, _AnalyticsController_enqueueEvent = function _AnalyticsController_enqueueEvent(queuedEvent) {
|
|
760
|
-
const eventQueue = {
|
|
761
|
-
...(this.state.eventQueue ?? {}),
|
|
762
|
-
[queuedEvent.messageId]: queuedEvent,
|
|
763
|
-
};
|
|
764
|
-
this.update((state) => {
|
|
765
|
-
state.eventQueue = eventQueue;
|
|
766
|
-
});
|
|
767
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendQueuedEvent).call(this, queuedEvent);
|
|
768
|
-
}, _AnalyticsController_sendQueuedEvent = function _AnalyticsController_sendQueuedEvent(queuedEvent) {
|
|
769
|
-
const timestamp = new Date(queuedEvent.timestamp);
|
|
770
|
-
if (Number.isNaN(timestamp.getTime())) {
|
|
771
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Dropping queued analytics event with invalid timestamp', {
|
|
772
|
-
messageId: queuedEvent.messageId,
|
|
773
|
-
});
|
|
774
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, queuedEvent.messageId);
|
|
775
|
-
return;
|
|
776
|
-
}
|
|
777
|
-
const options = {
|
|
778
|
-
messageId: queuedEvent.messageId,
|
|
779
|
-
timestamp,
|
|
780
|
-
callback: (error) => {
|
|
781
|
-
if (error) {
|
|
782
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Queued analytics event delivery failed', {
|
|
783
|
-
messageId: queuedEvent.messageId,
|
|
784
|
-
error,
|
|
785
|
-
});
|
|
786
|
-
}
|
|
787
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, queuedEvent.messageId);
|
|
788
|
-
},
|
|
789
|
-
};
|
|
790
|
-
try {
|
|
791
|
-
if (queuedEvent.type === 'track') {
|
|
792
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(queuedEvent.eventName, (0, lodash_1.cloneDeep)(queuedEvent.properties), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
793
|
-
}
|
|
794
|
-
else if (queuedEvent.type === 'identify') {
|
|
795
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(queuedEvent.userId, (0, lodash_1.cloneDeep)(queuedEvent.traits), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
796
|
-
}
|
|
797
|
-
else {
|
|
798
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(queuedEvent.name, (0, lodash_1.cloneDeep)(queuedEvent.properties), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
catch (error) {
|
|
802
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Error sending queued analytics event', {
|
|
803
|
-
messageId: queuedEvent.messageId,
|
|
804
|
-
error,
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
}, _AnalyticsController_replayQueuedEvents = function _AnalyticsController_replayQueuedEvents() {
|
|
808
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f") || !this.state.eventQueue) {
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
if (!selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
812
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearQueuedEvents).call(this);
|
|
813
|
-
return;
|
|
814
|
-
}
|
|
815
|
-
for (const [messageId, queuedEvent] of Object.entries(this.state.eventQueue)) {
|
|
816
|
-
if (!isAnalyticsQueuedEvent(queuedEvent) ||
|
|
817
|
-
queuedEvent.messageId !== messageId) {
|
|
818
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Dropping invalid queued analytics event', { messageId });
|
|
819
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, messageId);
|
|
820
|
-
continue;
|
|
821
|
-
}
|
|
822
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendQueuedEvent).call(this, queuedEvent);
|
|
823
|
-
}
|
|
824
|
-
}, _AnalyticsController_removeQueuedEvent = function _AnalyticsController_removeQueuedEvent(messageId) {
|
|
825
|
-
const currentEventQueue = this.state.eventQueue;
|
|
826
|
-
if (!currentEventQueue ||
|
|
827
|
-
!Object.prototype.hasOwnProperty.call(currentEventQueue, messageId)) {
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
const { [messageId]: _deletedEvent, ...eventQueue } = currentEventQueue;
|
|
831
|
-
this.update((state) => {
|
|
832
|
-
state.eventQueue = eventQueue;
|
|
833
|
-
});
|
|
834
|
-
}, _AnalyticsController_clearQueuedEvents = function _AnalyticsController_clearQueuedEvents() {
|
|
835
|
-
if (!this.state.eventQueue ||
|
|
836
|
-
Object.keys(this.state.eventQueue).length === 0) {
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
this.update((state) => {
|
|
840
|
-
state.eventQueue = {};
|
|
841
|
-
});
|
|
842
|
-
}, _AnalyticsController_enqueuePreConsentEvent = function _AnalyticsController_enqueuePreConsentEvent(queuedEvent) {
|
|
843
|
-
const preConsentEventQueue = {
|
|
844
|
-
...(this.state.preConsentEventQueue ?? {}),
|
|
845
|
-
[queuedEvent.messageId]: queuedEvent,
|
|
846
|
-
};
|
|
847
|
-
this.update((state) => {
|
|
848
|
-
state.preConsentEventQueue = preConsentEventQueue;
|
|
849
|
-
});
|
|
850
|
-
}, _AnalyticsController_replayPreConsentEvents = function _AnalyticsController_replayPreConsentEvents(queue) {
|
|
851
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearPreConsentEvents).call(this);
|
|
852
|
-
for (const [messageId, queuedEvent] of Object.entries(queue)) {
|
|
853
|
-
if (!isAnalyticsQueuedEvent(queuedEvent) ||
|
|
854
|
-
queuedEvent.messageId !== messageId) {
|
|
855
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Dropping invalid queued pre-consent analytics event', {
|
|
856
|
-
messageId,
|
|
857
|
-
});
|
|
858
|
-
continue;
|
|
859
|
-
}
|
|
860
|
-
const eventToReplay = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enrichPreConsentEvent).call(this, queuedEvent);
|
|
861
|
-
if (__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
862
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, eventToReplay);
|
|
863
|
-
}
|
|
864
|
-
else {
|
|
865
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendQueuedEvent).call(this, eventToReplay);
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
}, _AnalyticsController_enrichPreConsentEvent = function _AnalyticsController_enrichPreConsentEvent(queuedEvent) {
|
|
869
|
-
if (queuedEvent.type === 'track' &&
|
|
870
|
-
queuedEvent.properties?.anonymous === true) {
|
|
871
|
-
return queuedEvent;
|
|
872
|
-
}
|
|
873
|
-
const context = __classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_withLocationContext).call(this, queuedEvent.context);
|
|
874
|
-
return {
|
|
875
|
-
...queuedEvent,
|
|
876
|
-
...(context === undefined ? {} : { context }),
|
|
877
|
-
};
|
|
878
|
-
}, _AnalyticsController_clearPreConsentEvents = function _AnalyticsController_clearPreConsentEvents() {
|
|
879
|
-
if (!this.state.preConsentEventQueue) {
|
|
880
|
-
return;
|
|
881
|
-
}
|
|
882
|
-
this.update((state) => {
|
|
883
|
-
state.preConsentEventQueue = {};
|
|
884
|
-
});
|
|
885
|
-
}, _AnalyticsController_reconcilePreConsentEvents = function _AnalyticsController_reconcilePreConsentEvents() {
|
|
886
|
-
const queue = this.state.preConsentEventQueue;
|
|
887
|
-
if (!queue) {
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isPreConsentQueueEnabled, "f")) {
|
|
891
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearPreConsentEvents).call(this);
|
|
892
|
-
return;
|
|
893
|
-
}
|
|
894
|
-
if (this.state.optedIn) {
|
|
895
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_replayPreConsentEvents).call(this, queue);
|
|
896
|
-
}
|
|
897
|
-
else if (this.state.consentDecisionMade) {
|
|
898
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearPreConsentEvents).call(this);
|
|
899
|
-
}
|
|
900
|
-
}, _AnalyticsController_reconcileEventFragments = function _AnalyticsController_reconcileEventFragments(initEventFragmentSnapshot) {
|
|
901
|
-
const fragments = this.state.eventFragments;
|
|
902
|
-
if (!fragments) {
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
905
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventFragmentsEnabled, "f") || !__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_isAnalyticsCaptureAllowed).call(this)) {
|
|
906
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearEventFragments).call(this);
|
|
907
|
-
return;
|
|
908
|
-
}
|
|
909
|
-
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_purgeStaleEventFragments).call(this, fragments, initEventFragmentSnapshot);
|
|
910
|
-
}, _AnalyticsController_purgeStaleEventFragments = function _AnalyticsController_purgeStaleEventFragments(currentEventFragments, initEventFragmentSnapshot) {
|
|
911
|
-
const eventFragments = {};
|
|
912
|
-
const now = Date.now();
|
|
913
|
-
for (const [id, fragment] of Object.entries(currentEventFragments)) {
|
|
914
|
-
if (!isAnalyticsEventFragment(fragment) || fragment.id !== id) {
|
|
915
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Dropping invalid persisted event fragment', { id });
|
|
916
|
-
continue;
|
|
917
|
-
}
|
|
918
|
-
if (now - fragment.lastUpdated > exports.EVENT_FRAGMENT_MAX_AGE) {
|
|
919
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Dropping expired persisted event fragment', { id });
|
|
920
|
-
continue;
|
|
921
|
-
}
|
|
922
|
-
const snapshotCreatedAt = initEventFragmentSnapshot.get(id);
|
|
923
|
-
if (fragment.persist === true ||
|
|
924
|
-
snapshotCreatedAt === undefined ||
|
|
925
|
-
fragment.createdAt !== snapshotCreatedAt) {
|
|
926
|
-
eventFragments[id] = fragment;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
if (Object.keys(eventFragments).length ===
|
|
930
|
-
Object.keys(currentEventFragments).length) {
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
this.update((state) => {
|
|
934
|
-
state.eventFragments = eventFragments;
|
|
935
|
-
});
|
|
936
|
-
}, _AnalyticsController_getEventFragment = function _AnalyticsController_getEventFragment(id) {
|
|
937
|
-
return this.state.eventFragments?.[id];
|
|
938
|
-
}, _AnalyticsController_setEventFragment = function _AnalyticsController_setEventFragment(fragment) {
|
|
939
|
-
const eventFragments = {
|
|
940
|
-
...this.state.eventFragments,
|
|
941
|
-
[fragment.id]: fragment,
|
|
942
|
-
};
|
|
943
|
-
this.update((state) => {
|
|
944
|
-
state.eventFragments = eventFragments;
|
|
945
|
-
});
|
|
946
|
-
}, _AnalyticsController_removeEventFragment = function _AnalyticsController_removeEventFragment(id) {
|
|
947
|
-
const currentEventFragments = this.state.eventFragments;
|
|
948
|
-
if (!currentEventFragments ||
|
|
949
|
-
!Object.prototype.hasOwnProperty.call(currentEventFragments, id)) {
|
|
950
|
-
return;
|
|
951
|
-
}
|
|
952
|
-
const { [id]: _deletedFragment, ...eventFragments } = currentEventFragments;
|
|
953
|
-
this.update((state) => {
|
|
954
|
-
state.eventFragments = eventFragments;
|
|
955
|
-
});
|
|
956
|
-
}, _AnalyticsController_clearEventFragments = function _AnalyticsController_clearEventFragments() {
|
|
957
|
-
if (!this.state.eventFragments ||
|
|
958
|
-
Object.keys(this.state.eventFragments).length === 0) {
|
|
959
|
-
return;
|
|
960
|
-
}
|
|
961
|
-
this.update((state) => {
|
|
962
|
-
state.eventFragments = {};
|
|
963
|
-
});
|
|
964
|
-
}, _AnalyticsController_shouldIgnoreEventFragmentCall = function _AnalyticsController_shouldIgnoreEventFragmentCall(method) {
|
|
965
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventFragmentsEnabled, "f")) {
|
|
966
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Ignoring event fragment call because the event fragments feature is disabled', { method });
|
|
967
|
-
return true;
|
|
968
|
-
}
|
|
969
|
-
if (!__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_isAnalyticsCaptureAllowed).call(this)) {
|
|
970
|
-
(0, AnalyticsLogger_js_1.projectLogger)('Ignoring event fragment call because the consent state does not allow capturing analytics', { method });
|
|
971
|
-
return true;
|
|
972
|
-
}
|
|
973
|
-
return false;
|
|
974
|
-
}, _AnalyticsController_emitEventFragment = function _AnalyticsController_emitEventFragment(fragment, name, context) {
|
|
975
|
-
const properties = { ...fragment.properties };
|
|
976
|
-
const sensitiveProperties = { ...fragment.sensitiveProperties };
|
|
977
|
-
this.trackEvent({
|
|
978
|
-
name,
|
|
979
|
-
properties,
|
|
980
|
-
sensitiveProperties,
|
|
981
|
-
saveDataRecording: false,
|
|
982
|
-
hasProperties: Object.keys(properties).length > 0 ||
|
|
983
|
-
Object.keys(sensitiveProperties).length > 0,
|
|
984
|
-
}, context);
|
|
985
|
-
}, _AnalyticsController_isAnalyticsCaptureAllowed = function _AnalyticsController_isAnalyticsCaptureAllowed() {
|
|
986
|
-
if (selectors_js_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
987
|
-
return true;
|
|
988
|
-
}
|
|
989
|
-
return __classPrivateFieldGet(this, _AnalyticsController_isPreConsentQueueEnabled, "f") && !this.state.consentDecisionMade;
|
|
990
|
-
};
|
|
991
|
-
//# sourceMappingURL=AnalyticsController.cjs.map
|