@molecule/app-analytics 1.0.3 → 1.1.0
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 +84 -6
- package/dist/auto-tracking.d.ts +110 -14
- package/dist/auto-tracking.d.ts.map +1 -1
- package/dist/auto-tracking.js +55 -62
- package/dist/auto-tracking.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-10-
|
|
6
|
+
Generated: 2026-10-24T04:18:36.696Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-analytics
|
|
@@ -47,15 +47,60 @@ npm install @molecule/app-analytics @molecule/app-bond
|
|
|
47
47
|
|
|
48
48
|
### Interfaces
|
|
49
49
|
|
|
50
|
+
#### `AnalyticsAuthUser`
|
|
51
|
+
|
|
52
|
+
The default auth profile: an immutable `id` plus the traits analytics records.
|
|
53
|
+
|
|
54
|
+
An app whose auth client carries its OWN profile (no `id`) still auto-tracks
|
|
55
|
+
auth events — it passes `identifyUser` to say which field identifies the user
|
|
56
|
+
(see {@link AutoTrackingOptions}).
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
interface AnalyticsAuthUser {
|
|
60
|
+
/** Unique user identifier. */
|
|
61
|
+
id: string
|
|
62
|
+
/** User email address. */
|
|
63
|
+
email?: string
|
|
64
|
+
/** User display name. */
|
|
65
|
+
name?: string
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
50
69
|
#### `AutoTrackingOptions`
|
|
51
70
|
|
|
52
|
-
Auto-tracking
|
|
53
|
-
sources are tracked. Works for both web and mobile
|
|
71
|
+
Auto-tracking sources and the identity adapter. Pass any combination of
|
|
72
|
+
sources — only provided sources are tracked. Works for both web and mobile
|
|
73
|
+
apps.
|
|
74
|
+
|
|
75
|
+
`TUser` is the profile the auth client hands to its listeners. The default,
|
|
76
|
+
{@link AnalyticsAuthUser}, has an `id`, and it is identified by that field
|
|
77
|
+
with no extra wiring. An app whose profile has no `id` (e.g.
|
|
78
|
+
`{ username, email, bio }`) passes an `identifyUser` extractor; it is
|
|
79
|
+
REQUIRED for such a profile, so a client cannot be wired into tracking with
|
|
80
|
+
no identity at all and `userId: undefined` never reaches a provider. That
|
|
81
|
+
requirement is applied by {@link setupAutoTracking}'s parameter (see
|
|
82
|
+
{@link IdentityRequirement}), not by this interface, so the options bag stays
|
|
83
|
+
declaration-mergeable:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
declare module '@molecule/app-analytics' {
|
|
87
|
+
interface AutoTrackingOptions {
|
|
88
|
+
label?: string
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
54
92
|
|
|
55
93
|
```typescript
|
|
56
|
-
interface AutoTrackingOptions {
|
|
94
|
+
interface AutoTrackingOptions<TUser extends object = AnalyticsAuthUser> {
|
|
57
95
|
/** Auth client for login/logout/register/error events. */
|
|
58
|
-
authClient?: AuthClientLike
|
|
96
|
+
authClient?: AuthClientLike<TUser>
|
|
97
|
+
/**
|
|
98
|
+
* Which field of the profile identifies the user in analytics — required when
|
|
99
|
+
* the profile has no `id: string`. The default reads `id`, `email` and `name`.
|
|
100
|
+
* Return `null` when the session has no stable identity: the sign-in is still
|
|
101
|
+
* tracked, without an `identify` call or a `userId`.
|
|
102
|
+
*/
|
|
103
|
+
identifyUser?: IdentifyUser<TUser>
|
|
59
104
|
/** Router for page view tracking. */
|
|
60
105
|
router?: RouterLike
|
|
61
106
|
/** HTTP client for error tracking. */
|
|
@@ -185,6 +230,33 @@ interface AnalyticsProvider {
|
|
|
185
230
|
}
|
|
186
231
|
```
|
|
187
232
|
|
|
233
|
+
### Types
|
|
234
|
+
|
|
235
|
+
#### `IdentifyUser`
|
|
236
|
+
|
|
237
|
+
Maps a signed-in profile to the identity analytics records for it.
|
|
238
|
+
|
|
239
|
+
Return `null` when this session has no stable identity to record (an
|
|
240
|
+
anonymous or throwaway session): the sign-in is then tracked without an
|
|
241
|
+
`identify` call instead of sending an undefined `userId`.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
type IdentifyUser<TUser> = (user: TUser) => AnalyticsUserProps | null
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### `IdentityRequirement`
|
|
248
|
+
|
|
249
|
+
The identity rule for one profile: a profile with `id: string` may omit
|
|
250
|
+
`identifyUser`, a profile without one must pass it. Applied to
|
|
251
|
+
{@link setupAutoTracking}'s parameter so {@link AutoTrackingOptions} stays an
|
|
252
|
+
interface that apps can augment.
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
type IdentityRequirement<TUser extends object> = [TUser] extends [{ id: string }]
|
|
256
|
+
? { identifyUser?: IdentifyUser<TUser> }
|
|
257
|
+
: { identifyUser: IdentifyUser<TUser> }
|
|
258
|
+
```
|
|
259
|
+
|
|
188
260
|
### Functions
|
|
189
261
|
|
|
190
262
|
#### `setupAutoTracking(options)`
|
|
@@ -199,8 +271,14 @@ The analytics provider is resolved at EVENT time, not at setup time — so
|
|
|
199
271
|
`setupAutoTracking()` may safely run before the analytics bond is set
|
|
200
272
|
(events fired before bonding no-op; events fired after are tracked).
|
|
201
273
|
|
|
274
|
+
The default-profile call takes an inline `getClient()`: it is typed as the
|
|
275
|
+
default {@link AnalyticsAuthUser}, so `identifyUser` stays optional exactly
|
|
276
|
+
as before. An app whose client carries its own profile names that profile —
|
|
277
|
+
either on the auth client and an `identifyUser` extractor, or as the setup's
|
|
278
|
+
type argument — and a profile with no `id: string` must pass `identifyUser`.
|
|
279
|
+
|
|
202
280
|
```typescript
|
|
203
|
-
function setupAutoTracking(options: AutoTrackingOptions): () => void
|
|
281
|
+
function setupAutoTracking(options: AutoTrackingOptions<AnalyticsAuthUser>): () => void
|
|
204
282
|
```
|
|
205
283
|
|
|
206
284
|
- `options` — Sources to auto-track.
|
package/dist/auto-tracking.d.ts
CHANGED
|
@@ -7,23 +7,46 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
+
import type { AnalyticsUserProps } from './types.js';
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* The default auth profile: an immutable `id` plus the traits analytics records.
|
|
13
|
+
*
|
|
14
|
+
* An app whose auth client carries its OWN profile (no `id`) still auto-tracks
|
|
15
|
+
* auth events — it passes `identifyUser` to say which field identifies the user
|
|
16
|
+
* (see {@link AutoTrackingOptions}).
|
|
17
|
+
*/
|
|
18
|
+
export interface AnalyticsAuthUser {
|
|
19
|
+
/** Unique user identifier. */
|
|
20
|
+
id: string;
|
|
21
|
+
/** User email address. */
|
|
22
|
+
email?: string;
|
|
23
|
+
/** User display name. */
|
|
24
|
+
name?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Maps a signed-in profile to the identity analytics records for it.
|
|
28
|
+
*
|
|
29
|
+
* Return `null` when this session has no stable identity to record (an
|
|
30
|
+
* anonymous or throwaway session): the sign-in is then tracked without an
|
|
31
|
+
* `identify` call instead of sending an undefined `userId`.
|
|
32
|
+
*
|
|
33
|
+
* @template TUser - The app's own profile shape.
|
|
34
|
+
*/
|
|
35
|
+
export type IdentifyUser<TUser> = (user: TUser) => AnalyticsUserProps | null;
|
|
36
|
+
/**
|
|
37
|
+
* Minimal auth event shape (mirrors `@molecule/app-auth` AuthEvent), typed by
|
|
38
|
+
* the app's profile.
|
|
12
39
|
*/
|
|
13
|
-
interface
|
|
40
|
+
interface AuthEventLike<TUser> {
|
|
14
41
|
type: 'login' | 'logout' | 'register' | 'refresh' | 'error';
|
|
15
|
-
user?:
|
|
16
|
-
id: string;
|
|
17
|
-
email?: string;
|
|
18
|
-
name?: string;
|
|
19
|
-
};
|
|
42
|
+
user?: TUser;
|
|
20
43
|
error?: string;
|
|
21
44
|
}
|
|
22
45
|
/**
|
|
23
46
|
* Minimal auth client interface for auto-tracking.
|
|
24
47
|
*/
|
|
25
|
-
interface AuthClientLike {
|
|
26
|
-
addEventListener(listener: (event:
|
|
48
|
+
interface AuthClientLike<TUser> {
|
|
49
|
+
addEventListener(listener: (event: AuthEventLike<TUser>) => void): () => void;
|
|
27
50
|
}
|
|
28
51
|
/**
|
|
29
52
|
* Minimal route location shape (mirrors `@molecule/app-routing` RouteLocation).
|
|
@@ -100,12 +123,40 @@ interface PushClientLike {
|
|
|
100
123
|
onNotificationAction(listener: (event: NotificationActionEventLike) => void): () => void;
|
|
101
124
|
}
|
|
102
125
|
/**
|
|
103
|
-
* Auto-tracking
|
|
104
|
-
* sources are tracked. Works for both web and mobile
|
|
126
|
+
* Auto-tracking sources and the identity adapter. Pass any combination of
|
|
127
|
+
* sources — only provided sources are tracked. Works for both web and mobile
|
|
128
|
+
* apps.
|
|
129
|
+
*
|
|
130
|
+
* `TUser` is the profile the auth client hands to its listeners. The default,
|
|
131
|
+
* {@link AnalyticsAuthUser}, has an `id`, and it is identified by that field
|
|
132
|
+
* with no extra wiring. An app whose profile has no `id` (e.g.
|
|
133
|
+
* `{ username, email, bio }`) passes an `identifyUser` extractor; it is
|
|
134
|
+
* REQUIRED for such a profile, so a client cannot be wired into tracking with
|
|
135
|
+
* no identity at all and `userId: undefined` never reaches a provider. That
|
|
136
|
+
* requirement is applied by {@link setupAutoTracking}'s parameter (see
|
|
137
|
+
* {@link IdentityRequirement}), not by this interface, so the options bag stays
|
|
138
|
+
* declaration-mergeable:
|
|
139
|
+
*
|
|
140
|
+
* ```typescript
|
|
141
|
+
* declare module '@molecule/app-analytics' {
|
|
142
|
+
* interface AutoTrackingOptions {
|
|
143
|
+
* label?: string
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @template TUser - The auth client's profile shape.
|
|
105
149
|
*/
|
|
106
|
-
export interface AutoTrackingOptions {
|
|
150
|
+
export interface AutoTrackingOptions<TUser extends object = AnalyticsAuthUser> {
|
|
107
151
|
/** Auth client for login/logout/register/error events. */
|
|
108
|
-
authClient?: AuthClientLike
|
|
152
|
+
authClient?: AuthClientLike<TUser>;
|
|
153
|
+
/**
|
|
154
|
+
* Which field of the profile identifies the user in analytics — required when
|
|
155
|
+
* the profile has no `id: string`. The default reads `id`, `email` and `name`.
|
|
156
|
+
* Return `null` when the session has no stable identity: the sign-in is still
|
|
157
|
+
* tracked, without an `identify` call or a `userId`.
|
|
158
|
+
*/
|
|
159
|
+
identifyUser?: IdentifyUser<TUser>;
|
|
109
160
|
/** Router for page view tracking. */
|
|
110
161
|
router?: RouterLike;
|
|
111
162
|
/** HTTP client for error tracking. */
|
|
@@ -115,6 +166,21 @@ export interface AutoTrackingOptions {
|
|
|
115
166
|
/** Push client for notification received/tapped tracking. */
|
|
116
167
|
pushClient?: PushClientLike;
|
|
117
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* The identity rule for one profile: a profile with `id: string` may omit
|
|
171
|
+
* `identifyUser`, a profile without one must pass it. Applied to
|
|
172
|
+
* {@link setupAutoTracking}'s parameter so {@link AutoTrackingOptions} stays an
|
|
173
|
+
* interface that apps can augment.
|
|
174
|
+
*
|
|
175
|
+
* @template TUser - The auth client's profile shape.
|
|
176
|
+
*/
|
|
177
|
+
export type IdentityRequirement<TUser extends object> = [TUser] extends [{
|
|
178
|
+
id: string;
|
|
179
|
+
}] ? {
|
|
180
|
+
identifyUser?: IdentifyUser<TUser>;
|
|
181
|
+
} : {
|
|
182
|
+
identifyUser: IdentifyUser<TUser>;
|
|
183
|
+
};
|
|
118
184
|
/**
|
|
119
185
|
* Sets up automatic analytics tracking for auth events, route changes,
|
|
120
186
|
* HTTP errors, app lifecycle transitions, push notifications, and deep links.
|
|
@@ -126,6 +192,12 @@ export interface AutoTrackingOptions {
|
|
|
126
192
|
* `setupAutoTracking()` may safely run before the analytics bond is set
|
|
127
193
|
* (events fired before bonding no-op; events fired after are tracked).
|
|
128
194
|
*
|
|
195
|
+
* The default-profile call takes an inline `getClient()`: it is typed as the
|
|
196
|
+
* default {@link AnalyticsAuthUser}, so `identifyUser` stays optional exactly
|
|
197
|
+
* as before. An app whose client carries its own profile names that profile —
|
|
198
|
+
* either on the auth client and an `identifyUser` extractor, or as the setup's
|
|
199
|
+
* type argument — and a profile with no `id: string` must pass `identifyUser`.
|
|
200
|
+
*
|
|
129
201
|
* @example
|
|
130
202
|
* ```typescript
|
|
131
203
|
* // Web app
|
|
@@ -135,6 +207,12 @@ export interface AutoTrackingOptions {
|
|
|
135
207
|
* httpClient: getHttp(),
|
|
136
208
|
* })
|
|
137
209
|
*
|
|
210
|
+
* // An app whose profile has no `id` says which field identifies the user:
|
|
211
|
+
* const cleanup = setupAutoTracking({
|
|
212
|
+
* authClient: authClient, // createJWTAuthClient<SessionUser>(…)
|
|
213
|
+
* identifyUser: (user) => ({ userId: user.username, email: user.email }),
|
|
214
|
+
* })
|
|
215
|
+
*
|
|
138
216
|
* // Mobile app (React Native) — add lifecycle and push
|
|
139
217
|
* const cleanup = setupAutoTracking({
|
|
140
218
|
* authClient: getClient(),
|
|
@@ -151,6 +229,24 @@ export interface AutoTrackingOptions {
|
|
|
151
229
|
* @param options - Sources to auto-track.
|
|
152
230
|
* @returns A cleanup function that removes all event subscriptions.
|
|
153
231
|
*/
|
|
154
|
-
export declare
|
|
232
|
+
export declare function setupAutoTracking(options: AutoTrackingOptions<AnalyticsAuthUser>): () => void;
|
|
233
|
+
/**
|
|
234
|
+
* Sets up automatic analytics tracking for an app whose auth client carries its
|
|
235
|
+
* own profile. `identifyUser` is required when that profile has no `id: string`.
|
|
236
|
+
*
|
|
237
|
+
* @template TUser - The auth client's profile shape.
|
|
238
|
+
* @param options - Sources to auto-track.
|
|
239
|
+
* @returns A cleanup function that removes all event subscriptions.
|
|
240
|
+
*/
|
|
241
|
+
export declare function setupAutoTracking<TUser extends object>(options: AutoTrackingOptions<TUser> & IdentityRequirement<TUser>): () => void;
|
|
242
|
+
/**
|
|
243
|
+
* Keeps derived options (`Parameters<typeof setupAutoTracking>[0]`) on the default profile.
|
|
244
|
+
* The first default overload also supplies contextual typing for nested untyped client calls;
|
|
245
|
+
* the custom-profile overload between them requires an identity extractor where needed.
|
|
246
|
+
*
|
|
247
|
+
* @param options - Sources to auto-track with the default profile.
|
|
248
|
+
* @returns A cleanup function that removes all event subscriptions.
|
|
249
|
+
*/
|
|
250
|
+
export declare function setupAutoTracking(options: AutoTrackingOptions<AnalyticsAuthUser>): () => void;
|
|
155
251
|
export {};
|
|
156
252
|
//# sourceMappingURL=auto-tracking.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-tracking.d.ts","sourceRoot":"","sources":["../src/auto-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"auto-tracking.d.ts","sourceRoot":"","sources":["../src/auto-tracking.ts"],"names":[],"mappings":"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"}
|
package/dist/auto-tracking.js
CHANGED
|
@@ -8,79 +8,72 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { getProvider } from './provider.js';
|
|
11
|
-
|
|
12
|
-
* Sets up automatic analytics tracking for auth events, route changes,
|
|
13
|
-
* HTTP errors, app lifecycle transitions, push notifications, and deep links.
|
|
14
|
-
* Returns a cleanup function that removes all subscriptions.
|
|
15
|
-
*
|
|
16
|
-
* Pass any combination of sources — only provided sources are tracked.
|
|
17
|
-
*
|
|
18
|
-
* The analytics provider is resolved at EVENT time, not at setup time — so
|
|
19
|
-
* `setupAutoTracking()` may safely run before the analytics bond is set
|
|
20
|
-
* (events fired before bonding no-op; events fired after are tracked).
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* // Web app
|
|
25
|
-
* const cleanup = setupAutoTracking({
|
|
26
|
-
* authClient: getClient(),
|
|
27
|
-
* router: getRouter(),
|
|
28
|
-
* httpClient: getHttp(),
|
|
29
|
-
* })
|
|
30
|
-
*
|
|
31
|
-
* // Mobile app (React Native) — add lifecycle and push
|
|
32
|
-
* const cleanup = setupAutoTracking({
|
|
33
|
-
* authClient: getClient(),
|
|
34
|
-
* router: getRouter(),
|
|
35
|
-
* httpClient: getHttp(),
|
|
36
|
-
* lifecycleClient: getLifecycleProvider(),
|
|
37
|
-
* pushClient: getPushProvider(),
|
|
38
|
-
* })
|
|
39
|
-
*
|
|
40
|
-
* // Later, to remove all listeners:
|
|
41
|
-
* cleanup()
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @param options - Sources to auto-track.
|
|
45
|
-
* @returns A cleanup function that removes all event subscriptions.
|
|
46
|
-
*/
|
|
47
|
-
export const setupAutoTracking = (options) => {
|
|
11
|
+
export function setupAutoTracking(options) {
|
|
48
12
|
const cleanups = [];
|
|
49
13
|
// Resolve the provider per event — capturing getProvider() once at setup
|
|
50
14
|
// permanently baked in the no-op provider whenever setupAutoTracking() ran
|
|
51
15
|
// before the analytics bond was set, silently dropping every event forever.
|
|
52
16
|
const analytics = () => getProvider();
|
|
17
|
+
/**
|
|
18
|
+
* The identity to record for a profile: the app's own extractor when given,
|
|
19
|
+
* otherwise the default `id`/`email`/`name` fields. `null` means this session
|
|
20
|
+
* has no identity to record — no `identify`, and no `userId` on the event.
|
|
21
|
+
*
|
|
22
|
+
* @param user - The profile a sign-in event carried.
|
|
23
|
+
* @returns The identity, or `null` when none can be read.
|
|
24
|
+
*/
|
|
25
|
+
const identityOf = (user) => {
|
|
26
|
+
if (options.identifyUser)
|
|
27
|
+
return options.identifyUser(user);
|
|
28
|
+
if (!('id' in user) || typeof user.id !== 'string' || user.id === '')
|
|
29
|
+
return null;
|
|
30
|
+
const identity = { userId: user.id };
|
|
31
|
+
if ('email' in user && typeof user.email === 'string')
|
|
32
|
+
identity.email = user.email;
|
|
33
|
+
if ('name' in user && typeof user.name === 'string')
|
|
34
|
+
identity.name = user.name;
|
|
35
|
+
return identity;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Identifies the signed-in user and tracks the sign-in event.
|
|
39
|
+
*
|
|
40
|
+
* When there is no identity ({@link IdentifyUser} returned `null`, or the
|
|
41
|
+
* profile carries no readable `id`), the `identify` call is skipped and the
|
|
42
|
+
* sign-in is STILL tracked — without a `userId` — so `auth.login` and
|
|
43
|
+
* `auth.register` counts are not silently lost for anonymous sessions.
|
|
44
|
+
*
|
|
45
|
+
* @param name - `auth.login` or `auth.register`.
|
|
46
|
+
* @param user - The profile the event carried.
|
|
47
|
+
*/
|
|
48
|
+
const trackSignIn = (name, user) => {
|
|
49
|
+
if (!user)
|
|
50
|
+
return;
|
|
51
|
+
const identity = identityOf(user);
|
|
52
|
+
if (identity) {
|
|
53
|
+
analytics()
|
|
54
|
+
.identify(identity)
|
|
55
|
+
.catch(() => { });
|
|
56
|
+
analytics()
|
|
57
|
+
.track({ name, properties: { userId: identity.userId } })
|
|
58
|
+
.catch(() => { });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// No identity means the app said this session has none (or the profile has
|
|
62
|
+
// no id and no extractor reached this client): never send `userId:
|
|
63
|
+
// undefined`, but do not drop the sign-in event either.
|
|
64
|
+
analytics()
|
|
65
|
+
.track({ name })
|
|
66
|
+
.catch(() => { });
|
|
67
|
+
};
|
|
53
68
|
// Auth events
|
|
54
69
|
if (options.authClient) {
|
|
55
70
|
const removeListener = options.authClient.addEventListener((event) => {
|
|
56
71
|
switch (event.type) {
|
|
57
72
|
case 'login':
|
|
58
|
-
|
|
59
|
-
analytics()
|
|
60
|
-
.identify({
|
|
61
|
-
userId: event.user.id,
|
|
62
|
-
email: event.user.email,
|
|
63
|
-
name: event.user.name,
|
|
64
|
-
})
|
|
65
|
-
.catch(() => { });
|
|
66
|
-
analytics()
|
|
67
|
-
.track({ name: 'auth.login', properties: { userId: event.user.id } })
|
|
68
|
-
.catch(() => { });
|
|
69
|
-
}
|
|
73
|
+
trackSignIn('auth.login', event.user);
|
|
70
74
|
break;
|
|
71
75
|
case 'register':
|
|
72
|
-
|
|
73
|
-
analytics()
|
|
74
|
-
.identify({
|
|
75
|
-
userId: event.user.id,
|
|
76
|
-
email: event.user.email,
|
|
77
|
-
name: event.user.name,
|
|
78
|
-
})
|
|
79
|
-
.catch(() => { });
|
|
80
|
-
analytics()
|
|
81
|
-
.track({ name: 'auth.register', properties: { userId: event.user.id } })
|
|
82
|
-
.catch(() => { });
|
|
83
|
-
}
|
|
76
|
+
trackSignIn('auth.register', event.user);
|
|
84
77
|
break;
|
|
85
78
|
case 'logout':
|
|
86
79
|
analytics()
|
|
@@ -192,5 +185,5 @@ export const setupAutoTracking = (options) => {
|
|
|
192
185
|
return () => {
|
|
193
186
|
cleanups.forEach((fn) => fn());
|
|
194
187
|
};
|
|
195
|
-
}
|
|
188
|
+
}
|
|
196
189
|
//# sourceMappingURL=auto-tracking.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-tracking.js","sourceRoot":"","sources":["../src/auto-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"auto-tracking.js","sourceRoot":"","sources":["../src/auto-tracking.ts"],"names":[],"mappings":"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"}
|