@od-oneapp/analytics 2026.2.1501-canary.1 → 2026.2.1701

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.
Files changed (65) hide show
  1. package/{ai-Co8hBoEj.mjs → ai-YMnynb-t.mjs} +2 -2
  2. package/{ai-Co8hBoEj.mjs.map → ai-YMnynb-t.mjs.map} +1 -1
  3. package/{client-C_4MPbIp.mjs → client-CcFTauAh.mjs} +1 -1
  4. package/{client-C_4MPbIp.mjs.map → client-CcFTauAh.mjs.map} +1 -1
  5. package/{client-BOIcr_5V.mjs → client-CeOLjbac.mjs} +1 -1
  6. package/{client-BOIcr_5V.mjs.map → client-CeOLjbac.mjs.map} +1 -1
  7. package/{client-BiJJm6CH.mjs → client-D339NFJS.mjs} +1 -1
  8. package/{client-BiJJm6CH.mjs.map → client-D339NFJS.mjs.map} +1 -1
  9. package/client-next.d.mts +7 -7
  10. package/client-next.mjs +10 -10
  11. package/client.d.mts +9 -9
  12. package/client.mjs +115 -7
  13. package/client.mjs.map +1 -1
  14. package/{config-BUMHyePt.d.mts → config-DPS6bSYo.d.mts} +2 -2
  15. package/{config-BUMHyePt.d.mts.map → config-DPS6bSYo.d.mts.map} +1 -1
  16. package/{config-6Mwe7b2O.mjs → config-P6P5adJg.mjs} +1 -1
  17. package/{config-6Mwe7b2O.mjs.map → config-P6P5adJg.mjs.map} +1 -1
  18. package/{ecommerce-DGG1FbiH.mjs → ecommerce-Cgu4wlux.mjs} +2 -2
  19. package/{ecommerce-DGG1FbiH.mjs.map → ecommerce-Cgu4wlux.mjs.map} +1 -1
  20. package/{emitters-BvEelkxS.mjs → emitters-6-nKo8i-.mjs} +1 -1
  21. package/{emitters-BvEelkxS.mjs.map → emitters-6-nKo8i-.mjs.map} +1 -1
  22. package/{emitters-BAXagFjt.d.mts → emitters-DldkVSPp.d.mts} +2 -2
  23. package/{emitters-BAXagFjt.d.mts.map → emitters-DldkVSPp.d.mts.map} +1 -1
  24. package/index-BfNWgfa5.d.mts +1494 -0
  25. package/index-BfNWgfa5.d.mts.map +1 -0
  26. package/{index-Cnz0VecZ.d.mts → index-BkIWe--N.d.mts} +2 -2
  27. package/{index-Cnz0VecZ.d.mts.map → index-BkIWe--N.d.mts.map} +1 -1
  28. package/{index-qlFPt3-1.d.mts → index-jPzXRn52.d.mts} +3 -3
  29. package/{index-qlFPt3-1.d.mts.map → index-jPzXRn52.d.mts.map} +1 -1
  30. package/{manager-B6kowr9x.d.mts → manager-DvRRjza6.d.mts} +9 -3
  31. package/{manager-B6kowr9x.d.mts.map → manager-DvRRjza6.d.mts.map} +1 -1
  32. package/package.json +7 -2
  33. package/{posthog-bootstrap-DDToYA4X.mjs → posthog-bootstrap-CYfIy_WS.mjs} +7 -6
  34. package/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
  35. package/{posthog-bootstrap-CRl1Pk_E.d.mts → posthog-bootstrap-DWxFrxlt.d.mts} +3 -3
  36. package/{posthog-bootstrap-CRl1Pk_E.d.mts.map → posthog-bootstrap-DWxFrxlt.d.mts.map} +1 -1
  37. package/providers-http-client.d.mts +1 -1
  38. package/providers-http-client.mjs +1 -1
  39. package/providers-http-server.d.mts +1 -1
  40. package/providers-http-server.mjs +1 -1
  41. package/server-edge.d.mts +3 -3
  42. package/server-edge.mjs +2 -2
  43. package/server-next.d.mts +11 -10
  44. package/server-next.d.mts.map +1 -1
  45. package/server-next.mjs +6 -6
  46. package/server.d.mts +10 -10
  47. package/server.mjs +6 -6
  48. package/service-Duqnlppl.mjs +1049 -0
  49. package/service-Duqnlppl.mjs.map +1 -0
  50. package/shared.d.mts +4 -4
  51. package/shared.mjs +3 -3
  52. package/{types-DnfdguWa.d.mts → types-BxBnNQ0V.d.mts} +1 -1
  53. package/{types-DnfdguWa.d.mts.map → types-BxBnNQ0V.d.mts.map} +1 -1
  54. package/{types-Brm88i6e.d.mts → types-CBvxUEaF.d.mts} +1 -1
  55. package/{types-Brm88i6e.d.mts.map → types-CBvxUEaF.d.mts.map} +1 -1
  56. package/types.d.mts +3 -3
  57. package/{vercel-types-Crq8m8c1.d.mts → vercel-types-lwakUfoI.d.mts} +1 -1
  58. package/{vercel-types-Crq8m8c1.d.mts.map → vercel-types-lwakUfoI.d.mts.map} +1 -1
  59. package/logs-B4zFs5kX.mjs +0 -108
  60. package/logs-B4zFs5kX.mjs.map +0 -1
  61. package/posthog-bootstrap-DDToYA4X.mjs.map +0 -1
  62. package/validation-DZc_nvoN.d.mts +0 -24
  63. package/validation-DZc_nvoN.d.mts.map +0 -1
  64. package/validation-Dll9R6h6.mjs +0 -315
  65. package/validation-Dll9R6h6.mjs.map +0 -1
