@metamask-previews/analytics-controller 0.0.0-preview-cb4a07d5 → 0.0.0-preview-565dfca2

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.
Files changed (54) hide show
  1. package/README.md +174 -30
  2. package/dist/AnalyticsController-method-action-types.cjs.map +1 -1
  3. package/dist/AnalyticsController-method-action-types.d.cts +24 -8
  4. package/dist/AnalyticsController-method-action-types.d.cts.map +1 -1
  5. package/dist/AnalyticsController-method-action-types.d.mts +24 -8
  6. package/dist/AnalyticsController-method-action-types.d.mts.map +1 -1
  7. package/dist/AnalyticsController-method-action-types.mjs.map +1 -1
  8. package/dist/AnalyticsController.cjs +78 -102
  9. package/dist/AnalyticsController.cjs.map +1 -1
  10. package/dist/AnalyticsController.d.cts +34 -48
  11. package/dist/AnalyticsController.d.cts.map +1 -1
  12. package/dist/AnalyticsController.d.mts +34 -48
  13. package/dist/AnalyticsController.d.mts.map +1 -1
  14. package/dist/AnalyticsController.mjs +79 -103
  15. package/dist/AnalyticsController.mjs.map +1 -1
  16. package/dist/AnalyticsPlatformAdapter.types.cjs.map +1 -1
  17. package/dist/AnalyticsPlatformAdapter.types.d.cts +15 -63
  18. package/dist/AnalyticsPlatformAdapter.types.d.cts.map +1 -1
  19. package/dist/AnalyticsPlatformAdapter.types.d.mts +15 -63
  20. package/dist/AnalyticsPlatformAdapter.types.d.mts.map +1 -1
  21. package/dist/AnalyticsPlatformAdapter.types.mjs.map +1 -1
  22. package/dist/index.cjs +4 -9
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +5 -6
  25. package/dist/index.d.cts.map +1 -1
  26. package/dist/index.d.mts +5 -6
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +3 -6
  29. package/dist/index.mjs.map +1 -1
  30. package/package.json +3 -2
  31. package/dist/AnalyticsPlatformAdapterSetupError.cjs +0 -17
  32. package/dist/AnalyticsPlatformAdapterSetupError.cjs.map +0 -1
  33. package/dist/AnalyticsPlatformAdapterSetupError.d.cts +0 -8
  34. package/dist/AnalyticsPlatformAdapterSetupError.d.cts.map +0 -1
  35. package/dist/AnalyticsPlatformAdapterSetupError.d.mts +0 -8
  36. package/dist/AnalyticsPlatformAdapterSetupError.d.mts.map +0 -1
  37. package/dist/AnalyticsPlatformAdapterSetupError.mjs +0 -13
  38. package/dist/AnalyticsPlatformAdapterSetupError.mjs.map +0 -1
  39. package/dist/analyticsControllerStateValidator.cjs +0 -34
  40. package/dist/analyticsControllerStateValidator.cjs.map +0 -1
  41. package/dist/analyticsControllerStateValidator.d.cts +0 -16
  42. package/dist/analyticsControllerStateValidator.d.cts.map +0 -1
  43. package/dist/analyticsControllerStateValidator.d.mts +0 -16
  44. package/dist/analyticsControllerStateValidator.d.mts.map +0 -1
  45. package/dist/analyticsControllerStateValidator.mjs +0 -29
  46. package/dist/analyticsControllerStateValidator.mjs.map +0 -1
  47. package/dist/selectors.cjs +0 -36
  48. package/dist/selectors.cjs.map +0 -1
  49. package/dist/selectors.d.cts +0 -11
  50. package/dist/selectors.d.cts.map +0 -1
  51. package/dist/selectors.d.mts +0 -11
  52. package/dist/selectors.d.mts.map +0 -1
  53. package/dist/selectors.mjs +0 -33
  54. package/dist/selectors.mjs.map +0 -1
@@ -10,13 +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_platformAdapter;
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 analyticsControllerStateValidator_1 = require("./analyticsControllerStateValidator.cjs");
17
+ const uuid_1 = require("uuid");
18
18
  const AnalyticsLogger_1 = require("./AnalyticsLogger.cjs");
19
- const selectors_1 = require("./selectors.cjs");
20
19
  // === GENERAL ===
21
20
  /**
22
21
  * The name of the {@link AnalyticsController}, used to namespace the
@@ -24,29 +23,16 @@ const selectors_1 = require("./selectors.cjs");
24
23
  * when composed with other controllers.
25
24
  */
26
25
  exports.controllerName = 'AnalyticsController';
