Files
mintel.me/src/utils/analytics/index.ts
2026-01-13 02:42:03 +01:00

93 lines
2.5 KiB
TypeScript

/**
* Analytics Service - Main entry point with DI
* Clean constructor-based dependency injection
*/
import type { AnalyticsAdapter, AnalyticsEvent, AnalyticsConfig } from './interfaces';
import { PlausibleAdapter } from './plausible-adapter';
export class AnalyticsService {
private adapter: AnalyticsAdapter;
/**
* Create analytics service with dependency injection
* @param adapter - Analytics adapter implementation
*/
constructor(adapter: AnalyticsAdapter) {
this.adapter = adapter;
}
getAdapter(): AnalyticsAdapter {
return this.adapter;
}
async track(event: AnalyticsEvent): Promise<void> {
return this.adapter.track(event);
}
async page(path: string, props?: Record<string, any>): Promise<void> {
if (this.adapter.page) {
return this.adapter.page(path, props);
}
return this.track({ name: 'Pageview', props: { path, ...props } });
}
async identify(userId: string, traits?: Record<string, any>): Promise<void> {
if (this.adapter.identify) {
return this.adapter.identify(userId, traits);
}
}
// Convenience methods
async trackEvent(name: string, props?: Record<string, any>): Promise<void> {
return this.track({ name, props });
}
async trackOutboundLink(url: string, text: string): Promise<void> {
return this.track({
name: 'Outbound Link',
props: { url, text }
});
}
async trackSearch(query: string, path: string): Promise<void> {
return this.track({
name: 'Search',
props: { query, path }
});
}
async trackPageLoad(loadTime: number, path: string, userAgent: string): Promise<void> {
return this.track({
name: 'Page Load',
props: { loadTime: Math.round(loadTime), path, userAgent }
});
}
}
// Factory function
export function createPlausibleAnalytics(config: AnalyticsConfig): AnalyticsService {
return new AnalyticsService(new PlausibleAdapter(config));
}
// Default singleton
let defaultAnalytics: AnalyticsService | null = null;
export function getDefaultAnalytics(): AnalyticsService {
if (!defaultAnalytics) {
defaultAnalytics = createPlausibleAnalytics({
domain: 'mintel.me',
scriptUrl: 'https://plausible.yourdomain.com/js/script.js'
});
}
return defaultAnalytics;
}
// Convenience function
export async function track(name: string, props?: Record<string, any>): Promise<void> {
return getDefaultAnalytics().trackEvent(name, props);
}
// Re-export for advanced usage
export type { AnalyticsAdapter, AnalyticsEvent, AnalyticsConfig };
export { PlausibleAdapter };