@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
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsController.d.mts","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.mts","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"}
@@ -9,11 +9,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  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");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _AnalyticsController_platformAdapter, _AnalyticsController_isAnonymousEventsFeatureEnabled, _AnalyticsController_initialized;
12
+ var _AnalyticsController_platformAdapter;
13
13
  import { BaseController } from "@metamask/base-controller";
14
- import { validateAnalyticsControllerState } from "./analyticsControllerStateValidator.mjs";
15
- import { projectLogger as log } from "./AnalyticsLogger.mjs";
16
- import { analyticsControllerSelectors } from "./selectors.mjs";
14
+ import { v4 as uuidv4 } from "uuid";
15
+ import { projectLogger } from "./AnalyticsLogger.mjs";
17
16
  // === GENERAL ===
18
17
  /**
19
18
  * The name of the {@link AnalyticsController}, used to namespace the
@@ -21,28 +20,16 @@ import { analyticsControllerSelectors } from "./selectors.mjs";
21
20
  * when composed with other controllers.
22
21
  */
23
22
  export const controllerName = 'AnalyticsController';
24
- /**
25
- * Returns default values for AnalyticsController state.
26
- *
27
- * Note: analyticsId is NOT included - it's an identity that must be
28
- * provided by the platform (generated once on first run, then persisted).
29
- *
30
- * @returns Default state without analyticsId
31
- */
32
- export function getDefaultAnalyticsControllerState() {
33
- return {
34
- optedIn: false,
35
- };
36
- }
37
23
  /**
38
24
  * The metadata for each property in {@link AnalyticsControllerState}.
39
- *
40
- * Note: `optedIn` is persisted by the controller (`persist: true`).
41
- * `analyticsId` is persisted by the platform (`persist: false`) and provided
42
- * via initial state. The platform should subscribe to `stateChange` events
43
- * to persist any state changes.
44
25
  */