27
- /**
28
- * Returns default values for AnalyticsController state.
29
- *
30
- * Note: analyticsId is NOT included - it's an identity that must be
31
- * provided by the platform (generated once on first run, then persisted).
32
- *
33
- * @returns Default state without analyticsId
34
- */
35
- function getDefaultAnalyticsControllerState() {
36
- return {
37
- optedIn: false,
38
- };
39
- }
40
- exports.getDefaultAnalyticsControllerState = getDefaultAnalyticsControllerState;
41
26
  /**
42
27
  * The metadata for each property in {@link AnalyticsControllerState}.
43
- *
44
- * Note: `optedIn` is persisted by the controller (`persist: true`).
45
- * `analyticsId` is persisted by the platform (`persist: false`) and provided
46
- * via initial state. The platform should subscribe to `stateChange` events
47
- * to persist any state changes.
48
28
  */
49
29
  const analyticsControllerMetadata = {
30
+ enabled: {
31
+ includeInStateLogs: true,
32
+ persist: true,
33
+ includeInDebugSnapshot: true,
34
+ usedInUi: true,
35
+ },
50
36
  optedIn: {
51
37
  includeInStateLogs: true,
52
38
  persist: true,
@@ -55,16 +41,34 @@ const analyticsControllerMetadata = {
55
41
  },
56
42
  analyticsId: {
57
43
  includeInStateLogs: true,
58
- persist: false,
44
+ persist: true,
59
45
  includeInDebugSnapshot: true,
60
46
  usedInUi: false,
61
47
  },
62
48
  };
49
+ /**
50
+ * Constructs the default {@link AnalyticsController} state. This allows
51
+ * consumers to provide a partial state object when initializing the controller
52
+ * and also helps in constructing complete state objects for this controller in
53
+ * tests.
54
+ *
55
+ * @returns The default {@link AnalyticsController} state.
56
+ */
57
+ function getDefaultAnalyticsControllerState() {
58
+ return {
59
+ enabled: true,
60
+ optedIn: false,
61
+ analyticsId: (0, uuid_1.v4)(),
62
+ };
63
+ }
64
+ exports.getDefaultAnalyticsControllerState = getDefaultAnalyticsControllerState;
63
65
  // === MESSENGER ===
64
66
  const MESSENGER_EXPOSED_METHODS = [
65
67
  'trackEvent',
66
68
  'identify',
67
- 'trackView',
69
+ 'trackPage',
70
+ 'enable',
71
+ 'disable',
68
72
  'optIn',
69
73
  'optOut',
70
74
  ];
@@ -77,128 +81,100 @@ const MESSENGER_EXPOSED_METHODS = [
77
81
  * This controller follows the MetaMask controller pattern and integrates with the
78
82
  * messenger system to allow other controllers and components to track analytics events.
79
83
  * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.
80
- *
81
- * Note: The controller persists `optedIn` internally. The `analyticsId` is persisted
82
- * by the platform and must be provided via initial state. The platform should subscribe
83
- * to `AnalyticsController:stateChange` events to persist any state changes.
84
84
  */
85
85
  class AnalyticsController extends base_controller_1.BaseController {
86
86
  /**
87
87
  * Constructs an AnalyticsController instance.
88
88
  *
89
89
  * @param options - Controller options
90
- * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.
91
- * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.
90
+ * @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
92
91
  * @param options.messenger - Messenger used to communicate with BaseController
93
92
  * @param options.platformAdapter - Platform adapter implementation for tracking
94
- * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
95
- * @throws Error if state.analyticsId is missing or not a valid UUIDv4
96
- * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
97
93
  */
98
- constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled = false, }) {
99
- const initialState = {
100
- ...getDefaultAnalyticsControllerState(),
101
- ...state,
102
- };
103
- (0, analyticsControllerStateValidator_1.validateAnalyticsControllerState)(initialState);
94
+ constructor({ state = {}, messenger, platformAdapter, }) {
104
95
  super({
105
96
  name: exports.controllerName,
106
97
  metadata: analyticsControllerMetadata,
107
- state: initialState,
98
+ state: {
99
+ ...getDefaultAnalyticsControllerState(),
100
+ ...state,
101
+ },
108
102
  messenger,
109
103
  });
110
104
  _AnalyticsController_platformAdapter.set(this, void 0);
111
- _AnalyticsController_isAnonymousEventsFeatureEnabled.set(this, void 0);
112
- _AnalyticsController_initialized.set(this, void 0);
113
- __classPrivateFieldSet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, isAnonymousEventsFeatureEnabled, "f");
114
105
  __classPrivateFieldSet(this, _AnalyticsController_platformAdapter, platformAdapter, "f");
115
- __classPrivateFieldSet(this, _AnalyticsController_initialized, false, "f");
116
106
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
117
107
  (0, AnalyticsLogger_1.projectLogger)('AnalyticsController initialized and ready', {
118
- enabled: selectors_1.analyticsControllerSelectors.selectEnabled(this.state),
108
+ enabled: this.state.enabled,
119
109
  optedIn: this.state.optedIn,
120
110
  analyticsId: this.state.analyticsId,
121
111
  });
122
112
  }
123
- /**
124
- * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.
125
- * This method must be called after construction to complete the setup process.
126
- */
127
- init() {
128
- if (__classPrivateFieldGet(this, _AnalyticsController_initialized, "f")) {
129
- (0, AnalyticsLogger_1.projectLogger)('AnalyticsController already initialized.');
130
- return;
131
- }
132
- __classPrivateFieldSet(this, _AnalyticsController_initialized, true, "f");
133
- // Call onSetupCompleted lifecycle hook after initialization
134
- // State is already validated, so analyticsId is guaranteed to be a valid UUIDv4
135
- try {
136
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").onSetupCompleted(this.state.analyticsId);
137
- }
138
- catch (error) {
139
- // Log error but don't throw - adapter setup failure shouldn't break controller
140
- (0, AnalyticsLogger_1.projectLogger)('Error calling platformAdapter.onSetupCompleted', error);
141
- }
142
- }
143
113
  /**
144
114
  * Track an analytics event.
145
115
  *
146
116
  * Events are only tracked if analytics is enabled.
147
117
  *
148
- * @param event - Analytics event with properties and sensitive properties
118
+ * @param eventName - The name of the event
119
+ * @param properties - Event properties
149
120
  */
150
- trackEvent(event) {
121
+ trackEvent(eventName, properties = {}) {
151
122
  // Don't track if analytics is disabled
152
- if (!selectors_1.analyticsControllerSelectors.selectEnabled(this.state)) {
123
+ if (!this.state.enabled) {
153
124
  return;
154
125
  }
155
- // if event does not have properties, send event without properties
156
- // and return to prevent any additional processing
157
- if (!event.hasProperties) {
158
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name);
159
- return;
160
- }
161
- // Track regular properties first if anonymous events feature is enabled
162
- if (__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f")) {
163
- // Note: Even if regular properties object is empty, we still send it to ensure
164
- // an event with user ID is tracked.
165
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
166
- ...event.properties,
167
- });
168
- }
169
- const hasSensitiveProperties = Object.keys(event.sensitiveProperties).length > 0;
170
- if (!__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f") || hasSensitiveProperties) {
171
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
172
- ...event.properties,
173
- ...event.sensitiveProperties,
174
- ...(hasSensitiveProperties && { anonymous: true }),
175
- });
176
- }
126
+ // Delegate to platform adapter
127
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackEvent(eventName, properties);
177
128
  }