@@ -51,4 +51,4 @@ var VercelClientProvider = class {
51
51
 
52
52
  //#endregion
53
53
  export { VercelClientProvider };
54
- //# sourceMappingURL=client-C_4MPbIp.mjs.map
54
+ //# sourceMappingURL=client-CcFTauAh.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-C_4MPbIp.mjs","names":[],"sources":["../src/providers/vercel/client.ts"],"sourcesContent":["/**\n * @fileoverview Vercel Analytics client-side (browser) provider implementation\n *\n * Provides client-side integration with Vercel Analytics for web analytics tracking.\n * Supports automatic page view tracking and custom event tracking.\n *\n * @remarks\n * This provider:\n * - Uses @vercel/analytics package for client-side tracking\n * - Supports dynamic imports to avoid SSR issues\n * - Handles initialization and event tracking\n * - Integrates with Vercel's analytics dashboard\n *\n * @module @repo/analytics/providers/vercel/client\n */\n\nimport type { VercelConfig } from './types';\nimport type { AnalyticsProvider, ProviderConfig } from '../../shared/types/types';\n\n// Vercel Analytics types are handled by @vercel/analytics package\n\nexport class VercelClientProvider implements AnalyticsProvider {\n readonly name = 'vercel';\n private config: VercelConfig;\n private isInitialized = false;\n\n constructor(config: ProviderConfig) {\n this.config = {\n options: config.options,\n };\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n // Dynamically import Vercel Analytics\n const { inject } = await import('@vercel/analytics');\n\n // Initialize Vercel Analytics\n inject(this.config.options);\n\n this.isInitialized = true;\n } catch {\n throw new Error(\n 'Vercel Analytics not available. Install with: npm install @vercel/analytics',\n );\n }\n }\n\n async track(event: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n try {\n // Import track function dynamically to avoid SSR issues\n const { track } = await import('@vercel/analytics');\n track(event, properties);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async identify(userId: string, traits: any = {}): Promise<void> {\n // Vercel Analytics doesn't have a native identify method\n // We can track this as a custom event\n await this.track('User Identified', {\n userId,\n ...traits,\n });\n }\n\n async page(name?: string, properties: any = {}): Promise<void> {\n // Vercel Analytics automatically tracks page views\n // We can track additional page data as custom events if needed\n if (name || Object.keys(properties).length > 0) {\n await this.track('Page View', {\n page: name,\n ...properties,\n });\n }\n }\n\n async group(groupId: string, traits: any = {}): Promise<void> {\n // Vercel Analytics doesn't have a native group method\n // We can track this as a custom event\n await this.track('Group Identified', {\n groupId,\n ...traits,\n });\n }\n\n async alias(userId: string, previousId: string): Promise<void> {\n // Vercel Analytics doesn't have a native alias method\n // We can track this as a custom event\n await this.track('User Aliased', {\n previousId,\n userId,\n });\n }\n}\n"],"mappings":";AAqBA,IAAa,uBAAb,MAA+D;CAC7D,AAAS,OAAO;CAChB,AAAQ;CACR,AAAQ,gBAAgB;CAExB,YAAY,QAAwB;AAClC,OAAK,SAAS,EACZ,SAAS,OAAO,SACjB;;CAGH,MAAM,aAA4B;AAChC,MAAI,KAAK,cAAe;AAExB,MAAI;GAEF,MAAM,EAAE,WAAW,MAAM,OAAO;AAGhC,UAAO,KAAK,OAAO,QAAQ;AAE3B,QAAK,gBAAgB;UACf;AACN,SAAM,IAAI,MACR,8EACD;;;CAIL,MAAM,MAAM,OAAe,aAAkB,EAAE,EAAiB;AAC9D,MAAI,CAAC,KAAK,cACR;AAGF,MAAI;GAEF,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,SAAM,OAAO,WAAW;UAClB;;CAKV,MAAM,SAAS,QAAgB,SAAc,EAAE,EAAiB;AAG9D,QAAM,KAAK,MAAM,mBAAmB;GAClC;GACA,GAAG;GACJ,CAAC;;CAGJ,MAAM,KAAK,MAAe,aAAkB,EAAE,EAAiB;AAG7D,MAAI,QAAQ,OAAO,KAAK,WAAW,CAAC,SAAS,EAC3C,OAAM,KAAK,MAAM,aAAa;GAC5B,MAAM;GACN,GAAG;GACJ,CAAC;;CAIN,MAAM,MAAM,SAAiB,SAAc,EAAE,EAAiB;AAG5D,QAAM,KAAK,MAAM,oBAAoB;GACnC;GACA,GAAG;GACJ,CAAC;;CAGJ,MAAM,MAAM,QAAgB,YAAmC;AAG7D,QAAM,KAAK,MAAM,gBAAgB;GAC/B;GACA;GACD,CAAC"}
1
+ {"version":3,"file":"client-CcFTauAh.mjs","names":[],"sources":["../src/providers/vercel/client.ts"],"sourcesContent":["/**\n * @fileoverview Vercel Analytics client-side (browser) provider implementation\n *\n * Provides client-side integration with Vercel Analytics for web analytics tracking.\n * Supports automatic page view tracking and custom event tracking.\n *\n * @remarks\n * This provider:\n * - Uses @vercel/analytics package for client-side tracking\n * - Supports dynamic imports to avoid SSR issues\n * - Handles initialization and event tracking\n * - Integrates with Vercel's analytics dashboard\n *\n * @module @repo/analytics/providers/vercel/client\n */\n\nimport type { VercelConfig } from './types';\nimport type { AnalyticsProvider, ProviderConfig } from '../../shared/types/types';\n\n// Vercel Analytics types are handled by @vercel/analytics package\n\nexport class VercelClientProvider implements AnalyticsProvider {\n readonly name = 'vercel';\n private config: VercelConfig;\n private isInitialized = false;\n\n constructor(config: ProviderConfig) {\n this.config = {\n options: config.options,\n };\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n // Dynamically import Vercel Analytics\n const { inject } = await import('@vercel/analytics');\n\n // Initialize Vercel Analytics\n inject(this.config.options);\n\n this.isInitialized = true;\n } catch {\n throw new Error(\n 'Vercel Analytics not available. Install with: npm install @vercel/analytics',\n );\n }\n }\n\n async track(event: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n try {\n // Import track function dynamically to avoid SSR issues\n const { track } = await import('@vercel/analytics');\n track(event, properties);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async identify(userId: string, traits: any = {}): Promise<void> {\n // Vercel Analytics doesn't have a native identify method\n // We can track this as a custom event\n await this.track('User Identified', {\n userId,\n ...traits,\n });\n }\n\n async page(name?: string, properties: any = {}): Promise<void> {\n // Vercel Analytics automatically tracks page views\n // We can track additional page data as custom events if needed\n if (name || Object.keys(properties).length > 0) {\n await this.track('Page View', {\n page: name,\n ...properties,\n });\n }\n }\n\n async group(groupId: string, traits: any = {}): Promise<void> {\n // Vercel Analytics doesn't have a native group method\n // We can track this as a custom event\n await this.track('Group Identified', {\n groupId,\n ...traits,\n });\n }\n\n async alias(userId: string, previousId: string): Promise<void> {\n // Vercel Analytics doesn't have a native alias method\n // We can track this as a custom event\n await this.track('User Aliased', {\n previousId,\n userId,\n });\n }\n}\n"],"mappings":";AAqBA,IAAa,uBAAb,MAA+D;CAC7D,AAAS,OAAO;CAChB,AAAQ;CACR,AAAQ,gBAAgB;CAExB,YAAY,QAAwB;AAClC,OAAK,SAAS,EACZ,SAAS,OAAO,SACjB;;CAGH,MAAM,aAA4B;AAChC,MAAI,KAAK,cAAe;AAExB,MAAI;GAEF,MAAM,EAAE,WAAW,MAAM,OAAO;AAGhC,UAAO,KAAK,OAAO,QAAQ;AAE3B,QAAK,gBAAgB;UACf;AACN,SAAM,IAAI,MACR,8EACD;;;CAIL,MAAM,MAAM,OAAe,aAAkB,EAAE,EAAiB;AAC9D,MAAI,CAAC,KAAK,cACR;AAGF,MAAI;GAEF,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,SAAM,OAAO,WAAW;UAClB;;CAKV,MAAM,SAAS,QAAgB,SAAc,EAAE,EAAiB;AAG9D,QAAM,KAAK,MAAM,mBAAmB;GAClC;GACA,GAAG;GACJ,CAAC;;CAGJ,MAAM,KAAK,MAAe,aAAkB,EAAE,EAAiB;AAG7D,MAAI,QAAQ,OAAO,KAAK,WAAW,CAAC,SAAS,EAC3C,OAAM,KAAK,MAAM,aAAa;GAC5B,MAAM;GACN,GAAG;GACJ,CAAC;;CAIN,MAAM,MAAM,SAAiB,SAAc,EAAE,EAAiB;AAG5D,QAAM,KAAK,MAAM,oBAAoB;GACnC;GACA,GAAG;GACJ,CAAC;;CAGJ,MAAM,MAAM,QAAgB,YAAmC;AAG7D,QAAM,KAAK,MAAM,gBAAgB;GAC/B;GACA;GACD,CAAC"}
@@ -278,4 +278,4 @@ var PostHogClientProvider = class {
278
278
 
279
279
  //#endregion
280
280
  export { PostHogClientProvider };
281
- //# sourceMappingURL=client-BOIcr_5V.mjs.map
281
+ //# sourceMappingURL=client-CeOLjbac.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-BOIcr_5V.mjs","names":[],"sources":["../src/providers/posthog/client.ts"],"sourcesContent":["/**\n * @fileoverview PostHog client-side (browser) provider implementation\n *\n * Provides client-side integration with PostHog Analytics including feature flags support.\n * Supports full PostHog tracking including capture, identify, reset, group, alias, and feature flags.\n *\n * @remarks\n * This provider:\n * - Uses PostHog JavaScript SDK for browser tracking\n * - Supports bootstrap data for SSR optimization\n * - Handles feature flags and experiments\n * - Integrates with PostHog's analytics dashboard\n *\n * @module @repo/analytics/providers/posthog/client\n */\n\n// Simple console fallbacks - observability integration can be added later\nimport type {\n BootstrapData,\n EnhancedPostHogProvider,\n ExperimentInfo,\n PostHogConfig,\n} from './types';\nimport type { AnalyticsProvider, ProviderConfig } from '../../shared/types/types';\nconst logDebug = (_message: string, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper debug logging via observability package\n};\nconst logError = (_message: string, _error?: Error, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper error logging via observability package\n};\nconst logWarn = (_message: string, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper error logging via observability package\n};\n\ndeclare global {\n interface Window {\n posthog?: {\n init: (apiKey: string, options?: any) => void;\n capture: (event: string, properties?: any) => void;\n identify: (userId: string, properties?: any) => void;\n reset: () => void;\n group: (groupType: string, groupKey: string, properties?: any) => void;\n alias: (alias: string) => void;\n people?: {\n set: (properties: any) => void;\n set_once: (properties: any) => void;\n };\n register: (properties: any) => void;\n\n // Feature flag methods\n isFeatureEnabled: (flag: string) => boolean;\n getFeatureFlag: (flag: string) => any;\n getFeatureFlagPayload: (flag: string) => any;\n getAllFlags: () => Record<string, any>;\n onFeatureFlags: (callback: (flags: string[], variants: Record<string, any>) => void) => void;\n\n // Experiment methods\n getActiveMatchingFeatureFlags: () => string[];\n\n // Utility methods\n get_distinct_id: () => string;\n shutdown: () => Promise<void>;\n };\n }\n}\n\nexport class PostHogClientProvider implements AnalyticsProvider, Partial<EnhancedPostHogProvider> {\n readonly name = 'posthog';\n private config: PostHogConfig;\n private isInitialized = false;\n private posthogInstance: any = null;\n private retryQueue: { method: string; args: any[] }[] = [];\n private isOnline = true;\n private debugMode = false;\n\n constructor(config: ProviderConfig) {\n if (!config.apiKey) {\n throw new Error('PostHog apiKey is required');\n }\n\n this.config = {\n apiKey: config.apiKey,\n options: config.options,\n };\n\n // Set up debug mode\n this.debugMode =\n config.options?.debug === true ||\n (typeof window !== 'undefined' && window.location.search.includes('debug=posthog'));\n\n // Monitor network status for retry queue\n if (typeof window !== 'undefined') {\n window.addEventListener('online', () => {\n this.isOnline = true;\n void this.flushRetryQueue();\n });\n\n window.addEventListener('offline', () => {\n this.isOnline = false;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n // Dynamically import PostHog (optional dependency)\n const { default: posthog } = await import('posthog-js');\n\n // Extract bootstrap data if provided\n const bootstrap = this.config.options?.bootstrap;\n\n // Initialize PostHog with enhanced options and all missing configurations\n const initOptions: any = {\n // Core PostHog configuration with PostHog recommended defaults\n api_host: 'https://app.posthog.com',\n capture_pageleave: true, // Important for engagement tracking\n capture_pageview: false, // We handle pageviews manually\n ui_host: 'https://app.posthog.com',\n\n opt_in_site_apps: false, // Conservative default\n // Privacy & GDPR compliance\n person_profiles: 'identified_only', // GDPR-friendly default\n respect_dnt: true, // Respect Do Not Track headers\n\n // Performance optimizations\n uuid_version: 'v7', // Better performance than v4\n batch_flush_interval_ms: 10000, // 10 second batching\n request_batching: true, // Batch requests for better performance\n\n // Session recording with safe defaults\n session_recording: {\n maskAllInputs: false,\n maskInputOptions: {\n email: false,\n number: false,\n password: true, // Always mask passwords\n text: false,\n },\n recordCanvas: false, // Performance consideration\n recordCrossOriginIframes: false, // Conservative default\n sampling: {\n minimumDurationMs: 1000, // Only record sessions > 1s\n sampleRate: 1, // Record all sessions by default\n },\n },\n\n // Debug mode\n debug: this.debugMode,\n\n // Apply user configuration (this will override defaults)\n ...this.config.options,\n\n // Add bootstrap data if available (must be last to not be overridden)\n ...(bootstrap && {\n bootstrap: {\n distinctID: bootstrap.distinctID,\n },\n }),\n };\n\n posthog.init(this.config.apiKey, initOptions);\n\n // Store instance references\n this.posthogInstance = posthog;\n window.posthog = posthog as any;\n\n this.isInitialized = true;\n } catch {\n throw new Error('PostHog JS SDK not available. Install with: npm install posthog-js');\n }\n }\n\n async track(event: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n await this.queueEvent('track', [event, properties]);\n return;\n }\n\n try {\n // Debug logging\n await this.log('Tracking event:', event, properties);\n\n // Validate properties in debug mode\n if (this.debugMode) {\n await this.validateEventProperties(event, properties);\n }\n\n this.posthogInstance.capture(event, properties);\n } catch (error) {\n // Queue event if offline\n if (!this.isOnline) {\n await this.queueEvent('track', [event, properties]);\n }\n\n // Enhanced error reporting\n await this.reportError(error, 'track', { event, properties });\n }\n }\n\n async identify(userId: string, traits: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.identify(userId, traits);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async page(name?: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.capture('$pageview', {\n $current_url: window.location.href,\n $title: name ?? document.title,\n ...properties,\n });\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async group(groupId: string, traits: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.group('company', groupId, traits);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async alias(userId: string, _previousId: string): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.alias(userId);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n // Feature Flag Methods\n async getAllFlags(userId?: string): Promise<Record<string, any>> {\n if (!this.isInitialized || !this.posthogInstance) {\n return {};\n }\n\n try {\n if (userId) {\n // If userId provided, identify first to ensure flags are for correct user\n await this.identify(userId);\n }\n\n return this.posthogInstance.getAllFlags() ?? {};\n } catch {\n return {};\n }\n }\n\n async getFeatureFlag(flag: string, userId?: string): Promise<any> {\n if (!this.isInitialized || !this.posthogInstance) {\n return false;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.getFeatureFlag(flag);\n } catch {\n return false;\n }\n }\n\n async isFeatureEnabled(flag: string, userId?: string): Promise<boolean> {\n if (!this.isInitialized || !this.posthogInstance) {\n return false;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.isFeatureEnabled(flag) ?? false;\n } catch {\n return false;\n }\n }\n\n async getFeatureFlagPayload(flag: string, userId?: string): Promise<any | null> {\n if (!this.isInitialized || !this.posthogInstance) {\n return null;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.getFeatureFlagPayload(flag) ?? null;\n } catch {\n return null;\n }\n }\n\n async getActiveExperiments(userId?: string): Promise<ExperimentInfo[]> {\n if (!this.isInitialized || !this.posthogInstance) {\n return [];\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n const activeFlags = this.posthogInstance.getActiveMatchingFeatureFlags() ?? [];\n return activeFlags.map((flag: string) => ({\n key: flag,\n payload: this.posthogInstance.getFeatureFlagPayload(flag),\n variant: this.posthogInstance.getFeatureFlag(flag),\n }));\n } catch {\n return [];\n }\n }\n\n // Bootstrap method (not typically used on client, but included for completeness)\n async getBootstrapData(distinctId: string): Promise<BootstrapData> {\n if (!this.isInitialized || !this.posthogInstance) {\n return { distinctID: distinctId };\n }\n\n try {\n await this.getAllFlags();\n\n return {\n distinctID: distinctId,\n };\n } catch {\n return { distinctID: distinctId };\n }\n }\n\n // Utility Methods\n reset(): void {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.reset();\n } catch {\n // Silently fail\n }\n }\n\n async shutdown(): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n if (this.posthogInstance.shutdown) {\n await this.posthogInstance.shutdown();\n }\n } catch {\n // Silently fail\n }\n }\n\n // Get distinct ID for bootstrap purposes\n getDistinctId(): string | null {\n if (!this.isInitialized || !this.posthogInstance) {\n return null;\n }\n\n try {\n return this.posthogInstance.get_distinct_id();\n } catch {\n return null;\n }\n }\n\n // Enhanced error handling and utility methods\n private async queueEvent(method: string, args: any[]) {\n this.retryQueue.push({ args, method });\n await this.log(`Queued ${method} event for retry: `, args);\n }\n\n private async flushRetryQueue() {\n await this.log(`Flushing retry queue with ${this.retryQueue.length} events`);\n\n while (this.retryQueue.length > 0) {\n const item = this.retryQueue.shift();\n if (!item) break;\n const { args, method } = item;\n try {\n await (this as any)[method](...args);\n } catch {\n // Re-queue failed events (limit retries)\n if (this.retryQueue.length < 100) {\n // Prevent infinite queue growth\n await this.queueEvent(method, args);\n }\n break;\n }\n }\n }\n\n private log(...args: any[]) {\n if (this.debugMode) {\n logDebug('PostHog Debug:', { args });\n }\n }\n\n private async validateEventProperties(event: string, properties: any) {\n // Check for reserved property names\n const reserved = new Set(['$set', '$set_once', '$unset', 'distinct_id', '$groups']);\n const conflicts = Object.keys(properties).filter(\n key => reserved.has(key) && !key.startsWith('$'),\n );\n\n if (conflicts.length > 0) {\n logWarn('PostHog: Properties may conflict with reserved names:', {\n conflicts: conflicts.join(', '),\n event,\n });\n }\n\n // Check for circular references\n try {\n JSON.stringify(properties);\n } catch (error) {\n logWarn('PostHog: Event properties contain circular references:', {\n event,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n private async reportError(error: any, method: string, context: any) {\n if (this.debugMode) {\n logError('PostHog Error:', error instanceof Error ? error : new Error(String(error)), {\n method,\n context,\n });\n }\n\n // Could emit error event to other analytics providers\n // this.emit('analytics_error', { provider: 'posthog', method, error: error.message, context });\n }\n\n // Consent management methods\n async optIn(): Promise<void> {\n if (this.posthogInstance) {\n this.posthogInstance.opt_in_capturing();\n await this.log('User opted in to tracking');\n }\n }\n\n async optOut(): Promise<void> {\n if (this.posthogInstance) {\n this.posthogInstance.opt_out_capturing();\n await this.log('User opted out of tracking');\n }\n }\n\n hasOptedOut(): boolean {\n return this.posthogInstance ? this.posthogInstance.has_opted_out_capturing() : false;\n }\n\n // Enhanced group analytics\n async groupIdentify(\n groupType: string,\n groupKey: string,\n groupProperties: any,\n options?: { setAsDefault?: boolean },\n ): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n await this.log('Group identify:', groupType, groupKey, groupProperties);\n\n // Set group properties\n this.posthogInstance.group(groupType, groupKey, groupProperties);\n\n // Optionally set as default group for user\n if (options?.setAsDefault) {\n this.posthogInstance.register({\n [`$groups`]: {\n [groupType]: groupKey,\n },\n });\n }\n } catch (error) {\n await this.reportError(error, 'groupIdentify', { groupKey, groupProperties, groupType });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client-CeOLjbac.mjs","names":[],"sources":["../src/providers/posthog/client.ts"],"sourcesContent":["/**\n * @fileoverview PostHog client-side (browser) provider implementation\n *\n * Provides client-side integration with PostHog Analytics including feature flags support.\n * Supports full PostHog tracking including capture, identify, reset, group, alias, and feature flags.\n *\n * @remarks\n * This provider:\n * - Uses PostHog JavaScript SDK for browser tracking\n * - Supports bootstrap data for SSR optimization\n * - Handles feature flags and experiments\n * - Integrates with PostHog's analytics dashboard\n *\n * @module @repo/analytics/providers/posthog/client\n */\n\n// Simple console fallbacks - observability integration can be added later\nimport type {\n BootstrapData,\n EnhancedPostHogProvider,\n ExperimentInfo,\n PostHogConfig,\n} from './types';\nimport type { AnalyticsProvider, ProviderConfig } from '../../shared/types/types';\nconst logDebug = (_message: string, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper debug logging via observability package\n};\nconst logError = (_message: string, _error?: Error, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper error logging via observability package\n};\nconst logWarn = (_message: string, _context?: any) => {\n // No-op to avoid console warnings in production\n // TODO: Add proper error logging via observability package\n};\n\ndeclare global {\n interface Window {\n posthog?: {\n init: (apiKey: string, options?: any) => void;\n capture: (event: string, properties?: any) => void;\n identify: (userId: string, properties?: any) => void;\n reset: () => void;\n group: (groupType: string, groupKey: string, properties?: any) => void;\n alias: (alias: string) => void;\n people?: {\n set: (properties: any) => void;\n set_once: (properties: any) => void;\n };\n register: (properties: any) => void;\n\n // Feature flag methods\n isFeatureEnabled: (flag: string) => boolean;\n getFeatureFlag: (flag: string) => any;\n getFeatureFlagPayload: (flag: string) => any;\n getAllFlags: () => Record<string, any>;\n onFeatureFlags: (callback: (flags: string[], variants: Record<string, any>) => void) => void;\n\n // Experiment methods\n getActiveMatchingFeatureFlags: () => string[];\n\n // Utility methods\n get_distinct_id: () => string;\n shutdown: () => Promise<void>;\n };\n }\n}\n\nexport class PostHogClientProvider implements AnalyticsProvider, Partial<EnhancedPostHogProvider> {\n readonly name = 'posthog';\n private config: PostHogConfig;\n private isInitialized = false;\n private posthogInstance: any = null;\n private retryQueue: { method: string; args: any[] }[] = [];\n private isOnline = true;\n private debugMode = false;\n\n constructor(config: ProviderConfig) {\n if (!config.apiKey) {\n throw new Error('PostHog apiKey is required');\n }\n\n this.config = {\n apiKey: config.apiKey,\n options: config.options,\n };\n\n // Set up debug mode\n this.debugMode =\n config.options?.debug === true ||\n (typeof window !== 'undefined' && window.location.search.includes('debug=posthog'));\n\n // Monitor network status for retry queue\n if (typeof window !== 'undefined') {\n window.addEventListener('online', () => {\n this.isOnline = true;\n void this.flushRetryQueue();\n });\n\n window.addEventListener('offline', () => {\n this.isOnline = false;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n // Dynamically import PostHog (optional dependency)\n const { default: posthog } = await import('posthog-js');\n\n // Extract bootstrap data if provided\n const bootstrap = this.config.options?.bootstrap;\n\n // Initialize PostHog with enhanced options and all missing configurations\n const initOptions: any = {\n // Core PostHog configuration with PostHog recommended defaults\n api_host: 'https://app.posthog.com',\n capture_pageleave: true, // Important for engagement tracking\n capture_pageview: false, // We handle pageviews manually\n ui_host: 'https://app.posthog.com',\n\n opt_in_site_apps: false, // Conservative default\n // Privacy & GDPR compliance\n person_profiles: 'identified_only', // GDPR-friendly default\n respect_dnt: true, // Respect Do Not Track headers\n\n // Performance optimizations\n uuid_version: 'v7', // Better performance than v4\n batch_flush_interval_ms: 10000, // 10 second batching\n request_batching: true, // Batch requests for better performance\n\n // Session recording with safe defaults\n session_recording: {\n maskAllInputs: false,\n maskInputOptions: {\n email: false,\n number: false,\n password: true, // Always mask passwords\n text: false,\n },\n recordCanvas: false, // Performance consideration\n recordCrossOriginIframes: false, // Conservative default\n sampling: {\n minimumDurationMs: 1000, // Only record sessions > 1s\n sampleRate: 1, // Record all sessions by default\n },\n },\n\n // Debug mode\n debug: this.debugMode,\n\n // Apply user configuration (this will override defaults)\n ...this.config.options,\n\n // Add bootstrap data if available (must be last to not be overridden)\n ...(bootstrap && {\n bootstrap: {\n distinctID: bootstrap.distinctID,\n },\n }),\n };\n\n posthog.init(this.config.apiKey, initOptions);\n\n // Store instance references\n this.posthogInstance = posthog;\n window.posthog = posthog as any;\n\n this.isInitialized = true;\n } catch {\n throw new Error('PostHog JS SDK not available. Install with: npm install posthog-js');\n }\n }\n\n async track(event: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n await this.queueEvent('track', [event, properties]);\n return;\n }\n\n try {\n // Debug logging\n await this.log('Tracking event:', event, properties);\n\n // Validate properties in debug mode\n if (this.debugMode) {\n await this.validateEventProperties(event, properties);\n }\n\n this.posthogInstance.capture(event, properties);\n } catch (error) {\n // Queue event if offline\n if (!this.isOnline) {\n await this.queueEvent('track', [event, properties]);\n }\n\n // Enhanced error reporting\n await this.reportError(error, 'track', { event, properties });\n }\n }\n\n async identify(userId: string, traits: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.identify(userId, traits);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async page(name?: string, properties: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.capture('$pageview', {\n $current_url: window.location.href,\n $title: name ?? document.title,\n ...properties,\n });\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async group(groupId: string, traits: any = {}): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.group('company', groupId, traits);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async alias(userId: string, _previousId: string): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.alias(userId);\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n // Feature Flag Methods\n async getAllFlags(userId?: string): Promise<Record<string, any>> {\n if (!this.isInitialized || !this.posthogInstance) {\n return {};\n }\n\n try {\n if (userId) {\n // If userId provided, identify first to ensure flags are for correct user\n await this.identify(userId);\n }\n\n return this.posthogInstance.getAllFlags() ?? {};\n } catch {\n return {};\n }\n }\n\n async getFeatureFlag(flag: string, userId?: string): Promise<any> {\n if (!this.isInitialized || !this.posthogInstance) {\n return false;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.getFeatureFlag(flag);\n } catch {\n return false;\n }\n }\n\n async isFeatureEnabled(flag: string, userId?: string): Promise<boolean> {\n if (!this.isInitialized || !this.posthogInstance) {\n return false;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.isFeatureEnabled(flag) ?? false;\n } catch {\n return false;\n }\n }\n\n async getFeatureFlagPayload(flag: string, userId?: string): Promise<any | null> {\n if (!this.isInitialized || !this.posthogInstance) {\n return null;\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n return this.posthogInstance.getFeatureFlagPayload(flag) ?? null;\n } catch {\n return null;\n }\n }\n\n async getActiveExperiments(userId?: string): Promise<ExperimentInfo[]> {\n if (!this.isInitialized || !this.posthogInstance) {\n return [];\n }\n\n try {\n if (userId) {\n await this.identify(userId);\n }\n\n const activeFlags = this.posthogInstance.getActiveMatchingFeatureFlags() ?? [];\n return activeFlags.map((flag: string) => ({\n key: flag,\n payload: this.posthogInstance.getFeatureFlagPayload(flag),\n variant: this.posthogInstance.getFeatureFlag(flag),\n }));\n } catch {\n return [];\n }\n }\n\n // Bootstrap method (not typically used on client, but included for completeness)\n async getBootstrapData(distinctId: string): Promise<BootstrapData> {\n if (!this.isInitialized || !this.posthogInstance) {\n return { distinctID: distinctId };\n }\n\n try {\n await this.getAllFlags();\n\n return {\n distinctID: distinctId,\n };\n } catch {\n return { distinctID: distinctId };\n }\n }\n\n // Utility Methods\n reset(): void {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n this.posthogInstance.reset();\n } catch {\n // Silently fail\n }\n }\n\n async shutdown(): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n if (this.posthogInstance.shutdown) {\n await this.posthogInstance.shutdown();\n }\n } catch {\n // Silently fail\n }\n }\n\n // Get distinct ID for bootstrap purposes\n getDistinctId(): string | null {\n if (!this.isInitialized || !this.posthogInstance) {\n return null;\n }\n\n try {\n return this.posthogInstance.get_distinct_id();\n } catch {\n return null;\n }\n }\n\n // Enhanced error handling and utility methods\n private async queueEvent(method: string, args: any[]) {\n this.retryQueue.push({ args, method });\n await this.log(`Queued ${method} event for retry: `, args);\n }\n\n private async flushRetryQueue() {\n await this.log(`Flushing retry queue with ${this.retryQueue.length} events`);\n\n while (this.retryQueue.length > 0) {\n const item = this.retryQueue.shift();\n if (!item) break;\n const { args, method } = item;\n try {\n await (this as any)[method](...args);\n } catch {\n // Re-queue failed events (limit retries)\n if (this.retryQueue.length < 100) {\n // Prevent infinite queue growth\n await this.queueEvent(method, args);\n }\n break;\n }\n }\n }\n\n private log(...args: any[]) {\n if (this.debugMode) {\n logDebug('PostHog Debug:', { args });\n }\n }\n\n private async validateEventProperties(event: string, properties: any) {\n // Check for reserved property names\n const reserved = new Set(['$set', '$set_once', '$unset', 'distinct_id', '$groups']);\n const conflicts = Object.keys(properties).filter(\n key => reserved.has(key) && !key.startsWith('$'),\n );\n\n if (conflicts.length > 0) {\n logWarn('PostHog: Properties may conflict with reserved names:', {\n conflicts: conflicts.join(', '),\n event,\n });\n }\n\n // Check for circular references\n try {\n JSON.stringify(properties);\n } catch (error) {\n logWarn('PostHog: Event properties contain circular references:', {\n event,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n private async reportError(error: any, method: string, context: any) {\n if (this.debugMode) {\n logError('PostHog Error:', error instanceof Error ? error : new Error(String(error)), {\n method,\n context,\n });\n }\n\n // Could emit error event to other analytics providers\n // this.emit('analytics_error', { provider: 'posthog', method, error: error.message, context });\n }\n\n // Consent management methods\n async optIn(): Promise<void> {\n if (this.posthogInstance) {\n this.posthogInstance.opt_in_capturing();\n await this.log('User opted in to tracking');\n }\n }\n\n async optOut(): Promise<void> {\n if (this.posthogInstance) {\n this.posthogInstance.opt_out_capturing();\n await this.log('User opted out of tracking');\n }\n }\n\n hasOptedOut(): boolean {\n return this.posthogInstance ? this.posthogInstance.has_opted_out_capturing() : false;\n }\n\n // Enhanced group analytics\n async groupIdentify(\n groupType: string,\n groupKey: string,\n groupProperties: any,\n options?: { setAsDefault?: boolean },\n ): Promise<void> {\n if (!this.isInitialized || !this.posthogInstance) {\n return;\n }\n\n try {\n await this.log('Group identify:', groupType, groupKey, groupProperties);\n\n // Set group properties\n this.posthogInstance.group(groupType, groupKey, groupProperties);\n\n // Optionally set as default group for user\n if (options?.setAsDefault) {\n this.posthogInstance.register({\n [`$groups`]: {\n [groupType]: groupKey,\n },\n });\n }\n } catch (error) {\n await this.reportError(error, 'groupIdentify', { groupKey, groupProperties, groupType });\n }\n }\n}\n"],"mappings":"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"}
@@ -264,4 +264,4 @@ var SegmentClientProvider = class extends BaseAnalyticsProvider {
264
264
 
265
265
  //#endregion
266
266
  export { SegmentClientProvider };
267
- //# sourceMappingURL=client-BiJJm6CH.mjs.map
267
+ //# sourceMappingURL=client-D339NFJS.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-BiJJm6CH.mjs","names":[],"sources":["../src/providers/base-provider.ts","../src/providers/segment/client.ts"],"sourcesContent":["/**\n * @fileoverview Base Analytics Provider\n *\n * Abstract base class that implements common provider patterns:\n * - Initialization state management\n * - Safe method execution with error handling\n * - Consistent interface implementation\n * - Error handling and logging\n *\n * **Provider Development**: Providers should extend this class and implement\n * the abstract methods (`doInitialize`, `doTrack`, `doIdentify`, etc.).\n *\n * **Benefits**:\n * - Consistent error handling across all providers\n * - Initialization state management\n * - Safe method execution (checks initialization before calling)\n * - Error callbacks for logging/reporting\n *\n * @module @od-oneapp/analytics/providers/base-provider\n */\n\nimport type {\n AnalyticsContext,\n AnalyticsProvider,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n UserTraits,\n} from '../shared/types/types';\n\n/**\n * Error handler type for provider operations.\n *\n * Called when an error occurs during provider operations. Receives the error\n * and context about which provider and method failed.\n *\n * @param {unknown} error - The error that occurred\n * @param {object} context - Context about the error (provider name, method name, metadata)\n */\nexport type ProviderErrorHandler = (\n error: unknown,\n context: {\n provider: string;\n method: string;\n [key: string]: unknown;\n },\n) => void;\n\n/**\n * Base configuration for all providers.\n *\n * Common configuration options that all providers support.\n */\nexport interface BaseProviderConfig {\n /** Error handler callback */\n onError?: ProviderErrorHandler;\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Abstract base class for analytics providers\n *\n * @example\n * ```typescript\n * class MyProvider extends BaseAnalyticsProvider<MyConfig> {\n * readonly name = 'my-provider';\n *\n * protected async doInitialize(): Promise<void> {\n * // Load SDK and set up client\n * }\n *\n * protected async doTrack(event: string, properties: Properties): Promise<void> {\n * // Call SDK track method\n * }\n *\n * // ... implement other abstract methods\n * }\n * ```\n */\nexport abstract class BaseAnalyticsProvider<\n TConfig extends BaseProviderConfig = BaseProviderConfig,\n> implements AnalyticsProvider {\n /** Provider name used for identification and logging */\n abstract readonly name: string;\n\n /** Provider-specific configuration */\n protected config: TConfig;\n\n /** Whether the provider has been initialized */\n protected isInitialized = false;\n\n /** Error handler for logging/reporting errors */\n protected onError?: ProviderErrorHandler | undefined;\n\n constructor(config: ProviderConfig, defaultConfig: Partial<TConfig> = {}) {\n this.config = {\n ...defaultConfig,\n ...config,\n ...(config.options as Partial<TConfig>),\n } as TConfig;\n this.onError = this.config.onError ?? undefined;\n }\n\n /**\n * Initialize the provider.\n *\n * This is called by the analytics manager before any tracking calls.\n * Calls the abstract `doInitialize()` method and handles errors.\n *\n * @param {ProviderConfig} [config] - Optional provider configuration\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n * @throws {Error} If initialization fails\n */\n async initialize(config?: ProviderConfig): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n await this.doInitialize(config);\n this.isInitialized = true;\n } catch (error) {\n this.handleError(error, 'initialize');\n throw error; // Re-throw to let manager know initialization failed\n }\n }\n\n /**\n * Track an event.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doTrack()` method. Handles errors gracefully without throwing.\n *\n * @param {string} event - Event name\n * @param {Properties} [properties] - Event properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when tracking is complete\n */\n async track(\n event: string,\n properties: Properties = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'track', { event });\n return;\n }\n\n try {\n await this.doTrack(event, properties, context);\n } catch (error) {\n this.handleError(error, 'track', { event, properties });\n }\n }\n\n /**\n * Identify a user.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doIdentify()` method. Handles errors gracefully without throwing.\n *\n * @param {string} userId - User identifier\n * @param {UserTraits} [traits] - User traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when identification is complete\n */\n async identify(\n userId: string,\n traits: UserTraits = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'identify', { userId });\n return;\n }\n\n try {\n await this.doIdentify(userId, traits, context);\n } catch (error) {\n this.handleError(error, 'identify', { userId });\n }\n }\n\n /**\n * Track a page view.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doPage()` method. Handles errors gracefully.\n *\n * @param {string} [name] - Page name\n * @param {PageProperties} [properties] - Page properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when page tracking is complete\n */\n async page(\n name?: string,\n properties: PageProperties = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'page', { name });\n return;\n }\n\n try {\n await this.doPage(name, properties, context);\n } catch (error) {\n this.handleError(error, 'page', { name });\n }\n }\n\n /**\n * Associate user with a group.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doGroup()` method. Handles errors gracefully.\n *\n * @param {string} groupId - Group identifier\n * @param {GroupTraits} [traits] - Group traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when group association is complete\n */\n async group(\n groupId: string,\n traits: GroupTraits = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'group', { groupId });\n return;\n }\n\n try {\n await this.doGroup(groupId, traits, context);\n } catch (error) {\n this.handleError(error, 'group', { groupId });\n }\n }\n\n /**\n * Alias one user ID to another.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doAlias()` method. Handles errors gracefully.\n *\n * @param {string} userId - New user identifier\n * @param {string} previousId - Previous user identifier\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when aliasing is complete\n */\n async alias(userId: string, previousId: string, context?: AnalyticsContext): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'alias', { userId, previousId });\n return;\n }\n\n try {\n await this.doAlias(userId, previousId, context);\n } catch (error) {\n this.handleError(error, 'alias', { userId, previousId });\n }\n }\n\n /**\n * Set global context for the provider\n */\n setContext?(context: AnalyticsContext): void;\n\n /**\n * Handle errors consistently across all methods.\n *\n * Calls the error handler callback if configured. Errors are swallowed\n * in production to not disrupt app flow, but logged via callback.\n *\n * @param {unknown} error - The error that occurred\n * @param {string} method - Method name where error occurred\n * @param {Record<string, unknown>} [metadata] - Additional error metadata\n *\n * @internal\n */\n protected handleError(error: unknown, method: string, metadata?: Record<string, unknown>): void {\n if (this.onError) {\n this.onError(error, {\n provider: this.name,\n method,\n ...metadata,\n });\n }\n // In production, errors are swallowed to not disrupt app flow\n // Logging happens via onError callback if provided\n }\n\n /**\n * Check if provider is ready to accept tracking calls.\n *\n * @returns {boolean} `true` if provider is initialized and ready, `false` otherwise\n */\n isReady(): boolean {\n return this.isInitialized;\n }\n\n // ============================================================================\n // ABSTRACT METHODS - Must be implemented by subclasses\n // ============================================================================\n\n /**\n * Perform provider-specific initialization.\n *\n * Called by `initialize()` after checking `isInitialized` flag.\n * Subclasses must implement this to perform actual provider initialization.\n *\n * @param {ProviderConfig} [config] - Optional provider configuration\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doInitialize(config?: ProviderConfig): Promise<void>;\n\n /**\n * Perform provider-specific track call.\n *\n * Called by `track()` after validation. Subclasses must implement this\n * to perform actual event tracking.\n *\n * @param {string} event - Event name\n * @param {Properties} properties - Event properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when tracking is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doTrack(\n event: string,\n properties: Properties,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific identify call.\n *\n * Called by `identify()` after validation. Subclasses must implement this\n * to perform actual user identification.\n *\n * @param {string} userId - User identifier\n * @param {UserTraits} traits - User traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when identification is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doIdentify(\n userId: string,\n traits: UserTraits,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific page call.\n *\n * Called by `page()` after validation. Subclasses must implement this\n * to perform actual page view tracking.\n *\n * @param {string | undefined} name - Page name\n * @param {PageProperties} properties - Page properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when page tracking is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doPage(\n name: string | undefined,\n properties: PageProperties,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific group call.\n *\n * Called by `group()` after validation. Subclasses must implement this\n * to perform actual group association.\n *\n * @param {string} groupId - Group identifier\n * @param {GroupTraits} traits - Group traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when group association is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doGroup(\n groupId: string,\n traits: GroupTraits,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific alias call.\n *\n * Called by `alias()` after validation. Subclasses must implement this\n * to perform actual user ID aliasing.\n *\n * @param {string} userId - New user identifier\n * @param {string} previousId - Previous user identifier\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when aliasing is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doAlias(\n userId: string,\n previousId: string,\n context?: AnalyticsContext,\n ): Promise<void>;\n}\n","/**\n * @fileoverview Segment client-side (browser) provider implementation\n *\n * Provides client-side integration with Segment Analytics using @segment/analytics-next.\n * Supports full Segment.io spec tracking including track, identify, page, group, and alias.\n *\n * @remarks\n * This provider:\n * - Uses @segment/analytics-next for browser tracking\n * - Supports dynamic imports to avoid SSR issues\n * - Handles initialization and event tracking\n * - Integrates with Segment's CDN and API\n *\n * @module @repo/analytics/providers/segment/client\n */\n\nimport { BaseAnalyticsProvider } from '../base-provider';\n\nimport type { SegmentConfig } from './types';\nimport type {\n AnalyticsContext,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n UserTraits,\n} from '../../shared/types/types';\n\n// Type for AnalyticsBrowser instance\ninterface AnalyticsBrowserInstance {\n track: (event: string, properties?: Properties) => Promise<unknown>;\n identify: (userId: string, traits?: UserTraits) => Promise<unknown>;\n page: (name?: string, properties?: PageProperties) => Promise<unknown>;\n group: (groupId: string, traits?: GroupTraits) => Promise<unknown>;\n alias: (userId: string, previousId: string) => Promise<unknown>;\n}\n\nexport class SegmentClientProvider extends BaseAnalyticsProvider<SegmentConfig> {\n readonly name = 'segment';\n private analytics: AnalyticsBrowserInstance | null = null;\n\n constructor(config: ProviderConfig) {\n super(config);\n\n if (!config.writeKey) {\n throw new Error('Segment writeKey is required');\n }\n\n this.config = {\n options: config.options as Record<string, unknown>,\n writeKey: config.writeKey,\n };\n }\n\n protected async doInitialize(): Promise<void> {\n // Dynamically import Segment Analytics Next\n const { AnalyticsBrowser } = await import(\n /* webpackChunkName: \"segment-analytics-browser\" */\n '@segment/analytics-next'\n );\n\n // Initialize Analytics Browser\n this.analytics = AnalyticsBrowser.load({\n writeKey: this.config.writeKey,\n ...this.config.options,\n }) as unknown as AnalyticsBrowserInstance;\n }\n\n protected async doTrack(\n event: string,\n properties: Properties,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.track(event, properties);\n }\n\n protected async doIdentify(\n userId: string,\n traits: UserTraits,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.identify(userId, traits);\n }\n\n protected async doPage(\n name: string | undefined,\n properties: PageProperties,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.page(name, properties);\n }\n\n protected async doGroup(\n groupId: string,\n traits: GroupTraits,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.group(groupId, traits);\n }\n\n protected async doAlias(\n userId: string,\n previousId: string,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.alias(userId, previousId);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client-D339NFJS.mjs","names":[],"sources":["../src/providers/base-provider.ts","../src/providers/segment/client.ts"],"sourcesContent":["/**\n * @fileoverview Base Analytics Provider\n *\n * Abstract base class that implements common provider patterns:\n * - Initialization state management\n * - Safe method execution with error handling\n * - Consistent interface implementation\n * - Error handling and logging\n *\n * **Provider Development**: Providers should extend this class and implement\n * the abstract methods (`doInitialize`, `doTrack`, `doIdentify`, etc.).\n *\n * **Benefits**:\n * - Consistent error handling across all providers\n * - Initialization state management\n * - Safe method execution (checks initialization before calling)\n * - Error callbacks for logging/reporting\n *\n * @module @od-oneapp/analytics/providers/base-provider\n */\n\nimport type {\n AnalyticsContext,\n AnalyticsProvider,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n UserTraits,\n} from '../shared/types/types';\n\n/**\n * Error handler type for provider operations.\n *\n * Called when an error occurs during provider operations. Receives the error\n * and context about which provider and method failed.\n *\n * @param {unknown} error - The error that occurred\n * @param {object} context - Context about the error (provider name, method name, metadata)\n */\nexport type ProviderErrorHandler = (\n error: unknown,\n context: {\n provider: string;\n method: string;\n [key: string]: unknown;\n },\n) => void;\n\n/**\n * Base configuration for all providers.\n *\n * Common configuration options that all providers support.\n */\nexport interface BaseProviderConfig {\n /** Error handler callback */\n onError?: ProviderErrorHandler;\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Abstract base class for analytics providers\n *\n * @example\n * ```typescript\n * class MyProvider extends BaseAnalyticsProvider<MyConfig> {\n * readonly name = 'my-provider';\n *\n * protected async doInitialize(): Promise<void> {\n * // Load SDK and set up client\n * }\n *\n * protected async doTrack(event: string, properties: Properties): Promise<void> {\n * // Call SDK track method\n * }\n *\n * // ... implement other abstract methods\n * }\n * ```\n */\nexport abstract class BaseAnalyticsProvider<\n TConfig extends BaseProviderConfig = BaseProviderConfig,\n> implements AnalyticsProvider {\n /** Provider name used for identification and logging */\n abstract readonly name: string;\n\n /** Provider-specific configuration */\n protected config: TConfig;\n\n /** Whether the provider has been initialized */\n protected isInitialized = false;\n\n /** Error handler for logging/reporting errors */\n protected onError?: ProviderErrorHandler | undefined;\n\n constructor(config: ProviderConfig, defaultConfig: Partial<TConfig> = {}) {\n this.config = {\n ...defaultConfig,\n ...config,\n ...(config.options as Partial<TConfig>),\n } as TConfig;\n this.onError = this.config.onError ?? undefined;\n }\n\n /**\n * Initialize the provider.\n *\n * This is called by the analytics manager before any tracking calls.\n * Calls the abstract `doInitialize()` method and handles errors.\n *\n * @param {ProviderConfig} [config] - Optional provider configuration\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n * @throws {Error} If initialization fails\n */\n async initialize(config?: ProviderConfig): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n await this.doInitialize(config);\n this.isInitialized = true;\n } catch (error) {\n this.handleError(error, 'initialize');\n throw error; // Re-throw to let manager know initialization failed\n }\n }\n\n /**\n * Track an event.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doTrack()` method. Handles errors gracefully without throwing.\n *\n * @param {string} event - Event name\n * @param {Properties} [properties] - Event properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when tracking is complete\n */\n async track(\n event: string,\n properties: Properties = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'track', { event });\n return;\n }\n\n try {\n await this.doTrack(event, properties, context);\n } catch (error) {\n this.handleError(error, 'track', { event, properties });\n }\n }\n\n /**\n * Identify a user.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doIdentify()` method. Handles errors gracefully without throwing.\n *\n * @param {string} userId - User identifier\n * @param {UserTraits} [traits] - User traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when identification is complete\n */\n async identify(\n userId: string,\n traits: UserTraits = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'identify', { userId });\n return;\n }\n\n try {\n await this.doIdentify(userId, traits, context);\n } catch (error) {\n this.handleError(error, 'identify', { userId });\n }\n }\n\n /**\n * Track a page view.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doPage()` method. Handles errors gracefully.\n *\n * @param {string} [name] - Page name\n * @param {PageProperties} [properties] - Page properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when page tracking is complete\n */\n async page(\n name?: string,\n properties: PageProperties = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'page', { name });\n return;\n }\n\n try {\n await this.doPage(name, properties, context);\n } catch (error) {\n this.handleError(error, 'page', { name });\n }\n }\n\n /**\n * Associate user with a group.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doGroup()` method. Handles errors gracefully.\n *\n * @param {string} groupId - Group identifier\n * @param {GroupTraits} [traits] - Group traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when group association is complete\n */\n async group(\n groupId: string,\n traits: GroupTraits = {},\n context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'group', { groupId });\n return;\n }\n\n try {\n await this.doGroup(groupId, traits, context);\n } catch (error) {\n this.handleError(error, 'group', { groupId });\n }\n }\n\n /**\n * Alias one user ID to another.\n *\n * Validates that the provider is initialized, then calls the abstract\n * `doAlias()` method. Handles errors gracefully.\n *\n * @param {string} userId - New user identifier\n * @param {string} previousId - Previous user identifier\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when aliasing is complete\n */\n async alias(userId: string, previousId: string, context?: AnalyticsContext): Promise<void> {\n if (!this.isInitialized) {\n this.handleError(new Error('Provider not initialized'), 'alias', { userId, previousId });\n return;\n }\n\n try {\n await this.doAlias(userId, previousId, context);\n } catch (error) {\n this.handleError(error, 'alias', { userId, previousId });\n }\n }\n\n /**\n * Set global context for the provider\n */\n setContext?(context: AnalyticsContext): void;\n\n /**\n * Handle errors consistently across all methods.\n *\n * Calls the error handler callback if configured. Errors are swallowed\n * in production to not disrupt app flow, but logged via callback.\n *\n * @param {unknown} error - The error that occurred\n * @param {string} method - Method name where error occurred\n * @param {Record<string, unknown>} [metadata] - Additional error metadata\n *\n * @internal\n */\n protected handleError(error: unknown, method: string, metadata?: Record<string, unknown>): void {\n if (this.onError) {\n this.onError(error, {\n provider: this.name,\n method,\n ...metadata,\n });\n }\n // In production, errors are swallowed to not disrupt app flow\n // Logging happens via onError callback if provided\n }\n\n /**\n * Check if provider is ready to accept tracking calls.\n *\n * @returns {boolean} `true` if provider is initialized and ready, `false` otherwise\n */\n isReady(): boolean {\n return this.isInitialized;\n }\n\n // ============================================================================\n // ABSTRACT METHODS - Must be implemented by subclasses\n // ============================================================================\n\n /**\n * Perform provider-specific initialization.\n *\n * Called by `initialize()` after checking `isInitialized` flag.\n * Subclasses must implement this to perform actual provider initialization.\n *\n * @param {ProviderConfig} [config] - Optional provider configuration\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doInitialize(config?: ProviderConfig): Promise<void>;\n\n /**\n * Perform provider-specific track call.\n *\n * Called by `track()` after validation. Subclasses must implement this\n * to perform actual event tracking.\n *\n * @param {string} event - Event name\n * @param {Properties} properties - Event properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when tracking is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doTrack(\n event: string,\n properties: Properties,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific identify call.\n *\n * Called by `identify()` after validation. Subclasses must implement this\n * to perform actual user identification.\n *\n * @param {string} userId - User identifier\n * @param {UserTraits} traits - User traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when identification is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doIdentify(\n userId: string,\n traits: UserTraits,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific page call.\n *\n * Called by `page()` after validation. Subclasses must implement this\n * to perform actual page view tracking.\n *\n * @param {string | undefined} name - Page name\n * @param {PageProperties} properties - Page properties\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when page tracking is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doPage(\n name: string | undefined,\n properties: PageProperties,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific group call.\n *\n * Called by `group()` after validation. Subclasses must implement this\n * to perform actual group association.\n *\n * @param {string} groupId - Group identifier\n * @param {GroupTraits} traits - Group traits\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when group association is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doGroup(\n groupId: string,\n traits: GroupTraits,\n context?: AnalyticsContext,\n ): Promise<void>;\n\n /**\n * Perform provider-specific alias call.\n *\n * Called by `alias()` after validation. Subclasses must implement this\n * to perform actual user ID aliasing.\n *\n * @param {string} userId - New user identifier\n * @param {string} previousId - Previous user identifier\n * @param {AnalyticsContext} [context] - Analytics context\n * @returns {Promise<void>} Promise that resolves when aliasing is complete\n *\n * @protected\n * @abstract\n */\n protected abstract doAlias(\n userId: string,\n previousId: string,\n context?: AnalyticsContext,\n ): Promise<void>;\n}\n","/**\n * @fileoverview Segment client-side (browser) provider implementation\n *\n * Provides client-side integration with Segment Analytics using @segment/analytics-next.\n * Supports full Segment.io spec tracking including track, identify, page, group, and alias.\n *\n * @remarks\n * This provider:\n * - Uses @segment/analytics-next for browser tracking\n * - Supports dynamic imports to avoid SSR issues\n * - Handles initialization and event tracking\n * - Integrates with Segment's CDN and API\n *\n * @module @repo/analytics/providers/segment/client\n */\n\nimport { BaseAnalyticsProvider } from '../base-provider';\n\nimport type { SegmentConfig } from './types';\nimport type {\n AnalyticsContext,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n UserTraits,\n} from '../../shared/types/types';\n\n// Type for AnalyticsBrowser instance\ninterface AnalyticsBrowserInstance {\n track: (event: string, properties?: Properties) => Promise<unknown>;\n identify: (userId: string, traits?: UserTraits) => Promise<unknown>;\n page: (name?: string, properties?: PageProperties) => Promise<unknown>;\n group: (groupId: string, traits?: GroupTraits) => Promise<unknown>;\n alias: (userId: string, previousId: string) => Promise<unknown>;\n}\n\nexport class SegmentClientProvider extends BaseAnalyticsProvider<SegmentConfig> {\n readonly name = 'segment';\n private analytics: AnalyticsBrowserInstance | null = null;\n\n constructor(config: ProviderConfig) {\n super(config);\n\n if (!config.writeKey) {\n throw new Error('Segment writeKey is required');\n }\n\n this.config = {\n options: config.options as Record<string, unknown>,\n writeKey: config.writeKey,\n };\n }\n\n protected async doInitialize(): Promise<void> {\n // Dynamically import Segment Analytics Next\n const { AnalyticsBrowser } = await import(\n /* webpackChunkName: \"segment-analytics-browser\" */\n '@segment/analytics-next'\n );\n\n // Initialize Analytics Browser\n this.analytics = AnalyticsBrowser.load({\n writeKey: this.config.writeKey,\n ...this.config.options,\n }) as unknown as AnalyticsBrowserInstance;\n }\n\n protected async doTrack(\n event: string,\n properties: Properties,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.track(event, properties);\n }\n\n protected async doIdentify(\n userId: string,\n traits: UserTraits,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.identify(userId, traits);\n }\n\n protected async doPage(\n name: string | undefined,\n properties: PageProperties,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.page(name, properties);\n }\n\n protected async doGroup(\n groupId: string,\n traits: GroupTraits,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.group(groupId, traits);\n }\n\n protected async doAlias(\n userId: string,\n previousId: string,\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.alias(userId, previousId);\n }\n}\n"],"mappings":"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"}
package/client-next.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import { C as EmitterPagePayload, D as EmitterTrackPayload, M as Properties, S as EmitterOptions, b as EmitterIdentifyPayload, c as ProviderConfig, d as TrackingOptions, g as EmitterContext, n as AnalyticsContext, p as EmitterAliasPayload, r as AnalyticsManager, t as AnalyticsConfig, u as ProviderRegistry, v as EmitterGroupPayload, w as EmitterPayload } from "./types-DnfdguWa.mjs";
2
- import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-BAXagFjt.mjs";
3
- import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload } from "./posthog-bootstrap-CRl1Pk_E.mjs";
4
- import { d as EcommerceEventSpec, m as OrderProperties, p as ExtendedProductProperties, r as CartProperties, t as BaseProductProperties } from "./types-Brm88i6e.mjs";
5
- import { t as index_d_exports } from "./index-qlFPt3-1.mjs";
6
- import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-BUMHyePt.mjs";
7
- import { a as ConsoleConfig, c as PostHogConfig, i as SegmentOptions, l as PostHogOptions, n as VercelOptions, o as ConsoleOptions, r as SegmentConfig, s as BootstrapData, t as VercelConfig } from "./vercel-types-Crq8m8c1.mjs";
1
+ import { C as EmitterPagePayload, D as EmitterTrackPayload, M as Properties, S as EmitterOptions, b as EmitterIdentifyPayload, c as ProviderConfig, d as TrackingOptions, g as EmitterContext, n as AnalyticsContext, p as EmitterAliasPayload, r as AnalyticsManager, t as AnalyticsConfig, u as ProviderRegistry, v as EmitterGroupPayload, w as EmitterPayload } from "./types-BxBnNQ0V.mjs";
2
+ import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-DldkVSPp.mjs";
3
+ import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload } from "./posthog-bootstrap-DWxFrxlt.mjs";
4
+ import { d as EcommerceEventSpec, m as OrderProperties, p as ExtendedProductProperties, r as CartProperties, t as BaseProductProperties } from "./types-CBvxUEaF.mjs";
5
+ import { t as index_d_exports } from "./index-jPzXRn52.mjs";
6
+ import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-DPS6bSYo.mjs";
7
+ import { a as ConsoleConfig, c as PostHogConfig, i as SegmentOptions, l as PostHogOptions, n as VercelOptions, o as ConsoleOptions, r as SegmentConfig, s as BootstrapData, t as VercelConfig } from "./vercel-types-lwakUfoI.mjs";
8
8
  import * as react_jsx_runtime0 from "react/jsx-runtime";
9
9
 
10
10
  //#region src/client/next/manager.d.ts
package/client-next.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
- import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload, v as createAnalyticsManager } from "./posthog-bootstrap-DDToYA4X.mjs";
4
- import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-BvEelkxS.mjs";
5
- import { t as ecommerce_exports } from "./ecommerce-DGG1FbiH.mjs";
6
- import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-6Mwe7b2O.mjs";
3
+ import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload, v as createAnalyticsManager } from "./posthog-bootstrap-CYfIy_WS.mjs";
4
+ import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-6-nKo8i-.mjs";
5
+ import { t as ecommerce_exports } from "./ecommerce-Cgu4wlux.mjs";
6
+ import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-P6P5adJg.mjs";
7
7
  import { useCallback, useEffect, useRef, useState } from "react";
