/** * 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 { return this.adapter.track(event); } async page(path: string, props?: Record): Promise { if (this.adapter.page) { return this.adapter.page(path, props); } return this.track({ name: 'Pageview', props: { path, ...props } }); } async identify(userId: string, traits?: Record): Promise { if (this.adapter.identify) { return this.adapter.identify(userId, traits); } } // Convenience methods async trackEvent(name: string, props?: Record): Promise { return this.track({ name, props }); } async trackOutboundLink(url: string, text: string): Promise { return this.track({ name: 'Outbound Link', props: { url, text } }); } async trackSearch(query: string, path: string): Promise { return this.track({ name: 'Search', props: { query, path } }); } async trackPageLoad(loadTime: number, path: string, userAgent: string): Promise { 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): Promise { return getDefaultAnalytics().trackEvent(name, props); } // Re-export for advanced usage export type { AnalyticsAdapter, AnalyticsEvent, AnalyticsConfig }; export { PlausibleAdapter };