178
129
  /**
179
130
  * Identify a user for analytics.
180
131
  *
132
+ * @param userId - The user identifier (e.g., metametrics ID)
181
133
  * @param traits - User traits/properties
182
134
  */
183
- identify(traits) {
184
- if (!selectors_1.analyticsControllerSelectors.selectEnabled(this.state)) {
135
+ identify(userId, traits) {
136
+ if (!this.state.enabled) {
185
137
  return;
186
138
  }
187
- // Delegate to platform adapter using the current analytics ID
188
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(this.state.analyticsId, traits);
139
+ // Update state with analytics ID
140
+ this.update((state) => {
141
+ state.analyticsId = userId;
142
+ });
143
+ // Delegate to platform adapter if supported
144
+ if (__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify) {
145
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(userId, traits);
146
+ }
189
147
  }
190
148
  /**
191
- * Track a page or screen view.
149
+ * Track a page view.
192
150
  *
193
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
194
- * @param properties - Optional properties associated with the view
151
+ * @param pageName - The name of the page
152
+ * @param properties - Page properties
195
153
  */
196
- trackView(name, properties) {
197
- if (!selectors_1.analyticsControllerSelectors.selectEnabled(this.state)) {
154
+ trackPage(pageName, properties) {
155
+ if (!this.state.enabled) {
198
156
  return;
199
157
  }
200
- // Delegate to platform adapter
201
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties);
158
+ // Delegate to platform adapter if supported
159
+ if (__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackPage) {
160
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackPage(pageName, properties);
161
+ }
162
+ }
163
+ /**
164
+ * Enable analytics tracking.
165
+ */
166
+ enable() {
167
+ this.update((state) => {
168
+ state.enabled = true;
169
+ });
170
+ }
171
+ /**
172
+ * Disable analytics tracking.
173
+ */
174
+ disable() {
175
+ this.update((state) => {
176
+ state.enabled = false;
177
+ });
202
178
  }
203
179
  /**
204
180
  * Opt in to analytics.
@@ -218,5 +194,5 @@ class AnalyticsController extends base_controller_1.BaseController {
218
194
  }
219
195
  }
220
196
  exports.AnalyticsController = AnalyticsController;
221
- _AnalyticsController_platformAdapter = new WeakMap(), _AnalyticsController_isAnonymousEventsFeatureEnabled = new WeakMap(), _AnalyticsController_initialized = new WeakMap();
197
+ _AnalyticsController_platformAdapter = new WeakMap();
222
198
  //# 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 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 * Note: `optedIn` is persisted by the controller (`persist: true`).\n * `analyticsId` is persisted by the platform (`persist: false`) and provided\n * via initial state. The platform should subscribe to `stateChange` events\n * to persist any state changes.\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: false,\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 and persisting the analyticsId.\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 * Note: The controller persists `optedIn` internally. The `analyticsId` is persisted\n * by the platform and must be provided via initial state. The platform should subscribe\n * to `AnalyticsController:stateChange` events to persist any state changes.\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(initialState);\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 */\n trackEvent(event: AnalyticsTrackingEvent): 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.#platformAdapter.track(event.name);\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.#platformAdapter.track(event.name, {\n ...event.properties,\n });\n }\n\n const hasSensitiveProperties =\n Object.keys(event.sensitiveProperties).length > 0;\n\n if (!this.#isAnonymousEventsFeatureEnabled || hasSensitiveProperties) {\n this.#platformAdapter.track(event.name, {\n ...event.properties,\n ...event.sensitiveProperties,\n ...(hasSensitiveProperties && { anonymous: true }),\n });\n }\n }\n\n /**\n * Identify a user for analytics.\n *\n * @param traits - User traits/properties\n */\n identify(traits?: AnalyticsUserTraits): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter using the current analytics ID\n this.#platformAdapter.identify(this.state.analyticsId, traits);\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 */\n trackView(name: string, properties?: AnalyticsEventProperties): void {\n if (!analyticsControllerSelectors.selectEnabled(this.state)) {\n return;\n }\n\n // Delegate to platform adapter\n this.#platformAdapter.view(name, properties);\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":";;;;;;;;;;;;;;;AAKA,+DAA2D;AAE3D,+BAAoC;AAGpC,2DAAkD;AAMlD,kBAAkB;AAElB;;;;GAIG;AACU,QAAA,cAAc,GAAG,qBAAqB,CAAC;AAwBpD;;GAEG;AACH,MAAM,2BAA2B,GAAG;IAClC,OAAO,EAAE;QACP,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,OAAO,EAAE;QACP,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,WAAW,EAAE;QACX,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,KAAK;KAChB;CACgD,CAAC;AAEpD;;;;;;;GAOG;AACH,SAAgB,kCAAkC;IAChD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,IAAA,SAAM,GAAE;KACtB,CAAC;AACJ,CAAC;AAND,gFAMC;AAED,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,YAAY;IACZ,UAAU;IACV,WAAW;IACX,QAAQ;IACR,SAAS;IACT,OAAO;IACP,QAAQ;CACA,CAAC;AAgEX;;;;;;;;;GASG;AACH,MAAa,mBAAoB,SAAQ,gCAIxC;IAGC;;;;;;;OAOG;IACH,YAAY,EACV,KAAK,GAAG,EAAE,EACV,SAAS,EACT,eAAe,GACY;QAC3B,KAAK,CAAC;YACJ,IAAI,EAAE,sBAAc;YACpB,QAAQ,EAAE,2BAA2B;YACrC,KAAK,EAAE;gBACL,GAAG,kCAAkC,EAAE;gBACvC,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;QAvBI,uDAA2C;QAyBlD,uBAAA,IAAI,wCAAoB,eAAe,MAAA,CAAC;QAExC,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;QAEF,IAAA,+BAAa,EAAC,2CAA2C,EAAE;YACzD,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAC3B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAC3B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;SACpC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CACR,SAAiB,EACjB,aAAuC,EAAE;QAEzC,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,uBAAA,IAAI,4CAAiB,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,MAAc,EAAE,MAAiC;QACxD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,4CAA4C;QAC5C,IAAI,uBAAA,IAAI,4CAAiB,CAAC,QAAQ,EAAE,CAAC;YACnC,uBAAA,IAAI,4CAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAgB,EAAE,UAAqC;QAC/D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,4CAA4C;QAC5C,IAAI,uBAAA,IAAI,4CAAiB,CAAC,SAAS,EAAE,CAAC;YACpC,uBAAA,IAAI,4CAAiB,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA3ID,kDA2IC","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 { v4 as uuidv4 } from 'uuid';\n\nimport type { AnalyticsControllerMethodActions } from './AnalyticsController-method-action-types';\nimport { projectLogger } from './AnalyticsLogger';\nimport type {\n AnalyticsPlatformAdapter,\n AnalyticsEventProperties,\n} from './AnalyticsPlatformAdapter.types';\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 analytics tracking is enabled\n */\n enabled: boolean;\n\n /**\n * Whether the user has opted in to analytics\n */\n optedIn: boolean;\n\n /**\n * User's UUIDv4 analytics identifier\n */\n analyticsId: string;\n};\n\n/**\n * The metadata for each property in {@link AnalyticsControllerState}.\n */\nconst analyticsControllerMetadata = {\n enabled: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\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/**\n * Constructs the default {@link AnalyticsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link AnalyticsController} state.\n */\nexport function getDefaultAnalyticsControllerState(): AnalyticsControllerState {\n return {\n enabled: true,\n optedIn: false,\n analyticsId: uuidv4(),\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'trackEvent',\n 'identify',\n 'trackPage',\n 'enable',\n 'disable',\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 state?: Partial<AnalyticsControllerState>;\n messenger: AnalyticsControllerMessenger;\n /**\n * Platform adapter implementation for tracking events\n */\n platformAdapter: AnalyticsPlatformAdapter;\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 */\nexport class AnalyticsController extends BaseController<\n 'AnalyticsController',\n AnalyticsControllerState,\n AnalyticsControllerMessenger\n> {\n readonly #platformAdapter: AnalyticsPlatformAdapter;\n\n /**\n * Constructs an AnalyticsController instance.\n *\n * @param options - Controller options\n * @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)\n * @param options.messenger - Messenger used to communicate with BaseController\n * @param options.platformAdapter - Platform adapter implementation for tracking\n */\n constructor({\n state = {},\n messenger,\n platformAdapter,\n }: AnalyticsControllerOptions) {\n super({\n name: controllerName,\n metadata: analyticsControllerMetadata,\n state: {\n ...getDefaultAnalyticsControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#platformAdapter = platformAdapter;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n projectLogger('AnalyticsController initialized and ready', {\n enabled: this.state.enabled,\n optedIn: this.state.optedIn,\n analyticsId: this.state.analyticsId,\n });\n }\n\n /**\n * Track an analytics event.\n *\n * Events are only tracked if analytics is enabled.\n *\n * @param eventName - The name of the event\n * @param properties - Event properties\n */\n trackEvent(\n eventName: string,\n properties: AnalyticsEventProperties = {},\n ): void {\n // Don't track if analytics is disabled\n if (!this.state.enabled) {\n return;\n }\n\n // Delegate to platform adapter\n this.#platformAdapter.trackEvent(eventName, properties);\n }\n\n /**\n * Identify a user for analytics.\n *\n * @param userId - The user identifier (e.g., metametrics ID)\n * @param traits - User traits/properties\n */\n identify(userId: string, traits?: AnalyticsEventProperties): void {\n if (!this.state.enabled) {\n return;\n }\n\n // Update state with analytics ID\n this.update((state) => {\n state.analyticsId = userId;\n });\n\n // Delegate to platform adapter if supported\n if (this.#platformAdapter.identify) {\n this.#platformAdapter.identify(userId, traits);\n }\n }\n\n /**\n * Track a page view.\n *\n * @param pageName - The name of the page\n * @param properties - Page properties\n */\n trackPage(pageName: string, properties?: AnalyticsEventProperties): void {\n if (!this.state.enabled) {\n return;\n }\n\n // Delegate to platform adapter if supported\n if (this.#platformAdapter.trackPage) {\n this.#platformAdapter.trackPage(pageName, properties);\n }\n }\n\n /**\n * Enable analytics tracking.\n */\n enable(): void {\n this.update((state) => {\n state.enabled = true;\n });\n }\n\n /**\n * Disable analytics tracking.\n */\n disable(): void {\n this.update((state) => {\n state.enabled = false;\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"]}
@@ -2,7 +2,7 @@ import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@meta
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { AnalyticsControllerMethodActions } from "./AnalyticsController-method-action-types.cjs";
5
- import type { AnalyticsPlatformAdapter, AnalyticsEventProperties, AnalyticsUserTraits, AnalyticsTrackingEvent } from "./AnalyticsPlatformAdapter.types.cjs";
5
+ import type { AnalyticsPlatformAdapter, AnalyticsEventProperties } from "./AnalyticsPlatformAdapter.types.cjs";
6
6
  /**
7
7
  * The name of the {@link AnalyticsController}, used to namespace the
8
8
  * controller's actions and events and to namespace the controller's state data
@@ -14,25 +14,27 @@ export declare const controllerName = "AnalyticsController";
14
14
  */
15
15
  export type AnalyticsControllerState = {
16
16
  /**
17
- * Whether the user has opted in to analytics.
17
+ * Whether analytics tracking is enabled
18
+ */
19
+ enabled: boolean;
20
+ /**
21
+ * Whether the user has opted in to analytics
18
22
  */
19
23
  optedIn: boolean;
20
24
  /**
21
- * User's UUIDv4 analytics identifier.
22
- * This is an identity (unique per user), not a preference.
23
- * Must be provided by the platform - the controller does not generate it.
25
+ * User's UUIDv4 analytics identifier
24
26
  */
25
27
  analyticsId: string;
26
28
  };
27
29
  /**
28
- * Returns default values for AnalyticsController state.
29
- *
30
- * Note: analyticsId is NOT included - it's an identity that must be
31
- * provided by the platform (generated once on first run, then persisted).
30
+ * Constructs the default {@link AnalyticsController} state. This allows
31
+ * consumers to provide a partial state object when initializing the controller
32
+ * and also helps in constructing complete state objects for this controller in
33
+ * tests.
32
34
  *
33
- * @returns Default state without analyticsId
35
+ * @returns The default {@link AnalyticsController} state.
34
36
  */
35
- export declare function getDefaultAnalyticsControllerState(): Omit<AnalyticsControllerState, 'analyticsId'>;
37
+ export declare function getDefaultAnalyticsControllerState(): AnalyticsControllerState;
36
38
  /**
37
39
  * Returns the state of the {@link AnalyticsController}.
38
40
  */
@@ -66,25 +68,12 @@ export type AnalyticsControllerMessenger = Messenger<typeof controllerName, Anal
66
68
  * The options that AnalyticsController takes.
67
69
  */
68
70
  export type AnalyticsControllerOptions = {
69
- /**
70
- * Initial controller state. Must include a valid UUIDv4 `analyticsId`.
71
- * The platform is responsible for generating and persisting the analyticsId.
72
- */
73
- state: AnalyticsControllerState;
74
- /**
75
- * Messenger used to communicate with BaseController and other controllers.
76
- */
71
+ state?: Partial<AnalyticsControllerState>;
77
72
  messenger: AnalyticsControllerMessenger;
78
73
  /**
79
- * Platform adapter implementation for tracking events.
74
+ * Platform adapter implementation for tracking events
80
75
  */
81
76
  platformAdapter: AnalyticsPlatformAdapter;
82
- /**
83
- * Whether the anonymous events feature is enabled.
84
- *
85
- * @default false
86
- */
87
- isAnonymousEventsFeatureEnabled?: boolean;
88
77
  };
89
78
  /**
90
79
  * The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
@@ -95,10 +84,6 @@ export type AnalyticsControllerOptions = {
95
84
  * This controller follows the MetaMask controller pattern and integrates with the
96
85
  * messenger system to allow other controllers and components to track analytics events.
97
86
  * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.
98
- *
99
- * Note: The controller persists `optedIn` internally. The `analyticsId` is persisted
100
- * by the platform and must be provided via initial state. The platform should subscribe
101
- * to `AnalyticsController:stateChange` events to persist any state changes.
102
87
  */
103
88
  export declare class AnalyticsController extends BaseController<'AnalyticsController', AnalyticsControllerState, AnalyticsControllerMessenger> {
104
89
  #private;
@@ -106,41 +91,42 @@ export declare class AnalyticsController extends BaseController<'AnalyticsContro
106
91
  * Constructs an AnalyticsController instance.
107
92
  *
108
93
  * @param options - Controller options
109
- * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.
110
- * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.
94
+ * @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
111
95
  * @param options.messenger - Messenger used to communicate with BaseController
112
96
  * @param options.platformAdapter - Platform adapter implementation for tracking
113
- * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
114
- * @throws Error if state.analyticsId is missing or not a valid UUIDv4
115
- * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
116
- */
117
- constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled, }: AnalyticsControllerOptions);
118
- /**
119
- * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.
120
- * This method must be called after construction to complete the setup process.
121
97
  */
122
- init(): void;
98
+ constructor({ state, messenger, platformAdapter, }: AnalyticsControllerOptions);
123
99
  /**
124
100
  * Track an analytics event.
125
101
  *
126
102
  * Events are only tracked if analytics is enabled.
127
103
  *
128
- * @param event - Analytics event with properties and sensitive properties
104
+ * @param eventName - The name of the event
105
+ * @param properties - Event properties
129
106
  */
130
- trackEvent(event: AnalyticsTrackingEvent): void;
107
+ trackEvent(eventName: string, properties?: AnalyticsEventProperties): void;
131
108
  /**
132
109
  * Identify a user for analytics.
133
110
  *
111
+ * @param userId - The user identifier (e.g., metametrics ID)
134
112
  * @param traits - User traits/properties
135
113
  */
136
- identify(traits?: AnalyticsUserTraits): void;
114
+ identify(userId: string, traits?: AnalyticsEventProperties): void;
137
115
  /**
138
- * Track a page or screen view.
116
+ * Track a page view.
139
117
  *
140
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
141
- * @param properties - Optional properties associated with the view
118
+ * @param pageName - The name of the page
119
+ * @param properties - Page properties
120
+ */
121
+ trackPage(pageName: string, properties?: AnalyticsEventProperties): void;
122
+ /**
123
+ * Enable analytics tracking.
124
+ */
125
+ enable(): void;
126
+ /**
127
+ * Disable analytics tracking.
142
128
  */
143
- trackView(name: string, properties?: AnalyticsEventProperties): void;
129
+ disable(): void;
144
130
  /**
145
131
  * Opt in to analytics.
146
132
  */
@@ -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;AAErD,OAAO,KAAK,EAAE,gCAAgC,EAAE,sDAAkD;AAGlG,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACvB,6CAAyC;AAK1C;;;;GAIG;AACH,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAIpD;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,IAAI,IAAI,CACxD,wBAAwB,EACxB,aAAa,CACd,CAIA;AAmCD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG,wBAAwB,CACtE,OAAO,cAAc,EACrB,wBAAwB,CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAClC,iCAAiC,GACjC,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG,0BAA0B,CAC1E,OAAO,cAAc,EACrB,wBAAwB,CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mCAAmC,CAAC;AAE5E;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG,SAAS,CAClD,OAAO,cAAc,EACrB,0BAA0B,GAAG,cAAc,EAC3C,yBAAyB,GAAG,aAAa,CAC1C,CAAC;AAIF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC;;;OAGG;IACH,KAAK,EAAE,wBAAwB,CAAC;IAChC;;OAEG;IACH,SAAS,EAAE,4BAA4B,CAAC;IACxC;;OAEG;IACH,eAAe,EAAE,wBAAwB,CAAC;IAE1C;;;;OAIG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAoB,SAAQ,cAAc,CACrD,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,CAC7B;;IAOC;;;;;;;;;;;OAWG;gBACS,EACV,KAAK,EACL,SAAS,EACT,eAAe,EACf,+BAAuC,GACxC,EAAE,0BAA0B;IA+B7B;;;OAGG;IACH,IAAI,IAAI,IAAI;IAkBZ;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAkC/C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI;IAS5C;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI;IASpE;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}
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;AAGrD,OAAO,KAAK,EAAE,gCAAgC,EAAE,sDAAkD;AAElG,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,6CAAyC;AAI1C;;;;GAIG;AACH,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAIpD;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AA0BF;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,IAAI,wBAAwB,CAM7E;AAcD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG,wBAAwB,CACtE,OAAO,cAAc,EACrB,wBAAwB,CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAClC,iCAAiC,GACjC,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG,0BAA0B,CAC1E,OAAO,cAAc,EACrB,wBAAwB,CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mCAAmC,CAAC;AAE5E;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG,SAAS,CAClD,OAAO,cAAc,EACrB,0BAA0B,GAAG,cAAc,EAC3C,yBAAyB,GAAG,aAAa,CAC1C,CAAC;AAIF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC1C,SAAS,EAAE,4BAA4B,CAAC;IACxC;;OAEG;IACH,eAAe,EAAE,wBAAwB,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,mBAAoB,SAAQ,cAAc,CACrD,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,CAC7B;;IAGC;;;;;;;OAOG;gBACS,EACV,KAAU,EACV,SAAS,EACT,eAAe,GAChB,EAAE,0BAA0B;IAyB7B;;;;;;;OAOG;IACH,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,wBAA6B,GACxC,IAAI;IAUP;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,wBAAwB,GAAG,IAAI;IAgBjE;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI;IAWxE;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,OAAO,IAAI,IAAI;IAMf;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}
@@ -2,7 +2,7 @@ import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@meta
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { AnalyticsControllerMethodActions } from "./AnalyticsController-method-action-types.mjs";
5
- import type { AnalyticsPlatformAdapter, AnalyticsEventProperties, AnalyticsUserTraits, AnalyticsTrackingEvent } from "./AnalyticsPlatformAdapter.types.mjs";
5
+ import type { AnalyticsPlatformAdapter, AnalyticsEventProperties } from "./AnalyticsPlatformAdapter.types.mjs";
6
6
  /**
7
7
  * The name of the {@link AnalyticsController}, used to namespace the
8
8
  * controller's actions and events and to namespace the controller's state data
@@ -14,25 +14,27 @@ export declare const controllerName = "AnalyticsController";
14
14
  */
