@levo-so/insights 0.1.65 → 0.1.76
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/dist/DA6yh6E3HQLu.js +857 -0
- package/dist/constants/storageKeys.d.ts +22 -0
- package/dist/index.d.ts +4 -305
- package/dist/index.js +582 -859
- package/dist/legacy/index.d.ts +71 -0
- package/dist/lib/analytics.d.ts +10 -0
- package/dist/lib/insights.d.ts +24 -0
- package/dist/stores/config.d.ts +11 -0
- package/dist/stores/events.d.ts +45 -0
- package/dist/stores/session.d.ts +21 -0
- package/dist/stores.d.ts +8 -0
- package/dist/stores.js +14 -0
- package/dist/tracking/activity.d.ts +21 -0
- package/dist/tracking/bounce.d.ts +24 -0
- package/dist/tracking/clicks.d.ts +9 -0
- package/dist/tracking/clipboard.d.ts +8 -0
- package/dist/tracking/currentTab.d.ts +16 -0
- package/dist/tracking/forms.d.ts +8 -0
- package/dist/tracking/page.d.ts +8 -0
- package/dist/tracking/scrollBehavior.d.ts +21 -0
- package/dist/tracking/textSelection.d.ts +13 -0
- package/dist/types/analytics.d.ts +4 -0
- package/dist/types/identity.d.ts +12 -0
- package/dist/types/options.d.ts +14 -0
- package/dist/utils/autocapture.d.ts +22 -0
- package/dist/utils/checkLocalStorage.d.ts +4 -0
- package/dist/utils/createPlugin.d.ts +66 -0
- package/dist/utils/detectMode.d.ts +10 -0
- package/dist/utils/getAuthHeaders.d.ts +9 -0
- package/dist/utils/getReferrer.d.ts +24 -0
- package/dist/utils/getUserProperties.d.ts +7 -0
- package/dist/utils/isIncognito.d.ts +8 -0
- package/dist/utils/lock.d.ts +20 -0
- package/dist/utils/pingEndpoint.d.ts +4 -0
- package/dist/utils/rageclick.d.ts +20 -0
- package/package.json +14 -8
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage keys used by the insights module.
|
|
3
|
+
* These are the same keys used in createLevoInsights.
|
|
4
|
+
*/
|
|
5
|
+
export declare const STORAGE_KEYS: {
|
|
6
|
+
/** Legacy: Lock key for identify operation (no longer used internally) */
|
|
7
|
+
readonly identify: "lock:lv_aud_identify";
|
|
8
|
+
/** Key for tracking open tab count */
|
|
9
|
+
readonly open_tabs: "lv_insights_ot";
|
|
10
|
+
/** Key for current tab ID (sessionStorage) */
|
|
11
|
+
readonly current_tab: "lv_insights_ct";
|
|
12
|
+
/** Key for all tabs registry */
|
|
13
|
+
readonly all_tabs: "lv_insights_at";
|
|
14
|
+
/** Device JWT for direct mode (1yr expiry, rotated on /welcome, analytics-only scope) */
|
|
15
|
+
readonly device_token: "lv_aud_device";
|
|
16
|
+
/** Session JWT for direct mode (1yr expiry, rotated on /welcome, analytics-only scope) */
|
|
17
|
+
readonly session_token: "lv_aud_session";
|
|
18
|
+
/** Cached insights mode ('proxy' | 'direct') */
|
|
19
|
+
readonly mode: "lv_aud_mode";
|
|
20
|
+
/** Key to store session data **/
|
|
21
|
+
readonly session: "lv_insights_session";
|
|
22
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,305 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type AnalyticsEventType = (typeof AnalyticsEventsList)[number];
|
|
6
|
-
declare const AnalyticsEvents: {
|
|
7
|
-
"bevy.collection.filled": "bevy.collection.filled";
|
|
8
|
-
"bevy.collection.submitted": "bevy.collection.submitted";
|
|
9
|
-
"bevy.collection.view": "bevy.collection.view";
|
|
10
|
-
"block.view": "block.view";
|
|
11
|
-
"blog.post.view": "blog.post.view";
|
|
12
|
-
"event.booking.confirmed": "event.booking.confirmed";
|
|
13
|
-
"event.booking.initiated": "event.booking.initiated";
|
|
14
|
-
"event.booking.pending": "event.booking.pending";
|
|
15
|
-
"event.coupon.applied": "event.coupon.applied";
|
|
16
|
-
"event.event.view": "event.event.view";
|
|
17
|
-
"form.change": "form.change";
|
|
18
|
-
"form.submit": "form.submit";
|
|
19
|
-
"membership.account.signin": "membership.account.signin";
|
|
20
|
-
"membership.account.signout": "membership.account.signout";
|
|
21
|
-
"membership.account.signup": "membership.account.signup";
|
|
22
|
-
"button.click": "button.click";
|
|
23
|
-
"page.bounce": "page.bounce";
|
|
24
|
-
"page.click": "page.click";
|
|
25
|
-
"page.copy": "page.copy";
|
|
26
|
-
"page.impression": "page.impression";
|
|
27
|
-
"page.scroll": "page.scroll";
|
|
28
|
-
"page.view": "page.view";
|
|
29
|
-
"page.selection": "page.selection";
|
|
30
|
-
"user.active": "user.active";
|
|
31
|
-
"user.idle": "user.idle";
|
|
32
|
-
};
|
|
33
|
-
declare namespace ILevoAudience {
|
|
34
|
-
interface Traits {
|
|
35
|
-
private_mode: boolean;
|
|
36
|
-
dark_mode: boolean;
|
|
37
|
-
locale: string;
|
|
38
|
-
timezone: string;
|
|
39
|
-
referrer: {
|
|
40
|
-
type: string;
|
|
41
|
-
referrer: Record<string, string>;
|
|
42
|
-
data: Record<string, string>;
|
|
43
|
-
};
|
|
44
|
-
properties: Record<string, any>;
|
|
45
|
-
withLock?: boolean;
|
|
46
|
-
}
|
|
47
|
-
type BaseProperties = Traits & {
|
|
48
|
-
resource: string;
|
|
49
|
-
identifier: string;
|
|
50
|
-
};
|
|
51
|
-
interface BlockProperties {
|
|
52
|
-
id: string;
|
|
53
|
-
}
|
|
54
|
-
interface ActivityProperties {
|
|
55
|
-
seconds_idle?: number;
|
|
56
|
-
seconds_active?: number;
|
|
57
|
-
}
|
|
58
|
-
interface ScrollProperties {
|
|
59
|
-
percent: number;
|
|
60
|
-
}
|
|
61
|
-
type Properties = Partial<BaseProperties & BlockProperties & ActivityProperties & ScrollProperties> & Partial<Omit<BaseInput, "workspace_id" | "tab_count" | "tab_id">> & Record<string, any>;
|
|
62
|
-
type EventProperties = {
|
|
63
|
-
properties: Properties;
|
|
64
|
-
traits: Traits;
|
|
65
|
-
event: AnalyticsEventType;
|
|
66
|
-
type: "track" | "page" | "identify";
|
|
67
|
-
userId: string | null;
|
|
68
|
-
};
|
|
69
|
-
type BaseInput = {
|
|
70
|
-
workspace_id: string;
|
|
71
|
-
site_id?: string;
|
|
72
|
-
hostname: string;
|
|
73
|
-
pathname: string;
|
|
74
|
-
page_title: string;
|
|
75
|
-
url: string;
|
|
76
|
-
created_at: string;
|
|
77
|
-
tab_id: string;
|
|
78
|
-
tab_count: number;
|
|
79
|
-
};
|
|
80
|
-
type WelcomeInput = Traits & BaseInput;
|
|
81
|
-
type WelcomeResponse = {
|
|
82
|
-
session: string;
|
|
83
|
-
device: string;
|
|
84
|
-
};
|
|
85
|
-
type CollectInput = BaseInput & {
|
|
86
|
-
session_id?: string;
|
|
87
|
-
device_id?: string;
|
|
88
|
-
event: AnalyticsEventType;
|
|
89
|
-
version?: number;
|
|
90
|
-
properties: Properties;
|
|
91
|
-
resource: string;
|
|
92
|
-
identifier: string | undefined;
|
|
93
|
-
};
|
|
94
|
-
type ActivityStatus = {
|
|
95
|
-
isIdle: boolean;
|
|
96
|
-
isDisabled: boolean;
|
|
97
|
-
active: number;
|
|
98
|
-
idle: number;
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
interface IInsightOptions {
|
|
103
|
-
/** Site ID for analytics tracking */
|
|
104
|
-
site?: string | null;
|
|
105
|
-
insightsUrl?: string;
|
|
106
|
-
/** Direct insights API URL for third-party mode (when reverse proxy unavailable) */
|
|
107
|
-
directInsightsUrl?: string;
|
|
108
|
-
/** Insights mode: 'auto' (default) detects via ping, 'proxy' forces reverse proxy, 'direct' forces direct API */
|
|
109
|
-
insightsMode?: "auto" | "proxy" | "direct";
|
|
110
|
-
/** Timeout for proxy ping detection in ms (default: 3000) */
|
|
111
|
-
pingTimeout?: number;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @fileoverview Levo Audience Analytics Module
|
|
116
|
-
*
|
|
117
|
-
* This module provides client-side analytics tracking for Levo-powered websites.
|
|
118
|
-
* It handles event collection, batching, cross-tab synchronization, and reliable
|
|
119
|
-
* delivery of analytics data to the Levo Insights API.
|
|
120
|
-
*
|
|
121
|
-
* ## Architecture Overview
|
|
122
|
-
*
|
|
123
|
-
* ```
|
|
124
|
-
* ┌────────────────────────────────────────────────────────────────────────┐
|
|
125
|
-
* │ Browser Tab │
|
|
126
|
-
* │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
|
|
127
|
-
* │ │ track() │───▶│ EventQueue │───▶│ /v1/insights/event/bulk │ │
|
|
128
|
-
* │ │ page() │ │ (batching) │ │ (sendBeacon / fetch) │ │
|
|
129
|
-
* │ │ identify() │ └──────────────┘ └──────────────────────────┘ │
|
|
130
|
-
* │ └──────────────┘ │ │
|
|
131
|
-
* │ │ │ flush on: │
|
|
132
|
-
* │ │ │ - 50 events (BATCH_SIZE) │
|
|
133
|
-
* │ │ │ - 5s interval (BATCH_INTERVAL_MS) │
|
|
134
|
-
* │ │ │ - page exit (visibilitychange) │
|
|
135
|
-
* │ │ │ - beforeunload / pagehide │
|
|
136
|
-
* │ ▼ │ │
|
|
137
|
-
* │ ┌──────────────┐ │ │
|
|
138
|
-
* │ │ Rate Limiter │───────────┘ │
|
|
139
|
-
* │ │ (500/page) │ │
|
|
140
|
-
* │ └──────────────┘ │
|
|
141
|
-
* └────────────────────────────────────────────────────────────────────────┘
|
|
142
|
-
* │
|
|
143
|
-
* │ BroadcastChannel
|
|
144
|
-
* │ (SESSION_SYNC, SESSION_REQUEST)
|
|
145
|
-
* ▼
|
|
146
|
-
* ┌────────────────────────────────────────────────────────────────────────┐
|
|
147
|
-
* │ Other Browser Tabs │
|
|
148
|
-
* │ - Receive session/device IDs from first tab │
|
|
149
|
-
* │ - Skip /welcome API call if session already established │
|
|
150
|
-
* └────────────────────────────────────────────────────────────────────────┘
|
|
151
|
-
* ```
|
|
152
|
-
*
|
|
153
|
-
* ## Key Features
|
|
154
|
-
*
|
|
155
|
-
* ### 1. Event Batching
|
|
156
|
-
* Instead of sending each event immediately (which caused 100+ requests per page),
|
|
157
|
-
* events are queued and sent in batches. This reduces:
|
|
158
|
-
* - Network requests by 50-100x
|
|
159
|
-
* - Server load
|
|
160
|
-
* - Bandwidth usage
|
|
161
|
-
*
|
|
162
|
-
* ### 2. Cross-Tab Session Synchronization
|
|
163
|
-
* Uses BroadcastChannel API to share session/device IDs across tabs:
|
|
164
|
-
* - First tab to complete /welcome broadcasts session to others
|
|
165
|
-
* - Other tabs skip /welcome API call, reducing duplicate sessions
|
|
166
|
-
* - Solves "Open in New Tab" race condition where multiple tabs would
|
|
167
|
-
* each create separate sessions
|
|
168
|
-
*
|
|
169
|
-
* ### 3. Reliable Page Exit Handling
|
|
170
|
-
* Uses multiple mechanisms to ensure events are sent before page unload:
|
|
171
|
-
* - visibilitychange (most reliable, fires when tab hidden)
|
|
172
|
-
* - beforeunload (backup for navigation)
|
|
173
|
-
* - pagehide (backup for bfcache scenarios)
|
|
174
|
-
* - sendBeacon API (survives page unload)
|
|
175
|
-
*
|
|
176
|
-
* ### 4. Rate Limiting
|
|
177
|
-
* Prevents runaway loops or malicious spam:
|
|
178
|
-
* - Max 500 events per page
|
|
179
|
-
* - Counter resets on page navigation
|
|
180
|
-
*
|
|
181
|
-
* ## Session Flow
|
|
182
|
-
*
|
|
183
|
-
* ```
|
|
184
|
-
* Page Load
|
|
185
|
-
* │
|
|
186
|
-
* ▼
|
|
187
|
-
* initiate() called
|
|
188
|
-
* │
|
|
189
|
-
* ├── Initialize BroadcastChannel
|
|
190
|
-
* │
|
|
191
|
-
* ├── Request session from other tabs (SESSION_REQUEST)
|
|
192
|
-
* │
|
|
193
|
-
* ├── Wait 50ms for response
|
|
194
|
-
* │ │
|
|
195
|
-
* │ ├── If SESSION_SYNC received: Use shared session, skip /welcome
|
|
196
|
-
* │ │
|
|
197
|
-
* │ └── If no response: Call /welcome API
|
|
198
|
-
* │ │
|
|
199
|
-
* │ └── On success: Broadcast SESSION_SYNC to other tabs
|
|
200
|
-
* │
|
|
201
|
-
* └── Start tracking events
|
|
202
|
-
* ```
|
|
203
|
-
*
|
|
204
|
-
* ## API Endpoints Used
|
|
205
|
-
*
|
|
206
|
-
* - `POST /v1/insights/event/welcome` - Initial session establishment
|
|
207
|
-
* - Called once per session (first tab only, thanks to BroadcastChannel)
|
|
208
|
-
* - Returns session_id and device_id from HttpOnly cookies
|
|
209
|
-
*
|
|
210
|
-
* - `POST /v1/insights/event/bulk` - Batch event submission
|
|
211
|
-
* - Receives array of CollectInput events
|
|
212
|
-
* - Used for all event tracking (replaces individual /collect calls)
|
|
213
|
-
*
|
|
214
|
-
* ## Configuration Constants
|
|
215
|
-
*
|
|
216
|
-
* - BATCH_SIZE (50): Flush queue when this many events accumulated
|
|
217
|
-
* - BATCH_INTERVAL_MS (5000): Flush queue every 5 seconds regardless of size
|
|
218
|
-
* - MAX_EVENTS_PER_PAGE (500): Rate limit per page to prevent abuse
|
|
219
|
-
* - BROADCAST_CHANNEL_NAME ("levo_analytics"): Channel for cross-tab sync
|
|
220
|
-
*
|
|
221
|
-
* ## Browser Compatibility
|
|
222
|
-
*
|
|
223
|
-
* - BroadcastChannel: Modern browsers (Chrome 54+, Firefox 38+, Safari 15.4+)
|
|
224
|
-
* - Gracefully degrades: If unavailable, each tab calls /welcome independently
|
|
225
|
-
*
|
|
226
|
-
* - sendBeacon: Universal support (Chrome 39+, Firefox 31+, Safari 11.1+)
|
|
227
|
-
* - Fallback: fetch() with keepalive option
|
|
228
|
-
*
|
|
229
|
-
* @module @levo-so/core/control/audience
|
|
230
|
-
*/
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Creates the Levo Audience analytics module.
|
|
234
|
-
*
|
|
235
|
-
* This factory function creates a new audience module instance tied to
|
|
236
|
-
* a specific Levo control instance and HTTP client. The module manages
|
|
237
|
-
* all analytics tracking for the page.
|
|
238
|
-
*
|
|
239
|
-
* @param core - The Levo control instance containing workspace config
|
|
240
|
-
* @param httpClient - HTTP client for making API requests
|
|
241
|
-
* @returns The audience module with tracking methods
|
|
242
|
-
*
|
|
243
|
-
* @example
|
|
244
|
-
* ```typescript
|
|
245
|
-
* const audience = createLevoAudienceModule(levoControl, httpClient);
|
|
246
|
-
*
|
|
247
|
-
* // Initialize on page load
|
|
248
|
-
* await audience.initiate({ id: 'page-123' });
|
|
249
|
-
*
|
|
250
|
-
* // Track custom events
|
|
251
|
-
* audience.track('button.click', { buttonId: 'cta-signup' });
|
|
252
|
-
*
|
|
253
|
-
* // Cleanup on unmount (optional, for SPAs)
|
|
254
|
-
* audience.destroy();
|
|
255
|
-
* ```
|
|
256
|
-
*/
|
|
257
|
-
declare const createLevoInsights: (client: ILevoClient, options?: IInsightOptions) => {
|
|
258
|
-
readonly insightsUrl: string;
|
|
259
|
-
/** Get the underlying analytics instance (read-only) */
|
|
260
|
-
readonly instance: AnalyticsInstance | null;
|
|
261
|
-
/** Check if session has been established (read-only) */
|
|
262
|
-
readonly is_identified: boolean;
|
|
263
|
-
/** Storage keys used by the module */
|
|
264
|
-
storage_keys: {
|
|
265
|
-
/** Legacy: Lock key for identify operation (no longer used internally) */
|
|
266
|
-
identify: string;
|
|
267
|
-
/** Key for tracking open tab count */
|
|
268
|
-
open_tabs: string;
|
|
269
|
-
/** Key for current tab ID (sessionStorage) */
|
|
270
|
-
current_tab: string;
|
|
271
|
-
/** Key for all tabs registry */
|
|
272
|
-
all_tabs: string;
|
|
273
|
-
/** Device JWT for direct mode (1yr expiry, rotated on /welcome, analytics-only scope) */
|
|
274
|
-
device_token: string;
|
|
275
|
-
/** Session JWT for direct mode (1yr expiry, rotated on /welcome, analytics-only scope) */
|
|
276
|
-
session_token: string;
|
|
277
|
-
/** Cached insights mode ('proxy' | 'direct') */
|
|
278
|
-
mode: string;
|
|
279
|
-
};
|
|
280
|
-
/** Initialize the module for a page */
|
|
281
|
-
initiate: (properties: ILevoAudience.Properties) => Promise<any>;
|
|
282
|
-
/** Identify/establish session */
|
|
283
|
-
identify: (options?: {
|
|
284
|
-
withLock?: boolean;
|
|
285
|
-
}) => Promise<void>;
|
|
286
|
-
/** Track a custom event */
|
|
287
|
-
track: <T extends ILevoAudience.Properties>(event: AnalyticsEventType, properties: T & ILevoAudience.Properties) => Promise<any>;
|
|
288
|
-
/** Track a bounce event */
|
|
289
|
-
bounce: (properties: ILevoAudience.Properties) => Promise<void>;
|
|
290
|
-
/** Cleanup the module */
|
|
291
|
-
destroy: () => void;
|
|
292
|
-
};
|
|
293
|
-
/**
|
|
294
|
-
* Type representing the audience module instance.
|
|
295
|
-
* Use this when you need to type a variable holding the module.
|
|
296
|
-
*
|
|
297
|
-
* @example
|
|
298
|
-
* ```typescript
|
|
299
|
-
* let audience: ILevoAudienceModule;
|
|
300
|
-
* audience = createLevoAudienceModule(core, httpClient);
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
type ILevoInsights = ReturnType<typeof createLevoInsights>;
|
|
304
|
-
|
|
305
|
-
export { type AnalyticsEventType, AnalyticsEvents, AnalyticsEventsList, type IInsightOptions, ILevoAudience, type ILevoInsights, createLevoInsights };
|
|
1
|
+
export * from './lib/insights';
|
|
2
|
+
export * from './types/analytics';
|
|
3
|
+
export * from './types/identity';
|
|
4
|
+
export * from './types/options';
|