45
26
  const analyticsControllerMetadata = {
27
+ enabled: {
28
+ includeInStateLogs: true,
29
+ persist: true,
30
+ includeInDebugSnapshot: true,
31
+ usedInUi: true,
32
+ },
46
33
  optedIn: {
47
34
  includeInStateLogs: true,
48
35
  persist: true,
@@ -51,16 +38,33 @@ const analyticsControllerMetadata = {
51
38
  },
52
39
  analyticsId: {
53
40
  includeInStateLogs: true,
54
- persist: false,
41
+ persist: true,
55
42
  includeInDebugSnapshot: true,
56
43
  usedInUi: false,
57
44
  },
58
45
  };
46
+ /**
47
+ * Constructs the default {@link AnalyticsController} state. This allows
48
+ * consumers to provide a partial state object when initializing the controller
49
+ * and also helps in constructing complete state objects for this controller in
50
+ * tests.
51
+ *
52
+ * @returns The default {@link AnalyticsController} state.
53
+ */
54
+ export function getDefaultAnalyticsControllerState() {
55
+ return {
56
+ enabled: true,
57
+ optedIn: false,
58
+ analyticsId: uuidv4(),
59
+ };
60
+ }
59
61
  // === MESSENGER ===
60
62
  const MESSENGER_EXPOSED_METHODS = [
61
63
  'trackEvent',
62
64
  'identify',
63
- 'trackView',
65
+ 'trackPage',
66
+ 'enable',
67
+ 'disable',
64
68
  'optIn',
65
69
  'optOut',
66
70
  ];
@@ -73,128 +77,100 @@ const MESSENGER_EXPOSED_METHODS = [
73
77
  * This controller follows the MetaMask controller pattern and integrates with the
74
78
  * messenger system to allow other controllers and components to track analytics events.
75
79
  * It delegates platform-specific implementation to an {@link AnalyticsPlatformAdapter}.
76
- *
77
- * Note: The controller persists `optedIn` internally. The `analyticsId` is persisted
78
- * by the platform and must be provided via initial state. The platform should subscribe
79
- * to `AnalyticsController:stateChange` events to persist any state changes.
80
80
  */
81
81
  export class AnalyticsController extends BaseController {
82
82
  /**
83
83
  * Constructs an AnalyticsController instance.
84
84
  *
85
85
  * @param options - Controller options
86
- * @param options.state - Initial controller state. Must include a valid UUIDv4 `analyticsId`.
87
- * Use `getDefaultAnalyticsControllerState()` for default opt-in preferences.
86
+ * @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
88
87
  * @param options.messenger - Messenger used to communicate with BaseController
89
88
  * @param options.platformAdapter - Platform adapter implementation for tracking
90
- * @param options.isAnonymousEventsFeatureEnabled - Whether the anonymous events feature is enabled
91
- * @throws Error if state.analyticsId is missing or not a valid UUIDv4
92
- * @remarks After construction, call {@link AnalyticsController.init} to complete initialization.
93
89
  */
94
- constructor({ state, messenger, platformAdapter, isAnonymousEventsFeatureEnabled = false, }) {
95
- const initialState = {
96
- ...getDefaultAnalyticsControllerState(),
97
- ...state,
98
- };
99
- validateAnalyticsControllerState(initialState);
90
+ constructor({ state = {}, messenger, platformAdapter, }) {
100
91
  super({
101
92
  name: controllerName,
102
93
  metadata: analyticsControllerMetadata,
103
- state: initialState,
94
+ state: {
95
+ ...getDefaultAnalyticsControllerState(),
96
+ ...state,
97
+ },
104
98
  messenger,
105
99
  });
106
100
  _AnalyticsController_platformAdapter.set(this, void 0);
107
- _AnalyticsController_isAnonymousEventsFeatureEnabled.set(this, void 0);
108
- _AnalyticsController_initialized.set(this, void 0);
109
- __classPrivateFieldSet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, isAnonymousEventsFeatureEnabled, "f");
110
101
  __classPrivateFieldSet(this, _AnalyticsController_platformAdapter, platformAdapter, "f");
111
- __classPrivateFieldSet(this, _AnalyticsController_initialized, false, "f");
112
102
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
113
- log('AnalyticsController initialized and ready', {
114
- enabled: analyticsControllerSelectors.selectEnabled(this.state),
103
+ projectLogger('AnalyticsController initialized and ready', {
104
+ enabled: this.state.enabled,
115
105
  optedIn: this.state.optedIn,
116
106
  analyticsId: this.state.analyticsId,
117
107
  });
118
108
  }
119
- /**
120
- * Initialize the controller by calling the platform adapter's onSetupCompleted lifecycle hook.
121
- * This method must be called after construction to complete the setup process.
122
- */
123
- init() {
124
- if (__classPrivateFieldGet(this, _AnalyticsController_initialized, "f")) {
125
- log('AnalyticsController already initialized.');
126
- return;
127
- }
128
- __classPrivateFieldSet(this, _AnalyticsController_initialized, true, "f");
129
- // Call onSetupCompleted lifecycle hook after initialization
130
- // State is already validated, so analyticsId is guaranteed to be a valid UUIDv4
131
- try {
132
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").onSetupCompleted(this.state.analyticsId);
133
- }
134
- catch (error) {
135
- // Log error but don't throw - adapter setup failure shouldn't break controller
136
- log('Error calling platformAdapter.onSetupCompleted', error);
137
- }
138
- }
139
109
  /**
140
110
  * Track an analytics event.
141
111
  *
142
112
  * Events are only tracked if analytics is enabled.
143
113
  *
144
- * @param event - Analytics event with properties and sensitive properties
114
+ * @param eventName - The name of the event
115
+ * @param properties - Event properties
145
116
  */
146
- trackEvent(event) {
117
+ trackEvent(eventName, properties = {}) {
147
118
  // Don't track if analytics is disabled
148
- if (!analyticsControllerSelectors.selectEnabled(this.state)) {
119
+ if (!this.state.enabled) {
149
120
  return;
150
121
  }
151
- // if event does not have properties, send event without properties
152
- // and return to prevent any additional processing
153
- if (!event.hasProperties) {
154
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name);
155
- return;
156
- }
157
- // Track regular properties first if anonymous events feature is enabled
158
- if (__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f")) {
159
- // Note: Even if regular properties object is empty, we still send it to ensure
160
- // an event with user ID is tracked.
161
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
162
- ...event.properties,
163
- });
164
- }
165
- const hasSensitiveProperties = Object.keys(event.sensitiveProperties).length > 0;
166
- if (!__classPrivateFieldGet(this, _AnalyticsController_isAnonymousEventsFeatureEnabled, "f") || hasSensitiveProperties) {
167
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
168
- ...event.properties,
169
- ...event.sensitiveProperties,
170
- ...(hasSensitiveProperties && { anonymous: true }),
171
- });
172
- }
122
+ // Delegate to platform adapter
123
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackEvent(eventName, properties);
173
124
  }
174
125
  /**
175
126
  * Identify a user for analytics.
176
127
  *
128
+ * @param userId - The user identifier (e.g., metametrics ID)
177
129
  * @param traits - User traits/properties
178
130
  */
179
- identify(traits) {
180
- if (!analyticsControllerSelectors.selectEnabled(this.state)) {
131
+ identify(userId, traits) {
132
+ if (!this.state.enabled) {
181
133
  return;
182
134
  }
183
- // Delegate to platform adapter using the current analytics ID
184
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(this.state.analyticsId, traits);
135
+ // Update state with analytics ID
136
+ this.update((state) => {
137
+ state.analyticsId = userId;
138
+ });
139
+ // Delegate to platform adapter if supported
140
+ if (__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify) {
141
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(userId, traits);
142
+ }
185
143
  }
186
144
  /**
187
- * Track a page or screen view.
145
+ * Track a page view.
188
146
  *
189
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
190
- * @param properties - Optional properties associated with the view
147
+ * @param pageName - The name of the page
148
+ * @param properties - Page properties
191
149
  */
192
- trackView(name, properties) {
193
- if (!analyticsControllerSelectors.selectEnabled(this.state)) {
150
+ trackPage(pageName, properties) {
151
+ if (!this.state.enabled) {
194
152
  return;
195
153
  }
196
- // Delegate to platform adapter
197
- __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").view(name, properties);
154
+ // Delegate to platform adapter if supported
155
+ if (__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackPage) {
156
+ __classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackPage(pageName, properties);
157
+ }
158
+ }
159
+ /**
160
+ * Enable analytics tracking.
161
+ */
162
+ enable() {
163
+ this.update((state) => {
164
+ state.enabled = true;
165
+ });
166
+ }
167
+ /**
168
+ * Disable analytics tracking.
169
+ */
170
+ disable() {
171
+ this.update((state) => {
172
+ state.enabled = false;
173
+ });
198
174
  }
199
175
  /**
200
176
  * Opt in to analytics.
@@ -213,5 +189,5 @@ export class AnalyticsController extends BaseController {
213
189
  });
214
190
  }
215
191
  }
216
- _AnalyticsController_platformAdapter = new WeakMap(), _AnalyticsController_isAnonymousEventsFeatureEnabled = new WeakMap(), _AnalyticsController_initialized = new WeakMap();
192
+ _AnalyticsController_platformAdapter = new WeakMap();
217
193
  //# sourceMappingURL=AnalyticsController.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsController.mjs","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.mjs","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 { 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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPlatformAdapter.types.cjs","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Json } from '@metamask/utils';\n\n/**\n * Analytics event properties\n */\nexport type AnalyticsEventProperties = Record<string, Json>;\n\n/**\n * User traits/properties for analytics identification\n */\nexport type AnalyticsUserTraits = Record<string, Json>;\n\n/**\n * Event properties structure with two distinct properties lists for regular and sensitive data.\n * Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.\n * Sensitivity is derived from the presence of sensitiveProperties (if sensitiveProperties has keys, the event is sensitive).\n */\nexport type AnalyticsTrackingEvent = {\n readonly name: string;\n properties: AnalyticsEventProperties;\n sensitiveProperties: AnalyticsEventProperties;\n /**\n * Legacy property handled by the mobile app.\n * This property is ignored by the analytics controller and will be removed from the type in the future.\n * The mobile app will use the future analytics privacy controller to handle this functionality.\n */\n saveDataRecording: boolean;\n readonly hasProperties: boolean;\n};\n\n/**\n * Platform adapter interface for analytics tracking\n * Implementations should handle platform-specific details (Segment SDK, etc.)\n */\nexport type AnalyticsPlatformAdapter = {\n /**\n * Track an analytics event.\n *\n * This is the same as trackEvent in the old analytics system\n *\n * @param eventName - The name of the event\n * @param properties - Event properties. If not provided, the event has no properties.\n * The privacy plugin should check for `isSensitive === true` to determine if an event contains sensitive data.\n */\n track(eventName: string, properties?: AnalyticsEventProperties): void;\n\n /**\n * Identify a user with traits.\n *\n * @param userId - The user identifier (e.g., metametrics ID)\n * @param traits - User traits/properties\n */\n identify(userId: string, traits?: AnalyticsUserTraits): void;\n\n /**\n * Track a UI unit (page or screen) view depending on the platform\n *\n * This method delegates to platform-specific Segment SDK methods:\n * - Web adapters should call `analytics.page(name, properties)`\n * - Mobile adapters should call `analytics.screen(name, properties)`\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 view(name: string, properties?: AnalyticsEventProperties): void;\n\n /**\n * Lifecycle hook called after the AnalyticsController is fully initialized.\n *\n * This hook allows platform-specific adapters to perform setup that requires\n * access to the controller's state (e.g., analyticsId).\n *\n * The controller calls this method once after initialization, passing the\n * analyticsId from controller state. The analyticsId is guaranteed to be set\n * when this method is called - this is the definition of \"completed\" setup.\n *\n * @param analyticsId - The analytics ID from controller state. Always set (never empty).\n * @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).\n * Errors thrown by this method are caught and logged by the controller, but do not prevent\n * controller initialization from completing successfully.\n *\n * @example\n * ```typescript\n * onSetupCompleted(analyticsId: string): void {\n * // Add platform-specific plugins that require analyticsId\n * client.add({\n * plugin: new PrivacyPlugin(analyticsId),\n * });\n * }\n * ```\n */\n onSetupCompleted(analyticsId: string): void;\n};\n"]}
1
+ {"version":3,"file":"AnalyticsPlatformAdapter.types.cjs","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Json } from '@metamask/utils';\n\n/**\n * Analytics event properties\n */\nexport type AnalyticsEventProperties = Record<string, Json>;\n\n/**\n * Platform adapter interface for analytics tracking\n * Implementations should handle platform-specific details (Segment SDK, etc.)\n *\n * @todo This type is work in progress and will be updated as we\n * integrate with the new analytics system on mobile.\n * We have this draft type to help us iterate on the implementation.\n * It will be updated with proper types as we create the mobile adapter\n * And the controller package will be released only when this is completed.\n */\nexport type AnalyticsPlatformAdapter = {\n /**\n * Track an analytics event\n *\n * @param eventName - The name of the event\n * @param properties - Event properties\n */\n trackEvent(eventName: string, properties: AnalyticsEventProperties): void;\n\n /**\n * Identify a user\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\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};\n"]}
@@ -3,85 +3,37 @@ import type { Json } from "@metamask/utils";
3
3
  * Analytics event properties
4
4
  */
5
5
  export type AnalyticsEventProperties = Record<string, Json>;
6
- /**
7
- * User traits/properties for analytics identification
8
- */
9
- export type AnalyticsUserTraits = Record<string, Json>;
10
- /**
11
- * Event properties structure with two distinct properties lists for regular and sensitive data.
12
- * Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.
13
- * Sensitivity is derived from the presence of sensitiveProperties (if sensitiveProperties has keys, the event is sensitive).
14
- */
15
- export type AnalyticsTrackingEvent = {
16
- readonly name: string;
17
- properties: AnalyticsEventProperties;
18
- sensitiveProperties: AnalyticsEventProperties;
19
- /**
20
- * Legacy property handled by the mobile app.
21
- * This property is ignored by the analytics controller and will be removed from the type in the future.
22
- * The mobile app will use the future analytics privacy controller to handle this functionality.
23
- */
24
- saveDataRecording: boolean;
25
- readonly hasProperties: boolean;
26
- };
27
6
  /**
28
7
  * Platform adapter interface for analytics tracking
29
8
  * Implementations should handle platform-specific details (Segment SDK, etc.)
9
+ *
10
+ * @todo This type is work in progress and will be updated as we
11
+ * integrate with the new analytics system on mobile.
12
+ * We have this draft type to help us iterate on the implementation.
13
+ * It will be updated with proper types as we create the mobile adapter
14
+ * And the controller package will be released only when this is completed.
30
15
  */
31
16
  export type AnalyticsPlatformAdapter = {
32
17
  /**
33
- * Track an analytics event.
34
- *
35
- * This is the same as trackEvent in the old analytics system
18
+ * Track an analytics event
36
19
  *
37
20
  * @param eventName - The name of the event
38
- * @param properties - Event properties. If not provided, the event has no properties.
39
- * The privacy plugin should check for `isSensitive === true` to determine if an event contains sensitive data.
21
+ * @param properties - Event properties
40
22
  */
41
- track(eventName: string, properties?: AnalyticsEventProperties): void;
23
+ trackEvent(eventName: string, properties: AnalyticsEventProperties): void;
42
24
  /**
43
- * Identify a user with traits.
25
+ * Identify a user
44
26
  *
45
27
  * @param userId - The user identifier (e.g., metametrics ID)
46
28
  * @param traits - User traits/properties
47
29
  */
48
- identify(userId: string, traits?: AnalyticsUserTraits): void;
30
+ identify?(userId: string, traits?: AnalyticsEventProperties): void;
49
31
  /**
50
- * Track a UI unit (page or screen) view depending on the platform
51
- *
52
- * This method delegates to platform-specific Segment SDK methods:
53
- * - Web adapters should call `analytics.page(name, properties)`
54
- * - Mobile adapters should call `analytics.screen(name, properties)`
55
- *
56
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
57
- * @param properties - Optional properties associated with the view
58
- */
59
- view(name: string, properties?: AnalyticsEventProperties): void;
60
- /**
61
- * Lifecycle hook called after the AnalyticsController is fully initialized.
62
- *
63
- * This hook allows platform-specific adapters to perform setup that requires
64
- * access to the controller's state (e.g., analyticsId).
65
- *
66
- * The controller calls this method once after initialization, passing the
67
- * analyticsId from controller state. The analyticsId is guaranteed to be set
68
- * when this method is called - this is the definition of "completed" setup.
69
- *
70
- * @param analyticsId - The analytics ID from controller state. Always set (never empty).
71
- * @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).
72
- * Errors thrown by this method are caught and logged by the controller, but do not prevent
73
- * controller initialization from completing successfully.
32
+ * Track a page view
74
33
  *
75
- * @example
76
- * ```typescript
77
- * onSetupCompleted(analyticsId: string): void {
78
- * // Add platform-specific plugins that require analyticsId
79
- * client.add({
80
- * plugin: new PrivacyPlugin(analyticsId),
81
- * });
82
- * }
83
- * ```
34
+ * @param pageName - The name of the page
35
+ * @param properties - Page properties
84
36
  */
85
- onSetupCompleted(analyticsId: string): void;
37
+ trackPage?(pageName: string, properties?: AnalyticsEventProperties): void;
86
38
  };
87
39
  //# sourceMappingURL=AnalyticsPlatformAdapter.types.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPlatformAdapter.types.d.cts","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,wBAAwB,CAAC;IACrC,mBAAmB,EAAE,wBAAwB,CAAC;IAC9C;;;;OAIG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;;;OAQG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEtE;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE7D;;;;;;;;;OASG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEhE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C,CAAC"}
1
+ {"version":3,"file":"AnalyticsPlatformAdapter.types.d.cts","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAE1E;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEnE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC3E,CAAC"}
@@ -3,85 +3,37 @@ import type { Json } from "@metamask/utils";
3
3
  * Analytics event properties
4
4
  */
5
5
  export type AnalyticsEventProperties = Record<string, Json>;
6
- /**
7
- * User traits/properties for analytics identification
8
- */
9
- export type AnalyticsUserTraits = Record<string, Json>;
10
- /**
11
- * Event properties structure with two distinct properties lists for regular and sensitive data.
12
- * Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.
13
- * Sensitivity is derived from the presence of sensitiveProperties (if sensitiveProperties has keys, the event is sensitive).
14
- */
15
- export type AnalyticsTrackingEvent = {
16
- readonly name: string;
17
- properties: AnalyticsEventProperties;
18
- sensitiveProperties: AnalyticsEventProperties;
19
- /**
20
- * Legacy property handled by the mobile app.
21
- * This property is ignored by the analytics controller and will be removed from the type in the future.
22
- * The mobile app will use the future analytics privacy controller to handle this functionality.
23
- */
24
- saveDataRecording: boolean;
25
- readonly hasProperties: boolean;
26
- };
27
6
  /**
28
7
  * Platform adapter interface for analytics tracking
29
8
  * Implementations should handle platform-specific details (Segment SDK, etc.)
9
+ *
10
+ * @todo This type is work in progress and will be updated as we
11
+ * integrate with the new analytics system on mobile.
12
+ * We have this draft type to help us iterate on the implementation.
13
+ * It will be updated with proper types as we create the mobile adapter
14
+ * And the controller package will be released only when this is completed.
30
15
  */
31
16
  export type AnalyticsPlatformAdapter = {
32
17
  /**
33
- * Track an analytics event.
34
- *
35
- * This is the same as trackEvent in the old analytics system
18
+ * Track an analytics event
36
19
  *
37
20
  * @param eventName - The name of the event
38
- * @param properties - Event properties. If not provided, the event has no properties.
39
- * The privacy plugin should check for `isSensitive === true` to determine if an event contains sensitive data.
21
+ * @param properties - Event properties
40
22
  */
41
- track(eventName: string, properties?: AnalyticsEventProperties): void;
23
+ trackEvent(eventName: string, properties: AnalyticsEventProperties): void;
42
24
  /**
43
- * Identify a user with traits.
25
+ * Identify a user
44
26
  *
45
27
  * @param userId - The user identifier (e.g., metametrics ID)
46
28
  * @param traits - User traits/properties
47
29
  */
48
- identify(userId: string, traits?: AnalyticsUserTraits): void;
30
+ identify?(userId: string, traits?: AnalyticsEventProperties): void;
49
31
  /**
50
- * Track a UI unit (page or screen) view depending on the platform
51
- *
52
- * This method delegates to platform-specific Segment SDK methods:
53
- * - Web adapters should call `analytics.page(name, properties)`
54
- * - Mobile adapters should call `analytics.screen(name, properties)`
55
- *
56
- * @param name - The identifier/name of the page or screen being viewed (e.g., "home", "settings", "wallet")
57
- * @param properties - Optional properties associated with the view
58
- */
59
- view(name: string, properties?: AnalyticsEventProperties): void;
60
- /**
61
- * Lifecycle hook called after the AnalyticsController is fully initialized.
62
- *
63
- * This hook allows platform-specific adapters to perform setup that requires
64
- * access to the controller's state (e.g., analyticsId).
65
- *
66
- * The controller calls this method once after initialization, passing the
67
- * analyticsId from controller state. The analyticsId is guaranteed to be set
68
- * when this method is called - this is the definition of "completed" setup.
69
- *
70
- * @param analyticsId - The analytics ID from controller state. Always set (never empty).
71
- * @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).
72
- * Errors thrown by this method are caught and logged by the controller, but do not prevent
73
- * controller initialization from completing successfully.
32
+ * Track a page view
74
33
  *
75
- * @example
76
- * ```typescript
77
- * onSetupCompleted(analyticsId: string): void {
78
- * // Add platform-specific plugins that require analyticsId
79
- * client.add({
80
- * plugin: new PrivacyPlugin(analyticsId),
81
- * });
82
- * }
83
- * ```
34
+ * @param pageName - The name of the page
35
+ * @param properties - Page properties
84
36
  */
85
- onSetupCompleted(analyticsId: string): void;
37
+ trackPage?(pageName: string, properties?: AnalyticsEventProperties): void;
86
38
  };
87
39
  //# sourceMappingURL=AnalyticsPlatformAdapter.types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPlatformAdapter.types.d.mts","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,wBAAwB,CAAC;IACrC,mBAAmB,EAAE,wBAAwB,CAAC;IAC9C;;;;OAIG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;;;OAQG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEtE;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE7D;;;;;;;;;OASG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEhE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C,CAAC"}
1
+ {"version":3,"file":"AnalyticsPlatformAdapter.types.d.mts","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAE1E;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEnE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC3E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPlatformAdapter.types.mjs","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Json } from '@metamask/utils';\n\n/**\n * Analytics event properties\n */\nexport type AnalyticsEventProperties = Record<string, Json>;\n\n/**\n * User traits/properties for analytics identification\n */\nexport type AnalyticsUserTraits = Record<string, Json>;\n\n/**\n * Event properties structure with two distinct properties lists for regular and sensitive data.\n * Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.\n * Sensitivity is derived from the presence of sensitiveProperties (if sensitiveProperties has keys, the event is sensitive).\n */\nexport type AnalyticsTrackingEvent = {\n readonly name: string;\n properties: AnalyticsEventProperties;\n sensitiveProperties: AnalyticsEventProperties;\n /**\n * Legacy property handled by the mobile app.\n * This property is ignored by the analytics controller and will be removed from the type in the future.\n * The mobile app will use the future analytics privacy controller to handle this functionality.\n */\n saveDataRecording: boolean;\n readonly hasProperties: boolean;\n};\n\n/**\n * Platform adapter interface for analytics tracking\n * Implementations should handle platform-specific details (Segment SDK, etc.)\n */\nexport type AnalyticsPlatformAdapter = {\n /**\n * Track an analytics event.\n *\n * This is the same as trackEvent in the old analytics system\n *\n * @param eventName - The name of the event\n * @param properties - Event properties. If not provided, the event has no properties.\n * The privacy plugin should check for `isSensitive === true` to determine if an event contains sensitive data.\n */\n track(eventName: string, properties?: AnalyticsEventProperties): void;\n\n /**\n * Identify a user with traits.\n *\n * @param userId - The user identifier (e.g., metametrics ID)\n * @param traits - User traits/properties\n */\n identify(userId: string, traits?: AnalyticsUserTraits): void;\n\n /**\n * Track a UI unit (page or screen) view depending on the platform\n *\n * This method delegates to platform-specific Segment SDK methods:\n * - Web adapters should call `analytics.page(name, properties)`\n * - Mobile adapters should call `analytics.screen(name, properties)`\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 view(name: string, properties?: AnalyticsEventProperties): void;\n\n /**\n * Lifecycle hook called after the AnalyticsController is fully initialized.\n *\n * This hook allows platform-specific adapters to perform setup that requires\n * access to the controller's state (e.g., analyticsId).\n *\n * The controller calls this method once after initialization, passing the\n * analyticsId from controller state. The analyticsId is guaranteed to be set\n * when this method is called - this is the definition of \"completed\" setup.\n *\n * @param analyticsId - The analytics ID from controller state. Always set (never empty).\n * @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).\n * Errors thrown by this method are caught and logged by the controller, but do not prevent\n * controller initialization from completing successfully.\n *\n * @example\n * ```typescript\n * onSetupCompleted(analyticsId: string): void {\n * // Add platform-specific plugins that require analyticsId\n * client.add({\n * plugin: new PrivacyPlugin(analyticsId),\n * });\n * }\n * ```\n */\n onSetupCompleted(analyticsId: string): void;\n};\n"]}
1
+ {"version":3,"file":"AnalyticsPlatformAdapter.types.mjs","sourceRoot":"","sources":["../src/AnalyticsPlatformAdapter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Json } from '@metamask/utils';\n\n/**\n * Analytics event properties\n */\nexport type AnalyticsEventProperties = Record<string, Json>;\n\n/**\n * Platform adapter interface for analytics tracking\n * Implementations should handle platform-specific details (Segment SDK, etc.)\n *\n * @todo This type is work in progress and will be updated as we\n * integrate with the new analytics system on mobile.\n * We have this draft type to help us iterate on the implementation.\n * It will be updated with proper types as we create the mobile adapter\n * And the controller package will be released only when this is completed.\n */\nexport type AnalyticsPlatformAdapter = {\n /**\n * Track an analytics event\n *\n * @param eventName - The name of the event\n * @param properties - Event properties\n */\n trackEvent(eventName: string, properties: AnalyticsEventProperties): void;\n\n /**\n * Identify a user\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\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};\n"]}
package/dist/index.cjs CHANGED
@@ -1,14 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.analyticsControllerSelectors = exports.AnalyticsPlatformAdapterSetupError = exports.getDefaultAnalyticsControllerState = exports.AnalyticsController = void 0;
4
- // Export controller class and state utilities
3
+ exports.getDefaultAnalyticsControllerState = exports.AnalyticsController = void 0;
4
+ // Export controller class
5
5
  var AnalyticsController_1 = require("./AnalyticsController.cjs");
6
6
  Object.defineProperty(exports, "AnalyticsController", { enumerable: true, get: function () { return AnalyticsController_1.AnalyticsController; } });
7
- Object.defineProperty(exports, "getDefaultAnalyticsControllerState", { enumerable: true, get: function () { return AnalyticsController_1.getDefaultAnalyticsControllerState; } });
8
- // Export errors
9
- var AnalyticsPlatformAdapterSetupError_1 = require("./AnalyticsPlatformAdapterSetupError.cjs");
10
- Object.defineProperty(exports, "AnalyticsPlatformAdapterSetupError", { enumerable: true, get: function () { return AnalyticsPlatformAdapterSetupError_1.AnalyticsPlatformAdapterSetupError; } });
11
- // Export selectors
12
- var selectors_1 = require("./selectors.cjs");
13
- Object.defineProperty(exports, "analyticsControllerSelectors", { enumerable: true, get: function () { return selectors_1.analyticsControllerSelectors; } });
7
+ var AnalyticsController_2 = require("./AnalyticsController.cjs");
8
+ Object.defineProperty(exports, "getDefaultAnalyticsControllerState", { enumerable: true, get: function () { return AnalyticsController_2.getDefaultAnalyticsControllerState; } });
14
9
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8CAA8C;AAC9C,iEAG+B;AAF7B,0HAAA,mBAAmB,OAAA;AACnB,yIAAA,kCAAkC,OAAA;AAIpC,gBAAgB;AAChB,+FAA0F;AAAjF,wJAAA,kCAAkC,OAAA;AAa3C,mBAAmB;AACnB,6CAA2D;AAAlD,yHAAA,4BAA4B,OAAA","sourcesContent":["// Export controller class and state utilities\nexport {\n AnalyticsController,\n getDefaultAnalyticsControllerState,\n} from './AnalyticsController';\nexport type { AnalyticsControllerOptions } from './AnalyticsController';\n\n// Export errors\nexport { AnalyticsPlatformAdapterSetupError } from './AnalyticsPlatformAdapterSetupError';\n\n// Export types\nexport type {\n AnalyticsEventProperties,\n AnalyticsUserTraits,\n AnalyticsPlatformAdapter,\n AnalyticsTrackingEvent,\n} from './AnalyticsPlatformAdapter.types';\n\n// Export state types\nexport type { AnalyticsControllerState } from './AnalyticsController';\n\n// Export selectors\nexport { analyticsControllerSelectors } from './selectors';\n\n// Export messenger types\nexport type { AnalyticsControllerMessenger } from './AnalyticsController';\n\n// Export action and event types\nexport type {\n AnalyticsControllerActions,\n AnalyticsControllerEvents,\n AnalyticsControllerGetStateAction,\n AnalyticsControllerStateChangeEvent,\n} from './AnalyticsController';\nexport type {\n AnalyticsControllerTrackEventAction,\n AnalyticsControllerIdentifyAction,\n AnalyticsControllerTrackViewAction,\n AnalyticsControllerOptInAction,\n AnalyticsControllerOptOutAction,\n AnalyticsControllerMethodActions,\n} from './AnalyticsController-method-action-types';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0BAA0B;AAC1B,iEAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAW5B,iEAA2E;AAAlE,yIAAA,kCAAkC,OAAA","sourcesContent":["// Export controller class\nexport { AnalyticsController } from './AnalyticsController';\nexport type { AnalyticsControllerOptions } from './AnalyticsController';\n\n// Export types\nexport type {\n AnalyticsEventProperties,\n AnalyticsPlatformAdapter,\n} from './AnalyticsPlatformAdapter.types';\n\n// Export state types and utilities\nexport type { AnalyticsControllerState } from './AnalyticsController';\nexport { getDefaultAnalyticsControllerState } from './AnalyticsController';\n\n// Export messenger types\nexport type { AnalyticsControllerMessenger } from './AnalyticsController';\n\n// Export action and event types\nexport type {\n AnalyticsControllerActions,\n AnalyticsControllerEvents,\n AnalyticsControllerGetStateAction,\n AnalyticsControllerStateChangeEvent,\n controllerName,\n} from './AnalyticsController';\nexport type {\n AnalyticsControllerTrackEventAction,\n AnalyticsControllerIdentifyAction,\n AnalyticsControllerTrackPageAction,\n AnalyticsControllerEnableAction,\n AnalyticsControllerDisableAction,\n AnalyticsControllerOptInAction,\n AnalyticsControllerOptOutAction,\n AnalyticsControllerMethodActions,\n} from './AnalyticsController-method-action-types';\n"]}