@nextsparkjs/plugin-amplitude 0.1.0-beta.1
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/CODE_REVIEW_REPORT.md +462 -0
- package/README.md +619 -0
- package/__tests__/amplitude-core.test.ts +279 -0
- package/__tests__/hooks.test.ts +478 -0
- package/__tests__/validation.test.ts +393 -0
- package/components/AnalyticsDashboard.tsx +339 -0
- package/components/ConsentManager.tsx +265 -0
- package/components/ExperimentWrapper.tsx +440 -0
- package/components/PerformanceMonitor.tsx +578 -0
- package/hooks/useAmplitude.ts +132 -0
- package/hooks/useAmplitudeEvents.ts +100 -0
- package/hooks/useExperiment.ts +195 -0
- package/hooks/useSessionReplay.ts +238 -0
- package/jest.setup.ts +276 -0
- package/lib/amplitude-core.ts +178 -0
- package/lib/cache.ts +181 -0
- package/lib/performance.ts +319 -0
- package/lib/queue.ts +389 -0
- package/lib/security.ts +188 -0
- package/package.json +15 -0
- package/plugin.config.ts +58 -0
- package/providers/AmplitudeProvider.tsx +113 -0
- package/styles/amplitude.css +593 -0
- package/translations/en.json +45 -0
- package/translations/es.json +45 -0
- package/tsconfig.json +47 -0
- package/types/amplitude.types.ts +105 -0
- package/utils/debounce.ts +133 -0
package/README.md
ADDED
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
# 📊 Amplitude Analytics Plugin
|
|
2
|
+
|
|
3
|
+
> **Enterprise-grade user analytics and behavioral tracking plugin for NextSpark applications**
|
|
4
|
+
|
|
5
|
+
[](./package.json)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://reactjs.org/)
|
|
9
|
+
[](#testing)
|
|
10
|
+
|
|
11
|
+
## 🎯 **Características Principales**
|
|
12
|
+
|
|
13
|
+
### **📈 Analytics Avanzado**
|
|
14
|
+
- **Auto-tracking inteligente** de page views, clicks, forms y navegación SPA
|
|
15
|
+
- **Event batching** optimizado para performance con cola offline
|
|
16
|
+
- **Real-time dashboards** con métricas de negocio y técnicas
|
|
17
|
+
- **Cache LRU con TTL** para optimización de performance
|
|
18
|
+
|
|
19
|
+
### **🔒 Seguridad y Privacidad Enterprise**
|
|
20
|
+
- **Gestión de consentimiento GDPR/CCPA** granular por categoría
|
|
21
|
+
- **Enmascaramiento automático de PII** con 13+ patrones de detección
|
|
22
|
+
- **Rate limiting** con sliding window (1000 eventos/minuto)
|
|
23
|
+
- **Audit logging** con retención configurable y severidad
|
|
24
|
+
|
|
25
|
+
### **🧪 A/B Testing y Experimentación**
|
|
26
|
+
- **Asignación determinística** con sticky sessions por user/device/session
|
|
27
|
+
- **Statistical significance** calculation con confidence intervals
|
|
28
|
+
- **Targeting avanzado** por propiedades, geolocation, device type
|
|
29
|
+
- **Exposure y conversion tracking** automático
|
|
30
|
+
|
|
31
|
+
### **🎬 Session Replay**
|
|
32
|
+
- **Grabación privacy-first** con masking automático de elementos sensibles
|
|
33
|
+
- **Sampling inteligente** para optimización de performance
|
|
34
|
+
- **Selective recording** con páginas excluidas configurables
|
|
35
|
+
- **Compression y batching** para transmisión eficiente
|
|
36
|
+
|
|
37
|
+
### **🎨 Integración con Temas**
|
|
38
|
+
- **Theme-aware components** que respetan el design system
|
|
39
|
+
- **CSS custom properties** para integración seamless
|
|
40
|
+
- **Component overrides** a través del sistema de temas
|
|
41
|
+
- **Dark mode support** automático
|
|
42
|
+
|
|
43
|
+
### **🌍 Internacionalización**
|
|
44
|
+
- **Plugin translation namespace** (`plugins.amplitude.*`)
|
|
45
|
+
- **Soporte completo English/Spanish** con 200+ strings
|
|
46
|
+
- **Fallback automático** para keys faltantes
|
|
47
|
+
- **Integration con sistema i18n** de la aplicación
|
|
48
|
+
|
|
49
|
+
## 🚀 **Instalación y Configuración**
|
|
50
|
+
|
|
51
|
+
### **1. Configuración Básica**
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// contents/plugins/amplitude/plugin.config.ts
|
|
55
|
+
import { amplitudePlugin } from './plugin.config';
|
|
56
|
+
|
|
57
|
+
const config = {
|
|
58
|
+
apiKey: 'your-amplitude-api-key-32-chars',
|
|
59
|
+
serverZone: 'US', // or 'EU'
|
|
60
|
+
enableSessionReplay: true,
|
|
61
|
+
enableABTesting: true,
|
|
62
|
+
enableConsentManagement: true,
|
|
63
|
+
debugMode: false, // Set to true for development
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### **2. Provider Setup**
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
// app/layout.tsx
|
|
71
|
+
import { AmplitudeProvider } from '@/contents/plugins/amplitude/providers/AmplitudeProvider';
|
|
72
|
+
|
|
73
|
+
export default function RootLayout({ children }) {
|
|
74
|
+
return (
|
|
75
|
+
<html>
|
|
76
|
+
<body>
|
|
77
|
+
<AmplitudeProvider overrideConfig={config}>
|
|
78
|
+
{children}
|
|
79
|
+
</AmplitudeProvider>
|
|
80
|
+
</body>
|
|
81
|
+
</html>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### **3. Hook Usage**
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// components/YourComponent.tsx
|
|
90
|
+
import { useAmplitude } from '@/contents/plugins/amplitude/hooks/useAmplitude';
|
|
91
|
+
|
|
92
|
+
export function YourComponent() {
|
|
93
|
+
const { track, identify, isInitialized } = useAmplitude();
|
|
94
|
+
|
|
95
|
+
const handleClick = async () => {
|
|
96
|
+
await track('Button Clicked', {
|
|
97
|
+
buttonId: 'cta-signup',
|
|
98
|
+
page: '/home',
|
|
99
|
+
user_plan: 'free'
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const handleUserLogin = async (userId: string) => {
|
|
104
|
+
await identify(userId, {
|
|
105
|
+
plan: 'premium',
|
|
106
|
+
signup_date: new Date().toISOString(),
|
|
107
|
+
feature_flags: ['new_ui', 'advanced_analytics']
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (!isInitialized) {
|
|
112
|
+
return <div>Loading analytics...</div>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<button onClick={handleClick}>
|
|
117
|
+
Track This Click
|
|
118
|
+
</button>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 📋 **API Reference**
|
|
124
|
+
|
|
125
|
+
### **useAmplitude Hook**
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const {
|
|
129
|
+
track, // (eventType: string, properties?: object) => Promise<void>
|
|
130
|
+
identify, // (userId: string, properties?: object) => Promise<void>
|
|
131
|
+
setUserProperties, // (properties: object) => Promise<void>
|
|
132
|
+
reset, // () => void
|
|
133
|
+
isInitialized, // boolean
|
|
134
|
+
context, // { config, consent, error }
|
|
135
|
+
lastError // Error | null
|
|
136
|
+
} = useAmplitude();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### **useExperiment Hook**
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const {
|
|
143
|
+
getVariant, // (experimentId: string, userId: string) => string | null
|
|
144
|
+
trackExposure, // (experimentId: string, variantId?: string) => Promise<void>
|
|
145
|
+
trackConversion, // (experimentId: string, metricId?: string, value?: number) => Promise<void>
|
|
146
|
+
isInExperiment, // (experimentId: string, userId: string) => boolean
|
|
147
|
+
registerExperiment, // (config: ExperimentConfig) => void
|
|
148
|
+
canRunExperiments // boolean
|
|
149
|
+
} = useExperiment();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### **useSessionReplay Hook**
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
const {
|
|
156
|
+
startRecording, // () => Promise<boolean>
|
|
157
|
+
stopRecording, // () => Promise<void>
|
|
158
|
+
pauseRecording, // () => void
|
|
159
|
+
resumeRecording, // () => void
|
|
160
|
+
isRecording, // boolean
|
|
161
|
+
canRecord, // boolean
|
|
162
|
+
recordingState, // RecordingState object
|
|
163
|
+
privacyControls // PrivacyControls object
|
|
164
|
+
} = useSessionReplay();
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 🧪 **A/B Testing y Experimentos**
|
|
168
|
+
|
|
169
|
+
### **Configuración de Experimento**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// Registrar experimento
|
|
173
|
+
const experimentConfig = {
|
|
174
|
+
id: 'checkout-flow-v2',
|
|
175
|
+
name: 'New Checkout Flow',
|
|
176
|
+
status: 'running',
|
|
177
|
+
variants: [
|
|
178
|
+
{
|
|
179
|
+
id: 'control',
|
|
180
|
+
name: 'Original Checkout',
|
|
181
|
+
allocation: 50,
|
|
182
|
+
isControl: true,
|
|
183
|
+
config: { showProgressBar: false, steps: 3 }
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: 'treatment',
|
|
187
|
+
name: 'Streamlined Checkout',
|
|
188
|
+
allocation: 50,
|
|
189
|
+
isControl: false,
|
|
190
|
+
config: { showProgressBar: true, steps: 2 }
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
targeting: {
|
|
194
|
+
userProperties: { plan: 'premium' },
|
|
195
|
+
deviceType: ['desktop', 'mobile']
|
|
196
|
+
},
|
|
197
|
+
startDate: new Date(),
|
|
198
|
+
endDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
|
|
199
|
+
sampleSize: 10000,
|
|
200
|
+
confidenceLevel: 0.95
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
registerExperiment(experimentConfig);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### **Uso con Componentes**
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
// Declarative A/B Testing
|
|
210
|
+
import { ExperimentWrapper, ABTest, FeatureFlag } from '@/contents/plugins/amplitude/components/ExperimentWrapper';
|
|
211
|
+
|
|
212
|
+
// Wrapper básico
|
|
213
|
+
<ExperimentWrapper
|
|
214
|
+
experimentId="checkout-flow-v2"
|
|
215
|
+
trackExposureOnMount={true}
|
|
216
|
+
>
|
|
217
|
+
{(variant, config) => (
|
|
218
|
+
variant === 'treatment' ?
|
|
219
|
+
<StreamlinedCheckout config={config} /> :
|
|
220
|
+
<OriginalCheckout config={config} />
|
|
221
|
+
)}
|
|
222
|
+
</ExperimentWrapper>
|
|
223
|
+
|
|
224
|
+
// A/B Test simplificado
|
|
225
|
+
<ABTest
|
|
226
|
+
experimentId="button-color-test"
|
|
227
|
+
variants={{
|
|
228
|
+
control: <button className="btn-blue">Sign Up</button>,
|
|
229
|
+
red: <button className="btn-red">Sign Up</button>,
|
|
230
|
+
green: <button className="btn-green">Sign Up</button>
|
|
231
|
+
}}
|
|
232
|
+
/>
|
|
233
|
+
|
|
234
|
+
// Feature Flag
|
|
235
|
+
<FeatureFlag flag="new-dashboard">
|
|
236
|
+
<NewDashboard />
|
|
237
|
+
</FeatureFlag>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### **Tracking de Conversiones**
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// En el componente de checkout
|
|
244
|
+
const { trackConversion } = useExperiment();
|
|
245
|
+
|
|
246
|
+
const handlePurchaseComplete = async (orderValue: number) => {
|
|
247
|
+
await trackConversion('checkout-flow-v2', 'purchase', orderValue);
|
|
248
|
+
};
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## 🎬 **Session Replay**
|
|
252
|
+
|
|
253
|
+
### **Configuración de Privacidad**
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
const sessionReplayConfig = {
|
|
257
|
+
enabled: true,
|
|
258
|
+
sampleRate: 0.1, // 10% de sesiones
|
|
259
|
+
privacyMode: 'balanced', // 'strict' | 'balanced' | 'permissive'
|
|
260
|
+
maskAllInputs: true,
|
|
261
|
+
blockSelector: [
|
|
262
|
+
'[data-private]',
|
|
263
|
+
'.sensitive-data',
|
|
264
|
+
'#credit-card-form'
|
|
265
|
+
],
|
|
266
|
+
maskSelector: [
|
|
267
|
+
'input[type="email"]',
|
|
268
|
+
'.user-details',
|
|
269
|
+
'[data-mask]'
|
|
270
|
+
],
|
|
271
|
+
ignoredPages: ['/admin', '/payment']
|
|
272
|
+
};
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### **Control Programático**
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
import { useSessionReplay } from '@/contents/plugins/amplitude/hooks/useSessionReplay';
|
|
279
|
+
|
|
280
|
+
function SessionControls() {
|
|
281
|
+
const {
|
|
282
|
+
startRecording,
|
|
283
|
+
stopRecording,
|
|
284
|
+
isRecording,
|
|
285
|
+
recordingState
|
|
286
|
+
} = useSessionReplay();
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
<div>
|
|
290
|
+
<p>Recording: {isRecording ? 'Active' : 'Stopped'}</p>
|
|
291
|
+
<p>Duration: {recordingState.duration}ms</p>
|
|
292
|
+
<p>Events: {recordingState.eventsCount}</p>
|
|
293
|
+
|
|
294
|
+
<button onClick={startRecording}>Start Recording</button>
|
|
295
|
+
<button onClick={stopRecording}>Stop Recording</button>
|
|
296
|
+
</div>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## 🔒 **Gestión de Consentimiento**
|
|
302
|
+
|
|
303
|
+
### **ConsentManager Component**
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
import { ConsentManager, useConsent } from '@/contents/plugins/amplitude/components/ConsentManager';
|
|
307
|
+
|
|
308
|
+
function App() {
|
|
309
|
+
const {
|
|
310
|
+
isConsentModalOpen,
|
|
311
|
+
openConsentModal,
|
|
312
|
+
closeConsentModal,
|
|
313
|
+
hasConsent,
|
|
314
|
+
getConsentStatus
|
|
315
|
+
} = useConsent();
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<>
|
|
319
|
+
<button onClick={openConsentModal}>
|
|
320
|
+
Privacy Settings
|
|
321
|
+
</button>
|
|
322
|
+
|
|
323
|
+
<ConsentManager
|
|
324
|
+
isOpen={isConsentModalOpen}
|
|
325
|
+
onClose={closeConsentModal}
|
|
326
|
+
onConsentChange={(consent) => {
|
|
327
|
+
console.log('Consent updated:', consent);
|
|
328
|
+
}}
|
|
329
|
+
position="center"
|
|
330
|
+
showBadge={true}
|
|
331
|
+
/>
|
|
332
|
+
|
|
333
|
+
{hasConsent('analytics') && (
|
|
334
|
+
<AnalyticsComponents />
|
|
335
|
+
)}
|
|
336
|
+
</>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### **Estados de Consentimiento**
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
// Verificar consentimiento específico
|
|
345
|
+
if (hasConsent('sessionReplay')) {
|
|
346
|
+
// Iniciar session replay
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Obtener estado completo
|
|
350
|
+
const status = getConsentStatus();
|
|
351
|
+
console.log(`${status.granted}/${status.total} categorías habilitadas`);
|
|
352
|
+
console.log(`${status.percentage}% de consentimiento`);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## 📊 **Dashboard y Monitoring**
|
|
356
|
+
|
|
357
|
+
### **Analytics Dashboard**
|
|
358
|
+
|
|
359
|
+
```tsx
|
|
360
|
+
import { AnalyticsDashboard } from '@/contents/plugins/amplitude/components/AnalyticsDashboard';
|
|
361
|
+
|
|
362
|
+
<AnalyticsDashboard
|
|
363
|
+
refreshInterval={30000} // 30 segundos
|
|
364
|
+
showAdvancedMetrics={true}
|
|
365
|
+
timeRange="24h"
|
|
366
|
+
compactMode={false}
|
|
367
|
+
/>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### **Performance Monitor**
|
|
371
|
+
|
|
372
|
+
```tsx
|
|
373
|
+
import { PerformanceMonitor } from '@/contents/plugins/amplitude/components/PerformanceMonitor';
|
|
374
|
+
|
|
375
|
+
<PerformanceMonitor
|
|
376
|
+
refreshInterval={5000} // 5 segundos
|
|
377
|
+
showAlerts={true}
|
|
378
|
+
showCharts={true}
|
|
379
|
+
alertThresholds={{
|
|
380
|
+
errorRate: 0.05, // 5%
|
|
381
|
+
memoryUsageMB: 100,
|
|
382
|
+
latencyMs: 1000,
|
|
383
|
+
queueSize: 1000
|
|
384
|
+
}}
|
|
385
|
+
onAlert={(alert) => {
|
|
386
|
+
console.warn('Performance Alert:', alert);
|
|
387
|
+
// Enviar a sistema de alertas
|
|
388
|
+
}}
|
|
389
|
+
/>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## 🧪 **Testing**
|
|
393
|
+
|
|
394
|
+
### **Ejecutar Tests**
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
# Tests unitarios
|
|
398
|
+
npm test
|
|
399
|
+
|
|
400
|
+
# Tests con watch mode
|
|
401
|
+
npm run test:watch
|
|
402
|
+
|
|
403
|
+
# Coverage report
|
|
404
|
+
npm run test:coverage
|
|
405
|
+
|
|
406
|
+
# Type checking
|
|
407
|
+
npm run type-check
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### **Mock para Testing**
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// __tests__/setup.ts
|
|
414
|
+
jest.mock('@/contents/plugins/amplitude/hooks/useAmplitude', () => ({
|
|
415
|
+
useAmplitude: () => ({
|
|
416
|
+
track: jest.fn().mockResolvedValue(undefined),
|
|
417
|
+
identify: jest.fn().mockResolvedValue(undefined),
|
|
418
|
+
isInitialized: true,
|
|
419
|
+
context: { config: mockConfig, consent: mockConsent, error: null }
|
|
420
|
+
})
|
|
421
|
+
}));
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## 🎨 **Personalización y Temas**
|
|
425
|
+
|
|
426
|
+
### **CSS Custom Properties**
|
|
427
|
+
|
|
428
|
+
```css
|
|
429
|
+
/* Personalizar colores del plugin */
|
|
430
|
+
:root {
|
|
431
|
+
--amplitude-primary: #3b82f6;
|
|
432
|
+
--amplitude-success: #10b981;
|
|
433
|
+
--amplitude-warning: #f59e0b;
|
|
434
|
+
--amplitude-error: #ef4444;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/* Dark mode */
|
|
438
|
+
[data-theme="dark"] {
|
|
439
|
+
--amplitude-bg-primary: #1f2937;
|
|
440
|
+
--amplitude-text-primary: #f9fafb;
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### **Component Overrides**
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
// Sistema de temas (ejemplo)
|
|
448
|
+
const themeOverrides = {
|
|
449
|
+
'amplitude.consent': {
|
|
450
|
+
Modal: CustomModal,
|
|
451
|
+
Button: CustomButton,
|
|
452
|
+
Card: CustomCard
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## 🔧 **Configuración Avanzada**
|
|
458
|
+
|
|
459
|
+
### **Plugin Configuration Schema**
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
const advancedConfig = {
|
|
463
|
+
// API Configuration
|
|
464
|
+
apiKey: 'your-32-char-api-key',
|
|
465
|
+
serverZone: 'US' | 'EU',
|
|
466
|
+
|
|
467
|
+
// Features
|
|
468
|
+
enableSessionReplay: true,
|
|
469
|
+
enableABTesting: true,
|
|
470
|
+
enableConsentManagement: true,
|
|
471
|
+
|
|
472
|
+
// Performance
|
|
473
|
+
batchSize: 30, // Events per batch
|
|
474
|
+
flushInterval: 10000, // ms between flushes
|
|
475
|
+
sampleRate: 1.0, // 0-1 sampling rate
|
|
476
|
+
|
|
477
|
+
// Security
|
|
478
|
+
piiMaskingEnabled: true,
|
|
479
|
+
rateLimitEventsPerMinute: 1000,
|
|
480
|
+
errorRetryAttempts: 3,
|
|
481
|
+
errorRetryDelayMs: 1000,
|
|
482
|
+
|
|
483
|
+
// Debug
|
|
484
|
+
debugMode: false,
|
|
485
|
+
};
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### **Event Queue Configuration**
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
const queueConfig = {
|
|
492
|
+
maxSize: 10000,
|
|
493
|
+
batchSize: 30,
|
|
494
|
+
flushIntervalMs: 10000,
|
|
495
|
+
maxRetries: 3,
|
|
496
|
+
enablePersistence: true,
|
|
497
|
+
priorityQueueEnabled: true
|
|
498
|
+
};
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### **Cache Configuration**
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
const cacheConfig = {
|
|
505
|
+
maxSize: 5000,
|
|
506
|
+
defaultTtlMs: 30 * 60 * 1000, // 30 minutos
|
|
507
|
+
maxMemoryMB: 20,
|
|
508
|
+
enablePersistence: true
|
|
509
|
+
};
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
## 🚨 **Troubleshooting**
|
|
513
|
+
|
|
514
|
+
### **Problemas Comunes**
|
|
515
|
+
|
|
516
|
+
#### **Plugin no inicializa**
|
|
517
|
+
```typescript
|
|
518
|
+
// Verificar API key
|
|
519
|
+
console.log('API Key length:', config.apiKey.length); // Debe ser 32
|
|
520
|
+
console.log('API Key format:', /^[a-zA-Z0-9]{32}$/.test(config.apiKey));
|
|
521
|
+
|
|
522
|
+
// Verificar contexto
|
|
523
|
+
const { error, isInitialized } = useAmplitudeContext();
|
|
524
|
+
if (error) console.error('Amplitude Error:', error);
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
#### **Eventos no se envían**
|
|
528
|
+
```typescript
|
|
529
|
+
// Verificar consentimiento
|
|
530
|
+
const { consent } = useAmplitudeContext();
|
|
531
|
+
console.log('Analytics consent:', consent.analytics);
|
|
532
|
+
|
|
533
|
+
// Verificar rate limiting
|
|
534
|
+
import { rateLimiter } from '@/contents/plugins/amplitude/lib/security';
|
|
535
|
+
console.log('Rate limit OK:', rateLimiter.checkRateLimit('user-id'));
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### **Performance Issues**
|
|
539
|
+
```typescript
|
|
540
|
+
// Verificar métricas
|
|
541
|
+
import { getPerformanceStats } from '@/contents/plugins/amplitude/lib/performance';
|
|
542
|
+
const stats = getPerformanceStats();
|
|
543
|
+
console.log('Memory usage:', stats.amplitudeCore.memoryUsage);
|
|
544
|
+
console.log('Queue size:', stats.amplitudeCore.eventQueueSize);
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### **Debug Mode**
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
// Habilitar debug mode
|
|
551
|
+
const debugConfig = {
|
|
552
|
+
...config,
|
|
553
|
+
debugMode: true
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// Logs adicionales en consola
|
|
557
|
+
// Performance metrics detalladas
|
|
558
|
+
// Event tracking verbose
|
|
559
|
+
// Error reporting extendido
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
## 📈 **Performance y Optimización**
|
|
563
|
+
|
|
564
|
+
### **Métricas Monitoreadas**
|
|
565
|
+
- **Initialization Time**: < 50ms
|
|
566
|
+
- **Event Processing**: < 10ms promedio
|
|
567
|
+
- **Memory Usage**: < 5MB máximo
|
|
568
|
+
- **Cache Hit Rate**: > 85%
|
|
569
|
+
- **Error Rate**: < 1%
|
|
570
|
+
|
|
571
|
+
### **Best Practices**
|
|
572
|
+
1. **Batch events** en lugar de enviar individualmente
|
|
573
|
+
2. **Use consent management** para compliance automático
|
|
574
|
+
3. **Configure sampling** para session replay (10-30%)
|
|
575
|
+
4. **Monitor performance** con alertas automáticas
|
|
576
|
+
5. **Test thoroughly** con coverage > 90%
|
|
577
|
+
|
|
578
|
+
## 🏗️ **Arquitectura**
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
contents/plugins/amplitude/
|
|
582
|
+
├── plugin.config.ts # Configuración principal
|
|
583
|
+
├── types/amplitude.types.ts # Tipos TypeScript
|
|
584
|
+
├── providers/ # React Providers
|
|
585
|
+
├── hooks/ # Custom Hooks
|
|
586
|
+
├── components/ # UI Components
|
|
587
|
+
├── lib/ # Core Logic
|
|
588
|
+
│ ├── amplitude-core.ts # Amplitude SDK Wrapper
|
|
589
|
+
│ ├── performance.ts # Performance Monitoring
|
|
590
|
+
│ ├── security.ts # Security & Privacy
|
|
591
|
+
│ ├── queue.ts # Event Queue System
|
|
592
|
+
│ └── cache.ts # LRU Cache with TTL
|
|
593
|
+
├── utils/ # Utilities
|
|
594
|
+
├── translations/ # i18n Files
|
|
595
|
+
├── styles/ # CSS Styles
|
|
596
|
+
└── __tests__/ # Test Suite
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## 📄 **License**
|
|
600
|
+
|
|
601
|
+
MIT License - ver [LICENSE](./LICENSE) para detalles completos.
|
|
602
|
+
|
|
603
|
+
## 🤝 **Contributing**
|
|
604
|
+
|
|
605
|
+
1. Fork el repositorio
|
|
606
|
+
2. Crear feature branch (`git checkout -b feature/amazing-feature`)
|
|
607
|
+
3. Commit cambios (`git commit -m 'Add amazing feature'`)
|
|
608
|
+
4. Push al branch (`git push origin feature/amazing-feature`)
|
|
609
|
+
5. Crear Pull Request
|
|
610
|
+
|
|
611
|
+
## 📞 **Soporte**
|
|
612
|
+
|
|
613
|
+
- **Issues**: [GitHub Issues](https://github.com/your-org/nextspark/issues)
|
|
614
|
+
- **Docs**: [Plugin Documentation](./docs/)
|
|
615
|
+
- **Team**: NextSpark Development Team
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
**🎊 Resultado**: Plugin de analytics enterprise-grade, completamente modular, que valida la arquitectura WordPress-like y establece la base para un ecosistema de plugins escalable.
|