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
TypeScript
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 };