15
15
  export type AnalyticsControllerState = {
16
16
  /**
17
- * Whether the user has opted in to analytics.
17
+ * Whether analytics tracking is enabled
18
+ */
19
+ enabled: boolean;
20
+ /**
21
+ * Whether the user has opted in to analytics
18
22
  */
19
23
  optedIn: boolean;
20
24
  /**
21
- * User's UUIDv4 analytics identifier.
22
- * This is an identity (unique per user), not a preference.
23
- * Must be provided by the platform - the controller does not generate it.
25
+ * User's UUIDv4 analytics identifier
24
26
  */
25
27
  analyticsId: string;
26
28
  };
27
29
  /**
28
- * Returns default values for AnalyticsController state.
29
- *
30
- * Note: analyticsId is NOT included - it's an identity that must be
31
- * provided by the platform (generated once on first run, then persisted).
30
+ * Constructs the default {@link AnalyticsController} state. This allows
31
+ * consumers to provide a partial state object when initializing the controller
32
+ * and also helps in constructing complete state objects for this controller in
33
+ * tests.
32
34
  *
33
- * @returns Default state without analyticsId
35
+ * @returns The default {@link AnalyticsController} state.
34
36
  */
35
- export declare function getDefaultAnalyticsControllerState(): Omit<AnalyticsControllerState, 'analyticsId'>;
37
+ export declare function getDefaultAnalyticsControllerState(): AnalyticsControllerState;
36
38
  /**
37
39
  * Returns the state of the {@link AnalyticsController}.
38
40
  */
