/** * Attribution Tracking Module * Handles UTM parameters, click IDs, and customer journey */ import type { Attribution, TouchPoint } from './types'; export declare class AttributionManager { private static readonly KLAVIYO_BINDING_KEY; private static readonly KLAVIYO_BINDING_TTL_MS; private attributionWindow; private trackedParams; private queryParamsCache; private pendingKlaviyoProfileId; private replaceVisibleUrl?; private UTM_PARAMS; private CLICK_IDS; private CLICK_ID_ALIASES; private DEFAULT_TRACKED_PARAMS; private MARKETING_COOKIES; private marketingAllowedFn?; constructor(options?: { attributionWindow?: number; trackedParams?: string[]; marketingAllowed?: () => boolean; replaceVisibleUrl?: (url: string) => void; }); private validKlaviyoProfileId; /** Capture the dedicated Klaviyo identity parameter before URL redaction. * It deliberately never enters the Attribution object or touch storage. */ private captureKlaviyoProfileBinding; /** Called once encryption is ready. The short TTL only bridges async init or * a reload before the landing event is queued; it is not a profile cache. */ hydrateKlaviyoProfileBinding(): Promise; /** One-shot binding for the next queued event. */ consumeKlaviyoProfileBinding(): string | null; private isMarketingAllowed; /** * Clear query params cache (called on page navigation) * FIXED: Prevents stale attribution data on SPA navigation */ clearCache(): void; /** * Capture current attribution from URL */ captureAttribution(): Attribution; /** * Store first touch attribution with 90-day expiration * * FIXED (DATA-01): Removed paid priority logic that was corrupting first-touch attribution. * First-touch is now IMMUTABLE except for expiration - this ensures accurate revenue attribution. */ storeFirstTouch(attribution: Attribution): void; /** * Get first touch attribution * Checks expiry and removes if expired (Issue #4) */ getFirstTouch(): Attribution | null; /** * Store last touch attribution with 90-day expiration */ storeLastTouch(attribution: Attribution): void; /** * Get last touch attribution * Checks expiry and removes if expired (Issue #4) */ getLastTouch(): Attribution | null; /** * Add touchpoint to customer journey */ addTouchpoint(sessionId: string, attribution: Attribution): void; /** * Get customer journey */ getJourney(): TouchPoint[]; /** * Capture advertising platform cookies */ private captureAdCookies; /** * Check if we have a specific click ID in current params * Uses cached params to avoid multiple URL parses (Issue #3) */ private hasClickId; /** * Get current fbclid from URL if present * Uses cached params to avoid multiple URL parses (Issue #3) */ private getCurrentFbclid; /** * Extract the fbclid embedded in an `_fbc` cookie value * (`fb.{subdomainIndex}.{creationTime}.{fbclid}` → the 4th dot-segment), or null if * the value is missing/malformed. Used to detect whether a NEW fbclid in the URL * differs from the one a prior _fbc was built for. (FSR-14) */ private extractFbclidFromFbc; /** * Get attribution data for event */ getAttributionData(): Record; /** * Determine source from attribution data */ private determineSource; /** * Determine medium from attribution data */ private determineMedium; /** * Whether two hosts share the same root domain (eTLD+1 approximation), so that * cross-subdomain internal navigation (e.g. shop.example.com → checkout.example.com) * is also treated as same-site. Not a full public-suffix parse — good enough to keep * internal navs from being mis-classified as referral. */ private isSameRootDomain; /** * Extract hostname from URL */ private extractHostname; /** * Check if attribution has expired */ isAttributionExpired(attribution: Attribution): boolean; /** * Clear expired attribution */ clearExpiredAttribution(): void; } //# sourceMappingURL=attribution.d.ts.map