@metamask-previews/analytics-controller 0.0.0-preview-704ae19a → 0.0.0-preview-b0cb618e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -61
- package/dist/AnalyticsController-method-action-types.cjs.map +1 -1
- package/dist/AnalyticsController-method-action-types.d.cts +23 -62
- package/dist/AnalyticsController-method-action-types.d.cts.map +1 -1
- package/dist/AnalyticsController-method-action-types.d.mts +23 -62
- package/dist/AnalyticsController-method-action-types.d.mts.map +1 -1
- package/dist/AnalyticsController-method-action-types.mjs.map +1 -1
- package/dist/AnalyticsController.cjs +52 -125
- package/dist/AnalyticsController.cjs.map +1 -1
- package/dist/AnalyticsController.d.cts +24 -52
- package/dist/AnalyticsController.d.cts.map +1 -1
- package/dist/AnalyticsController.d.mts +24 -52
- package/dist/AnalyticsController.d.mts.map +1 -1
- package/dist/AnalyticsController.mjs +53 -126
- package/dist/AnalyticsController.mjs.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.cjs.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.d.cts +13 -69
- package/dist/AnalyticsPlatformAdapter.types.d.cts.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.d.mts +13 -69
- package/dist/AnalyticsPlatformAdapter.types.d.mts.map +1 -1
- package/dist/AnalyticsPlatformAdapter.types.mjs.map +1 -1
- package/dist/index.cjs +1 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/AnalyticsPlatformAdapterSetupError.cjs +0 -17
- package/dist/AnalyticsPlatformAdapterSetupError.cjs.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.d.cts +0 -8
- package/dist/AnalyticsPlatformAdapterSetupError.d.cts.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.d.mts +0 -8
- package/dist/AnalyticsPlatformAdapterSetupError.d.mts.map +0 -1
- package/dist/AnalyticsPlatformAdapterSetupError.mjs +0 -13
- package/dist/AnalyticsPlatformAdapterSetupError.mjs.map +0 -1
- package/dist/analyticsStateComputer.cjs +0 -46
- package/dist/analyticsStateComputer.cjs.map +0 -1
- package/dist/analyticsStateComputer.d.cts +0 -35
- package/dist/analyticsStateComputer.d.cts.map +0 -1
- package/dist/analyticsStateComputer.d.mts +0 -35
- package/dist/analyticsStateComputer.d.mts.map +0 -1
- package/dist/analyticsStateComputer.mjs +0 -42
- package/dist/analyticsStateComputer.mjs.map +0 -1
|
@@ -11,9 +11,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _AnalyticsController_platformAdapter;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
|
-
import { v4 as uuidv4
|
|
14
|
+
import { v4 as uuidv4 } from "uuid";
|
|
15
15
|
import { projectLogger } from "./AnalyticsLogger.mjs";
|
|
16
|
-
import { computeEnabledState } from "./analyticsStateComputer.mjs";
|
|
17
16
|
// === GENERAL ===
|
|
18
17
|
/**
|
|
19
18
|
* The name of the {@link AnalyticsController}, used to namespace the
|
|
@@ -25,19 +24,19 @@ export const controllerName = 'AnalyticsController';
|
|
|
25
24
|
* The metadata for each property in {@link AnalyticsControllerState}.
|
|
26
25
|
*/
|
|
27
26
|
const analyticsControllerMetadata = {
|
|
28
|
-
|
|
27
|
+
enabled: {
|
|
29
28
|
includeInStateLogs: true,
|
|
30
29
|
persist: true,
|
|
31
30
|
includeInDebugSnapshot: true,
|
|
32
31
|
usedInUi: true,
|
|
33
32
|
},
|
|
34
|
-
|
|
33
|
+
optedIn: {
|
|
35
34
|
includeInStateLogs: true,
|
|
36
35
|
persist: true,
|
|
37
36
|
includeInDebugSnapshot: true,
|
|
38
37
|
usedInUi: true,
|
|
39
38
|
},
|
|
40
|
-
|
|
39
|
+
analyticsId: {
|
|
41
40
|
includeInStateLogs: true,
|
|
42
41
|
persist: true,
|
|
43
42
|
includeInDebugSnapshot: true,
|
|
@@ -54,24 +53,20 @@ const analyticsControllerMetadata = {
|
|
|
54
53
|
*/
|
|
55
54
|
export function getDefaultAnalyticsControllerState() {
|
|
56
55
|
return {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
enabled: true,
|
|
57
|
+
optedIn: false,
|
|
58
|
+
analyticsId: uuidv4(),
|
|
60
59
|
};
|
|
61
60
|
}
|
|
62
61
|
// === MESSENGER ===
|
|
63
62
|
const MESSENGER_EXPOSED_METHODS = [
|
|
64
63
|
'trackEvent',
|
|
65
64
|
'identify',
|
|
66
|
-
'
|
|
65
|
+
'trackPage',
|
|
66
|
+
'enable',
|
|
67
|
+
'disable',
|
|
67
68
|
'optIn',
|
|
68
69
|
'optOut',
|
|
69
|
-
'socialOptIn',
|
|
70
|
-
'socialOptOut',
|
|
71
|
-
'getAnalyticsId',
|
|
72
|
-
'isEnabled',
|
|
73
|
-
'isOptedIn',
|
|
74
|
-
'isSocialOptedIn',
|
|
75
70
|
];
|
|
76
71
|
/**
|
|
77
72
|
* The AnalyticsController manages analytics tracking across platforms (Mobile/Extension).
|
|
@@ -88,179 +83,111 @@ export class AnalyticsController extends BaseController {
|
|
|
88
83
|
* Constructs an AnalyticsController instance.
|
|
89
84
|
*
|
|
90
85
|
* @param options - Controller options
|
|
91
|
-
* @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
|
|
92
|
-
* For migration from a previous system, pass the existing analytics ID via state.user_analyticsId.
|
|
86
|
+
* @param options.state - Initial controller state (defaults from getDefaultAnalyticsControllerState)
|
|
93
87
|
* @param options.messenger - Messenger used to communicate with BaseController
|
|
94
88
|
* @param options.platformAdapter - Platform adapter implementation for tracking
|
|
95
89
|
*/
|
|
96
90
|
constructor({ state = {}, messenger, platformAdapter, }) {
|
|
97
|
-
const initialState = {
|
|
98
|
-
...getDefaultAnalyticsControllerState(),
|
|
99
|
-
...state,
|
|
100
|
-
};
|
|
101
91
|
super({
|
|
102
92
|
name: controllerName,
|
|
103
93
|
metadata: analyticsControllerMetadata,
|
|
104
|
-
state:
|
|
94
|
+
state: {
|
|
95
|
+
...getDefaultAnalyticsControllerState(),
|
|
96
|
+
...state,
|
|
97
|
+
},
|
|
105
98
|
messenger,
|
|
106
99
|
});
|
|
107
100
|
_AnalyticsController_platformAdapter.set(this, void 0);
|
|
108
101
|
__classPrivateFieldSet(this, _AnalyticsController_platformAdapter, platformAdapter, "f");
|
|
109
102
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
110
103
|
projectLogger('AnalyticsController initialized and ready', {
|
|
111
|
-
enabled:
|
|
112
|
-
optedIn: this.state.
|
|
113
|
-
|
|
114
|
-
analyticsId: this.state.user_analyticsId,
|
|
104
|
+
enabled: this.state.enabled,
|
|
105
|
+
optedIn: this.state.optedIn,
|
|
106
|
+
analyticsId: this.state.analyticsId,
|
|
115
107
|
});
|
|
116
|
-
// Call onSetupCompleted lifecycle hook after initialization
|
|
117
|
-
// Only call if analyticsId is set and is a valid UUIDv4 (this is the definition of "completed" setup)
|
|
118
|
-
if (this.state.user_analyticsId &&
|
|
119
|
-
uuidValidate(this.state.user_analyticsId) &&
|
|
120
|
-
uuidVersion(this.state.user_analyticsId) === 4) {
|
|
121
|
-
try {
|
|
122
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").onSetupCompleted(this.state.user_analyticsId);
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
// Log error but don't throw - adapter setup failure shouldn't break controller
|
|
126
|
-
projectLogger('Error calling platformAdapter.onSetupCompleted', error);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
// analyticsId is undefined, null, empty string, or not a valid UUIDv4
|
|
131
|
-
throw new Error(`Invalid analyticsId: expected a valid UUIDv4, but got ${JSON.stringify(this.state.user_analyticsId)}`);
|
|
132
|
-
}
|
|
133
108
|
}
|
|
134
109
|
/**
|
|
135
110
|
* Track an analytics event.
|
|
136
111
|
*
|
|
137
112
|
* Events are only tracked if analytics is enabled.
|
|
138
113
|
*
|
|
139
|
-
* @param
|
|
114
|
+
* @param eventName - The name of the event
|
|
115
|
+
* @param properties - Event properties
|
|
140
116
|
*/
|
|
141
|
-
trackEvent(
|
|
117
|
+
trackEvent(eventName, properties = {}) {
|
|
142
118
|
// Don't track if analytics is disabled
|
|
143
|
-
if (!
|
|
119
|
+
if (!this.state.enabled) {
|
|
144
120
|
return;
|
|
145
121
|
}
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
if (!event.hasProperties) {
|
|
149
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
|
|
150
|
-
anonymous: false,
|
|
151
|
-
});
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
// Log all non-anonymous properties, or an empty event if there's no non-anon props.
|
|
155
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
|
|
156
|
-
anonymous: false,
|
|
157
|
-
...event.properties,
|
|
158
|
-
});
|
|
159
|
-
// Track all sensitive properties in an anonymous event
|
|
160
|
-
if (event.isAnonymous) {
|
|
161
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").track(event.name, {
|
|
162
|
-
anonymous: true,
|
|
163
|
-
...event.properties,
|
|
164
|
-
...event.sensitiveProperties,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
122
|
+
// Delegate to platform adapter
|
|
123
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").trackEvent(eventName, properties);
|
|
167
124
|
}
|
|
168
125
|
/**
|
|
169
126
|
* Identify a user for analytics.
|
|
170
127
|
*
|
|
128
|
+
* @param userId - The user identifier (e.g., metametrics ID)
|
|
171
129
|
* @param traits - User traits/properties
|
|
172
130
|
*/
|
|
173
|
-
identify(traits) {
|
|
174
|
-
if (!
|
|
131
|
+
identify(userId, traits) {
|
|
132
|
+
if (!this.state.enabled) {
|
|
175
133
|
return;
|
|
176
134
|
}
|
|
177
|
-
//
|
|
135
|
+
// Update state with analytics ID
|
|
136
|
+
this.update((state) => {
|
|
137
|
+
state.analyticsId = userId;
|
|
138
|
+
});
|
|
139
|
+
// Delegate to platform adapter if supported
|
|
178
140
|
if (__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify) {
|
|
179
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(
|
|
141
|
+
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").identify(userId, traits);
|
|
180
142
|
}
|
|
181
143
|
}
|
|
182
144
|
/**
|
|
183
145
|
* Track a page view.
|
|
184
146
|
*
|
|
185
|
-
* @param
|
|
186
|
-
* @param properties -
|
|
147
|
+
* @param pageName - The name of the page
|
|
148
|
+
* @param properties - Page properties
|
|
187
149
|
*/
|
|
188
|
-
|
|
189
|
-
if (!
|
|
150
|
+
trackPage(pageName, properties) {
|
|
151
|
+
if (!this.state.enabled) {
|
|
190
152
|
return;
|
|
191
153
|
}
|
|
192
|
-
// Delegate to platform adapter
|
|
193
|
-
__classPrivateFieldGet(this, _AnalyticsController_platformAdapter, "f").
|
|
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
|
+
}
|
|
194
158
|
}
|
|
195
159
|
/**
|
|
196
|
-
*
|
|
197
|
-
* This updates the user's opt-in status.
|
|
160
|
+
* Enable analytics tracking.
|
|
198
161
|
*/
|
|
199
|
-
|
|
162
|
+
enable() {
|
|
200
163
|
this.update((state) => {
|
|
201
|
-
state.
|
|
164
|
+
state.enabled = true;
|
|
202
165
|
});
|
|
203
166
|
}
|
|
204
167
|
/**
|
|
205
|
-
*
|
|
206
|
-
* This updates the user's opt-in status.
|
|
168
|
+
* Disable analytics tracking.
|
|
207
169
|
*/
|
|
208
|
-
|
|
170
|
+
disable() {
|
|
209
171
|
this.update((state) => {
|
|
210
|
-
state.
|
|
172
|
+
state.enabled = false;
|
|
211
173
|
});
|
|
212
174
|
}
|
|
213
175
|
/**
|
|
214
|
-
* Opt in to analytics
|
|
215
|
-
* This updates the user's social opt-in status.
|
|
176
|
+
* Opt in to analytics.
|
|
216
177
|
*/
|
|
217
|
-
|
|
178
|
+
optIn() {
|
|
218
179
|
this.update((state) => {
|
|
219
|
-
state.
|
|
180
|
+
state.optedIn = true;
|
|
220
181
|
});
|
|
221
182
|
}
|
|
222
183
|
/**
|
|
223
|
-
* Opt out of analytics
|
|
224
|
-
* This updates the user's social opt-in status.
|
|
184
|
+
* Opt out of analytics.
|
|
225
185
|
*/
|
|
226
|
-
|
|
186
|
+
optOut() {
|
|
227
187
|
this.update((state) => {
|
|
228
|
-
state.
|
|
188
|
+
state.optedIn = false;
|
|
229
189
|
});
|
|
230
190
|
}
|
|
231
|
-
/**
|
|
232
|
-
* Get the analytics ID from the controller state.
|
|
233
|
-
*
|
|
234
|
-
* @returns The current analytics ID.
|
|
235
|
-
*/
|
|
236
|
-
getAnalyticsId() {
|
|
237
|
-
return this.state.user_analyticsId;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Get the enabled status from the controller state.
|
|
241
|
-
* This is computed from user state via the state machine.
|
|
242
|
-
*
|
|
243
|
-
* @returns The current enabled status.
|
|
244
|
-
*/
|
|
245
|
-
isEnabled() {
|
|
246
|
-
return computeEnabledState(this.state);
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Get the opted in status from the controller state.
|
|
250
|
-
*
|
|
251
|
-
* @returns The current opted in status.
|
|
252
|
-
*/
|
|
253
|
-
isOptedIn() {
|
|
254
|
-
return this.state.user_optedIn;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Get the social opted in status from the controller state.
|
|
258
|
-
*
|
|
259
|
-
* @returns The current social opted in status.
|
|
260
|
-
*/
|
|
261
|
-
isSocialOptedIn() {
|
|
262
|
-
return this.state.user_socialOptedIn;
|
|
263
|
-
}
|
|
264
191
|
}
|
|
265
192
|
_AnalyticsController_platformAdapter = new WeakMap();
|
|
266
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';\nimport {\n v4 as uuidv4,\n validate as uuidValidate,\n version as uuidVersion,\n} from 'uuid';\n\nimport type { AnalyticsControllerMethodActions } from './AnalyticsController-method-action-types';\nimport { projectLogger } from './AnalyticsLogger';\nimport type {\n AnalyticsPlatformAdapter,\n AnalyticsEventProperties,\n AnalyticsUserTraits,\n AnalyticsTrackingEvent,\n} from './AnalyticsPlatformAdapter.types';\nimport { computeEnabledState } from './analyticsStateComputer';\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 * User domain: Whether the user has opted in to analytics.\n */\n user_optedIn: boolean;\n\n /**\n * User domain: Whether the user has opted in to analytics through social account.\n */\n user_socialOptedIn: boolean;\n\n /**\n * User domain: User's UUIDv4 analytics identifier.\n */\n user_analyticsId: string;\n};\n\n/**\n * The metadata for each property in {@link AnalyticsControllerState}.\n */\nconst analyticsControllerMetadata = {\n user_optedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n user_socialOptedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n user_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 user_optedIn: false,\n user_socialOptedIn: false,\n user_analyticsId: uuidv4(),\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'trackEvent',\n 'identify',\n 'trackView',\n 'optIn',\n 'optOut',\n 'socialOptIn',\n 'socialOptOut',\n 'getAnalyticsId',\n 'isEnabled',\n 'isOptedIn',\n 'isSocialOptedIn',\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 * For migration from a previous system, pass the existing analytics ID via state.user_analyticsId.\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 const initialState = {\n ...getDefaultAnalyticsControllerState(),\n ...state,\n };\n\n super({\n name: controllerName,\n metadata: analyticsControllerMetadata,\n state: initialState,\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: computeEnabledState(this.state),\n optedIn: this.state.user_optedIn,\n socialOptedIn: this.state.user_socialOptedIn,\n analyticsId: this.state.user_analyticsId,\n });\n\n // Call onSetupCompleted lifecycle hook after initialization\n // Only call if analyticsId is set and is a valid UUIDv4 (this is the definition of \"completed\" setup)\n if (\n this.state.user_analyticsId &&\n uuidValidate(this.state.user_analyticsId) &&\n uuidVersion(this.state.user_analyticsId) === 4\n ) {\n try {\n this.#platformAdapter.onSetupCompleted(this.state.user_analyticsId);\n } catch (error) {\n // Log error but don't throw - adapter setup failure shouldn't break controller\n projectLogger('Error calling platformAdapter.onSetupCompleted', error);\n }\n } else {\n // analyticsId is undefined, null, empty string, or not a valid UUIDv4\n throw new Error(\n `Invalid analyticsId: expected a valid UUIDv4, but got ${JSON.stringify(this.state.user_analyticsId)}`,\n );\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 (!computeEnabledState(this.state)) {\n return;\n }\n\n // if event does not have properties, only send the non-anonymous empty event\n // and return to prevent any additional processing\n if (!event.hasProperties) {\n this.#platformAdapter.track(event.name, {\n anonymous: false,\n } as AnalyticsEventProperties);\n\n return;\n }\n\n // Log all non-anonymous properties, or an empty event if there's no non-anon props.\n this.#platformAdapter.track(event.name, {\n anonymous: false,\n ...event.properties,\n } as AnalyticsEventProperties);\n\n // Track all sensitive properties in an anonymous event\n if (event.isAnonymous) {\n this.#platformAdapter.track(event.name, {\n anonymous: true,\n ...event.properties,\n ...event.sensitiveProperties,\n } as AnalyticsEventProperties);\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 (!computeEnabledState(this.state)) {\n return;\n }\n\n // Delegate to platform adapter if supported, using the current analytics ID\n if (this.#platformAdapter.identify) {\n this.#platformAdapter.identify(this.state.user_analyticsId, traits);\n }\n }\n\n /**\n * Track a page view.\n *\n * @param name - The name of the UI item being viewed (pages for web, screen for mobile)\n * @param properties - UI item properties\n */\n trackView(name: string, properties?: AnalyticsEventProperties): void {\n if (!computeEnabledState(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 * This updates the user's opt-in status.\n */\n optIn(): void {\n this.update((state) => {\n state.user_optedIn = true;\n });\n }\n\n /**\n * Opt out of analytics.\n * This updates the user's opt-in status.\n */\n optOut(): void {\n this.update((state) => {\n state.user_optedIn = false;\n });\n }\n\n /**\n * Opt in to analytics through social account.\n * This updates the user's social opt-in status.\n */\n socialOptIn(): void {\n this.update((state) => {\n state.user_socialOptedIn = true;\n });\n }\n\n /**\n * Opt out of analytics through social account.\n * This updates the user's social opt-in status.\n */\n socialOptOut(): void {\n this.update((state) => {\n state.user_socialOptedIn = false;\n });\n }\n\n /**\n * Get the analytics ID from the controller state.\n *\n * @returns The current analytics ID.\n */\n getAnalyticsId(): string {\n return this.state.user_analyticsId;\n }\n\n /**\n * Get the enabled status from the controller state.\n * This is computed from user state via the state machine.\n *\n * @returns The current enabled status.\n */\n isEnabled(): boolean {\n return computeEnabledState(this.state);\n }\n\n /**\n * Get the opted in status from the controller state.\n *\n * @returns The current opted in status.\n */\n isOptedIn(): boolean {\n return this.state.user_optedIn;\n }\n\n /**\n * Get the social opted in status from the controller state.\n *\n * @returns The current social opted in status.\n */\n isSocialOptedIn(): boolean {\n return this.state.user_socialOptedIn;\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 *
|
|
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"]}
|
|
@@ -1,95 +1,39 @@
|
|
|
1
1
|
import type { Json } from "@metamask/utils";
|
|
2
|
-
/**
|
|
3
|
-
* Represents values that can be passed as properties to the event tracking function.
|
|
4
|
-
* Similar to JsonValue from Segment SDK but decoupled for platform agnosticism.
|
|
5
|
-
*/
|
|
6
|
-
type AnalyticsJsonValue = boolean | number | string | null | AnalyticsJsonValue[] | AnalyticsJsonMap | undefined;
|
|
7
|
-
/**
|
|
8
|
-
* Represents the map object used to pass properties to the event tracking function.
|
|
9
|
-
* Similar to JsonMap from Segment SDK but decoupled for platform agnosticism.
|
|
10
|
-
*/
|
|
11
|
-
type AnalyticsJsonMap = {
|
|
12
|
-
[key: string]: AnalyticsJsonValue;
|
|
13
|
-
[index: number]: AnalyticsJsonValue;
|
|
14
|
-
};
|
|
15
2
|
/**
|
|
16
3
|
* Analytics event properties
|
|
17
4
|
*/
|
|
18
5
|
export type AnalyticsEventProperties = Record<string, Json>;
|
|
19
|
-
/**
|
|
20
|
-
* User traits/properties for analytics identification
|
|
21
|
-
*/
|
|
22
|
-
export type AnalyticsUserTraits = Record<string, Json>;
|
|
23
|
-
/**
|
|
24
|
-
* Event properties structure with two distinct properties lists for anonymous and non-anonymous data.
|
|
25
|
-
* Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.
|
|
26
|
-
*/
|
|
27
|
-
export type AnalyticsTrackingEvent = {
|
|
28
|
-
readonly name: string;
|
|
29
|
-
properties: AnalyticsJsonMap;
|
|
30
|
-
sensitiveProperties: AnalyticsJsonMap;
|
|
31
|
-
saveDataRecording: boolean;
|
|
32
|
-
readonly isAnonymous: boolean;
|
|
33
|
-
readonly hasProperties: boolean;
|
|
34
|
-
};
|
|
35
6
|
/**
|
|
36
7
|
* Platform adapter interface for analytics tracking
|
|
37
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.
|
|
38
15
|
*/
|
|
39
16
|
export type AnalyticsPlatformAdapter = {
|
|
40
17
|
/**
|
|
41
|
-
* Track an analytics event
|
|
42
|
-
*
|
|
43
|
-
* This is the same as trackEvent in the old analytics system
|
|
18
|
+
* Track an analytics event
|
|
44
19
|
*
|
|
45
20
|
* @param eventName - The name of the event
|
|
46
21
|
* @param properties - Event properties
|
|
47
22
|
*/
|
|
48
|
-
|
|
23
|
+
trackEvent(eventName: string, properties: AnalyticsEventProperties): void;
|
|
49
24
|
/**
|
|
50
|
-
* Identify a user
|
|
25
|
+
* Identify a user
|
|
51
26
|
*
|
|
52
27
|
* @param userId - The user identifier (e.g., metametrics ID)
|
|
53
28
|
* @param traits - User traits/properties
|
|
54
29
|
*/
|
|
55
|
-
identify(userId: string, traits?:
|
|
30
|
+
identify?(userId: string, traits?: AnalyticsEventProperties): void;
|
|
56
31
|
/**
|
|
57
|
-
* Track a
|
|
58
|
-
*
|
|
59
|
-
* This is the same as page in Segment web SDK and screen in Segment mobile SDK.
|
|
60
|
-
* Each platform adapter should implement this method to track UI views
|
|
61
|
-
* using the appropriate method for the platform: "pages" for web, "screen" for mobile.
|
|
32
|
+
* Track a page view
|
|
62
33
|
*
|
|
63
|
-
* @param
|
|
34
|
+
* @param pageName - The name of the page
|
|
64
35
|
* @param properties - Page properties
|
|
65
36
|
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Lifecycle hook called after the AnalyticsController is fully initialized.
|
|
69
|
-
*
|
|
70
|
-
* This hook allows platform-specific adapters to perform setup that requires
|
|
71
|
-
* access to the controller's state (e.g., analyticsId).
|
|
72
|
-
*
|
|
73
|
-
* The controller calls this method once after initialization, passing the
|
|
74
|
-
* analyticsId from controller state. The analyticsId is guaranteed to be set
|
|
75
|
-
* when this method is called - this is the definition of "completed" setup.
|
|
76
|
-
*
|
|
77
|
-
* @param analyticsId - The analytics ID from controller state. Always set (never empty).
|
|
78
|
-
* @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).
|
|
79
|
-
* Errors thrown by this method are caught and logged by the controller, but do not prevent
|
|
80
|
-
* controller initialization from completing successfully.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```typescript
|
|
84
|
-
* onSetupCompleted(analyticsId: string): void {
|
|
85
|
-
* // Add platform-specific plugins that require analyticsId
|
|
86
|
-
* client.add({
|
|
87
|
-
* plugin: new PrivacyPlugin(analyticsId),
|
|
88
|
-
* });
|
|
89
|
-
* }
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
onSetupCompleted(analyticsId: string): void;
|
|
37
|
+
trackPage?(pageName: string, properties?: AnalyticsEventProperties): void;
|
|
93
38
|
};
|
|
94
|
-
export {};
|
|
95
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
|
|
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"}
|
|
@@ -1,95 +1,39 @@
|
|
|
1
1
|
import type { Json } from "@metamask/utils";
|
|
2
|
-
/**
|
|
3
|
-
* Represents values that can be passed as properties to the event tracking function.
|
|
4
|
-
* Similar to JsonValue from Segment SDK but decoupled for platform agnosticism.
|
|
5
|
-
*/
|
|
6
|
-
type AnalyticsJsonValue = boolean | number | string | null | AnalyticsJsonValue[] | AnalyticsJsonMap | undefined;
|
|
7
|
-
/**
|
|
8
|
-
* Represents the map object used to pass properties to the event tracking function.
|
|
9
|
-
* Similar to JsonMap from Segment SDK but decoupled for platform agnosticism.
|
|
10
|
-
*/
|
|
11
|
-
type AnalyticsJsonMap = {
|
|
12
|
-
[key: string]: AnalyticsJsonValue;
|
|
13
|
-
[index: number]: AnalyticsJsonValue;
|
|
14
|
-
};
|
|
15
2
|
/**
|
|
16
3
|
* Analytics event properties
|
|
17
4
|
*/
|
|
18
5
|
export type AnalyticsEventProperties = Record<string, Json>;
|
|
19
|
-
/**
|
|
20
|
-
* User traits/properties for analytics identification
|
|
21
|
-
*/
|
|
22
|
-
export type AnalyticsUserTraits = Record<string, Json>;
|
|
23
|
-
/**
|
|
24
|
-
* Event properties structure with two distinct properties lists for anonymous and non-anonymous data.
|
|
25
|
-
* Similar to ITrackingEvent from legacy analytics but decoupled for platform agnosticism.
|
|
26
|
-
*/
|
|
27
|
-
export type AnalyticsTrackingEvent = {
|
|
28
|
-
readonly name: string;
|
|
29
|
-
properties: AnalyticsJsonMap;
|
|
30
|
-
sensitiveProperties: AnalyticsJsonMap;
|
|
31
|
-
saveDataRecording: boolean;
|
|
32
|
-
readonly isAnonymous: boolean;
|
|
33
|
-
readonly hasProperties: boolean;
|
|
34
|
-
};
|
|
35
6
|
/**
|
|
36
7
|
* Platform adapter interface for analytics tracking
|
|
37
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.
|
|
38
15
|
*/
|
|
39
16
|
export type AnalyticsPlatformAdapter = {
|
|
40
17
|
/**
|
|
41
|
-
* Track an analytics event
|
|
42
|
-
*
|
|
43
|
-
* This is the same as trackEvent in the old analytics system
|
|
18
|
+
* Track an analytics event
|
|
44
19
|
*
|
|
45
20
|
* @param eventName - The name of the event
|
|
46
21
|
* @param properties - Event properties
|
|
47
22
|
*/
|
|
48
|
-
|
|
23
|
+
trackEvent(eventName: string, properties: AnalyticsEventProperties): void;
|
|
49
24
|
/**
|
|
50
|
-
* Identify a user
|
|
25
|
+
* Identify a user
|
|
51
26
|
*
|
|
52
27
|
* @param userId - The user identifier (e.g., metametrics ID)
|
|
53
28
|
* @param traits - User traits/properties
|
|
54
29
|
*/
|
|
55
|
-
identify(userId: string, traits?:
|
|
30
|
+
identify?(userId: string, traits?: AnalyticsEventProperties): void;
|
|
56
31
|
/**
|
|
57
|
-
* Track a
|
|
58
|
-
*
|
|
59
|
-
* This is the same as page in Segment web SDK and screen in Segment mobile SDK.
|
|
60
|
-
* Each platform adapter should implement this method to track UI views
|
|
61
|
-
* using the appropriate method for the platform: "pages" for web, "screen" for mobile.
|
|
32
|
+
* Track a page view
|
|
62
33
|
*
|
|
63
|
-
* @param
|
|
34
|
+
* @param pageName - The name of the page
|
|
64
35
|
* @param properties - Page properties
|
|
65
36
|
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Lifecycle hook called after the AnalyticsController is fully initialized.
|
|
69
|
-
*
|
|
70
|
-
* This hook allows platform-specific adapters to perform setup that requires
|
|
71
|
-
* access to the controller's state (e.g., analyticsId).
|
|
72
|
-
*
|
|
73
|
-
* The controller calls this method once after initialization, passing the
|
|
74
|
-
* analyticsId from controller state. The analyticsId is guaranteed to be set
|
|
75
|
-
* when this method is called - this is the definition of "completed" setup.
|
|
76
|
-
*
|
|
77
|
-
* @param analyticsId - The analytics ID from controller state. Always set (never empty).
|
|
78
|
-
* @throws {AnalyticsPlatformAdapterSetupError} May throw errors during setup (e.g., configuration errors, network failures).
|
|
79
|
-
* Errors thrown by this method are caught and logged by the controller, but do not prevent
|
|
80
|
-
* controller initialization from completing successfully.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```typescript
|
|
84
|
-
* onSetupCompleted(analyticsId: string): void {
|
|
85
|
-
* // Add platform-specific plugins that require analyticsId
|
|
86
|
-
* client.add({
|
|
87
|
-
* plugin: new PrivacyPlugin(analyticsId),
|
|
88
|
-
* });
|
|
89
|
-
* }
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
onSetupCompleted(analyticsId: string): void;
|
|
37
|
+
trackPage?(pageName: string, properties?: AnalyticsEventProperties): void;
|
|
93
38
|
};
|
|
94
|
-
export {};
|
|
95
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
|
|
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 *
|
|
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,12 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDefaultAnalyticsControllerState = exports.
|
|
3
|
+
exports.getDefaultAnalyticsControllerState = exports.AnalyticsController = void 0;
|
|
4
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
|
-
// Export errors
|
|
8
|
-
var AnalyticsPlatformAdapterSetupError_1 = require("./AnalyticsPlatformAdapterSetupError.cjs");
|
|
9
|
-
Object.defineProperty(exports, "AnalyticsPlatformAdapterSetupError", { enumerable: true, get: function () { return AnalyticsPlatformAdapterSetupError_1.AnalyticsPlatformAdapterSetupError; } });
|
|
10
7
|
var AnalyticsController_2 = require("./AnalyticsController.cjs");
|
|
11
8
|
Object.defineProperty(exports, "getDefaultAnalyticsControllerState", { enumerable: true, get: function () { return AnalyticsController_2.getDefaultAnalyticsControllerState; } });
|
|
12
9
|
//# sourceMappingURL=index.cjs.map
|