@@ -66,25 +68,12 @@ export type AnalyticsControllerMessenger = Messenger<typeof controllerName, Anal
66
68
  * The options that AnalyticsController takes.
67
69
  */
68
70
  export type AnalyticsControllerOptions = {
69
- /**
70
- * Initial controller state. Must include a valid UUIDv4 `analyticsId`.
71
- * The platform is responsible for generating and persisting the analyticsId.
72
- */
73
- state: AnalyticsControllerState;
74
- /**
75
- * Messenger used to communicate with BaseController and other controllers.
76
- */
71
+ state?: Partial<AnalyticsControllerState>;
77
72
  messenger: AnalyticsControllerMessenger;
78
73
  /**
79
- * Platform adapter implementation for tracking events.
74
+ * Platform adapter implementation for tracking events
80
75
  */
81
76
  platformAdapter: AnalyticsPlatformAdapter;
82
- /**
83
- * Whether the anonymous events feature is enabled.
84
- *
85
- * @default false
86
- */
87
- isAnonymousEventsFeatureEnabled?: boolean;
88
77
  };
89
78
  /**
90
79
  * The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
@@ -95,10 +84,6 @@ export type AnalyticsControllerOptions = {
95
84
  * This controller follows the MetaMask controller pattern and integrates with the
96
85
  * messenger system to allow other controllers and components to track analytics events.
97
86
  * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.
98
- *
99
- * Note: The controller persists `optedIn` internally. The `analyticsId` is persisted
100
- * by the platform and must be provided via initial state. The platform should subscribe
101
- * to `AnalyticsController:stateChange` events to persist any state changes.
102
87
  */
