@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.
Files changed (184) hide show
  1. package/README.md +509 -0
  2. package/dist/ai-YMnynb-t.mjs +3347 -0
  3. package/dist/ai-YMnynb-t.mjs.map +1 -0
  4. package/dist/chunk-DQk6qfdC.mjs +18 -0
  5. package/dist/client-CTzJVFU5.mjs +9 -0
  6. package/dist/client-CTzJVFU5.mjs.map +1 -0
  7. package/dist/client-CcFTauAh.mjs +54 -0
  8. package/dist/client-CcFTauAh.mjs.map +1 -0
  9. package/dist/client-CeOLjbac.mjs +281 -0
  10. package/dist/client-CeOLjbac.mjs.map +1 -0
  11. package/dist/client-D339NFJS.mjs +267 -0
  12. package/dist/client-D339NFJS.mjs.map +1 -0
  13. package/dist/client-next.d.mts +62 -0
  14. package/dist/client-next.d.mts.map +1 -0
  15. package/dist/client-next.mjs +525 -0
  16. package/dist/client-next.mjs.map +1 -0
  17. package/dist/client.d.mts +30 -0
  18. package/dist/client.d.mts.map +1 -0
  19. package/dist/client.mjs +186 -0
  20. package/dist/client.mjs.map +1 -0
  21. package/dist/config-DPS6bSYo.d.mts +34 -0
  22. package/dist/config-DPS6bSYo.d.mts.map +1 -0
  23. package/dist/config-P6P5adJg.mjs +287 -0
  24. package/dist/config-P6P5adJg.mjs.map +1 -0
  25. package/dist/console-8bND3mMU.mjs +128 -0
  26. package/dist/console-8bND3mMU.mjs.map +1 -0
  27. package/dist/ecommerce-Cgu4wlux.mjs +993 -0
  28. package/dist/ecommerce-Cgu4wlux.mjs.map +1 -0
  29. package/dist/emitters-6-nKo8i-.mjs +208 -0
  30. package/dist/emitters-6-nKo8i-.mjs.map +1 -0
  31. package/dist/emitters-DldkVSPp.d.mts +12 -0
  32. package/dist/emitters-DldkVSPp.d.mts.map +1 -0
  33. package/dist/index-BfNWgfa5.d.mts +1494 -0
  34. package/dist/index-BfNWgfa5.d.mts.map +1 -0
  35. package/dist/index-BkIWe--N.d.mts +953 -0
  36. package/dist/index-BkIWe--N.d.mts.map +1 -0
  37. package/dist/index-jPzXRn52.d.mts +184 -0
  38. package/dist/index-jPzXRn52.d.mts.map +1 -0
  39. package/dist/manager-DvRRjza6.d.mts +76 -0
  40. package/dist/manager-DvRRjza6.d.mts.map +1 -0
  41. package/dist/posthog-bootstrap-CYfIy_WS.mjs +1769 -0
  42. package/dist/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
  43. package/dist/posthog-bootstrap-DWxFrxlt.d.mts +81 -0
  44. package/dist/posthog-bootstrap-DWxFrxlt.d.mts.map +1 -0
  45. package/dist/providers-http-client.d.mts +37 -0
  46. package/dist/providers-http-client.d.mts.map +1 -0
  47. package/dist/providers-http-client.mjs +320 -0
  48. package/dist/providers-http-client.mjs.map +1 -0
  49. package/dist/providers-http-server.d.mts +31 -0
  50. package/dist/providers-http-server.d.mts.map +1 -0
  51. package/dist/providers-http-server.mjs +297 -0
  52. package/dist/providers-http-server.mjs.map +1 -0
  53. package/dist/providers-http.d.mts +46 -0
  54. package/dist/providers-http.d.mts.map +1 -0
  55. package/dist/providers-http.mjs +4 -0
  56. package/dist/server-edge.d.mts +9 -0
  57. package/dist/server-edge.d.mts.map +1 -0
  58. package/dist/server-edge.mjs +373 -0
  59. package/dist/server-edge.mjs.map +1 -0
  60. package/dist/server-next.d.mts +67 -0
  61. package/dist/server-next.d.mts.map +1 -0
  62. package/dist/server-next.mjs +193 -0
  63. package/dist/server-next.mjs.map +1 -0
  64. package/dist/server.d.mts +10 -0
  65. package/dist/server.mjs +7 -0
  66. package/dist/service-cYtBBL8x.mjs +945 -0
  67. package/dist/service-cYtBBL8x.mjs.map +1 -0
  68. package/dist/shared.d.mts +16 -0
  69. package/dist/shared.d.mts.map +1 -0
  70. package/dist/shared.mjs +93 -0
  71. package/dist/shared.mjs.map +1 -0
  72. package/dist/types-BxBnNQ0V.d.mts +354 -0
  73. package/dist/types-BxBnNQ0V.d.mts.map +1 -0
  74. package/dist/types-CBvxUEaF.d.mts +216 -0
  75. package/dist/types-CBvxUEaF.d.mts.map +1 -0
  76. package/dist/types.d.mts +4 -0
  77. package/dist/types.mjs +0 -0
  78. package/dist/vercel-types-lwakUfoI.d.mts +102 -0
  79. package/dist/vercel-types-lwakUfoI.d.mts.map +1 -0
  80. package/package.json +129 -0
  81. package/src/client/index.ts +164 -0
  82. package/src/client/manager.ts +71 -0
  83. package/src/client/next/components.tsx +270 -0
  84. package/src/client/next/hooks.ts +217 -0
  85. package/src/client/next/manager.ts +141 -0
  86. package/src/client/next.ts +144 -0
  87. package/src/client-next.ts +101 -0
  88. package/src/client.ts +89 -0
  89. package/src/examples/ai-sdk-patterns.ts +583 -0
  90. package/src/examples/emitter-patterns.ts +476 -0
  91. package/src/examples/nextjs-emitter-patterns.tsx +403 -0
  92. package/src/next/app-router.tsx +564 -0
  93. package/src/next/client.ts +419 -0
  94. package/src/next/index.ts +84 -0
  95. package/src/next/middleware.ts +429 -0
  96. package/src/next/rsc.tsx +300 -0
  97. package/src/next/server.ts +253 -0
  98. package/src/next/types.d.ts +220 -0
  99. package/src/providers/base-provider.ts +419 -0
  100. package/src/providers/console/client.ts +10 -0
  101. package/src/providers/console/index.ts +152 -0
  102. package/src/providers/console/server.ts +6 -0
  103. package/src/providers/console/types.ts +15 -0
  104. package/src/providers/http/client.ts +464 -0
  105. package/src/providers/http/index.ts +30 -0
  106. package/src/providers/http/server.ts +396 -0
  107. package/src/providers/http/types.ts +135 -0
  108. package/src/providers/posthog/client.ts +518 -0
  109. package/src/providers/posthog/index.ts +11 -0
  110. package/src/providers/posthog/server.ts +329 -0
  111. package/src/providers/posthog/types.ts +104 -0
  112. package/src/providers/segment/client.ts +113 -0
  113. package/src/providers/segment/index.ts +11 -0
  114. package/src/providers/segment/server.ts +115 -0
  115. package/src/providers/segment/types.ts +51 -0
  116. package/src/providers/vercel/client.ts +102 -0
  117. package/src/providers/vercel/index.ts +11 -0
  118. package/src/providers/vercel/server.ts +89 -0
  119. package/src/providers/vercel/types.ts +27 -0
  120. package/src/server/index.ts +103 -0
  121. package/src/server/manager.ts +62 -0
  122. package/src/server/next.ts +210 -0
  123. package/src/server-edge.ts +442 -0
  124. package/src/server-next.ts +39 -0
  125. package/src/server.ts +106 -0
  126. package/src/shared/emitters/ai/README.md +981 -0
  127. package/src/shared/emitters/ai/events/agent.ts +130 -0
  128. package/src/shared/emitters/ai/events/artifacts.ts +167 -0
  129. package/src/shared/emitters/ai/events/chat.ts +126 -0
  130. package/src/shared/emitters/ai/events/chatbot-ecommerce.ts +133 -0
  131. package/src/shared/emitters/ai/events/completion.ts +103 -0
  132. package/src/shared/emitters/ai/events/content-generation.ts +347 -0
  133. package/src/shared/emitters/ai/events/conversation.ts +332 -0
  134. package/src/shared/emitters/ai/events/product-features.ts +1402 -0
  135. package/src/shared/emitters/ai/events/streaming.ts +114 -0
  136. package/src/shared/emitters/ai/events/tool.ts +93 -0
  137. package/src/shared/emitters/ai/index.ts +69 -0
  138. package/src/shared/emitters/ai/track-ai-sdk.ts +74 -0
  139. package/src/shared/emitters/ai/track-ai.ts +50 -0
  140. package/src/shared/emitters/ai/types.ts +1041 -0
  141. package/src/shared/emitters/ai/utils.ts +468 -0
  142. package/src/shared/emitters/ecommerce/events/cart-checkout.ts +106 -0
  143. package/src/shared/emitters/ecommerce/events/coupon.ts +49 -0
  144. package/src/shared/emitters/ecommerce/events/engagement.ts +61 -0
  145. package/src/shared/emitters/ecommerce/events/marketplace.ts +119 -0
  146. package/src/shared/emitters/ecommerce/events/order.ts +199 -0
  147. package/src/shared/emitters/ecommerce/events/product.ts +205 -0
  148. package/src/shared/emitters/ecommerce/events/registry.ts +123 -0
  149. package/src/shared/emitters/ecommerce/events/wishlist-sharing.ts +140 -0
  150. package/src/shared/emitters/ecommerce/index.ts +46 -0
  151. package/src/shared/emitters/ecommerce/track-ecommerce.ts +53 -0
  152. package/src/shared/emitters/ecommerce/types.ts +314 -0
  153. package/src/shared/emitters/ecommerce/utils.ts +216 -0
  154. package/src/shared/emitters/emitter-types.ts +974 -0
  155. package/src/shared/emitters/emitters.ts +292 -0
  156. package/src/shared/emitters/helpers.ts +419 -0
  157. package/src/shared/emitters/index.ts +66 -0
  158. package/src/shared/index.ts +142 -0
  159. package/src/shared/ingestion/index.ts +66 -0
  160. package/src/shared/ingestion/schemas.ts +386 -0
  161. package/src/shared/ingestion/service.ts +628 -0
  162. package/src/shared/node22-features.ts +848 -0
  163. package/src/shared/providers/console-provider.ts +160 -0
  164. package/src/shared/types/base-types.ts +54 -0
  165. package/src/shared/types/console-types.ts +19 -0
  166. package/src/shared/types/posthog-types.ts +131 -0
  167. package/src/shared/types/segment-types.ts +15 -0
  168. package/src/shared/types/types.ts +397 -0
  169. package/src/shared/types/vercel-types.ts +19 -0
  170. package/src/shared/utils/config-client.ts +19 -0
  171. package/src/shared/utils/config.ts +250 -0
  172. package/src/shared/utils/emitter-adapter.ts +212 -0
  173. package/src/shared/utils/manager.test.ts +36 -0
  174. package/src/shared/utils/manager.ts +1322 -0
  175. package/src/shared/utils/posthog-bootstrap.ts +136 -0
  176. package/src/shared/utils/posthog-client-utils.ts +48 -0
  177. package/src/shared/utils/posthog-next-utils.ts +282 -0
  178. package/src/shared/utils/posthog-server-utils.ts +210 -0
  179. package/src/shared/utils/rate-limit.ts +289 -0
  180. package/src/shared/utils/security.ts +545 -0
  181. package/src/shared/utils/validation-client.ts +161 -0
  182. package/src/shared/utils/validation.ts +399 -0
  183. package/src/shared.ts +155 -0
  184. package/src/types/index.ts +62 -0
