@metamask-previews/analytics-controller 1.0.1-preview-8e8c4f6f5 → 1.0.1-preview-855431b
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 +1 -0
- package/README.md +9 -0
- package/dist/AnalyticsController.cjs +191 -37
- package/dist/AnalyticsController.cjs.map +1 -1
- package/dist/AnalyticsController.d.cts +73 -1
- package/dist/AnalyticsController.d.cts.map +1 -1
- package/dist/AnalyticsController.d.mts +73 -1
- package/dist/AnalyticsController.d.mts.map +1 -1
- package/dist/AnalyticsController.mjs +192 -37
- package/dist/AnalyticsController.mjs.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.cjs.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.d.cts +29 -3
- package/dist/AnalyticsPlatformAdapter.types.d.cts.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.d.mts +29 -3
- package/dist/AnalyticsPlatformAdapter.types.d.mts.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
+
- Optional persisted event queue support in `AnalyticsController`, disabled by default. ([#8797](https://github.com/MetaMask/core/pull/8797))
|
|
12
13
|
- Add optional analytics context on `trackEvent`, `identify`, and `trackView` to forward platform-specific context to `AnalyticsPlatformAdapter` implementations ([#8835](https://github.com/MetaMask/core/pull/8835))
|
|
13
14
|
- Optional `skipUUIDv4Check` on `AnalyticsPlatformAdapter` to allow non-UUIDv4 `analyticsId` strings when constructing `AnalyticsController` ([#8543](https://github.com/MetaMask/core/pull/8543))
|
|
14
15
|
|
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ The AnalyticsController provides a unified interface for tracking analytics even
|
|
|
20
20
|
| ------------- | --------- | --------------------------------------------- | --------- |
|
|
21
21
|
| `analyticsId` | `string` | UUIDv4 identifier (client platform-generated) | Yes |
|
|
22
22
|
| `optedIn` | `boolean` | User opt-in status | Yes |
|
|
23
|
+
| `eventQueue` | `object` | Optional persisted delivery queue | Yes |
|
|
23
24
|
|
|
24
25
|
### Client Platform Responsibilities
|
|
25
26
|
|
|
@@ -37,6 +38,14 @@ When `isAnonymousEventsFeatureEnabled` is enabled in the constructor, events wit
|
|
|
37
38
|
|
|
38
39
|
This allows sensitive data to be tracked anonymously while maintaining user identification for regular properties. When disabled (default), all properties are tracked in a single event.
|
|
39
40
|
|
|
41
|
+
## Persisted Event Queue
|
|
42
|
+
|
|
43
|
+
When `isEventQueuePersistenceEnabled` is enabled in the constructor, each final platform adapter payload is persisted until the adapter reports successful delivery through its callback.
|
|
44
|
+
|
|
45
|
+
This feature is disabled by default. Client platforms that already rely on SDK-level persistence, such as MetaMask Mobile through `@segment/analytics-react-native`'s `storePersistor` option, should leave it disabled.
|
|
46
|
+
|
|
47
|
+
Platforms without SDK-level persistence, such as MetaMask Extension, can enable it to replay queued payloads after restart. The queue stores the final adapter calls, so anonymous event splitting persists the identified and anonymous payloads separately.
|
|
48
|
+
|
|
40
49
|
## Lifecycle Hooks
|
|
41
50
|
|
|
42
51
|
### `onSetupCompleted`
|
|
@@ -10,10 +10,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
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
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _AnalyticsController_platformAdapter, _AnalyticsController_isAnonymousEventsFeatureEnabled, _AnalyticsController_initialized;
|
|
13
|
+
var _AnalyticsController_instances, _AnalyticsController_platformAdapter, _AnalyticsController_isAnonymousEventsFeatureEnabled, _AnalyticsController_isEventQueuePersistenceEnabled, _AnalyticsController_initialized, _AnalyticsController_sendOrQueueTrackEvent, _AnalyticsController_sendOrQueueIdentifyEvent, _AnalyticsController_sendOrQueueViewEvent, _AnalyticsController_enqueueEvent, _AnalyticsController_sendQueuedEvent, _AnalyticsController_replayQueuedEvents, _AnalyticsController_removeQueuedEvent, _AnalyticsController_clearQueuedEvents;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AnalyticsController = exports.getDefaultAnalyticsControllerState = exports.controllerName = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
+
const lodash_1 = require("lodash");
|
|
18
|
+
const uuid_1 = require("uuid");
|
|
17
19
|
const analyticsControllerStateValidator_1 = require("./analyticsControllerStateValidator.cjs");
|
|
18
20
|
const AnalyticsLogger_1 = require("./AnalyticsLogger.cjs");
|
|
19
21
|
const selectors_1 = require("./selectors.cjs");
|
|
@@ -57,6 +59,12 @@ const analyticsControllerMetadata = {
|
|
|
57
59
|
includeInDebugSnapshot: true,
|
|
58
60
|
usedInUi: false,
|
|
59
61
|
},
|
|
62
|
+
eventQueue: {
|
|
63
|
+
includeInStateLogs: false,
|
|
64
|
+
persist: true,
|
|
65
|
+
includeInDebugSnapshot: false,
|
|
66
|
+
usedInUi: false,
|
|
67
|
+
},
|
|
60
68
|
};
|
|
61
69
|
// === MESSENGER ===
|
|
62
70
|
const MESSENGER_EXPOSED_METHODS = [
|
|
@@ -66,6 +74,46 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
66
74
|
'optIn',
|
|
67
75
|
'optOut',
|
|
68
76
|
];
|
|
77
|
+
/**
|
|
78
|
+
* Returns whether a value is a non-array object.
|
|
79
|
+
*
|
|
80
|
+
* @param value - The value to check.
|
|
81
|
+
* @returns True if the value is a record.
|
|
82
|
+
*/
|
|
83
|
+
function isRecord(value) {
|
|
84
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns whether a value is a valid persisted analytics event.
|
|
88
|
+
*
|
|
89
|
+
* @param value - The value to check.
|
|
90
|
+
* @returns True if the value is a queued analytics event.
|
|
91
|
+
*/
|
|
92
|
+
function isAnalyticsQueuedEvent(value) {
|
|
93
|
+
if (!isRecord(value)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (typeof value.messageId !== 'string' ||
|
|
97
|
+
typeof value.timestamp !== 'string') {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
if (value.type === 'track') {
|
|
101
|
+
return (typeof value.eventName === 'string' &&
|
|
102
|
+
(value.properties === undefined || isRecord(value.properties)) &&
|
|
103
|
+
(value.context === undefined || isRecord(value.context)));
|
|
104
|
+
}
|
|
105
|
+
if (value.type === 'identify') {
|
|
106
|
+
return (typeof value.userId === 'string' &&
|
|
107
|
+
(value.traits === undefined || isRecord(value.traits)) &&
|
|
108
|
+
(value.context === undefined || isRecord(value.context)));
|
|
109
|
+
}
|
|
110
|
+
if (value.type === 'view') {
|
|
111
|
+
return (typeof value.name === 'string' &&
|
|
112
|
+
(value.properties === undefined || isRecord(value.properties)) &&
|
|
113
|
+
(value.context === undefined || isRecord(value.context)));
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
69
117
|
/**
|
|
70
118
|
* The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
|
|
71
119
|
* It provides a unified interface for tracking events, identifying users, and managing
|
|
@@ -89,10 +137,11 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
89
137
|
* @param options.messenger - Messenger used to communicate with BaseController
|
|
90
138
|
* @param options.platformAdapter - Platform adapter implementation for tracking
|
|
91
139
|
* @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
|
|
140
|
+
* @param options.isEventQueuePersistenceEnabled - Whether analytics event queue persistence is enabled
|
|
92
141
|
* @throws Error if state.analyticsId is missing or not a valid UUIDv4
|
|
93
142
|
* @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
|
|
94
143
|
*/
|
|
95
|
-
constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled = false, }) {
|
|
144
|
+
constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled = false, isEventQueuePersistenceEnabled = false, }) {
|
|
96
145
|
const initialState = {
|
|
97
146
|
...getDefaultAnalyticsControllerState(),
|
|
98
147
|
...state,
|
|
@@ -104,10 +153,13 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
104
153
|
state: initialState,
|
|
105
154
|
messenger,
|
|
106
155
|
});
|
|
156
|
+
_AnalyticsController_instances.add(this);
|
|
107
157
|
_AnalyticsController_platformAdapter.set(this, void 0);
|
|
108
158
|
_AnalyticsController_isAnonymousEventsFeatureEnabled.set(this, void 0);
|
|
159
|
+
_AnalyticsController_isEventQueuePersistenceEnabled.set(this, void 0);
|
|
109
160
|
_AnalyticsController_initialized.set(this, void 0);
|
|
110
161
|
__classPrivateFieldSet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, isAnonymousEventsFeatureEnabled, "f");
|
|
162
|
+
__classPrivateFieldSet(this, _AnalyticsController_isEventQueuePersistenceEnabled, isEventQueuePersistenceEnabled, "f");
|
|
111
163
|
__classPrivateFieldSet(this, _AnalyticsController_platformAdapter, platformAdapter, "f");
|
|
112
164
|
__classPrivateFieldSet(this, _AnalyticsController_initialized, false, "f");
|
|
113
165
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
@@ -115,6 +167,7 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
115
167
|
enabled: selectors_1.analyticsControllerSelectors.selectEnabled(this.state),
|
|
116
168
|
optedIn: this.state.optedIn,
|
|
117
169
|
analyticsId: this.state.analyticsId,
|
|
170
|
+
eventQueuePersistenceEnabled: __classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f"),
|
|
118
171
|
});
|
|
119
172
|
}
|
|
120
173
|
/**
|
|
@@ -136,6 +189,7 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
136
189
|
// Log error but don't throw - adapter setup failure shouldn't break controller
|
|
137
190
|
(0, AnalyticsLogger_1.projectLogger)('Error calling platformAdapter.onSetupCompleted', error);
|
|
138
191
|
}
|
|
192
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_replayQueuedEvents).call(this);
|
|
139
193
|
}
|
|
140
194
|
/**
|
|
141
195
|
* Track an analytics event.
|
|
@@ -153,41 +207,24 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
153
207
|
// if event does not have properties, send event without properties
|
|
154
208
|
// and return to prevent any additional processing
|
|
155
209
|
if (!event.hasProperties) {
|
|
156
|
-
|
|
157
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, undefined, context);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name);
|
|
161
|
-
}
|
|
210
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, undefined, context);
|
|
162
211
|
return;
|
|
163
212
|
}
|
|
164
213
|
// Track regular properties first if anonymous events feature is enabled
|
|
165
214
|
if (__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f")) {
|
|
166
215
|
// Note: Even if regular properties object is empty, we still send it to ensure
|
|
167
216
|
// an event with user ID is tracked.
|
|
168
|
-
|
|
217
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, {
|
|
169
218
|
...event.properties,
|
|
170
|
-
};
|
|
171
|
-
if (context) {
|
|
172
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, properties, context);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, properties);
|
|
176
|
-
}
|
|
219
|
+
}, context);
|
|
177
220
|
}
|
|
178
221
|
const hasSensitiveProperties = Object.keys(event.sensitiveProperties).length > 0;
|
|
179
222
|
if (!__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f") || hasSensitiveProperties) {
|
|
180
|
-
|
|
223
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueTrackEvent).call(this, event.name, {
|
|
181
224
|
...event.properties,
|
|
182
225
|
...event.sensitiveProperties,
|
|
183
226
|
...(hasSensitiveProperties && { anonymous: true }),
|
|
184
|
-
};
|
|
185
|
-
if (context) {
|
|
186
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, properties, context);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, properties);
|
|
190
|
-
}
|
|
227
|
+
}, context);
|
|
191
228
|
}
|
|
192
229
|
}
|
|
193
230
|
/**
|
|
@@ -201,12 +238,7 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
201
238
|
return;
|
|
202
239
|
}
|
|
203
240
|
// Delegate to platform adapter using the current analytics ID
|
|
204
|
-
|
|
205
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(this.state.analyticsId, traits, context);
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(this.state.analyticsId, traits);
|
|
209
|
-
}
|
|
241
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueIdentifyEvent).call(this, this.state.analyticsId, traits, context);
|
|
210
242
|
}
|
|
211
243
|
/**
|
|
212
244
|
* Track a page or screen view.
|
|
@@ -220,12 +252,7 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
220
252
|
return;
|
|
221
253
|
}
|
|
222
254
|
// Delegate to platform adapter
|
|
223
|
-
|
|
224
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties, context);
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties);
|
|
228
|
-
}
|
|
255
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendOrQueueViewEvent).call(this, name, properties, context);
|
|
229
256
|
}
|
|
230
257
|
/**
|
|
231
258
|
* Opt in to analytics.
|
|
@@ -242,8 +269,135 @@ class AnalyticsController extends base_controller_1.BaseController {
|
|
|
242
269
|
this.update((state) => {
|
|
243
270
|
state.optedIn = false;
|
|
244
271
|
});
|
|
272
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearQueuedEvents).call(this);
|
|
245
273
|
}
|
|
246
274
|
}
|
|
247
275
|
exports.AnalyticsController = AnalyticsController;
|
|
248
|
-
_AnalyticsController_platformAdapter = new WeakMap(), _AnalyticsController_isAnonymousEventsFeatureEnabled = new WeakMap(), _AnalyticsController_initialized = new WeakMap()
|
|
276
|
+
_AnalyticsController_platformAdapter = new WeakMap(), _AnalyticsController_isAnonymousEventsFeatureEnabled = new WeakMap(), _AnalyticsController_isEventQueuePersistenceEnabled = new WeakMap(), _AnalyticsController_initialized = new WeakMap(), _AnalyticsController_instances = new WeakSet(), _AnalyticsController_sendOrQueueTrackEvent = function _AnalyticsController_sendOrQueueTrackEvent(eventName, properties, context) {
|
|
277
|
+
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
278
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(eventName, properties, context);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const queuedEvent = {
|
|
282
|
+
type: 'track',
|
|
283
|
+
eventName,
|
|
284
|
+
messageId: (0, uuid_1.v4)(),
|
|
285
|
+
timestamp: new Date().toISOString(),
|
|
286
|
+
...(properties === undefined ? {} : { properties }),
|
|
287
|
+
...(context === undefined ? {} : { context }),
|
|
288
|
+
};
|
|
289
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
290
|
+
}, _AnalyticsController_sendOrQueueIdentifyEvent = function _AnalyticsController_sendOrQueueIdentifyEvent(userId, traits, context) {
|
|
291
|
+
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
292
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(userId, traits, context);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const queuedEvent = {
|
|
296
|
+
type: 'identify',
|
|
297
|
+
userId,
|
|
298
|
+
messageId: (0, uuid_1.v4)(),
|
|
299
|
+
timestamp: new Date().toISOString(),
|
|
300
|
+
...(traits === undefined ? {} : { traits }),
|
|
301
|
+
...(context === undefined ? {} : { context }),
|
|
302
|
+
};
|
|
303
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
304
|
+
}, _AnalyticsController_sendOrQueueViewEvent = function _AnalyticsController_sendOrQueueViewEvent(name, properties, context) {
|
|
305
|
+
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f")) {
|
|
306
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties, context);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const queuedEvent = {
|
|
310
|
+
type: 'view',
|
|
311
|
+
name,
|
|
312
|
+
messageId: (0, uuid_1.v4)(),
|
|
313
|
+
timestamp: new Date().toISOString(),
|
|
314
|
+
...(properties === undefined ? {} : { properties }),
|
|
315
|
+
...(context === undefined ? {} : { context }),
|
|
316
|
+
};
|
|
317
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_enqueueEvent).call(this, queuedEvent);
|
|
318
|
+
}, _AnalyticsController_enqueueEvent = function _AnalyticsController_enqueueEvent(queuedEvent) {
|
|
319
|
+
const eventQueue = {
|
|
320
|
+
...(this.state.eventQueue ?? {}),
|
|
321
|
+
[queuedEvent.messageId]: queuedEvent,
|
|
322
|
+
};
|
|
323
|
+
this.update((state) => {
|
|
324
|
+
state.eventQueue = eventQueue;
|
|
325
|
+
});
|
|
326
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendQueuedEvent).call(this, queuedEvent);
|
|
327
|
+
}, _AnalyticsController_sendQueuedEvent = function _AnalyticsController_sendQueuedEvent(queuedEvent) {
|
|
328
|
+
const timestamp = new Date(queuedEvent.timestamp);
|
|
329
|
+
if (Number.isNaN(timestamp.getTime())) {
|
|
330
|
+
(0, AnalyticsLogger_1.projectLogger)('Dropping queued analytics event with invalid timestamp', {
|
|
331
|
+
messageId: queuedEvent.messageId,
|
|
332
|
+
});
|
|
333
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, queuedEvent.messageId);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const options = {
|
|
337
|
+
messageId: queuedEvent.messageId,
|
|
338
|
+
timestamp,
|
|
339
|
+
callback: (error) => {
|
|
340
|
+
if (error) {
|
|
341
|
+
(0, AnalyticsLogger_1.projectLogger)('Queued analytics event delivery failed', {
|
|
342
|
+
messageId: queuedEvent.messageId,
|
|
343
|
+
error,
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, queuedEvent.messageId);
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
try {
|
|
351
|
+
if (queuedEvent.type === 'track') {
|
|
352
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(queuedEvent.eventName, (0, lodash_1.cloneDeep)(queuedEvent.properties), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
353
|
+
}
|
|
354
|
+
else if (queuedEvent.type === 'identify') {
|
|
355
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(queuedEvent.userId, (0, lodash_1.cloneDeep)(queuedEvent.traits), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(queuedEvent.name, (0, lodash_1.cloneDeep)(queuedEvent.properties), (0, lodash_1.cloneDeep)(queuedEvent.context), options);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
(0, AnalyticsLogger_1.projectLogger)('Error sending queued analytics event', {
|
|
363
|
+
messageId: queuedEvent.messageId,
|
|
364
|
+
error,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}, _AnalyticsController_replayQueuedEvents = function _AnalyticsController_replayQueuedEvents() {
|
|
368
|
+
if (!__classPrivateFieldGet(this, _AnalyticsController_isEventQueuePersistenceEnabled, "f") || !this.state.eventQueue) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (!selectors_1.analyticsControllerSelectors.selectEnabled(this.state)) {
|
|
372
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_clearQueuedEvents).call(this);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
for (const [messageId, queuedEvent] of Object.entries(this.state.eventQueue)) {
|
|
376
|
+
if (!isAnalyticsQueuedEvent(queuedEvent) ||
|
|
377
|
+
queuedEvent.messageId !== messageId) {
|
|
378
|
+
(0, AnalyticsLogger_1.projectLogger)('Dropping invalid queued analytics event', { messageId });
|
|
379
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_removeQueuedEvent).call(this, messageId);
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
__classPrivateFieldGet(this, _AnalyticsController_instances, "m", _AnalyticsController_sendQueuedEvent).call(this, queuedEvent);
|
|
383
|
+
}
|
|
384
|
+
}, _AnalyticsController_removeQueuedEvent = function _AnalyticsController_removeQueuedEvent(messageId) {
|
|
385
|
+
const currentEventQueue = this.state.eventQueue;
|
|
386
|
+
if (!currentEventQueue ||
|
|
387
|
+
!Object.prototype.hasOwnProperty.call(currentEventQueue, messageId)) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const { [messageId]: _deletedEvent, ...eventQueue } = currentEventQueue;
|
|
391
|
+
this.update((state) => {
|
|
392
|
+
state.eventQueue = eventQueue;
|
|
393
|
+
});
|
|
394
|
+
}, _AnalyticsController_clearQueuedEvents = function _AnalyticsController_clearQueuedEvents() {
|
|
395
|
+
if (!this.state.eventQueue ||
|
|
396
|
+
Object.keys(this.state.eventQueue).length === 0) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
this.update((state) => {
|
|
400
|
+
state.eventQueue = {};
|
|
401
|
+
});
|
|
402
|
+
};
|
|
249
403
|
//# sourceMappingURL=AnalyticsController.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsController.cjs","sourceRoot":"","sources":["../src/AnalyticsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { AnalyticsControllerMethodActions } from './AnalyticsController-method-action-types';\nimport { validateAnalyticsControllerState } from './analyticsControllerStateValidator';\nimport { projectLogger as log } from './AnalyticsLogger';\nimport type {\n AnalyticsPlatformAdapter,\n AnalyticsContext,\n AnalyticsEventProperties,\n AnalyticsUserTraits,\n AnalyticsTrackingEvent,\n} from './AnalyticsPlatformAdapter.types';\nimport { analyticsControllerSelectors } from './selectors';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link AnalyticsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'AnalyticsController';\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link AnalyticsController}.\n */\nexport type AnalyticsControllerState = {\n /**\n * Whether the user has opted in to analytics.\n */\n optedIn: boolean;\n\n /**\n * User's UUIDv4 analytics identifier.\n * This is an identity (unique per user), not a preference.\n * Must be provided by the platform - the controller does not generate it.\n */\n analyticsId: string;\n};\n\n/**\n * Returns default values for AnalyticsController state.\n *\n * Note: analyticsId is NOT included - it's an identity that must be\n * provided by the platform (generated once on first run, then persisted).\n *\n * @returns Default state without analyticsId\n */\nexport function getDefaultAnalyticsControllerState(): Omit<\n AnalyticsControllerState,\n 'analyticsId'\n> {\n return {\n optedIn: false,\n };\n}\n\n/**\n * The metadata for each property in {@link AnalyticsControllerState}.\n *\n * Both `optedIn` and `analyticsId` are persisted (`persist: true`).\n * The platform must supply a valid UUIDv4 `analyticsId` on first run.\n */\nconst analyticsControllerMetadata = {\n optedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n analyticsId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n },\n} satisfies StateMetadata<AnalyticsControllerState>;\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'trackEvent',\n 'identify',\n 'trackView',\n 'optIn',\n 'optOut',\n] as const;\n\n/**\n * Returns the state of the {@link AnalyticsController}.\n */\nexport type AnalyticsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AnalyticsControllerState\n>;\n\n/**\n * Actions that {@link AnalyticsControllerMessenger} exposes to other consumers.\n */\nexport type AnalyticsControllerActions =\n | AnalyticsControllerGetStateAction\n | AnalyticsControllerMethodActions;\n\n/**\n * Actions from other messengers that {@link AnalyticsControllerMessenger} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Event emitted when the state of the {@link AnalyticsController} changes.\n */\nexport type AnalyticsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AnalyticsControllerState\n>;\n\n/**\n * Events that {@link AnalyticsControllerMessenger} exposes to other consumers.\n */\nexport type AnalyticsControllerEvents = AnalyticsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link AnalyticsControllerMessenger} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link AnalyticsController}.\n */\nexport type AnalyticsControllerMessenger = Messenger<\n typeof controllerName,\n AnalyticsControllerActions | AllowedActions,\n AnalyticsControllerEvents | AllowedEvents\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * The options that AnalyticsController takes.\n */\nexport type AnalyticsControllerOptions = {\n /**\n * Initial controller state. Must include a valid UUIDv4 `analyticsId`.\n * The platform is responsible for generating the ID on first run.\n * It is then persisted with controller state when using a persisted store.\n */\n state: AnalyticsControllerState;\n /**\n * Messenger used to communicate with BaseController and other controllers.\n */\n messenger: AnalyticsControllerMessenger;\n /**\n * Platform adapter implementation for tracking events.\n */\n platformAdapter: AnalyticsPlatformAdapter;\n\n /**\n * Whether the anonymous events feature is enabled.\n *\n * @default false\n */\n isAnonymousEventsFeatureEnabled?: boolean;\n};\n\n/**\n * The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).\n * It provides a unified interface for tracking events, identifying users, and managing\n * analytics preferences while delegating platform-specific implementation to an\n * {@link AnalyticsPlatformAdapter}.\n *\n * This controller follows the MetaMask controller pattern and integrates with the\n * messenger system to allow other controllers and components to track analytics events.\n * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.\n *\n * The controller persists `optedIn` and `analyticsId` when composed with a persisted\n * store. The platform must supply a valid `analyticsId` on first launch.\n */\nexport class AnalyticsController extends BaseController<\n 'AnalyticsController',\n AnalyticsControllerState,\n AnalyticsControllerMessenger\n> {\n readonly #platformAdapter: AnalyticsPlatformAdapter;\n\n readonly #isAnonymousEventsFeatureEnabled: boolean;\n\n #initialized: boolean;\n\n /**\n * Constructs an AnalyticsController instance.\n *\n * @param options - Controller options\n * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.\n * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.\n * @param options.messenger - Messenger used to communicate with BaseController\n * @param options.platformAdapter - Platform adapter implementation for tracking\n * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled\n * @throws Error if state.analyticsId is missing or not a valid UUIDv4\n * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.\n */\n constructor({\n state,\n messenger,\n platformAdapter,\n isAnonymousEventsFeatureEnabled = false,\n }: AnalyticsControllerOptions) {\n const initialState: AnalyticsControllerState = {\n ...getDefaultAnalyticsControllerState(),\n ...state,\n };\n\n validateAnalyticsControllerState(\n initialState,\n platformAdapter.skipUUIDv4Check === true,\n );\n\n super({\n name: controllerName,\n metadata: analyticsControllerMetadata,\n state: initialState,\n messenger,\n });\n\n this.#isAnonymousEventsFeatureEnabled = isAnonymousEventsFeatureEnabled;\n this.#platformAdapter = platformAdapter;\n this.#initialized = false;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n log('AnalyticsController initialized and ready', {\n enabled: analyticsControllerSelectors.selectEnabled(this.state),\n optedIn: this.state.optedIn,\n analyticsId: this.state.analyticsId,\n });\n }\n\n /**\n * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.\n * This method must be called after construction to complete the setup process.\n */\n init(): void {\n if (this.#initialized) {\n log('AnalyticsController already initialized.');\n return;\n }\n\n this.#initialized = true;\n\n // Call onSetupCompleted lifecycle hook after initialization\n // State is already validated, so analyticsId is guaranteed to be a valid UUIDv4\n try {\n this.#platformAdapter.onSetupCompleted(this.state.analyticsId);\n } catch (error) {\n // Log error but don't throw - adapter setup failure shouldn't break controller\n log('Error calling platformAdapter.onSetupCompleted', error);\n }\n }\n\n /**\n * Track an analytics event.\n *\n * Events are only tracked if analytics is enabled.\n *\n * @param event - Analytics event with properties and sensitive properties\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n trackEvent(event: AnalyticsTrackingEvent, context?: AnalyticsContext): void {\n // Don't track if analytics is disabled\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // if event does not have properties, send event without properties\n // and return to prevent any additional processing\n if (!event.hasProperties) {\n if (context) {\n this.#platformAdapter.track(event.name, undefined, context);\n } else {\n this.#platformAdapter.track(event.name);\n }\n return;\n }\n\n // Track regular properties first if anonymous events feature is enabled\n if (this.#isAnonymousEventsFeatureEnabled) {\n // Note: Even if regular properties object is empty, we still send it to ensure\n // an event with user ID is tracked.\n const properties = {\n ...event.properties,\n };\n if (context) {\n this.#platformAdapter.track(event.name, properties, context);\n } else {\n this.#platformAdapter.track(event.name, properties);\n }\n }\n\n const hasSensitiveProperties =\n Object.keys(event.sensitiveProperties).length > 0;\n\n if (!this.#isAnonymousEventsFeatureEnabled || hasSensitiveProperties) {\n const properties = {\n ...event.properties,\n ...event.sensitiveProperties,\n ...(hasSensitiveProperties && { anonymous: true }),\n };\n if (context) {\n this.#platformAdapter.track(event.name, properties, context);\n } else {\n this.#platformAdapter.track(event.name, properties);\n }\n }\n }\n\n /**\n * Identify a user for analytics.\n *\n * @param traits - User traits/properties\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n identify(traits?: AnalyticsUserTraits, context?: AnalyticsContext): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter using the current analytics ID\n if (context) {\n this.#platformAdapter.identify(this.state.analyticsId, traits, context);\n } else {\n this.#platformAdapter.identify(this.state.analyticsId, traits);\n }\n }\n\n /**\n * Track a page or screen view.\n *\n * @param name - The identifier/name of the page or screen being viewed (e.g., \"home\", \"settings\", \"wallet\")\n * @param properties - Optional properties associated with the view\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n trackView(\n name: string,\n properties?: AnalyticsEventProperties,\n context?: AnalyticsContext,\n ): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter\n if (context) {\n this.#platformAdapter.view(name, properties, context);\n } else {\n this.#platformAdapter.view(name, properties);\n }\n }\n\n /**\n * Opt in to analytics.\n */\n optIn(): void {\n this.update((state) => {\n state.optedIn = true;\n });\n }\n\n /**\n * Opt out of analytics.\n */\n optOut(): void {\n this.update((state) => {\n state.optedIn = false;\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AnalyticsController.cjs","sourceRoot":"","sources":["../src/AnalyticsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\nimport { v4 as uuid } from 'uuid';\n\nimport type { AnalyticsControllerMethodActions } from './AnalyticsController-method-action-types';\nimport { validateAnalyticsControllerState } from './analyticsControllerStateValidator';\nimport { projectLogger as log } from './AnalyticsLogger';\nimport type {\n AnalyticsPlatformAdapter,\n AnalyticsDeliveryOptions,\n AnalyticsContext,\n AnalyticsEventProperties,\n AnalyticsUserTraits,\n AnalyticsTrackingEvent,\n} from './AnalyticsPlatformAdapter.types';\nimport { analyticsControllerSelectors } from './selectors';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link AnalyticsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'AnalyticsController';\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link AnalyticsController}.\n */\nexport type AnalyticsControllerState = {\n /**\n * Whether the user has opted in to analytics.\n */\n optedIn: boolean;\n\n /**\n * User's UUIDv4 analytics identifier.\n * This is an identity (unique per user), not a preference.\n * Must be provided by the platform - the controller does not generate it.\n */\n analyticsId: string;\n\n /**\n * Persisted queue of analytics events waiting for delivery acknowledgement.\n * This is only used when event queue persistence is enabled.\n */\n eventQueue?: Record<string, Json>;\n};\n\n/**\n * Event types supported by the persisted analytics event queue.\n */\nexport type AnalyticsQueuedEventType = 'track' | 'identify' | 'view';\n\n/**\n * Base persisted event queue entry.\n */\nexport type AnalyticsQueuedEventBase = {\n /**\n * Event type used to replay the payload with the platform adapter.\n */\n type: AnalyticsQueuedEventType;\n\n /**\n * Stable identifier for the analytics payload.\n */\n messageId: string;\n\n /**\n * Original payload timestamp serialized for persistence.\n */\n timestamp: string;\n};\n\n/**\n * Persisted track event queue entry.\n */\nexport type AnalyticsQueuedTrackEvent = AnalyticsQueuedEventBase & {\n type: 'track';\n eventName: string;\n properties?: AnalyticsEventProperties;\n context?: AnalyticsContext;\n};\n\n/**\n * Persisted identify event queue entry.\n */\nexport type AnalyticsQueuedIdentifyEvent = AnalyticsQueuedEventBase & {\n type: 'identify';\n userId: string;\n traits?: AnalyticsUserTraits;\n context?: AnalyticsContext;\n};\n\n/**\n * Persisted view event queue entry.\n */\nexport type AnalyticsQueuedViewEvent = AnalyticsQueuedEventBase & {\n type: 'view';\n name: string;\n properties?: AnalyticsEventProperties;\n context?: AnalyticsContext;\n};\n\n/**\n * Persisted analytics event queue entry.\n */\nexport type AnalyticsQueuedEvent =\n | AnalyticsQueuedTrackEvent\n | AnalyticsQueuedIdentifyEvent\n | AnalyticsQueuedViewEvent;\n\n/**\n * Persisted analytics event queue keyed by message ID.\n */\nexport type AnalyticsEventQueue = Record<string, AnalyticsQueuedEvent>;\n\n/**\n * Returns default values for AnalyticsController state.\n *\n * Note: analyticsId is NOT included - it's an identity that must be\n * provided by the platform (generated once on first run, then persisted).\n *\n * @returns Default state without analyticsId\n */\nexport function getDefaultAnalyticsControllerState(): Omit<\n AnalyticsControllerState,\n 'analyticsId'\n> {\n return {\n optedIn: false,\n };\n}\n\n/**\n * The metadata for each property in {@link AnalyticsControllerState}.\n *\n * Both `optedIn` and `analyticsId` are persisted (`persist: true`).\n * The platform must supply a valid UUIDv4 `analyticsId` on first run.\n */\nconst analyticsControllerMetadata = {\n optedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n analyticsId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n },\n eventQueue: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<AnalyticsControllerState>;\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'trackEvent',\n 'identify',\n 'trackView',\n 'optIn',\n 'optOut',\n] as const;\n\n/**\n * Returns the state of the {@link AnalyticsController}.\n */\nexport type AnalyticsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AnalyticsControllerState\n>;\n\n/**\n * Actions that {@link AnalyticsControllerMessenger} exposes to other consumers.\n */\nexport type AnalyticsControllerActions =\n | AnalyticsControllerGetStateAction\n | AnalyticsControllerMethodActions;\n\n/**\n * Actions from other messengers that {@link AnalyticsControllerMessenger} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Event emitted when the state of the {@link AnalyticsController} changes.\n */\nexport type AnalyticsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AnalyticsControllerState\n>;\n\n/**\n * Events that {@link AnalyticsControllerMessenger} exposes to other consumers.\n */\nexport type AnalyticsControllerEvents = AnalyticsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link AnalyticsControllerMessenger} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link AnalyticsController}.\n */\nexport type AnalyticsControllerMessenger = Messenger<\n typeof controllerName,\n AnalyticsControllerActions | AllowedActions,\n AnalyticsControllerEvents | AllowedEvents\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * The options that AnalyticsController takes.\n */\nexport type AnalyticsControllerOptions = {\n /**\n * Initial controller state. Must include a valid UUIDv4 `analyticsId`.\n * The platform is responsible for generating the ID on first run.\n * It is then persisted with controller state when using a persisted store.\n */\n state: AnalyticsControllerState;\n /**\n * Messenger used to communicate with BaseController and other controllers.\n */\n messenger: AnalyticsControllerMessenger;\n /**\n * Platform adapter implementation for tracking events.\n */\n platformAdapter: AnalyticsPlatformAdapter;\n\n /**\n * Whether the anonymous events feature is enabled.\n *\n * @default false\n */\n isAnonymousEventsFeatureEnabled?: boolean;\n\n /**\n * Whether analytics event queue persistence is enabled.\n *\n * When enabled, AnalyticsController persists each platform adapter payload\n * until the adapter reports successful delivery.\n *\n * @default false\n */\n isEventQueuePersistenceEnabled?: boolean;\n};\n\n/**\n * Returns whether a value is a non-array object.\n *\n * @param value - The value to check.\n * @returns True if the value is a record.\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Returns whether a value is a valid persisted analytics event.\n *\n * @param value - The value to check.\n * @returns True if the value is a queued analytics event.\n */\nfunction isAnalyticsQueuedEvent(value: unknown): value is AnalyticsQueuedEvent {\n if (!isRecord(value)) {\n return false;\n }\n\n if (\n typeof value.messageId !== 'string' ||\n typeof value.timestamp !== 'string'\n ) {\n return false;\n }\n\n if (value.type === 'track') {\n return (\n typeof value.eventName === 'string' &&\n (value.properties === undefined || isRecord(value.properties)) &&\n (value.context === undefined || isRecord(value.context))\n );\n }\n\n if (value.type === 'identify') {\n return (\n typeof value.userId === 'string' &&\n (value.traits === undefined || isRecord(value.traits)) &&\n (value.context === undefined || isRecord(value.context))\n );\n }\n\n if (value.type === 'view') {\n return (\n typeof value.name === 'string' &&\n (value.properties === undefined || isRecord(value.properties)) &&\n (value.context === undefined || isRecord(value.context))\n );\n }\n\n return false;\n}\n\n/**\n * The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).\n * It provides a unified interface for tracking events, identifying users, and managing\n * analytics preferences while delegating platform-specific implementation to an\n * {@link AnalyticsPlatformAdapter}.\n *\n * This controller follows the MetaMask controller pattern and integrates with the\n * messenger system to allow other controllers and components to track analytics events.\n * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.\n *\n * The controller persists `optedIn` and `analyticsId` when composed with a persisted\n * store. The platform must supply a valid `analyticsId` on first launch.\n */\nexport class AnalyticsController extends BaseController<\n 'AnalyticsController',\n AnalyticsControllerState,\n AnalyticsControllerMessenger\n> {\n readonly #platformAdapter: AnalyticsPlatformAdapter;\n\n readonly #isAnonymousEventsFeatureEnabled: boolean;\n\n readonly #isEventQueuePersistenceEnabled: boolean;\n\n #initialized: boolean;\n\n /**\n * Constructs an AnalyticsController instance.\n *\n * @param options - Controller options\n * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.\n * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.\n * @param options.messenger - Messenger used to communicate with BaseController\n * @param options.platformAdapter - Platform adapter implementation for tracking\n * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled\n * @param options.isEventQueuePersistenceEnabled - Whether analytics event queue persistence is enabled\n * @throws Error if state.analyticsId is missing or not a valid UUIDv4\n * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.\n */\n constructor({\n state,\n messenger,\n platformAdapter,\n isAnonymousEventsFeatureEnabled = false,\n isEventQueuePersistenceEnabled = false,\n }: AnalyticsControllerOptions) {\n const initialState: AnalyticsControllerState = {\n ...getDefaultAnalyticsControllerState(),\n ...state,\n };\n\n validateAnalyticsControllerState(\n initialState,\n platformAdapter.skipUUIDv4Check === true,\n );\n\n super({\n name: controllerName,\n metadata: analyticsControllerMetadata,\n state: initialState,\n messenger,\n });\n\n this.#isAnonymousEventsFeatureEnabled = isAnonymousEventsFeatureEnabled;\n this.#isEventQueuePersistenceEnabled = isEventQueuePersistenceEnabled;\n this.#platformAdapter = platformAdapter;\n this.#initialized = false;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n log('AnalyticsController initialized and ready', {\n enabled: analyticsControllerSelectors.selectEnabled(this.state),\n optedIn: this.state.optedIn,\n analyticsId: this.state.analyticsId,\n eventQueuePersistenceEnabled: this.#isEventQueuePersistenceEnabled,\n });\n }\n\n /**\n * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.\n * This method must be called after construction to complete the setup process.\n */\n init(): void {\n if (this.#initialized) {\n log('AnalyticsController already initialized.');\n return;\n }\n\n this.#initialized = true;\n\n // Call onSetupCompleted lifecycle hook after initialization\n // State is already validated, so analyticsId is guaranteed to be a valid UUIDv4\n try {\n this.#platformAdapter.onSetupCompleted(this.state.analyticsId);\n } catch (error) {\n // Log error but don't throw - adapter setup failure shouldn't break controller\n log('Error calling platformAdapter.onSetupCompleted', error);\n }\n\n this.#replayQueuedEvents();\n }\n\n /**\n * Send final track payload through the platform adapter or queue it if persistence is enabled.\n *\n * @param eventName - The name of the event.\n * @param properties - Optional event properties.\n * @param context - Optional platform-specific context.\n */\n #sendOrQueueTrackEvent(\n eventName: string,\n properties?: AnalyticsEventProperties,\n context?: AnalyticsContext,\n ): void {\n if (!this.#isEventQueuePersistenceEnabled) {\n this.#platformAdapter.track(eventName, properties, context);\n return;\n }\n\n const queuedEvent: AnalyticsQueuedTrackEvent = {\n type: 'track',\n eventName,\n messageId: uuid(),\n timestamp: new Date().toISOString(),\n ...(properties === undefined ? {} : { properties }),\n ...(context === undefined ? {} : { context }),\n };\n\n this.#enqueueEvent(queuedEvent);\n }\n\n /**\n * Send final identify payload through the platform adapter or queue it if persistence is enabled.\n *\n * @param userId - The user ID.\n * @param traits - Optional user traits.\n * @param context - Optional platform-specific context.\n */\n #sendOrQueueIdentifyEvent(\n userId: string,\n traits?: AnalyticsUserTraits,\n context?: AnalyticsContext,\n ): void {\n if (!this.#isEventQueuePersistenceEnabled) {\n this.#platformAdapter.identify(userId, traits, context);\n return;\n }\n\n const queuedEvent: AnalyticsQueuedIdentifyEvent = {\n type: 'identify',\n userId,\n messageId: uuid(),\n timestamp: new Date().toISOString(),\n ...(traits === undefined ? {} : { traits }),\n ...(context === undefined ? {} : { context }),\n };\n\n this.#enqueueEvent(queuedEvent);\n }\n\n /**\n * Send final view payload through the platform adapter or queue it if persistence is enabled.\n *\n * @param name - The view name.\n * @param properties - Optional view properties.\n * @param context - Optional platform-specific context.\n */\n #sendOrQueueViewEvent(\n name: string,\n properties?: AnalyticsEventProperties,\n context?: AnalyticsContext,\n ): void {\n if (!this.#isEventQueuePersistenceEnabled) {\n this.#platformAdapter.view(name, properties, context);\n return;\n }\n\n const queuedEvent: AnalyticsQueuedViewEvent = {\n type: 'view',\n name,\n messageId: uuid(),\n timestamp: new Date().toISOString(),\n ...(properties === undefined ? {} : { properties }),\n ...(context === undefined ? {} : { context }),\n };\n\n this.#enqueueEvent(queuedEvent);\n }\n\n /**\n * Add an analytics event to the queue and send it.\n *\n * @param queuedEvent - The event to enqueue and deliver.\n */\n #enqueueEvent(queuedEvent: AnalyticsQueuedEvent): void {\n const eventQueue: Record<string, Json> = {\n ...(this.state.eventQueue ?? {}),\n [queuedEvent.messageId]: queuedEvent as unknown as Json,\n };\n\n this.update((state) => {\n state.eventQueue = eventQueue as never;\n });\n\n this.#sendQueuedEvent(queuedEvent);\n }\n\n /**\n * Send a queued event through the platform adapter.\n *\n * @param queuedEvent - The queued event to deliver.\n */\n #sendQueuedEvent(queuedEvent: AnalyticsQueuedEvent): void {\n const timestamp = new Date(queuedEvent.timestamp);\n\n if (Number.isNaN(timestamp.getTime())) {\n log('Dropping queued analytics event with invalid timestamp', {\n messageId: queuedEvent.messageId,\n });\n this.#removeQueuedEvent(queuedEvent.messageId);\n return;\n }\n\n const options: AnalyticsDeliveryOptions = {\n messageId: queuedEvent.messageId,\n timestamp,\n callback: (error?: unknown) => {\n if (error) {\n log('Queued analytics event delivery failed', {\n messageId: queuedEvent.messageId,\n error,\n });\n return;\n }\n\n this.#removeQueuedEvent(queuedEvent.messageId);\n },\n };\n\n try {\n if (queuedEvent.type === 'track') {\n this.#platformAdapter.track(\n queuedEvent.eventName,\n cloneDeep(queuedEvent.properties),\n cloneDeep(queuedEvent.context),\n options,\n );\n } else if (queuedEvent.type === 'identify') {\n this.#platformAdapter.identify(\n queuedEvent.userId,\n cloneDeep(queuedEvent.traits),\n cloneDeep(queuedEvent.context),\n options,\n );\n } else {\n this.#platformAdapter.view(\n queuedEvent.name,\n cloneDeep(queuedEvent.properties),\n cloneDeep(queuedEvent.context),\n options,\n );\n }\n } catch (error) {\n log('Error sending queued analytics event', {\n messageId: queuedEvent.messageId,\n error,\n });\n }\n }\n\n /**\n * Replay persisted analytics events.\n */\n #replayQueuedEvents(): void {\n if (!this.#isEventQueuePersistenceEnabled || !this.state.eventQueue) {\n return;\n }\n\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n this.#clearQueuedEvents();\n return;\n }\n\n for (const [messageId, queuedEvent] of Object.entries(\n this.state.eventQueue,\n )) {\n if (\n !isAnalyticsQueuedEvent(queuedEvent) ||\n queuedEvent.messageId !== messageId\n ) {\n log('Dropping invalid queued analytics event', { messageId });\n this.#removeQueuedEvent(messageId);\n continue;\n }\n\n this.#sendQueuedEvent(queuedEvent);\n }\n }\n\n /**\n * Remove a queued analytics event.\n *\n * @param messageId - The queued event message ID.\n */\n #removeQueuedEvent(messageId: string): void {\n const currentEventQueue = this.state.eventQueue;\n\n if (\n !currentEventQueue ||\n !Object.prototype.hasOwnProperty.call(currentEventQueue, messageId)\n ) {\n return;\n }\n\n const { [messageId]: _deletedEvent, ...eventQueue } = currentEventQueue;\n\n this.update((state) => {\n state.eventQueue = eventQueue as never;\n });\n }\n\n /**\n * Clear all queued analytics events.\n */\n #clearQueuedEvents(): void {\n if (\n !this.state.eventQueue ||\n Object.keys(this.state.eventQueue).length === 0\n ) {\n return;\n }\n\n this.update((state) => {\n state.eventQueue = {} as never;\n });\n }\n\n /**\n * Track an analytics event.\n *\n * Events are only tracked if analytics is enabled.\n *\n * @param event - Analytics event with properties and sensitive properties\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n trackEvent(event: AnalyticsTrackingEvent, context?: AnalyticsContext): void {\n // Don't track if analytics is disabled\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // if event does not have properties, send event without properties\n // and return to prevent any additional processing\n if (!event.hasProperties) {\n this.#sendOrQueueTrackEvent(event.name, undefined, context);\n return;\n }\n\n // Track regular properties first if anonymous events feature is enabled\n if (this.#isAnonymousEventsFeatureEnabled) {\n // Note: Even if regular properties object is empty, we still send it to ensure\n // an event with user ID is tracked.\n this.#sendOrQueueTrackEvent(\n event.name,\n {\n ...event.properties,\n },\n context,\n );\n }\n\n const hasSensitiveProperties =\n Object.keys(event.sensitiveProperties).length > 0;\n\n if (!this.#isAnonymousEventsFeatureEnabled || hasSensitiveProperties) {\n this.#sendOrQueueTrackEvent(\n event.name,\n {\n ...event.properties,\n ...event.sensitiveProperties,\n ...(hasSensitiveProperties && { anonymous: true }),\n },\n context,\n );\n }\n }\n\n /**\n * Identify a user for analytics.\n *\n * @param traits - User traits/properties\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n identify(traits?: AnalyticsUserTraits, context?: AnalyticsContext): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter using the current analytics ID\n this.#sendOrQueueIdentifyEvent(this.state.analyticsId, traits, context);\n }\n\n /**\n * Track a page or screen view.\n *\n * @param name - The identifier/name of the page or screen being viewed (e.g., \"home\", \"settings\", \"wallet\")\n * @param properties - Optional properties associated with the view\n * @param context - Optional platform-specific context forwarded to the platform adapter.\n */\n trackView(\n name: string,\n properties?: AnalyticsEventProperties,\n context?: AnalyticsContext,\n ): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter\n this.#sendOrQueueViewEvent(name, properties, context);\n }\n\n /**\n * Opt in to analytics.\n */\n optIn(): void {\n this.update((state) => {\n state.optedIn = true;\n });\n }\n\n /**\n * Opt out of analytics.\n */\n optOut(): void {\n this.update((state) => {\n state.optedIn = false;\n });\n\n this.#clearQueuedEvents();\n }\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
|
|
2
2
|
import { BaseController } from "@metamask/base-controller";
|
|
3
3
|
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import type { Json } from "@metamask/utils";
|
|
4
5
|
import type { AnalyticsControllerMethodActions } from "./AnalyticsController-method-action-types.cjs";
|
|
5
6
|
import type { AnalyticsPlatformAdapter, AnalyticsContext, AnalyticsEventProperties, AnalyticsUserTraits, AnalyticsTrackingEvent } from "./AnalyticsPlatformAdapter.types.cjs";
|
|
6
7
|
/**
|
|
@@ -23,7 +24,68 @@ export type AnalyticsControllerState = {
|
|
|
23
24
|
* Must be provided by the platform - the controller does not generate it.
|
|
24
25
|
*/
|
|
25
26
|
analyticsId: string;
|
|
27
|
+
/**
|
|
28
|
+
* Persisted queue of analytics events waiting for delivery acknowledgement.
|
|
29
|
+
* This is only used when event queue persistence is enabled.
|
|
30
|
+
*/
|
|
31
|
+
eventQueue?: Record<string, Json>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Event types supported by the persisted analytics event queue.
|
|
35
|
+
*/
|
|
36
|
+
export type AnalyticsQueuedEventType = 'track' | 'identify' | 'view';
|
|
37
|
+
/**
|
|
38
|
+
* Base persisted event queue entry.
|
|
39
|
+
*/
|
|
40
|
+
export type AnalyticsQueuedEventBase = {
|
|
41
|
+
/**
|
|
42
|
+
* Event type used to replay the payload with the platform adapter.
|
|
43
|
+
*/
|
|
44
|
+
type: AnalyticsQueuedEventType;
|
|
45
|
+
/**
|
|
46
|
+
* Stable identifier for the analytics payload.
|
|
47
|
+
*/
|
|
48
|
+
messageId: string;
|
|
49
|
+
/**
|
|
50
|
+
* Original payload timestamp serialized for persistence.
|
|
51
|
+
*/
|
|
52
|
+
timestamp: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Persisted track event queue entry.
|
|
56
|
+
*/
|
|
57
|
+
export type AnalyticsQueuedTrackEvent = AnalyticsQueuedEventBase & {
|
|
58
|
+
type: 'track';
|
|
59
|
+
eventName: string;
|
|
60
|
+
properties?: AnalyticsEventProperties;
|
|
61
|
+
context?: AnalyticsContext;
|
|
26
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Persisted identify event queue entry.
|
|
65
|
+
*/
|
|
66
|
+
export type AnalyticsQueuedIdentifyEvent = AnalyticsQueuedEventBase & {
|
|
67
|
+
type: 'identify';
|
|
68
|
+
userId: string;
|
|
69
|
+
traits?: AnalyticsUserTraits;
|
|
70
|
+
context?: AnalyticsContext;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Persisted view event queue entry.
|
|
74
|
+
*/
|
|
75
|
+
export type AnalyticsQueuedViewEvent = AnalyticsQueuedEventBase & {
|
|
76
|
+
type: 'view';
|
|
77
|
+
name: string;
|
|
78
|
+
properties?: AnalyticsEventProperties;
|
|
79
|
+
context?: AnalyticsContext;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Persisted analytics event queue entry.
|
|
83
|
+
*/
|
|
84
|
+
export type AnalyticsQueuedEvent = AnalyticsQueuedTrackEvent | AnalyticsQueuedIdentifyEvent | AnalyticsQueuedViewEvent;
|
|
85
|
+
/**
|
|
86
|
+
* Persisted analytics event queue keyed by message ID.
|
|
87
|
+
*/
|
|
88
|
+
export type AnalyticsEventQueue = Record<string, AnalyticsQueuedEvent>;
|
|
27
89
|
/**
|
|
28
90
|
* Returns default values for AnalyticsController state.
|
|
29
91
|
*
|
|
@@ -86,6 +148,15 @@ export type AnalyticsControllerOptions = {
|
|
|
86
148
|
* @default false
|
|
87
149
|
*/
|
|
88
150
|
isAnonymousEventsFeatureEnabled?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Whether analytics event queue persistence is enabled.
|
|
153
|
+
*
|
|
154
|
+
* When enabled, AnalyticsController persists each platform adapter payload
|
|
155
|
+
* until the adapter reports successful delivery.
|
|
156
|
+
*
|
|
157
|
+
* @default false
|
|
158
|
+
*/
|
|
159
|
+
isEventQueuePersistenceEnabled?: boolean;
|
|
89
160
|
};
|
|
90
161
|
/**
|
|
91
162
|
* The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
|
|
@@ -111,10 +182,11 @@ export declare class AnalyticsController extends BaseController<'AnalyticsContro
|
|
|
111
182
|
* @param options.messenger - Messenger used to communicate with BaseController
|
|
112
183
|
* @param options.platformAdapter - Platform adapter implementation for tracking
|
|
113
184
|
* @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
|
|
185
|
+
* @param options.isEventQueuePersistenceEnabled - Whether analytics event queue persistence is enabled
|
|
114
186
|
* @throws Error if state.analyticsId is missing or not a valid UUIDv4
|
|
115
187
|
* @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
|
|
116
188
|
*/
|
|
117
|
-
constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled, }: AnalyticsControllerOptions);
|
|
189
|
+
constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled, isEventQueuePersistenceEnabled, }: AnalyticsControllerOptions);
|
|
118
190
|
/**
|
|
119
191
|
* Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.
|
|
120
192
|
* This method must be called after construction to complete the setup process.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsController.d.cts","sourceRoot":"","sources":["../src/AnalyticsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"AnalyticsController.d.cts","sourceRoot":"","sources":["../src/AnalyticsController.ts"],"names":[],"mappings":"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"}
|