103
88
  export declare class AnalyticsController extends BaseController<'AnalyticsController', AnalyticsControllerState, AnalyticsControllerMessenger> {
104
89
  #private;
@@ -106,41 +91,42 @@ export declare class AnalyticsController extends BaseController<'AnalyticsContro
106
91
  * Constructs an AnalyticsController instance.
107
92
  *
108
93
  * @param options - Controller options
109
- * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.
110
- * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.
94
+ * @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
111
95
  * @param options.messenger - Messenger used to communicate with BaseController
112
96
  * @param options.platformAdapter - Platform adapter implementation for tracking
113
- * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
114
- * @throws Error if state.analyticsId is missing or not a valid UUIDv4
115
- * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
116
- */
117
- constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled, }: AnalyticsControllerOptions);
118
- /**
119
- * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.
120
- * This method must be called after construction to complete the setup process.
121
97
  */
122
- init(): void;
98
+ constructor({ state, messenger, platformAdapter, }: AnalyticsControllerOptions);
123
99
  /**
124
100
  * Track an analytics event.
125
101
  *
126
102
  * Events are only tracked if analytics is enabled.
127
103
  *
128
- * @param event - Analytics event with properties and sensitive properties
104
+ * @param eventName - The name of the event
105
+ * @param properties - Event properties
129
106
  */
130
- trackEvent(event: AnalyticsTrackingEvent): void;
107
+ trackEvent(eventName: string, properties?: AnalyticsEventProperties): void;
131
108
  /**
132
109
  * Identify a user for analytics.
133
110
  *
111
+ * @param userId - The user identifier (e.g., metametrics ID)
134
112
  * @param traits - User traits/properties
135
113
  */
136
- identify(traits?: AnalyticsUserTraits): void;
114
+ identify(userId: string, traits?: AnalyticsEventProperties): void;
137
115
  /**
138
- * Track a page or screen view.
116
+ * Track a page view.
139
117
  *
140
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
141
- * @param properties - Optional properties associated with the view
118
+ * @param pageName - The name of the page
119
+ * @param properties - Page properties
120
+ */
121
+ trackPage(pageName: string, properties?: AnalyticsEventProperties): void;
122
+ /**
123
+ * Enable analytics tracking.
124
+ */
125
+ enable(): void;
126
+ /**
127
+ * Disable analytics tracking.
142
128
  */
143
- trackView(name: string, properties?: AnalyticsEventProperties): void;
129
+ disable(): void;
144
130
  /**
145
131
  * Opt in to analytics.
146
132
  */