@od-oneapp/analytics 2026.1.1301
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 +509 -0
- package/dist/ai-YMnynb-t.mjs +3347 -0
- package/dist/ai-YMnynb-t.mjs.map +1 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/client-CTzJVFU5.mjs +9 -0
- package/dist/client-CTzJVFU5.mjs.map +1 -0
- package/dist/client-CcFTauAh.mjs +54 -0
- package/dist/client-CcFTauAh.mjs.map +1 -0
- package/dist/client-CeOLjbac.mjs +281 -0
- package/dist/client-CeOLjbac.mjs.map +1 -0
- package/dist/client-D339NFJS.mjs +267 -0
- package/dist/client-D339NFJS.mjs.map +1 -0
- package/dist/client-next.d.mts +62 -0
- package/dist/client-next.d.mts.map +1 -0
- package/dist/client-next.mjs +525 -0
- package/dist/client-next.mjs.map +1 -0
- package/dist/client.d.mts +30 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +186 -0
- package/dist/client.mjs.map +1 -0
- package/dist/config-DPS6bSYo.d.mts +34 -0
- package/dist/config-DPS6bSYo.d.mts.map +1 -0
- package/dist/config-P6P5adJg.mjs +287 -0
- package/dist/config-P6P5adJg.mjs.map +1 -0
- package/dist/console-8bND3mMU.mjs +128 -0
- package/dist/console-8bND3mMU.mjs.map +1 -0
- package/dist/ecommerce-Cgu4wlux.mjs +993 -0
- package/dist/ecommerce-Cgu4wlux.mjs.map +1 -0
- package/dist/emitters-6-nKo8i-.mjs +208 -0
- package/dist/emitters-6-nKo8i-.mjs.map +1 -0
- package/dist/emitters-DldkVSPp.d.mts +12 -0
- package/dist/emitters-DldkVSPp.d.mts.map +1 -0
- package/dist/index-BfNWgfa5.d.mts +1494 -0
- package/dist/index-BfNWgfa5.d.mts.map +1 -0
- package/dist/index-BkIWe--N.d.mts +953 -0
- package/dist/index-BkIWe--N.d.mts.map +1 -0
- package/dist/index-jPzXRn52.d.mts +184 -0
- package/dist/index-jPzXRn52.d.mts.map +1 -0
- package/dist/manager-DvRRjza6.d.mts +76 -0
- package/dist/manager-DvRRjza6.d.mts.map +1 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs +1769 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts +81 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts.map +1 -0
- package/dist/providers-http-client.d.mts +37 -0
- package/dist/providers-http-client.d.mts.map +1 -0
- package/dist/providers-http-client.mjs +320 -0
- package/dist/providers-http-client.mjs.map +1 -0
- package/dist/providers-http-server.d.mts +31 -0
- package/dist/providers-http-server.d.mts.map +1 -0
- package/dist/providers-http-server.mjs +297 -0
- package/dist/providers-http-server.mjs.map +1 -0
- package/dist/providers-http.d.mts +46 -0
- package/dist/providers-http.d.mts.map +1 -0
- package/dist/providers-http.mjs +4 -0
- package/dist/server-edge.d.mts +9 -0
- package/dist/server-edge.d.mts.map +1 -0
- package/dist/server-edge.mjs +373 -0
- package/dist/server-edge.mjs.map +1 -0
- package/dist/server-next.d.mts +67 -0
- package/dist/server-next.d.mts.map +1 -0
- package/dist/server-next.mjs +193 -0
- package/dist/server-next.mjs.map +1 -0
- package/dist/server.d.mts +10 -0
- package/dist/server.mjs +7 -0
- package/dist/service-cYtBBL8x.mjs +945 -0
- package/dist/service-cYtBBL8x.mjs.map +1 -0
- package/dist/shared.d.mts +16 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +93 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types-BxBnNQ0V.d.mts +354 -0
- package/dist/types-BxBnNQ0V.d.mts.map +1 -0
- package/dist/types-CBvxUEaF.d.mts +216 -0
- package/dist/types-CBvxUEaF.d.mts.map +1 -0
- package/dist/types.d.mts +4 -0
- package/dist/types.mjs +0 -0
- package/dist/vercel-types-lwakUfoI.d.mts +102 -0
- package/dist/vercel-types-lwakUfoI.d.mts.map +1 -0
- package/package.json +129 -0
- package/src/client/index.ts +164 -0
- package/src/client/manager.ts +71 -0
- package/src/client/next/components.tsx +270 -0
- package/src/client/next/hooks.ts +217 -0
- package/src/client/next/manager.ts +141 -0
- package/src/client/next.ts +144 -0
- package/src/client-next.ts +101 -0
- package/src/client.ts +89 -0
- package/src/examples/ai-sdk-patterns.ts +583 -0
- package/src/examples/emitter-patterns.ts +476 -0
- package/src/examples/nextjs-emitter-patterns.tsx +403 -0
- package/src/next/app-router.tsx +564 -0
- package/src/next/client.ts +419 -0
- package/src/next/index.ts +84 -0
- package/src/next/middleware.ts +429 -0
- package/src/next/rsc.tsx +300 -0
- package/src/next/server.ts +253 -0
- package/src/next/types.d.ts +220 -0
- package/src/providers/base-provider.ts +419 -0
- package/src/providers/console/client.ts +10 -0
- package/src/providers/console/index.ts +152 -0
- package/src/providers/console/server.ts +6 -0
- package/src/providers/console/types.ts +15 -0
- package/src/providers/http/client.ts +464 -0
- package/src/providers/http/index.ts +30 -0
- package/src/providers/http/server.ts +396 -0
- package/src/providers/http/types.ts +135 -0
- package/src/providers/posthog/client.ts +518 -0
- package/src/providers/posthog/index.ts +11 -0
- package/src/providers/posthog/server.ts +329 -0
- package/src/providers/posthog/types.ts +104 -0
- package/src/providers/segment/client.ts +113 -0
- package/src/providers/segment/index.ts +11 -0
- package/src/providers/segment/server.ts +115 -0
- package/src/providers/segment/types.ts +51 -0
- package/src/providers/vercel/client.ts +102 -0
- package/src/providers/vercel/index.ts +11 -0
- package/src/providers/vercel/server.ts +89 -0
- package/src/providers/vercel/types.ts +27 -0
- package/src/server/index.ts +103 -0
- package/src/server/manager.ts +62 -0
- package/src/server/next.ts +210 -0
- package/src/server-edge.ts +442 -0
- package/src/server-next.ts +39 -0
- package/src/server.ts +106 -0
- package/src/shared/emitters/ai/README.md +981 -0
- package/src/shared/emitters/ai/events/agent.ts +130 -0
- package/src/shared/emitters/ai/events/artifacts.ts +167 -0
- package/src/shared/emitters/ai/events/chat.ts +126 -0
- package/src/shared/emitters/ai/events/chatbot-ecommerce.ts +133 -0
- package/src/shared/emitters/ai/events/completion.ts +103 -0
- package/src/shared/emitters/ai/events/content-generation.ts +347 -0
- package/src/shared/emitters/ai/events/conversation.ts +332 -0
- package/src/shared/emitters/ai/events/product-features.ts +1402 -0
- package/src/shared/emitters/ai/events/streaming.ts +114 -0
- package/src/shared/emitters/ai/events/tool.ts +93 -0
- package/src/shared/emitters/ai/index.ts +69 -0
- package/src/shared/emitters/ai/track-ai-sdk.ts +74 -0
- package/src/shared/emitters/ai/track-ai.ts +50 -0
- package/src/shared/emitters/ai/types.ts +1041 -0
- package/src/shared/emitters/ai/utils.ts +468 -0
- package/src/shared/emitters/ecommerce/events/cart-checkout.ts +106 -0
- package/src/shared/emitters/ecommerce/events/coupon.ts +49 -0
- package/src/shared/emitters/ecommerce/events/engagement.ts +61 -0
- package/src/shared/emitters/ecommerce/events/marketplace.ts +119 -0
- package/src/shared/emitters/ecommerce/events/order.ts +199 -0
- package/src/shared/emitters/ecommerce/events/product.ts +205 -0
- package/src/shared/emitters/ecommerce/events/registry.ts +123 -0
- package/src/shared/emitters/ecommerce/events/wishlist-sharing.ts +140 -0
- package/src/shared/emitters/ecommerce/index.ts +46 -0
- package/src/shared/emitters/ecommerce/track-ecommerce.ts +53 -0
- package/src/shared/emitters/ecommerce/types.ts +314 -0
- package/src/shared/emitters/ecommerce/utils.ts +216 -0
- package/src/shared/emitters/emitter-types.ts +974 -0
- package/src/shared/emitters/emitters.ts +292 -0
- package/src/shared/emitters/helpers.ts +419 -0
- package/src/shared/emitters/index.ts +66 -0
- package/src/shared/index.ts +142 -0
- package/src/shared/ingestion/index.ts +66 -0
- package/src/shared/ingestion/schemas.ts +386 -0
- package/src/shared/ingestion/service.ts +628 -0
- package/src/shared/node22-features.ts +848 -0
- package/src/shared/providers/console-provider.ts +160 -0
- package/src/shared/types/base-types.ts +54 -0
- package/src/shared/types/console-types.ts +19 -0
- package/src/shared/types/posthog-types.ts +131 -0
- package/src/shared/types/segment-types.ts +15 -0
- package/src/shared/types/types.ts +397 -0
- package/src/shared/types/vercel-types.ts +19 -0
- package/src/shared/utils/config-client.ts +19 -0
- package/src/shared/utils/config.ts +250 -0
- package/src/shared/utils/emitter-adapter.ts +212 -0
- package/src/shared/utils/manager.test.ts +36 -0
- package/src/shared/utils/manager.ts +1322 -0
- package/src/shared/utils/posthog-bootstrap.ts +136 -0
- package/src/shared/utils/posthog-client-utils.ts +48 -0
- package/src/shared/utils/posthog-next-utils.ts +282 -0
- package/src/shared/utils/posthog-server-utils.ts +210 -0
- package/src/shared/utils/rate-limit.ts +289 -0
- package/src/shared/utils/security.ts +545 -0
- package/src/shared/utils/validation-client.ts +161 -0
- package/src/shared/utils/validation.ts +399 -0
- package/src/shared.ts +155 -0
- package/src/types/index.ts +62 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Emitter Usage Patterns - Examples and Best Practices
|
|
3
|
+
* Emitter Usage Patterns - Examples and Best Practices
|
|
4
|
+
*
|
|
5
|
+
* This file demonstrates various patterns for using the emitter-first
|
|
6
|
+
* approach in the analytics package.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { logError, logInfo } from '@repo/shared/logger';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
type AnalyticsManager,
|
|
13
|
+
ContextBuilder,
|
|
14
|
+
createAnonymousSession,
|
|
15
|
+
createClientAnalytics,
|
|
16
|
+
createUserSession,
|
|
17
|
+
ecommerce,
|
|
18
|
+
EventBatch,
|
|
19
|
+
identify,
|
|
20
|
+
page,
|
|
21
|
+
PayloadBuilder,
|
|
22
|
+
track,
|
|
23
|
+
withMetadata,
|
|
24
|
+
withUTM,
|
|
25
|
+
} from '../client';
|
|
26
|
+
|
|
27
|
+
// ====================================
|
|
28
|
+
// BASIC EMITTER USAGE
|
|
29
|
+
// ====================================
|
|
30
|
+
|
|
31
|
+
async function basicEmitterUsage(analytics: AnalyticsManager) {
|
|
32
|
+
// 1. Direct emit method (RECOMMENDED)
|
|
33
|
+
await analytics.emit(
|
|
34
|
+
track('Button Clicked', {
|
|
35
|
+
button_id: 'cta-hero',
|
|
36
|
+
text: 'Get Started',
|
|
37
|
+
variant: 'primary',
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// 2. Using overloaded methods
|
|
42
|
+
await analytics.track(
|
|
43
|
+
track('Form Submitted', {
|
|
44
|
+
form_id: 'contact',
|
|
45
|
+
fields_filled: 5,
|
|
46
|
+
time_to_complete: 45000,
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// 3. Batch multiple events
|
|
51
|
+
await analytics.emitBatch([
|
|
52
|
+
identify('user_123', { email: 'user@example.com' }),
|
|
53
|
+
track('Signup Completed', { method: 'email' }),
|
|
54
|
+
page(undefined, 'Welcome', { first_visit: true }),
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ====================================
|
|
59
|
+
// CONTEXT MANAGEMENT
|
|
60
|
+
// ====================================
|
|
61
|
+
|
|
62
|
+
async function contextManagement(analytics: AnalyticsManager) {
|
|
63
|
+
// Build rich context for all events
|
|
64
|
+
const context = new ContextBuilder()
|
|
65
|
+
.setUser('user_123', {
|
|
66
|
+
created_at: '2024-01-15',
|
|
67
|
+
email: 'user@example.com',
|
|
68
|
+
plan: 'premium',
|
|
69
|
+
})
|
|
70
|
+
.setOrganization('org_456')
|
|
71
|
+
.setPage({
|
|
72
|
+
path: '/dashboard',
|
|
73
|
+
referrer: 'https://google.com',
|
|
74
|
+
title: 'Analytics Dashboard',
|
|
75
|
+
})
|
|
76
|
+
.setCampaign({
|
|
77
|
+
campaign: 'summer-sale',
|
|
78
|
+
content: 'banner-a',
|
|
79
|
+
medium: 'cpc',
|
|
80
|
+
source: 'google',
|
|
81
|
+
})
|
|
82
|
+
.setDevice({
|
|
83
|
+
type: 'desktop',
|
|
84
|
+
browser: 'chrome',
|
|
85
|
+
os: 'macos',
|
|
86
|
+
})
|
|
87
|
+
.build();
|
|
88
|
+
|
|
89
|
+
// Use context with PayloadBuilder
|
|
90
|
+
const builder = new PayloadBuilder(context);
|
|
91
|
+
|
|
92
|
+
await analytics.emit(
|
|
93
|
+
builder.track('Dashboard Viewed', {
|
|
94
|
+
widgets_count: 5,
|
|
95
|
+
time_range: '30d',
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
await analytics.emit(
|
|
100
|
+
builder.track('Export Generated', {
|
|
101
|
+
format: 'csv',
|
|
102
|
+
rows: 1500,
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ====================================
|
|
108
|
+
// USER SESSION TRACKING
|
|
109
|
+
// ====================================
|
|
110
|
+
|
|
111
|
+
async function sessionTracking(analytics: AnalyticsManager) {
|
|
112
|
+
// Create a session for authenticated user
|
|
113
|
+
const session = createUserSession('user_123', 'session_abc123');
|
|
114
|
+
|
|
115
|
+
// All events in this session will have consistent context
|
|
116
|
+
await analytics.emit(
|
|
117
|
+
session.identify({
|
|
118
|
+
name: 'John Doe',
|
|
119
|
+
company: 'Acme Corp',
|
|
120
|
+
email: 'john@example.com',
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await analytics.emit(
|
|
125
|
+
session.track('Feature Used', {
|
|
126
|
+
feature_name: 'advanced-search',
|
|
127
|
+
query_length: 25,
|
|
128
|
+
results_count: 142,
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
await analytics.emit(
|
|
133
|
+
session.page('Search Results', {
|
|
134
|
+
filters_applied: ['price', 'rating'],
|
|
135
|
+
query: 'analytics tools',
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
await analytics.emit(
|
|
140
|
+
session.group('org_456', {
|
|
141
|
+
name: 'Acme Corp',
|
|
142
|
+
plan: 'enterprise',
|
|
143
|
+
seats: 50,
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ====================================
|
|
149
|
+
// ANONYMOUS USER TRACKING
|
|
150
|
+
// ====================================
|
|
151
|
+
|
|
152
|
+
async function anonymousTracking(analytics: AnalyticsManager) {
|
|
153
|
+
// Track anonymous user behavior
|
|
154
|
+
const anonSession = createAnonymousSession('anon_789xyz');
|
|
155
|
+
|
|
156
|
+
// Track browsing behavior
|
|
157
|
+
await analytics.emit(
|
|
158
|
+
anonSession.track('Product Viewed', {
|
|
159
|
+
product_id: 'EXAMPLE-123',
|
|
160
|
+
category: 'Electronics',
|
|
161
|
+
price: 99.99,
|
|
162
|
+
}),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
await analytics.emit(
|
|
166
|
+
anonSession.page('Product Detail', {
|
|
167
|
+
product_id: 'EXAMPLE-123',
|
|
168
|
+
}),
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// When user signs up, alias and identify
|
|
172
|
+
const userId = 'user_123';
|
|
173
|
+
|
|
174
|
+
await analytics.emit(anonSession.alias(userId));
|
|
175
|
+
|
|
176
|
+
await analytics.emit(
|
|
177
|
+
anonSession.identify(userId, {
|
|
178
|
+
email: 'newuser@example.com',
|
|
179
|
+
source: 'organic',
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ====================================
|
|
185
|
+
// ECOMMERCE TRACKING
|
|
186
|
+
// ====================================
|
|
187
|
+
|
|
188
|
+
async function ecommerceTracking(analytics: AnalyticsManager) {
|
|
189
|
+
// Product browsing
|
|
190
|
+
await analytics.emit(
|
|
191
|
+
ecommerce.productViewed({
|
|
192
|
+
product_id: 'EXAMPLE-123',
|
|
193
|
+
name: 'Wireless Headphones',
|
|
194
|
+
image_url: 'https://shop.com/images/headphones-black.jpg',
|
|
195
|
+
url: 'https://shop.com/products/wireless-headphones',
|
|
196
|
+
brand: 'AudioTech',
|
|
197
|
+
category: 'Electronics/Audio',
|
|
198
|
+
position: 1,
|
|
199
|
+
price: 129.99,
|
|
200
|
+
variant: 'Black',
|
|
201
|
+
}),
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Add to cart
|
|
205
|
+
await analytics.emit(
|
|
206
|
+
ecommerce.cartUpdated({
|
|
207
|
+
action: 'added',
|
|
208
|
+
cart_total: 129.99,
|
|
209
|
+
product: {
|
|
210
|
+
product_id: 'EXAMPLE-123',
|
|
211
|
+
name: 'Wireless Headphones',
|
|
212
|
+
category: 'Electronics/Audio',
|
|
213
|
+
price: 129.99,
|
|
214
|
+
quantity: 1,
|
|
215
|
+
},
|
|
216
|
+
}),
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
// Checkout flow
|
|
220
|
+
const checkoutBatch = new EventBatch();
|
|
221
|
+
|
|
222
|
+
checkoutBatch
|
|
223
|
+
.addTrack('Checkout Step Viewed', {
|
|
224
|
+
step_name: 'shipping_info',
|
|
225
|
+
shipping_method: 'standard',
|
|
226
|
+
step: 1,
|
|
227
|
+
})
|
|
228
|
+
.addTrack('Checkout Step Viewed', {
|
|
229
|
+
step_name: 'payment_info',
|
|
230
|
+
payment_method: 'credit_card',
|
|
231
|
+
step: 2,
|
|
232
|
+
})
|
|
233
|
+
.addTrack('Order Completed', {
|
|
234
|
+
order_id: 'ORD-12345',
|
|
235
|
+
coupon: '',
|
|
236
|
+
currency: 'USD',
|
|
237
|
+
discount: 0,
|
|
238
|
+
products: [
|
|
239
|
+
{
|
|
240
|
+
product_id: 'EXAMPLE-123',
|
|
241
|
+
name: 'Wireless Headphones',
|
|
242
|
+
brand: 'AudioTech',
|
|
243
|
+
category: 'Electronics/Audio',
|
|
244
|
+
price: 129.99,
|
|
245
|
+
quantity: 1,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
revenue: 129.99,
|
|
249
|
+
shipping: 0,
|
|
250
|
+
tax: 12.49,
|
|
251
|
+
total: 142.48,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await analytics.emitBatch(checkoutBatch.getEvents());
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ====================================
|
|
258
|
+
// METADATA AND ENRICHMENT
|
|
259
|
+
// ====================================
|
|
260
|
+
|
|
261
|
+
async function metadataEnrichment(analytics: AnalyticsManager) {
|
|
262
|
+
// Base event
|
|
263
|
+
const event = track('Feature Launched', {
|
|
264
|
+
feature: 'ai-assistant',
|
|
265
|
+
trigger: 'keyboard-shortcut',
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Add application metadata
|
|
269
|
+
const enrichedEvent = withMetadata(event, {
|
|
270
|
+
experiment_id: 'exp_123',
|
|
271
|
+
build: 'production',
|
|
272
|
+
source: 'web-app',
|
|
273
|
+
version: '2.1.0',
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Add UTM parameters
|
|
277
|
+
const campaignEvent = withUTM(enrichedEvent, {
|
|
278
|
+
campaign: 'feature-announcement',
|
|
279
|
+
content: 'variant-a',
|
|
280
|
+
medium: 'newsletter',
|
|
281
|
+
source: 'email',
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
await analytics.emit(campaignEvent);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ====================================
|
|
288
|
+
// FORM TRACKING PATTERN
|
|
289
|
+
// ====================================
|
|
290
|
+
|
|
291
|
+
async function formTracking(analytics: AnalyticsManager) {
|
|
292
|
+
const formId = 'signup-form';
|
|
293
|
+
const formSession = new EventBatch();
|
|
294
|
+
|
|
295
|
+
// Track form interactions
|
|
296
|
+
formSession
|
|
297
|
+
.addTrack('Form Viewed', {
|
|
298
|
+
form_id: formId,
|
|
299
|
+
fields_count: 5,
|
|
300
|
+
})
|
|
301
|
+
.addTrack('Form Started', {
|
|
302
|
+
form_id: formId,
|
|
303
|
+
first_field: 'email',
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Track field completions
|
|
307
|
+
const fields = ['email', 'password', 'company', 'role', 'phone'];
|
|
308
|
+
fields.forEach((field, index) => {
|
|
309
|
+
formSession.addTrack('Form Field Completed', {
|
|
310
|
+
form_id: formId,
|
|
311
|
+
field_name: field,
|
|
312
|
+
field_index: index,
|
|
313
|
+
time_to_complete: Math.random() * 5000,
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Track form submission
|
|
318
|
+
formSession.addTrack('Form Submitted', {
|
|
319
|
+
form_id: formId,
|
|
320
|
+
validation_errors: 0,
|
|
321
|
+
total_time: 45000,
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
await analytics.emitBatch(formSession.getEvents());
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ====================================
|
|
328
|
+
// ERROR TRACKING PATTERN
|
|
329
|
+
// ====================================
|
|
330
|
+
|
|
331
|
+
async function errorTracking(analytics: AnalyticsManager) {
|
|
332
|
+
try {
|
|
333
|
+
// Some operation that might fail
|
|
334
|
+
throw new Error('Network timeout');
|
|
335
|
+
} catch (error) {
|
|
336
|
+
await analytics.emit(
|
|
337
|
+
track('Error Occurred', {
|
|
338
|
+
error_type: 'network',
|
|
339
|
+
component: 'data-fetcher',
|
|
340
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
341
|
+
error_stack: error instanceof Error ? error.stack : undefined,
|
|
342
|
+
recovery_action: 'retry',
|
|
343
|
+
severity: 'high',
|
|
344
|
+
user_impact: 'data-not-loaded',
|
|
345
|
+
}),
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ====================================
|
|
351
|
+
// A/B TEST TRACKING
|
|
352
|
+
// ====================================
|
|
353
|
+
|
|
354
|
+
async function abTestTracking(analytics: AnalyticsManager) {
|
|
355
|
+
const experiments = {
|
|
356
|
+
'cta-color': 'green',
|
|
357
|
+
'homepage-hero': 'variant-b',
|
|
358
|
+
'pricing-layout': 'cards',
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// Track experiment exposure
|
|
362
|
+
for (const [experiment, variant] of Object.entries(experiments)) {
|
|
363
|
+
await analytics.emit(
|
|
364
|
+
track('Experiment Viewed', {
|
|
365
|
+
experiment_id: experiment,
|
|
366
|
+
variant_id: variant,
|
|
367
|
+
timestamp: new Date().toISOString(),
|
|
368
|
+
}),
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Track conversion with experiment context
|
|
373
|
+
const conversionEvent = track('Trial Started', {
|
|
374
|
+
billing_cycle: 'monthly',
|
|
375
|
+
plan: 'premium',
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const enrichedConversion = withMetadata(conversionEvent, {
|
|
379
|
+
experiments,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
await analytics.emit(enrichedConversion);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ====================================
|
|
386
|
+
// FUNNEL TRACKING
|
|
387
|
+
// ====================================
|
|
388
|
+
|
|
389
|
+
async function funnelTracking(analytics: AnalyticsManager) {
|
|
390
|
+
const funnelId = 'onboarding';
|
|
391
|
+
const userId = 'user_123';
|
|
392
|
+
|
|
393
|
+
// Create a context for the entire funnel
|
|
394
|
+
const funnelContext = new ContextBuilder().setUser(userId).build();
|
|
395
|
+
|
|
396
|
+
const funnelBuilder = new PayloadBuilder(funnelContext);
|
|
397
|
+
|
|
398
|
+
// Track funnel steps
|
|
399
|
+
const steps = [
|
|
400
|
+
{ name: 'Signup Started', properties: { method: 'email' } },
|
|
401
|
+
{ name: 'Email Verified', properties: { time_to_verify: 120000 } },
|
|
402
|
+
{ name: 'Profile Created', properties: { fields_filled: 7 } },
|
|
403
|
+
{ name: 'Team Invited', properties: { invites_sent: 3 } },
|
|
404
|
+
{ name: 'First Project Created', properties: { template_used: 'blank' } },
|
|
405
|
+
{ name: 'Onboarding Completed', properties: { total_time: 600000 } },
|
|
406
|
+
];
|
|
407
|
+
|
|
408
|
+
for (const [index, step] of steps.entries()) {
|
|
409
|
+
await analytics.emit(
|
|
410
|
+
funnelBuilder.track(step.name, {
|
|
411
|
+
...step.properties,
|
|
412
|
+
funnel_id: funnelId,
|
|
413
|
+
funnel_step_name: step.name.toLowerCase().replaceAll(/\s+/g, '_'),
|
|
414
|
+
funnel_step: index + 1,
|
|
415
|
+
}),
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ====================================
|
|
421
|
+
// MAIN EXAMPLE RUNNER
|
|
422
|
+
// ====================================
|
|
423
|
+
|
|
424
|
+
export async function runAllExamples() {
|
|
425
|
+
// Initialize analytics
|
|
426
|
+
const analytics = await createClientAnalytics({
|
|
427
|
+
providers: {
|
|
428
|
+
console: { options: { prefix: '[Example]' } },
|
|
429
|
+
// Add other providers as needed
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
logInfo('🚀 Running Emitter Pattern Examples...');
|
|
434
|
+
|
|
435
|
+
// Run all examples
|
|
436
|
+
await basicEmitterUsage(analytics);
|
|
437
|
+
logInfo('✅ Basic emitter usage complete');
|
|
438
|
+
|
|
439
|
+
await contextManagement(analytics);
|
|
440
|
+
logInfo('✅ Context management complete');
|
|
441
|
+
|
|
442
|
+
await sessionTracking(analytics);
|
|
443
|
+
logInfo('✅ Session tracking complete');
|
|
444
|
+
|
|
445
|
+
await anonymousTracking(analytics);
|
|
446
|
+
logInfo('✅ Anonymous tracking complete');
|
|
447
|
+
|
|
448
|
+
await ecommerceTracking(analytics);
|
|
449
|
+
logInfo('✅ Ecommerce tracking complete');
|
|
450
|
+
|
|
451
|
+
await metadataEnrichment(analytics);
|
|
452
|
+
logInfo('✅ Metadata enrichment complete');
|
|
453
|
+
|
|
454
|
+
await formTracking(analytics);
|
|
455
|
+
logInfo('✅ Form tracking complete');
|
|
456
|
+
|
|
457
|
+
await errorTracking(analytics);
|
|
458
|
+
logInfo('✅ Error tracking complete');
|
|
459
|
+
|
|
460
|
+
await abTestTracking(analytics);
|
|
461
|
+
logInfo('✅ A/B test tracking complete');
|
|
462
|
+
|
|
463
|
+
await funnelTracking(analytics);
|
|
464
|
+
logInfo('✅ Funnel tracking complete');
|
|
465
|
+
|
|
466
|
+
logInfo('🎉 All examples completed successfully!');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Run examples if this file is executed directly
|
|
470
|
+
if (require.main === module) {
|
|
471
|
+
// Intentionally not awaited - fire and forget
|
|
472
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
|
473
|
+
runAllExamples().catch(error => {
|
|
474
|
+
logError('Error running examples', { error });
|
|
475
|
+
});
|
|
476
|
+
}
|