@@ -0,0 +1,289 @@
1
+ /**
2
+ * @fileoverview Rate limiting utilities for analytics calls
3
+ * Rate limiting utilities for analytics calls
4
+ *
5
+ * Prevents overwhelming provider APIs, hitting rate limits, and excessive costs.
6
+ * Uses token bucket algorithm for smooth rate limiting with bursts.
7
+ *
8
+ * @module rate-limit
9
+ */
10
+
11
+ import { logWarn } from '@repo/shared/logger';
12
+
13
+ /**
14
+ * Rate limiter configuration
15
+ */
16
+ export interface RateLimiterConfig {
17
+ /** Maximum number of calls per window */
18
+ maxCalls: number;
19
+ /** Window size in milliseconds */
20
+ windowMs: number;
21
+ /** Maximum number of concurrent calls */
22
+ maxConcurrent?: number;
23
+ /** Whether to queue excess calls or drop them */
24
+ queueExcess?: boolean;
25
+ /** Maximum queue size */
26
+ maxQueueSize?: number;
27
+ }
28
+
29
+ /**
30
+ * Rate limiter for analytics calls
31
+ *
32
+ * Implements token bucket algorithm with optional call queuing.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const limiter = new RateLimiter({
37
+ * maxCalls: 100,
38
+ * windowMs: 1000, // 100 calls per second
39
+ * maxConcurrent: 10,
40
+ * });
41
+ *
42
+ * // Check if call is allowed
43
+ * if (await limiter.tryAcquire()) {
44
+ * await analytics.track('Event');
45
+ * limiter.release();
46
+ * }
47
+ *
48
+ * // Or use wrapper
49
+ * await limiter.execute(() => analytics.track('Event'));
50
+ * ```
51
+ */
52
+ export class RateLimiter {
53
+ private callCount = 0;
54
+ private concurrentCount = 0;
55
+ private windowStart = Date.now();
56
+ private queue: Array<() => void> = [];
57
+ private readonly config: Required<RateLimiterConfig>;
58
+
59
+ constructor(config: RateLimiterConfig) {
60
+ this.config = {
61
+ maxCalls: config.maxCalls,
62
+ windowMs: config.windowMs,
63
+ maxConcurrent: config.maxConcurrent ?? Infinity,
64
+ queueExcess: config.queueExcess ?? false,
65
+ maxQueueSize: config.maxQueueSize ?? 1000,
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Try to acquire a rate limit token
71
+ *
72
+ * @returns Promise resolving to whether the call is allowed
73
+ */
74
+ async tryAcquire(): Promise<boolean> {
75
+ // Reset window if needed
76
+ const now = Date.now();
77
+ if (now - this.windowStart >= this.config.windowMs) {
78
+ this.callCount = 0;
79
+ this.windowStart = now;
80
+ }
81
+
82
+ // Check rate limit
83
+ if (this.callCount >= this.config.maxCalls) {
84
+ if (this.config.queueExcess && this.queue.length < this.config.maxQueueSize) {
85
+ // Queue the call - will re-check rate limit when dequeued
86
+ return new Promise<boolean>(resolve => {
87
+ this.queue.push(() => {
88
+ // Re-check rate limit when dequeued to prevent bypassing
89
+ const now = Date.now();
90
+ if (now - this.windowStart >= this.config.windowMs) {
91
+ this.callCount = 0;
92
+ this.windowStart = now;
93
+ }
94
+ if (this.callCount < this.config.maxCalls) {
95
+ this.callCount++;
96
+ resolve(true);
97
+ } else {
98
+ resolve(false);
99
+ }
100
+ });
101
+ });
102
+ }
103
+
104
+ if (process.env.NODE_ENV === 'development') {
105
+ logWarn('Rate limit exceeded', {
106
+ maxCalls: this.config.maxCalls,
107
+ windowMs: this.config.windowMs,
108
+ currentCount: this.callCount,
109
+ });
110
+ }
111
+
112
+ return false;
113
+ }
114
+
115
+ // Check concurrency limit
116
+ if (this.concurrentCount >= this.config.maxConcurrent) {
117
+ if (this.config.queueExcess && this.queue.length < this.config.maxQueueSize) {
118
+ // Queue the call
119
+ return new Promise<boolean>(resolve => {
120
+ this.queue.push(() => resolve(true));
121
+ });
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ this.callCount++;
128
+ this.concurrentCount++;
129
+ return true;
130
+ }
131
+
132
+ /**
133
+ * Release a rate limit token
134
+ */
135
+ release(): void {
136
+ this.concurrentCount = Math.max(0, this.concurrentCount - 1);
137
+
138
+ // Process queue - only process if concurrency allows and rate limit allows
139
+ if (this.queue.length > 0 && this.concurrentCount < this.config.maxConcurrent) {
140
+ // Reset rate limit window if needed before processing queue
141
+ const now = Date.now();
142
+ if (now - this.windowStart >= this.config.windowMs) {
143
+ this.callCount = 0;
144
+ this.windowStart = now;
145
+ }
146
+
147
+ // Only process if rate limit allows
148
+ if (this.callCount < this.config.maxCalls) {
149
+ const next = this.queue.shift();
150
+ if (next) {
151
+ this.concurrentCount++;
152
+ next();
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Execute a function with rate limiting
160
+ *
161
+ * @param fn - Function to execute
162
+ * @returns Promise resolving to function result
163
+ */
164
+ async execute<T>(fn: () => Promise<T>): Promise<T | null> {
165
+ const allowed = await this.tryAcquire();
166
+
167
+ if (!allowed) {
168
+ return null;
169
+ }
170
+
171
+ try {
172
+ return await fn();
173
+ } finally {
174
+ this.release();
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Get current rate limiter stats
180
+ */
181
+ getStats(): {
182
+ callCount: number;
183
+ concurrentCount: number;
184
+ queueSize: number;
185
+ remainingCalls: number;
186
+ windowStart: number;
187
+ } {
188
+ return {
189
+ callCount: this.callCount,
190
+ concurrentCount: this.concurrentCount,
191
+ queueSize: this.queue.length,
192
+ remainingCalls: Math.max(0, this.config.maxCalls - this.callCount),
193
+ windowStart: this.windowStart,
194
+ };
195
+ }
196
+
197
+ /**
198
+ * Reset the rate limiter
199
+ */
200
+ reset(): void {
201
+ this.callCount = 0;
202
+ this.concurrentCount = 0;
203
+ this.windowStart = Date.now();
204
+ this.queue = [];
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Simple in-memory rate limiter using Map
210
+ *
211
+ * Useful for per-provider or per-user rate limiting.
212
+ */
213
+ export class MapRateLimiter {
214
+ private limiters = new Map<string, RateLimiter>();
215
+ private readonly config: RateLimiterConfig;
216
+
217
+ constructor(config: RateLimiterConfig) {
218
+ this.config = config;
219
+ }
220
+
221
+ /**
222
+ * Get or create a rate limiter for a key
223
+ */
224
+ private getLimiter(key: string): RateLimiter {
225
+ let limiter = this.limiters.get(key);
226
+
227
+ if (!limiter) {
228
+ limiter = new RateLimiter(this.config);
229
+ this.limiters.set(key, limiter);
230
+ }
231
+
232
+ return limiter;
233
+ }
234
+
235
+ /**
236
+ * Try to acquire a rate limit token for a key
237
+ */
238
+ async tryAcquire(key: string): Promise<boolean> {
239
+ return this.getLimiter(key).tryAcquire();
240
+ }
241
+
242
+ /**
243
+ * Release a rate limit token for a key
244
+ */
245
+ release(key: string): void {
246
+ this.getLimiter(key).release();
247
+ }
248
+
249
+ /**
250
+ * Execute a function with rate limiting for a key
251
+ */
252
+ async execute<T>(key: string, fn: () => Promise<T>): Promise<T | null> {
253
+ return this.getLimiter(key).execute(fn);
254
+ }
255
+
256
+ /**
257
+ * Get stats for a key
258
+ */
259
+ getStats(key: string): ReturnType<RateLimiter['getStats']> | null {
260
+ const limiter = this.limiters.get(key);
261
+ return limiter ? limiter.getStats() : null;
262
+ }
263
+
264
+ /**
265
+ * Reset rate limiter for a key
266
+ */
267
+ reset(key: string): void {
268
+ const limiter = this.limiters.get(key);
269
+ if (limiter) {
270
+ limiter.reset();
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Clean up old limiters (call periodically)
276
+ */
277
+ cleanup(maxAge: number = 60000): void {
278
+ const now = Date.now();
279
+
280
+ for (const [key, limiter] of this.limiters.entries()) {
281
+ const stats = limiter.getStats();
282
+
283
+ // Remove if inactive for maxAge
284
+ if (now - stats.windowStart > maxAge && stats.callCount === 0 && stats.queueSize === 0) {
285
+ this.limiters.delete(key);
286
+ }
287
+ }
288
+ }
289
+ }