UNPKG

mentiq-sdk

Version:

A powerful analytics SDK for React and Next.js with heatmap tracking, session monitoring, and performance analytics

725 lines (711 loc) 25.2 kB
import * as react_jsx_runtime from 'react/jsx-runtime'; import React$1, { ComponentType, ReactNode } from 'react'; interface EventProperties { [key: string]: string | number | boolean | null | undefined; } interface BackendEvent { event_id?: string; event_type: string; user_id?: string; session_id?: string; timestamp?: string; properties?: EventProperties; user_agent?: string; ip_address?: string; } interface PageProperties { title?: string; url?: string; path?: string; referrer?: string; search?: string; } interface UserProperties { [key: string]: string | number | boolean | null | undefined; } interface AnalyticsEvent { id: string; timestamp: number; type: "track" | "page" | "identify" | "alias" | "heatmap" | "session" | "error"; event?: string; properties?: EventProperties; userId?: string; anonymousId: string; sessionId: string; context: { page?: PageProperties; userAgent?: string; timezone?: string; locale?: string; screen?: { width: number; height: number; }; library: { name: string; version: string; }; performance?: PerformanceData; heatmap?: HeatmapData; session?: SessionData; error?: ErrorData; }; } interface AnalyticsInstance { track: (event: string, properties?: EventProperties) => void; page: (properties?: PageProperties) => void; identify: (userId: string, traits?: UserProperties) => void; alias: (newId: string, previousId?: string) => void; reset: () => void; flush: () => Promise<void>; setUserId: (userId: string) => void; getUserId: () => string | null; getAnonymousId: () => string; getSessionId: () => string; getSessionData: () => SessionData; trackCustomError: (error: string | Error, properties?: EventProperties) => void; trackPerformance: (performanceData: PerformanceData) => void; trackFeatureUsage: (featureName: string, properties?: EventProperties) => void; trackFunnelStep: (funnelName: string, stepName: string, stepIndex: number, properties?: EventProperties) => void; completeFunnel: (funnelName: string, properties?: EventProperties) => void; startFunnel: (funnelName: string, properties?: EventProperties) => void; advanceFunnel: (funnelName: string, stepName: string, properties?: EventProperties) => void; abandonFunnel: (funnelName: string, reason?: string, properties?: EventProperties) => void; getFunnelState: (funnelName: string) => FunnelState | undefined; getActiveSession: () => SessionData; calculateEngagementScore: () => number; getQueueSize: () => number; clearQueue: () => void; startRecording: () => void; stopRecording: () => void; pauseRecording: () => void; resumeRecording: () => void; isRecordingActive: () => boolean; config: { apiKey: string; projectId: string; endpoint?: string; debug?: boolean; userId?: string; sessionTimeout?: number; batchSize?: number; flushInterval?: number; enableAutoPageTracking?: boolean; enablePerformanceTracking?: boolean; enableHeatmapTracking?: boolean; enableSessionRecording?: boolean; enableErrorTracking?: boolean; maxQueueSize?: number; retryAttempts?: number; retryDelay?: number; enableABTesting?: boolean; }; } interface AnalyticsProvider { name: string; track: (event: AnalyticsEvent) => Promise<void>; } interface HeatmapData { x: number; y: number; element?: string; selector?: string; action: "click" | "move" | "scroll"; viewport: { width: number; height: number; }; } interface SessionData { sessionId?: string; startTime: number; endTime?: number; duration?: number; pageViews: number; clicks: number; scrollDepth: number; maxScrollDepth: number; isActive: boolean; events: string[]; scrollEvents?: number; clickEvents?: number; pageChanges?: number; engagementScore?: number; bounceLikelihood?: number; channel?: string; } interface FunnelStep { stepName: string; stepIndex: number; timestamp: number; timeInFunnel: number; properties?: EventProperties; } interface FunnelState { funnelName: string; currentStep: number; startTime: number; steps: FunnelStep[]; isActive: boolean; } interface PerformanceData { loadTime?: number; domReady?: number; firstPaint?: number; firstContentfulPaint?: number; largestContentfulPaint?: number; firstInputDelay?: number; cumulativeLayoutShift?: number; timeToInteractive?: number; } interface ErrorData { message: string; stack?: string; filename?: string; lineno?: number; colno?: number; type: "javascript" | "unhandledrejection" | "network" | "custom"; } interface QueuedEvent { event: AnalyticsEvent; retries: number; timestamp: number; } interface ABTestConfig { enableABTesting?: boolean; assignmentCacheTTL?: number; autoTrackExposures?: boolean; } interface Experiment { id: string; name: string; description?: string; key: string; status: "DRAFT" | "RUNNING" | "PAUSED" | "COMPLETED" | "ARCHIVED"; trafficSplit: number; startDate?: string; endDate?: string; createdAt: string; updatedAt: string; variants: Variant[]; } interface Variant { id: string; name: string; key: string; description?: string; isControl: boolean; trafficSplit: number; createdAt: string; updatedAt: string; } interface ExperimentAssignment { experimentId: string; variantId: string; variantKey: string; variantName: string; isControl: boolean; assignedAt: string; experiment?: Experiment; } interface ConversionEvent { experimentId: string; eventName: string; eventValue?: number; properties?: EventProperties; } interface ABTestAnalytics { getExperiment: (experimentKey: string) => Promise<Experiment | null>; getAssignment: (experimentKey: string, options?: AssignmentOptions) => Promise<ExperimentAssignment | null>; trackConversion: (conversion: ConversionEvent) => Promise<void>; getAllExperiments: () => Promise<Experiment[]>; isVariantEnabled: (experimentKey: string, variantKey: string) => Promise<boolean>; getActiveVariants: () => Promise<Record<string, ExperimentAssignment>>; } interface AssignmentOptions { userId?: string; anonymousId?: string; forceRefresh?: boolean; } interface ABTestContext { assignments: Record<string, ExperimentAssignment>; experiments: Record<string, Experiment>; lastFetch: number; } interface AnalyticsConfig { apiKey: string; projectId: string; endpoint?: string; debug?: boolean; userId?: string; sessionTimeout?: number; batchSize?: number; flushInterval?: number; enableAutoPageTracking?: boolean; enablePerformanceTracking?: boolean; enableHeatmapTracking?: boolean; enableSessionRecording?: boolean; enableErrorTracking?: boolean; maxQueueSize?: number; retryAttempts?: number; retryDelay?: number; enableABTesting?: boolean; abTestConfig?: ABTestConfig; } interface AnalyticsConfig { apiKey: string; projectId: string; endpoint?: string; debug?: boolean; userId?: string; sessionTimeout?: number; batchSize?: number; flushInterval?: number; enableAutoPageTracking?: boolean; enablePerformanceTracking?: boolean; enableHeatmapTracking?: boolean; enableSessionRecording?: boolean; enableErrorTracking?: boolean; maxQueueSize?: number; retryAttempts?: number; retryDelay?: number; enableABTesting?: boolean; abTestConfig?: ABTestConfig; } declare class Analytics implements AnalyticsInstance { config: AnalyticsConfig & { endpoint: string; debug: boolean; sessionTimeout: number; batchSize: number; flushInterval: number; enableAutoPageTracking: boolean; enablePerformanceTracking: boolean; enableHeatmapTracking: boolean; enableSessionRecording: boolean; enableErrorTracking: boolean; maxQueueSize: number; retryAttempts: number; retryDelay: number; }; private eventQueue; private providers; private flushTimer?; private sessionTimer?; private isInitialized; private sessionData; private heatmapListeners; private errorListeners; private sessionRecorder?; private funnelState; private funnelAbandonmentTimer; constructor(config: AnalyticsConfig); private initializeSession; private initialize; private setupSessionTracking; private setupHeatmapTracking; private setupErrorTracking; private getElementSelector; private endSession; private setupAutoFlush; private setupAutoPageTracking; private setupPerformanceTracking; addProvider(provider: AnalyticsProvider): void; track(event: string, properties?: EventProperties): void; page(properties?: PageProperties): void; identify(userId: string, traits?: UserProperties & { email?: string; }): void; alias(newId: string, previousId?: string): void; reset(): void; flush(): Promise<void>; setUserId(userId: string): void; getUserId(): string | null; getAnonymousId(): string; getSessionId(): string; getSessionData(): SessionData; getActiveSession(): SessionData; calculateEngagementScore(): number; private calculateDetailedSessionMetrics; private calculateBounceLikelihood; trackCustomError(error: string | Error, properties?: EventProperties): void; trackPerformance(performanceData: PerformanceData): void; trackFeatureUsage(featureName: string, properties?: EventProperties): void; trackFunnelStep(funnelName: string, stepName: string, stepIndex: number, properties?: EventProperties): void; completeFunnel(funnelName: string, properties?: EventProperties): void; startFunnel(funnelName: string, properties?: EventProperties): void; advanceFunnel(funnelName: string, stepName: string, properties?: EventProperties): void; abandonFunnel(funnelName: string, reason?: string, properties?: EventProperties): void; getFunnelState(funnelName: string): any; private clearFunnelState; private resetAbandonmentTimer; private calculateFunnelCompletion; getQueueSize(): number; clearQueue(): void; private enqueueEvent; private createBatches; private sendBatch; private transformEventForBackend; private sendEvent; private setupSessionRecording; startRecording(): void; stopRecording(): void; pauseRecording(): void; resumeRecording(): void; isRecordingActive(): boolean; destroy(): void; } declare function generateId(): string; declare function getSessionId(): string; declare function getAnonymousId(): string; declare function getUserId(): string | null; declare function setUserId(userId: string): void; declare function clearUserId(): void; declare function getContext(): { page?: PageProperties; userAgent?: string; timezone?: string; locale?: string; screen?: { width: number; height: number; }; library: { name: string; version: string; }; performance?: PerformanceData; heatmap?: HeatmapData; session?: SessionData; error?: ErrorData; }; declare function createEvent(type: AnalyticsEvent["type"], event?: string, properties?: any): AnalyticsEvent; declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): T; declare function throttle<T extends (...args: any[]) => any>(func: T, limit: number): T; /** * Detect acquisition channel from URL parameters and referrer */ declare function detectChannel(): string; /** * Get channel from URL parameters (for manual checking) */ declare function getChannelFromUrl(url?: string): string | null; /** * Get user email from storage or auth session * Checks multiple sources in order of priority: * 1. Mentiq-specific storage * 2. NextAuth/Auth.js session * 3. Supabase auth * 4. Firebase auth * 5. Clerk auth * 6. Custom auth patterns */ declare function getUserEmail(): string | null; interface RecordingConfig { maxDuration?: number; checkoutEveryNms?: number; blockClass?: string; ignoreClass?: string; maskAllInputs?: boolean; maskTextClass?: string; inlineStylesheet?: boolean; collectFonts?: boolean; sampling?: { mousemove?: boolean | number; mouseInteraction?: boolean | Record<string, boolean | undefined>; scroll?: number; input?: "last" | "all"; }; } declare class SessionRecorder { private config; private recordingConfig; private stopRecording?; private events; private sessionId; private isRecording; private uploadInterval?; private recordingStartTime?; constructor(config: AnalyticsConfig, sessionId: string, recordingConfig?: RecordingConfig); start(): void; stop(): void; private uploadRecording; pause(): void; resume(): void; isActive(): boolean; getEventCount(): number; clearEvents(): void; } interface MentiqAnalyticsProviderProps { config: AnalyticsConfig; children: ReactNode; fallback?: ReactNode; loading?: ReactNode; } /** * MentiQ Analytics Provider with dynamic loading for optimal performance * Features: * - Server-side rendering support * - Code splitting and lazy loading * - Better bundle optimization * - Graceful error handling */ declare function MentiqAnalyticsProvider({ config, children, fallback, loading, }: MentiqAnalyticsProviderProps): react_jsx_runtime.JSX.Element; /** * Higher-Order Component for wrapping components with MentiQ analytics */ declare function withMentiqAnalytics<P extends object>(WrappedComponent: ComponentType<P>, config: AnalyticsConfig): { (props: P): react_jsx_runtime.JSX.Element; displayName: string; }; /** * Hook for accessing MentiQ analytics from context */ declare function useMentiqAnalytics(): { track: (event: string, properties?: any) => void; page: (properties?: any) => void; identify: (userId: string, properties?: any) => void; reset: () => void; flush: () => Promise<void>; trackCustomError: (error: string | Error, properties?: any) => void; analytics: AnalyticsInstance; }; declare function usePageTracking(properties?: EventProperties): void; declare function useInteractionTracking(): { trackClick: (element: string, properties?: EventProperties) => void; trackHover: (element: string, properties?: EventProperties) => void; trackView: (element: string, properties?: EventProperties) => void; }; declare function useElementTracking(elementRef: React.RefObject<HTMLElement>, event?: string, properties?: EventProperties, options?: { threshold?: number; delay?: number; once?: boolean; }): void; declare function useSessionTracking(): { sessionData: SessionData; sessionId: string; isActive: boolean; duration: number; pageViews: number; clicks: number; scrollDepth: number; }; declare function useErrorTracking(): { trackJavaScriptError: (error: Error, properties?: EventProperties) => void; trackCustomError: (message: string, properties?: EventProperties) => void; }; declare function usePerformanceTracking(): { measureCustomPerformance: (label: string) => { start: () => PerformanceMark; end: () => void; } | undefined; }; declare const useAnalytics: typeof useMentiqAnalytics; interface TrackViewProps { event?: string; properties?: EventProperties; children: ReactNode; threshold?: number; delay?: number; } declare function TrackView({ event, properties, children, threshold, delay, }: TrackViewProps): react_jsx_runtime.JSX.Element; interface TrackClickProps { event?: string; properties?: EventProperties; children: ReactNode; element?: string; } declare function TrackClick({ event, properties, children, element, }: TrackClickProps): react_jsx_runtime.JSX.Element; interface TrackFormProps { formName: string; children: ReactNode; trackSubmit?: boolean; trackFieldChanges?: boolean; } declare function TrackForm({ formName, children, trackSubmit, trackFieldChanges, }: TrackFormProps): react_jsx_runtime.JSX.Element; interface TrackScrollProps { children: ReactNode; milestones?: number[]; } declare function TrackScroll({ children, milestones, }: TrackScrollProps): react_jsx_runtime.JSX.Element; interface TrackTimeProps { children: ReactNode; event?: string; intervals?: number[]; } declare function TrackTime({ children, event, intervals, }: TrackTimeProps): react_jsx_runtime.JSX.Element; declare function withTracking<P extends object>(WrappedComponent: React$1.ComponentType<P>, componentName: string, trackProps?: (props: P) => EventProperties): (props: P) => react_jsx_runtime.JSX.Element; interface ErrorBoundaryProps { children: ReactNode; fallback?: ReactNode; onError?: (error: Error, errorInfo: React$1.ErrorInfo) => void; } declare function AnalyticsErrorBoundary({ children, fallback, onError, }: ErrorBoundaryProps): react_jsx_runtime.JSX.Element; interface PerformanceMonitorProps { children: ReactNode; measureRender?: boolean; componentName?: string; } declare function PerformanceMonitor({ children, measureRender, componentName, }: PerformanceMonitorProps): react_jsx_runtime.JSX.Element; interface HeatmapTrackerProps { children: ReactNode; trackClicks?: boolean; trackHovers?: boolean; trackScrolls?: boolean; element?: string; } declare function HeatmapTracker({ children, trackClicks, trackHovers, trackScrolls, element, }: HeatmapTrackerProps): react_jsx_runtime.JSX.Element; interface SessionMonitorProps { children: ReactNode; trackInactivity?: boolean; inactivityThreshold?: number; } declare function SessionMonitor({ children, trackInactivity, inactivityThreshold, }: SessionMonitorProps): react_jsx_runtime.JSX.Element; declare class ABTesting implements ABTestAnalytics { private config; private headers; constructor(config: AnalyticsConfig); private get apiEndpoint(); getAssignment(experimentKey: string, options?: AssignmentOptions): Promise<ExperimentAssignment | null>; trackConversion(conversion: ConversionEvent): Promise<void>; getAllExperiments(): Promise<Experiment[]>; getExperiment(experimentKey: string): Promise<Experiment | null>; isVariantEnabled(experimentKey: string, variantKey: string): Promise<boolean>; getActiveVariants(): Promise<Record<string, ExperimentAssignment>>; } declare function useABTesting(): ABTesting | null; declare function useExperiment(experimentKey: string, options?: AssignmentOptions): { loading: boolean; error: Error | null; assignment: ExperimentAssignment | null; variantKey: string | undefined; trackConversion: (eventName: string, eventValue?: number, properties?: EventProperties) => void; }; declare function useVariant(experimentKey: string, variantKey: string): { isEnabled: boolean; loading: boolean; error: Error | null; assignment: ExperimentAssignment | null; }; declare function useVariantValue<T>(experimentKey: string, controlValue: T, variantValues: Record<string, T>): { value: T; loading: boolean; error: Error | null; variant: string | undefined; isControl: boolean | undefined; }; declare function useVariantRunner(experimentKey: string, functions: Record<string, () => void>): { loading: boolean; variant: string | undefined; isControl: boolean | undefined; }; declare function useConversionTracking(): { trackConversion: (conversion: ConversionEvent) => Promise<void>; }; declare function useActiveExperiments(): { activeVariants: Record<string, ExperimentAssignment>; loading: boolean; error: string | null; refetch: () => void; count: number; }; declare function useExperimentInfo(experimentKey: string): { experiment: Experiment | null; loading: boolean; error: string | null; refetch: () => void; isRunning: boolean; variants: Variant[]; }; declare function useABTestWithFallback<T>(experimentKey: string, controlValue: T, variantValues: Record<string, T>, fallbackValue?: T): { value: T; loading: boolean; error: Error | null; hasError: boolean; isUsingFallback: boolean | null; }; interface OnboardingStep { name: string; index: number; required?: boolean; } interface OnboardingConfig { steps: OnboardingStep[]; autoTrack?: boolean; } declare class OnboardingTracker { private analytics; private config; private currentStepIndex; private startTime; private completedSteps; constructor(analytics: Analytics, config: OnboardingConfig); /** * Start the onboarding process */ start(properties?: Record<string, any>): void; /** * Complete a step in the onboarding process */ completeStep(stepName: string, properties?: Record<string, any>): void; /** * Skip a step (optional steps only) */ skipStep(stepName: string, reason?: string): void; /** * Mark onboarding as complete */ complete(properties?: Record<string, any>): void; /** * Abandon onboarding */ abandon(reason?: string): void; /** * Get current progress */ getProgress(): { currentStep: string | null; currentStepIndex: number; completedSteps: string[]; totalSteps: number; progressPercent: number; duration: number | null; }; /** * Check if a step is completed */ isStepCompleted(stepName: string): boolean; /** * Get current step name */ private getCurrentStepName; /** * Reset the tracker */ reset(): void; } declare function useOnboardingTracker(analytics: Analytics | null, config: OnboardingConfig): OnboardingTracker | null; declare function init(config: AnalyticsConfig): Analytics; declare function track(event: string, properties?: any): void; declare function page(properties?: any): void; declare function identify(userId: string, traits?: any): void; declare function alias(newId: string, previousId?: string): void; declare function reset(): void; declare function flush(): Promise<void>; declare function getInstance(): Analytics | null; declare function startRecording(): void; declare function stopRecording(): void; declare function pauseRecording(): void; declare function resumeRecording(): void; declare function isRecordingActive(): boolean; declare function trackFeatureUsage(featureName: string, properties?: any): void; declare function trackFunnelStep(funnelName: string, stepName: string, stepIndex: number, properties?: any): void; declare function completeFunnel(funnelName: string, properties?: any): void; declare function startFunnel(funnelName: string, properties?: any): void; declare function advanceFunnel(funnelName: string, stepName: string, properties?: any): void; declare function abandonFunnel(funnelName: string, reason?: string, properties?: any): void; declare function getFunnelState(funnelName: string): any; declare function getActiveSession(): any; declare function calculateEngagementScore(): number; export { Analytics, AnalyticsErrorBoundary, HeatmapTracker, MentiqAnalyticsProvider, OnboardingTracker, PerformanceMonitor, SessionMonitor, SessionRecorder, TrackClick, TrackForm, TrackScroll, TrackTime, TrackView, abandonFunnel, advanceFunnel, alias, calculateEngagementScore, clearUserId, completeFunnel, createEvent, debounce, detectChannel, flush, generateId, getActiveSession, getAnonymousId, getChannelFromUrl, getContext, getFunnelState, getInstance, getSessionId, getUserEmail, getUserId, identify, init, isRecordingActive, page, pauseRecording, reset, resumeRecording, setUserId, startFunnel, startRecording, stopRecording, throttle, track, trackFeatureUsage, trackFunnelStep, useABTestWithFallback, useABTesting, useActiveExperiments, useAnalytics, useConversionTracking, useElementTracking, useErrorTracking, useExperiment, useExperimentInfo, useInteractionTracking, useMentiqAnalytics, useOnboardingTracker, usePageTracking, usePerformanceTracking, useSessionTracking, useVariant, useVariantRunner, useVariantValue, withMentiqAnalytics, withTracking }; export type { ABTestAnalytics, ABTestConfig, ABTestContext, AnalyticsConfig, AnalyticsEvent, AnalyticsInstance, AnalyticsProvider, AssignmentOptions, BackendEvent, ConversionEvent, ErrorData, EventProperties, Experiment, ExperimentAssignment, FunnelState, FunnelStep, HeatmapData, OnboardingConfig, OnboardingStep, PageProperties, PerformanceData, QueuedEvent, RecordingConfig, SessionData, UserProperties, Variant };