8
8
  import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation";
9
9
  import { createClientObservability } from "@od-oneapp/observability/client/next";
@@ -53,7 +53,7 @@ async function createNextJSClientAnalytics(config) {
53
53
  case "posthog": {
54
54
  const module = await import(
55
55
  /* webpackChunkName: "analytics-posthog" */
56
- "./client-BOIcr_5V.mjs"
56
+ "./client-CeOLjbac.mjs"
57
57
  );
58
58
  CLIENT_PROVIDERS.posthog = (config) => new module.PostHogClientProvider(config);
59
59
  break;
@@ -61,7 +61,7 @@ async function createNextJSClientAnalytics(config) {
61
61
  case "segment": {
62
62
  const module = await import(
63
63
  /* webpackChunkName: "analytics-segment" */
64
- "./client-BiJJm6CH.mjs"
64
+ "./client-D339NFJS.mjs"
65
65
  );
66
66
  CLIENT_PROVIDERS.segment = (config) => new module.SegmentClientProvider(config);
67
67
  break;
@@ -69,7 +69,7 @@ async function createNextJSClientAnalytics(config) {
69
69
  case "vercel": {
70
70
  const module = await import(
71
71
  /* webpackChunkName: "analytics-vercel" */
72
- "./client-C_4MPbIp.mjs"
72
+ "./client-CcFTauAh.mjs"
73
73
  );
74
74
  CLIENT_PROVIDERS.vercel = (config) => new module.VercelClientProvider(config);
75
75
  break;
@@ -104,17 +104,17 @@ async function createNextJSClientAnalyticsUninitialized(config) {
104
104
  break;
105
105
  }
106
106
  case "posthog": {
107
- const { PostHogClientProvider } = await import("./client-BOIcr_5V.mjs");
107
+ const { PostHogClientProvider } = await import("./client-CeOLjbac.mjs");
108
108
  CLIENT_PROVIDERS.posthog = (config) => new PostHogClientProvider(config);
109
109
  break;
110
110
  }
111
111
  case "segment": {
112
- const { SegmentClientProvider } = await import("./client-BiJJm6CH.mjs");
112
+ const { SegmentClientProvider } = await import("./client-D339NFJS.mjs");
113
113
  CLIENT_PROVIDERS.segment = (config) => new SegmentClientProvider(config);
114
114
  break;
115
115
  }
116
116
  case "vercel": {
117
- const { VercelClientProvider } = await import("./client-C_4MPbIp.mjs");
117
+ const { VercelClientProvider } = await import("./client-CcFTauAh.mjs");
118
118
  CLIENT_PROVIDERS.vercel = (config) => new VercelClientProvider(config);
119
119
  break;
120
120
  }
package/client.d.mts CHANGED
@@ -1,12 +1,12 @@
1
- import { C as EmitterPagePayload, D as EmitterTrackPayload, S as EmitterOptions, b as EmitterIdentifyPayload, c as ProviderConfig, d as TrackingOptions, g as EmitterContext, i as AnalyticsProvider, n as AnalyticsContext, p as EmitterAliasPayload, r as AnalyticsManager, t as AnalyticsConfig, u as ProviderRegistry, v as EmitterGroupPayload, w as EmitterPayload } from "./types-DnfdguWa.mjs";
2
- import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-BAXagFjt.mjs";
3
- import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload } from "./posthog-bootstrap-CRl1Pk_E.mjs";
4
- import { d as EcommerceEventSpec, m as OrderProperties, p as ExtendedProductProperties, r as CartProperties, t as BaseProductProperties } from "./types-Brm88i6e.mjs";
5
- import { t as index_d_exports$1 } from "./index-qlFPt3-1.mjs";
6
- import { t as index_d_exports } from "./index-Cnz0VecZ.mjs";
7
- import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-BUMHyePt.mjs";
8
- import { a as ConsoleConfig, c as PostHogConfig, i as SegmentOptions, l as PostHogOptions, n as VercelOptions, o as ConsoleOptions, r as SegmentConfig, s as BootstrapData, t as VercelConfig } from "./vercel-types-Crq8m8c1.mjs";
9
- import { n as createAnalyticsManager, t as AnalyticsManager$1 } from "./manager-B6kowr9x.mjs";
1
+ import { C as EmitterPagePayload, D as EmitterTrackPayload, S as EmitterOptions, b as EmitterIdentifyPayload, c as ProviderConfig, d as TrackingOptions, g as EmitterContext, i as AnalyticsProvider, n as AnalyticsContext, p as EmitterAliasPayload, r as AnalyticsManager, t as AnalyticsConfig, u as ProviderRegistry, v as EmitterGroupPayload, w as EmitterPayload } from "./types-BxBnNQ0V.mjs";
2
+ import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-DldkVSPp.mjs";
3
+ import { a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload } from "./posthog-bootstrap-DWxFrxlt.mjs";
4
+ import { d as EcommerceEventSpec, m as OrderProperties, p as ExtendedProductProperties, r as CartProperties, t as BaseProductProperties } from "./types-CBvxUEaF.mjs";
5
+ import { t as index_d_exports$1 } from "./index-jPzXRn52.mjs";
6
+ import { t as index_d_exports } from "./index-BkIWe--N.mjs";
7
+ import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-DPS6bSYo.mjs";
8
+ import { a as ConsoleConfig, c as PostHogConfig, i as SegmentOptions, l as PostHogOptions, n as VercelOptions, o as ConsoleOptions, r as SegmentConfig, s as BootstrapData, t as VercelConfig } from "./vercel-types-lwakUfoI.mjs";
9
+ import { n as createAnalyticsManager, t as AnalyticsManager$1 } from "./manager-DvRRjza6.mjs";
10
10
 
11
11
  //#region src/client/manager.d.ts
12
12
  declare function createClientAnalytics(config: AnalyticsConfig): Promise<AnalyticsManager>;
package/client.mjs CHANGED
@@ -1,13 +1,121 @@
1
1
  import { t as ConsoleProvider } from "./console-8bND3mMU.mjs";
2
2
  import { HttpClientProvider } from "./providers-http-client.mjs";
3
- import { _ as AnalyticsManager, a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload, v as createAnalyticsManager } from "./posthog-bootstrap-DDToYA4X.mjs";
4
- import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-BvEelkxS.mjs";
5
- import { t as ecommerce_exports } from "./ecommerce-DGG1FbiH.mjs";
6
- import { t as ai_exports } from "./ai-Co8hBoEj.mjs";
7
- import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-6Mwe7b2O.mjs";
8
- import { SegmentClientProvider } from "@integrations/segment/analytics-provider/client";
9
- import { VercelClientProvider } from "@integrations/vercel/analytics-provider/client";
3
+ import { _ as AnalyticsManager, a as ContextBuilder, c as createAnonymousSession, d as isGroupPayload, f as isIdentifyPayload, g as withUTM, h as withMetadata, i as getDistinctIdFromCookies, l as createUserSession, m as isTrackPayload, n as createMinimalBootstrapData, o as EventBatch, p as isPagePayload, r as generateDistinctId, s as PayloadBuilder, t as createBootstrapData, u as isAliasPayload, v as createAnalyticsManager } from "./posthog-bootstrap-CYfIy_WS.mjs";
4
+ import { a as screen, i as page, n as group, o as track, r as identify, t as alias } from "./emitters-6-nKo8i-.mjs";
5
+ import { t as ecommerce_exports } from "./ecommerce-Cgu4wlux.mjs";
6
+ import { t as ai_exports } from "./ai-YMnynb-t.mjs";
7
+ import { a as createEmitterProcessor, i as validateConfig, n as createConfigBuilder, o as processEmitterPayload, r as getAnalyticsConfig, s as trackEcommerceEvent, t as PROVIDER_REQUIREMENTS } from "./config-P6P5adJg.mjs";
10
8
 
9
+ //#region ../../integrations/segment/src/analytics-provider/client.ts
10
+ var SegmentClientProvider = class {
11
+ name = "segment";
12
+ analytics = null;
13
+ config;
14
+ isInitialized = false;
15
+ constructor(config) {
16
+ if (!config.writeKey) throw new Error("Segment writeKey is required");
17
+ this.config = {
18
+ options: config.options,
19
+ writeKey: config.writeKey
20
+ };
21
+ }
22
+ async initialize() {
23
+ if (this.isInitialized) return;
24
+ const { AnalyticsBrowser } = await import(
25
+ /* webpackChunkName: "segment-analytics-browser" */
26
+ "@segment/analytics-next"
27
+ );
28
+ this.analytics = AnalyticsBrowser.load({
29
+ writeKey: this.config.writeKey,
30
+ ...this.config.options
31
+ });
32
+ this.isInitialized = true;
33
+ }
34
+ async track(event, properties = {}, _context) {
35
+ if (!this.analytics) return;
36
+ await this.analytics.track(event, properties);
37
+ }
38
+ async identify(userId, traits = {}, _context) {
39
+ if (!this.analytics) return;
40
+ await this.analytics.identify(userId, traits);
41
+ }
42
+ async page(name, properties = {}, _context) {
43
+ if (!this.analytics) return;
44
+ await this.analytics.page(name, properties);
45
+ }
46
+ async group(groupId, traits = {}, _context) {
47
+ if (!this.analytics) return;
48
+ await this.analytics.group(groupId, traits);
49
+ }
50
+ async alias(userId, previousId, _context) {
51
+ if (!this.analytics) return;
52
+ await this.analytics.alias(userId, previousId);
53
+ }
54
+ };
55
+
56
+ //#endregion
57
+ //#region ../../integrations/vercel/src/analytics-provider/client.ts
58
+ /**
59
+ * Converts internal Properties type to Vercel Analytics format.
60
+ * Vercel Analytics requires Record<string, string | number | boolean>.
61
+ */
62
+ function normalizePropertiesToVercel(properties) {
63
+ if (!properties) return {};
64
+ const normalized = {};
65
+ for (const [key, value] of Object.entries(properties)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") normalized[key] = value;
66
+ return normalized;
67
+ }
68
+ var VercelClientProvider = class {
69
+ name = "vercel";
70
+ config;
71
+ isInitialized = false;
72
+ constructor(config) {
73
+ this.config = { options: config.options };
74
+ }
75
+ async initialize() {
76
+ if (this.isInitialized) return;
77
+ try {
78
+ const { inject } = await import("@vercel/analytics");
79
+ inject(this.config.options);
80
+ this.isInitialized = true;
81
+ } catch {
82
+ throw new Error("Vercel Analytics not available. Install with: npm install @vercel/analytics");
83
+ }
84
+ }
85
+ async track(event, properties = {}) {
86
+ if (!this.isInitialized) return;
87
+ try {
88
+ const { track } = await import("@vercel/analytics");
89
+ track(event, normalizePropertiesToVercel(properties));
90
+ } catch {}
91
+ }
92
+ async identify(userId, traits = {}) {
93
+ await this.track("User Identified", {
94
+ userId,
95
+ ...traits
96
+ });
97
+ }
98
+ async page(name, properties = {}) {
99
+ if (name || Object.keys(properties).length > 0) await this.track("Page View", {
100
+ page: name,
101
+ ...properties
102
+ });
103
+ }
104
+ async group(groupId, traits = {}) {
105
+ await this.track("Group Identified", {
106
+ groupId,
107
+ ...traits
108
+ });
109
+ }
110
+ async alias(userId, previousId) {
111
+ await this.track("User Aliased", {
112
+ previousId,
113
+ userId
114
+ });
115
+ }
116
+ };
117
+
118
+ //#endregion
11
119
  //#region src/client/manager.ts
12
120
  /**
13
121
  * @fileoverview Client Analytics Manager
package/client.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../src/client/manager.ts","../src/shared/utils/validation-client.ts"],"sourcesContent":["/**\n * @fileoverview Client Analytics Manager\n *\n * Client-side analytics manager with static provider registry. Provides\n * factory functions for creating client analytics instances with support\n * for multiple providers (Console, HTTP, Segment, Vercel).\n *\n * **Providers Supported**:\n * - `console`: Console logging provider (development/debugging)\n * - `http`: HTTP provider for remote ingestion (oneapp-api)\n * - `segment`: Segment.io analytics provider\n * - `vercel`: Vercel Analytics provider\n *\n * @module @od-oneapp/analytics/client/manager\n */\n\nimport { SegmentClientProvider } from '@integrations/segment/analytics-provider/client';\nimport { VercelClientProvider } from '@integrations/vercel/analytics-provider/client';\n\nimport { ConsoleProvider } from '../providers/console/client';\nimport { HttpClientProvider } from '../providers/http/client';\nimport { createAnalyticsManager } from '../shared/utils/manager';\n\nimport type { AnalyticsConfig, AnalyticsManager, ProviderRegistry } from '../shared/types/types';\n\n// Static provider registry for client environments\nconst CLIENT_PROVIDERS: ProviderRegistry = {\n console: config => new ConsoleProvider(config),\n http: config => new HttpClientProvider(config),\n segment: config => new SegmentClientProvider(config),\n vercel: config => new VercelClientProvider(config),\n};\n\n/**\n * Create and initialize a client analytics instance\n * This is the primary way to create analytics for client-side applications\n *\n * @example\n * ```typescript\n * const analytics = await createClientAnalytics({\n * providers: {\n * http: { endpoint: '/api/v1/ingest' },\n * },\n * });\n * await analytics.track('Button Clicked', { variant: 'primary' });\n * ```\n * @param config - Analytics configuration including providers and settings\n * @returns Promise resolving to initialized analytics manager\n */\nexport async function createClientAnalytics(config: AnalyticsConfig): Promise<AnalyticsManager> {\n const manager = createAnalyticsManager(config, CLIENT_PROVIDERS);\n await manager.initialize();\n return manager;\n}\n\n/**\n * Create a client analytics instance without initializing\n * Useful when you need to control initialization timing\n *\n * @example\n * ```typescript\n * const analytics = createClientAnalyticsUninitialized(config);\n * // later inside a lazy effect\n * await analytics.initialize();\n * ```\n * @param config - Analytics configuration including providers and settings\n * @returns Uninitialized analytics manager instance\n */\nexport function createClientAnalyticsUninitialized(config: AnalyticsConfig): AnalyticsManager {\n return createAnalyticsManager(config, CLIENT_PROVIDERS);\n}\n","/**\n * @fileoverview Client-safe validation utilities for analytics configuration\n * Client-safe validation utilities for analytics configuration\n * This file contains only validation functions that are safe to use in browser environments\n */\n\nimport { PROVIDER_REQUIREMENTS } from './config';\n\nimport type { AnalyticsConfig, ProviderConfig } from '../types/types';\n\ninterface ValidationError {\n field: string;\n message: string;\n provider: string;\n}\n\ninterface ValidationResult {\n errors: ValidationError[];\n isValid: boolean;\n warnings: string[];\n}\n\n/**\n * Comprehensive configuration validation (client-safe version)\n * Accepts unknown input for defensive validation of potentially malformed configs\n */\nexport function validateAnalyticsConfig(config: unknown): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: string[] = [];\n\n // Check if config exists and is an object\n if (!config || typeof config !== 'object') {\n errors.push({\n provider: 'global',\n field: 'config',\n message: 'Analytics configuration is required and must be an object',\n });\n return { isValid: false, errors, warnings };\n }\n\n const typedConfig = config as AnalyticsConfig;\n\n // Check if providers object exists\n if (!typedConfig.providers || typeof typedConfig.providers !== 'object') {\n errors.push({\n provider: 'global',\n field: 'providers',\n message: 'Providers configuration is required and must be an object',\n });\n return { isValid: false, errors, warnings };\n }\n\n // Check if at least one provider is configured\n const providerCount = Object.keys(typedConfig.providers).length;\n if (providerCount === 0) {\n warnings.push('No providers configured. Analytics will not track any events.');\n }\n\n // Validate each provider\n for (const [providerName, providerConfig] of Object.entries(typedConfig.providers)) {\n const providerErrors = validateProvider(providerName, providerConfig);\n errors.push(...providerErrors);\n }\n\n // Environment-specific warnings\n if (typedConfig.providers.mixpanel) {\n warnings.push(\n 'Mixpanel provider configured on client-side. Consider using server-side for better performance.',\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate a single provider configuration\n */\nexport function validateProvider(providerName: string, config: ProviderConfig): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Check if provider is known\n const knownProviders = ['segment', 'posthog', 'vercel', 'console', 'mixpanel'];\n if (!knownProviders.includes(providerName)) {\n errors.push({\n provider: providerName,\n field: 'name',\n message: `Unknown provider '${providerName}'. Known providers: ${knownProviders.join(', ')}`,\n });\n return errors;\n }\n\n // Check required fields\n const requiredFields = PROVIDER_REQUIREMENTS[providerName] ?? [];\n for (const field of requiredFields) {\n const value = config[field as keyof ProviderConfig];\n\n if (!value) {\n errors.push({\n provider: providerName,\n field,\n message: `Required field '${field}' is missing for provider '${providerName}'`,\n });\n } else if (typeof value === 'string' && value.trim() === '') {\n errors.push({\n provider: providerName,\n field,\n message: `Required field '${field}' cannot be empty for provider '${providerName}'`,\n });\n }\n }\n\n // Provider-specific validation\n switch (providerName) {\n case 'segment':\n if (config.writeKey && !isValidSegmentWriteKey(config.writeKey)) {\n errors.push({\n provider: providerName,\n field: 'writeKey',\n message: 'Segment writeKey appears to be invalid format',\n });\n }\n break;\n\n case 'posthog':\n if (config.apiKey && !isValidPostHogApiKey(config.apiKey)) {\n errors.push({\n provider: providerName,\n field: 'apiKey',\n message: 'PostHog apiKey appears to be invalid format',\n });\n }\n break;\n }\n\n return errors;\n}\n\n/**\n * Helper functions for format validation\n */\nfunction isValidSegmentWriteKey(writeKey: string): boolean {\n // Segment write keys are typically 32 characters, alphanumeric\n return /^[\\dA-Za-z]{20,40}$/.test(writeKey);\n}\n\nfunction isValidPostHogApiKey(apiKey: string): boolean {\n // PostHog API keys start with 'phc_' followed by alphanumeric characters\n return /^phc_[\\dA-Za-z]{43}$/.test(apiKey);\n}\n\n/**\n * Utility to validate configuration (client-safe version without throwing)\n * Returns validation result instead of throwing errors\n */\nexport function validateConfig(config: AnalyticsConfig): ValidationResult {\n return validateAnalyticsConfig(config);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAM,mBAAqC;CACzC,UAAS,WAAU,IAAI,gBAAgB,OAAO;CAC9C,OAAM,WAAU,IAAI,mBAAmB,OAAO;CAC9C,UAAS,WAAU,IAAI,sBAAsB,OAAO;CACpD,SAAQ,WAAU,IAAI,qBAAqB,OAAO;CACnD;;;;;;;;;;;;;;;;;AAkBD,eAAsB,sBAAsB,QAAoD;CAC9F,MAAM,UAAU,uBAAuB,QAAQ,iBAAiB;AAChE,OAAM,QAAQ,YAAY;AAC1B,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,mCAAmC,QAA2C;AAC5F,QAAO,uBAAuB,QAAQ,iBAAiB;;;;;;;;;;;;;;AC3CzD,SAAgB,wBAAwB,QAAmC;CACzE,MAAM,SAA4B,EAAE;CACpC,MAAM,WAAqB,EAAE;AAG7B,KAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,SAAO,KAAK;GACV,UAAU;GACV,OAAO;GACP,SAAS;GACV,CAAC;AACF,SAAO;GAAE,SAAS;GAAO;GAAQ;GAAU;;CAG7C,MAAM,cAAc;AAGpB,KAAI,CAAC,YAAY,aAAa,OAAO,YAAY,cAAc,UAAU;AACvE,SAAO,KAAK;GACV,UAAU;GACV,OAAO;GACP,SAAS;GACV,CAAC;AACF,SAAO;GAAE,SAAS;GAAO;GAAQ;GAAU;;AAK7C,KADsB,OAAO,KAAK,YAAY,UAAU,CAAC,WACnC,EACpB,UAAS,KAAK,gEAAgE;AAIhF,MAAK,MAAM,CAAC,cAAc,mBAAmB,OAAO,QAAQ,YAAY,UAAU,EAAE;EAClF,MAAM,iBAAiB,iBAAiB,cAAc,eAAe;AACrE,SAAO,KAAK,GAAG,eAAe;;AAIhC,KAAI,YAAY,UAAU,SACxB,UAAS,KACP,kGACD;AAGH,QAAO;EACL,SAAS,OAAO,WAAW;EAC3B;EACA;EACD;;;;;AAMH,SAAgB,iBAAiB,cAAsB,QAA2C;CAChG,MAAM,SAA4B,EAAE;CAGpC,MAAM,iBAAiB;EAAC;EAAW;EAAW;EAAU;EAAW;EAAW;AAC9E,KAAI,CAAC,eAAe,SAAS,aAAa,EAAE;AAC1C,SAAO,KAAK;GACV,UAAU;GACV,OAAO;GACP,SAAS,qBAAqB,aAAa,sBAAsB,eAAe,KAAK,KAAK;GAC3F,CAAC;AACF,SAAO;;CAIT,MAAM,iBAAiB,sBAAsB,iBAAiB,EAAE;AAChE,MAAK,MAAM,SAAS,gBAAgB;EAClC,MAAM,QAAQ,OAAO;AAErB,MAAI,CAAC,MACH,QAAO,KAAK;GACV,UAAU;GACV;GACA,SAAS,mBAAmB,MAAM,6BAA6B,aAAa;GAC7E,CAAC;WACO,OAAO,UAAU,YAAY,MAAM,MAAM,KAAK,GACvD,QAAO,KAAK;GACV,UAAU;GACV;GACA,SAAS,mBAAmB,MAAM,kCAAkC,aAAa;GAClF,CAAC;;AAKN,SAAQ,cAAR;EACE,KAAK;AACH,OAAI,OAAO,YAAY,CAAC,uBAAuB,OAAO,SAAS,CAC7D,QAAO,KAAK;IACV,UAAU;IACV,OAAO;IACP,SAAS;IACV,CAAC;AAEJ;EAEF,KAAK;AACH,OAAI,OAAO,UAAU,CAAC,qBAAqB,OAAO,OAAO,CACvD,QAAO,KAAK;IACV,UAAU;IACV,OAAO;IACP,SAAS;IACV,CAAC;AAEJ;;AAGJ,QAAO;;;;;AAMT,SAAS,uBAAuB,UAA2B;AAEzD,QAAO,sBAAsB,KAAK,SAAS;;AAG7C,SAAS,qBAAqB,QAAyB;AAErD,QAAO,uBAAuB,KAAK,OAAO"}
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../../../integrations/segment/src/analytics-provider/client.ts","../../../integrations/vercel/src/analytics-provider/client.ts","../src/client/manager.ts","../src/shared/utils/validation-client.ts"],"sourcesContent":["/**\n * @fileoverview Segment client-side (browser) analytics provider\n *\n * Provides client-side integration with Segment Analytics using @segment/analytics-next.\n * Implements the @od-oneapp/analytics AnalyticsProvider interface for use in the analytics\n * manager's provider registry.\n *\n * @module @integrations/segment/analytics-provider/client\n */\n\nimport type {\n AnalyticsContext,\n AnalyticsProvider,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n SegmentConfig,\n UserTraits,\n} from './types';\n\n// Type for AnalyticsBrowser instance\ninterface AnalyticsBrowserInstance {\n track: (event: string, properties?: Properties) => Promise<unknown>;\n identify: (userId: string, traits?: UserTraits) => Promise<unknown>;\n page: (name?: string, properties?: PageProperties) => Promise<unknown>;\n group: (groupId: string, traits?: GroupTraits) => Promise<unknown>;\n alias: (userId: string, previousId: string) => Promise<unknown>;\n}\n\nexport class SegmentClientProvider implements AnalyticsProvider {\n readonly name = 'segment';\n private analytics: AnalyticsBrowserInstance | null = null;\n private config: SegmentConfig;\n private isInitialized = false;\n\n constructor(config: ProviderConfig) {\n if (!config.writeKey) {\n throw new Error('Segment writeKey is required');\n }\n\n this.config = {\n options: config.options as Record<string, unknown>,\n writeKey: config.writeKey,\n };\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n const { AnalyticsBrowser } = await import(\n /* webpackChunkName: \"segment-analytics-browser\" */\n '@segment/analytics-next'\n );\n\n this.analytics = AnalyticsBrowser.load({\n writeKey: this.config.writeKey,\n ...this.config.options,\n } as Parameters<typeof AnalyticsBrowser.load>[0]) as unknown as AnalyticsBrowserInstance;\n\n this.isInitialized = true;\n }\n\n async track(\n event: string,\n properties: Properties = {},\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.track(event, properties);\n }\n\n async identify(\n userId: string,\n traits: UserTraits = {},\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.identify(userId, traits);\n }\n\n async page(\n name?: string,\n properties: PageProperties = {},\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.page(name, properties);\n }\n\n async group(\n groupId: string,\n traits: GroupTraits = {},\n _context?: AnalyticsContext,\n ): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.group(groupId, traits);\n }\n\n async alias(userId: string, previousId: string, _context?: AnalyticsContext): Promise<void> {\n if (!this.analytics) return;\n await this.analytics.alias(userId, previousId);\n }\n}\n","/**\n * @fileoverview Vercel Analytics client-side (browser) provider\n *\n * Provides client-side integration with Vercel Analytics. Implements the\n * @od-oneapp/analytics AnalyticsProvider interface for use in the analytics\n * manager's provider registry.\n *\n * @module @integrations/vercel/analytics-provider/client\n */\n\nimport type {\n AnalyticsProvider,\n GroupTraits,\n PageProperties,\n Properties,\n ProviderConfig,\n UserTraits,\n VercelConfig,\n} from './types';\n\n/**\n * Converts internal Properties type to Vercel Analytics format.\n * Vercel Analytics requires Record<string, string | number | boolean>.\n */\nfunction normalizePropertiesToVercel(\n properties?: Properties,\n): Record<string, string | number | boolean> {\n if (!properties) return {};\n const normalized: Record<string, string | number | boolean> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n normalized[key] = value;\n }\n }\n return normalized;\n}\n\nexport class VercelClientProvider implements AnalyticsProvider {\n readonly name = 'vercel';\n private config: VercelConfig;\n private isInitialized = false;\n\n constructor(config: ProviderConfig) {\n this.config = {\n options: config.options,\n };\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n try {\n const { inject } = await import('@vercel/analytics');\n inject(this.config.options);\n this.isInitialized = true;\n } catch {\n throw new Error(\n 'Vercel Analytics not available. Install with: npm install @vercel/analytics',\n );\n }\n }\n\n async track(event: string, properties: Properties = {}): Promise<void> {\n if (!this.isInitialized) return;\n\n try {\n const { track } = await import('@vercel/analytics');\n track(event, normalizePropertiesToVercel(properties));\n } catch {\n // Silently fail to avoid disrupting app flow\n }\n }\n\n async identify(userId: string, traits: UserTraits = {}): Promise<void> {\n await this.track('User Identified', {\n userId,\n ...traits,\n });\n }\n\n async page(name?: string, properties: PageProperties = {}): Promise<void> {\n if (name || Object.keys(properties).length > 0) {\n await this.track('Page View', {\n page: name,\n ...properties,\n });\n }\n }\n\n async group(groupId: string, traits: GroupTraits = {}): Promise<void> {\n await this.track('Group Identified', {\n groupId,\n ...traits,\n });\n }\n\n async alias(userId: string, previousId: string): Promise<void> {\n await this.track('User Aliased', {\n previousId,\n userId,\n });\n }\n}\n","/**\n * @fileoverview Client Analytics Manager\n *\n * Client-side analytics manager with static provider registry. Provides\n * factory functions for creating client analytics instances with support\n * for multiple providers (Console, HTTP, Segment, Vercel).\n *\n * **Providers Supported**:\n * - `console`: Console logging provider (development/debugging)\n * - `http`: HTTP provider for remote ingestion (oneapp-api)\n * - `segment`: Segment.io analytics provider\n * - `vercel`: Vercel Analytics provider\n *\n * @module @od-oneapp/analytics/client/manager\n */\n\nimport { SegmentClientProvider } from '@integrations/segment/analytics-provider/client';\nimport { VercelClientProvider } from '@integrations/vercel/analytics-provider/client';\n\nimport { ConsoleProvider } from '../providers/console/client';\nimport { HttpClientProvider } from '../providers/http/client';\nimport { createAnalyticsManager } from '../shared/utils/manager';\n\nimport type { AnalyticsConfig, AnalyticsManager, ProviderRegistry } from '../shared/types/types';\n\n// Static provider registry for client environments\nconst CLIENT_PROVIDERS: ProviderRegistry = {\n console: config => new ConsoleProvider(config),\n http: config => new HttpClientProvider(config),\n segment: config => new SegmentClientProvider(config),\n vercel: config => new VercelClientProvider(config),\n};\n\n/**\n * Create and initialize a client analytics instance\n * This is the primary way to create analytics for client-side applications\n *\n * @example\n * ```typescript\n * const analytics = await createClientAnalytics({\n * providers: {\n * http: { endpoint: '/api/v1/ingest' },\n * },\n * });\n * await analytics.track('Button Clicked', { variant: 'primary' });\n * ```\n * @param config - Analytics configuration including providers and settings\n * @returns Promise resolving to initialized analytics manager\n */\nexport async function createClientAnalytics(config: AnalyticsConfig): Promise<AnalyticsManager> {\n const manager = createAnalyticsManager(config, CLIENT_PROVIDERS);\n await manager.initialize();\n return manager;\n}\n\n/**\n * Create a client analytics instance without initializing\n * Useful when you need to control initialization timing\n *\n * @example\n * ```typescript\n * const analytics = createClientAnalyticsUninitialized(config);\n * // later inside a lazy effect\n * await analytics.initialize();\n * ```\n * @param config - Analytics configuration including providers and settings\n * @returns Uninitialized analytics manager instance\n */\nexport function createClientAnalyticsUninitialized(config: AnalyticsConfig): AnalyticsManager {\n return createAnalyticsManager(config, CLIENT_PROVIDERS);\n}\n","/**\n * @fileoverview Client-safe validation utilities for analytics configuration\n * Client-safe validation utilities for analytics configuration\n * This file contains only validation functions that are safe to use in browser environments\n */\n\nimport { PROVIDER_REQUIREMENTS } from './config';\n\nimport type { AnalyticsConfig, ProviderConfig } from '../types/types';\n\ninterface ValidationError {\n field: string;\n message: string;\n provider: string;\n}\n\ninterface ValidationResult {\n errors: ValidationError[];\n isValid: boolean;\n warnings: string[];\n}\n\n/**\n * Comprehensive configuration validation (client-safe version)\n * Accepts unknown input for defensive validation of potentially malformed configs\n */\nexport function validateAnalyticsConfig(config: unknown): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: string[] = [];\n\n // Check if config exists and is an object\n if (!config || typeof config !== 'object') {\n errors.push({\n provider: 'global',\n field: 'config',\n message: 'Analytics configuration is required and must be an object',\n });\n return { isValid: false, errors, warnings };\n }\n\n const typedConfig = config as AnalyticsConfig;\n\n // Check if providers object exists\n if (!typedConfig.providers || typeof typedConfig.providers !== 'object') {\n errors.push({\n provider: 'global',\n field: 'providers',\n message: 'Providers configuration is required and must be an object',\n });\n return { isValid: false, errors, warnings };\n }\n\n // Check if at least one provider is configured\n const providerCount = Object.keys(typedConfig.providers).length;\n if (providerCount === 0) {\n warnings.push('No providers configured. Analytics will not track any events.');\n }\n\n // Validate each provider\n for (const [providerName, providerConfig] of Object.entries(typedConfig.providers)) {\n const providerErrors = validateProvider(providerName, providerConfig);\n errors.push(...providerErrors);\n }\n\n // Environment-specific warnings\n if (typedConfig.providers.mixpanel) {\n warnings.push(\n 'Mixpanel provider configured on client-side. Consider using server-side for better performance.',\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate a single provider configuration\n */\nexport function validateProvider(providerName: string, config: ProviderConfig): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Check if provider is known\n const knownProviders = ['segment', 'posthog', 'vercel', 'console', 'mixpanel'];\n if (!knownProviders.includes(providerName)) {\n errors.push({\n provider: providerName,\n field: 'name',\n message: `Unknown provider '${providerName}'. Known providers: ${knownProviders.join(', ')}`,\n });\n return errors;\n }\n\n // Check required fields\n const requiredFields = PROVIDER_REQUIREMENTS[providerName] ?? [];\n for (const field of requiredFields) {\n const value = config[field as keyof ProviderConfig];\n\n if (!value) {\n errors.push({\n provider: providerName,\n field,\n message: `Required field '${field}' is missing for provider '${providerName}'`,\n });\n } else if (typeof value === 'string' && value.trim() === '') {\n errors.push({\n provider: providerName,\n field,\n message: `Required field '${field}' cannot be empty for provider '${providerName}'`,\n });\n }\n }\n\n // Provider-specific validation\n switch (providerName) {\n case 'segment':\n if (config.writeKey && !isValidSegmentWriteKey(config.writeKey)) {\n errors.push({\n provider: providerName,\n field: 'writeKey',\n message: 'Segment writeKey appears to be invalid format',\n });\n }\n break;\n\n case 'posthog':\n if (config.apiKey && !isValidPostHogApiKey(config.apiKey)) {\n errors.push({\n provider: providerName,\n field: 'apiKey',\n message: 'PostHog apiKey appears to be invalid format',\n });\n }\n break;\n }\n\n return errors;\n}\n\n/**\n * Helper functions for format validation\n */\nfunction isValidSegmentWriteKey(writeKey: string): boolean {\n // Segment write keys are typically 32 characters, alphanumeric\n return /^[\\dA-Za-z]{20,40}$/.test(writeKey);\n}\n\nfunction isValidPostHogApiKey(apiKey: string): boolean {\n // PostHog API keys start with 'phc_' followed by alphanumeric characters\n return /^phc_[\\dA-Za-z]{43}$/.test(apiKey);\n}\n\n/**\n * Utility to validate configuration (client-safe version without throwing)\n * Returns validation result instead of throwing errors\n */\nexport function validateConfig(config: AnalyticsConfig): ValidationResult {\n return validateAnalyticsConfig(config);\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as ProviderConfig, r as AnalyticsManager, t as AnalyticsConfig, w as EmitterPayload } from "./types-DnfdguWa.mjs";
1
+ import { c as ProviderConfig, r as AnalyticsManager, t as AnalyticsConfig, w as EmitterPayload } from "./types-BxBnNQ0V.mjs";
2
2
 
3
3
  //#region src/shared/utils/emitter-adapter.d.ts
4
4
  declare function processEmitterPayload(analytics: AnalyticsManager, payload: EmitterPayload): Promise<void>;
@@ -31,4 +31,4 @@ interface AnalyticsConfigOptions {
31
31
  declare function getAnalyticsConfig(options?: AnalyticsConfigOptions): AnalyticsConfig;
32
32
  //#endregion
33
33
  export { createEmitterProcessor as a, validateConfig as i, createConfigBuilder as n, processEmitterPayload as o, getAnalyticsConfig as r, trackEcommerceEvent as s, PROVIDER_REQUIREMENTS as t };
34
- //# sourceMappingURL=config-BUMHyePt.d.mts.map
34
+ //# sourceMappingURL=config-DPS6bSYo.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-BUMHyePt.d.mts","names":[],"sources":["../src/shared/utils/emitter-adapter.ts","../src/shared/utils/config.ts"],"mappings":";;;iBAoCsB,qBAAA,CACpB,SAAA,EAAW,gBAAA,EACX,OAAA,EAAS,cAAA,GACR,OAAA;AAAA,iBAsJa,sBAAA,CAAuB,SAAA,EAAW,gBAAA,IACxC,OAAA,EAAS,cAAA,KAAc,OAAA;AAAA,iBAgBX,mBAAA,CACpB,SAAA,EAAW,gBAAA,EACX,SAAA;EAAa,IAAA;EAAc,UAAA,EAAY,MAAA;AAAA,IACtC,OAAA;;;KCzLS,kBAAA,GAAqB,MAAA;AAAA,cAQpB,qBAAA,EAAuB,kBAAA;AAAA,iBA0BpB,cAAA,CAAe,MAAA;AAAA,UA8Cd,aAAA;EACf,UAAA,CAAW,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC/C,UAAA,CAAW,MAAA,UAAgB,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC/D,WAAA,CAAY,IAAA,UAAc,MAAA,EAAQ,cAAA,GAAiB,aAAA;EACnD,UAAA,CAAW,QAAA,UAAkB,OAAA,GAAU,MAAA,oBAA0B,aAAA;EACjE,SAAA,CAAU,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC9C,KAAA,IAAS,eAAA;EACT,SAAA,EAAW,MAAA,SAAe,cAAA;AAAA;AAAA,iBAoBZ,mBAAA,CAAA,GAAuB,aAAA;AAAA,UA0CtB,sBAAA;EACf,aAAA;EACA,SAAA;EACA,eAAA;EACA,aAAA;AAAA;AAAA,iBAyBc,kBAAA,CAAmB,OAAA,GAAU,sBAAA,GAAyB,eAAA"}
1
+ {"version":3,"file":"config-DPS6bSYo.d.mts","names":[],"sources":["../src/shared/utils/emitter-adapter.ts","../src/shared/utils/config.ts"],"mappings":";;;iBAoCsB,qBAAA,CACpB,SAAA,EAAW,gBAAA,EACX,OAAA,EAAS,cAAA,GACR,OAAA;AAAA,iBAsJa,sBAAA,CAAuB,SAAA,EAAW,gBAAA,IACxC,OAAA,EAAS,cAAA,KAAc,OAAA;AAAA,iBAgBX,mBAAA,CACpB,SAAA,EAAW,gBAAA,EACX,SAAA;EAAa,IAAA;EAAc,UAAA,EAAY,MAAA;AAAA,IACtC,OAAA;;;KCzLS,kBAAA,GAAqB,MAAA;AAAA,cAQpB,qBAAA,EAAuB,kBAAA;AAAA,iBA0BpB,cAAA,CAAe,MAAA;AAAA,UA8Cd,aAAA;EACf,UAAA,CAAW,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC/C,UAAA,CAAW,MAAA,UAAgB,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC/D,WAAA,CAAY,IAAA,UAAc,MAAA,EAAQ,cAAA,GAAiB,aAAA;EACnD,UAAA,CAAW,QAAA,UAAkB,OAAA,GAAU,MAAA,oBAA0B,aAAA;EACjE,SAAA,CAAU,OAAA,GAAU,MAAA,oBAA0B,aAAA;EAC9C,KAAA,IAAS,eAAA;EACT,SAAA,EAAW,MAAA,SAAe,cAAA;AAAA;AAAA,iBAoBZ,mBAAA,CAAA,GAAuB,aAAA;AAAA,UA0CtB,sBAAA;EACf,aAAA;EACA,SAAA;EACA,eAAA;EACA,aAAA;AAAA;AAAA,iBAyBc,kBAAA,CAAmB,OAAA,GAAU,sBAAA,GAAyB,eAAA"}
@@ -284,4 +284,4 @@ function getAnalyticsConfig(options) {
284
284
 
285
285
  //#endregion
286
286
  export { createEmitterProcessor as a, validateConfig as i, createConfigBuilder as n, processEmitterPayload as o, getAnalyticsConfig as r, trackEcommerceEvent as s, PROVIDER_REQUIREMENTS as t };
287
- //# sourceMappingURL=config-6Mwe7b2O.mjs.map
287
+ //# sourceMappingURL=config-P6P5adJg.mjs.map