@beworke/pixel 0.1.0-rc.1
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.
- package/CHANGELOG.md +194 -0
- package/README.md +163 -0
- package/RELEASE_CANDIDATE.md +256 -0
- package/dist/PixelLogger-B21lEjep.d.mts +8 -0
- package/dist/PixelLogger-B21lEjep.d.ts +8 -0
- package/dist/StorageFactory-BhpbB6Jj.d.mts +8 -0
- package/dist/StorageFactory-CAkJJqVD.d.ts +8 -0
- package/dist/config/index.cjs.js +3 -0
- package/dist/config/index.cjs.js.map +1 -0
- package/dist/config/index.d.mts +19 -0
- package/dist/config/index.d.ts +19 -0
- package/dist/config/index.esm.js +3 -0
- package/dist/config/index.esm.js.map +1 -0
- package/dist/events/index.cjs.js +3 -0
- package/dist/events/index.cjs.js.map +1 -0
- package/dist/events/index.d.mts +1 -0
- package/dist/events/index.d.ts +1 -0
- package/dist/events/index.esm.js +3 -0
- package/dist/events/index.esm.js.map +1 -0
- package/dist/examples/html-script/README.md +71 -0
- package/dist/examples/html-script/RELEASE_CANDIDATE.md +121 -0
- package/dist/examples/html-script/add-payment-info/README.md +46 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-autocomplete.html +494 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-disabled.html +478 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-fields.html +486 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-data-track.html +479 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-dedupe.html +492 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-manual.html +495 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-rules-card.html +469 -0
- package/dist/examples/html-script/add-payment-info/example-add-payment-info-security.html +489 -0
- package/dist/examples/html-script/add-to-cart/README.md +36 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-attribute.html +517 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-auto.html +512 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-click.html +519 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-dedupe.html +514 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-manual.html +517 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-order-bump.html +527 -0
- package/dist/examples/html-script/add-to-cart/example-add-to-cart-text.html +524 -0
- package/dist/examples/html-script/example-basic.html +350 -0
- package/dist/examples/html-script/example-behavior.html +435 -0
- package/dist/examples/html-script/example-conversion.html +479 -0
- package/dist/examples/html-script/example-integration.html +709 -0
- package/dist/examples/html-script/example-transport.html +748 -0
- package/dist/examples/html-script/initiate-checkout/README.md +38 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-attribute.html +485 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-auto.html +491 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-click.html +493 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-manual.html +494 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-snapshot.html +497 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-submit.html +502 -0
- package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-text.html +496 -0
- package/dist/examples/html-script/lead/README.md +25 -0
- package/dist/examples/html-script/lead/example-lead-trigger-attribute.html +594 -0
- package/dist/examples/html-script/lead/example-lead-trigger-auto.html +431 -0
- package/dist/examples/html-script/lead/example-lead-trigger-click.html +587 -0
- package/dist/examples/html-script/release-candidate.html +726 -0
- package/dist/examples/html-script/remove-from-cart/README.md +36 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-attribute.html +532 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-css.html +524 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-dedupe.html +540 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-manual.html +533 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-multi.html +557 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-state.html +539 -0
- package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-text.html +524 -0
- package/dist/examples/html-script/search/README.md +41 -0
- package/dist/examples/html-script/search/example-search-attribute.html +454 -0
- package/dist/examples/html-script/search/example-search-button-sync.html +455 -0
- package/dist/examples/html-script/search/example-search-dedupe.html +466 -0
- package/dist/examples/html-script/search/example-search-input.html +456 -0
- package/dist/examples/html-script/search/example-search-manual.html +473 -0
- package/dist/examples/html-script/search/example-search-submit.html +450 -0
- package/dist/examples/html-script/search/example-search-text.html +441 -0
- package/dist/examples/html-script/view-content/README.md +48 -0
- package/dist/examples/html-script/view-content/example-view-content-attribute.html +488 -0
- package/dist/examples/html-script/view-content/example-view-content-css.html +467 -0
- package/dist/examples/html-script/view-content/example-view-content-dedupe.html +485 -0
- package/dist/examples/html-script/view-content/example-view-content-empty.html +469 -0
- package/dist/examples/html-script/view-content/example-view-content-manual.html +496 -0
- package/dist/examples/html-script/view-content/example-view-content-product-card.html +478 -0
- package/dist/examples/html-script/view-content/example-view-content-text.html +473 -0
- package/dist/examples/release-candidate/README.md +14 -0
- package/dist/examples/v2/README.md +33 -0
- package/dist/index-DUfFzniE.d.mts +274 -0
- package/dist/index-DUfFzniE.d.ts +274 -0
- package/dist/index.cjs.js +3 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.mts +364 -0
- package/dist/index.d.ts +364 -0
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/logger/index.cjs.js +3 -0
- package/dist/logger/index.cjs.js.map +1 -0
- package/dist/logger/index.d.mts +12 -0
- package/dist/logger/index.d.ts +12 -0
- package/dist/logger/index.esm.js +3 -0
- package/dist/logger/index.esm.js.map +1 -0
- package/dist/pixel-CbeF25mD.d.mts +555 -0
- package/dist/pixel-CbeF25mD.d.ts +555 -0
- package/dist/pixel-default-config-1VgLFOiL.d.mts +5 -0
- package/dist/pixel-default-config-Bxb-Vdd8.d.ts +5 -0
- package/dist/runtime/index.cjs.js +3 -0
- package/dist/runtime/index.cjs.js.map +1 -0
- package/dist/runtime/index.d.mts +48 -0
- package/dist/runtime/index.d.ts +48 -0
- package/dist/runtime/index.esm.js +3 -0
- package/dist/runtime/index.esm.js.map +1 -0
- package/dist/services/index.cjs.js +3 -0
- package/dist/services/index.cjs.js.map +1 -0
- package/dist/services/index.d.mts +169 -0
- package/dist/services/index.d.ts +169 -0
- package/dist/services/index.esm.js +3 -0
- package/dist/services/index.esm.js.map +1 -0
- package/dist/types-CTpRvFKZ.d.ts +71 -0
- package/dist/types-DGlBdsAy.d.mts +71 -0
- package/dist/v2/global.global.js +3 -0
- package/dist/v2/global.global.js.map +1 -0
- package/dist/v2/index.cjs.js +3 -0
- package/dist/v2/index.cjs.js.map +1 -0
- package/dist/v2/index.d.mts +7 -0
- package/dist/v2/index.d.ts +7 -0
- package/dist/v2/index.esm.js +3 -0
- package/dist/v2/index.esm.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/behavior/trackers/BehaviorTrackerBase.ts","../src/modules/behavior/trackers/ScrollTracker.ts","../src/modules/behavior/trackers/utils/element.ts","../src/modules/behavior/trackers/ClickTracker.ts","../src/modules/behavior/trackers/VisibilityTracker.ts","../src/modules/behavior/trackers/IdleTracker.ts","../src/modules/behavior/trackers/ExitIntentTracker.ts","../src/modules/behavior/behavior.module.ts","../src/modules/conversion/auto/BaseAutoTracker.ts","../src/modules/conversion/commerce/ProductCatalog.ts","../src/modules/conversion/commerce/CommerceState.ts","../src/modules/conversion/commerce/extractor-utils.ts","../src/modules/conversion/commerce/CustomerExtractor.ts","../src/modules/conversion/commerce/ProductExtractor.ts","../src/modules/conversion/commerce/FormConditionEvaluator.ts","../src/modules/conversion/commerce/OrderCalculator.ts","../src/modules/conversion/commerce/CommerceResolver.ts","../src/modules/conversion/detectors/TextSelectorResolver.ts","../src/modules/conversion/detectors/SelectorResolver.ts","../src/modules/conversion/detectors/configured/ConfiguredFormDetector.ts","../src/modules/conversion/detectors/configured/ConfiguredSelectorDetector.ts","../src/modules/conversion/detectors/card/card-field-detection.ts","../src/modules/conversion/detectors/card/CardDetector.ts","../src/modules/conversion/detectors/checkout/CheckoutDetector.ts","../src/modules/conversion/detectors/selector/selector-utils.ts","../src/modules/conversion/detectors/selector/SelectorDetector.ts","../src/modules/conversion/detectors/text/TextDetector.ts","../src/modules/conversion/detectors/url/HistoryNavigationPatch.ts","../src/modules/conversion/detectors/url/UrlDetector.ts","../src/modules/conversion/auto/AutoTrackerFactory.ts","../src/modules/conversion/dedupe/ConversionDeduper.ts","../src/modules/conversion/dedupe/AddToCartDedupe.ts","../src/modules/conversion/dedupe/dedupe-key.ts","../src/modules/conversion/tracks/BaseTracker.ts","../src/modules/conversion/tracks/AddPaymentInfoTracker.ts","../src/modules/conversion/tracks/AddToCartTracker.ts","../src/modules/conversion/tracks/InitiateCheckoutTracker.ts","../src/modules/conversion/tracks/LeadTracker.ts","../src/modules/conversion/tracks/PurchaseTracker.ts","../src/modules/conversion/tracks/RemoveFromCartTracker.ts","../src/modules/conversion/tracks/SearchTracker.ts","../src/modules/conversion/tracks/ViewContentTracker.ts","../src/modules/conversion/tracks/TrackerFactory.ts","../src/modules/conversion/conversion.engine.ts","../src/modules/conversion/conversion.module.ts","../src/modules/core/engines/fingerprint/FingerprintEngine.ts","../src/modules/core/engines/pageview/NavigationObserver.ts","../src/modules/core/engines/pageview/PageViewDeduper.ts","../src/modules/core/engines/pageview/PageViewEngine.ts","../src/modules/core/engines/session/SessionEngine.ts","../src/modules/core/engines/visitor/VisitorEngine.ts","../src/modules/core/core.module.ts","../src/integration/DestinationRegistry.ts","../src/integration/DestinationMetrics.ts","../src/integration/DestinationLogger.ts","../src/integration/DestinationErrorHandler.ts","../src/integration/DestinationExecutor.ts","../src/integration/DestinationDispatcher.ts","../src/integration/DestinationPipeline.ts","../src/integration/DestinationSubscriber.ts","../src/integration/adapters/BaseDestinationAdapter.ts","../src/integration/adapters/ConsoleDestination.ts","../src/integration/adapters/MemoryDestination.ts","../src/integration/adapters/MockDestination.ts","../src/integration/browser/ExternalPageViewDeduper.ts","../src/integration/browser/ScriptLoader.ts","../src/integration/adapters/browser/meta/types.ts","../src/integration/adapters/browser/meta/MetaScriptLoader.ts","../src/integration/adapters/browser/meta/MetaBrowserDestination.ts","../src/integration/adapters/browser/google/types.ts","../src/integration/adapters/browser/google/GoogleScriptLoader.ts","../src/integration/adapters/browser/google/GoogleBrowserDestination.ts","../src/integration/adapters/browser/tiktok/types.ts","../src/integration/adapters/browser/tiktok/TikTokScriptLoader.ts","../src/integration/adapters/browser/tiktok/TikTokBrowserDestination.ts","../src/integration/IntegrationEngine.ts","../src/modules/integrations/integrations.module.ts","../src/modules/privacy/privacy.module.ts","../src/transport/subscriber/DispatcherSubscriber.ts","../src/transport/batch/BatchManager.ts","../src/transport/compression/IdentityCompressionStrategy.ts","../src/transport/compression/index.ts","../src/transport/coordination/CoordinationManager.ts","../src/transport/dead-letter/DeadLetterManager.ts","../src/transport/delivery/TransportDelivery.ts","../src/transport/flush/FlushManager.ts","../src/transport/network/OfflineDetector.ts","../src/transport/ordering/OrderingManager.ts","../src/transport/pipeline/stages/EnqueueStage.ts","../src/transport/pipeline/stages/NormalizeStage.ts","../src/transport/pipeline/stages/ValidateStage.ts","../src/transport/pipeline/TransportPipeline.ts","../src/transport/queue/PersistentQueue.ts","../src/transport/queue/MemoryQueue.ts","../src/transport/queue/storage/MemoryQueueStorage.ts","../src/transport/queue/storage/LocalStorageQueueStorage.ts","../src/transport/queue/storage/IndexedDBQueueStorage.ts","../src/transport/queue/storage/StorageFactory.ts","../src/transport/replay/ReplayManager.ts","../src/transport/resilience/BackpressureManager.ts","../src/transport/resilience/CircuitBreaker.ts","../src/transport/resilience/CircuitBreakerSender.ts","../src/transport/retry/types.ts","../src/transport/retry/RetryEngine.ts","../src/transport/sender/EventPayloadBuilder.ts","../src/transport/network/fetchWithTimeout.ts","../src/transport/sender/HttpSender.ts","../src/transport/sender/MockSender.ts","../src/transport/sender/TimedSender.ts","../src/transport/transport.engine.ts","../src/transport/transport.module.ts","../src/runtime/ModuleRegistry.ts","../src/events/builder/BaseEventBuilder.ts","../src/logger/ConsolePixelLogger.ts","../src/services/attribution/types.ts","../src/services/attribution/ClickIdParser.ts","../src/services/attribution/CookieCollector.ts","../src/services/attribution/AttributionCollector.ts","../src/services/attribution/AttributionStore.ts","../src/services/attribution/AttributionService.ts","../src/services/browser-metadata/BrowserMetadataService.ts","../src/services/dispatcher/DispatcherService.ts","../src/services/fingerprint/FingerprintService.ts","../src/services/storage/BrowserStorageAdapter.ts","../src/services/storage/MemoryStorageAdapter.ts","../src/services/storage/StorageService.ts","../src/services/storage/StorageFactory.ts","../src/services/session/session-id.ts","../src/services/session/SessionService.ts","../src/services/visitor/visitor-id.ts","../src/services/visitor/VisitorService.ts","../src/runtime/PixelRuntime.ts","../src/pixel/Pixel.ts","../src/config/defaults/attribution.ts","../src/config/defaults/modules/behavior.ts","../src/config/defaults/modules/conversion.ts","../src/config/defaults/modules/core.ts","../src/config/defaults/modules/integrations.ts","../src/config/defaults/modules/privacy.ts","../src/config/defaults/modules/transport.ts","../src/config/defaults/pixel-default-config.ts"],"sourcesContent":["export { Pixel } from './pixel/Pixel';\nexport { DEFAULT_PIXEL_CONFIG } from './config/defaults/pixel-default-config';\nexport type { PixelConfig } from './config/types/pixel';\nexport { resolveStorageAdapterName } from './services/storage/StorageFactory';\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\nimport type { PixelEvent } from '@/events';\n\nimport type { IBehaviorTracker } from '../contracts/IBehaviorTracker';\n\ntype ListenerTarget = 'window' | 'document';\n\ntype ManagedListener = {\n readonly target: ListenerTarget;\n readonly type: string;\n readonly handler: EventListener;\n readonly options?: boolean | AddEventListenerOptions;\n};\n\nexport abstract class BehaviorTrackerBase implements IBehaviorTracker {\n protected readonly context: PixelRuntimeContext;\n\n private active = false;\n\n private readonly managedListeners: ManagedListener[] = [];\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n init(): void {\n if (this.active) return;\n this.onInit();\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n this.onDestroy();\n this.removeAllManagedListeners();\n this.active = false;\n }\n\n protected abstract onInit(): void;\n\n protected abstract onDestroy(): void;\n\n protected isWindowAvailable(): boolean {\n return typeof window !== 'undefined';\n }\n\n protected isDocumentAvailable(): boolean {\n return typeof document !== 'undefined';\n }\n\n protected addWindowListener<K extends keyof WindowEventMap>(\n type: K,\n handler: (event: WindowEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void {\n if (!this.isWindowAvailable()) return;\n\n const listener = handler as EventListener;\n window.addEventListener(type, listener, options);\n this.managedListeners.push({ target: 'window', type, handler: listener, options });\n }\n\n protected addDocumentListener<K extends keyof DocumentEventMap>(\n type: K,\n handler: (event: DocumentEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void {\n if (!this.isDocumentAvailable()) return;\n\n const listener = handler as EventListener;\n document.addEventListener(type, listener, options);\n this.managedListeners.push({\n target: 'document',\n type,\n handler: listener,\n options,\n });\n }\n\n protected removeAllManagedListeners(): void {\n for (const entry of this.managedListeners) {\n if (entry.target === 'window' && this.isWindowAvailable()) {\n window.removeEventListener(entry.type, entry.handler, entry.options);\n } else if (entry.target === 'document' && this.isDocumentAvailable()) {\n document.removeEventListener(entry.type, entry.handler, entry.options);\n }\n }\n this.managedListeners.length = 0;\n }\n\n protected clearManagedTimeout(\n timer: ReturnType<typeof setTimeout> | null\n ): null {\n if (timer) clearTimeout(timer);\n return null;\n }\n\n protected dispatchEngagement<T extends { type: string }>(\n partial: T & { category: 'ENGAGEMENT' }\n ): void {\n const event = this.context.services.eventBuilder.build(\n partial\n ) as PixelEvent;\n this.context.services.dispatcher.dispatch(event);\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BehaviorTrackerBase } from './BehaviorTrackerBase';\n\n/** Alinhado ao legado: throttle fixo de 100ms. */\nconst SCROLL_THROTTLE_MS = 100;\n\ninterface ScrollState {\n maxScrollPercent: number;\n scrollEvents: number;\n scrollVelocityAvg: number;\n lastScrollAt: number;\n}\n\nexport class ScrollTracker extends BehaviorTrackerBase {\n private state: ScrollState = {\n maxScrollPercent: 0,\n scrollEvents: 0,\n scrollVelocityAvg: 0,\n lastScrollAt: 0,\n };\n\n private throttleTimer: ReturnType<typeof setTimeout> | null = null;\n\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n private lastScrollY = 0;\n\n private lastScrollTime = 0;\n\n private velocitySum = 0;\n\n private crossedThresholds = new Set<number>();\n\n private lastDispatchedMaxPercent = -1;\n\n private lastDispatchAt = 0;\n\n constructor(context: PixelRuntimeContext) {\n super(context);\n }\n\n protected onInit(): void {\n if (!this.isWindowAvailable()) return;\n\n this.resetState();\n this.lastScrollY = window.scrollY;\n this.lastScrollTime = Date.now();\n\n this.addWindowListener('scroll', () => this.handleScroll(), {\n passive: true,\n });\n }\n\n protected onDestroy(): void {\n this.throttleTimer = this.clearManagedTimeout(this.throttleTimer);\n this.debounceTimer = this.clearManagedTimeout(this.debounceTimer);\n }\n\n private resetState(): void {\n this.state = {\n maxScrollPercent: 0,\n scrollEvents: 0,\n scrollVelocityAvg: 0,\n lastScrollAt: 0,\n };\n this.lastScrollY = 0;\n this.lastScrollTime = 0;\n this.velocitySum = 0;\n this.crossedThresholds.clear();\n this.lastDispatchedMaxPercent = -1;\n this.lastDispatchAt = 0;\n }\n\n private getMaxScrollPercent(): number {\n if (!this.isWindowAvailable() || !this.isDocumentAvailable()) {\n return 0;\n }\n\n const doc = document.documentElement;\n const bodyScroll = document.body ? document.body.scrollHeight : 0;\n const scrollHeight = Math.max(doc.scrollHeight, bodyScroll);\n const clientHeight = doc.clientHeight;\n\n if (scrollHeight <= clientHeight) return 100;\n\n const maxScroll = scrollHeight - clientHeight;\n const current = window.scrollY || window.pageYOffset;\n return Math.min(100, Math.round((current / maxScroll) * 100));\n }\n\n private canDispatch(minIntervalMs: number): boolean {\n return Date.now() - this.lastDispatchAt >= minIntervalMs;\n }\n\n private handleScroll(): void {\n if (!this.isWindowAvailable()) return;\n\n const { debounceMs } = this.context.config.modules.behavior.trackers.scroll;\n\n if (this.throttleTimer) return;\n\n this.throttleTimer = setTimeout(() => {\n this.throttleTimer = null;\n this.updateScrollState();\n this.maybeDispatchOnThresholdCrossing(debounceMs);\n\n this.debounceTimer = this.clearManagedTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.maybeDispatchOnScrollEnd(debounceMs);\n }, debounceMs);\n }, SCROLL_THROTTLE_MS);\n }\n\n private updateScrollState(): void {\n if (!this.isWindowAvailable()) return;\n\n const now = Date.now();\n const scrollY = window.scrollY || window.pageYOffset;\n\n const percent = this.getMaxScrollPercent();\n if (percent > this.state.maxScrollPercent) {\n this.state.maxScrollPercent = percent;\n }\n\n this.state.scrollEvents += 1;\n this.state.lastScrollAt = now;\n\n if (this.state.scrollEvents > 1 && this.lastScrollTime > 0) {\n const deltaSeconds = (now - this.lastScrollTime) / 1000;\n const deltaY = Math.abs(scrollY - this.lastScrollY);\n if (deltaSeconds > 0) {\n const velocity = deltaY / deltaSeconds;\n this.velocitySum += velocity;\n this.state.scrollVelocityAvg =\n this.velocitySum / (this.state.scrollEvents - 1);\n }\n }\n\n this.lastScrollY = scrollY;\n this.lastScrollTime = now;\n }\n\n private maybeDispatchOnThresholdCrossing(minIntervalMs: number): void {\n const { thresholds } = this.context.config.modules.behavior.trackers.scroll;\n const percent = this.state.maxScrollPercent;\n\n let crossedNew = false;\n for (const threshold of thresholds) {\n if (percent >= threshold && !this.crossedThresholds.has(threshold)) {\n this.crossedThresholds.add(threshold);\n crossedNew = true;\n }\n }\n\n if (crossedNew && this.canDispatch(minIntervalMs)) {\n this.emitScrollEvent();\n }\n }\n\n private maybeDispatchOnScrollEnd(minIntervalMs: number): void {\n if (this.state.maxScrollPercent === this.lastDispatchedMaxPercent) return;\n if (!this.canDispatch(minIntervalMs)) return;\n\n this.emitScrollEvent();\n }\n\n private emitScrollEvent(): void {\n this.dispatchEngagement({\n type: 'SCROLL',\n category: 'ENGAGEMENT',\n maxScrollPercent: this.state.maxScrollPercent,\n scrollEvents: this.state.scrollEvents,\n scrollVelocityAvg: this.state.scrollVelocityAvg,\n lastScrollAt: this.state.lastScrollAt,\n });\n this.lastDispatchedMaxPercent = this.state.maxScrollPercent;\n this.lastDispatchAt = Date.now();\n }\n}\n","import type { ElementDescriptor } from '@/events/shared/ElementDescriptor';\n\nconst MAX_TEXT_LENGTH = 80;\n\nexport function describeElement(element: Element | null): ElementDescriptor | undefined {\n if (!element) return undefined;\n\n const htmlElement = element as HTMLElement;\n const classes = element.classList?.length\n ? Array.from(element.classList)\n : undefined;\n\n let text: string | undefined;\n const rawText = htmlElement.innerText?.trim() ?? htmlElement.textContent?.trim();\n if (rawText) {\n text =\n rawText.length > MAX_TEXT_LENGTH\n ? `${rawText.slice(0, MAX_TEXT_LENGTH)}…`\n : rawText;\n }\n\n const dataset: Record<string, string> = {};\n if (htmlElement.dataset) {\n for (const [key, value] of Object.entries(htmlElement.dataset)) {\n if (value !== undefined) {\n dataset[key] = value;\n }\n }\n }\n\n return {\n tagName: element.tagName?.toLowerCase(),\n id: element.id || undefined,\n classes,\n text,\n role: htmlElement.getAttribute('role') ?? undefined,\n name: htmlElement.getAttribute('name') ?? undefined,\n dataset: Object.keys(dataset).length > 0 ? dataset : undefined,\n };\n}\n\n/** Fingerprint estável alinhado ao algoritmo legado (tag + id + classes + data-*). */\nexport function getElementFingerprint(el: EventTarget | null): string {\n if (!el || !(el instanceof Element)) return 'unknown';\n\n const tag = el.tagName.toLowerCase();\n const id = el.id ? `#${el.id}` : '';\n const classes =\n el.className && typeof el.className === 'string'\n ? `.${el.className.trim().split(/\\s+/).slice(0, 3).join('.')}`\n : '';\n\n const dataAttrs: string[] = [];\n if (typeof el.getAttributeNames === 'function') {\n el.getAttributeNames()\n .filter(name => name.startsWith('data-'))\n .slice(0, 5)\n .sort()\n .forEach(name => {\n const value = el.getAttribute(name);\n if (value != null) {\n dataAttrs.push(`${name}=${value.slice(0, 50)}`);\n }\n });\n }\n\n return [tag, id, classes, dataAttrs.join('|')].filter(Boolean).join('');\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BehaviorTrackerBase } from './BehaviorTrackerBase';\nimport { describeElement, getElementFingerprint } from './utils/element';\n\ninterface ClickState {\n clickCount: number;\n rageClickCount: number;\n lastClickAt: number;\n}\n\nexport class ClickTracker extends BehaviorTrackerBase {\n private state: ClickState = {\n clickCount: 0,\n rageClickCount: 0,\n lastClickAt: 0,\n };\n\n private clickHistory = new Map<string, number[]>();\n\n private rageCooldownUntil = new Map<string, number>();\n\n constructor(context: PixelRuntimeContext) {\n super(context);\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n\n this.resetState();\n this.addDocumentListener(\n 'click',\n (event: MouseEvent) => this.handleClick(event),\n true\n );\n }\n\n protected onDestroy(): void {\n this.clickHistory.clear();\n this.rageCooldownUntil.clear();\n }\n\n private resetState(): void {\n this.state = {\n clickCount: 0,\n rageClickCount: 0,\n lastClickAt: 0,\n };\n this.clickHistory.clear();\n this.rageCooldownUntil.clear();\n }\n\n private handleClick(event: MouseEvent): void {\n const now = Date.now();\n const { rageClick } = this.context.config.modules.behavior.trackers.click;\n\n this.state.clickCount += 1;\n this.state.lastClickAt = now;\n\n const target = event.target instanceof Element ? event.target : null;\n const currentTarget =\n event.currentTarget instanceof Element ? event.currentTarget : null;\n\n const targetDescriptor = describeElement(target);\n const currentTargetDescriptor = describeElement(currentTarget);\n\n this.dispatchEngagement({\n type: 'PAGE_CLICK',\n category: 'ENGAGEMENT',\n clickCount: this.state.clickCount,\n rageClickCount: this.state.rageClickCount,\n lastClickAt: now,\n target: targetDescriptor,\n currentTarget: currentTargetDescriptor,\n clientX: event.clientX,\n clientY: event.clientY,\n pageX: event.pageX,\n pageY: event.pageY,\n offsetX: event.offsetX,\n offsetY: event.offsetY,\n });\n\n if (!target || !rageClick.enabled) return;\n\n const fingerprint = getElementFingerprint(target);\n\n const cooldownUntil = this.rageCooldownUntil.get(fingerprint) ?? 0;\n if (now < cooldownUntil) return;\n\n const history = this.clickHistory.get(fingerprint) ?? [];\n const recent = history.filter(ts => now - ts < rageClick.windowMs);\n recent.push(now);\n this.clickHistory.set(fingerprint, recent);\n\n if (recent.length >= rageClick.threshold) {\n this.state.rageClickCount += 1;\n this.dispatchEngagement({\n type: 'RAGE_CLICK',\n category: 'ENGAGEMENT',\n threshold: rageClick.threshold,\n windowMs: rageClick.windowMs,\n clickCount: recent.length,\n target: targetDescriptor,\n });\n this.clickHistory.delete(fingerprint);\n this.rageCooldownUntil.set(fingerprint, now + rageClick.windowMs);\n }\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BehaviorTrackerBase } from './BehaviorTrackerBase';\n\ninterface VisibilityState {\n isVisible: boolean;\n visibleSince: number;\n hiddenAt: number | null;\n}\n\nexport class VisibilityTracker extends BehaviorTrackerBase {\n private state: VisibilityState = {\n isVisible: true,\n visibleSince: 0,\n hiddenAt: null,\n };\n\n constructor(context: PixelRuntimeContext) {\n super(context);\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n\n const now = Date.now();\n const isVisible = document.visibilityState === 'visible';\n\n this.state = {\n isVisible,\n visibleSince: now,\n hiddenAt: isVisible ? null : now,\n };\n\n this.addDocumentListener('visibilitychange', () =>\n this.handleVisibilityChange()\n );\n this.emitVisibilityEvent();\n }\n\n protected onDestroy(): void {}\n\n private handleVisibilityChange(): void {\n if (!this.isDocumentAvailable()) return;\n\n const now = Date.now();\n const isVisible = document.visibilityState === 'visible';\n\n if (isVisible) {\n this.state = {\n isVisible: true,\n visibleSince: now,\n hiddenAt: null,\n };\n } else {\n this.state = {\n isVisible: false,\n visibleSince: this.state.visibleSince,\n hiddenAt: now,\n };\n }\n\n this.emitVisibilityEvent();\n }\n\n private emitVisibilityEvent(): void {\n this.dispatchEngagement({\n type: 'VISIBILITY_CHANGE',\n category: 'ENGAGEMENT',\n isVisible: this.state.isVisible,\n visibleSince: this.state.visibleSince,\n hiddenAt: this.state.hiddenAt,\n });\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BehaviorTrackerBase } from './BehaviorTrackerBase';\n\nconst ACTIVITY_EVENTS = ['mousemove', 'scroll', 'keydown', 'touchstart'] as const;\n\nexport class IdleTracker extends BehaviorTrackerBase {\n private isIdle = false;\n\n private idleSince = 0;\n\n private idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(context: PixelRuntimeContext) {\n super(context);\n }\n\n protected onInit(): void {\n if (!this.isWindowAvailable()) return;\n\n this.isIdle = false;\n this.idleSince = 0;\n this.scheduleIdleCheck();\n\n for (const eventName of ACTIVITY_EVENTS) {\n this.addWindowListener(eventName, () => this.onActivity(), {\n passive: true,\n });\n }\n }\n\n protected onDestroy(): void {\n this.idleTimer = this.clearManagedTimeout(this.idleTimer);\n this.isIdle = false;\n this.idleSince = 0;\n }\n\n private get thresholdMs(): number {\n return this.context.config.modules.behavior.trackers.idle.thresholdMs;\n }\n\n private scheduleIdleCheck(): void {\n this.idleTimer = this.clearManagedTimeout(this.idleTimer);\n this.idleTimer = setTimeout(() => this.enterIdle(), this.thresholdMs);\n }\n\n private onActivity(): void {\n const now = Date.now();\n\n if (this.isIdle) {\n const previousIdleDurationMs = Math.max(0, now - this.idleSince);\n this.isIdle = false;\n this.dispatchEngagement({\n type: 'USER_ACTIVE',\n category: 'ENGAGEMENT',\n activeAt: now,\n previousIdleDurationMs,\n });\n }\n\n this.scheduleIdleCheck();\n }\n\n private enterIdle(): void {\n if (this.isIdle) return;\n\n const now = Date.now();\n this.isIdle = true;\n this.idleSince = now;\n\n this.dispatchEngagement({\n type: 'USER_IDLE',\n category: 'ENGAGEMENT',\n idleSince: now,\n thresholdMs: this.thresholdMs,\n });\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BehaviorTrackerBase } from './BehaviorTrackerBase';\n\nconst DEFAULT_EXIT_INTENT_THRESHOLD = 5;\n\nexport class ExitIntentTracker extends BehaviorTrackerBase {\n private fired = false;\n\n constructor(context: PixelRuntimeContext) {\n super(context);\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n\n this.fired = false;\n this.addDocumentListener(\n 'mousemove',\n (event: MouseEvent) => this.handleMouseMove(event),\n { passive: true }\n );\n }\n\n protected onDestroy(): void {\n this.fired = false;\n }\n\n private handleMouseMove(event: MouseEvent): void {\n if (this.fired) return;\n if (event.clientY > DEFAULT_EXIT_INTENT_THRESHOLD) return;\n\n this.fired = true;\n const now = Date.now();\n\n this.dispatchEngagement({\n type: 'EXIT_INTENT',\n category: 'ENGAGEMENT',\n triggeredAt: now,\n clientY: event.clientY,\n });\n }\n}\n","import type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport type { IBehaviorTracker } from './contracts/IBehaviorTracker';\nimport {\n ClickTracker,\n ExitIntentTracker,\n IdleTracker,\n ScrollTracker,\n VisibilityTracker,\n} from './trackers';\n\nexport class BehaviorModule implements PixelModule {\n readonly name = 'behavior' as const;\n\n private trackers: IBehaviorTracker[] = [];\n\n private active = false;\n\n init(context: PixelRuntimeContext): void {\n if (this.active) {\n context.logger.debug('[Pixel] Behavior module already initialized');\n return;\n }\n\n const { enabled, trackers: trackerConfig } = context.config.modules.behavior;\n\n if (!enabled) {\n context.logger.debug('[Pixel] Behavior module disabled');\n return;\n }\n\n context.logger.debug('[Pixel] Behavior module initialized');\n\n const trackers: IBehaviorTracker[] = [];\n\n if (trackerConfig.scroll.enabled) {\n trackers.push(new ScrollTracker(context));\n }\n if (trackerConfig.click.enabled) {\n trackers.push(new ClickTracker(context));\n }\n if (trackerConfig.visibility.enabled) {\n trackers.push(new VisibilityTracker(context));\n }\n if (trackerConfig.idle.enabled) {\n trackers.push(new IdleTracker(context));\n }\n if (trackerConfig.exitIntent.enabled) {\n trackers.push(new ExitIntentTracker(context));\n }\n\n for (const tracker of trackers) {\n tracker.init();\n }\n\n this.trackers = trackers;\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n\n for (let i = this.trackers.length - 1; i >= 0; i -= 1) {\n this.trackers[i]?.destroy();\n }\n this.trackers = [];\n this.active = false;\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport type { IConversionDetector } from '../contracts';\n\ntype ManagedListener = {\n readonly target: 'window' | 'document';\n readonly type: string;\n readonly handler: EventListener;\n readonly options?: boolean | AddEventListenerOptions;\n};\n\nexport abstract class BaseAutoTracker implements IConversionDetector {\n protected readonly context: PixelRuntimeContext;\n\n private active = false;\n\n private readonly managedListeners: ManagedListener[] = [];\n\n private observer: MutationObserver | null = null;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n init(): void {\n if (this.active) return;\n this.onInit();\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n this.onDestroy();\n this.removeAllManagedListeners();\n this.observer?.disconnect();\n this.observer = null;\n this.active = false;\n }\n\n protected abstract onInit(): void;\n\n protected abstract onDestroy(): void;\n\n protected isWindowAvailable(): boolean {\n return typeof window !== 'undefined';\n }\n\n protected isDocumentAvailable(): boolean {\n return typeof document !== 'undefined';\n }\n\n protected addWindowListener<K extends keyof WindowEventMap>(\n type: K,\n handler: (event: WindowEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void {\n if (!this.isWindowAvailable()) return;\n const listener = handler as EventListener;\n window.addEventListener(type, listener, options);\n this.managedListeners.push({ target: 'window', type, handler: listener, options });\n }\n\n protected addDocumentListener<K extends keyof DocumentEventMap>(\n type: K,\n handler: (event: DocumentEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void {\n if (!this.isDocumentAvailable()) return;\n const listener = handler as EventListener;\n document.addEventListener(type, listener, options);\n this.managedListeners.push({\n target: 'document',\n type,\n handler: listener,\n options,\n });\n }\n\n protected observeDom(callback: () => void): void {\n if (!this.isDocumentAvailable()) return;\n this.observer?.disconnect();\n this.observer = new MutationObserver(() => callback());\n if (document.body) {\n this.observer.observe(document.body, { childList: true, subtree: true });\n }\n }\n\n protected clearManagedTimeout(\n timer: ReturnType<typeof setTimeout> | null\n ): null {\n if (timer) clearTimeout(timer);\n return null;\n }\n\n protected removeAllManagedListeners(): void {\n for (const entry of this.managedListeners) {\n if (entry.target === 'window' && this.isWindowAvailable()) {\n window.removeEventListener(entry.type, entry.handler, entry.options);\n } else if (entry.target === 'document' && this.isDocumentAvailable()) {\n document.removeEventListener(entry.type, entry.handler, entry.options);\n }\n }\n this.managedListeners.length = 0;\n }\n}\n","import type { CommerceProduct } from '@/config/shared/commerce';\n\nexport type ProductCatalogOptions = {\n readonly defaultCurrency?: string;\n};\n\nexport type ProductCatalogSnapshot = {\n readonly products: CommerceProduct[];\n readonly count: number;\n};\n\n/**\n * Catálogo de produtos configurados em `conversion.commerce.catalog`.\n * Isolado por instância — sem estado global / module-level.\n * Não acessa DOM, Transport nem altera payloads de eventos.\n */\nexport class ProductCatalog {\n private readonly productsById = new Map<string, CommerceProduct>();\n\n private readonly productsBySku = new Map<string, CommerceProduct>();\n\n private readonly orderedIds: string[] = [];\n\n constructor(\n products: readonly CommerceProduct[] | undefined = [],\n options: ProductCatalogOptions = {}\n ) {\n this.indexProducts(products ?? [], options.defaultCurrency);\n }\n\n list(): CommerceProduct[] {\n return this.orderedIds.map(id => this.cloneProduct(this.productsById.get(id)!));\n }\n\n getById(id: string): CommerceProduct | null {\n if (!id) return null;\n const product = this.productsById.get(id);\n return product ? this.cloneProduct(product) : null;\n }\n\n getBySku(sku: string): CommerceProduct | null {\n if (!sku) return null;\n const product = this.productsBySku.get(sku);\n return product ? this.cloneProduct(product) : null;\n }\n\n hasProduct(id: string): boolean {\n return Boolean(id) && this.productsById.has(id);\n }\n\n getSnapshot(): ProductCatalogSnapshot {\n const products = this.list();\n return { products, count: products.length };\n }\n\n private indexProducts(\n products: readonly CommerceProduct[],\n defaultCurrency?: string\n ): void {\n for (const raw of products) {\n if (!raw || typeof raw !== 'object') continue;\n\n const id = typeof raw.id === 'string' ? raw.id.trim() : '';\n if (!id) continue;\n\n // Duplicado por id: mantém o primeiro (determinístico).\n if (this.productsById.has(id)) continue;\n\n const product = this.normalizeProduct(raw, id, defaultCurrency);\n this.productsById.set(id, product);\n this.orderedIds.push(id);\n\n const sku =\n typeof product.sku === 'string' ? product.sku.trim() : '';\n if (sku && !this.productsBySku.has(sku)) {\n this.productsBySku.set(sku, product);\n }\n }\n }\n\n private normalizeProduct(\n raw: CommerceProduct,\n id: string,\n defaultCurrency?: string\n ): CommerceProduct {\n const sku =\n typeof raw.sku === 'string' && raw.sku.trim()\n ? raw.sku.trim()\n : undefined;\n\n const currency =\n typeof raw.currency === 'string' && raw.currency.trim()\n ? raw.currency.trim()\n : defaultCurrency;\n\n const quantity =\n typeof raw.quantity === 'number' && Number.isFinite(raw.quantity)\n ? raw.quantity\n : undefined;\n\n return {\n ...raw,\n id,\n ...(sku !== undefined ? { sku } : {}),\n ...(currency !== undefined ? { currency } : {}),\n ...(quantity !== undefined ? { quantity } : {}),\n ...(raw.metadata ? { metadata: { ...raw.metadata } } : {}),\n };\n }\n\n private cloneProduct(product: CommerceProduct): CommerceProduct {\n return {\n ...product,\n ...(product.metadata ? { metadata: { ...product.metadata } } : {}),\n };\n }\n}\n","import type { CommerceItem } from '@/config/shared/commerce';\n\nexport type CommerceStateOptions = {\n /**\n * Quando `false`, `upsertItem` só atualiza itens já presentes\n * (não adiciona novos productIds). Default: `true`.\n */\n readonly allowDynamicItems?: boolean;\n};\n\nexport type CommerceStateSnapshot = {\n readonly selectedItems: CommerceItem[];\n readonly count: number;\n};\n\n/**\n * Estado em memória do checkout/cart da instância.\n * Inicializado com `conversion.commerce.checkout.selectedItems`.\n * Não persiste, não acessa DOM/Transport e não dispara eventos.\n */\nexport class CommerceState {\n private readonly itemsByProductId = new Map<string, CommerceItem>();\n\n private readonly allowDynamicItems: boolean;\n\n constructor(\n initialItems: readonly CommerceItem[] | undefined = [],\n options: CommerceStateOptions = {}\n ) {\n this.allowDynamicItems = options.allowDynamicItems !== false;\n this.seed(initialItems ?? []);\n }\n\n getSelectedItems(): CommerceItem[] {\n return Array.from(this.itemsByProductId.values()).map(item =>\n this.cloneItem(item)\n );\n }\n\n hasItem(productId: string): boolean {\n return Boolean(productId) && this.itemsByProductId.has(productId);\n }\n\n getItem(productId: string): CommerceItem | null {\n if (!productId) return null;\n const item = this.itemsByProductId.get(productId);\n return item ? this.cloneItem(item) : null;\n }\n\n /**\n * Insere ou atualiza item.\n * - Sem `productId` → no-op\n * - `selected === false` → remove se existir / não adiciona\n * - `quantity <= 0` → remove\n * - `allowDynamicItems === false` e item novo → no-op\n */\n upsertItem(item: CommerceItem): void {\n if (!item || typeof item !== 'object') return;\n\n const productId =\n typeof item.productId === 'string' ? item.productId.trim() : '';\n if (!productId) return;\n\n if (item.selected === false) {\n this.itemsByProductId.delete(productId);\n return;\n }\n\n const quantity = this.normalizeQuantity(item.quantity);\n if (quantity <= 0) {\n this.itemsByProductId.delete(productId);\n return;\n }\n\n const exists = this.itemsByProductId.has(productId);\n if (!exists && !this.allowDynamicItems) return;\n\n const previous = this.itemsByProductId.get(productId);\n const metadata = item.metadata\n ? { ...item.metadata }\n : previous?.metadata\n ? { ...previous.metadata }\n : undefined;\n\n const next: CommerceItem = {\n ...previous,\n ...item,\n productId,\n quantity,\n selected: true,\n ...(metadata ? { metadata } : {}),\n };\n\n this.itemsByProductId.set(productId, next);\n }\n\n removeItem(productId: string): void {\n if (!productId) return;\n this.itemsByProductId.delete(productId);\n }\n\n /**\n * Atualiza quantidade. `quantity <= 0` remove o item.\n */\n updateQuantity(productId: string, quantity: number): void {\n if (!productId || !this.itemsByProductId.has(productId)) return;\n\n const normalized = this.normalizeQuantity(quantity);\n if (normalized <= 0) {\n this.itemsByProductId.delete(productId);\n return;\n }\n\n const current = this.itemsByProductId.get(productId)!;\n this.itemsByProductId.set(productId, {\n ...current,\n quantity: normalized,\n });\n }\n\n clear(): void {\n this.itemsByProductId.clear();\n }\n\n getSnapshot(): CommerceStateSnapshot {\n const selectedItems = this.getSelectedItems();\n return { selectedItems, count: selectedItems.length };\n }\n\n private seed(initialItems: readonly CommerceItem[]): void {\n for (const item of initialItems) {\n // Seed ignora allowDynamicItems — itens da config sempre entram\n // (exceto selected:false / inválidos / quantity<=0).\n this.seedItem(item);\n }\n }\n\n private seedItem(item: CommerceItem): void {\n if (!item || typeof item !== 'object') return;\n\n const productId =\n typeof item.productId === 'string' ? item.productId.trim() : '';\n if (!productId) return;\n if (item.selected === false) return;\n\n const quantity = this.normalizeQuantity(item.quantity);\n if (quantity <= 0) return;\n\n // Duplicado por productId no seed: mantém o primeiro.\n if (this.itemsByProductId.has(productId)) return;\n\n this.itemsByProductId.set(productId, {\n ...item,\n productId,\n quantity,\n selected: true,\n ...(item.metadata ? { metadata: { ...item.metadata } } : {}),\n });\n }\n\n private normalizeQuantity(quantity: number | undefined): number {\n if (quantity === undefined || quantity === null) return 1;\n if (typeof quantity !== 'number' || !Number.isFinite(quantity)) return 1;\n return quantity;\n }\n\n private cloneItem(item: CommerceItem): CommerceItem {\n return {\n ...item,\n ...(item.metadata ? { metadata: { ...item.metadata } } : {}),\n };\n }\n}\n","/**\n * Utilitários compartilhados pelos extractors de commerce.\n * SSR-safe: sem acesso obrigatório a window/document.\n */\n\nconst SENSITIVE_PATTERN =\n /\\b(card|cardnumber|card_number|cc[-_]?number|credit[-_]?card|cvv|cvc|security(?:code)?|expir(?:y|ation)|exp(?:date|iry)?|password|senha|secret|token)\\b/i;\n\nexport function isBrowserElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\nexport function isHtmlFormElement(value: unknown): value is HTMLFormElement {\n return typeof HTMLFormElement !== 'undefined' && value instanceof HTMLFormElement;\n}\n\nexport function isHtmlInputElement(value: unknown): value is HTMLInputElement {\n return typeof HTMLInputElement !== 'undefined' && value instanceof HTMLInputElement;\n}\n\nexport function trimNonEmpty(value: unknown): string | undefined {\n if (value == null) return undefined;\n const text = String(value).trim();\n return text.length > 0 ? text : undefined;\n}\n\n/**\n * Normaliza preço para number decimal.\n * Exemplos: \"R$ 197,00\" → 197 · \"197.00\" → 197 · \"19700\" → 19700\n * Não divide automaticamente por 100 (centavos).\n */\nexport function normalizePrice(value: unknown): number | undefined {\n const raw = trimNonEmpty(value);\n if (!raw) return undefined;\n\n let cleaned = raw.replace(/[^\\d.,\\-]/g, '');\n if (!cleaned || cleaned === '-' || cleaned === '.' || cleaned === ',') {\n return undefined;\n }\n\n const hasComma = cleaned.includes(',');\n const hasDot = cleaned.includes('.');\n\n if (hasComma && hasDot) {\n // \"1.234,56\" (BR) vs \"1,234.56\" (US) — último separador é decimal.\n if (cleaned.lastIndexOf(',') > cleaned.lastIndexOf('.')) {\n cleaned = cleaned.replace(/\\./g, '').replace(',', '.');\n } else {\n cleaned = cleaned.replace(/,/g, '');\n }\n } else if (hasComma) {\n cleaned = cleaned.replace(',', '.');\n }\n\n const parsed = Number(cleaned);\n if (!Number.isFinite(parsed)) return undefined;\n return parsed;\n}\n\n/**\n * Normaliza quantity para number.\n * Inválido ou <= 0 → undefined (não preenche default nesta etapa).\n */\nexport function normalizeQuantity(value: unknown): number | undefined {\n const raw = trimNonEmpty(value);\n if (!raw) return undefined;\n\n const parsed = Number(raw.replace(',', '.'));\n if (!Number.isFinite(parsed) || parsed <= 0) return undefined;\n return parsed;\n}\n\nexport function isSensitiveField(el: Element): boolean {\n if (isHtmlInputElement(el) && el.type === 'password') return true;\n\n const haystack = [\n el.getAttribute('name'),\n el.getAttribute('id'),\n el.getAttribute('autocomplete'),\n el.getAttribute('placeholder'),\n el.getAttribute('aria-label'),\n ]\n .filter(Boolean)\n .join(' ');\n\n return SENSITIVE_PATTERN.test(haystack);\n}\n\nexport function readAttribute(\n element: Element,\n names: readonly string[]\n): string | undefined {\n for (const name of names) {\n if (!name) continue;\n const attrName = name.startsWith('data-') ? name : name;\n const value = trimNonEmpty(element.getAttribute(attrName));\n if (value) return value;\n }\n return undefined;\n}\n\nexport function readInputValue(el: Element): string | undefined {\n if (isSensitiveField(el)) return undefined;\n\n if (isHtmlInputElement(el) || el instanceof HTMLTextAreaElement) {\n return trimNonEmpty(el.value);\n }\n\n if (el instanceof HTMLSelectElement) {\n return trimNonEmpty(el.value);\n }\n\n return undefined;\n}\n\n/**\n * Busca valor de campo por name/id (exatos e contains) dentro de um escopo.\n * Inclui o próprio `root` quando ele é um input/textarea/select.\n */\nexport function findFieldValue(\n root: Element,\n candidates: readonly string[]\n): string | undefined {\n for (const candidate of candidates) {\n if (!candidate) continue;\n\n const exact = root.querySelector(\n `input[name=\"${cssEscape(candidate)}\"], textarea[name=\"${cssEscape(candidate)}\"], select[name=\"${cssEscape(candidate)}\"], input[id=\"${cssEscape(candidate)}\"]`\n );\n if (exact) {\n const value = readInputValue(exact);\n if (value) return value;\n }\n }\n\n const inputs: Element[] = [];\n if (\n isHtmlInputElement(root) ||\n root instanceof HTMLTextAreaElement ||\n root instanceof HTMLSelectElement\n ) {\n inputs.push(root);\n }\n inputs.push(...Array.from(root.querySelectorAll('input, textarea, select')));\n\n for (const candidate of candidates) {\n const needle = candidate.toLowerCase();\n for (const input of inputs) {\n if (isSensitiveField(input)) continue;\n const name = (input.getAttribute('name') ?? '').toLowerCase();\n const id = (input.getAttribute('id') ?? '').toLowerCase();\n if (!fieldNameMatches(name, id, needle)) continue;\n const value = readInputValue(input);\n if (value) return value;\n }\n }\n\n return undefined;\n}\n\nfunction fieldNameMatches(\n name: string,\n id: string,\n needle: string\n): boolean {\n if (name === needle || id === needle) return true;\n // Chaves curtas (id, tel, qty…) só batem exact — evita falso positivo.\n if (needle.length < 4) return false;\n return name.includes(needle) || id.includes(needle);\n}\n\nfunction cssEscape(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(/[\"\\\\]/g, '\\\\$&');\n}\n\nexport function mergeDefined<T extends Record<string, unknown>>(\n ...sources: Array<Partial<T> | null | undefined>\n): T {\n const result: Record<string, unknown> = {};\n for (const source of sources) {\n if (!source) continue;\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined || value === null || value === '') continue;\n if (result[key] !== undefined) continue; // prioridade: primeiro preenchido vence\n result[key] = value;\n }\n }\n return result as T;\n}\n\nexport function uniqueNames(\n custom: readonly string[] | undefined,\n defaults: readonly string[]\n): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const name of [...(custom ?? []), ...defaults]) {\n const trimmed = name?.trim();\n if (!trimmed || seen.has(trimmed)) continue;\n seen.add(trimmed);\n result.push(trimmed);\n }\n return result;\n}\n","import {\n findFieldValue,\n isBrowserElement,\n isHtmlFormElement,\n mergeDefined,\n readAttribute,\n readInputValue,\n trimNonEmpty,\n uniqueNames,\n} from './extractor-utils';\n\nexport type CustomerData = {\n email?: string;\n phone?: string;\n name?: string;\n firstName?: string;\n lastName?: string;\n};\n\nexport type CustomerExtractorOptions = {\n fieldMappings?: Record<string, string[]>;\n};\n\nconst DEFAULT_EMAIL_FIELDS = [\n 'email',\n 'customerEmail',\n 'customer_email',\n 'e-mail',\n] as const;\n\nconst DEFAULT_PHONE_FIELDS = [\n 'phone',\n 'telefone',\n 'tel',\n 'customerPhone',\n 'customer_phone',\n 'celular',\n 'mobile',\n] as const;\n\nconst DEFAULT_NAME_FIELDS = ['name', 'nome', 'fullName', 'full_name'] as const;\n\nconst DEFAULT_FIRST_NAME_FIELDS = [\n 'firstName',\n 'first_name',\n 'primeiro',\n 'primeiro_nome',\n 'given-name',\n] as const;\n\nconst DEFAULT_LAST_NAME_FIELDS = [\n 'lastName',\n 'last_name',\n 'sobrenome',\n 'family-name',\n] as const;\n\nconst EMAIL_ATTRS = ['data-email'] as const;\nconst PHONE_ATTRS = ['data-phone', 'data-telefone'] as const;\nconst NAME_ATTRS = ['data-name', 'data-nome'] as const;\nconst FIRST_NAME_ATTRS = ['data-first-name', 'data-firstname'] as const;\nconst LAST_NAME_ATTRS = ['data-last-name', 'data-lastname'] as const;\n\n/**\n * Extrai dados de customer a partir de Element/Form/Container.\n * Não dispara eventos, não persiste e não acessa Transport.\n *\n * Prioridade de merge: elemento alvo → form mais próximo → container.\n */\nexport class CustomerExtractor {\n private readonly fieldMappings: Record<string, string[]>;\n\n constructor(options: CustomerExtractorOptions = {}) {\n this.fieldMappings = options.fieldMappings ?? {};\n }\n\n extractFromElement(element: Element | null): CustomerData {\n if (!isBrowserElement(element)) return {};\n\n const fromSelf = this.extractFromScope(element);\n const form = element.closest('form');\n const fromForm = isHtmlFormElement(form)\n ? this.extractFromScope(form)\n : {};\n const container = this.findCustomerContainer(element);\n const fromContainer =\n container && container !== element && container !== form\n ? this.extractFromScope(container)\n : {};\n\n return mergeDefined<CustomerData>(fromSelf, fromForm, fromContainer);\n }\n\n extractFromForm(form: HTMLFormElement | null): CustomerData {\n if (!isHtmlFormElement(form)) return {};\n return this.extractFromScope(form);\n }\n\n extractFromContainer(container: Element | null): CustomerData {\n if (!isBrowserElement(container)) return {};\n return this.extractFromScope(container);\n }\n\n private extractFromScope(root: Element): CustomerData {\n const email =\n this.readTypedInput(root, 'email') ??\n this.readAutocomplete(root, 'email') ??\n readAttribute(root, EMAIL_ATTRS) ??\n findFieldValue(root, this.fieldsFor('email', DEFAULT_EMAIL_FIELDS));\n\n const phone =\n this.readTypedInput(root, 'tel') ??\n this.readAutocomplete(root, 'tel') ??\n readAttribute(root, PHONE_ATTRS) ??\n findFieldValue(root, this.fieldsFor('phone', DEFAULT_PHONE_FIELDS));\n\n const name =\n this.readAutocomplete(root, 'name') ??\n readAttribute(root, NAME_ATTRS) ??\n findFieldValue(root, this.fieldsFor('name', DEFAULT_NAME_FIELDS));\n\n const firstName =\n this.readAutocomplete(root, 'given-name') ??\n readAttribute(root, FIRST_NAME_ATTRS) ??\n findFieldValue(\n root,\n this.fieldsFor('firstName', DEFAULT_FIRST_NAME_FIELDS)\n );\n\n const lastName =\n this.readAutocomplete(root, 'family-name') ??\n readAttribute(root, LAST_NAME_ATTRS) ??\n findFieldValue(\n root,\n this.fieldsFor('lastName', DEFAULT_LAST_NAME_FIELDS)\n );\n\n return mergeDefined<CustomerData>({\n email: trimNonEmpty(email),\n phone: trimNonEmpty(phone),\n name: trimNonEmpty(name),\n firstName: trimNonEmpty(firstName),\n lastName: trimNonEmpty(lastName),\n });\n }\n\n private fieldsFor(key: string, defaults: readonly string[]): string[] {\n return uniqueNames(this.fieldMappings[key], defaults);\n }\n\n private readTypedInput(root: Element, type: string): string | undefined {\n const selector = `input[type=\"${type}\"]`;\n const input = root.matches(selector)\n ? root\n : root.querySelector(selector);\n return input ? readInputValue(input) : undefined;\n }\n\n private readAutocomplete(\n root: Element,\n autocomplete: string\n ): string | undefined {\n const selector = `input[autocomplete=\"${autocomplete}\"]`;\n const input = root.matches(selector)\n ? root\n : root.querySelector(selector);\n return input ? readInputValue(input) : undefined;\n }\n\n private findCustomerContainer(element: Element): Element | null {\n return element.closest(\n '[data-email], [data-phone], [data-name], [data-track], .lead-form, .checkout-form'\n );\n }\n}\n","import {\n findFieldValue,\n isBrowserElement,\n isHtmlFormElement,\n mergeDefined,\n normalizePrice,\n normalizeQuantity,\n readAttribute,\n trimNonEmpty,\n uniqueNames,\n} from './extractor-utils';\n\nexport type ExtractedProductData = {\n productId?: string;\n productName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n};\n\nexport type ProductExtractorOptions = {\n attributeMappings?: Record<string, string[]>;\n fieldMappings?: Record<string, string[]>;\n};\n\nconst DEFAULT_PRODUCT_ID_ATTRS = [\n 'data-product-id',\n 'data-product',\n 'data-sku',\n 'data-item-id',\n 'data-id',\n] as const;\n\nconst DEFAULT_PRODUCT_NAME_ATTRS = [\n 'data-product-name',\n 'data-name',\n 'data-item-name',\n] as const;\n\nconst DEFAULT_PRICE_ATTRS = [\n 'data-product-price',\n 'data-price',\n 'data-value',\n 'data-amount',\n] as const;\n\nconst DEFAULT_QUANTITY_ATTRS = ['data-quantity', 'data-qty'] as const;\n\nconst DEFAULT_CURRENCY_ATTRS = ['data-currency'] as const;\n\nconst DEFAULT_PRODUCT_ID_FIELDS = [\n 'productId',\n 'product_id',\n 'product',\n 'sku',\n 'item_id',\n 'id',\n] as const;\n\nconst DEFAULT_PRODUCT_NAME_FIELDS = [\n 'productName',\n 'product_name',\n 'item_name',\n 'name',\n] as const;\n\nconst DEFAULT_PRICE_FIELDS = [\n 'price',\n 'amount',\n 'value',\n 'product_price',\n] as const;\n\nconst DEFAULT_QUANTITY_FIELDS = ['quantity', 'qty'] as const;\n\nconst DEFAULT_CURRENCY_FIELDS = ['currency'] as const;\n\nconst PRODUCT_CONTAINER_SELECTOR = [\n '[data-product-id]',\n '[data-sku]',\n '[data-product]',\n '[data-item-id]',\n '[data-track]',\n '.product-card',\n '.product',\n '[data-product-card]',\n].join(', ');\n\n/**\n * Extrai dados de produto a partir de Element/Form/Container.\n * Usa mappings de attributes/fields. Não consulta ProductCatalog\n * nem atualiza CommerceState (etapa futura: CommerceResolver).\n *\n * Prioridade de merge: elemento alvo → form mais próximo → container.\n * Price/quantity são normalizados para `number` (sem conversão automática para centavos).\n */\nexport class ProductExtractor {\n private readonly attributeMappings: Record<string, string[]>;\n\n private readonly fieldMappings: Record<string, string[]>;\n\n constructor(options: ProductExtractorOptions = {}) {\n this.attributeMappings = options.attributeMappings ?? {};\n this.fieldMappings = options.fieldMappings ?? {};\n }\n\n extractFromElement(element: Element | null): ExtractedProductData {\n if (!isBrowserElement(element)) return {};\n\n const fromSelf = this.extractFromScope(element);\n const form = element.closest('form');\n const fromForm = isHtmlFormElement(form)\n ? this.extractFromScope(form)\n : {};\n const container = this.findProductContainer(element);\n const fromContainer =\n container && container !== element && container !== form\n ? this.extractFromScope(container)\n : {};\n\n return mergeDefined<ExtractedProductData>(\n fromSelf,\n fromForm,\n fromContainer\n );\n }\n\n extractFromForm(form: HTMLFormElement | null): ExtractedProductData {\n if (!isHtmlFormElement(form)) return {};\n return this.extractFromScope(form);\n }\n\n extractFromContainer(container: Element | null): ExtractedProductData {\n if (!isBrowserElement(container)) return {};\n return this.extractFromScope(container);\n }\n\n private extractFromScope(root: Element): ExtractedProductData {\n const productId =\n readAttribute(root, this.attrsFor('productId', DEFAULT_PRODUCT_ID_ATTRS)) ??\n findFieldValue(\n root,\n this.fieldsFor('productId', DEFAULT_PRODUCT_ID_FIELDS)\n );\n\n const productName =\n readAttribute(\n root,\n this.attrsFor('productName', DEFAULT_PRODUCT_NAME_ATTRS)\n ) ??\n findFieldValue(\n root,\n this.fieldsFor('productName', DEFAULT_PRODUCT_NAME_FIELDS)\n );\n\n const priceRaw =\n readAttribute(root, this.attrsFor('price', DEFAULT_PRICE_ATTRS)) ??\n findFieldValue(root, this.fieldsFor('price', DEFAULT_PRICE_FIELDS));\n\n const quantityRaw =\n readAttribute(root, this.attrsFor('quantity', DEFAULT_QUANTITY_ATTRS)) ??\n findFieldValue(\n root,\n this.fieldsFor('quantity', DEFAULT_QUANTITY_FIELDS)\n );\n\n const currency =\n readAttribute(root, this.attrsFor('currency', DEFAULT_CURRENCY_ATTRS)) ??\n findFieldValue(\n root,\n this.fieldsFor('currency', DEFAULT_CURRENCY_FIELDS)\n );\n\n return mergeDefined<ExtractedProductData>({\n productId: trimNonEmpty(productId),\n productName: trimNonEmpty(productName),\n price: normalizePrice(priceRaw),\n quantity: normalizeQuantity(quantityRaw),\n currency: trimNonEmpty(currency),\n });\n }\n\n private attrsFor(key: string, defaults: readonly string[]): string[] {\n return uniqueNames(this.attributeMappings[key], defaults);\n }\n\n private fieldsFor(key: string, defaults: readonly string[]): string[] {\n return uniqueNames(this.fieldMappings[key], defaults);\n }\n\n private findProductContainer(element: Element): Element | null {\n // parentElement: o próprio elemento já é coberto por fromSelf;\n // closest no pai encontra card/container ancestral (ex.: botão com data-track).\n return element.parentElement?.closest(PRODUCT_CONTAINER_SELECTOR) ?? null;\n }\n}\n","import type {\n SelectorFormConfig,\n SelectorFormMode,\n SelectorFormTrigger,\n} from '@/config/shared/form';\n\nimport {\n findFieldValue,\n isBrowserElement,\n isHtmlFormElement,\n isHtmlInputElement,\n readAttribute,\n readInputValue,\n trimNonEmpty,\n} from './extractor-utils';\n\nexport type NormalizedSelectorFormConfig = {\n fields: string[];\n mode: SelectorFormMode;\n minRequired?: number;\n formSelector?: string;\n trigger: SelectorFormTrigger;\n debounceMs?: number;\n fireOnce?: boolean;\n};\n\nexport type FormConditionEvaluateInput = {\n element?: Element | null;\n form?: HTMLFormElement | null;\n container?: Element | null;\n trigger?: SelectorFormTrigger;\n};\n\nexport type FormConditionReason =\n | 'matched'\n | 'no_config'\n | 'no_fields'\n | 'no_form'\n | 'trigger_mismatch'\n | 'missing_required_fields'\n | 'min_required_not_met';\n\nexport type FormConditionEvaluateResult = {\n matched: boolean;\n reason: FormConditionReason;\n fields: string[];\n filledFields: string[];\n missingFields: string[];\n values: Record<string, string>;\n config: NormalizedSelectorFormConfig | null;\n};\n\nconst DEFAULT_MODE: SelectorFormMode = 'all';\nconst DEFAULT_TRIGGER: SelectorFormTrigger = 'auto';\n\nconst VALID_TRIGGERS: readonly SelectorFormTrigger[] = [\n 'input',\n 'change',\n 'submit',\n 'click',\n 'auto',\n];\n\n/** Heurísticas por campo conhecido → attributes + field names. */\nconst FIELD_HEURISTICS: Record<\n string,\n { attrs: string[]; fields: string[]; type?: string; autocomplete?: string }\n> = {\n email: {\n attrs: ['data-email'],\n fields: ['email', 'customerEmail', 'customer_email', 'e-mail'],\n type: 'email',\n autocomplete: 'email',\n },\n phone: {\n attrs: ['data-phone', 'data-telefone'],\n fields: [\n 'phone',\n 'telefone',\n 'tel',\n 'customerPhone',\n 'customer_phone',\n 'celular',\n 'mobile',\n ],\n type: 'tel',\n autocomplete: 'tel',\n },\n name: {\n attrs: ['data-name', 'data-nome'],\n fields: ['name', 'nome', 'fullName', 'full_name'],\n autocomplete: 'name',\n },\n firstName: {\n attrs: ['data-first-name', 'data-firstname'],\n fields: [\n 'firstName',\n 'first_name',\n 'primeiro',\n 'primeiro_nome',\n 'given-name',\n ],\n autocomplete: 'given-name',\n },\n lastName: {\n attrs: ['data-last-name', 'data-lastname'],\n fields: ['lastName', 'last_name', 'sobrenome', 'family-name'],\n autocomplete: 'family-name',\n },\n productId: {\n attrs: [\n 'data-product-id',\n 'data-product',\n 'data-sku',\n 'data-item-id',\n 'data-id',\n ],\n fields: ['productId', 'product_id', 'product', 'sku', 'item_id', 'id'],\n },\n quantity: {\n attrs: ['data-quantity', 'data-qty'],\n fields: ['quantity', 'qty'],\n },\n};\n\n/**\n * Avalia `selectorForm` como condição de formulário.\n * Não cria listeners, não dispara eventos e não altera payloads.\n */\nexport class FormConditionEvaluator {\n private readonly normalized: NormalizedSelectorFormConfig | null;\n\n private readonly hasConfig: boolean;\n\n constructor(config?: SelectorFormConfig) {\n this.hasConfig = config !== undefined && config !== null;\n this.normalized = this.hasConfig ? normalizeSelectorFormConfig(config) : null;\n }\n\n getConfig(): NormalizedSelectorFormConfig | null {\n if (!this.normalized) return null;\n return {\n ...this.normalized,\n fields: [...this.normalized.fields],\n };\n }\n\n evaluate(input: FormConditionEvaluateInput = {}): FormConditionEvaluateResult {\n if (!this.hasConfig || !this.normalized) {\n return this.result({\n matched: false,\n reason: 'no_config',\n fields: [],\n filledFields: [],\n missingFields: [],\n values: {},\n config: null,\n });\n }\n\n const config = this.normalized;\n\n if (config.fields.length === 0) {\n return this.result({\n matched: false,\n reason: 'no_fields',\n fields: [],\n filledFields: [],\n missingFields: [],\n values: {},\n config,\n });\n }\n\n if (!this.isTriggerCompatible(config.trigger, input.trigger)) {\n return this.result({\n matched: false,\n reason: 'trigger_mismatch',\n fields: [...config.fields],\n filledFields: [],\n missingFields: [...config.fields],\n values: {},\n config,\n });\n }\n\n const scope = this.resolveScope(input, config);\n if (scope === 'missing_form_selector') {\n return this.result({\n matched: false,\n reason: 'no_form',\n fields: [...config.fields],\n filledFields: [],\n missingFields: [...config.fields],\n values: {},\n config,\n });\n }\n\n if (!scope) {\n return this.result({\n matched: false,\n reason: 'no_form',\n fields: [...config.fields],\n filledFields: [],\n missingFields: [...config.fields],\n values: {},\n config,\n });\n }\n\n const values: Record<string, string> = {};\n const filledFields: string[] = [];\n const missingFields: string[] = [];\n\n for (const field of config.fields) {\n const value = resolveFieldValue(scope, field);\n if (value) {\n values[field] = value;\n filledFields.push(field);\n } else {\n missingFields.push(field);\n }\n }\n\n const matched = this.matchesRequirement(\n config,\n filledFields.length,\n config.fields.length\n );\n\n let reason: FormConditionReason = 'matched';\n if (!matched) {\n reason =\n config.minRequired != null\n ? 'min_required_not_met'\n : 'missing_required_fields';\n }\n\n return this.result({\n matched,\n reason,\n fields: [...config.fields],\n filledFields,\n missingFields,\n values,\n config,\n });\n }\n\n private matchesRequirement(\n config: NormalizedSelectorFormConfig,\n filledCount: number,\n total: number\n ): boolean {\n if (config.minRequired != null) {\n const required = Math.max(0, config.minRequired);\n return filledCount >= required;\n }\n\n if (config.mode === 'any') {\n return filledCount >= 1;\n }\n\n // mode: all\n return filledCount === total && total > 0;\n }\n\n private isTriggerCompatible(\n configured: SelectorFormTrigger,\n received?: SelectorFormTrigger\n ): boolean {\n if (configured === 'auto') return true;\n if (received == null) return false;\n return received === configured;\n }\n\n /**\n * Ordem de resolução do escopo:\n * 1. form explícito no input\n * 2. element.form (input/button)\n * 3. element.closest('form')\n * 4. formSelector (obrigatório se configurado — falha → missing_form_selector)\n * 5. container explícito\n * 6. próprio element\n */\n private resolveScope(\n input: FormConditionEvaluateInput,\n config: NormalizedSelectorFormConfig\n ): Element | null | 'missing_form_selector' {\n if (isHtmlFormElement(input.form)) {\n return input.form;\n }\n\n const element = isBrowserElement(input.element) ? input.element : null;\n\n if (element) {\n const ownerForm = getOwnerForm(element);\n if (ownerForm) return ownerForm;\n\n const closestForm = element.closest('form');\n if (isHtmlFormElement(closestForm)) return closestForm;\n }\n\n if (config.formSelector) {\n const found = safeQuerySelector(config.formSelector);\n if (!found) return 'missing_form_selector';\n return found;\n }\n\n if (isBrowserElement(input.container)) {\n return input.container;\n }\n\n if (element) return element;\n\n return null;\n }\n\n private result(\n partial: FormConditionEvaluateResult\n ): FormConditionEvaluateResult {\n return {\n ...partial,\n config: partial.config\n ? {\n ...partial.config,\n fields: [...partial.config.fields],\n }\n : null,\n fields: [...partial.fields],\n filledFields: [...partial.filledFields],\n missingFields: [...partial.missingFields],\n values: { ...partial.values },\n };\n }\n}\n\nexport function normalizeSelectorFormConfig(\n config: SelectorFormConfig | undefined | null\n): NormalizedSelectorFormConfig | null {\n if (config == null) return null;\n\n if (Array.isArray(config)) {\n const fields = sanitizeFields(config);\n return {\n fields,\n mode: DEFAULT_MODE,\n trigger: DEFAULT_TRIGGER,\n };\n }\n\n if (typeof config !== 'object') return null;\n\n const fields = sanitizeFields(config.fields ?? []);\n const mode: SelectorFormMode =\n config.mode === 'any' || config.mode === 'all' ? config.mode : DEFAULT_MODE;\n const trigger: SelectorFormTrigger = VALID_TRIGGERS.includes(\n config.trigger as SelectorFormTrigger\n )\n ? (config.trigger as SelectorFormTrigger)\n : DEFAULT_TRIGGER;\n\n const normalized: NormalizedSelectorFormConfig = {\n fields,\n mode,\n trigger,\n };\n\n if (typeof config.minRequired === 'number' && Number.isFinite(config.minRequired)) {\n normalized.minRequired = config.minRequired;\n }\n\n const formSelector = trimNonEmpty(config.formSelector);\n if (formSelector) normalized.formSelector = formSelector;\n\n if (typeof config.debounceMs === 'number' && Number.isFinite(config.debounceMs)) {\n normalized.debounceMs = config.debounceMs;\n }\n\n if (typeof config.fireOnce === 'boolean') {\n normalized.fireOnce = config.fireOnce;\n }\n\n return normalized;\n}\n\nfunction sanitizeFields(fields: readonly string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const field of fields) {\n const trimmed = typeof field === 'string' ? field.trim() : '';\n if (!trimmed || seen.has(trimmed)) continue;\n seen.add(trimmed);\n result.push(trimmed);\n }\n return result;\n}\n\nfunction getOwnerForm(element: Element): HTMLFormElement | null {\n if (\n isHtmlInputElement(element) ||\n element instanceof HTMLButtonElement ||\n element instanceof HTMLSelectElement ||\n element instanceof HTMLTextAreaElement\n ) {\n const form = element.form;\n return isHtmlFormElement(form) ? form : null;\n }\n return null;\n}\n\nfunction safeQuerySelector(selector: string): Element | null {\n if (typeof document === 'undefined') return null;\n try {\n return document.querySelector(selector);\n } catch {\n return null;\n }\n}\n\nfunction resolveFieldValue(scope: Element, field: string): string | undefined {\n const key = field.trim();\n if (!key) return undefined;\n\n const heuristic = FIELD_HEURISTICS[key];\n\n if (heuristic?.type) {\n const typed = readTypedInput(scope, heuristic.type);\n if (typed) return typed;\n }\n\n if (heuristic?.autocomplete) {\n const auto = readAutocomplete(scope, heuristic.autocomplete);\n if (auto) return auto;\n }\n\n if (heuristic) {\n const fromAttr = readAttribute(scope, heuristic.attrs);\n if (fromAttr) return fromAttr;\n\n const fromFields = findFieldValue(scope, heuristic.fields);\n if (fromFields) return fromFields;\n }\n\n // Campo customizado / fallback genérico\n const kebab = toKebabCase(key);\n const fromCustomAttr = readAttribute(scope, [\n `data-${kebab}`,\n `data-${key}`,\n ]);\n if (fromCustomAttr) return fromCustomAttr;\n\n return findFieldValue(scope, [key, kebab]);\n}\n\nfunction readTypedInput(root: Element, type: string): string | undefined {\n const selector = `input[type=\"${type}\"]`;\n try {\n const input = root.matches(selector)\n ? root\n : root.querySelector(selector);\n return input ? readInputValue(input) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readAutocomplete(\n root: Element,\n autocomplete: string\n): string | undefined {\n const selector = `input[autocomplete=\"${autocomplete}\"]`;\n try {\n const input = root.matches(selector)\n ? root\n : root.querySelector(selector);\n return input ? readInputValue(input) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction toKebabCase(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[_\\s]+/g, '-')\n .toLowerCase();\n}\n","/**\n * Calcula value/currency a partir de items resolvidos.\n * Não conhece DOM, detectors, Transport nem Dispatcher.\n * Não muta o input.\n */\n\nexport type ResolvedCommerceItem = {\n productId?: string;\n sku?: string;\n productName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n variant?: string;\n brand?: string;\n type?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type OrderCalculationInput = {\n items?: ResolvedCommerceItem[];\n value?: number;\n currency?: string;\n defaultCurrency?: string;\n};\n\nexport type OrderCalculationResult = {\n items: ResolvedCommerceItem[];\n value?: number;\n currency?: string;\n};\n\nexport class OrderCalculator {\n calculate(input: OrderCalculationInput): OrderCalculationResult {\n const sourceItems = Array.isArray(input.items) ? input.items : [];\n const items = sourceItems.map(item => this.cloneItem(item));\n\n for (const item of items) {\n if (item.quantity == null || !Number.isFinite(item.quantity)) {\n item.quantity = 1;\n }\n }\n\n const value =\n typeof input.value === 'number' && Number.isFinite(input.value)\n ? input.value\n : this.sumValue(items);\n\n const currency = this.resolveCurrency(input, items);\n\n return {\n items,\n ...(value !== undefined ? { value } : {}),\n ...(currency !== undefined ? { currency } : {}),\n };\n }\n\n private sumValue(items: ResolvedCommerceItem[]): number | undefined {\n let total = 0;\n let hasPriced = false;\n\n for (const item of items) {\n if (typeof item.price !== 'number' || !Number.isFinite(item.price)) {\n continue;\n }\n const qty =\n typeof item.quantity === 'number' && Number.isFinite(item.quantity)\n ? item.quantity\n : 1;\n total += item.price * qty;\n hasPriced = true;\n }\n\n return hasPriced ? total : undefined;\n }\n\n /**\n * Ordem: currency manual → primeiro item com currency → defaultCurrency.\n * Multi-currency: determinístico — usa o primeiro item com currency\n * (não normaliza conversão entre moedas nesta etapa).\n */\n private resolveCurrency(\n input: OrderCalculationInput,\n items: ResolvedCommerceItem[]\n ): string | undefined {\n if (typeof input.currency === 'string' && input.currency.trim()) {\n return input.currency.trim();\n }\n\n for (const item of items) {\n if (typeof item.currency === 'string' && item.currency.trim()) {\n return item.currency.trim();\n }\n }\n\n if (\n typeof input.defaultCurrency === 'string' &&\n input.defaultCurrency.trim()\n ) {\n return input.defaultCurrency.trim();\n }\n\n return undefined;\n }\n\n private cloneItem(item: ResolvedCommerceItem): ResolvedCommerceItem {\n return {\n ...item,\n ...(item.metadata ? { metadata: { ...item.metadata } } : {}),\n };\n }\n}\n","import type { CommerceCalculateValueFrom } from '@/config/shared/commerce';\nimport type { PixelItem } from '@/events/conversion';\n\nimport type { CommerceState } from './CommerceState';\nimport type { ProductCatalog } from './ProductCatalog';\nimport type {\n OrderCalculator,\n ResolvedCommerceItem,\n} from './OrderCalculator';\n\nexport type CommerceEventType =\n | 'ADD_TO_CART'\n | 'REMOVE_FROM_CART'\n | 'INITIATE_CHECKOUT'\n | 'PURCHASE';\n\nexport type ExtractedProductInput = {\n productId?: string;\n productName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n sku?: string;\n};\n\nexport type CommerceResolverInput = {\n eventType: CommerceEventType;\n payload?: Record<string, unknown>;\n extractedProduct?: ExtractedProductInput;\n items?: Array<{\n productId?: string;\n id?: string;\n sku?: string;\n name?: string;\n productName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n }>;\n};\n\nexport type CommerceResolverResult = {\n data: Record<string, unknown>;\n items?: ResolvedCommerceItem[];\n value?: number;\n currency?: string;\n};\n\nexport type CommerceResolverOptions = {\n catalog: ProductCatalog;\n state: CommerceState;\n calculator: OrderCalculator;\n defaultCurrency?: string;\n calculateValueFrom?: CommerceCalculateValueFrom;\n};\n\n/**\n * Combina payload + extracted + state + catalog + defaults.\n * Não dispara eventos, não escreve em CommerceState, não conhece DOM/Transport.\n *\n * Prioridade de merge por campo:\n * manual payload > extractedProduct > commerce state > catalog > defaults\n */\nexport class CommerceResolver {\n private readonly catalog: ProductCatalog;\n\n private readonly state: CommerceState;\n\n private readonly calculator: OrderCalculator;\n\n private readonly defaultCurrency?: string;\n\n private readonly calculateValueFrom: CommerceCalculateValueFrom;\n\n constructor(options: CommerceResolverOptions) {\n this.catalog = options.catalog;\n this.state = options.state;\n this.calculator = options.calculator;\n this.defaultCurrency = trim(options.defaultCurrency);\n this.calculateValueFrom =\n options.calculateValueFrom ?? 'selected_items';\n }\n\n resolve(input: CommerceResolverInput): CommerceResolverResult {\n switch (input.eventType) {\n case 'ADD_TO_CART':\n return this.resolveAddToCart(input);\n case 'REMOVE_FROM_CART':\n return this.resolveRemoveFromCart(input);\n case 'INITIATE_CHECKOUT':\n return this.resolveCheckoutLike(input, false);\n case 'PURCHASE':\n return this.resolveCheckoutLike(input, true);\n default:\n return { data: { ...(input.payload ?? {}) } };\n }\n }\n\n private resolveAddToCart(\n input: CommerceResolverInput\n ): CommerceResolverResult {\n const payload = input.payload ?? {};\n const extracted = input.extractedProduct ?? {};\n\n const productId =\n asString(payload.productId) ??\n asString(extracted.productId) ??\n this.lookupIdBySku(\n asString(payload.sku) ?? asString(extracted.sku)\n );\n\n const catalogProduct = productId\n ? this.catalog.getById(productId)\n : this.lookupProductBySku(\n asString(payload.sku) ?? asString(extracted.sku)\n );\n\n const resolvedId = productId ?? catalogProduct?.id;\n const stateItem = resolvedId ? this.state.getItem(resolvedId) : null;\n\n const productName =\n asString(payload.productName) ??\n asString(extracted.productName) ??\n catalogProduct?.name;\n\n const price =\n asNumber(payload.price) ??\n asNumber(extracted.price) ??\n asNumber(stateItem?.price) ??\n catalogProduct?.price;\n\n const quantity =\n asNumber(payload.quantity) ??\n asNumber(extracted.quantity) ??\n asNumber(stateItem?.quantity) ??\n catalogProduct?.quantity ??\n 1;\n\n const currency =\n asString(payload.currency) ??\n asString(extracted.currency) ??\n asString(stateItem?.currency) ??\n catalogProduct?.currency ??\n this.defaultCurrency;\n\n const data: Record<string, unknown> = {};\n if (resolvedId) data.productId = resolvedId;\n if (productName) data.productName = productName;\n if (price !== undefined) data.price = price;\n if (currency) data.currency = currency;\n if (quantity !== undefined) data.quantity = quantity;\n\n // Preserva campos extras do payload (sem sobrescrever resolvidos).\n for (const [key, value] of Object.entries(payload)) {\n if (value === undefined) continue;\n if (!(key in data)) data[key] = value;\n }\n\n return { data };\n }\n\n private resolveRemoveFromCart(\n input: CommerceResolverInput\n ): CommerceResolverResult {\n const payload = input.payload ?? {};\n const extracted = input.extractedProduct ?? {};\n\n const productId =\n asString(payload.productId) ??\n asString(extracted.productId) ??\n this.lookupIdBySku(\n asString(payload.sku) ?? asString(extracted.sku)\n );\n\n const catalogProduct = productId\n ? this.catalog.getById(productId)\n : null;\n\n const resolvedId = productId ?? catalogProduct?.id;\n const stateItem = resolvedId ? this.state.getItem(resolvedId) : null;\n\n const quantity =\n asNumber(payload.quantity) ??\n asNumber(extracted.quantity) ??\n asNumber(stateItem?.quantity) ??\n 1;\n\n const data: Record<string, unknown> = {};\n if (resolvedId) data.productId = resolvedId;\n if (quantity !== undefined) data.quantity = quantity;\n\n for (const [key, value] of Object.entries(payload)) {\n if (value === undefined) continue;\n if (!(key in data)) data[key] = value;\n }\n\n return { data };\n }\n\n private resolveCheckoutLike(\n input: CommerceResolverInput,\n isPurchase: boolean\n ): CommerceResolverResult {\n const payload = { ...(input.payload ?? {}) };\n const manualValue = asNumber(payload.value);\n const manualCurrency = asString(payload.currency);\n const manualItems = this.readPayloadItems(input);\n\n const resolvedItems = this.resolveItemsSource(manualItems);\n const pixelItems = resolvedItems.map(item => this.toPixelItem(item));\n\n const shouldCalculateValue =\n manualValue === undefined && this.calculateValueFrom !== 'manual';\n\n const calc = this.calculator.calculate({\n items: resolvedItems,\n value: shouldCalculateValue ? undefined : manualValue,\n currency: manualCurrency,\n defaultCurrency: this.defaultCurrency,\n });\n\n // Se calculateValueFrom === 'manual' e sem value manual, não inventar value.\n const value =\n manualValue !== undefined\n ? manualValue\n : this.calculateValueFrom === 'manual'\n ? undefined\n : calc.value;\n\n const currency =\n manualCurrency ?? calc.currency ?? this.defaultCurrency;\n\n const data: Record<string, unknown> = { ...payload };\n\n if (pixelItems.length > 0) {\n data.items = pixelItems;\n } else if (manualItems === null) {\n // Sem items manuais e sem fonte → não forçar items vazios no payload.\n delete data.items;\n }\n\n if (value !== undefined) {\n data.value = value;\n } else {\n delete data.value;\n }\n\n if (currency) {\n data.currency = currency;\n }\n\n if (isPurchase) {\n // orderId e demais campos do payload já estão em data via spread.\n }\n\n return {\n data,\n items: calc.items,\n ...(value !== undefined ? { value } : {}),\n ...(currency ? { currency } : {}),\n };\n }\n\n /**\n * null = payload não trouxe items (usar state conforme calculateValueFrom)\n * [] = payload trouxe items vazios\n */\n private readPayloadItems(\n input: CommerceResolverInput\n ): ResolvedCommerceItem[] | null {\n if (input.items) {\n return input.items.map(item => this.normalizeLooseItem(item));\n }\n\n const raw = input.payload?.items;\n if (raw === undefined) return null;\n if (!Array.isArray(raw)) return null;\n return raw.map(item =>\n this.normalizeLooseItem(\n (item && typeof item === 'object'\n ? item\n : {}) as Record<string, unknown>\n )\n );\n }\n\n private resolveItemsSource(\n manualItems: ResolvedCommerceItem[] | null\n ): ResolvedCommerceItem[] {\n // Items manuais sempre vencem state.\n if (manualItems !== null) {\n return manualItems.map(item => this.enrichItem(item));\n }\n\n if (this.calculateValueFrom === 'selected_items') {\n return this.state.getSelectedItems().map(stateItem =>\n this.enrichItem({\n productId: stateItem.productId,\n price: stateItem.price,\n quantity: stateItem.quantity,\n currency: stateItem.currency,\n })\n );\n }\n\n // event_items / manual sem items no payload → sem items\n return [];\n }\n\n private enrichItem(item: ResolvedCommerceItem): ResolvedCommerceItem {\n const productId =\n item.productId ?? this.lookupIdBySku(item.sku) ?? undefined;\n const catalog = productId\n ? this.catalog.getById(productId)\n : this.lookupProductBySku(item.sku);\n\n const resolvedId = productId ?? catalog?.id;\n\n return {\n ...item,\n ...(resolvedId ? { productId: resolvedId } : {}),\n productName: item.productName ?? catalog?.name,\n sku: item.sku ?? catalog?.sku,\n price: item.price ?? catalog?.price,\n quantity: item.quantity ?? catalog?.quantity ?? 1,\n currency:\n item.currency ?? catalog?.currency ?? this.defaultCurrency,\n category: item.category ?? catalog?.category,\n variant: item.variant ?? catalog?.variant,\n brand: item.brand ?? catalog?.brand,\n type: item.type ?? catalog?.type,\n metadata: item.metadata ?? catalog?.metadata,\n };\n }\n\n private toPixelItem(item: ResolvedCommerceItem): PixelItem {\n const pixel: PixelItem = {\n ...(item.productId ? { id: item.productId } : {}),\n ...(item.productName ? { name: item.productName } : {}),\n ...(item.category ? { category: item.category } : {}),\n ...(item.price !== undefined ? { price: item.price } : {}),\n ...(item.quantity !== undefined ? { quantity: item.quantity } : {}),\n };\n return pixel;\n }\n\n private normalizeLooseItem(\n item: Record<string, unknown> | {\n productId?: string;\n id?: string;\n sku?: string;\n name?: string;\n productName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n }\n ): ResolvedCommerceItem {\n return {\n productId:\n asString((item as { productId?: unknown }).productId) ??\n asString((item as { id?: unknown }).id),\n sku: asString((item as { sku?: unknown }).sku),\n productName:\n asString((item as { productName?: unknown }).productName) ??\n asString((item as { name?: unknown }).name),\n price: asNumber((item as { price?: unknown }).price),\n quantity: asNumber((item as { quantity?: unknown }).quantity),\n currency: asString((item as { currency?: unknown }).currency),\n category: asString((item as { category?: unknown }).category),\n };\n }\n\n private lookupIdBySku(sku: string | undefined): string | undefined {\n if (!sku) return undefined;\n return this.catalog.getBySku(sku)?.id;\n }\n\n private lookupProductBySku(sku: string | undefined) {\n if (!sku) return null;\n return this.catalog.getBySku(sku);\n }\n}\n\nfunction asString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value)) return undefined;\n return value;\n}\n\nfunction trim(value: string | undefined): string | undefined {\n if (typeof value !== 'string') return undefined;\n const t = value.trim();\n return t.length > 0 ? t : undefined;\n}\n","import type { SelectorDescriptor } from '@/config/shared/selector';\n\nexport type TextMatchOptions = Pick<\n SelectorDescriptor,\n 'value' | 'exact' | 'caseSensitive'\n>;\n\n/** Normaliza espaços em branco (trim + colapsa runs). */\nexport function normalizeSelectorText(text: string): string {\n return text.trim().replace(/\\s+/g, ' ');\n}\n\nfunction prepare(text: string, caseSensitive: boolean): string {\n const normalized = normalizeSelectorText(text);\n return caseSensitive ? normalized : normalized.toLowerCase();\n}\n\n/**\n * Compara texto bruto de um elemento (`textContent`, inclui descendentes).\n * Preferir `isTextMatchLeaf` em match de click/walk-up.\n */\nexport function elementMatchesText(\n element: Element,\n options: TextMatchOptions\n): boolean {\n const raw = element.textContent;\n if (raw == null) return false;\n\n const caseSensitive = options.caseSensitive === true;\n const haystack = prepare(raw, caseSensitive);\n const needle = prepare(options.value, caseSensitive);\n if (!needle) return false;\n\n if (options.exact === true) {\n return haystack === needle;\n }\n\n return haystack.includes(needle);\n}\n\n/**\n * Match de texto no elemento “folha”: o próprio elemento bate e nenhum\n * descendente também bate. Evita que ancestrais (card/body) disparem só\n * porque contêm um botão `text:Comprar agora` no `textContent`.\n */\nexport function isTextMatchLeaf(\n element: Element,\n options: TextMatchOptions\n): boolean {\n if (!elementMatchesText(element, options)) return false;\n\n const descendants = element.querySelectorAll('*');\n for (let i = 0; i < descendants.length; i += 1) {\n const child = descendants[i];\n if (child && elementMatchesText(child, options)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Busca elementos cujo texto satisfaz o seletor.\n * Escopo opcional via `closest` (container CSS). SSR-safe: sem document → [].\n */\nexport function queryElementsByText(\n options: TextMatchOptions & { closest?: string },\n root?: ParentNode | null\n): Element[] {\n if (typeof document === 'undefined') return [];\n\n const scope = root ?? document;\n\n if (options.closest) {\n try {\n const containers: Element[] = [];\n if (scope instanceof Element && scope.matches(options.closest)) {\n containers.push(scope);\n }\n containers.push(...Array.from(scope.querySelectorAll(options.closest)));\n\n const matched: Element[] = [];\n for (const container of containers) {\n matched.push(...collectTextMatches(container, options));\n }\n return Array.from(new Set(matched));\n } catch {\n return [];\n }\n }\n\n return collectTextMatches(scope, options);\n}\n\nfunction collectTextMatches(\n root: ParentNode,\n options: TextMatchOptions\n): Element[] {\n const results: Element[] = [];\n const nodes = Array.from(root.querySelectorAll('*'));\n\n if (root instanceof Element) {\n nodes.unshift(root);\n }\n\n for (const el of nodes) {\n if (isTextMatchLeaf(el, options)) {\n results.push(el);\n }\n }\n\n return results;\n}\n\nexport const TextSelectorResolver = {\n normalizeSelectorText,\n elementMatchesText,\n isTextMatchLeaf,\n queryElementsByText,\n} as const;\n","import {\n DEFAULT_SELECTOR_TYPE,\n type SelectorConfig,\n type SelectorDescriptor,\n type SelectorInput,\n type SelectorType,\n} from '@/config/shared/selector';\nimport type { PixelLogger } from '@/logger';\n\nimport {\n isTextMatchLeaf,\n queryElementsByText,\n} from './TextSelectorResolver';\n\nconst PREFIX_TO_TYPE: Record<string, SelectorType> = {\n css: 'css',\n id: 'id',\n class: 'class',\n attr: 'attribute',\n attribute: 'attribute',\n text: 'text',\n};\n\nexport type NormalizedSelector = {\n readonly type: SelectorType;\n readonly value: string;\n readonly exact?: boolean;\n readonly caseSensitive?: boolean;\n readonly closest?: string;\n};\n\ntype SelectorLogger = Pick<PixelLogger, 'debug'>;\n\n/**\n * Resolve `SelectorConfig` (string | array | objeto) em descritores normalizados\n * e consulta/match no DOM de forma SSR-safe.\n *\n * Ordem de resolução por item:\n * 1. Objeto → type do objeto\n * 2. String com prefixo (css:|id:|class:|attr:|attribute:|text:) → prefixo\n * 3. String sem prefixo → selectorType (fallback)\n * 4. Sem selectorType → css\n */\nexport class SelectorResolver {\n private readonly logger: SelectorLogger | null;\n\n constructor(logger?: SelectorLogger | null) {\n this.logger = logger ?? null;\n }\n\n hasEntries(selector: SelectorConfig | undefined): boolean {\n return this.normalize(selector).length > 0;\n }\n\n normalize(\n selector: SelectorConfig | undefined,\n selectorType: SelectorType = DEFAULT_SELECTOR_TYPE\n ): NormalizedSelector[] {\n if (selector == null) return [];\n\n const inputs = Array.isArray(selector) ? selector : [selector];\n const result: NormalizedSelector[] = [];\n\n for (const input of inputs) {\n const normalized = this.normalizeInput(input, selectorType);\n if (normalized) result.push(normalized);\n }\n\n return result;\n }\n\n /**\n * Retorna elementos que batem com qualquer seletor (OR).\n * Selector inválido → debug log + lista vazia para aquele item.\n */\n queryAll(\n selector: SelectorConfig | undefined,\n selectorType: SelectorType = DEFAULT_SELECTOR_TYPE,\n root?: ParentNode | null\n ): Element[] {\n if (typeof document === 'undefined') return [];\n\n const scope = root ?? document;\n const matched: Element[] = [];\n\n for (const item of this.normalize(selector, selectorType)) {\n matched.push(...this.queryNormalized(item, scope));\n }\n\n return Array.from(new Set(matched));\n }\n\n /**\n * Verifica se `element` satisfaz algum seletor normalizado.\n * Usado no walk-up de click — não usa `element.matches('text:...')`.\n */\n matches(\n element: Element,\n selector: SelectorConfig | undefined,\n selectorType: SelectorType = DEFAULT_SELECTOR_TYPE\n ): boolean {\n for (const item of this.normalize(selector, selectorType)) {\n if (this.matchesNormalized(element, item)) return true;\n }\n return false;\n }\n\n private normalizeInput(\n input: SelectorInput,\n fallbackType: SelectorType\n ): NormalizedSelector | null {\n if (typeof input !== 'string') {\n return this.fromDescriptor(input);\n }\n\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n const prefixed = this.parsePrefix(trimmed);\n if (prefixed) {\n return this.fromDescriptor({\n type: prefixed.type,\n value: prefixed.value,\n });\n }\n\n return this.fromDescriptor({\n type: fallbackType,\n value: trimmed,\n });\n }\n\n private fromDescriptor(\n descriptor: SelectorDescriptor\n ): NormalizedSelector | null {\n const value = descriptor.value?.trim();\n if (!value) return null;\n\n return {\n type: descriptor.type,\n value,\n exact: descriptor.exact,\n caseSensitive: descriptor.caseSensitive,\n closest: descriptor.closest,\n };\n }\n\n private parsePrefix(\n raw: string\n ): { type: SelectorType; value: string } | null {\n const colon = raw.indexOf(':');\n if (colon <= 0) return null;\n\n const prefix = raw.slice(0, colon).toLowerCase();\n const type = PREFIX_TO_TYPE[prefix];\n if (!type) return null;\n\n const value = raw.slice(colon + 1).trim();\n if (!value) return null;\n\n return { type, value };\n }\n\n private queryNormalized(\n item: NormalizedSelector,\n root: ParentNode\n ): Element[] {\n if (item.type === 'text') {\n return queryElementsByText(\n {\n value: item.value,\n exact: item.exact,\n caseSensitive: item.caseSensitive,\n closest: item.closest,\n },\n root\n );\n }\n\n const css = this.toCssSelector(item);\n if (!css) return [];\n\n try {\n const nodes = Array.from(root.querySelectorAll(css));\n if (!item.closest) return nodes;\n\n return nodes.filter(el => {\n try {\n return el.closest(item.closest!) != null;\n } catch {\n return false;\n }\n });\n } catch (error) {\n this.logger?.debug(\n `[SelectorResolver] Invalid CSS selector ignored: ${css}`,\n error\n );\n return [];\n }\n }\n\n private matchesNormalized(\n element: Element,\n item: NormalizedSelector\n ): boolean {\n if (item.closest) {\n try {\n if (element.closest(item.closest) == null) return false;\n } catch {\n this.logger?.debug(\n `[SelectorResolver] Invalid closest selector ignored: ${item.closest}`\n );\n return false;\n }\n }\n\n if (item.type === 'text') {\n // Folha apenas — senão walk-up dispara em card/body que contém o botão\n return isTextMatchLeaf(element, {\n value: item.value,\n exact: item.exact,\n caseSensitive: item.caseSensitive,\n });\n }\n\n const css = this.toCssSelector(item);\n if (!css) return false;\n\n try {\n return element.matches(css);\n } catch (error) {\n this.logger?.debug(\n `[SelectorResolver] Invalid CSS selector ignored: ${css}`,\n error\n );\n return false;\n }\n }\n\n /**\n * Converte descritor não-text em CSS.\n * Preserva compat legado: `#` / `.` / `[` passam direto;\n * `attribute` sem isso vira `[data-track=\"...\"]`.\n */\n toCssSelector(item: Pick<NormalizedSelector, 'type' | 'value'>): string | null {\n if (item.type === 'text') return null;\n\n const { value } = item;\n if (\n value.startsWith('[') ||\n value.startsWith('.') ||\n value.startsWith('#')\n ) {\n return value;\n }\n\n switch (item.type) {\n case 'id':\n return `#${escapeCssIdent(value)}`;\n case 'class':\n return `.${escapeCssIdent(value)}`;\n case 'attribute':\n return `[data-track=\"${escapeAttrValue(value)}\"]`;\n case 'css':\n return value;\n default:\n return value;\n }\n }\n}\n\nfunction escapeCssIdent(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(/([ !\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, '\\\\$1');\n}\n\nfunction escapeAttrValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","import type { SelectorFormConfig, SelectorFormTrigger } from '@/config/shared/form';\nimport type {\n SelectorConfig,\n SelectorType,\n} from '@/config/shared/selector';\nimport { DEFAULT_SELECTOR_TYPE } from '@/config/shared/selector';\nimport type { ConversionEventData } from '@/events/conversion';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport {\n CustomerExtractor,\n FormConditionEvaluator,\n ProductExtractor,\n} from '../../commerce';\nimport { isHtmlFormElement } from '../../commerce/extractor-utils';\nimport type {\n ConversionEventOrigin,\n} from '../../contracts';\nimport { SelectorResolver } from '../SelectorResolver';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\n\nexport type FormCapableEventType =\n | 'LEAD'\n | 'ADD_TO_CART'\n | 'INITIATE_CHECKOUT';\n\nexport type ConfiguredFormOptions = {\n readonly eventType: FormCapableEventType;\n readonly selector?: SelectorConfig;\n readonly selectorType?: SelectorType;\n readonly selectorForm: SelectorFormConfig;\n readonly origin: ConversionEventOrigin;\n};\n\n/**\n * Detector de `selectorForm`: escuta DOM, avalia condição e dispara via TrackerFactory.\n * Não usa CommerceResolver / OrderCalculator (etapas futuras).\n * Não chama Dispatcher diretamente.\n */\nexport class ConfiguredFormDetector extends BaseAutoTracker {\n private readonly factory: TrackerFactory;\n\n private readonly options: ConfiguredFormOptions;\n\n private readonly formEvaluator: FormConditionEvaluator;\n\n private readonly selectorResolver: SelectorResolver;\n\n private readonly customerExtractor: CustomerExtractor;\n\n private readonly productExtractor: ProductExtractor;\n\n private readonly hasSelector: boolean;\n\n private readonly selectorType: SelectorType;\n\n private readonly debounceMs: number;\n\n private readonly fireOnce: boolean;\n\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n private hasFired = false;\n\n private destroyed = false;\n\n constructor(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n options: ConfiguredFormOptions\n ) {\n super(context);\n this.factory = factory;\n this.options = options;\n this.formEvaluator = new FormConditionEvaluator(options.selectorForm);\n this.selectorResolver = new SelectorResolver(context.logger);\n this.hasSelector = this.selectorResolver.hasEntries(options.selector);\n this.selectorType = options.selectorType ?? DEFAULT_SELECTOR_TYPE;\n\n const commerce = context.config.modules.conversion.commerce;\n this.customerExtractor = new CustomerExtractor({\n fieldMappings: commerce?.mappings?.fields,\n });\n this.productExtractor = new ProductExtractor({\n attributeMappings: commerce?.mappings?.attributes,\n fieldMappings: commerce?.mappings?.fields,\n });\n\n const normalized = this.formEvaluator.getConfig();\n this.debounceMs =\n typeof normalized?.debounceMs === 'number' && normalized.debounceMs > 0\n ? normalized.debounceMs\n : 0;\n this.fireOnce = normalized?.fireOnce === true;\n }\n\n get name(): string {\n return `ConfiguredForm(${this.options.eventType})`;\n }\n\n protected onInit(): void {\n this.destroyed = false;\n this.hasFired = false;\n this.debounceTimer = this.clearManagedTimeout(this.debounceTimer);\n\n if (!this.isDocumentAvailable()) return;\n\n const trigger = this.formEvaluator.getConfig()?.trigger ?? 'auto';\n const events = this.resolveDomEvents(trigger);\n\n for (const type of events) {\n this.addDocumentListener(\n type,\n event => this.handleDomEvent(event, type),\n true\n );\n }\n }\n\n protected onDestroy(): void {\n this.destroyed = true;\n this.debounceTimer = this.clearManagedTimeout(this.debounceTimer);\n }\n\n private resolveDomEvents(\n trigger: SelectorFormTrigger\n ): Array<'input' | 'change' | 'submit' | 'click'> {\n if (trigger === 'auto') {\n return ['input', 'change', 'submit', 'click'];\n }\n return [trigger];\n }\n\n private handleDomEvent(\n event: Event,\n domType: 'input' | 'change' | 'submit' | 'click'\n ): void {\n if (this.destroyed) return;\n if (this.fireOnce && this.hasFired) return;\n\n const trigger = domType as SelectorFormTrigger;\n const element =\n event.target instanceof Element ? event.target : null;\n\n // Com selector + click: exige match no elemento (walk-up).\n if (this.hasSelector && trigger === 'click') {\n if (!this.matchesSelector(element)) return;\n }\n\n const evaluation = this.formEvaluator.evaluate({\n element,\n trigger,\n });\n\n if (!evaluation.matched) {\n this.context.logger.debug(\n `[ConfiguredFormDetector] ${this.options.eventType} skipped: ${evaluation.reason}`\n );\n return;\n }\n\n const data = this.buildPayload(element);\n if (data === null) return;\n\n this.scheduleTrack(data);\n }\n\n private matchesSelector(element: Element | null): boolean {\n if (!element || !this.options.selector) return false;\n\n let current: Element | null = element;\n while (current && current !== document.body) {\n if (\n this.selectorResolver.matches(\n current,\n this.options.selector,\n this.selectorType\n )\n ) {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n /**\n * Alinha a extração de customer ao escopo da condição quando há `formSelector`.\n * Sem formSelector, mantém o elemento do evento — extractors já fazem\n * merge elemento → form → container (necessário p/ data-* no botão).\n */\n private resolveCustomerRoot(element: Element | null): Element | null {\n const formSelector = this.formEvaluator.getConfig()?.formSelector;\n if (formSelector && typeof document !== 'undefined') {\n try {\n const found = document.querySelector(formSelector);\n if (found) return found;\n } catch {\n // CSS inválido — fallback abaixo\n }\n }\n\n return element;\n }\n\n /**\n * LEAD: exige email|phone|name (contrato TrackerFactory.normalize).\n * ADD_TO_CART / INITIATE_CHECKOUT: payload parcial permitido (sem catalog/value ainda).\n */\n private buildPayload(element: Element | null): ConversionEventData | null {\n const { eventType } = this.options;\n\n if (eventType === 'LEAD') {\n const root = this.resolveCustomerRoot(element);\n const customer = isHtmlFormElement(root)\n ? this.customerExtractor.extractFromForm(root)\n : this.customerExtractor.extractFromElement(root);\n if (!customer.email && !customer.phone && !customer.name) {\n this.context.logger.debug(\n '[ConfiguredFormDetector] LEAD skipped: no email/phone/name'\n );\n return null;\n }\n return {\n ...(customer.email ? { email: customer.email } : {}),\n ...(customer.phone ? { phone: customer.phone } : {}),\n ...(customer.name ? { name: customer.name } : {}),\n };\n }\n\n if (eventType === 'ADD_TO_CART') {\n // Preferir o alvo do evento para data-* no botão; extractors mesclam form/card\n const product = this.productExtractor.extractFromElement(element);\n return {\n ...(product.productId ? { productId: product.productId } : {}),\n ...(product.productName ? { productName: product.productName } : {}),\n ...(product.price != null ? { price: product.price } : {}),\n ...(product.currency ? { currency: product.currency } : {}),\n ...(product.quantity != null ? { quantity: product.quantity } : {}),\n };\n }\n\n // INITIATE_CHECKOUT — parcial no detector; CommerceResolver completa no TrackerFactory\n return {};\n }\n\n private scheduleTrack(data: ConversionEventData): void {\n if (this.debounceMs <= 0) {\n this.track(data);\n return;\n }\n\n this.debounceTimer = this.clearManagedTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n if (this.destroyed) return;\n this.track(data);\n }, this.debounceMs);\n }\n\n private track(data: ConversionEventData): void {\n if (this.destroyed) return;\n if (this.fireOnce && this.hasFired) return;\n\n this.factory.trackAuto(this.options.eventType, data, {\n origin: this.options.origin,\n });\n\n if (this.fireOnce) {\n this.hasFired = true;\n }\n }\n}\n","import type {\n SelectorConfig,\n SelectorType,\n} from '@/config/shared/selector';\nimport { DEFAULT_SELECTOR_TYPE } from '@/config/shared/selector';\nimport type { ConversionEventData } from '@/events/conversion';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport {\n CustomerExtractor,\n ProductExtractor,\n} from '../../commerce';\nimport type {\n ConversionEventOrigin,\n ConversionEventType,\n} from '../../contracts';\nimport { SelectorResolver } from '../SelectorResolver';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\n\nexport type ConfiguredSelectorOptions = {\n readonly eventType: ConversionEventType;\n readonly selector: SelectorConfig;\n readonly selectorType?: SelectorType;\n readonly origin: ConversionEventOrigin;\n};\n\n/**\n * Detector configurado por selector (sem selectorForm).\n * Extrai dados mínimos via CustomerExtractor/ProductExtractor e dispara\n * via TrackerFactory.trackAuto — CommerceResolver completa no dispatch.\n *\n * Não chama Dispatcher/Transport. Não escreve CommerceState.\n * Com selectorForm no mesmo evento, AutoTrackerFactory usa FormDetector.\n */\nexport class ConfiguredSelectorDetector extends BaseAutoTracker {\n private readonly factory: TrackerFactory;\n\n private readonly config: ConfiguredSelectorOptions;\n\n private readonly resolver: SelectorResolver;\n\n private readonly selectorType: SelectorType;\n\n private readonly customerExtractor: CustomerExtractor;\n\n private readonly productExtractor: ProductExtractor;\n\n constructor(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n config: ConfiguredSelectorOptions\n ) {\n super(context);\n this.factory = factory;\n this.config = config;\n this.selectorType = config.selectorType ?? DEFAULT_SELECTOR_TYPE;\n this.resolver = new SelectorResolver(context.logger);\n\n const commerce = context.config.modules.conversion.commerce;\n this.customerExtractor = new CustomerExtractor({\n fieldMappings: commerce?.mappings?.fields,\n });\n this.productExtractor = new ProductExtractor({\n attributeMappings: commerce?.mappings?.attributes,\n fieldMappings: commerce?.mappings?.fields,\n });\n }\n\n get name(): string {\n return `ConfiguredSelector(${this.config.eventType})`;\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n\n this.addDocumentListener('click', event => this.handleEvent(event), true);\n this.addDocumentListener('submit', event => this.handleEvent(event), true);\n }\n\n protected onDestroy(): void {}\n\n private handleEvent(event: Event): void {\n try {\n const matched = this.findMatchedElement(event);\n if (!matched) return;\n\n const data = this.extractData(matched);\n if (data === null) return;\n\n this.factory.trackAuto(this.config.eventType, data, {\n origin: this.config.origin,\n });\n } catch (error) {\n this.context.logger.debug(\n `[ConfiguredSelectorDetector] ${this.config.eventType} ignored:`,\n error\n );\n }\n }\n\n /**\n * Walk-up a partir do target (click em filho → botão/form pai).\n * Em submit, também considera o form do evento.\n */\n private findMatchedElement(event: Event): Element | null {\n const candidates: Element[] = [];\n\n if (event.type === 'submit' && event.target instanceof Element) {\n candidates.push(event.target);\n }\n\n let current: Element | null =\n event.target instanceof Element ? event.target : null;\n\n while (current && current !== document.documentElement) {\n candidates.push(current);\n current = current.parentElement;\n }\n\n for (const element of candidates) {\n if (\n this.resolver.matches(\n element,\n this.config.selector,\n this.selectorType\n )\n ) {\n return element;\n }\n }\n\n return null;\n }\n\n /**\n * Extrai payload mínimo. `null` = não disparar.\n * LEAD exige email|phone|name. SEARCH exige query.\n * Commerce events: parcial OK (CommerceResolver completa depois).\n */\n private extractData(element: Element): ConversionEventData | null {\n const { eventType } = this.config;\n\n if (eventType === 'LEAD') {\n const customer = this.customerExtractor.extractFromElement(element);\n if (!customer.email && !customer.phone && !customer.name) {\n this.context.logger.debug(\n '[ConfiguredSelectorDetector] LEAD skipped: no email/phone/name'\n );\n return null;\n }\n return {\n ...(customer.email ? { email: customer.email } : {}),\n ...(customer.phone ? { phone: customer.phone } : {}),\n ...(customer.name ? { name: customer.name } : {}),\n };\n }\n\n if (eventType === 'ADD_TO_CART' || eventType === 'REMOVE_FROM_CART') {\n const product = this.productExtractor.extractFromElement(element);\n if (eventType === 'REMOVE_FROM_CART') {\n return {\n ...(product.productId ? { productId: product.productId } : {}),\n ...(product.quantity != null ? { quantity: product.quantity } : {}),\n };\n }\n return {\n ...(product.productId ? { productId: product.productId } : {}),\n ...(product.productName ? { productName: product.productName } : {}),\n ...(product.price != null ? { price: product.price } : {}),\n ...(product.currency ? { currency: product.currency } : {}),\n ...(product.quantity != null ? { quantity: product.quantity } : {}),\n };\n }\n\n if (eventType === 'SEARCH') {\n const query =\n element.getAttribute('data-query') ??\n (typeof HTMLInputElement !== 'undefined' &&\n element instanceof HTMLInputElement\n ? element.value\n : '');\n if (!query.trim()) return null;\n return { query: query.trim() };\n }\n\n if (eventType === 'INITIATE_CHECKOUT' || eventType === 'PURCHASE') {\n // Payload vazio permitido — CommerceResolver usa selectedItems/catalog.\n return {};\n }\n\n if (eventType === 'VIEW_CONTENT') {\n const product = this.productExtractor.extractFromElement(element);\n return {\n ...(product.productId ? { contentId: product.productId } : {}),\n ...(product.price != null ? { value: product.price } : {}),\n ...(product.currency ? { currency: product.currency } : {}),\n };\n }\n\n return {};\n }\n}\n","const CARD_NUMBER_IDS = ['card_number', 'cardNumber', 'card-number', 'cc_number'];\nconst CARD_NUMBER_NAMES = ['card_number', 'cardNumber', 'cc_number'];\nconst CVV_IDS = ['cvv', 'cvc', 'security_code'];\nconst CVV_NAMES = ['cvv', 'cvc', 'security_code'];\n\nfunction isVisibleInput(el: HTMLInputElement): boolean {\n return el.type !== 'hidden' && !el.disabled;\n}\n\nfunction inputHasValue(input: HTMLInputElement): boolean {\n return input.value.length > 0;\n}\n\nfunction findStartedByIdOrName(ids: string[], names: string[]): boolean {\n if (typeof document === 'undefined') return false;\n\n for (const id of ids) {\n const el = document.getElementById(id);\n if (el instanceof HTMLInputElement && isVisibleInput(el) && inputHasValue(el)) {\n return true;\n }\n }\n\n for (const name of names) {\n const elements = document.querySelectorAll(`input[name=\"${name}\"]`);\n for (const el of elements) {\n if (el instanceof HTMLInputElement && isVisibleInput(el) && inputHasValue(el)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction findStartedByAutocomplete(value: string): boolean {\n if (typeof document === 'undefined') return false;\n\n const elements = document.querySelectorAll(`input[autocomplete=\"${value}\"]`);\n for (const el of elements) {\n if (el instanceof HTMLInputElement && isVisibleInput(el) && inputHasValue(el)) {\n return true;\n }\n }\n\n return false;\n}\n\n/** Detecta início de preenchimento — nenhum valor é armazenado ou retornado. */\nexport function scanPaymentInputStarted(): boolean {\n return (\n findStartedByAutocomplete('cc-number') ||\n findStartedByIdOrName(CARD_NUMBER_IDS, CARD_NUMBER_NAMES) ||\n findStartedByAutocomplete('cc-exp') ||\n findStartedByAutocomplete('cc-exp-month') ||\n findStartedByAutocomplete('cc-exp-year') ||\n findStartedByAutocomplete('cc-csc') ||\n findStartedByIdOrName(CVV_IDS, CVV_NAMES)\n );\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\nimport { scanPaymentInputStarted } from './card-field-detection';\n\nconst FIELD_EVENTS = ['input', 'change', 'focusin'] as const;\n\nexport class CardDetector extends BaseAutoTracker {\n readonly name = 'CardDetector';\n\n private readonly factory: TrackerFactory;\n\n private checkTimer: ReturnType<typeof setTimeout> | null = null;\n\n private tracked = false;\n\n constructor(context: PixelRuntimeContext, factory: TrackerFactory) {\n super(context);\n this.factory = factory;\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n\n for (const eventName of FIELD_EVENTS) {\n this.addDocumentListener(eventName, () => this.scheduleCheck(), true);\n }\n\n this.observeDom(() => this.scheduleCheck());\n this.scheduleCheck();\n }\n\n protected onDestroy(): void {\n this.checkTimer = this.clearManagedTimeout(this.checkTimer);\n this.tracked = false;\n }\n\n private scheduleCheck(): void {\n if (this.tracked) return;\n this.checkTimer = this.clearManagedTimeout(this.checkTimer);\n this.checkTimer = setTimeout(() => {\n this.checkTimer = null;\n this.evaluate();\n }, 300);\n }\n\n private evaluate(): void {\n if (this.tracked || !this.isDocumentAvailable()) return;\n if (!scanPaymentInputStarted()) return;\n\n this.tracked = true;\n this.factory.trackAuto(\n 'ADD_PAYMENT_INFO',\n { paymentMethod: 'CREDIT_CARD' },\n { origin: 'auto:card' }\n );\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\n\nconst CHECKOUT_SELECTORS = [\n 'form[action*=\"checkout\"]',\n '[data-checkout]',\n '[name=\"checkout\"]',\n 'button[name=\"checkout\"]',\n 'a[href*=\"checkout\"]',\n];\n\nexport class CheckoutDetector extends BaseAutoTracker {\n readonly name = 'CheckoutDetector';\n private readonly factory: TrackerFactory;\n\n constructor(context: PixelRuntimeContext, factory: TrackerFactory) {\n super(context);\n this.factory = factory;\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n this.addDocumentListener('click', event => this.handleClick(event), true);\n this.addDocumentListener('submit', event => this.handleSubmit(event), true);\n }\n\n protected onDestroy(): void {}\n\n private handleClick(event: Event): void {\n const element =\n event.target instanceof Element\n ? event.target.closest('a,button,[role=\"button\"],input[type=\"submit\"]')\n : null;\n\n if (!element) return;\n\n const text = element.textContent?.toLowerCase() ?? '';\n const href = (element as HTMLAnchorElement).href?.toLowerCase() ?? '';\n\n const isCheckout =\n CHECKOUT_SELECTORS.some(selector => element.matches(selector)) ||\n (text.includes('checkout') && !text.includes('continue shopping')) ||\n (text.includes('finalizar') && text.includes('compra')) ||\n href.includes('/checkout');\n\n if (isCheckout) {\n this.factory.trackAuto('INITIATE_CHECKOUT', {}, {\n origin: 'auto:checkout',\n });\n }\n }\n\n private handleSubmit(event: Event): void {\n const form = event.target instanceof HTMLFormElement ? event.target : null;\n if (!form) return;\n\n const action = form.getAttribute('action')?.toLowerCase() ?? '';\n if (action.includes('checkout') || form.matches('[data-checkout]')) {\n this.factory.trackAuto('INITIATE_CHECKOUT', {}, {\n origin: 'auto:checkout',\n });\n }\n }\n}\n","import type { SelectorType } from '@/config/shared/selector';\n\nimport type { ConversionEventType } from '../../contracts';\n\nconst DATA_TRACK_EVENT_MAP: Record<string, ConversionEventType> = {\n purchase: 'PURCHASE',\n lead: 'LEAD',\n add_to_cart: 'ADD_TO_CART',\n addtocart: 'ADD_TO_CART',\n remove_from_cart: 'REMOVE_FROM_CART',\n removefromcart: 'REMOVE_FROM_CART',\n initiate_checkout: 'INITIATE_CHECKOUT',\n initiatecheckout: 'INITIATE_CHECKOUT',\n checkout: 'INITIATE_CHECKOUT',\n add_payment_info: 'ADD_PAYMENT_INFO',\n addpaymentinfo: 'ADD_PAYMENT_INFO',\n view_content: 'VIEW_CONTENT',\n viewcontent: 'VIEW_CONTENT',\n search: 'SEARCH',\n};\n\nexport function resolveDataTrackEvent(\n value: string\n): ConversionEventType | null {\n const normalized = value.trim().toLowerCase().replace(/\\s+/g, '_');\n return DATA_TRACK_EVENT_MAP[normalized] ?? null;\n}\n\nexport function buildSelector(selector: string): string {\n if (\n selector.startsWith('[') ||\n selector.startsWith('.') ||\n selector.startsWith('#')\n ) {\n return selector;\n }\n return `[data-track=\"${selector}\"]`;\n}\n\nexport function buildSelectorFromConfig(\n selector: string,\n selectorType: SelectorType = 'css'\n): string {\n if (\n selector.startsWith('[') ||\n selector.startsWith('.') ||\n selector.startsWith('#')\n ) {\n return selector;\n }\n\n switch (selectorType) {\n case 'id':\n return selector.startsWith('#') ? selector : `#${selector}`;\n case 'class':\n return selector.startsWith('.') ? selector : `.${selector}`;\n case 'css':\n return selector;\n case 'text':\n // Text selectors are resolved by SelectorResolver (Etapa 12B).\n // Do not wrap as data-track — that would be incorrect.\n return selector;\n case 'attribute':\n return buildSelector(selector);\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport type { ConversionEventData } from '@/events/conversion';\n\nimport type { ConversionEventType } from '../../contracts';\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\nimport { buildSelector, resolveDataTrackEvent } from './selector-utils';\n\nexport class SelectorDetector extends BaseAutoTracker {\n readonly name = 'SelectorDetector';\n private readonly factory: TrackerFactory;\n\n private readonly selectors: string[];\n\n constructor(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n selectors: string[] = []\n ) {\n super(context);\n this.factory = factory;\n this.selectors =\n selectors.length > 0 ? selectors : ['[data-track]', '[data-track-event]'];\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n this.addDocumentListener('click', event => this.handleClick(event), true);\n }\n\n protected onDestroy(): void {}\n\n private handleClick(event: Event): void {\n let element = event.target instanceof Element ? event.target : null;\n\n while (element && element !== document.body) {\n const match = this.matchElement(element);\n if (match) {\n this.factory.trackAuto(match.type, match.data, {\n origin: 'auto:selector',\n });\n return;\n }\n element = element.parentElement;\n }\n }\n\n private matchElement(\n element: Element\n ): { type: ConversionEventType; data: ConversionEventData } | null {\n for (const selector of this.selectors) {\n const built = buildSelector(selector);\n if (!element.matches(built)) continue;\n\n const trackValue =\n element.getAttribute('data-track') ??\n element.getAttribute('data-track-event') ??\n element.getAttribute('data-event');\n\n if (!trackValue) continue;\n\n const type = resolveDataTrackEvent(trackValue);\n if (!type) continue;\n\n const data: ConversionEventData = {};\n const valueAttr = element.getAttribute('data-track-value');\n if (valueAttr && type === 'PURCHASE') {\n Object.assign(data, { value: Number(valueAttr) || undefined });\n }\n\n return { type, data };\n }\n\n const dataTrack = element.getAttribute('data-track');\n if (dataTrack) {\n const type = resolveDataTrackEvent(dataTrack);\n if (type) return { type, data: {} };\n }\n\n return null;\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\n\nconst DEFAULT_KEYWORD_EVENTS: Array<{\n keyword: string;\n type: 'INITIATE_CHECKOUT' | 'ADD_TO_CART';\n}> = [\n { keyword: 'comprar agora', type: 'INITIATE_CHECKOUT' },\n { keyword: 'finalizar compra', type: 'INITIATE_CHECKOUT' },\n { keyword: 'checkout', type: 'INITIATE_CHECKOUT' },\n { keyword: 'comprar', type: 'ADD_TO_CART' },\n];\n\nexport class TextDetector extends BaseAutoTracker {\n readonly name = 'TextDetector';\n private readonly factory: TrackerFactory;\n\n private readonly keywords: string[];\n\n constructor(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n keywords: string[] = []\n ) {\n super(context);\n this.factory = factory;\n this.keywords = keywords;\n }\n\n protected onInit(): void {\n if (!this.isDocumentAvailable()) return;\n this.addDocumentListener('click', event => this.handleClick(event), true);\n }\n\n protected onDestroy(): void {}\n\n private handleClick(event: Event): void {\n const element =\n event.target instanceof Element\n ? event.target.closest('a,button,[role=\"button\"],input[type=\"submit\"]')\n : null;\n\n if (!element?.textContent) return;\n\n const text = element.textContent.trim().toLowerCase();\n if (!text) return;\n\n for (const rule of DEFAULT_KEYWORD_EVENTS) {\n if (\n this.keywords.some(k => k.toLowerCase() === rule.keyword) &&\n text.includes(rule.keyword)\n ) {\n this.factory.trackAuto(rule.type, {}, {\n origin: 'auto:text',\n });\n return;\n }\n }\n\n for (const keyword of this.keywords) {\n const normalized = keyword.toLowerCase();\n if (text.includes(normalized)) {\n this.factory.trackAuto('INITIATE_CHECKOUT', {}, {\n origin: 'auto:text',\n });\n return;\n }\n }\n }\n}\n","/**\n * Coordenador de patch do History API para multi-instance.\n * Infraestrutura de browser — não armazena estado de negócio.\n */\ntype NavigationListener = () => void;\n\nexport class HistoryNavigationPatch {\n private static refCount = 0;\n\n private static readonly listeners = new Set<NavigationListener>();\n\n private static originalPushState: History['pushState'] | null = null;\n\n private static originalReplaceState: History['replaceState'] | null = null;\n\n private static installed = false;\n\n static subscribe(listener: NavigationListener): () => void {\n if (typeof window === 'undefined' || typeof history === 'undefined') {\n return () => {};\n }\n\n this.listeners.add(listener);\n this.refCount += 1;\n this.install();\n\n return () => {\n this.listeners.delete(listener);\n this.refCount -= 1;\n if (this.refCount <= 0) {\n this.uninstall();\n this.refCount = 0;\n }\n };\n }\n\n /** @internal Testes apenas. */\n static resetForTests(): void {\n this.listeners.clear();\n this.refCount = 0;\n this.uninstall();\n }\n\n private static install(): void {\n if (this.installed) return;\n\n this.originalPushState = history.pushState.bind(history);\n this.originalReplaceState = history.replaceState.bind(history);\n\n history.pushState = (...args: Parameters<History['pushState']>) => {\n this.originalPushState?.(...args);\n this.notify();\n };\n\n history.replaceState = (...args: Parameters<History['replaceState']>) => {\n this.originalReplaceState?.(...args);\n this.notify();\n };\n\n this.installed = true;\n }\n\n private static uninstall(): void {\n if (!this.installed) return;\n\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n }\n\n this.originalPushState = null;\n this.originalReplaceState = null;\n this.installed = false;\n }\n\n private static notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BaseAutoTracker } from '../../auto/BaseAutoTracker';\nimport type { TrackerFactory } from '../../tracks/TrackerFactory';\nimport { HistoryNavigationPatch } from './HistoryNavigationPatch';\n\nexport class UrlDetector extends BaseAutoTracker {\n readonly name = 'UrlDetector';\n\n private readonly factory: TrackerFactory;\n\n private readonly patterns: RegExp[];\n\n private unsubscribeHistory: (() => void) | null = null;\n\n constructor(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n patterns: string[] = []\n ) {\n super(context);\n this.factory = factory;\n this.patterns = patterns.map(pattern => new RegExp(pattern, 'i'));\n }\n\n protected onInit(): void {\n if (!this.isWindowAvailable()) return;\n\n this.checkUrl();\n this.addWindowListener('popstate', () => this.checkUrl());\n this.unsubscribeHistory = HistoryNavigationPatch.subscribe(() => this.checkUrl());\n }\n\n protected onDestroy(): void {\n this.unsubscribeHistory?.();\n this.unsubscribeHistory = null;\n }\n\n private checkUrl(): void {\n if (!this.isWindowAvailable()) return;\n\n const href = window.location.href;\n const path = window.location.pathname;\n\n for (const pattern of this.patterns) {\n if (pattern.test(href) || pattern.test(path)) {\n const isPurchase = /thank|success|order|obrigado/i.test(pattern.source);\n this.factory.trackAuto(isPurchase ? 'PURCHASE' : 'INITIATE_CHECKOUT', {}, {\n origin: 'auto:url',\n });\n return;\n }\n }\n }\n}\n","import type {\n AutoConversionConfig,\n FormCapableAutoDetectorConfig,\n} from '@/config/types/modules/conversion';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport type {\n ConversionEventOrigin,\n ConversionEventType,\n IConversionDetector,\n} from '../contracts';\nimport { TrackerFactory } from '../tracks/TrackerFactory';\nimport { ConfiguredFormDetector } from '../detectors/configured/ConfiguredFormDetector';\nimport type { FormCapableEventType } from '../detectors/configured/ConfiguredFormDetector';\nimport { ConfiguredSelectorDetector } from '../detectors/configured/ConfiguredSelectorDetector';\nimport { CardDetector } from '../detectors/card/CardDetector';\nimport { CheckoutDetector } from '../detectors/checkout/CheckoutDetector';\nimport { SelectorDetector } from '../detectors/selector/SelectorDetector';\nimport { SelectorResolver } from '../detectors/SelectorResolver';\nimport { TextDetector } from '../detectors/text/TextDetector';\nimport { UrlDetector } from '../detectors/url/UrlDetector';\n\ntype DetectorConfigEntry = {\n readonly configKey: keyof AutoConversionConfig['detectors'];\n readonly eventType: ConversionEventType;\n readonly origin: ConversionEventOrigin;\n};\n\ntype FormDetectorConfigEntry = {\n readonly configKey: 'lead' | 'addToCart' | 'initiateCheckout';\n readonly eventType: FormCapableEventType;\n readonly origin: ConversionEventOrigin;\n};\n\nconst CONFIGURED_DETECTORS: readonly DetectorConfigEntry[] = [\n { configKey: 'purchase', eventType: 'PURCHASE', origin: 'auto:purchase' },\n { configKey: 'lead', eventType: 'LEAD', origin: 'auto:lead' },\n {\n configKey: 'addToCart',\n eventType: 'ADD_TO_CART',\n origin: 'auto:addToCart',\n },\n {\n configKey: 'removeFromCart',\n eventType: 'REMOVE_FROM_CART',\n origin: 'auto:removeFromCart',\n },\n {\n configKey: 'initiateCheckout',\n eventType: 'INITIATE_CHECKOUT',\n origin: 'auto:initiateCheckout',\n },\n { configKey: 'search', eventType: 'SEARCH', origin: 'auto:search' },\n {\n configKey: 'viewContent',\n eventType: 'VIEW_CONTENT',\n origin: 'auto:viewContent',\n },\n];\n\nconst FORM_DETECTORS: readonly FormDetectorConfigEntry[] = [\n { configKey: 'lead', eventType: 'LEAD', origin: 'auto:lead' },\n {\n configKey: 'addToCart',\n eventType: 'ADD_TO_CART',\n origin: 'auto:addToCart',\n },\n {\n configKey: 'initiateCheckout',\n eventType: 'INITIATE_CHECKOUT',\n origin: 'auto:initiateCheckout',\n },\n];\n\n/**\n * Orquestra auto-detectors configurados e heurísticos.\n *\n * Ordem de criação (Etapa 12K):\n * 1. ConfiguredFormDetector / ConfiguredSelectorDetector\n * 2. Rules heurísticas (Selector/Text/Url/Checkout/Card)\n * 3. CardDetector via addPaymentInfo (se rules.card off)\n *\n * Regra selector vs form:\n * - selectorForm → ConfiguredFormDetector (pode incluir selector)\n * - selector sem selectorForm → ConfiguredSelectorDetector\n * - nunca ambos para o mesmo evento\n */\nexport class AutoTrackerFactory {\n static create(\n context: PixelRuntimeContext,\n factory: TrackerFactory\n ): IConversionDetector[] {\n const { auto, rules } = context.config.modules.conversion;\n const detectors: IConversionDetector[] = [];\n const logger = context.logger;\n\n if (!auto.enabled) {\n logger.debug('[AutoTrackerFactory] Auto detection disabled');\n return detectors;\n }\n\n // 1. Configurados específicos primeiro\n detectors.push(...this.createConfiguredDetectors(context, factory, auto));\n\n // 2. Heurísticos / rules\n if (rules.enabled) {\n if (rules.selectors.length > 0) {\n detectors.push(new SelectorDetector(context, factory, rules.selectors));\n logger.debug('[AutoTrackerFactory] SelectorDetector registered');\n }\n if (rules.texts.length > 0) {\n detectors.push(new TextDetector(context, factory, rules.texts));\n logger.debug('[AutoTrackerFactory] TextDetector registered');\n }\n if (rules.urlPatterns.length > 0) {\n detectors.push(new UrlDetector(context, factory, rules.urlPatterns));\n logger.debug('[AutoTrackerFactory] UrlDetector registered');\n }\n if (rules.checkout.enabled) {\n detectors.push(new CheckoutDetector(context, factory));\n logger.debug('[AutoTrackerFactory] CheckoutDetector registered');\n }\n if (rules.card.enabled) {\n detectors.push(new CardDetector(context, factory));\n logger.debug('[AutoTrackerFactory] CardDetector registered (rules)');\n }\n }\n\n // 3. Payment card via auto.detectors (sem duplicar rules.card)\n const paymentCfg = auto.detectors.addPaymentInfo;\n if (paymentCfg.enabled && paymentCfg.cardDetection && !rules.card.enabled) {\n detectors.push(new CardDetector(context, factory));\n logger.debug(\n '[AutoTrackerFactory] CardDetector registered (addPaymentInfo)'\n );\n }\n\n logger.debug(\n `[AutoTrackerFactory] Created ${detectors.length} detector(s)`\n );\n\n return detectors;\n }\n\n private static createConfiguredDetectors(\n context: PixelRuntimeContext,\n factory: TrackerFactory,\n auto: AutoConversionConfig\n ): IConversionDetector[] {\n const detectors: IConversionDetector[] = [];\n const resolver = new SelectorResolver(context.logger);\n const logger = context.logger;\n const formKeys = new Set<string>();\n\n for (const entry of FORM_DETECTORS) {\n const cfg = auto.detectors[\n entry.configKey\n ] as FormCapableAutoDetectorConfig;\n if (!cfg.enabled) {\n logger.debug(\n `[AutoTrackerFactory] Skipped disabled detector: ${entry.configKey}`\n );\n continue;\n }\n if (!cfg.selectorForm) continue;\n\n detectors.push(\n new ConfiguredFormDetector(context, factory, {\n eventType: entry.eventType,\n selector: cfg.selector,\n selectorType: cfg.selectorType,\n selectorForm: cfg.selectorForm,\n origin: entry.origin,\n })\n );\n formKeys.add(entry.configKey);\n logger.debug(\n `[AutoTrackerFactory] ConfiguredFormDetector registered for ${entry.eventType}`\n );\n }\n\n for (const entry of CONFIGURED_DETECTORS) {\n const cfg = auto.detectors[entry.configKey];\n if (!cfg.enabled) continue;\n if (!('selector' in cfg)) continue;\n\n // Com selectorForm, o FormDetector já cobre selector+form (evita double-fire).\n if (formKeys.has(entry.configKey)) {\n logger.debug(\n `[AutoTrackerFactory] Skipped ConfiguredSelectorDetector for ${entry.configKey}: selectorForm configured`\n );\n continue;\n }\n\n if (!resolver.hasEntries(cfg.selector)) {\n logger.debug(\n `[AutoTrackerFactory] Skipped ConfiguredSelectorDetector for ${entry.configKey}: empty selector`\n );\n continue;\n }\n\n detectors.push(\n new ConfiguredSelectorDetector(context, factory, {\n eventType: entry.eventType,\n selector: cfg.selector!,\n selectorType: cfg.selectorType,\n origin: entry.origin,\n })\n );\n logger.debug(\n `[AutoTrackerFactory] ConfiguredSelectorDetector registered for ${entry.eventType}`\n );\n }\n\n return detectors;\n }\n}\n","export class ConversionDeduper {\n private readonly sentKeys = new Set<string>();\n\n has(key: string): boolean {\n return this.sentKeys.has(key);\n }\n\n add(key: string): void {\n this.sentKeys.add(key);\n }\n\n clear(): void {\n this.sentKeys.clear();\n }\n\n getKeys(): readonly string[] {\n return Array.from(this.sentKeys);\n }\n\n get size(): number {\n return this.sentKeys.size;\n }\n}\n","import type { AddToCartData } from '@/events/conversion';\n\n/** Janela de interação para dedupe de ADD_TO_CART / cross-detector (ms). */\nexport const CONVERSION_INTERACTION_WINDOW_MS = 500;\n\n/**\n * Estratégia de dedupe para ADD_TO_CART (Etapa 12J).\n *\n * Objetivo:\n * - Bloquear duplicidade na mesma interação (mesmo bucket).\n * - Permitir nova ação legítima após a janela.\n * - Não bloquear o mesmo productId para sempre.\n *\n * Chave (com productId):\n * ADD_TO_CART:product:{id}:qty:{n}:bucket:{t}\n *\n * Origin NÃO entra na chave quando há productId — assim selector + form\n * na mesma interação colidem corretamente.\n *\n * Sem productId:\n * ADD_TO_CART:name:{name}:qty:{n}:bucket:{t} | ADD_TO_CART:interaction:{bucket}\n */\nexport function buildAddToCartDedupeKey(\n data: AddToCartData | undefined,\n now: number = Date.now(),\n windowMs: number = CONVERSION_INTERACTION_WINDOW_MS\n): string {\n const bucket = getInteractionBucket(now, windowMs);\n const productId =\n typeof data?.productId === 'string' ? data.productId.trim() : '';\n const quantity = normalizeQuantity(data?.quantity);\n const productName =\n typeof data?.productName === 'string' ? data.productName.trim() : '';\n\n if (productId) {\n return `ADD_TO_CART:product:${productId}:qty:${quantity}:bucket:${bucket}`;\n }\n\n if (productName) {\n return `ADD_TO_CART:name:${productName}:qty:${quantity}:bucket:${bucket}`;\n }\n\n return `ADD_TO_CART:interaction:${bucket}`;\n}\n\nexport function getInteractionBucket(\n now: number = Date.now(),\n windowMs: number = CONVERSION_INTERACTION_WINDOW_MS\n): number {\n const window = windowMs > 0 ? windowMs : CONVERSION_INTERACTION_WINDOW_MS;\n return Math.floor(now / window);\n}\n\nfunction normalizeQuantity(quantity: number | undefined): number {\n if (typeof quantity === 'number' && Number.isFinite(quantity)) {\n return quantity;\n }\n return 1;\n}\n","import type {\n AddToCartData,\n ConversionEventData,\n LeadData,\n PurchaseData,\n RemoveFromCartData,\n SearchData,\n ViewContentData,\n} from '@/events/conversion';\n\nimport type { ConversionEventOrigin, ConversionEventType } from '../contracts';\nimport {\n buildAddToCartDedupeKey,\n CONVERSION_INTERACTION_WINDOW_MS,\n getInteractionBucket,\n} from './AddToCartDedupe';\n\nexport { CONVERSION_INTERACTION_WINDOW_MS, getInteractionBucket };\n\nconst CLICK_ORIGINS = new Set<ConversionEventOrigin>([\n 'manual',\n 'auto:selector',\n 'auto:text',\n 'auto:checkout',\n 'auto:purchase',\n 'auto:lead',\n 'auto:addToCart',\n 'auto:removeFromCart',\n 'auto:initiateCheckout',\n 'auto:addPaymentInfo',\n 'auto:search',\n 'auto:viewContent',\n]);\n\nfunction secondBucket(now = Date.now()): number {\n return Math.floor(now / 1000);\n}\n\nfunction currentPath(): string {\n if (typeof window === 'undefined') return '';\n return window.location.pathname;\n}\n\n/**\n * Chave canônica de dedupe — sem origem (exceto fallbacks específicos).\n * Garante 1 evento por tipo/interação mesmo com múltiplos detectores.\n */\nexport function buildCanonicalDedupeKey(\n type: ConversionEventType,\n data: ConversionEventData | undefined,\n origin: ConversionEventOrigin,\n sessionId: string,\n now = Date.now()\n): string {\n const payload = data ?? {};\n const bucket = getInteractionBucket(now, CONVERSION_INTERACTION_WINDOW_MS);\n\n switch (type) {\n case 'PURCHASE': {\n const purchase = payload as PurchaseData;\n if (purchase.orderId) {\n return `PURCHASE:order:${purchase.orderId}`;\n }\n if (origin === 'auto:url') {\n return `PURCHASE:url:${currentPath()}`;\n }\n if (CLICK_ORIGINS.has(origin)) {\n return `PURCHASE:interaction:${bucket}`;\n }\n return `PURCHASE:manual:${secondBucket(now)}`;\n }\n case 'LEAD': {\n const lead = payload as LeadData;\n const identity = `${lead.email ?? ''}:${lead.phone ?? ''}`;\n if (identity !== ':') {\n return `LEAD:identity:${identity}`;\n }\n return `LEAD:interaction:${bucket}`;\n }\n case 'ADD_TO_CART':\n return buildAddToCartDedupeKey(\n payload as AddToCartData,\n now,\n CONVERSION_INTERACTION_WINDOW_MS\n );\n case 'REMOVE_FROM_CART': {\n const remove = payload as RemoveFromCartData;\n if (remove.productId) {\n return `REMOVE_FROM_CART:product:${remove.productId}`;\n }\n return `REMOVE_FROM_CART:interaction:${bucket}`;\n }\n case 'INITIATE_CHECKOUT': {\n if (origin === 'auto:url') {\n return `INITIATE_CHECKOUT:url:${currentPath()}`;\n }\n return `INITIATE_CHECKOUT:interaction:${bucket}`;\n }\n case 'ADD_PAYMENT_INFO':\n return `ADD_PAYMENT_INFO:session:${sessionId}`;\n case 'VIEW_CONTENT': {\n const view = payload as ViewContentData;\n if (view.contentId) {\n return `VIEW_CONTENT:content:${view.contentId}`;\n }\n return `VIEW_CONTENT:interaction:${bucket}`;\n }\n case 'SEARCH': {\n const search = payload as SearchData;\n return `SEARCH:query:${search.query}`;\n }\n default:\n return `${type}:interaction:${bucket}`;\n }\n}\n","import type { ConversionEventData } from '@/events/conversion';\n\nimport type { ConversionEventType } from '../contracts';\nimport { TrackerFactory } from './TrackerFactory';\n\nexport type ConversionTrackFn = (\n type: ConversionEventType,\n data: ConversionEventData,\n options?: { dedupeKey?: string; origin?: string }\n) => void;\n\nexport abstract class BaseTracker {\n protected readonly factory: TrackerFactory;\n\n constructor(factory: TrackerFactory) {\n this.factory = factory;\n }\n}\n","import type { AddPaymentInfoData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class AddPaymentInfoTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: AddPaymentInfoData): void {\n if (!this.factory.isManualEnabled('addPaymentInfo')) return;\n this.factory.dispatchManual('ADD_PAYMENT_INFO', data);\n }\n}\n","import type { AddToCartData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class AddToCartTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: AddToCartData): void {\n if (!this.factory.isManualEnabled('addToCart')) return;\n this.factory.dispatchManual('ADD_TO_CART', data);\n }\n}\n","import type { InitiateCheckoutData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class InitiateCheckoutTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: InitiateCheckoutData): void {\n if (!this.factory.isManualEnabled('initiateCheckout')) return;\n this.factory.dispatchManual('INITIATE_CHECKOUT', data);\n }\n}\n","import type { LeadData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class LeadTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: LeadData): void {\n if (!this.factory.isManualEnabled('lead')) return;\n this.factory.dispatchManual('LEAD', data);\n }\n}\n","import type { PurchaseData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class PurchaseTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: PurchaseData): void {\n if (!this.factory.isManualEnabled('purchase')) return;\n this.factory.dispatchManual('PURCHASE', data);\n }\n}\n","import type { RemoveFromCartData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class RemoveFromCartTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: RemoveFromCartData): void {\n if (!this.factory.isManualEnabled('removeFromCart')) return;\n this.factory.dispatchManual('REMOVE_FROM_CART', data);\n }\n}\n","import type { SearchData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class SearchTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: SearchData): void {\n if (!this.factory.isManualEnabled('search')) return;\n this.factory.dispatchManual('SEARCH', data);\n }\n}\n","import type { ViewContentData } from '@/events/conversion';\n\nimport { BaseTracker } from './BaseTracker';\nimport type { TrackerFactory } from './TrackerFactory';\n\nexport class ViewContentTracker extends BaseTracker {\n constructor(factory: TrackerFactory) {\n super(factory);\n }\n\n track(data: ViewContentData): void {\n if (!this.factory.isManualEnabled('viewContent')) return;\n this.factory.dispatchManual('VIEW_CONTENT', data);\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\nimport type {\n AddToCartData,\n ConversionEventData,\n LeadData,\n PurchaseData,\n RemoveFromCartData,\n} from '@/events/conversion';\n\nimport type {\n ConversionEventOrigin,\n ConversionEventType,\n TrackConversionOptions,\n} from '../contracts';\nimport {\n CommerceResolver,\n type CommerceEventType,\n} from '../commerce/CommerceResolver';\nimport type { CommerceState } from '../commerce/CommerceState';\nimport { OrderCalculator } from '../commerce/OrderCalculator';\nimport type { ProductCatalog } from '../commerce/ProductCatalog';\nimport { buildCanonicalDedupeKey } from '../dedupe/dedupe-key';\nimport type { ConversionTrackFn } from './BaseTracker';\nimport { AddPaymentInfoTracker } from './AddPaymentInfoTracker';\nimport { AddToCartTracker } from './AddToCartTracker';\nimport { InitiateCheckoutTracker } from './InitiateCheckoutTracker';\nimport { LeadTracker } from './LeadTracker';\nimport { PurchaseTracker } from './PurchaseTracker';\nimport { RemoveFromCartTracker } from './RemoveFromCartTracker';\nimport { SearchTracker } from './SearchTracker';\nimport { ViewContentTracker } from './ViewContentTracker';\n\nconst COMMERCE_EVENT_TYPES: readonly CommerceEventType[] = [\n 'ADD_TO_CART',\n 'REMOVE_FROM_CART',\n 'INITIATE_CHECKOUT',\n 'PURCHASE',\n];\n\nexport type TrackerFactoryCommerceDeps = {\n readonly catalog: ProductCatalog;\n readonly state: CommerceState;\n};\n\nexport class TrackerFactory {\n private readonly context: PixelRuntimeContext;\n\n private readonly trackFn: ConversionTrackFn;\n\n private readonly dedupeSessionId: string;\n\n private readonly resolver: CommerceResolver | null;\n\n private readonly commerceState: CommerceState | null;\n\n readonly purchase: PurchaseTracker;\n\n readonly lead: LeadTracker;\n\n readonly addToCart: AddToCartTracker;\n\n readonly removeFromCart: RemoveFromCartTracker;\n\n readonly initiateCheckout: InitiateCheckoutTracker;\n\n readonly addPaymentInfo: AddPaymentInfoTracker;\n\n readonly viewContent: ViewContentTracker;\n\n readonly search: SearchTracker;\n\n constructor(\n context: PixelRuntimeContext,\n trackFn: ConversionTrackFn,\n dedupeSessionId: string,\n commerce?: TrackerFactoryCommerceDeps\n ) {\n this.context = context;\n this.trackFn = trackFn;\n this.dedupeSessionId = dedupeSessionId;\n this.commerceState = commerce?.state ?? null;\n\n if (commerce) {\n const cfg = context.config.modules.conversion.commerce;\n this.resolver = new CommerceResolver({\n catalog: commerce.catalog,\n state: commerce.state,\n calculator: new OrderCalculator(),\n defaultCurrency: cfg?.currency,\n calculateValueFrom:\n cfg?.checkout?.calculateValueFrom ?? 'selected_items',\n });\n } else {\n this.resolver = null;\n }\n\n this.purchase = new PurchaseTracker(this);\n this.lead = new LeadTracker(this);\n this.addToCart = new AddToCartTracker(this);\n this.removeFromCart = new RemoveFromCartTracker(this);\n this.initiateCheckout = new InitiateCheckoutTracker(this);\n this.addPaymentInfo = new AddPaymentInfoTracker(this);\n this.viewContent = new ViewContentTracker(this);\n this.search = new SearchTracker(this);\n }\n\n trackAuto(\n type: ConversionEventType,\n data?: ConversionEventData,\n options?: TrackConversionOptions\n ): void {\n this.dispatch(type, data, options?.origin ?? 'auto:selector');\n }\n\n dispatchManual(type: ConversionEventType, data?: ConversionEventData): void {\n this.dispatch(type, data, 'manual');\n }\n\n normalize(\n type: ConversionEventType,\n data: ConversionEventData | undefined\n ): ConversionEventData {\n switch (type) {\n case 'SEARCH': {\n const search = data as { query?: string; searchTerm?: string };\n const query = search?.query ?? search?.searchTerm ?? '';\n if (!query.trim()) {\n throw new Error('[Conversion] SEARCH requires query');\n }\n return { query: query.trim() };\n }\n case 'PURCHASE': {\n const purchase = data as PurchaseData;\n if (purchase?.value != null && purchase.value < 0) {\n throw new Error('[Conversion] PURCHASE value cannot be negative');\n }\n return purchase ?? {};\n }\n case 'LEAD': {\n const lead = data as LeadData;\n if (!lead?.email && !lead?.phone && !lead?.name) {\n throw new Error('[Conversion] LEAD requires email, phone or name');\n }\n return lead;\n }\n default:\n return data ?? {};\n }\n }\n\n buildDedupeKey(\n type: ConversionEventType,\n data: ConversionEventData | undefined,\n origin: ConversionEventOrigin\n ): string {\n return buildCanonicalDedupeKey(type, data, origin, this.dedupeSessionId);\n }\n\n isManualEnabled(\n key:\n | 'purchase'\n | 'lead'\n | 'addToCart'\n | 'removeFromCart'\n | 'initiateCheckout'\n | 'addPaymentInfo'\n | 'viewContent'\n | 'search'\n ): boolean {\n return this.context.config.modules.conversion.manual[key].enabled;\n }\n\n private dispatch(\n type: ConversionEventType,\n data: ConversionEventData | undefined,\n origin: ConversionEventOrigin\n ): void {\n const enriched = this.enrichCommerce(type, data);\n const normalized = this.normalize(type, enriched);\n this.syncCommerceState(type, normalized);\n const key = buildCanonicalDedupeKey(\n type,\n normalized,\n origin,\n this.dedupeSessionId\n );\n this.trackFn(type, normalized, { dedupeKey: key, origin });\n }\n\n private enrichCommerce(\n type: ConversionEventType,\n data: ConversionEventData | undefined\n ): ConversionEventData | undefined {\n if (!this.resolver || !isCommerceEventType(type)) {\n return data;\n }\n\n const result = this.resolver.resolve({\n eventType: type,\n payload: (data ?? {}) as Record<string, unknown>,\n });\n\n return result.data as ConversionEventData;\n }\n\n /**\n * Sync controlado do checkout/cart após resolução.\n * - ADD_TO_CART: upsertItem (sem incremento automático)\n * - REMOVE_FROM_CART: removeItem\n * - Demais eventos: no-op (só leitura via CommerceResolver)\n * Sem productId → não escreve.\n */\n private syncCommerceState(\n type: ConversionEventType,\n data: ConversionEventData\n ): void {\n if (!this.commerceState) return;\n\n if (type === 'ADD_TO_CART') {\n this.syncAddToCart(data as AddToCartData);\n return;\n }\n\n if (type === 'REMOVE_FROM_CART') {\n this.syncRemoveFromCart(data as RemoveFromCartData);\n }\n }\n\n private syncAddToCart(data: AddToCartData): void {\n if (!this.commerceState) return;\n\n const productId =\n typeof data.productId === 'string' ? data.productId.trim() : '';\n if (!productId) return;\n\n const quantity =\n typeof data.quantity === 'number' && Number.isFinite(data.quantity)\n ? data.quantity\n : 1;\n\n // quantity <= 0: CommerceState.upsertItem remove o item\n this.commerceState.upsertItem({\n productId,\n quantity,\n ...(typeof data.price === 'number' && Number.isFinite(data.price)\n ? { price: data.price }\n : {}),\n ...(typeof data.currency === 'string' && data.currency.trim()\n ? { currency: data.currency.trim() }\n : {}),\n });\n }\n\n private syncRemoveFromCart(data: RemoveFromCartData): void {\n if (!this.commerceState) return;\n\n const productId =\n typeof data.productId === 'string' ? data.productId.trim() : '';\n if (!productId) return;\n\n this.commerceState.removeItem(productId);\n }\n}\n\nfunction isCommerceEventType(\n type: ConversionEventType\n): type is CommerceEventType {\n return (COMMERCE_EVENT_TYPES as readonly string[]).includes(type);\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\nimport type { PixelEvent } from '@/events';\nimport type { ConversionEventData } from '@/events/conversion';\n\nimport type { ConversionEventType } from './contracts';\nimport { AutoTrackerFactory } from './auto/AutoTrackerFactory';\nimport { CommerceState, ProductCatalog } from './commerce';\nimport { ConversionDeduper } from './dedupe/ConversionDeduper';\nimport type { IConversionDetector } from './contracts';\nimport { TrackerFactory } from './tracks/TrackerFactory';\n\nexport class ConversionEngine {\n private readonly context: PixelRuntimeContext;\n\n private readonly deduper = new ConversionDeduper();\n\n private readonly dedupeSessionId: string;\n\n /** Catálogo da instância — lido pelo CommerceResolver (sem escrita aqui). */\n readonly catalog: ProductCatalog;\n\n /**\n * Estado de checkout/cart da instância.\n * Lido pelo CommerceResolver; escrito de forma controlada no TrackerFactory\n * após ADD_TO_CART / REMOVE_FROM_CART (Etapa 12I).\n */\n readonly commerceState: CommerceState;\n\n readonly factory: TrackerFactory;\n\n private detectors: IConversionDetector[] = [];\n\n private active = false;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n this.dedupeSessionId = `${context.config.identity.pixelId}:${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;\n\n const commerce = context.config.modules.conversion.commerce;\n this.catalog = new ProductCatalog(commerce?.catalog?.products, {\n defaultCurrency: commerce?.currency,\n });\n this.commerceState = new CommerceState(commerce?.checkout?.selectedItems, {\n allowDynamicItems: commerce?.checkout?.allowDynamicItems !== false,\n });\n\n this.factory = new TrackerFactory(\n context,\n (type, data, options) => {\n this.dispatch(type, data, options?.dedupeKey);\n },\n this.dedupeSessionId,\n { catalog: this.catalog, state: this.commerceState }\n );\n }\n\n init(): void {\n if (this.active) return;\n\n this.detectors = AutoTrackerFactory.create(this.context, this.factory);\n for (const detector of this.detectors) {\n detector.init();\n }\n\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n\n for (let i = this.detectors.length - 1; i >= 0; i -= 1) {\n this.detectors[i]?.destroy();\n }\n this.detectors = [];\n this.deduper.clear();\n this.commerceState.clear();\n this.active = false;\n }\n\n getDedupeKeys(): readonly string[] {\n return this.deduper.getKeys();\n }\n\n getActiveDetectors(): readonly string[] {\n return this.detectors.map(\n detector => detector.name ?? detector.constructor.name\n );\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n private dispatch(\n type: ConversionEventType,\n data: ConversionEventData,\n dedupeKey?: string\n ): void {\n const key =\n dedupeKey ?? this.factory.buildDedupeKey(type, data, 'manual');\n\n if (this.deduper.has(key)) {\n this.context.logger.debug(`[ConversionEngine] Deduped ${type} (${key})`);\n return;\n }\n\n this.deduper.add(key);\n\n const event = this.context.services.eventBuilder.build({\n type,\n category: 'CONVERSION' as const,\n data,\n }) as PixelEvent;\n\n this.context.logger.debug(`[ConversionEngine] Dispatching ${type}`);\n this.context.services.dispatcher.dispatch(event);\n }\n}\n","import type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\nimport type {\n AddPaymentInfoData,\n AddToCartData,\n InitiateCheckoutData,\n LeadData,\n PurchaseData,\n RemoveFromCartData,\n SearchData,\n ViewContentData,\n} from '@/events/conversion';\n\nimport { ConversionEngine } from './conversion.engine';\n\nexport class ConversionModule implements PixelModule {\n readonly name = 'conversion' as const;\n\n private engine: ConversionEngine | null = null;\n\n private active = false;\n\n init(context: PixelRuntimeContext): void {\n if (this.active) {\n context.logger.debug('[Pixel] Conversion module already initialized');\n return;\n }\n\n if (!context.config.modules.conversion.enabled) {\n context.logger.debug('[Pixel] Conversion module disabled');\n return;\n }\n\n context.logger.debug('[Pixel] Conversion module initialized');\n\n this.engine = new ConversionEngine(context);\n this.engine.init();\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n\n this.engine?.destroy();\n this.engine = null;\n this.active = false;\n }\n\n purchase(data: PurchaseData): void {\n this.engine?.factory.purchase.track(data);\n }\n\n lead(data: LeadData): void {\n this.engine?.factory.lead.track(data);\n }\n\n addToCart(data: AddToCartData): void {\n this.engine?.factory.addToCart.track(data);\n }\n\n removeFromCart(data: RemoveFromCartData): void {\n this.engine?.factory.removeFromCart.track(data);\n }\n\n initiateCheckout(data: InitiateCheckoutData): void {\n this.engine?.factory.initiateCheckout.track(data);\n }\n\n addPaymentInfo(data: AddPaymentInfoData): void {\n this.engine?.factory.addPaymentInfo.track(data);\n }\n\n viewContent(data: ViewContentData): void {\n this.engine?.factory.viewContent.track(data);\n }\n\n search(data: SearchData): void {\n this.engine?.factory.search.track(data);\n }\n\n /** @internal For playground and development only. */\n getDebugDedupeKeys(): readonly string[] {\n return this.engine?.getDedupeKeys() ?? [];\n }\n\n /** @internal For playground and development only. */\n getDebugActiveDetectors(): readonly string[] {\n return this.engine?.getActiveDetectors() ?? [];\n }\n\n /** @internal For playground and development only. */\n isEngineActive(): boolean {\n return this.engine?.isActive() ?? false;\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nexport class FingerprintEngine {\n private readonly context: PixelRuntimeContext;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n init(): void {\n if (!this.context.config.modules.core.fingerprint.enabled) return;\n\n this.context.logger.debug('[FingerprintEngine] Ensuring fingerprint');\n this.context.services.fingerprint.ensureFingerprint();\n }\n\n destroy(): void {}\n}\n","export type NavigationReason =\n | 'pushState'\n | 'replaceState'\n | 'back'\n | 'forward'\n | 'hash';\n\ntype NavigationCallback = (reason: NavigationReason) => void;\n\nexport class NavigationObserver {\n private readonly onNavigate: NavigationCallback;\n\n private started = false;\n\n private originalPushState: History['pushState'] | null = null;\n\n private originalReplaceState: History['replaceState'] | null = null;\n\n private readonly handlePopState = (): void => {\n this.onNavigate('back');\n };\n\n private readonly handleHashChange = (): void => {\n this.onNavigate('hash');\n };\n\n constructor(onNavigate: NavigationCallback) {\n this.onNavigate = onNavigate;\n }\n\n start(): void {\n if (this.started || typeof window === 'undefined') return;\n\n this.started = true;\n this.originalPushState = history.pushState.bind(history);\n this.originalReplaceState = history.replaceState.bind(history);\n\n history.pushState = (...args: Parameters<History['pushState']>) => {\n this.originalPushState?.(...args);\n this.onNavigate('pushState');\n };\n\n history.replaceState = (...args: Parameters<History['replaceState']>) => {\n this.originalReplaceState?.(...args);\n this.onNavigate('replaceState');\n };\n\n window.addEventListener('popstate', this.handlePopState);\n window.addEventListener('hashchange', this.handleHashChange);\n }\n\n destroy(): void {\n if (!this.started || typeof window === 'undefined') return;\n\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n }\n\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n }\n\n window.removeEventListener('popstate', this.handlePopState);\n window.removeEventListener('hashchange', this.handleHashChange);\n\n this.originalPushState = null;\n this.originalReplaceState = null;\n this.started = false;\n }\n}\n","export class PageViewDeduper {\n private lastPath: string | null = null;\n\n private lastTimestamp = 0;\n\n private readonly dedupeMs: number;\n\n constructor(dedupeMs: number) {\n this.dedupeMs = dedupeMs;\n }\n\n shouldDispatch(path: string, timestamp = Date.now()): boolean {\n if (\n this.lastPath === path &&\n timestamp - this.lastTimestamp < this.dedupeMs\n ) {\n return false;\n }\n\n this.lastPath = path;\n this.lastTimestamp = timestamp;\n return true;\n }\n\n reset(): void {\n this.lastPath = null;\n this.lastTimestamp = 0;\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { NavigationObserver } from './NavigationObserver';\nimport { PageViewDeduper } from './PageViewDeduper';\n\nexport class PageViewEngine {\n private readonly context: PixelRuntimeContext;\n\n private readonly deduper: PageViewDeduper;\n\n private navigationObserver: NavigationObserver | null = null;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n this.deduper = new PageViewDeduper(\n context.config.modules.core.pageView.dedupeMs\n );\n }\n\n init(): void {\n const { pageView } = this.context.config.modules.core;\n\n if (!pageView.enabled) return;\n\n if (pageView.trackInitialPageView) {\n this.trackPageView();\n }\n\n if (pageView.spa) {\n this.navigationObserver = new NavigationObserver(() => {\n this.trackPageView();\n });\n this.navigationObserver.start();\n }\n }\n\n trackPageView(): void {\n const metadata = this.context.services.browserMetadata.getMetadata();\n const path = metadata.path ?? '';\n const timestamp = Date.now();\n\n if (!this.deduper.shouldDispatch(path, timestamp)) {\n this.context.logger.debug('[PageViewEngine] Page view deduplicated');\n return;\n }\n\n const event = this.context.services.eventBuilder.build({\n type: 'PAGE_VIEW' as const,\n });\n\n this.context.logger.debug('[PageViewEngine] Dispatching PAGE_VIEW');\n this.context.services.dispatcher.dispatch(event);\n }\n\n destroy(): void {\n this.navigationObserver?.destroy();\n this.navigationObserver = null;\n this.deduper.reset();\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nexport class SessionEngine {\n private readonly context: PixelRuntimeContext;\n\n private unsubscribe: (() => void) | null = null;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n init(): void {\n if (!this.context.config.modules.core.session.enabled) return;\n\n this.context.logger.debug('[SessionEngine] Ensuring session');\n\n const { ttlMs } = this.context.config.modules.core.session;\n this.applySessionLifecycle(ttlMs);\n\n this.unsubscribe = this.context.services.dispatcher.subscribe(event => {\n if (event.type === 'PAGE_VIEW') {\n this.handlePageViewActivity();\n }\n });\n }\n\n destroy(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n\n private handlePageViewActivity(): void {\n const { ttlMs, renewOnActivity } = this.context.config.modules.core.session;\n const { session } = this.context.services;\n\n if (session.isExpired(ttlMs)) {\n this.applySessionLifecycle(ttlMs);\n return;\n }\n\n if (renewOnActivity) {\n session.touchActivity();\n this.context.logger.debug('[SessionEngine] Session activity renewed');\n }\n }\n\n private applySessionLifecycle(ttlMs: number): void {\n const result = this.context.services.session.ensureSession(ttlMs);\n\n if (result.expired && result.previousSessionId) {\n const expiredEvent = this.context.services.eventBuilder.build({\n type: 'SESSION_EXPIRED' as const,\n sessionId: result.previousSessionId,\n });\n\n this.context.logger.debug('[SessionEngine] Dispatching SESSION_EXPIRED');\n this.context.services.dispatcher.dispatch(expiredEvent);\n\n const renewedEvent = this.context.services.eventBuilder.build({\n type: 'SESSION_RENEWED' as const,\n sessionId: result.sessionId,\n previousSessionId: result.previousSessionId,\n });\n\n this.context.logger.debug('[SessionEngine] Dispatching SESSION_RENEWED');\n this.context.services.dispatcher.dispatch(renewedEvent);\n }\n }\n}\n","import type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nexport class VisitorEngine {\n private readonly context: PixelRuntimeContext;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n init(): void {\n if (!this.context.config.modules.core.visitor.enabled) return;\n\n this.context.logger.debug('[VisitorEngine] Ensuring visitor');\n this.context.services.visitor.ensureVisitorId();\n }\n\n destroy(): void {}\n}\n","import type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport {\n FingerprintEngine,\n PageViewEngine,\n SessionEngine,\n VisitorEngine,\n} from './engines';\n\nexport class CoreModule implements PixelModule {\n readonly name = 'core' as const;\n\n private visitorEngine: VisitorEngine | null = null;\n\n private sessionEngine: SessionEngine | null = null;\n\n private fingerprintEngine: FingerprintEngine | null = null;\n\n private pageViewEngine: PageViewEngine | null = null;\n\n init(context: PixelRuntimeContext): void {\n context.logger.debug('[Pixel] Core module initialized');\n\n this.visitorEngine = new VisitorEngine(context);\n this.sessionEngine = new SessionEngine(context);\n this.fingerprintEngine = new FingerprintEngine(context);\n this.pageViewEngine = new PageViewEngine(context);\n\n this.visitorEngine.init();\n this.sessionEngine.init();\n this.fingerprintEngine.init();\n this.pageViewEngine.init();\n }\n\n destroy(): void {\n this.pageViewEngine?.destroy();\n this.fingerprintEngine?.destroy();\n this.sessionEngine?.destroy();\n this.visitorEngine?.destroy();\n\n this.pageViewEngine = null;\n this.fingerprintEngine = null;\n this.sessionEngine = null;\n this.visitorEngine = null;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { DestinationAdapter } from './types';\n\n/**\n * Registry of destination adapters — mirror of ModuleRegistry pattern.\n * No switch/if cascades; support decisions live inside each adapter.\n */\nexport class DestinationRegistry {\n private readonly adapters = new Map<string, DestinationAdapter>();\n\n register(destination: DestinationAdapter): void {\n if (this.adapters.has(destination.name)) {\n throw new Error(\n `[Integration] Destination \"${destination.name}\" is already registered`\n );\n }\n this.adapters.set(destination.name, destination);\n }\n\n remove(name: string): boolean {\n const existing = this.adapters.get(name);\n if (!existing) return false;\n existing.destroy?.();\n return this.adapters.delete(name);\n }\n\n get(name: string): DestinationAdapter | undefined {\n return this.adapters.get(name);\n }\n\n getAll(): readonly DestinationAdapter[] {\n return [...this.adapters.values()];\n }\n\n supports(event: PixelEvent): readonly DestinationAdapter[] {\n return this.getAll().filter(adapter => {\n try {\n return adapter.supports(event);\n } catch {\n return false;\n }\n });\n }\n\n has(name: string): boolean {\n return this.adapters.has(name);\n }\n\n size(): number {\n return this.adapters.size;\n }\n\n clear(): void {\n for (const adapter of this.adapters.values()) {\n adapter.destroy?.();\n }\n this.adapters.clear();\n }\n}\n","import type { DestinationMetricsSnapshot, DestinationResult } from './types';\n\ntype DestinationCounters = {\n sent: number;\n failed: number;\n ignored: number;\n skipped: number;\n totalDuration: number;\n pageViewSent: number;\n pageViewDeduped: number;\n pageViewFailed: number;\n scriptLoadAttempts: number;\n scriptLoadSuccess: number;\n scriptLoadFailure: number;\n initAttempts: number;\n initSuccess: number;\n initFailure: number;\n lastError: string | null;\n};\n\nfunction emptyCounters(): DestinationCounters {\n return {\n sent: 0,\n failed: 0,\n ignored: 0,\n skipped: 0,\n totalDuration: 0,\n pageViewSent: 0,\n pageViewDeduped: 0,\n pageViewFailed: 0,\n scriptLoadAttempts: 0,\n scriptLoadSuccess: 0,\n scriptLoadFailure: 0,\n initAttempts: 0,\n initSuccess: 0,\n initFailure: 0,\n lastError: null,\n };\n}\n\nexport class DestinationMetrics {\n private registeredDestinations = 0;\n\n private eventsSent = 0;\n\n private eventsFailed = 0;\n\n private eventsIgnored = 0;\n\n private eventsSkipped = 0;\n\n private pageViewReceived = 0;\n\n private pageViewSent = 0;\n\n private pageViewSkipped = 0;\n\n private pageViewDeduped = 0;\n\n private pageViewFailed = 0;\n\n private scriptLoadAttempts = 0;\n\n private scriptLoadSuccess = 0;\n\n private scriptLoadFailure = 0;\n\n private initAttempts = 0;\n\n private initSuccess = 0;\n\n private initFailure = 0;\n\n private totalDuration = 0;\n\n private lastExecutionAt: number | null = null;\n\n private lastErrorAt: number | null = null;\n\n private lastErrorMessage: string | null = null;\n\n private readonly perDestination = new Map<string, DestinationCounters>();\n\n private readonly perDestinationId = new Map<\n string,\n {\n sent: number;\n failed: number;\n pageViewSent: number;\n pageViewDeduped: number;\n pageViewFailed: number;\n }\n >();\n\n private getDestinationCounters(name: string): DestinationCounters {\n let counters = this.perDestination.get(name);\n if (!counters) {\n counters = emptyCounters();\n this.perDestination.set(name, counters);\n }\n return counters;\n }\n\n setRegisteredCount(count: number): void {\n this.registeredDestinations = count;\n }\n\n recordPageViewReceived(): void {\n this.pageViewReceived += 1;\n }\n\n recordScriptLoadAttempt(adapter: string): void {\n this.scriptLoadAttempts += 1;\n this.getDestinationCounters(adapter).scriptLoadAttempts += 1;\n }\n\n recordScriptLoadSuccess(adapter: string): void {\n this.scriptLoadSuccess += 1;\n this.getDestinationCounters(adapter).scriptLoadSuccess += 1;\n }\n\n recordScriptLoadFailure(adapter: string): void {\n this.scriptLoadFailure += 1;\n this.getDestinationCounters(adapter).scriptLoadFailure += 1;\n }\n\n recordInitAttempt(adapter: string): void {\n this.initAttempts += 1;\n this.getDestinationCounters(adapter).initAttempts += 1;\n }\n\n recordInitSuccess(adapter: string): void {\n this.initSuccess += 1;\n this.getDestinationCounters(adapter).initSuccess += 1;\n }\n\n recordInitFailure(adapter: string): void {\n this.initFailure += 1;\n this.getDestinationCounters(adapter).initFailure += 1;\n }\n\n record(result: DestinationResult): void {\n const adapter = result.adapter;\n const counters = this.getDestinationCounters(adapter);\n\n this.lastExecutionAt = result.timestamp;\n this.totalDuration += result.duration;\n\n if (result.status === 'success') {\n this.eventsSent += 1;\n counters.sent += 1;\n } else if (result.status === 'failed') {\n this.eventsFailed += 1;\n counters.failed += 1;\n this.lastErrorAt = result.timestamp;\n this.lastErrorMessage = result.error ?? 'Unknown error';\n counters.lastError = this.lastErrorMessage;\n } else if (result.status === 'ignored') {\n this.eventsIgnored += 1;\n counters.ignored += 1;\n } else if (result.status === 'skipped') {\n this.eventsSkipped += 1;\n counters.skipped += 1;\n }\n\n counters.totalDuration += result.duration;\n\n if (result.metadata) {\n const sent = Number(result.metadata.sent ?? 0);\n const deduped = Number(result.metadata.deduped ?? 0);\n const failed = Number(result.metadata.failed ?? 0);\n\n if (sent > 0) {\n this.pageViewSent += sent;\n counters.pageViewSent += sent;\n }\n if (deduped > 0) {\n this.pageViewDeduped += deduped;\n counters.pageViewDeduped += deduped;\n }\n if (failed > 0) {\n this.pageViewFailed += failed;\n counters.pageViewFailed += failed;\n }\n\n const pixelIds = result.metadata.pixelIds as string[] | undefined;\n const tagIds = result.metadata.tagIds as string[] | undefined;\n const ids = pixelIds ?? tagIds;\n if (ids && sent > 0) {\n for (const id of ids.slice(0, sent)) {\n this.recordDestinationId(adapter, id, 'sent', sent / ids.length);\n }\n }\n }\n\n if (result.status === 'failed' && result.error) {\n this.pageViewFailed += 1;\n counters.pageViewFailed += 1;\n }\n }\n\n private recordDestinationId(\n adapter: string,\n id: string,\n kind: 'sent' | 'failed',\n count: number\n ): void {\n const key = `${adapter}:${id}`;\n let counters = this.perDestinationId.get(key);\n if (!counters) {\n counters = {\n sent: 0,\n failed: 0,\n pageViewSent: 0,\n pageViewDeduped: 0,\n pageViewFailed: 0,\n };\n this.perDestinationId.set(key, counters);\n }\n if (kind === 'sent') {\n counters.sent += count;\n counters.pageViewSent += count;\n } else {\n counters.failed += count;\n counters.pageViewFailed += count;\n }\n }\n\n getSnapshot(): DestinationMetricsSnapshot {\n const total = this.eventsSent + this.eventsFailed;\n const perDestination: Record<\n string,\n DestinationMetricsSnapshot['perDestination'][string]\n > = {};\n\n for (const [name, counters] of this.perDestination) {\n const destTotal = counters.sent + counters.failed;\n perDestination[name] = {\n sent: counters.sent,\n failed: counters.failed,\n ignored: counters.ignored,\n skipped: counters.skipped,\n averageDuration:\n destTotal > 0 ? counters.totalDuration / destTotal : 0,\n successRate: destTotal > 0 ? counters.sent / destTotal : 0,\n pageViewSent: counters.pageViewSent,\n pageViewDeduped: counters.pageViewDeduped,\n pageViewFailed: counters.pageViewFailed,\n scriptLoadAttempts: counters.scriptLoadAttempts,\n scriptLoadSuccess: counters.scriptLoadSuccess,\n scriptLoadFailure: counters.scriptLoadFailure,\n initAttempts: counters.initAttempts,\n initSuccess: counters.initSuccess,\n initFailure: counters.initFailure,\n lastError: counters.lastError,\n };\n }\n\n return {\n registeredDestinations: this.registeredDestinations,\n activeDestinations: this.registeredDestinations,\n eventsSent: this.eventsSent,\n eventsFailed: this.eventsFailed,\n eventsIgnored: this.eventsIgnored,\n eventsSkipped: this.eventsSkipped,\n pageViewReceived: this.pageViewReceived,\n pageViewSent: this.pageViewSent,\n pageViewSkipped: this.pageViewSkipped,\n pageViewDeduped: this.pageViewDeduped,\n pageViewFailed: this.pageViewFailed,\n scriptLoadAttempts: this.scriptLoadAttempts,\n scriptLoadSuccess: this.scriptLoadSuccess,\n scriptLoadFailure: this.scriptLoadFailure,\n initAttempts: this.initAttempts,\n initSuccess: this.initSuccess,\n initFailure: this.initFailure,\n averageDuration: total > 0 ? this.totalDuration / total : 0,\n successRate: total > 0 ? this.eventsSent / total : 0,\n lastExecutionAt: this.lastExecutionAt,\n lastErrorAt: this.lastErrorAt,\n lastErrorMessage: this.lastErrorMessage,\n perDestination,\n perDestinationId: Object.fromEntries(this.perDestinationId),\n };\n }\n\n reset(): void {\n this.registeredDestinations = 0;\n this.eventsSent = 0;\n this.eventsFailed = 0;\n this.eventsIgnored = 0;\n this.eventsSkipped = 0;\n this.pageViewReceived = 0;\n this.pageViewSent = 0;\n this.pageViewSkipped = 0;\n this.pageViewDeduped = 0;\n this.pageViewFailed = 0;\n this.scriptLoadAttempts = 0;\n this.scriptLoadSuccess = 0;\n this.scriptLoadFailure = 0;\n this.initAttempts = 0;\n this.initSuccess = 0;\n this.initFailure = 0;\n this.totalDuration = 0;\n this.lastExecutionAt = null;\n this.lastErrorAt = null;\n this.lastErrorMessage = null;\n this.perDestination.clear();\n this.perDestinationId.clear();\n }\n}\n","import type { PixelLogger } from '@/logger';\n\n/**\n * Prefixed logger scoped to Integration Engine — never mixes with Transport logs.\n */\nexport class DestinationLogger {\n private readonly logger: PixelLogger;\n\n private readonly scope: string;\n\n constructor(logger: PixelLogger, scope = 'Integration') {\n this.logger = logger;\n this.scope = scope;\n }\n\n forAdapter(name: string): DestinationLogger {\n return new DestinationLogger(this.logger, name);\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.logger.debug(`[${this.scope}] ${message}`, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.logger.info(`[${this.scope}] ${message}`, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.logger.warn(`[${this.scope}] ${message}`, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.logger.error(`[${this.scope}] ${message}`, ...args);\n }\n}\n","import type { DestinationAdapter, DestinationResult } from './types';\nimport type { DestinationLogger } from './DestinationLogger';\n\n/**\n * Isolates destination failures so one adapter never brings down others.\n */\nexport class DestinationErrorHandler {\n private readonly logger: DestinationLogger;\n\n private readonly continueOnError: boolean;\n\n constructor(logger: DestinationLogger, continueOnError: boolean) {\n this.logger = logger;\n this.continueOnError = continueOnError;\n }\n\n toFailedResult(\n adapter: DestinationAdapter,\n error: unknown,\n duration: number\n ): DestinationResult {\n const message = error instanceof Error ? error.message : String(error);\n this.logger.forAdapter(adapter.name).error(`Execution failed: ${message}`);\n\n return {\n status: 'failed',\n adapter: adapter.name,\n duration,\n timestamp: Date.now(),\n error: message,\n };\n }\n\n shouldContinue(): boolean {\n return this.continueOnError;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type {\n DestinationAdapter,\n DestinationContext,\n DestinationHooks,\n DestinationResult,\n} from './types';\nimport type { DestinationErrorHandler } from './DestinationErrorHandler';\nimport type { DestinationLogger } from './DestinationLogger';\n\n/**\n * Executes a single destination with timeout (AbortSignal), hooks and error isolation.\n */\nexport class DestinationExecutor {\n private readonly logger: DestinationLogger;\n\n private readonly errorHandler: DestinationErrorHandler;\n\n private readonly hooks: DestinationHooks;\n\n private readonly timeoutMs: number;\n\n private readonly debug: boolean;\n\n constructor(options: {\n logger: DestinationLogger;\n errorHandler: DestinationErrorHandler;\n hooks?: DestinationHooks;\n timeoutMs: number;\n debug?: boolean;\n }) {\n this.logger = options.logger;\n this.errorHandler = options.errorHandler;\n this.hooks = options.hooks ?? {};\n this.timeoutMs = options.timeoutMs;\n this.debug = options.debug ?? false;\n }\n\n async execute(\n adapter: DestinationAdapter,\n event: PixelEvent\n ): Promise<DestinationResult> {\n const startedAt = Date.now();\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n const context: DestinationContext = {\n event,\n signal: controller.signal,\n timeoutMs: this.timeoutMs,\n debug: this.debug,\n };\n\n try {\n await this.hooks.beforeExecute?.(adapter, event);\n\n const result = await adapter.execute(context);\n const enriched: DestinationResult = {\n ...result,\n adapter: result.adapter || adapter.name,\n duration: result.duration || Date.now() - startedAt,\n timestamp: result.timestamp || Date.now(),\n };\n\n await this.hooks.afterExecute?.(adapter, event, enriched);\n\n if (enriched.status === 'success') {\n await this.hooks.onSuccess?.(adapter, event, enriched);\n } else if (enriched.status === 'failed' || enriched.status === 'retry') {\n await this.hooks.onFailure?.(adapter, event, enriched);\n } else if (enriched.status === 'ignored' || enriched.status === 'skipped') {\n await this.hooks.onIgnored?.(adapter, event, enriched);\n }\n\n if (this.debug) {\n this.logger\n .forAdapter(adapter.name)\n .debug(`Result ${enriched.status} in ${enriched.duration}ms`);\n }\n\n return enriched;\n } catch (error) {\n const failed = this.errorHandler.toFailedResult(\n adapter,\n error,\n Date.now() - startedAt\n );\n await this.hooks.onFailure?.(adapter, event, failed);\n await this.hooks.afterExecute?.(adapter, event, failed);\n return failed;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { DestinationRegistry } from './DestinationRegistry';\nimport type { DestinationExecutor } from './DestinationExecutor';\nimport type { DestinationMetrics } from './DestinationMetrics';\nimport type { DestinationLogger } from './DestinationLogger';\nimport type { DestinationResult } from './types';\n\nexport type DestinationDispatcherConfig = {\n readonly registry: DestinationRegistry;\n readonly executor: DestinationExecutor;\n readonly metrics: DestinationMetrics;\n readonly logger: DestinationLogger;\n readonly concurrency?: number;\n};\n\nexport class DestinationDispatcher {\n private readonly registry: DestinationRegistry;\n\n private readonly executor: DestinationExecutor;\n\n private readonly metrics: DestinationMetrics;\n\n private readonly logger: DestinationLogger;\n\n private readonly concurrency: number;\n\n private lastResults: DestinationResult[] = [];\n\n constructor(config: DestinationDispatcherConfig) {\n this.registry = config.registry;\n this.executor = config.executor;\n this.metrics = config.metrics;\n this.logger = config.logger;\n const raw = config.concurrency ?? 3;\n this.concurrency = raw <= 0 ? 1 : raw;\n }\n\n async dispatch(event: PixelEvent): Promise<readonly DestinationResult[]> {\n const destinations = this.registry.supports(event);\n if (destinations.length === 0) {\n this.lastResults = [];\n return [];\n }\n\n const results: DestinationResult[] = [];\n\n for (let i = 0; i < destinations.length; i += this.concurrency) {\n const batch = destinations.slice(i, i + this.concurrency);\n const settled = await Promise.allSettled(\n batch.map(adapter => this.executor.execute(adapter, event))\n );\n\n for (let j = 0; j < settled.length; j += 1) {\n const outcome = settled[j]!;\n const adapter = batch[j]!;\n\n if (outcome.status === 'fulfilled') {\n results.push(outcome.value);\n this.metrics.record(outcome.value);\n } else {\n const failed: DestinationResult = {\n status: 'failed',\n adapter: adapter.name,\n duration: 0,\n timestamp: Date.now(),\n error:\n outcome.reason instanceof Error\n ? outcome.reason.message\n : String(outcome.reason),\n };\n results.push(failed);\n this.metrics.record(failed);\n this.logger.error(\n `Unhandled destination error: ${adapter.name}`,\n outcome.reason\n );\n }\n }\n }\n\n this.lastResults = results;\n return results;\n }\n\n getLastResults(): readonly DestinationResult[] {\n return this.lastResults;\n }\n\n clearLastResults(): void {\n this.lastResults = [];\n }\n}\n","import type { PixelEvent } from '@/events';\n\nexport type DestinationPipelineStage = {\n readonly name: string;\n process(event: PixelEvent): PixelEvent | null;\n};\n\n/**\n * Optional internal pipeline for destinations / engine ingress.\n * Stages compose; PixelEvent is never mutated in place — stages return new or same reference.\n */\nexport class DestinationPipeline {\n private readonly stages: readonly DestinationPipelineStage[];\n\n private lastSteps: string[] = [];\n\n constructor(stages: readonly DestinationPipelineStage[] = []) {\n this.stages = stages;\n }\n\n static identity(): DestinationPipeline {\n return new DestinationPipeline([\n {\n name: 'identity',\n process(event) {\n return event;\n },\n },\n ]);\n }\n\n process(event: PixelEvent): PixelEvent | null {\n const steps: string[] = [];\n let current: PixelEvent | null = event;\n\n for (const stage of this.stages) {\n steps.push(stage.name);\n if (!current) break;\n current = stage.process(current);\n }\n\n this.lastSteps = steps;\n return current;\n }\n\n getLastSteps(): readonly string[] {\n return this.lastSteps;\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { DispatcherService } from '@/services/dispatcher/types';\n\n/**\n * Subscribes Integration Engine to Dispatcher — owns no Transport knowledge.\n */\nexport class DestinationSubscriber {\n private readonly dispatcher: DispatcherService;\n\n private readonly onEvent: (event: PixelEvent) => void;\n\n private unsubscribe: (() => void) | null = null;\n\n constructor(\n dispatcher: DispatcherService,\n onEvent: (event: PixelEvent) => void\n ) {\n this.dispatcher = dispatcher;\n this.onEvent = onEvent;\n }\n\n subscribe(): void {\n if (this.unsubscribe) return;\n this.unsubscribe = this.dispatcher.subscribe(event => this.onEvent(event));\n }\n\n unsubscribeAll(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n\n isSubscribed(): boolean {\n return this.unsubscribe !== null;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { DestinationAdapter, DestinationResult } from '../types';\n\n/** Events typically relevant for conversion / commerce destinations. */\nexport const DEFAULT_COMMERCE_EVENT_TYPES = new Set([\n 'PAGE_VIEW',\n 'PAGE_CLICK',\n 'SEARCH',\n 'LEAD',\n 'INITIATE_CHECKOUT',\n 'PURCHASE',\n 'ADD_PAYMENT_INFO',\n 'ADD_TO_CART',\n 'REMOVE_FROM_CART',\n 'VIEW_CONTENT',\n]);\n\nexport type BaseDestinationOptions = {\n readonly name: string;\n readonly version?: string;\n readonly supportedTypes?: ReadonlySet<string>;\n};\n\n/**\n * Shared helpers for destination adapters — each subclass owns supports() subset\n * and builds its own external payload without mutating PixelEvent.\n */\nexport abstract class BaseDestinationAdapter implements DestinationAdapter {\n readonly name: string;\n\n readonly version: string;\n\n protected readonly supportedTypes: ReadonlySet<string>;\n\n constructor(options: BaseDestinationOptions) {\n this.name = options.name;\n this.version = options.version ?? '1.0.0';\n this.supportedTypes = options.supportedTypes ?? DEFAULT_COMMERCE_EVENT_TYPES;\n }\n\n supports(event: PixelEvent): boolean {\n return this.supportedTypes.has(event.type);\n }\n\n abstract execute(context: {\n readonly event: PixelEvent;\n readonly signal: AbortSignal;\n readonly timeoutMs: number;\n readonly debug: boolean;\n }): Promise<DestinationResult>;\n\n protected createResult(\n status: DestinationResult['status'],\n duration: number,\n extras?: Partial<DestinationResult>\n ): DestinationResult {\n return {\n status,\n adapter: this.name,\n duration,\n timestamp: Date.now(),\n ...extras,\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport {\n BaseDestinationAdapter,\n DEFAULT_COMMERCE_EVENT_TYPES,\n} from './BaseDestinationAdapter';\nimport type { DestinationResult } from '../types';\n\nexport type ConsoleDestinationOptions = {\n readonly log?: (message: string, payload?: unknown) => void;\n};\n\n/**\n * Test / debug destination — logs events to console without side effects.\n */\nexport class ConsoleDestination extends BaseDestinationAdapter {\n private readonly log: (message: string, payload?: unknown) => void;\n\n private sent = 0;\n\n constructor(options: ConsoleDestinationOptions = {}) {\n super({\n name: 'console',\n version: '1.0.0',\n supportedTypes: DEFAULT_COMMERCE_EVENT_TYPES,\n });\n this.log =\n options.log ??\n ((message, payload) => {\n // eslint-disable-next-line no-console\n console.log(message, payload);\n });\n }\n\n async execute(context: {\n readonly event: PixelEvent;\n readonly signal: AbortSignal;\n }): Promise<DestinationResult> {\n const startedAt = Date.now();\n\n if (context.signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n const payload = {\n type: context.event.type,\n timestamp: context.event.timestamp,\n category: 'category' in context.event ? context.event.category : undefined,\n };\n\n this.log(`[Console] ${context.event.type}`, payload);\n this.sent += 1;\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { sent: this.sent },\n });\n }\n\n getSentCount(): number {\n return this.sent;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport {\n BaseDestinationAdapter,\n DEFAULT_COMMERCE_EVENT_TYPES,\n} from './BaseDestinationAdapter';\nimport type { DestinationResult } from '../types';\n\n/**\n * In-memory destination for tests and playground inspection.\n * Stores transformed payloads — never mutates PixelEvent.\n */\nexport class MemoryDestination extends BaseDestinationAdapter {\n private readonly records: Array<{\n readonly at: number;\n readonly type: string;\n readonly payload: Readonly<Record<string, unknown>>;\n }> = [];\n\n constructor() {\n super({\n name: 'memory',\n version: '1.0.0',\n supportedTypes: DEFAULT_COMMERCE_EVENT_TYPES,\n });\n }\n\n async execute(context: {\n readonly event: PixelEvent;\n readonly signal: AbortSignal;\n }): Promise<DestinationResult> {\n const startedAt = Date.now();\n\n if (context.signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n const payload = this.transform(context.event);\n this.records.push({\n at: Date.now(),\n type: context.event.type,\n payload,\n });\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { recordCount: this.records.length },\n });\n }\n\n getRecords(): readonly {\n readonly at: number;\n readonly type: string;\n readonly payload: Readonly<Record<string, unknown>>;\n }[] {\n return [...this.records];\n }\n\n clear(): void {\n this.records.length = 0;\n }\n\n destroy(): void {\n this.clear();\n }\n\n private transform(event: PixelEvent): Record<string, unknown> {\n return {\n destination: 'memory',\n eventType: event.type,\n timestamp: event.timestamp,\n path: 'path' in event ? event.path : undefined,\n data: 'data' in event ? event.data : undefined,\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport {\n BaseDestinationAdapter,\n DEFAULT_COMMERCE_EVENT_TYPES,\n} from './BaseDestinationAdapter';\nimport type { DestinationResult } from '../types';\n\nexport type MockDestinationOptions = {\n readonly failOnTypes?: ReadonlySet<string>;\n readonly ignoreTypes?: ReadonlySet<string>;\n readonly delayMs?: number;\n readonly supportedTypes?: ReadonlySet<string>;\n};\n\n/**\n * Controllable mock destination for unit tests (fail / ignore / delay).\n */\nexport class MockDestination extends BaseDestinationAdapter {\n private readonly failOnTypes: ReadonlySet<string>;\n\n private readonly ignoreTypes: ReadonlySet<string>;\n\n private readonly delayMs: number;\n\n private executions = 0;\n\n constructor(options: MockDestinationOptions = {}) {\n super({\n name: 'mock',\n version: '1.0.0',\n supportedTypes: options.supportedTypes ?? DEFAULT_COMMERCE_EVENT_TYPES,\n });\n this.failOnTypes = options.failOnTypes ?? new Set();\n this.ignoreTypes = options.ignoreTypes ?? new Set();\n this.delayMs = options.delayMs ?? 0;\n }\n\n async execute(context: {\n readonly event: PixelEvent;\n readonly signal: AbortSignal;\n }): Promise<DestinationResult> {\n const startedAt = Date.now();\n this.executions += 1;\n\n if (this.delayMs > 0) {\n await this.wait(this.delayMs, context.signal);\n }\n\n if (context.signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n if (this.ignoreTypes.has(context.event.type)) {\n return this.createResult('ignored', Date.now() - startedAt, {\n ignored: true,\n });\n }\n\n if (this.failOnTypes.has(context.event.type)) {\n throw new Error(`[Mock] Simulated failure for ${context.event.type}`);\n }\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { executions: this.executions },\n });\n }\n\n getExecutionCount(): number {\n return this.executions;\n }\n\n private wait(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = (): void => {\n cleanup();\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n };\n\n const cleanup = (): void => {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n };\n\n if (signal.aborted) {\n cleanup();\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n return;\n }\n\n signal.addEventListener('abort', onAbort);\n });\n }\n}\n","/**\n * Shared PAGE_VIEW dedupe across Pixel instances (browser infra only).\n * Key: destinationName + destinationId + eventType + path/url + sessionId\n * Example: meta:877074838786597:PAGE_VIEW:/checkout:sess_abc\n */\nconst globalSeen = new Set<string>();\n\nexport function buildExternalPageViewKey(\n destinationName: string,\n destinationId: string,\n eventType: string,\n pathOrUrl: string,\n sessionId: string\n): string {\n return `${destinationName}:${destinationId}:${eventType}:${pathOrUrl}:${sessionId}`;\n}\n\nexport function shouldSkipExternalPageView(key: string): boolean {\n if (globalSeen.has(key)) return true;\n globalSeen.add(key);\n return false;\n}\n\n/** Test-only — clears shared dedupe state. */\nexport function clearExternalPageViewDeduper(): void {\n globalSeen.clear();\n}\n\nexport function getExternalPageViewDeduperSize(): number {\n return globalSeen.size;\n}\n\n/** @deprecated Use module functions — kept for backward compatibility in tests. */\nexport class ExternalPageViewDeduper {\n buildKey(\n destinationName: string,\n destinationId: string,\n eventType: string,\n path: string,\n sessionId: string\n ): string {\n return buildExternalPageViewKey(\n destinationName,\n destinationId,\n eventType,\n path,\n sessionId\n );\n }\n\n shouldSkip(key: string): boolean {\n return shouldSkipExternalPageView(key);\n }\n\n clear(): void {\n clearExternalPageViewDeduper();\n }\n\n size(): number {\n return getExternalPageViewDeduperSize();\n }\n}\n","type ScriptEntry = {\n promise: Promise<void>;\n refCount: number;\n loaded: boolean;\n};\n\n/**\n * SSR-safe script loader with URL-level cache + ref-count.\n * Infrastructure only — no business state.\n */\nconst scriptCache = new Map<string, ScriptEntry>();\n\nexport type ScriptLoaderOptions = {\n readonly src: string;\n readonly id?: string;\n readonly timeoutMs?: number;\n readonly attributes?: Readonly<Record<string, string>>;\n};\n\nexport function loadScript(options: ScriptLoaderOptions): Promise<void> {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return Promise.reject(new Error('[ScriptLoader] Browser APIs unavailable'));\n }\n\n const existing = scriptCache.get(options.src);\n if (existing) {\n existing.refCount += 1;\n return existing.promise;\n }\n\n const timeoutMs = options.timeoutMs ?? 10_000;\n\n const promise = new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.async = true;\n script.src = options.src;\n if (options.id) script.id = options.id;\n\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n script.setAttribute(key, value);\n }\n }\n\n const timer = setTimeout(() => {\n cleanup();\n reject(new Error(`[ScriptLoader] Timeout loading ${options.src}`));\n }, timeoutMs);\n\n const cleanup = (): void => {\n clearTimeout(timer);\n script.onload = null;\n script.onerror = null;\n };\n\n script.onload = () => {\n cleanup();\n const entry = scriptCache.get(options.src);\n if (entry) entry.loaded = true;\n resolve();\n };\n\n script.onerror = () => {\n cleanup();\n scriptCache.delete(options.src);\n reject(new Error(`[ScriptLoader] Failed to load ${options.src}`));\n };\n\n document.head.appendChild(script);\n });\n\n scriptCache.set(options.src, { promise, refCount: 1, loaded: false });\n return promise;\n}\n\nexport function releaseScript(src: string): void {\n const entry = scriptCache.get(src);\n if (!entry) return;\n entry.refCount = Math.max(0, entry.refCount - 1);\n // Keep script in DOM for other instances; only drop cache entry when unused.\n if (entry.refCount === 0 && !entry.loaded) {\n scriptCache.delete(src);\n }\n}\n\n/** @internal tests */\nexport function _testClearScriptCache(): void {\n scriptCache.clear();\n}\n","export type MetaFbq = {\n (...args: unknown[]): void;\n callMethod?: (...args: unknown[]) => void;\n queue?: unknown[];\n loaded?: boolean;\n version?: string;\n push?: (...args: unknown[]) => void;\n};\n\nexport const META_PIXEL_SCRIPT_SRC =\n 'https://connect.facebook.net/en_US/fbevents.js';\n","import { loadScript, releaseScript } from '../../../browser/ScriptLoader';\nimport { META_PIXEL_SCRIPT_SRC, type MetaFbq } from './types';\n\ntype WindowWithFbq = Window & { fbq?: MetaFbq; _fbq?: MetaFbq };\n\nfunction getWindow(): WindowWithFbq | null {\n return typeof window !== 'undefined' ? (window as WindowWithFbq) : null;\n}\n\nfunction ensureFbqStub(): MetaFbq {\n const win = getWindow();\n if (!win) throw new Error('[MetaScriptLoader] window unavailable');\n if (win.fbq) return win.fbq as MetaFbq;\n\n const fbq = function (...args: unknown[]) {\n const fn = fbq as MetaFbq;\n if (fn.callMethod) {\n fn.callMethod(...args);\n } else {\n (fn.queue = fn.queue || []).push(args);\n }\n } as MetaFbq;\n\n fbq.push = fbq;\n fbq.loaded = false;\n fbq.version = '2.0';\n fbq.queue = [];\n\n win.fbq = fbq;\n if (!win._fbq) win._fbq = fbq;\n\n return fbq;\n}\n\nexport class MetaScriptLoader {\n private loaded = false;\n\n async load(timeoutMs = 10_000): Promise<MetaFbq> {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error('[MetaScriptLoader] Browser APIs unavailable');\n }\n\n const fbq = ensureFbqStub();\n if (this.loaded && fbq.loaded) return fbq;\n\n await loadScript({\n src: META_PIXEL_SCRIPT_SRC,\n id: 'pixel-v2-meta-fbevents',\n timeoutMs,\n });\n\n fbq.loaded = true;\n this.loaded = true;\n return fbq;\n }\n\n release(): void {\n releaseScript(META_PIXEL_SCRIPT_SRC);\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { MetaBrowserDestinationConfig } from '@/config/types/modules/integrations';\n\nimport { BaseDestinationAdapter } from '../../BaseDestinationAdapter';\nimport type { DestinationContext, DestinationResult } from '../../../types';\nimport {\n buildExternalPageViewKey,\n shouldSkipExternalPageView,\n} from '../../../browser/ExternalPageViewDeduper';\nimport type { DestinationMetrics } from '../../../DestinationMetrics';\nimport { DestinationLogger } from '../../../DestinationLogger';\nimport { MetaScriptLoader } from './MetaScriptLoader';\nimport type { MetaFbq } from './types';\n\nexport type MetaBrowserDestinationDeps = {\n readonly config: MetaBrowserDestinationConfig;\n readonly getSessionId: () => string;\n readonly logger: DestinationLogger;\n readonly metrics?: DestinationMetrics;\n readonly debug: boolean;\n};\n\n/**\n * Meta Pixel browser destination — PAGE_VIEW only.\n * Conversões Meta CAPI pertencem ao backend.\n */\nexport class MetaBrowserDestination extends BaseDestinationAdapter {\n private readonly config: MetaBrowserDestinationConfig;\n\n private readonly getSessionId: () => string;\n\n private readonly logger: DestinationLogger;\n\n private readonly metrics?: DestinationMetrics;\n\n private readonly debug: boolean;\n\n private readonly scriptLoader = new MetaScriptLoader();\n\n private readonly pixelIds: string[];\n\n private initialized = false;\n\n private fbq: MetaFbq | null = null;\n\n constructor(deps: MetaBrowserDestinationDeps) {\n super({\n name: 'meta',\n version: '1.0.0',\n supportedTypes: new Set(['PAGE_VIEW']),\n });\n this.config = deps.config;\n this.getSessionId = deps.getSessionId;\n this.logger = deps.logger.forAdapter('MetaBrowser');\n this.metrics = deps.metrics;\n this.debug = deps.debug;\n this.pixelIds = [...new Set(deps.config.pixelIds.filter(Boolean))];\n }\n\n supports(event: PixelEvent): boolean {\n return (\n this.config.enabled &&\n this.config.autoPageView !== false &&\n this.pixelIds.length > 0 &&\n event.type === 'PAGE_VIEW'\n );\n }\n\n async ensureInit(timeoutMs: number): Promise<void> {\n if (this.initialized) return;\n if (!this.config.enabled || this.pixelIds.length === 0) return;\n\n this.metrics?.recordInitAttempt('meta');\n if (this.debug) this.logger.debug('destination_init_start');\n\n if (this.config.loadScript !== false) {\n this.metrics?.recordScriptLoadAttempt('meta');\n if (this.debug) this.logger.debug('script_load_start');\n try {\n this.fbq = await this.scriptLoader.load(timeoutMs);\n this.metrics?.recordScriptLoadSuccess('meta');\n if (this.debug) this.logger.debug('script_load_success');\n } catch (error) {\n this.metrics?.recordScriptLoadFailure('meta');\n this.logger.error('script_load_failure', error);\n throw error;\n }\n } else if (typeof window !== 'undefined' && (window as { fbq?: MetaFbq }).fbq) {\n this.fbq = (window as { fbq?: MetaFbq }).fbq ?? null;\n }\n\n const fbq = this.fbq;\n if (!fbq) {\n this.metrics?.recordInitFailure('meta');\n throw new Error('[MetaBrowser] fbq unavailable');\n }\n\n let initFailed = false;\n for (const pixelId of this.pixelIds) {\n try {\n fbq('init', pixelId);\n } catch (error) {\n initFailed = true;\n this.metrics?.recordInitFailure('meta');\n this.logger.error(`destination_init_failure id=${pixelId}`, error);\n }\n }\n\n this.initialized = true;\n if (!initFailed) this.metrics?.recordInitSuccess('meta');\n if (this.debug) this.logger.debug('destination_init_success');\n }\n\n async execute(context: DestinationContext): Promise<DestinationResult> {\n const startedAt = Date.now();\n const { event, signal, timeoutMs } = context;\n\n if (event.type !== 'PAGE_VIEW') {\n return this.createResult('ignored', Date.now() - startedAt, {\n ignored: true,\n });\n }\n\n if (signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n if (this.debug) this.logger.debug('pageview_received');\n\n try {\n await this.ensureInit(timeoutMs);\n } catch (error) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const fbq =\n this.fbq ??\n (typeof window !== 'undefined'\n ? (window as { fbq?: MetaFbq }).fbq ?? null\n : null);\n if (!fbq) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'fbq unavailable',\n });\n }\n\n const path = event.path ?? event.url ?? '/';\n const sessionId = this.getSessionId();\n let sent = 0;\n let deduped = 0;\n\n for (const pixelId of this.pixelIds) {\n const key = buildExternalPageViewKey(\n 'meta',\n pixelId,\n 'PAGE_VIEW',\n path,\n sessionId\n );\n\n if (shouldSkipExternalPageView(key)) {\n deduped += 1;\n if (this.debug) this.logger.debug(`pageview_skipped_dedupe id=${pixelId}`);\n continue;\n }\n\n try {\n if (typeof fbq === 'function') {\n try {\n fbq('trackSingle', pixelId, 'PageView');\n } catch {\n fbq('track', 'PageView');\n }\n }\n sent += 1;\n if (this.debug) this.logger.debug(`pageview_sent id=${pixelId}`);\n } catch (error) {\n this.logger.error(`destination_execute_failure id=${pixelId}`, error);\n }\n }\n\n if (sent === 0 && deduped > 0) {\n return this.createResult('skipped', Date.now() - startedAt, {\n skipped: true,\n metadata: { sent, deduped },\n });\n }\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { sent, deduped, pixelIds: this.pixelIds },\n });\n }\n\n destroy(): void {\n this.scriptLoader.release();\n this.initialized = false;\n this.fbq = null;\n }\n}\n","export type GoogleGtag = (...args: unknown[]) => void;\n\nexport const GOOGLE_GTAG_SCRIPT_BASE = 'https://www.googletagmanager.com/gtag/js';\n","import { loadScript, releaseScript } from '../../../browser/ScriptLoader';\nimport { GOOGLE_GTAG_SCRIPT_BASE, type GoogleGtag } from './types';\n\ntype WindowWithGtag = Window & {\n dataLayer?: unknown[];\n gtag?: GoogleGtag;\n};\n\nfunction getWindow(): WindowWithGtag | null {\n return typeof window !== 'undefined' ? (window as WindowWithGtag) : null;\n}\n\nfunction ensureGtagStub(): GoogleGtag {\n const win = getWindow();\n if (!win) throw new Error('[GoogleScriptLoader] window unavailable');\n\n win.dataLayer = win.dataLayer || [];\n if (!win.gtag) {\n win.gtag = function gtag(...args: unknown[]) {\n win.dataLayer?.push(args);\n };\n }\n return win.gtag;\n}\n\nexport class GoogleScriptLoader {\n private loadedSrc: string | null = null;\n\n async load(primaryTagId: string, timeoutMs = 10_000): Promise<GoogleGtag> {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error('[GoogleScriptLoader] Browser APIs unavailable');\n }\n\n const gtag = ensureGtagStub();\n const src = `${GOOGLE_GTAG_SCRIPT_BASE}?id=${encodeURIComponent(primaryTagId)}`;\n\n await loadScript({\n src,\n id: 'pixel-v2-google-gtag',\n timeoutMs,\n });\n\n this.loadedSrc = src;\n gtag('js', new Date());\n return gtag;\n }\n\n release(): void {\n if (this.loadedSrc) {\n releaseScript(this.loadedSrc);\n this.loadedSrc = null;\n }\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { GoogleBrowserDestinationConfig } from '@/config/types/modules/integrations';\n\nimport { BaseDestinationAdapter } from '../../BaseDestinationAdapter';\nimport type { DestinationContext, DestinationResult } from '../../../types';\nimport {\n buildExternalPageViewKey,\n shouldSkipExternalPageView,\n} from '../../../browser/ExternalPageViewDeduper';\nimport type { DestinationMetrics } from '../../../DestinationMetrics';\nimport { DestinationLogger } from '../../../DestinationLogger';\nimport { GoogleScriptLoader } from './GoogleScriptLoader';\nimport type { GoogleGtag } from './types';\n\nexport type GoogleBrowserDestinationDeps = {\n readonly config: GoogleBrowserDestinationConfig;\n readonly getSessionId: () => string;\n readonly logger: DestinationLogger;\n readonly metrics?: DestinationMetrics;\n readonly debug: boolean;\n};\n\n/**\n * Google gtag browser destination — PAGE_VIEW only.\n * Conversões server-side pertencem ao backend.\n */\nexport class GoogleBrowserDestination extends BaseDestinationAdapter {\n private readonly config: GoogleBrowserDestinationConfig;\n\n private readonly getSessionId: () => string;\n\n private readonly logger: DestinationLogger;\n\n private readonly metrics?: DestinationMetrics;\n\n private readonly debug: boolean;\n\n private readonly scriptLoader = new GoogleScriptLoader();\n\n private readonly tagIds: string[];\n\n private initialized = false;\n\n private gtag: GoogleGtag | null = null;\n\n constructor(deps: GoogleBrowserDestinationDeps) {\n super({\n name: 'google',\n version: '1.0.0',\n supportedTypes: new Set(['PAGE_VIEW']),\n });\n this.config = deps.config;\n this.getSessionId = deps.getSessionId;\n this.logger = deps.logger.forAdapter('GoogleBrowser');\n this.metrics = deps.metrics;\n this.debug = deps.debug;\n this.tagIds = [...new Set(deps.config.tagIds.filter(Boolean))];\n }\n\n supports(event: PixelEvent): boolean {\n return (\n this.config.enabled &&\n this.config.autoPageView !== false &&\n this.tagIds.length > 0 &&\n event.type === 'PAGE_VIEW'\n );\n }\n\n async ensureInit(timeoutMs: number): Promise<void> {\n if (this.initialized) return;\n if (!this.config.enabled || this.tagIds.length === 0) return;\n\n this.metrics?.recordInitAttempt('google');\n if (this.debug) this.logger.debug('destination_init_start');\n const primary = this.tagIds[0]!;\n\n if (this.config.loadScript !== false) {\n this.metrics?.recordScriptLoadAttempt('google');\n if (this.debug) this.logger.debug('script_load_start');\n try {\n this.gtag = await this.scriptLoader.load(primary, timeoutMs);\n this.metrics?.recordScriptLoadSuccess('google');\n if (this.debug) this.logger.debug('script_load_success');\n } catch (error) {\n this.metrics?.recordScriptLoadFailure('google');\n this.logger.error('script_load_failure', error);\n throw error;\n }\n } else if (typeof window !== 'undefined' && (window as { gtag?: GoogleGtag }).gtag) {\n this.gtag = (window as { gtag?: GoogleGtag }).gtag ?? null;\n }\n\n const gtag = this.gtag;\n if (!gtag) {\n this.metrics?.recordInitFailure('google');\n throw new Error('[GoogleBrowser] gtag unavailable');\n }\n\n let initFailed = false;\n for (const tagId of this.tagIds) {\n try {\n gtag('config', tagId, { send_page_view: false });\n } catch (error) {\n initFailed = true;\n this.metrics?.recordInitFailure('google');\n this.logger.error(`destination_init_failure id=${tagId}`, error);\n }\n }\n\n this.initialized = true;\n if (!initFailed) this.metrics?.recordInitSuccess('google');\n if (this.debug) this.logger.debug('destination_init_success');\n }\n\n async execute(context: DestinationContext): Promise<DestinationResult> {\n const startedAt = Date.now();\n const { event, signal, timeoutMs } = context;\n\n if (event.type !== 'PAGE_VIEW') {\n return this.createResult('ignored', Date.now() - startedAt, {\n ignored: true,\n });\n }\n\n if (signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n if (this.debug) this.logger.debug('pageview_received');\n\n try {\n await this.ensureInit(timeoutMs);\n } catch (error) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const gtag =\n this.gtag ??\n (typeof window !== 'undefined'\n ? (window as { gtag?: GoogleGtag }).gtag ?? null\n : null);\n if (!gtag) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'gtag unavailable',\n });\n }\n\n const path = event.path ?? '/';\n const url =\n event.url ??\n (typeof window !== 'undefined' ? window.location?.href : undefined) ??\n path;\n const title =\n typeof document !== 'undefined' ? document.title : undefined;\n const sessionId = this.getSessionId();\n let sent = 0;\n let deduped = 0;\n\n for (const tagId of this.tagIds) {\n const key = buildExternalPageViewKey(\n 'google',\n tagId,\n 'PAGE_VIEW',\n path,\n sessionId\n );\n\n if (shouldSkipExternalPageView(key)) {\n deduped += 1;\n if (this.debug) this.logger.debug(`pageview_skipped_dedupe id=${tagId}`);\n continue;\n }\n\n try {\n gtag('event', 'page_view', {\n send_to: tagId,\n page_location: url,\n page_path: path,\n page_title: title,\n });\n sent += 1;\n if (this.debug) this.logger.debug(`pageview_sent id=${tagId}`);\n } catch (error) {\n this.logger.error(`destination_execute_failure id=${tagId}`, error);\n }\n }\n\n if (sent === 0 && deduped > 0) {\n return this.createResult('skipped', Date.now() - startedAt, {\n skipped: true,\n metadata: { sent, deduped },\n });\n }\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { sent, deduped, tagIds: this.tagIds },\n });\n }\n\n destroy(): void {\n this.scriptLoader.release();\n this.initialized = false;\n this.gtag = null;\n }\n}\n","export type TikTokTtq = {\n load: (pixelId: string) => void;\n page: () => void;\n track?: (event: string, payload?: Record<string, unknown>) => void;\n instance?: (pixelId: string) => TikTokTtq;\n};\n\nexport const TIKTOK_PIXEL_SCRIPT_SRC =\n 'https://analytics.tiktok.com/i18n/pixel/events.js';\n","import { loadScript, releaseScript } from '../../../browser/ScriptLoader';\nimport { TIKTOK_PIXEL_SCRIPT_SRC, type TikTokTtq } from './types';\n\ntype WindowWithTtq = Window & {\n ttq?: TikTokTtq;\n TiktokAnalyticsObject?: string;\n};\n\nfunction getWindow(): WindowWithTtq | null {\n return typeof window !== 'undefined' ? (window as WindowWithTtq) : null;\n}\n\nfunction ensureTtqStub(): TikTokTtq {\n const win = getWindow();\n if (!win) throw new Error('[TikTokScriptLoader] window unavailable');\n if (win.ttq) return win.ttq;\n\n const ttq = {\n load() {},\n page() {},\n track() {},\n } as TikTokTtq;\n\n win.TiktokAnalyticsObject = 'ttq';\n win.ttq = ttq;\n return ttq;\n}\n\nexport class TikTokScriptLoader {\n private loaded = false;\n\n async load(timeoutMs = 10_000): Promise<TikTokTtq> {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error('[TikTokScriptLoader] Browser APIs unavailable');\n }\n\n const ttq = ensureTtqStub();\n if (this.loaded) return ttq;\n\n await loadScript({\n src: TIKTOK_PIXEL_SCRIPT_SRC,\n id: 'pixel-v2-tiktok-analytics',\n timeoutMs,\n });\n\n this.loaded = true;\n return getWindow()?.ttq ?? ttq;\n }\n\n release(): void {\n releaseScript(TIKTOK_PIXEL_SCRIPT_SRC);\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { TikTokBrowserDestinationConfig } from '@/config/types/modules/integrations';\n\nimport { BaseDestinationAdapter } from '../../BaseDestinationAdapter';\nimport type { DestinationContext, DestinationResult } from '../../../types';\nimport {\n buildExternalPageViewKey,\n shouldSkipExternalPageView,\n} from '../../../browser/ExternalPageViewDeduper';\nimport type { DestinationMetrics } from '../../../DestinationMetrics';\nimport { DestinationLogger } from '../../../DestinationLogger';\nimport { TikTokScriptLoader } from './TikTokScriptLoader';\nimport type { TikTokTtq } from './types';\n\nexport type TikTokBrowserDestinationDeps = {\n readonly config: TikTokBrowserDestinationConfig;\n readonly getSessionId: () => string;\n readonly logger: DestinationLogger;\n readonly metrics?: DestinationMetrics;\n readonly debug: boolean;\n};\n\n/**\n * TikTok Pixel browser destination — PAGE_VIEW only.\n *\n * Limitation: when only the global `ttq.page()` API exists (no `ttq.instance`),\n * a single page() call is issued per PAGE_VIEW event — not once per pixelId.\n * Multi-pixel dedupe still tracks per pixelId for the instance API path.\n */\nexport class TikTokBrowserDestination extends BaseDestinationAdapter {\n private readonly config: TikTokBrowserDestinationConfig;\n\n private readonly getSessionId: () => string;\n\n private readonly logger: DestinationLogger;\n\n private readonly metrics?: DestinationMetrics;\n\n private readonly debug: boolean;\n\n private readonly scriptLoader = new TikTokScriptLoader();\n\n private readonly pixelIds: string[];\n\n private initialized = false;\n\n private ttq: TikTokTtq | null = null;\n\n constructor(deps: TikTokBrowserDestinationDeps) {\n super({\n name: 'tiktok',\n version: '1.0.0',\n supportedTypes: new Set(['PAGE_VIEW']),\n });\n this.config = deps.config;\n this.getSessionId = deps.getSessionId;\n this.logger = deps.logger.forAdapter('TikTokBrowser');\n this.metrics = deps.metrics;\n this.debug = deps.debug;\n this.pixelIds = [...new Set(deps.config.pixelIds.filter(Boolean))];\n }\n\n supports(event: PixelEvent): boolean {\n return (\n this.config.enabled &&\n this.config.autoPageView !== false &&\n this.pixelIds.length > 0 &&\n event.type === 'PAGE_VIEW'\n );\n }\n\n async ensureInit(timeoutMs: number): Promise<void> {\n if (this.initialized) return;\n if (!this.config.enabled || this.pixelIds.length === 0) return;\n\n this.metrics?.recordInitAttempt('tiktok');\n if (this.debug) this.logger.debug('destination_init_start');\n\n if (this.config.loadScript !== false) {\n this.metrics?.recordScriptLoadAttempt('tiktok');\n if (this.debug) this.logger.debug('script_load_start');\n try {\n this.ttq = await this.scriptLoader.load(timeoutMs);\n this.metrics?.recordScriptLoadSuccess('tiktok');\n if (this.debug) this.logger.debug('script_load_success');\n } catch (error) {\n this.metrics?.recordScriptLoadFailure('tiktok');\n this.logger.error('script_load_failure', error);\n throw error;\n }\n } else if (typeof window !== 'undefined' && (window as { ttq?: TikTokTtq }).ttq) {\n this.ttq = (window as { ttq?: TikTokTtq }).ttq ?? null;\n }\n\n const ttq = this.ttq;\n if (!ttq) {\n this.metrics?.recordInitFailure('tiktok');\n throw new Error('[TikTokBrowser] ttq unavailable');\n }\n\n let initFailed = false;\n for (const pixelId of this.pixelIds) {\n try {\n ttq.load(pixelId);\n } catch (error) {\n initFailed = true;\n this.metrics?.recordInitFailure('tiktok');\n this.logger.error(`destination_init_failure id=${pixelId}`, error);\n }\n }\n\n this.initialized = true;\n if (!initFailed) this.metrics?.recordInitSuccess('tiktok');\n if (this.debug) this.logger.debug('destination_init_success');\n }\n\n async execute(context: DestinationContext): Promise<DestinationResult> {\n const startedAt = Date.now();\n const { event, signal, timeoutMs } = context;\n\n if (event.type !== 'PAGE_VIEW') {\n return this.createResult('ignored', Date.now() - startedAt, {\n ignored: true,\n });\n }\n\n if (signal.aborted) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'Aborted',\n });\n }\n\n if (this.debug) this.logger.debug('pageview_received');\n\n try {\n await this.ensureInit(timeoutMs);\n } catch (error) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const ttq =\n this.ttq ??\n (typeof window !== 'undefined'\n ? (window as { ttq?: TikTokTtq }).ttq ?? null\n : null);\n if (!ttq) {\n return this.createResult('failed', Date.now() - startedAt, {\n error: 'ttq unavailable',\n });\n }\n\n const path = event.path ?? event.url ?? '/';\n const sessionId = this.getSessionId();\n let sent = 0;\n let deduped = 0;\n\n const hasInstanceApi = typeof ttq.instance === 'function';\n\n if (hasInstanceApi) {\n for (const pixelId of this.pixelIds) {\n const key = buildExternalPageViewKey(\n 'tiktok',\n pixelId,\n 'PAGE_VIEW',\n path,\n sessionId\n );\n\n if (shouldSkipExternalPageView(key)) {\n deduped += 1;\n if (this.debug) this.logger.debug(`pageview_skipped_dedupe id=${pixelId}`);\n continue;\n }\n\n try {\n const instance = ttq.instance!(pixelId);\n instance.page();\n sent += 1;\n if (this.debug) this.logger.debug(`pageview_sent id=${pixelId}`);\n } catch (error) {\n this.logger.error(`destination_execute_failure id=${pixelId}`, error);\n }\n }\n } else {\n // Global ttq.page() — single call per PAGE_VIEW, not per pixelId.\n const dedupeId = this.pixelIds[0] ?? 'global';\n const key = buildExternalPageViewKey(\n 'tiktok',\n dedupeId,\n 'PAGE_VIEW',\n path,\n sessionId\n );\n\n if (shouldSkipExternalPageView(key)) {\n deduped = 1;\n if (this.debug) this.logger.debug('pageview_skipped_dedupe global');\n } else {\n try {\n ttq.page();\n sent = 1;\n if (this.debug) this.logger.debug('pageview_sent global');\n } catch (error) {\n this.logger.error('destination_execute_failure global', error);\n }\n }\n }\n\n if (sent === 0 && deduped > 0) {\n return this.createResult('skipped', Date.now() - startedAt, {\n skipped: true,\n metadata: { sent, deduped },\n });\n }\n\n return this.createResult('success', Date.now() - startedAt, {\n metadata: { sent, deduped, pixelIds: this.pixelIds },\n });\n }\n\n destroy(): void {\n this.scriptLoader.release();\n this.initialized = false;\n this.ttq = null;\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelLogger } from '@/logger';\nimport type { IntegrationsModuleConfig } from '@/config/types/modules/integrations';\n\nimport {\n ConsoleDestination,\n MemoryDestination,\n MockDestination,\n} from './adapters';\nimport {\n MetaBrowserDestination,\n GoogleBrowserDestination,\n TikTokBrowserDestination,\n} from './adapters/browser';\nimport type { DestinationAdapter } from './types';\nimport type {\n IntegrationDebugState,\n DestinationHooks,\n DestinationResult,\n} from './types';\nimport { DestinationDispatcher } from './DestinationDispatcher';\nimport { DestinationErrorHandler } from './DestinationErrorHandler';\nimport { DestinationExecutor } from './DestinationExecutor';\nimport { DestinationLogger } from './DestinationLogger';\nimport { DestinationMetrics } from './DestinationMetrics';\nimport { DestinationPipeline } from './DestinationPipeline';\nimport { DestinationRegistry } from './DestinationRegistry';\n\nexport type IntegrationEngineConfig = {\n readonly moduleConfig: IntegrationsModuleConfig;\n readonly getSessionId: () => string;\n};\n\n/**\n * Browser destinations fan-out only.\n * Does NOT collect attribution, enrich events, or talk to Transport/API.\n */\nexport class IntegrationEngine {\n private readonly registry: DestinationRegistry;\n\n private readonly metrics: DestinationMetrics;\n\n private readonly logger: DestinationLogger;\n\n private readonly pipeline: DestinationPipeline;\n\n private readonly dispatcher: DestinationDispatcher;\n\n private memoryDestination: MemoryDestination | null = null;\n\n private active = false;\n\n private readonly debug: boolean;\n\n constructor(\n pixelLogger: PixelLogger,\n config: IntegrationEngineConfig,\n hooks?: DestinationHooks,\n extraAdapters: readonly DestinationAdapter[] = []\n ) {\n this.registry = new DestinationRegistry();\n this.metrics = new DestinationMetrics();\n this.logger = new DestinationLogger(pixelLogger);\n this.pipeline = DestinationPipeline.identity();\n this.debug = config.moduleConfig.debug;\n\n const errorHandler = new DestinationErrorHandler(\n this.logger,\n config.moduleConfig.continueOnError\n );\n const executor = new DestinationExecutor({\n logger: this.logger,\n errorHandler,\n hooks,\n timeoutMs: config.moduleConfig.timeoutMs,\n debug: config.moduleConfig.debug,\n });\n\n this.dispatcher = new DestinationDispatcher({\n registry: this.registry,\n executor,\n metrics: this.metrics,\n logger: this.logger,\n concurrency: config.moduleConfig.concurrency,\n });\n\n const destinations = config.moduleConfig.destinations;\n const debug = config.moduleConfig.debug;\n\n if (destinations.console.enabled) {\n this.registry.register(\n new ConsoleDestination({\n log: debug\n ? (message, payload) => this.logger.debug(message, payload)\n : () => undefined,\n })\n );\n }\n\n if (destinations.memory.enabled) {\n this.memoryDestination = new MemoryDestination();\n this.registry.register(this.memoryDestination);\n }\n\n if (destinations.mock.enabled) {\n this.registry.register(new MockDestination());\n }\n\n if (destinations.meta.enabled && destinations.meta.pixelIds.length > 0) {\n this.registry.register(\n new MetaBrowserDestination({\n config: destinations.meta,\n getSessionId: config.getSessionId,\n logger: this.logger,\n metrics: this.metrics,\n debug,\n })\n );\n }\n\n if (destinations.google.enabled && destinations.google.tagIds.length > 0) {\n this.registry.register(\n new GoogleBrowserDestination({\n config: destinations.google,\n getSessionId: config.getSessionId,\n logger: this.logger,\n metrics: this.metrics,\n debug,\n })\n );\n }\n\n if (\n destinations.tiktok.enabled &&\n destinations.tiktok.pixelIds.length > 0\n ) {\n this.registry.register(\n new TikTokBrowserDestination({\n config: destinations.tiktok,\n getSessionId: config.getSessionId,\n logger: this.logger,\n metrics: this.metrics,\n debug,\n })\n );\n }\n\n for (const adapter of extraAdapters) {\n this.registry.register(adapter);\n }\n\n this.metrics.setRegisteredCount(this.registry.size());\n }\n\n init(): void {\n if (this.active) return;\n this.active = true;\n if (this.debug) {\n this.logger.debug('IntegrationEngine initialized (browser destinations)');\n }\n }\n\n destroy(): void {\n if (!this.active) return;\n this.registry.clear();\n this.metrics.reset();\n this.dispatcher.clearLastResults();\n this.memoryDestination = null;\n this.active = false;\n if (this.debug) {\n this.logger.debug('IntegrationEngine destroyed');\n }\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n handleEvent(event: PixelEvent): void {\n if (!this.active) return;\n\n if (event.type === 'PAGE_VIEW') {\n this.metrics.recordPageViewReceived();\n }\n\n const processed = this.pipeline.process(event);\n if (!processed) {\n if (this.debug) {\n this.logger.debug(`Event dropped by destination pipeline: ${event.type}`);\n }\n return;\n }\n\n void this.dispatcher.dispatch(processed);\n }\n\n async handleEventAsync(\n event: PixelEvent\n ): Promise<readonly DestinationResult[]> {\n if (!this.active) return [];\n\n if (event.type === 'PAGE_VIEW') {\n this.metrics.recordPageViewReceived();\n }\n\n const processed = this.pipeline.process(event);\n if (!processed) return [];\n\n return this.dispatcher.dispatch(processed);\n }\n\n registerDestination(adapter: DestinationAdapter): void {\n this.registry.register(adapter);\n this.metrics.setRegisteredCount(this.registry.size());\n }\n\n removeDestination(name: string): boolean {\n const removed = this.registry.remove(name);\n this.metrics.setRegisteredCount(this.registry.size());\n return removed;\n }\n\n getRegistry(): DestinationRegistry {\n return this.registry;\n }\n\n getMemoryRecords() {\n return this.memoryDestination?.getRecords() ?? [];\n }\n\n getDebugState(): IntegrationDebugState {\n return {\n active: this.active,\n destinationNames: this.registry.getAll().map(adapter => adapter.name),\n metrics: this.metrics.getSnapshot(),\n lastResults: this.dispatcher.getLastResults(),\n };\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport {\n IntegrationEngine,\n DestinationSubscriber,\n type IntegrationDebugState,\n type DestinationAdapter,\n} from '@/integration';\n\n/**\n * PixelModule facade — browser destinations only.\n * Subscribes Dispatcher in parallel with Transport.\n * Attribution is a separate Runtime service.\n */\nexport class IntegrationsModule implements PixelModule {\n readonly name = 'integrations' as const;\n\n private engine: IntegrationEngine | null = null;\n\n private subscriber: DestinationSubscriber | null = null;\n\n private active = false;\n\n init(context: PixelRuntimeContext): void {\n if (this.active) {\n context.logger.debug('[Pixel] Integrations module already initialized');\n return;\n }\n\n if (!context.config.modules.integrations.enabled) {\n context.logger.debug('[Pixel] Integrations module disabled');\n return;\n }\n\n const moduleConfig = context.config.modules.integrations;\n\n this.engine = new IntegrationEngine(context.logger, {\n moduleConfig: {\n ...moduleConfig,\n debug: moduleConfig.debug || context.config.app.debug === true,\n },\n getSessionId: () =>\n context.services.session.getSessionId() ??\n `anon_${context.config.identity.pixelId || 'pixel'}`,\n });\n\n this.engine.init();\n\n this.subscriber = new DestinationSubscriber(\n context.services.dispatcher,\n event => this.engine?.handleEvent(event)\n );\n this.subscriber.subscribe();\n\n this.active = true;\n context.logger.debug('[Pixel] Integrations module initialized');\n }\n\n destroy(): void {\n if (!this.active) return;\n\n this.subscriber?.unsubscribeAll();\n this.subscriber = null;\n\n this.engine?.destroy();\n this.engine = null;\n\n this.active = false;\n }\n\n getDebugState(): IntegrationDebugState | null {\n return this.engine?.getDebugState() ?? null;\n }\n\n isEngineActive(): boolean {\n return this.engine?.isActive() ?? false;\n }\n\n registerDestination(adapter: DestinationAdapter): void {\n this.engine?.registerDestination(adapter);\n }\n\n removeDestination(name: string): boolean {\n return this.engine?.removeDestination(name) ?? false;\n }\n\n getMemoryRecords() {\n return this.engine?.getMemoryRecords() ?? [];\n }\n\n handleEventAsync(event: PixelEvent) {\n return this.engine?.handleEventAsync(event) ?? Promise.resolve([]);\n }\n}\n","import type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nexport class PrivacyModule implements PixelModule {\n readonly name = 'privacy' as const;\n\n init(context: PixelRuntimeContext): void {\n context.logger.debug('[Pixel] Privacy module initialized');\n }\n\n destroy(): void {}\n}\n","import type { PixelEvent } from '@/events';\nimport type { DispatcherService } from '@/services/dispatcher/types';\n\nexport class DispatcherSubscriber {\n private readonly dispatcher: DispatcherService;\n\n private readonly onEvent: (event: PixelEvent) => void;\n\n private unsubscribe: (() => void) | null = null;\n\n constructor(\n dispatcher: DispatcherService,\n onEvent: (event: PixelEvent) => void\n ) {\n this.dispatcher = dispatcher;\n this.onEvent = onEvent;\n }\n\n subscribe(): void {\n if (this.unsubscribe) return;\n this.unsubscribe = this.dispatcher.subscribe(event => this.onEvent(event));\n }\n\n unsubscribeAll(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n\n isSubscribed(): boolean {\n return this.unsubscribe !== null;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { BatchConfig, BatchDebugState, IBatchManager } from './types';\n\nexport class BatchManager implements IBatchManager {\n private buffer: PixelEvent[] = [];\n\n private oldestAt: number | null = null;\n\n add(events: readonly PixelEvent[]): void {\n if (events.length === 0) return;\n\n if (this.buffer.length === 0) {\n this.oldestAt = Date.now();\n }\n\n this.buffer.push(...events);\n }\n\n takeBatch(maxSize?: number): PixelEvent[] {\n if (this.buffer.length === 0) return [];\n\n const limit = maxSize ?? this.buffer.length;\n const batch = this.buffer.splice(0, limit);\n\n if (this.buffer.length === 0) {\n this.oldestAt = null;\n }\n\n return batch;\n }\n\n peek(): readonly PixelEvent[] {\n return [...this.buffer];\n }\n\n size(): number {\n return this.buffer.length;\n }\n\n clear(): void {\n this.buffer = [];\n this.oldestAt = null;\n }\n\n shouldFlush(config: BatchConfig): boolean {\n if (this.buffer.length === 0) return false;\n if (this.buffer.length >= config.batchSize) return true;\n\n if (this.oldestAt !== null && Date.now() - this.oldestAt >= config.maxWaitMs) {\n return true;\n }\n\n return false;\n }\n\n getState(): BatchDebugState {\n return {\n bufferSize: this.buffer.length,\n oldestEventAt: this.oldestAt,\n pendingBatches: this.buffer.length,\n };\n }\n}\n","import type { CompressionResult, CompressionStrategy } from './types';\n\nexport class IdentityCompressionStrategy implements CompressionStrategy {\n readonly name = 'identity';\n\n compress(payload: string): CompressionResult {\n return {\n encoding: 'identity',\n body: payload,\n originalSize: payload.length,\n compressedSize: payload.length,\n };\n }\n}\n","import { IdentityCompressionStrategy } from './IdentityCompressionStrategy';\nimport type { CompressionConfig, CompressionDebugState, CompressionStrategy } from './types';\n\nexport function createCompressionStrategy(\n config: CompressionConfig\n): CompressionStrategy {\n if (!config.enabled || config.strategy === 'identity') {\n return new IdentityCompressionStrategy();\n }\n\n return new IdentityCompressionStrategy();\n}\n\nexport function getCompressionDebugState(\n config: CompressionConfig,\n strategy: CompressionStrategy,\n lastResult?: { originalSize: number; compressedSize: number } | null\n): CompressionDebugState {\n return {\n enabled: config.enabled,\n strategy: strategy.name,\n lastOriginalSize: lastResult?.originalSize ?? null,\n lastCompressedSize: lastResult?.compressedSize ?? null,\n };\n}\n\nexport type { CompressionConfig, CompressionDebugState, CompressionStrategy, CompressionResult } from './types';\nexport { IdentityCompressionStrategy } from './IdentityCompressionStrategy';\n","export type CoordinationConfig = {\n readonly enabled: boolean;\n readonly channelName?: string;\n};\n\nexport type CoordinationDebugState = {\n readonly enabled: boolean;\n readonly tabId: string;\n readonly isLeader: boolean;\n readonly leaderTabId: string | null;\n readonly tabCount: number;\n readonly transport: 'broadcastChannel' | 'storageEvents' | 'none';\n};\n\ntype LeaderMessage =\n | { type: 'leader_claim'; tabId: string; at: number }\n | { type: 'leader_release'; tabId: string }\n | { type: 'heartbeat'; tabId: string; at: number };\n\nexport class CoordinationManager {\n private readonly config: CoordinationConfig;\n\n private readonly tabId: string;\n\n private readonly channelName: string;\n\n private channel: BroadcastChannel | null = null;\n\n private storageKey: string;\n\n private isLeader = false;\n\n private leaderTabId: string | null = null;\n\n private tabCount = 1;\n\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n\n private onLeaderChange: ((isLeader: boolean) => void) | null = null;\n\n private storageListener: ((event: StorageEvent) => void) | null = null;\n\n private transport: CoordinationDebugState['transport'] = 'none';\n\n constructor(config: CoordinationConfig, instanceId: string) {\n this.config = config;\n this.tabId = `tab_${instanceId}_${crypto.randomUUID().slice(0, 8)}`;\n this.channelName = config.channelName ?? `pixel_transport_coordination_${instanceId}`;\n this.storageKey = `${this.channelName}:leader`;\n }\n\n init(onLeaderChange?: (isLeader: boolean) => void): void {\n if (!this.config.enabled || typeof window === 'undefined') {\n this.isLeader = true;\n this.leaderTabId = this.tabId;\n return;\n }\n\n this.onLeaderChange = onLeaderChange ?? null;\n\n if (typeof BroadcastChannel !== 'undefined') {\n this.transport = 'broadcastChannel';\n this.channel = new BroadcastChannel(this.channelName);\n this.channel.onmessage = event => this.handleMessage(event.data as LeaderMessage);\n } else {\n this.transport = 'storageEvents';\n this.storageListener = (event: StorageEvent) => {\n if (event.key !== this.storageKey || !event.newValue) return;\n try {\n this.handleMessage(JSON.parse(event.newValue) as LeaderMessage);\n } catch {\n // ignore malformed messages\n }\n };\n window.addEventListener('storage', this.storageListener);\n }\n\n this.claimLeadership();\n this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), 2000);\n }\n\n destroy(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n if (this.isLeader) {\n this.releaseLeadership();\n }\n\n if (this.channel) {\n this.channel.close();\n this.channel = null;\n }\n\n if (this.storageListener && typeof window !== 'undefined') {\n window.removeEventListener('storage', this.storageListener);\n this.storageListener = null;\n }\n\n this.onLeaderChange = null;\n }\n\n canSend(): boolean {\n if (!this.config.enabled) return true;\n return this.isLeader;\n }\n\n shouldPersistOnly(): boolean {\n return this.config.enabled && !this.isLeader;\n }\n\n isTabLeader(): boolean {\n return this.isLeader;\n }\n\n getDebugState(): CoordinationDebugState {\n return {\n enabled: this.config.enabled,\n tabId: this.tabId,\n isLeader: this.isLeader,\n leaderTabId: this.leaderTabId,\n tabCount: this.tabCount,\n transport: this.transport,\n };\n }\n\n private claimLeadership(): void {\n const message: LeaderMessage = { type: 'leader_claim', tabId: this.tabId, at: Date.now() };\n this.broadcast(message);\n\n if (!this.leaderTabId) {\n this.setLeader(this.tabId);\n }\n }\n\n private releaseLeadership(): void {\n const message: LeaderMessage = { type: 'leader_release', tabId: this.tabId };\n this.broadcast(message);\n if (this.isLeader) {\n this.setLeader(null);\n }\n }\n\n private sendHeartbeat(): void {\n if (!this.isLeader) return;\n this.broadcast({ type: 'heartbeat', tabId: this.tabId, at: Date.now() });\n }\n\n private handleMessage(message: LeaderMessage): void {\n switch (message.type) {\n case 'leader_claim':\n if (!this.leaderTabId || message.at < Date.now()) {\n this.setLeader(message.tabId);\n }\n break;\n case 'leader_release':\n if (this.leaderTabId === message.tabId) {\n this.setLeader(null);\n if (!this.isLeader) {\n this.claimLeadership();\n }\n }\n break;\n case 'heartbeat':\n this.tabCount = Math.max(this.tabCount, 1);\n if (this.leaderTabId === message.tabId) {\n this.leaderTabId = message.tabId;\n }\n break;\n default:\n break;\n }\n }\n\n private setLeader(tabId: string | null): void {\n const wasLeader = this.isLeader;\n this.leaderTabId = tabId;\n this.isLeader = tabId === this.tabId;\n\n if (wasLeader !== this.isLeader) {\n this.onLeaderChange?.(this.isLeader);\n }\n }\n\n private broadcast(message: LeaderMessage): void {\n if (this.channel) {\n this.channel.postMessage(message);\n return;\n }\n\n if (typeof window !== 'undefined' && window.localStorage) {\n try {\n window.localStorage.setItem(this.storageKey, JSON.stringify(message));\n } catch {\n // ignore quota errors\n }\n }\n }\n}\n","import type { PixelEvent } from '@/events';\n\nexport type DeadLetterReason =\n | 'max_retries_exceeded'\n | 'circuit_open'\n | 'permanent_failure'\n | 'manual';\n\nexport type DeadLetterEntry = {\n readonly id: string;\n readonly events: readonly PixelEvent[];\n readonly reason: DeadLetterReason;\n readonly failedAt: number;\n readonly attempts: number;\n readonly lastError?: string;\n};\n\nexport type DeadLetterConfig = {\n readonly enabled: boolean;\n readonly maxEntries: number;\n};\n\nexport type DeadLetterDebugState = {\n readonly enabled: boolean;\n readonly count: number;\n readonly maxEntries: number;\n readonly entries: readonly DeadLetterEntry[];\n};\n\nexport class DeadLetterManager {\n private readonly config: DeadLetterConfig;\n\n private entries: DeadLetterEntry[] = [];\n\n constructor(config: DeadLetterConfig) {\n this.config = config;\n }\n\n move(\n events: readonly PixelEvent[],\n reason: DeadLetterReason,\n attempts = 0,\n lastError?: string\n ): DeadLetterEntry | null {\n if (!this.config.enabled || events.length === 0) return null;\n\n const entry: DeadLetterEntry = {\n id: crypto.randomUUID(),\n events: [...events],\n reason,\n failedAt: Date.now(),\n attempts,\n lastError,\n };\n\n this.entries.push(entry);\n\n if (this.entries.length > this.config.maxEntries) {\n this.entries = this.entries.slice(-this.config.maxEntries);\n }\n\n return entry;\n }\n\n replayEntry(id: string): readonly PixelEvent[] | null {\n const index = this.entries.findIndex(entry => entry.id === id);\n if (index < 0) return null;\n\n const [entry] = this.entries.splice(index, 1);\n return entry?.events ?? null;\n }\n\n replayAll(): PixelEvent[] {\n const events = this.entries.flatMap(entry => [...entry.events]);\n this.entries = [];\n return events;\n }\n\n clear(): void {\n this.entries = [];\n }\n\n getEntries(): readonly DeadLetterEntry[] {\n return [...this.entries];\n }\n\n getCount(): number {\n return this.entries.length;\n }\n\n getDebugState(): DeadLetterDebugState {\n return {\n enabled: this.config.enabled,\n count: this.entries.length,\n maxEntries: this.config.maxEntries,\n entries: this.getEntries(),\n };\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelLogger } from '@/logger';\n\nimport type { IBatchManager, BatchConfig } from '../batch/types';\nimport type { IFlushManager } from '../flush/types';\nimport type { IOfflineDetector } from '../network/types';\nimport type { IRetryEngine } from '../retry/types';\nimport type { EventSender } from '../sender/types';\n\nexport type DeliveryConfig = {\n readonly batch: BatchConfig;\n readonly timeoutMs: number;\n};\n\nexport type DeliveryDebugState = {\n readonly batch: ReturnType<IBatchManager['getState']>;\n readonly retry: ReturnType<IRetryEngine['getState']>;\n readonly offline: ReturnType<IOfflineDetector['getState']>;\n readonly flush: ReturnType<IFlushManager['getState']>;\n readonly timeoutMs: number;\n readonly inFlight: boolean;\n readonly ackCount: number;\n};\n\nexport class TransportDelivery {\n private readonly batchManager: IBatchManager;\n\n private readonly flushManager: IFlushManager;\n\n private readonly retryEngine: IRetryEngine;\n\n private readonly offlineDetector: IOfflineDetector;\n\n private readonly sender: EventSender;\n\n private readonly config: DeliveryConfig;\n\n private readonly logger: PixelLogger;\n\n private active = false;\n\n private inFlight = false;\n\n private ackCount = 0;\n\n private abortPending: (() => void) | null = null;\n\n private readonly onPermanentFailure:\n | ((events: readonly PixelEvent[], error: unknown) => void)\n | null;\n\n constructor(deps: {\n batchManager: IBatchManager;\n flushManager: IFlushManager;\n retryEngine: IRetryEngine;\n offlineDetector: IOfflineDetector;\n sender: EventSender;\n config: DeliveryConfig;\n logger: PixelLogger;\n abortPending?: () => void;\n onPermanentFailure?: (events: readonly PixelEvent[], error: unknown) => void;\n }) {\n this.batchManager = deps.batchManager;\n this.flushManager = deps.flushManager;\n this.retryEngine = deps.retryEngine;\n this.offlineDetector = deps.offlineDetector;\n this.sender = deps.sender;\n this.config = deps.config;\n this.logger = deps.logger;\n this.abortPending = deps.abortPending ?? null;\n this.onPermanentFailure = deps.onPermanentFailure ?? null;\n }\n\n init(): void {\n if (this.active) return;\n\n this.offlineDetector.init(\n () => {\n this.logger.debug('[TransportDelivery] Online — resuming');\n this.flush();\n },\n () => {\n this.logger.debug('[TransportDelivery] Offline — paused');\n }\n );\n\n this.flushManager.init(() => this.flush());\n this.active = true;\n }\n\n destroy(): void {\n if (!this.active) return;\n\n this.abortPending?.();\n this.retryEngine.cancelAll();\n this.flushManager.destroy();\n this.offlineDetector.destroy();\n this.batchManager.clear();\n this.active = false;\n this.inFlight = false;\n }\n\n ingest(events: readonly PixelEvent[]): void {\n if (!this.active || events.length === 0) return;\n\n this.batchManager.add(events);\n\n if (this.batchManager.shouldFlush(this.config.batch)) {\n this.flush();\n }\n }\n\n flush(): void {\n if (!this.active || !this.offlineDetector.isOnline()) return;\n void this.processBatch();\n }\n\n getDebugState(): DeliveryDebugState {\n return {\n batch: this.batchManager.getState(),\n retry: this.retryEngine.getState(),\n offline: this.offlineDetector.getState(),\n flush: this.flushManager.getState(),\n timeoutMs: this.config.timeoutMs,\n inFlight: this.inFlight,\n ackCount: this.ackCount,\n };\n }\n\n getOfflineDetector(): IOfflineDetector {\n return this.offlineDetector;\n }\n\n private async processBatch(): Promise<void> {\n if (this.inFlight || !this.offlineDetector.isOnline()) return;\n\n const batch = this.batchManager.takeBatch(this.config.batch.batchSize);\n if (batch.length === 0) return;\n\n this.inFlight = true;\n\n try {\n await this.retryEngine.retry(async () => {\n const result = await this.sender.send(batch);\n if (!result.ack) {\n throw new Error('[TransportDelivery] Send not acknowledged');\n }\n this.ackCount += result.eventCount;\n }, `delivery-${Date.now()}`);\n } catch (error) {\n this.logger.error('[TransportDelivery] Delivery failed after retries', error);\n\n if (this.onPermanentFailure) {\n this.onPermanentFailure(batch, error);\n } else {\n this.batchManager.add(batch);\n }\n } finally {\n this.inFlight = false;\n\n if (this.batchManager.size() > 0 && this.offlineDetector.isOnline()) {\n this.flush();\n }\n }\n }\n}\n","import type { FlushConfig, FlushDebugState, IFlushManager } from './types';\n\ntype ManagedListener = {\n readonly target: 'window' | 'document';\n readonly type: string;\n readonly handler: EventListener;\n};\n\nexport class FlushManager implements IFlushManager {\n private readonly config: FlushConfig;\n\n private onFlush: (() => void) | null = null;\n\n private intervalId: ReturnType<typeof setInterval> | null = null;\n\n private flushCount = 0;\n\n private lastFlushAt: number | null = null;\n\n private readonly listeners: ManagedListener[] = [];\n\n constructor(config: FlushConfig) {\n this.config = config;\n }\n\n init(onFlush: () => void): void {\n this.onFlush = onFlush;\n\n if (this.config.flushIntervalMs > 0) {\n this.intervalId = setInterval(() => this.flush(), this.config.flushIntervalMs);\n }\n\n if (this.config.prepareUnloadHooks) {\n this.registerUnloadHooks();\n }\n }\n\n flush(): void {\n if (!this.onFlush) return;\n\n this.flushCount += 1;\n this.lastFlushAt = Date.now();\n this.onFlush();\n }\n\n destroy(): void {\n if (this.config.flushOnDestroy) {\n this.flush();\n }\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n this.removeListeners();\n this.onFlush = null;\n }\n\n getState(): FlushDebugState {\n return {\n flushCount: this.flushCount,\n lastFlushAt: this.lastFlushAt,\n intervalActive: this.intervalId !== null,\n };\n }\n\n private registerUnloadHooks(): void {\n if (typeof window === 'undefined') return;\n\n const handler = (): void => this.flush();\n\n for (const type of ['pagehide', 'beforeunload'] as const) {\n window.addEventListener(type, handler);\n this.listeners.push({ target: 'window', type, handler });\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', handler);\n this.listeners.push({ target: 'document', type: 'visibilitychange', handler });\n }\n }\n\n private removeListeners(): void {\n for (const entry of this.listeners) {\n if (entry.target === 'window' && typeof window !== 'undefined') {\n window.removeEventListener(entry.type, entry.handler);\n } else if (entry.target === 'document' && typeof document !== 'undefined') {\n document.removeEventListener(entry.type, entry.handler);\n }\n }\n this.listeners.length = 0;\n }\n}\n","import type { OfflineDebugState, IOfflineDetector } from './types';\n\ntype ManagedListener = {\n readonly type: string;\n readonly handler: EventListener;\n};\n\nexport class OfflineDetector implements IOfflineDetector {\n private online = true;\n\n private paused = false;\n\n private simulatedOffline = false;\n\n private onOnline: (() => void) | null = null;\n\n private onOffline: (() => void) | null = null;\n\n private readonly listeners: ManagedListener[] = [];\n\n init(onOnline: () => void, onOffline: () => void): void {\n this.onOnline = onOnline;\n this.onOffline = onOffline;\n\n if (typeof window === 'undefined') return;\n\n this.online = typeof navigator === 'undefined' ? true : navigator.onLine;\n\n const handleOnline = (): void => {\n if (this.simulatedOffline) return;\n this.online = true;\n this.paused = false;\n this.onOnline?.();\n };\n\n const handleOffline = (): void => {\n if (this.simulatedOffline) return;\n this.online = false;\n this.paused = true;\n this.onOffline?.();\n };\n\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n this.listeners.push(\n { type: 'online', handler: handleOnline as EventListener },\n { type: 'offline', handler: handleOffline as EventListener }\n );\n }\n\n isOnline(): boolean {\n return this.online && !this.simulatedOffline;\n }\n\n isPaused(): boolean {\n return this.paused || this.simulatedOffline;\n }\n\n destroy(): void {\n if (typeof window !== 'undefined') {\n for (const entry of this.listeners) {\n window.removeEventListener(entry.type, entry.handler);\n }\n }\n this.listeners.length = 0;\n this.onOnline = null;\n this.onOffline = null;\n }\n\n simulateOffline(offline: boolean): void {\n this.simulatedOffline = offline;\n if (offline) {\n this.paused = true;\n this.onOffline?.();\n } else {\n this.paused = false;\n this.online = true;\n this.onOnline?.();\n }\n }\n\n getState(): OfflineDebugState {\n return {\n isOnline: this.isOnline(),\n paused: this.isPaused(),\n simulatedOffline: this.simulatedOffline,\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { QueuedEventRecord } from '../queue/storage/types';\n\nexport type OrderingConfig = {\n readonly enabled: boolean;\n};\n\nexport type OrderingDebugState = {\n readonly enabled: boolean;\n readonly globalSequence: number;\n readonly sessionSequence: number;\n readonly lastCorrelationId: string | null;\n readonly recordCount: number;\n};\n\nexport class OrderingManager {\n private readonly enabled: boolean;\n\n private globalSequence = 0;\n\n private sessionSequence = 0;\n\n private lastCorrelationId: string | null = null;\n\n constructor(config: OrderingConfig) {\n this.enabled = config.enabled;\n }\n\n assign(event: PixelEvent, correlationId?: string, transactionGroup?: string): QueuedEventRecord {\n if (this.enabled) {\n this.globalSequence += 1;\n this.sessionSequence += 1;\n }\n\n if (correlationId) {\n this.lastCorrelationId = correlationId;\n }\n\n return {\n id: crypto.randomUUID(),\n event,\n sequence: this.globalSequence,\n sessionSequence: this.sessionSequence,\n correlationId: correlationId ?? this.lastCorrelationId ?? undefined,\n transactionGroup,\n enqueuedAt: Date.now(),\n };\n }\n\n sort(records: readonly QueuedEventRecord[]): QueuedEventRecord[] {\n if (!this.enabled) return [...records];\n\n return [...records].sort((left, right) => {\n if (left.sequence !== right.sequence) {\n return left.sequence - right.sequence;\n }\n return left.enqueuedAt - right.enqueuedAt;\n });\n }\n\n restoreFromRecords(records: readonly QueuedEventRecord[]): void {\n if (!this.enabled || records.length === 0) return;\n\n const maxGlobal = records.reduce((max, record) => Math.max(max, record.sequence), 0);\n const maxSession = records.reduce(\n (max, record) => Math.max(max, record.sessionSequence),\n 0\n );\n\n this.globalSequence = Math.max(this.globalSequence, maxGlobal);\n this.sessionSequence = Math.max(this.sessionSequence, maxSession);\n\n const lastWithCorrelation = [...records]\n .reverse()\n .find(record => record.correlationId);\n if (lastWithCorrelation?.correlationId) {\n this.lastCorrelationId = lastWithCorrelation.correlationId;\n }\n }\n\n resetSessionSequence(): void {\n this.sessionSequence = 0;\n }\n\n getDebugState(recordCount = 0): OrderingDebugState {\n return {\n enabled: this.enabled,\n globalSequence: this.globalSequence,\n sessionSequence: this.sessionSequence,\n lastCorrelationId: this.lastCorrelationId,\n recordCount,\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { IEventQueue } from '../../queue/types';\nimport type { PipelineStage } from '../types';\n\nexport class EnqueueStage implements PipelineStage {\n readonly name = 'enqueue';\n\n private readonly queue: IEventQueue;\n\n constructor(queue: IEventQueue) {\n this.queue = queue;\n }\n\n process(event: PixelEvent): PixelEvent | null {\n this.queue.enqueue(event);\n return event;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { PipelineStage } from '../types';\n\nexport class NormalizeStage implements PipelineStage {\n readonly name = 'normalize';\n\n process(event: PixelEvent): PixelEvent | null {\n return {\n ...event,\n timestamp: event.timestamp ?? Date.now(),\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { PipelineStage } from '../types';\n\nexport class ValidateStage implements PipelineStage {\n readonly name = 'validate';\n\n process(event: PixelEvent): PixelEvent | null {\n if (!event.type || typeof event.type !== 'string') {\n return null;\n }\n\n if (typeof event.timestamp !== 'number' || Number.isNaN(event.timestamp)) {\n return null;\n }\n\n return event;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { IEventQueue } from '../queue/types';\nimport { EnqueueStage } from './stages/EnqueueStage';\nimport { NormalizeStage } from './stages/NormalizeStage';\nimport { ValidateStage } from './stages/ValidateStage';\nimport type { PipelineResult, PipelineStage } from './types';\n\nexport class TransportPipeline {\n private readonly stages: readonly PipelineStage[];\n\n private lastSteps: string[] = [];\n\n constructor(stages: readonly PipelineStage[]) {\n this.stages = stages;\n }\n\n static createDefault(queue: IEventQueue): TransportPipeline {\n return new TransportPipeline([\n new ValidateStage(),\n new NormalizeStage(),\n new EnqueueStage(queue),\n ]);\n }\n\n process(event: PixelEvent): PipelineResult {\n const steps: string[] = [];\n let current: PixelEvent | null = event;\n\n for (const stage of this.stages) {\n steps.push(stage.name);\n if (!current) break;\n current = stage.process(current);\n }\n\n this.lastSteps = steps;\n return { event: current, steps };\n }\n\n getLastSteps(): readonly string[] {\n return this.lastSteps;\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { BackpressureManager } from '../resilience/BackpressureManager';\nimport type { OrderingManager } from '../ordering/OrderingManager';\nimport type { IQueueStorage, QueuedEventRecord } from './storage/types';\nimport type { IEventQueue } from './types';\n\nexport class PersistentQueue implements IEventQueue {\n private readonly storage: IQueueStorage;\n\n private readonly ordering: OrderingManager;\n\n private readonly backpressure: BackpressureManager;\n\n private records: QueuedEventRecord[] = [];\n\n private loaded = false;\n\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n storage: IQueueStorage,\n ordering: OrderingManager,\n backpressure: BackpressureManager\n ) {\n this.storage = storage;\n this.ordering = ordering;\n this.backpressure = backpressure;\n }\n\n async init(): Promise<void> {\n await this.storage.init();\n const loaded = await this.storage.load();\n this.records = this.ordering.sort(loaded);\n this.ordering.restoreFromRecords(this.records);\n this.loaded = true;\n }\n\n destroy(): void {\n if (this.persistTimer) {\n clearTimeout(this.persistTimer);\n this.persistTimer = null;\n }\n void this.flushPersist();\n this.storage.destroy();\n this.records = [];\n this.loaded = false;\n }\n\n enqueue(event: PixelEvent): void {\n this.ensureLoaded();\n\n const decision = this.backpressure.evaluateEnqueue(this.records.length);\n if (!decision.accepted) return;\n\n if (decision.policy === 'drop_oldest' && this.records.length > 0) {\n this.records.shift();\n }\n\n if (decision.policy === 'drop_newest' && decision.dropped > 0) {\n return;\n }\n\n const record = this.ordering.assign(event);\n const applied = this.backpressure.applyPolicy(this.records, record);\n this.records = applied.items;\n this.schedulePersist();\n }\n\n dequeue(): PixelEvent | undefined {\n this.ensureLoaded();\n const record = this.records.shift();\n this.schedulePersist();\n return record?.event;\n }\n\n peek(): PixelEvent | undefined {\n this.ensureLoaded();\n return this.records[0]?.event;\n }\n\n size(): number {\n this.ensureLoaded();\n return this.records.length;\n }\n\n clear(): void {\n this.records = [];\n this.schedulePersist();\n }\n\n remove(predicate: (event: PixelEvent) => boolean): number {\n this.ensureLoaded();\n const before = this.records.length;\n this.records = this.records.filter(record => !predicate(record.event));\n const removed = before - this.records.length;\n if (removed > 0) this.schedulePersist();\n return removed;\n }\n\n isEmpty(): boolean {\n return this.size() === 0;\n }\n\n getAll(): readonly PixelEvent[] {\n this.ensureLoaded();\n return this.records.map(record => record.event);\n }\n\n getRecords(): readonly QueuedEventRecord[] {\n this.ensureLoaded();\n return [...this.records];\n }\n\n importRecords(records: readonly QueuedEventRecord[]): void {\n this.records = this.ordering.sort(records);\n this.ordering.restoreFromRecords(this.records);\n this.schedulePersist();\n }\n\n exportRecords(): readonly QueuedEventRecord[] {\n return this.getRecords();\n }\n\n getStorageAdapterName(): string {\n return this.storage.getAdapterName();\n }\n\n async reload(): Promise<void> {\n const loaded = await this.storage.load();\n this.records = this.ordering.sort(loaded);\n this.ordering.restoreFromRecords(this.records);\n this.loaded = true;\n }\n\n private ensureLoaded(): void {\n if (!this.loaded) {\n this.loaded = true;\n }\n }\n\n private schedulePersist(): void {\n if (this.persistTimer) clearTimeout(this.persistTimer);\n this.persistTimer = setTimeout(() => {\n this.persistTimer = null;\n void this.flushPersist();\n }, 0);\n }\n\n private async flushPersist(): Promise<void> {\n await this.storage.save(this.records);\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { IEventQueue } from './types';\n\nexport class MemoryQueue implements IEventQueue {\n private readonly items: PixelEvent[] = [];\n\n enqueue(event: PixelEvent): void {\n this.items.push(event);\n }\n\n dequeue(): PixelEvent | undefined {\n return this.items.shift();\n }\n\n peek(): PixelEvent | undefined {\n return this.items[0];\n }\n\n size(): number {\n return this.items.length;\n }\n\n clear(): void {\n this.items.length = 0;\n }\n\n remove(predicate: (event: PixelEvent) => boolean): number {\n const before = this.items.length;\n const kept = this.items.filter(event => !predicate(event));\n this.items.length = 0;\n this.items.push(...kept);\n return before - kept.length;\n }\n\n isEmpty(): boolean {\n return this.items.length === 0;\n }\n\n getAll(): readonly PixelEvent[] {\n return [...this.items];\n }\n}\n","import type { IQueueStorage, QueuedEventRecord } from './types';\n\nexport class MemoryQueueStorage implements IQueueStorage {\n private records: QueuedEventRecord[] = [];\n\n init(): void {\n // no-op\n }\n\n destroy(): void {\n this.records = [];\n }\n\n load(): readonly QueuedEventRecord[] {\n return [...this.records];\n }\n\n save(records: readonly QueuedEventRecord[]): void {\n this.records = [...records];\n }\n\n getAdapterName(): string {\n return 'MemoryQueueStorage';\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { IQueueStorage, QueuedEventRecord } from './types';\n\nexport class LocalStorageQueueStorage implements IQueueStorage {\n private readonly storageKey: string;\n\n constructor(storageKey: string) {\n this.storageKey = storageKey;\n }\n\n init(): void {\n // no-op\n }\n\n destroy(): void {\n // persistence survives destroy by design\n }\n\n load(): readonly QueuedEventRecord[] {\n if (typeof window === 'undefined' || !window.localStorage) return [];\n\n try {\n const raw = window.localStorage.getItem(this.storageKey);\n if (!raw) return [];\n const parsed = JSON.parse(raw) as QueuedEventRecord[];\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n\n save(records: readonly QueuedEventRecord[]): void {\n if (typeof window === 'undefined' || !window.localStorage) return;\n\n try {\n window.localStorage.setItem(this.storageKey, JSON.stringify(records));\n } catch {\n // quota exceeded — caller may apply backpressure\n }\n }\n\n getAdapterName(): string {\n return 'LocalStorageQueueStorage';\n }\n\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false;\n\n try {\n const testKey = `${this.storageKey}__probe`;\n window.localStorage.setItem(testKey, '1');\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { IQueueStorage, QueuedEventRecord } from './types';\n\nconst DB_VERSION = 1;\nconst STORE_NAME = 'queue_records';\n\nexport class IndexedDBQueueStorage implements IQueueStorage {\n private readonly dbName: string;\n\n private db: IDBDatabase | null = null;\n\n constructor(dbName: string) {\n this.dbName = dbName;\n }\n\n async init(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n this.db = await new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, DB_VERSION);\n\n request.onupgradeneeded = () => {\n const database = request.result;\n if (!database.objectStoreNames.contains(STORE_NAME)) {\n database.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error('IndexedDB open failed'));\n });\n }\n\n destroy(): void {\n this.db?.close();\n this.db = null;\n }\n\n async load(): Promise<readonly QueuedEventRecord[]> {\n if (!this.db) return [];\n\n return new Promise<readonly QueuedEventRecord[]>((resolve, reject) => {\n const transaction = this.db!.transaction(STORE_NAME, 'readonly');\n const store = transaction.objectStore(STORE_NAME);\n const request = store.getAll();\n\n request.onsuccess = () => {\n const records = request.result as QueuedEventRecord[];\n resolve(Array.isArray(records) ? records : []);\n };\n request.onerror = () => reject(request.error ?? new Error('IndexedDB load failed'));\n });\n }\n\n async save(records: readonly QueuedEventRecord[]): Promise<void> {\n if (!this.db) return;\n\n await new Promise<void>((resolve, reject) => {\n const transaction = this.db!.transaction(STORE_NAME, 'readwrite');\n const store = transaction.objectStore(STORE_NAME);\n const clearRequest = store.clear();\n\n clearRequest.onsuccess = () => {\n for (const record of records) {\n store.put(record);\n }\n };\n\n transaction.oncomplete = () => resolve();\n transaction.onerror = () => reject(transaction.error ?? new Error('IndexedDB save failed'));\n });\n }\n\n getAdapterName(): string {\n return 'IndexedDBQueueStorage';\n }\n\n isAvailable(): boolean {\n return typeof indexedDB !== 'undefined';\n }\n}\n","import type { PixelConfig } from '@/config';\nimport type { QueueStoragePersistence } from '@/config/shared/persistence';\n\nimport { IndexedDBQueueStorage } from './IndexedDBQueueStorage';\nimport { LocalStorageQueueStorage } from './LocalStorageQueueStorage';\nimport { MemoryQueueStorage } from './MemoryQueueStorage';\nimport type { IQueueStorage } from './types';\n\nexport type QueueStorageFactoryOptions = {\n readonly preferred?: QueueStoragePersistence;\n readonly namespace: string;\n readonly prefix?: string;\n readonly pixelId: string;\n};\n\nfunction buildStorageKey(options: QueueStorageFactoryOptions): string {\n const prefix = options.prefix ?? '__gmk';\n const namespace = options.namespace || 'pixel';\n const pixelId = options.pixelId || 'default';\n return `${prefix}:${namespace}:${pixelId}:transport-queue`;\n}\n\nfunction buildDbName(options: QueueStorageFactoryOptions): string {\n const namespace = options.namespace || 'pixel';\n const pixelId = options.pixelId || 'default';\n return `${namespace}_${pixelId}_transport_queue`;\n}\n\nfunction createByType(\n type: QueueStoragePersistence,\n options: QueueStorageFactoryOptions\n): IQueueStorage {\n const key = buildStorageKey(options);\n\n switch (type) {\n case 'localStorage':\n return new LocalStorageQueueStorage(key);\n case 'indexedDB':\n return new IndexedDBQueueStorage(buildDbName(options));\n case 'memory':\n default:\n return new MemoryQueueStorage();\n }\n}\n\nfunction resolveFallbackChain(\n preferred?: QueueStoragePersistence\n): QueueStoragePersistence[] {\n const order: QueueStoragePersistence[] = ['indexedDB', 'localStorage', 'memory'];\n\n if (!preferred || preferred === 'memory') {\n return order;\n }\n\n const rest = order.filter(item => item !== preferred);\n return [preferred, ...rest];\n}\n\nexport function createQueueStorage(options: QueueStorageFactoryOptions): IQueueStorage {\n if (typeof window === 'undefined') {\n return new MemoryQueueStorage();\n }\n\n const chain = resolveFallbackChain(options.preferred);\n\n for (const type of chain) {\n const storage = createByType(type, options);\n if (storage.isAvailable()) {\n return storage;\n }\n }\n\n return new MemoryQueueStorage();\n}\n\nexport function createQueueStorageFromConfig(config: PixelConfig): IQueueStorage {\n return createQueueStorage({\n preferred: config.storage.queue?.persistence,\n namespace: config.storage.namespace,\n prefix: config.storage.prefix,\n pixelId: config.identity.pixelId,\n });\n}\n\nexport function resolveQueueStorageAdapterName(\n preferred?: QueueStoragePersistence\n): string {\n const chain = resolveFallbackChain(preferred);\n\n for (const type of chain) {\n const storage = createByType(type, {\n preferred: type,\n namespace: 'probe',\n pixelId: 'probe',\n });\n if (storage.isAvailable()) {\n return storage.getAdapterName();\n }\n }\n\n return 'MemoryQueueStorage';\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { PersistentQueue } from '../queue/PersistentQueue';\n\nexport type ReplayTrigger = 'init' | 'reload' | 'reconnect' | 'restart' | 'manual';\n\nexport type ReplayConfig = {\n readonly enabled: boolean;\n};\n\nexport type ReplayDebugState = {\n readonly enabled: boolean;\n readonly lastTrigger: ReplayTrigger | null;\n readonly lastReplayAt: number | null;\n readonly totalReplayed: number;\n readonly pendingCount: number;\n};\n\nexport class ReplayManager {\n private readonly config: ReplayConfig;\n\n private readonly queue: PersistentQueue;\n\n private lastTrigger: ReplayTrigger | null = null;\n\n private lastReplayAt: number | null = null;\n\n private totalReplayed = 0;\n\n private onReplay: (() => void) | null = null;\n\n constructor(config: ReplayConfig, queue: PersistentQueue) {\n this.config = config;\n this.queue = queue;\n }\n\n setReplayHandler(handler: () => void): void {\n this.onReplay = handler;\n }\n\n async replay(trigger: ReplayTrigger): Promise<number> {\n if (!this.config.enabled) return 0;\n\n await this.queue.reload();\n const count = this.queue.size();\n\n this.lastTrigger = trigger;\n this.lastReplayAt = Date.now();\n this.totalReplayed += count;\n\n if (count > 0) {\n this.onReplay?.();\n }\n\n return count;\n }\n\n getPendingEvents(): readonly PixelEvent[] {\n return this.queue.getAll();\n }\n\n getDebugState(): ReplayDebugState {\n return {\n enabled: this.config.enabled,\n lastTrigger: this.lastTrigger,\n lastReplayAt: this.lastReplayAt,\n totalReplayed: this.totalReplayed,\n pendingCount: this.queue.size(),\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nexport type BackpressurePolicy =\n | 'drop_oldest'\n | 'drop_newest'\n | 'reject_new'\n | 'sample'\n | 'none';\n\nexport type BackpressureConfig = {\n readonly enabled: boolean;\n readonly maxQueueSize: number;\n readonly policy: BackpressurePolicy;\n readonly sampleRate?: number;\n};\n\nexport type BackpressureDecision = {\n readonly accepted: boolean;\n readonly dropped: number;\n readonly policy: BackpressurePolicy;\n readonly reason?: string;\n};\n\nexport type BackpressureDebugState = {\n readonly enabled: boolean;\n readonly currentSize: number;\n readonly maxQueueSize: number;\n readonly policy: BackpressurePolicy;\n readonly totalDropped: number;\n readonly totalRejected: number;\n readonly totalSampled: number;\n};\n\nexport class BackpressureManager {\n private readonly config: BackpressureConfig;\n\n private totalDropped = 0;\n\n private totalRejected = 0;\n\n private totalSampled = 0;\n\n constructor(config: BackpressureConfig) {\n this.config = config;\n }\n\n evaluateEnqueue(currentSize: number): BackpressureDecision {\n if (!this.config.enabled || this.config.policy === 'none') {\n return { accepted: true, dropped: 0, policy: this.config.policy };\n }\n\n if (currentSize < this.config.maxQueueSize) {\n return { accepted: true, dropped: 0, policy: this.config.policy };\n }\n\n switch (this.config.policy) {\n case 'reject_new':\n this.totalRejected += 1;\n return {\n accepted: false,\n dropped: 0,\n policy: this.config.policy,\n reason: 'queue_full_reject_new',\n };\n case 'sample': {\n const rate = this.config.sampleRate ?? 0.5;\n const accept = Math.random() < rate;\n if (!accept) this.totalSampled += 1;\n return {\n accepted: accept,\n dropped: accept ? 0 : 1,\n policy: this.config.policy,\n reason: accept ? undefined : 'sampled_out',\n };\n }\n case 'drop_oldest':\n case 'drop_newest':\n return { accepted: true, dropped: 1, policy: this.config.policy };\n default:\n return { accepted: true, dropped: 0, policy: 'none' };\n }\n }\n\n applyPolicy<T>(items: T[], incoming: T): { items: T[]; dropped: number } {\n const decision = this.evaluateEnqueue(items.length);\n\n if (!decision.accepted) {\n return { items, dropped: decision.dropped };\n }\n\n if (items.length < this.config.maxQueueSize) {\n return { items: [...items, incoming], dropped: 0 };\n }\n\n if (this.config.policy === 'drop_oldest') {\n this.totalDropped += 1;\n return { items: [...items.slice(1), incoming], dropped: 1 };\n }\n\n if (this.config.policy === 'drop_newest') {\n this.totalDropped += 1;\n return { items, dropped: 1 };\n }\n\n return { items: [...items, incoming], dropped: 0 };\n }\n\n getDebugState(currentSize: number): BackpressureDebugState {\n return {\n enabled: this.config.enabled,\n currentSize,\n maxQueueSize: this.config.maxQueueSize,\n policy: this.config.policy,\n totalDropped: this.totalDropped,\n totalRejected: this.totalRejected,\n totalSampled: this.totalSampled,\n };\n }\n}\n\nexport type { PixelEvent };\n","export type CircuitBreakerState = 'closed' | 'open' | 'half_open';\n\nexport type CircuitBreakerConfig = {\n readonly enabled: boolean;\n readonly failureThreshold: number;\n readonly resetTimeoutMs: number;\n readonly halfOpenMaxAttempts: number;\n};\n\nexport type CircuitBreakerMetrics = {\n readonly state: CircuitBreakerState;\n readonly consecutiveFailures: number;\n readonly totalFailures: number;\n readonly totalSuccesses: number;\n readonly totalBlocked: number;\n readonly lastFailureAt: number | null;\n readonly lastSuccessAt: number | null;\n readonly openedAt: number | null;\n};\n\nexport class CircuitBreaker {\n private readonly config: CircuitBreakerConfig;\n\n private state: CircuitBreakerState = 'closed';\n\n private consecutiveFailures = 0;\n\n private totalFailures = 0;\n\n private totalSuccesses = 0;\n\n private totalBlocked = 0;\n\n private halfOpenAttempts = 0;\n\n private lastFailureAt: number | null = null;\n\n private lastSuccessAt: number | null = null;\n\n private openedAt: number | null = null;\n\n constructor(config: CircuitBreakerConfig) {\n this.config = config;\n }\n\n canExecute(): boolean {\n if (!this.config.enabled) return true;\n\n if (this.state === 'closed') return true;\n\n if (this.state === 'open') {\n if (\n this.openedAt !== null &&\n Date.now() - this.openedAt >= this.config.resetTimeoutMs\n ) {\n this.state = 'half_open';\n this.halfOpenAttempts = 0;\n return true;\n }\n\n this.totalBlocked += 1;\n return false;\n }\n\n return this.halfOpenAttempts < this.config.halfOpenMaxAttempts;\n }\n\n recordSuccess(): void {\n if (!this.config.enabled) return;\n\n this.totalSuccesses += 1;\n this.lastSuccessAt = Date.now();\n this.consecutiveFailures = 0;\n this.halfOpenAttempts = 0;\n this.state = 'closed';\n this.openedAt = null;\n }\n\n recordFailure(): void {\n if (!this.config.enabled) return;\n\n this.totalFailures += 1;\n this.lastFailureAt = Date.now();\n this.consecutiveFailures += 1;\n\n if (this.state === 'half_open') {\n this.halfOpenAttempts += 1;\n if (this.halfOpenAttempts >= this.config.halfOpenMaxAttempts) {\n this.open();\n }\n return;\n }\n\n if (this.consecutiveFailures >= this.config.failureThreshold) {\n this.open();\n }\n }\n\n forceOpen(): void {\n this.open();\n }\n\n forceClose(): void {\n this.state = 'closed';\n this.consecutiveFailures = 0;\n this.halfOpenAttempts = 0;\n this.openedAt = null;\n }\n\n getMetrics(): CircuitBreakerMetrics {\n return {\n state: this.state,\n consecutiveFailures: this.consecutiveFailures,\n totalFailures: this.totalFailures,\n totalSuccesses: this.totalSuccesses,\n totalBlocked: this.totalBlocked,\n lastFailureAt: this.lastFailureAt,\n lastSuccessAt: this.lastSuccessAt,\n openedAt: this.openedAt,\n };\n }\n\n private open(): void {\n this.state = 'open';\n this.openedAt = Date.now();\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { EventSender, SendOptions, SendResult } from '../sender/types';\nimport type { CircuitBreaker } from './CircuitBreaker';\n\nexport class CircuitBreakerSender implements EventSender {\n private readonly circuitBreaker: CircuitBreaker;\n\n private readonly inner: EventSender;\n\n constructor(circuitBreaker: CircuitBreaker, inner: EventSender) {\n this.circuitBreaker = circuitBreaker;\n this.inner = inner;\n }\n\n async send(events: PixelEvent[], options?: SendOptions): Promise<SendResult> {\n if (!this.circuitBreaker.canExecute()) {\n throw new Error('[CircuitBreakerSender] Circuit is open — send blocked');\n }\n\n try {\n const result = await this.inner.send(events, options);\n if (result.ack) {\n this.circuitBreaker.recordSuccess();\n } else {\n this.circuitBreaker.recordFailure();\n }\n return result;\n } catch (error) {\n this.circuitBreaker.recordFailure();\n throw error;\n }\n }\n\n getCircuitBreaker(): CircuitBreaker {\n return this.circuitBreaker;\n }\n}\n","export type RetryConfig = {\n readonly maxAttempts: number;\n readonly baseDelayMs: number;\n readonly maxDelayMs: number;\n readonly multiplier: number;\n};\n\nexport type RetryTask = () => Promise<void>;\n\nexport type RetryAttemptState = {\n readonly id: string;\n readonly attempt: number;\n readonly nextRetryAt: number | null;\n readonly status: 'pending' | 'running' | 'scheduled' | 'completed' | 'failed' | 'cancelled';\n};\n\nexport type RetryDebugState = {\n readonly pendingCount: number;\n readonly attempts: readonly RetryAttemptState[];\n};\n\nexport interface IRetryEngine {\n retry(task: RetryTask, taskId?: string): Promise<void>;\n\n cancel(taskId: string): void;\n\n cancelAll(): void;\n\n getState(): RetryDebugState;\n}\n\nexport function calculateBackoffDelay(\n attempt: number,\n config: RetryConfig\n): number {\n const delay = config.baseDelayMs * config.multiplier ** (attempt - 1);\n return Math.min(delay, config.maxDelayMs);\n}\n","import type { PixelLogger } from '@/logger';\n\nimport { calculateBackoffDelay } from './types';\nimport type {\n IRetryEngine,\n RetryAttemptState,\n RetryConfig,\n RetryDebugState,\n RetryTask,\n} from './types';\n\ntype InternalRetryEntry = {\n readonly id: string;\n task: RetryTask;\n attempt: number;\n status: RetryAttemptState['status'];\n nextRetryAt: number | null;\n timer: ReturnType<typeof setTimeout> | null;\n abort: () => void;\n};\n\nexport class RetryEngine implements IRetryEngine {\n private readonly config: RetryConfig;\n\n private readonly logger: PixelLogger;\n\n private readonly entries = new Map<string, InternalRetryEntry>();\n\n private idCounter = 0;\n\n constructor(config: RetryConfig, logger: PixelLogger) {\n this.config = config;\n this.logger = logger;\n }\n\n async retry(task: RetryTask, taskId?: string): Promise<void> {\n const id = taskId ?? `retry-${++this.idCounter}`;\n\n return new Promise<void>((resolve, reject) => {\n let cancelled = false;\n\n const entry: InternalRetryEntry = {\n id,\n task,\n attempt: 0,\n status: 'pending',\n nextRetryAt: null,\n timer: null,\n abort: () => {\n cancelled = true;\n if (entry.timer) clearTimeout(entry.timer);\n entry.status = 'cancelled';\n entry.timer = null;\n this.entries.delete(id);\n resolve();\n },\n };\n\n this.entries.set(id, entry);\n\n const runAttempt = async (): Promise<void> => {\n if (cancelled) return;\n\n entry.attempt += 1;\n entry.status = 'running';\n entry.nextRetryAt = null;\n\n try {\n await task();\n entry.status = 'completed';\n this.entries.delete(id);\n resolve();\n } catch (error) {\n if (cancelled) return;\n\n if (entry.attempt >= this.config.maxAttempts) {\n entry.status = 'failed';\n this.entries.delete(id);\n reject(error);\n return;\n }\n\n const delay = calculateBackoffDelay(entry.attempt, this.config);\n entry.status = 'scheduled';\n entry.nextRetryAt = Date.now() + delay;\n\n this.logger.debug(\n `[RetryEngine] Attempt ${entry.attempt} failed, retry in ${delay}ms`\n );\n\n entry.timer = setTimeout(() => {\n entry.timer = null;\n void runAttempt();\n }, delay);\n }\n };\n\n void runAttempt();\n });\n }\n\n cancel(taskId: string): void {\n this.entries.get(taskId)?.abort();\n }\n\n cancelAll(): void {\n for (const entry of this.entries.values()) {\n entry.abort();\n }\n this.entries.clear();\n }\n\n getState(): RetryDebugState {\n return {\n pendingCount: this.entries.size,\n attempts: Array.from(this.entries.values()).map(entry => ({\n id: entry.id,\n attempt: entry.attempt,\n nextRetryAt: entry.nextRetryAt,\n status: entry.status,\n })),\n };\n }\n}\n","import type { PixelConfig } from '@/config';\nimport type { PixelEvent } from '@/events';\nimport type { AttributionIdentifiers } from '@/services/attribution/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport type {\n ApiBatchEventRequest,\n ApiEvent,\n ApiEventCategory,\n ApiEventIdentifiers,\n} from './api-types';\n\nfunction generateEventId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return `evt_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction mapCategory(event: PixelEvent): ApiEventCategory {\n if ('category' in event && event.category) {\n if (event.category === 'ENGAGEMENT') return 'ENGAGEMENT';\n if (event.category === 'CONVERSION') return 'CONVERSION';\n }\n return 'OTHER';\n}\n\nfunction extractData(event: PixelEvent): Record<string, unknown> | undefined {\n if ('data' in event && event.data && typeof event.data === 'object') {\n return event.data as Record<string, unknown>;\n }\n\n const {\n type,\n timestamp,\n category,\n path,\n url,\n hostname,\n language,\n timezone,\n identifiers,\n ...rest\n } = event as unknown as Record<string, unknown>;\n\n void type;\n void timestamp;\n void category;\n void path;\n void url;\n void hostname;\n void language;\n void timezone;\n void identifiers;\n\n const keys = Object.keys(rest);\n if (keys.length === 0) return undefined;\n\n return rest;\n}\n\nfunction mapIdentifiers(\n identifiers: AttributionIdentifiers | undefined\n): ApiEventIdentifiers {\n const base = {\n fbp: identifiers?.fbp ?? '',\n fbc: identifiers?.fbc ?? '',\n ga: identifiers?.ga ?? '',\n gcl_au: identifiers?.gclAu ?? '',\n };\n\n if (!identifiers) return base;\n\n return {\n ...base,\n fbclid: identifiers.fbclid ?? '',\n gclid: identifiers.gclid ?? '',\n gbraid: identifiers.gbraid ?? '',\n wbraid: identifiers.wbraid ?? '',\n gid: identifiers.gid ?? '',\n ttclid: identifiers.ttclid ?? '',\n ttp: identifiers.ttp ?? '',\n msclkid: identifiers.msclkid ?? '',\n li_fat_id: identifiers.liFatId ?? '',\n epik: identifiers.epik ?? '',\n customClickIds: identifiers.customClickIds ?? {},\n landingUrl: identifiers.landingUrl ?? '',\n referrer: identifiers.referrer ?? '',\n firstCollectedAt: identifiers.firstCollectedAt ?? 0,\n lastCollectedAt: identifiers.lastCollectedAt ?? 0,\n };\n}\n\nexport class EventPayloadBuilder {\n private readonly context: PixelRuntimeContext;\n\n constructor(context: PixelRuntimeContext) {\n this.context = context;\n }\n\n buildApiEvent(event: PixelEvent, eventId?: string): ApiEvent {\n const config = this.context.config;\n const services = this.context.services;\n const metadata = services.browserMetadata.getMetadata();\n\n const visitorId =\n services.visitor.getVisitorId() ?? services.visitor.ensureVisitorId();\n\n const sessionId =\n services.session.getSessionId() ??\n `session_${config.identity.pixelId || 'anonymous'}_${Date.now()}`;\n\n const fingerprint =\n services.fingerprint.getFingerprint() ??\n services.fingerprint.ensureFingerprint();\n\n const identifiers =\n 'identifiers' in event && event.identifiers\n ? event.identifiers\n : services.attribution?.getSnapshot();\n\n return {\n id: eventId ?? generateEventId(),\n session_id: sessionId,\n visitor_id: visitorId,\n pixel_code: config.identity.pixelId,\n type: event.type as ApiEvent['type'],\n category: mapCategory(event),\n timestamp: String(event.timestamp ?? Date.now()),\n fingerprint,\n identifiers: mapIdentifiers(identifiers),\n page: {\n url: event.url ?? metadata.url ?? '',\n title: typeof document !== 'undefined' ? document.title : '',\n referrer: typeof document !== 'undefined' ? document.referrer : '',\n path: event.path ?? metadata.path ?? '',\n hostname: event.hostname ?? metadata.hostname ?? '',\n },\n device: {\n id: fingerprint,\n type: 'desktop',\n os: { name: 'Unknown', version: '' },\n browser: { name: 'Unknown', version: '' },\n engine: { name: 'Unknown', version: '' },\n userAgent: metadata.userAgent ?? '',\n language: event.language ?? metadata.language ?? '',\n screen: {\n width: metadata.screenWidth ?? 0,\n height: metadata.screenHeight ?? 0,\n pixel_ratio: 1,\n },\n },\n data: extractData(event),\n meta: {\n version: '2.0.0',\n pixel_source: 'pixel-v2',\n environment: config.app.environment,\n script_url:\n typeof document !== 'undefined' && document.currentScript\n ? String((document.currentScript as HTMLScriptElement).src ?? '')\n : '',\n projectId: '',\n pageId: '',\n },\n };\n }\n\n buildBatchPayload(events: PixelEvent[]): ApiBatchEventRequest {\n const first = this.buildApiEvent(events[0] ?? ({} as PixelEvent));\n const apiEvents = events.map(event => this.buildApiEvent(event));\n\n return {\n pixel_code: this.context.config.identity.pixelId,\n visitor_id: first.visitor_id,\n session_id: first.session_id,\n batch_id: generateEventId(),\n sent_at: Date.now(),\n meta: first.meta,\n events: apiEvents,\n };\n }\n}\n\nexport type { PixelConfig };\n","/** fetch com AbortController e timeout configurável. */\n\nexport interface FetchWithTimeoutOptions extends RequestInit {\n timeoutMs?: number;\n}\n\nexport async function fetchWithTimeout(\n url: string,\n options: FetchWithTimeoutOptions = {}\n): Promise<Response> {\n const { timeoutMs = 10_000, signal: externalSignal, ...init } = options;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n if (externalSignal) {\n if (externalSignal.aborted) controller.abort();\n else\n externalSignal.addEventListener('abort', () => controller.abort(), {\n once: true,\n });\n }\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeoutId);\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelLogger } from '@/logger';\nimport { fetchWithTimeout } from '../network/fetchWithTimeout';\n\nimport type { CompressionStrategy } from '../compression/types';\nimport type { EventPayloadBuilder } from './EventPayloadBuilder';\nimport type { EventSender, SendOptions, SenderDebugState } from './types';\n\nconst SINGLE_ENDPOINT = '/pixels/public/event';\nconst BATCH_ENDPOINT = '/pixels/public/event/batch';\n\nexport type HttpSenderConfig = {\n readonly apiEndpoint: string;\n readonly timeoutMs: number;\n};\n\nexport type HttpSenderResponseLog = {\n readonly at: number;\n readonly url: string;\n readonly status: number;\n readonly ack: boolean;\n readonly eventCount: number;\n readonly body?: unknown;\n readonly error?: string;\n};\n\nexport class HttpSender implements EventSender {\n private readonly config: HttpSenderConfig;\n\n private readonly payloadBuilder: EventPayloadBuilder;\n\n private readonly compression: CompressionStrategy;\n\n private readonly logger: PixelLogger;\n\n private sentCount = 0;\n\n private lastAck: boolean | null = null;\n\n private readonly responseLogs: HttpSenderResponseLog[] = [];\n\n private lastCompression:\n | { originalSize: number; compressedSize: number }\n | null = null;\n\n constructor(\n config: HttpSenderConfig,\n payloadBuilder: EventPayloadBuilder,\n compression: CompressionStrategy,\n logger: PixelLogger\n ) {\n this.config = config;\n this.payloadBuilder = payloadBuilder;\n this.compression = compression;\n this.logger = logger;\n }\n\n async send(events: PixelEvent[], options?: SendOptions): Promise<{ ack: boolean; eventCount: number }> {\n if (events.length === 0) {\n return { ack: true, eventCount: 0 };\n }\n\n if (options?.signal?.aborted) {\n throw new DOMException('The operation was aborted.', 'AbortError');\n }\n\n const useBatch = events.length > 1;\n const url = `${this.config.apiEndpoint.replace(/\\/$/, '')}${useBatch ? BATCH_ENDPOINT : SINGLE_ENDPOINT}`;\n\n const rawBody = useBatch\n ? JSON.stringify(this.payloadBuilder.buildBatchPayload(events))\n : JSON.stringify(this.payloadBuilder.buildApiEvent(events[0]!));\n\n const compressed = this.compression.compress(rawBody);\n this.lastCompression = {\n originalSize: compressed.originalSize,\n compressedSize: compressed.compressedSize,\n };\n\n try {\n const response = await fetchWithTimeout(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Encoding': compressed.encoding,\n },\n body: compressed.body,\n keepalive: true,\n timeoutMs: this.config.timeoutMs,\n signal: options?.signal,\n });\n\n const body = await response.json().catch(() => ({}));\n\n const ack = response.ok;\n this.lastAck = ack;\n\n if (ack) {\n this.sentCount += events.length;\n }\n\n this.responseLogs.push({\n at: Date.now(),\n url,\n status: response.status,\n ack,\n eventCount: events.length,\n body,\n });\n\n if (!ack) {\n throw new Error(`[HttpSender] HTTP ${response.status}`);\n }\n\n this.logger.debug(`[HttpSender] Sent ${events.length} event(s) — ACK`);\n\n return { ack: true, eventCount: events.length };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.lastAck = false;\n\n this.responseLogs.push({\n at: Date.now(),\n url,\n status: 0,\n ack: false,\n eventCount: events.length,\n error: message,\n });\n\n throw error;\n }\n }\n\n getState(): SenderDebugState & {\n responses: readonly HttpSenderResponseLog[];\n compression: { originalSize: number; compressedSize: number } | null;\n mode: 'http';\n } {\n return {\n sentCount: this.sentCount,\n logs: this.responseLogs.map(\n log =>\n `[HttpSender] ${log.status} ack=${log.ack} events=${log.eventCount}${log.error ? ` err=${log.error}` : ''}`\n ),\n lastAck: this.lastAck,\n responses: [...this.responseLogs],\n compression: this.lastCompression,\n mode: 'http',\n };\n }\n\n clear(): void {\n this.sentCount = 0;\n this.lastAck = null;\n this.responseLogs.length = 0;\n this.lastCompression = null;\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelLogger } from '@/logger';\n\nimport type { EventSender, SendOptions, SenderDebugState } from './types';\n\nexport type MockSenderOptions = {\n readonly delayMs?: number;\n readonly failUntilAttempt?: number;\n readonly simulateTimeout?: boolean;\n};\n\nexport class MockSender implements EventSender {\n private readonly logger: PixelLogger;\n\n private readonly options: MockSenderOptions;\n\n private readonly sentBatches: PixelEvent[][] = [];\n\n private sendAttempts = 0;\n\n private lastAck: boolean | null = null;\n\n constructor(logger: PixelLogger, options: MockSenderOptions = {}) {\n this.logger = logger;\n this.options = options;\n }\n\n async send(events: PixelEvent[], options?: SendOptions): Promise<{ ack: boolean; eventCount: number }> {\n if (events.length === 0) {\n return { ack: true, eventCount: 0 };\n }\n\n if (options?.signal?.aborted) {\n throw new DOMException('The operation was aborted.', 'AbortError');\n }\n\n this.sendAttempts += 1;\n\n if (\n this.options.failUntilAttempt !== undefined &&\n this.sendAttempts < this.options.failUntilAttempt\n ) {\n throw new Error(`[MockSender] Simulated failure (attempt ${this.sendAttempts})`);\n }\n\n if (this.options.simulateTimeout) {\n throw new DOMException('The operation was aborted.', 'AbortError');\n }\n\n await this.waitWithAbort(options?.signal);\n\n this.sentBatches.push([...events]);\n this.lastAck = true;\n this.logger.debug(`[MockSender] Simulated send of ${events.length} event(s)`);\n\n return { ack: true, eventCount: events.length };\n }\n\n getSentBatches(): readonly (readonly PixelEvent[])[] {\n return this.sentBatches.map(batch => [...batch]);\n }\n\n getSentCount(): number {\n return this.sentBatches.reduce((total, batch) => total + batch.length, 0);\n }\n\n getLogs(): readonly string[] {\n return this.sentBatches.map(\n batch => `[MockSender] ${batch.map(event => event.type).join(', ')}`\n );\n }\n\n getState(): SenderDebugState {\n return {\n sentCount: this.getSentCount(),\n logs: this.getLogs(),\n lastAck: this.lastAck,\n };\n }\n\n clear(): void {\n this.sentBatches.length = 0;\n this.sendAttempts = 0;\n this.lastAck = null;\n }\n\n /** @internal Playground — reconfigura comportamento em runtime. */\n configure(options: Partial<MockSenderOptions>): void {\n if (options.delayMs !== undefined) {\n (this.options as { delayMs?: number }).delayMs = options.delayMs;\n }\n if ('failUntilAttempt' in options) {\n (this.options as { failUntilAttempt?: number }).failUntilAttempt = options.failUntilAttempt;\n }\n if (options.simulateTimeout !== undefined) {\n (this.options as { simulateTimeout?: boolean }).simulateTimeout = options.simulateTimeout;\n }\n }\n\n private waitWithAbort(signal?: AbortSignal): Promise<void> {\n const delayMs = this.options.delayMs ?? 0;\n if (delayMs <= 0) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, delayMs);\n\n const onAbort = (): void => {\n cleanup();\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n };\n\n const cleanup = (): void => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n };\n\n if (signal?.aborted) {\n cleanup();\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n return;\n }\n\n signal?.addEventListener('abort', onAbort);\n });\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { EventSender, SendOptions } from './types';\n\nexport type TimedSenderConfig = {\n readonly timeoutMs: number;\n};\n\nexport class TimedSender implements EventSender {\n private readonly inner: EventSender;\n\n private readonly timeoutMs: number;\n\n private abortController: AbortController | null = null;\n\n constructor(inner: EventSender, config: TimedSenderConfig) {\n this.inner = inner;\n this.timeoutMs = config.timeoutMs;\n }\n\n async send(events: PixelEvent[], options?: SendOptions): Promise<{ ack: boolean; eventCount: number }> {\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n const controller = this.abortController;\n const signals = [controller.signal, options?.signal].filter(Boolean) as AbortSignal[];\n\n const combined = combineAbortSignals(signals);\n\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n return await this.inner.send(events, { signal: combined });\n } finally {\n clearTimeout(timeoutId);\n if (this.abortController === controller) {\n this.abortController = null;\n }\n }\n }\n\n abortPending(): void {\n this.abortController?.abort();\n this.abortController = null;\n }\n}\n\nfunction combineAbortSignals(signals: AbortSignal[]): AbortSignal | undefined {\n if (signals.length === 0) return undefined;\n if (signals.length === 1) return signals[0];\n\n const controller = new AbortController();\n\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort();\n return controller.signal;\n }\n signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n return controller.signal;\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { BatchManager } from './batch/BatchManager';\nimport { createCompressionStrategy, getCompressionDebugState } from './compression';\nimport type { CompressionDebugState } from './compression';\nimport { CoordinationManager } from './coordination';\nimport type { CoordinationDebugState } from './coordination';\nimport { DeadLetterManager } from './dead-letter';\nimport type { DeadLetterDebugState } from './dead-letter';\nimport { TransportDelivery } from './delivery/TransportDelivery';\nimport { FlushManager } from './flush/FlushManager';\nimport { OfflineDetector } from './network/OfflineDetector';\nimport { OrderingManager } from './ordering';\nimport type { OrderingDebugState } from './ordering';\nimport { TransportPipeline } from './pipeline/TransportPipeline';\nimport { PersistentQueue } from './queue/PersistentQueue';\nimport type { IEventQueue } from './queue/types';\nimport { MemoryQueue } from './queue/MemoryQueue';\nimport { createQueueStorageFromConfig } from './queue/storage';\nimport { ReplayManager } from './replay';\nimport type { ReplayDebugState } from './replay';\nimport {\n BackpressureManager,\n CircuitBreaker,\n CircuitBreakerSender,\n} from './resilience';\nimport type { BackpressureDebugState, CircuitBreakerMetrics } from './resilience';\nimport { RetryEngine } from './retry/RetryEngine';\nimport { EventPayloadBuilder } from './sender/EventPayloadBuilder';\nimport { HttpSender } from './sender/HttpSender';\nimport { MockSender } from './sender/MockSender';\nimport type { EventSender } from './sender/types';\nimport { TimedSender } from './sender/TimedSender';\n\nexport type TransportAdvancedDebugState = {\n readonly storage: {\n readonly adapter: string;\n readonly persistenceEnabled: boolean;\n readonly recordCount: number;\n };\n readonly replay: ReplayDebugState;\n readonly ordering: OrderingDebugState;\n readonly coordination: CoordinationDebugState;\n readonly circuitBreaker: CircuitBreakerMetrics;\n readonly backpressure: BackpressureDebugState;\n readonly deadLetter: DeadLetterDebugState;\n readonly compression: CompressionDebugState;\n readonly senderMode: 'mock' | 'http';\n};\n\nexport type TransportDebugState = {\n readonly queueSize: number;\n readonly queueContents: readonly PixelEvent[];\n readonly pipelineSteps: readonly string[];\n readonly senderLogs: readonly string[];\n readonly sentCount: number;\n readonly delivery: ReturnType<TransportDelivery['getDebugState']> | null;\n readonly sender: Record<string, unknown> | null;\n readonly advanced: TransportAdvancedDebugState | null;\n};\n\nexport class TransportEngine {\n private readonly context: PixelRuntimeContext;\n\n private readonly queue: IEventQueue;\n\n private readonly persistentQueue: PersistentQueue | null;\n\n private readonly pipeline: TransportPipeline;\n\n private readonly mockSender: MockSender | null;\n\n private readonly httpSender: HttpSender | null;\n\n private readonly delivery: TransportDelivery | null;\n\n private readonly timedSender: TimedSender | null;\n\n private readonly replayManager: ReplayManager | null;\n\n private readonly orderingManager: OrderingManager;\n\n private readonly coordinationManager: CoordinationManager;\n\n private readonly circuitBreaker: CircuitBreaker;\n\n private readonly backpressureManager: BackpressureManager;\n\n private readonly deadLetterManager: DeadLetterManager;\n\n private readonly senderMode: 'mock' | 'http';\n\n private active = false;\n\n constructor(\n context: PixelRuntimeContext,\n queue?: IEventQueue,\n sender?: EventSender\n ) {\n this.context = context;\n const moduleConfig = context.config.modules.transport;\n\n this.orderingManager = new OrderingManager({\n enabled: moduleConfig.ordering.enabled,\n });\n\n this.backpressureManager = new BackpressureManager({\n enabled: moduleConfig.backpressure.enabled,\n maxQueueSize: moduleConfig.backpressure.maxQueueSize,\n policy: moduleConfig.backpressure.policy,\n sampleRate: moduleConfig.backpressure.sampleRate,\n });\n\n this.deadLetterManager = new DeadLetterManager({\n enabled: moduleConfig.deadLetter.enabled,\n maxEntries: moduleConfig.deadLetter.maxEntries,\n });\n\n this.circuitBreaker = new CircuitBreaker({\n enabled: moduleConfig.circuitBreaker.enabled,\n failureThreshold: moduleConfig.circuitBreaker.failureThreshold,\n resetTimeoutMs: moduleConfig.circuitBreaker.resetTimeoutMs,\n halfOpenMaxAttempts: moduleConfig.circuitBreaker.halfOpenMaxAttempts,\n });\n\n this.coordinationManager = new CoordinationManager(\n { enabled: moduleConfig.coordination.enabled },\n context.config.identity.pixelId || 'pixel'\n );\n\n if (queue) {\n this.queue = queue;\n this.persistentQueue = null;\n } else if (moduleConfig.persistence.enabled) {\n const storage = createQueueStorageFromConfig(context.config);\n this.persistentQueue = new PersistentQueue(\n storage,\n this.orderingManager,\n this.backpressureManager\n );\n this.queue = this.persistentQueue;\n } else {\n this.persistentQueue = null;\n this.queue = new MemoryQueue();\n }\n\n this.pipeline = TransportPipeline.createDefault(this.queue);\n\n const compression = createCompressionStrategy(moduleConfig.compression);\n const payloadBuilder = new EventPayloadBuilder(context);\n\n const useHttp =\n sender === undefined &&\n (moduleConfig.sender?.mode === 'http' ||\n (!moduleConfig.mockSender.enabled && moduleConfig.sender?.mode !== 'mock'));\n\n this.senderMode = sender instanceof HttpSender || useHttp ? 'http' : 'mock';\n\n const mockSender =\n sender instanceof MockSender\n ? sender\n : new MockSender(context.logger);\n this.mockSender = sender instanceof MockSender || !sender ? mockSender : null;\n\n this.httpSender =\n sender instanceof HttpSender\n ? sender\n : useHttp\n ? new HttpSender(\n {\n apiEndpoint: context.config.transport.apiEndpoint,\n timeoutMs: moduleConfig.timeout.timeoutMs,\n },\n payloadBuilder,\n compression,\n context.logger\n )\n : null;\n\n let eventSender: EventSender = sender ?? this.httpSender ?? mockSender;\n\n if (moduleConfig.circuitBreaker.enabled) {\n eventSender = new CircuitBreakerSender(this.circuitBreaker, eventSender);\n }\n\n let timedSender: TimedSender | null = null;\n\n if (moduleConfig.timeout.enabled) {\n timedSender = new TimedSender(eventSender, {\n timeoutMs: moduleConfig.timeout.timeoutMs,\n });\n eventSender = timedSender;\n }\n\n this.timedSender = timedSender;\n\n if (this.persistentQueue) {\n this.replayManager = new ReplayManager(\n { enabled: moduleConfig.replay.enabled },\n this.persistentQueue\n );\n this.replayManager.setReplayHandler(() => this.forwardQueuedEvents());\n } else {\n this.replayManager = null;\n }\n\n if (\n moduleConfig.retry.enabled ||\n moduleConfig.batch.enabled ||\n moduleConfig.offline.enabled ||\n moduleConfig.flush.enabled\n ) {\n const batchManager = new BatchManager();\n const flushManager = new FlushManager({\n flushIntervalMs: moduleConfig.flush.enabled\n ? moduleConfig.flush.flushIntervalMs\n : 0,\n flushOnDestroy: moduleConfig.flush.flushOnDestroy,\n prepareUnloadHooks: moduleConfig.flush.prepareUnloadHooks,\n });\n const retryEngine = new RetryEngine(\n {\n maxAttempts: moduleConfig.retry.maxAttempts,\n baseDelayMs: moduleConfig.retry.baseDelayMs,\n maxDelayMs: moduleConfig.retry.maxDelayMs,\n multiplier: moduleConfig.retry.multiplier,\n },\n context.logger\n );\n const offlineDetector = new OfflineDetector();\n\n this.delivery = new TransportDelivery({\n batchManager,\n flushManager,\n retryEngine,\n offlineDetector,\n sender: eventSender,\n config: {\n batch: {\n batchSize: moduleConfig.batch.batchSize,\n flushIntervalMs: moduleConfig.batch.flushIntervalMs,\n maxWaitMs: moduleConfig.batch.maxWaitMs,\n },\n timeoutMs: moduleConfig.timeout.timeoutMs,\n },\n logger: context.logger,\n abortPending: () => timedSender?.abortPending(),\n onPermanentFailure: moduleConfig.deadLetter.enabled\n ? (events, error) => {\n this.deadLetterManager.move(\n events,\n 'max_retries_exceeded',\n moduleConfig.retry.maxAttempts,\n error instanceof Error ? error.message : String(error)\n );\n }\n : undefined,\n });\n } else {\n this.delivery = null;\n }\n }\n\n async init(): Promise<void> {\n if (this.active) return;\n\n if (this.persistentQueue) {\n await this.persistentQueue.init();\n }\n\n this.coordinationManager.init(isLeader => {\n if (isLeader) {\n void this.replayManager?.replay('reconnect');\n this.forwardQueuedEvents();\n }\n });\n\n this.delivery?.init();\n\n if (this.replayManager) {\n await this.replayManager.replay('init');\n }\n\n this.active = true;\n this.context.logger.debug('[TransportEngine] Initialized');\n }\n\n destroy(): void {\n if (!this.active) return;\n\n this.timedSender?.abortPending();\n this.delivery?.destroy();\n this.coordinationManager.destroy();\n\n if (this.persistentQueue) {\n this.persistentQueue.destroy();\n } else {\n this.queue.clear();\n }\n\n this.mockSender?.clear();\n this.httpSender?.clear();\n this.active = false;\n this.context.logger.debug('[TransportEngine] Destroyed');\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n handleEvent(event: PixelEvent): void {\n if (!this.active) return;\n\n const result = this.pipeline.process(event);\n if (!result.event) {\n this.context.logger.debug('[TransportEngine] Event dropped by pipeline');\n return;\n }\n\n if (this.coordinationManager.shouldPersistOnly()) {\n return;\n }\n\n this.forwardQueuedEvents();\n }\n\n manualFlush(): void {\n this.delivery?.flush();\n }\n\n simulateOffline(offline: boolean): void {\n this.delivery?.getOfflineDetector().simulateOffline(offline);\n if (!offline) {\n void this.replayManager?.replay('reconnect');\n this.forwardQueuedEvents();\n }\n }\n\n configureMockSender(options: Parameters<MockSender['configure']>[0]): void {\n this.mockSender?.configure(options);\n }\n\n async simulateReload(): Promise<void> {\n await this.replayManager?.replay('reload');\n this.forwardQueuedEvents();\n }\n\n async simulateRestart(): Promise<void> {\n await this.replayManager?.replay('restart');\n this.forwardQueuedEvents();\n }\n\n forceCircuitOpen(): void {\n this.circuitBreaker.forceOpen();\n }\n\n forceCircuitClose(): void {\n this.circuitBreaker.forceClose();\n }\n\n async manualReplay(): Promise<number> {\n const count = (await this.replayManager?.replay('manual')) ?? 0;\n this.forwardQueuedEvents();\n return count;\n }\n\n replayDeadLetter(): PixelEvent[] {\n const events = this.deadLetterManager.replayAll();\n if (events.length > 0) {\n for (const event of events) {\n this.queue.enqueue(event);\n }\n this.forwardQueuedEvents();\n }\n return events;\n }\n\n clearDeadLetter(): void {\n this.deadLetterManager.clear();\n }\n\n exportQueue(): string {\n if (this.persistentQueue) {\n return JSON.stringify(this.persistentQueue.exportRecords(), null, 2);\n }\n return JSON.stringify(this.queue.getAll(), null, 2);\n }\n\n importQueue(raw: string): number {\n const parsed = JSON.parse(raw) as unknown;\n\n if (this.persistentQueue && Array.isArray(parsed) && parsed[0]?.event) {\n this.persistentQueue.importRecords(parsed);\n return parsed.length;\n }\n\n if (Array.isArray(parsed)) {\n this.queue.clear();\n for (const event of parsed as PixelEvent[]) {\n this.queue.enqueue(event);\n }\n return parsed.length;\n }\n\n return 0;\n }\n\n getQueue(): IEventQueue {\n return this.queue;\n }\n\n getPipelineSteps(): readonly string[] {\n return this.pipeline.getLastSteps();\n }\n\n getDebugState(): TransportDebugState {\n const senderState = this.httpSender?.getState() ?? this.mockSender?.getState() ?? null;\n\n return {\n queueSize: this.queue.size(),\n queueContents: this.queue.getAll(),\n pipelineSteps: this.pipeline.getLastSteps(),\n senderLogs: senderState?.logs ?? [],\n sentCount: senderState?.sentCount ?? 0,\n delivery: this.delivery?.getDebugState() ?? null,\n sender: senderState as Record<string, unknown> | null,\n advanced: {\n storage: {\n adapter: this.persistentQueue?.getStorageAdapterName() ?? 'MemoryQueue',\n persistenceEnabled: this.persistentQueue !== null,\n recordCount: this.persistentQueue?.getRecords().length ?? this.queue.size(),\n },\n replay: this.replayManager?.getDebugState() ?? {\n enabled: false,\n lastTrigger: null,\n lastReplayAt: null,\n totalReplayed: 0,\n pendingCount: 0,\n },\n ordering: this.orderingManager.getDebugState(this.queue.size()),\n coordination: this.coordinationManager.getDebugState(),\n circuitBreaker: this.circuitBreaker.getMetrics(),\n backpressure: this.backpressureManager.getDebugState(this.queue.size()),\n deadLetter: this.deadLetterManager.getDebugState(),\n compression: getCompressionDebugState(\n this.context.config.modules.transport.compression,\n createCompressionStrategy(this.context.config.modules.transport.compression),\n this.httpSender?.getState().compression ?? null\n ),\n senderMode: this.senderMode,\n },\n };\n }\n\n private forwardQueuedEvents(): void {\n if (!this.coordinationManager.canSend()) return;\n\n const events: PixelEvent[] = [];\n\n while (!this.queue.isEmpty()) {\n const event = this.queue.dequeue();\n if (event) events.push(event);\n }\n\n if (events.length === 0) return;\n\n if (this.delivery) {\n this.delivery.ingest(events);\n return;\n }\n\n const sender = this.httpSender ?? this.mockSender;\n void sender?.send(events).catch(error => {\n for (const event of events) {\n this.queue.enqueue(event);\n }\n this.context.logger.error('[TransportEngine] Direct send failed', error);\n });\n }\n}\n","import type { PixelEvent } from '@/events';\nimport type { PixelModule } from '@/runtime/types';\nimport type { PixelRuntimeContext } from '@/runtime/PixelRuntimeContext';\n\nimport { DispatcherSubscriber } from './subscriber/DispatcherSubscriber';\nimport type { TransportDebugState } from './transport.engine';\nimport { TransportEngine } from './transport.engine';\nimport type { MockSender } from './sender/MockSender';\n\nexport class TransportModule implements PixelModule {\n readonly name = 'transport' as const;\n\n private engine: TransportEngine | null = null;\n\n private subscriber: DispatcherSubscriber | null = null;\n\n private active = false;\n\n async init(context: PixelRuntimeContext): Promise<void> {\n if (this.active) {\n context.logger.debug('[Pixel] Transport module already initialized');\n return;\n }\n\n if (!context.config.modules.transport.enabled) {\n context.logger.debug('[Pixel] Transport module disabled');\n return;\n }\n\n context.logger.debug('[Pixel] Transport module initialized');\n\n this.engine = new TransportEngine(context);\n await this.engine.init();\n\n this.subscriber = new DispatcherSubscriber(\n context.services.dispatcher,\n event => this.engine?.handleEvent(event)\n );\n this.subscriber.subscribe();\n\n this.active = true;\n }\n\n async destroy(): Promise<void> {\n if (!this.active) return;\n\n this.subscriber?.unsubscribeAll();\n this.subscriber = null;\n\n this.engine?.destroy();\n this.engine = null;\n\n this.active = false;\n }\n\n getDebugState(): TransportDebugState | null {\n return this.engine?.getDebugState() ?? null;\n }\n\n isEngineActive(): boolean {\n return this.engine?.isActive() ?? false;\n }\n\n manualFlush(): void {\n this.engine?.manualFlush();\n }\n\n simulateOffline(offline: boolean): void {\n this.engine?.simulateOffline(offline);\n }\n\n configureMockSender(options: Parameters<MockSender['configure']>[0]): void {\n this.engine?.configureMockSender(options);\n }\n\n simulateReload(): Promise<void> {\n return this.engine?.simulateReload() ?? Promise.resolve();\n }\n\n simulateRestart(): Promise<void> {\n return this.engine?.simulateRestart() ?? Promise.resolve();\n }\n\n forceCircuitOpen(): void {\n this.engine?.forceCircuitOpen();\n }\n\n forceCircuitClose(): void {\n this.engine?.forceCircuitClose();\n }\n\n manualReplay(): Promise<number> {\n return this.engine?.manualReplay() ?? Promise.resolve(0);\n }\n\n replayDeadLetter(): PixelEvent[] {\n return this.engine?.replayDeadLetter() ?? [];\n }\n\n clearDeadLetter(): void {\n this.engine?.clearDeadLetter();\n }\n\n exportQueue(): string {\n return this.engine?.exportQueue() ?? '[]';\n }\n\n importQueue(raw: string): number {\n return this.engine?.importQueue(raw) ?? 0;\n }\n}\n","import type { PixelModule } from './types';\n\nexport class ModuleRegistry {\n private readonly modules: PixelModule[] = [];\n\n register(module: PixelModule): void {\n if (this.modules.some(existing => existing.name === module.name)) {\n throw new Error(`[Pixel] Module \"${module.name}\" is already registered`);\n }\n\n this.modules.push(module);\n }\n\n getAll(): readonly PixelModule[] {\n return this.modules;\n }\n\n size(): number {\n return this.modules.length;\n }\n}\n","import type { AttributionService } from '@/services/attribution/types';\nimport type { BrowserMetadataService } from '@/services/browser-metadata';\n\nimport type { BasePixelEvent } from '../base';\n\nexport class BaseEventBuilder {\n private readonly metadataService: BrowserMetadataService;\n\n private readonly attribution: AttributionService | null;\n\n constructor(\n metadataService: BrowserMetadataService,\n attribution?: AttributionService | null\n ) {\n this.metadataService = metadataService;\n this.attribution = attribution ?? null;\n }\n\n build<T extends { type: string }>(event: T): T & BasePixelEvent {\n const metadata = this.metadataService.getMetadata();\n const identifiers = this.attribution?.getSnapshot();\n const hasIdentifiers =\n identifiers !== undefined &&\n Object.keys(identifiers).some(key => {\n const value = identifiers[key as keyof typeof identifiers];\n return value !== undefined && value !== null && value !== '';\n });\n\n return {\n ...event,\n timestamp: Date.now(),\n path: metadata.path,\n url: metadata.url,\n hostname: metadata.hostname,\n language: metadata.language,\n timezone: metadata.timezone,\n ...(hasIdentifiers ? { identifiers } : {}),\n };\n }\n}\n","import type { PixelLogger } from './PixelLogger';\n\nexport class ConsolePixelLogger implements PixelLogger {\n constructor(private readonly debugEnabled: boolean) {}\n\n debug(...args: unknown[]): void {\n if (!this.debugEnabled) return;\n if (typeof console === 'undefined') return;\n console.debug(...args);\n }\n\n info(...args: unknown[]): void {\n if (typeof console === 'undefined') return;\n console.info(...args);\n }\n\n warn(...args: unknown[]): void {\n if (typeof console === 'undefined') return;\n console.warn(...args);\n }\n\n error(...args: unknown[]): void {\n if (typeof console === 'undefined') return;\n console.error(...args);\n }\n}\n","export type AttributionIdentifiers = {\n readonly fbclid?: string;\n readonly fbp?: string;\n readonly fbc?: string;\n\n readonly gclid?: string;\n readonly gbraid?: string;\n readonly wbraid?: string;\n readonly ga?: string;\n readonly gid?: string;\n readonly gclAu?: string;\n\n readonly ttclid?: string;\n readonly ttp?: string;\n\n readonly msclkid?: string;\n readonly liFatId?: string;\n readonly epik?: string;\n\n readonly customClickIds?: Readonly<Record<string, string>>;\n\n readonly firstCollectedAt?: number;\n readonly lastCollectedAt?: number;\n readonly landingUrl?: string;\n readonly referrer?: string;\n};\n\nexport type AttributionConfig = {\n readonly enabled: boolean;\n readonly ttlDays?: number;\n readonly persist?: boolean;\n readonly captureUrlParams?: boolean;\n readonly captureCookies?: boolean;\n readonly customClickIdParams?: string[];\n};\n\nexport const DEFAULT_ATTRIBUTION_CONFIG: AttributionConfig = {\n enabled: true,\n ttlDays: 90,\n persist: true,\n captureUrlParams: true,\n captureCookies: true,\n customClickIdParams: [],\n};\n\nexport const ATTRIBUTION_STORAGE_KEY = 'attribution';\n\nexport interface AttributionService {\n init(): void;\n destroy(): void;\n collect(): AttributionIdentifiers;\n getSnapshot(): AttributionIdentifiers;\n update(partial: Partial<AttributionIdentifiers>): AttributionIdentifiers;\n clear(): void;\n}\n","import type { AttributionIdentifiers } from './types';\n\nconst BUILTIN_CLICK_PARAMS = [\n 'fbclid',\n 'gclid',\n 'gbraid',\n 'wbraid',\n 'ttclid',\n 'msclkid',\n 'epik',\n 'li_fat_id',\n] as const;\n\n/**\n * Parses click IDs from URL search params and maps to AttributionIdentifiers fields.\n */\nexport class ClickIdParser {\n parse(\n customParams: readonly string[] = []\n ): Partial<AttributionIdentifiers> {\n if (typeof window === 'undefined' || !window.location?.search) {\n return {};\n }\n\n try {\n const params = new URLSearchParams(window.location.search);\n const result: Record<string, unknown> = {};\n const customClickIds: Record<string, string> = {};\n\n for (const key of BUILTIN_CLICK_PARAMS) {\n const value = params.get(key);\n if (!value) continue;\n\n if (key === 'li_fat_id') {\n result.liFatId = value;\n } else {\n result[key] = value;\n }\n }\n\n for (const key of customParams) {\n const value = params.get(key);\n if (value) customClickIds[key] = value;\n }\n\n if (Object.keys(customClickIds).length > 0) {\n result.customClickIds = customClickIds;\n }\n\n return result as Partial<AttributionIdentifiers>;\n } catch {\n return {};\n }\n }\n\n /**\n * Meta convention: when fbclid is present and _fbc cookie is missing,\n * synthesize fbc = fb.1.<timestamp_ms>.<fbclid>\n */\n synthesizeFbc(fbclid: string, existingFbc?: string): string | undefined {\n if (existingFbc) return existingFbc;\n if (!fbclid) return undefined;\n return `fb.1.${Date.now()}.${fbclid}`;\n }\n}\n","/**\n * SSR-safe cookie reader for attribution identifiers.\n */\nexport class CookieCollector {\n collectKnown(): Readonly<Record<string, string>> {\n if (typeof document === 'undefined') return {};\n\n const cookies = this.parseCookies();\n const result: Record<string, string> = {};\n\n const map: Record<string, string> = {\n _fbp: 'fbp',\n _fbc: 'fbc',\n _ga: 'ga',\n _gid: 'gid',\n _gcl_au: 'gclAu',\n _ttp: 'ttp',\n li_fat_id: 'liFatId',\n epik: 'epik',\n };\n\n for (const [cookieName, field] of Object.entries(map)) {\n const value = cookies[cookieName];\n if (value) result[field] = value;\n }\n\n return result;\n }\n\n private parseCookies(): Record<string, string> {\n if (typeof document === 'undefined') return {};\n\n try {\n return document.cookie.split(';').reduce(\n (acc, part) => {\n const [rawKey, ...rest] = part.trim().split('=');\n if (!rawKey) return acc;\n acc[rawKey] = decodeURIComponent(rest.join('=') || '');\n return acc;\n },\n {} as Record<string, string>\n );\n } catch {\n return {};\n }\n }\n}\n","import type { AttributionIdentifiers } from './types';\nimport { ClickIdParser } from './ClickIdParser';\nimport { CookieCollector } from './CookieCollector';\n\n/**\n * Collects attribution signals from URL + cookies and merges them.\n */\nexport class AttributionCollector {\n private readonly clickIdParser = new ClickIdParser();\n\n private readonly cookieCollector = new CookieCollector();\n\n private readonly customParams: readonly string[];\n\n private readonly captureUrlParams: boolean;\n\n private readonly captureCookies: boolean;\n\n constructor(\n options: {\n customParams?: readonly string[];\n captureUrlParams?: boolean;\n captureCookies?: boolean;\n } = {}\n ) {\n this.customParams = options.customParams ?? [];\n this.captureUrlParams = options.captureUrlParams !== false;\n this.captureCookies = options.captureCookies !== false;\n }\n\n collectFresh(): Partial<AttributionIdentifiers> {\n const fromUrl = this.captureUrlParams\n ? this.clickIdParser.parse(this.customParams)\n : {};\n const fromCookies = this.captureCookies\n ? this.cookieCollector.collectKnown()\n : {};\n\n const merged: Record<string, unknown> = {\n ...fromCookies,\n ...fromUrl,\n };\n\n const customClickIds = {\n ...((fromCookies as AttributionIdentifiers).customClickIds ?? {}),\n ...(fromUrl.customClickIds ?? {}),\n };\n if (Object.keys(customClickIds).length > 0) {\n merged.customClickIds = customClickIds;\n }\n\n if (typeof merged.fbclid === 'string' && merged.fbclid) {\n const fbc = this.clickIdParser.synthesizeFbc(\n merged.fbclid,\n typeof merged.fbc === 'string' ? merged.fbc : undefined\n );\n if (fbc) merged.fbc = fbc;\n }\n\n if (typeof window !== 'undefined') {\n try {\n merged.landingUrl = window.location.href;\n } catch {\n // ignore\n }\n }\n\n if (typeof document !== 'undefined') {\n try {\n if (document.referrer) merged.referrer = document.referrer;\n } catch {\n // ignore\n }\n }\n\n return merged as Partial<AttributionIdentifiers>;\n }\n\n /**\n * Merge: never overwrite existing defined values with undefined.\n */\n merge(\n existing: AttributionIdentifiers,\n incoming: Partial<AttributionIdentifiers>\n ): AttributionIdentifiers {\n const next: Record<string, unknown> = { ...existing };\n\n for (const [key, value] of Object.entries(incoming)) {\n if (value === undefined || value === null || value === '') continue;\n\n if (key === 'customClickIds' && typeof value === 'object') {\n next.customClickIds = {\n ...((existing.customClickIds as Record<string, string>) ?? {}),\n ...(value as Record<string, string>),\n };\n continue;\n }\n\n next[key] = value;\n }\n\n const now = Date.now();\n if (!existing.firstCollectedAt) {\n next.firstCollectedAt = now;\n }\n next.lastCollectedAt = now;\n\n return next as AttributionIdentifiers;\n }\n}\n","import type { StorageService } from '@/services/storage/types';\n\nimport { ATTRIBUTION_STORAGE_KEY, type AttributionIdentifiers } from './types';\n\n/**\n * Persists AttributionIdentifiers via StorageService only (no direct localStorage).\n */\nexport class AttributionStore {\n private readonly storage: StorageService;\n\n private readonly persist: boolean;\n\n private readonly ttlMs: number;\n\n private readonly storageKey: string;\n\n constructor(\n storage: StorageService,\n options: { persist: boolean; ttlDays: number; storageKey?: string }\n ) {\n this.storage = storage;\n this.persist = options.persist;\n this.ttlMs = options.ttlDays * 24 * 60 * 60 * 1000;\n this.storageKey = options.storageKey ?? ATTRIBUTION_STORAGE_KEY;\n }\n\n load(): AttributionIdentifiers | null {\n if (!this.persist) return null;\n\n try {\n const snapshot = this.storage.get<AttributionIdentifiers>(this.storageKey);\n if (!snapshot) return null;\n\n if (this.isExpired(snapshot)) {\n this.clear();\n return null;\n }\n\n return snapshot;\n } catch {\n return null;\n }\n }\n\n save(snapshot: AttributionIdentifiers): void {\n if (!this.persist) return;\n\n try {\n this.storage.set(this.storageKey, snapshot);\n } catch {\n // quota / SSR — keep in-memory only\n }\n }\n\n clear(): void {\n try {\n this.storage.remove(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n private isExpired(snapshot: AttributionIdentifiers): boolean {\n const anchor = snapshot.lastCollectedAt ?? snapshot.firstCollectedAt;\n if (!anchor) return false;\n return Date.now() - anchor > this.ttlMs;\n }\n}\n","import type { StorageService } from '@/services/storage/types';\n\nimport { AttributionCollector } from './AttributionCollector';\nimport { AttributionStore } from './AttributionStore';\nimport {\n DEFAULT_ATTRIBUTION_CONFIG,\n type AttributionConfig,\n type AttributionIdentifiers,\n type AttributionService,\n} from './types';\n\nexport class AttributionServiceImpl implements AttributionService {\n private readonly store: AttributionStore;\n\n private readonly collector: AttributionCollector;\n\n private readonly enabled: boolean;\n\n private snapshot: AttributionIdentifiers = {};\n\n private active = false;\n\n constructor(storage: StorageService, config: AttributionConfig = DEFAULT_ATTRIBUTION_CONFIG) {\n this.enabled = config.enabled !== false;\n this.store = new AttributionStore(storage, {\n persist: config.persist !== false,\n ttlDays: config.ttlDays ?? 90,\n });\n this.collector = new AttributionCollector({\n customParams: config.customClickIdParams ?? [],\n captureUrlParams: config.captureUrlParams !== false,\n captureCookies: config.captureCookies !== false,\n });\n }\n\n init(): void {\n if (this.active) return;\n this.active = true;\n\n if (!this.enabled) return;\n\n const stored = this.store.load();\n if (stored) {\n this.snapshot = stored;\n }\n\n this.collect();\n }\n\n destroy(): void {\n if (!this.active) return;\n this.active = false;\n }\n\n collect(): AttributionIdentifiers {\n if (!this.enabled) return this.snapshot;\n\n const fresh = this.collector.collectFresh();\n this.snapshot = this.collector.merge(this.snapshot, fresh);\n this.store.save(this.snapshot);\n return this.snapshot;\n }\n\n getSnapshot(): AttributionIdentifiers {\n return { ...this.snapshot };\n }\n\n update(partial: Partial<AttributionIdentifiers>): AttributionIdentifiers {\n this.snapshot = this.collector.merge(this.snapshot, partial);\n this.store.save(this.snapshot);\n return this.getSnapshot();\n }\n\n clear(): void {\n this.snapshot = {};\n this.store.clear();\n }\n}\n","import type { BrowserMetadata, BrowserMetadataService } from './types';\n\nexport class BrowserMetadataServiceImpl implements BrowserMetadataService {\n getMetadata(): BrowserMetadata {\n if (typeof window === 'undefined') {\n return {};\n }\n\n const timezone = (() => {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n return undefined;\n }\n })();\n\n return {\n url: location.href,\n path: location.pathname,\n hostname: location.hostname,\n origin: location.origin,\n title: typeof document !== 'undefined' ? document.title : undefined,\n referrer: typeof document !== 'undefined' ? document.referrer : undefined,\n language: navigator.language,\n timezone,\n userAgent: navigator.userAgent,\n platform: navigator.platform,\n screenWidth: screen.width,\n screenHeight: screen.height,\n colorDepth: screen.colorDepth,\n };\n }\n}\n","import type { PixelEvent } from '@/events';\n\nimport type { DispatcherService } from './types';\n\ntype EventListener = (event: PixelEvent) => void;\n\nexport class DispatcherServiceImpl implements DispatcherService {\n private readonly listeners = new Set<EventListener>();\n\n private lastEvent: PixelEvent | null = null;\n\n dispatch(event: PixelEvent): void {\n this.lastEvent = event;\n\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n subscribe(listener: (event: PixelEvent) => void): () => void {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n clear(): void {\n this.listeners.clear();\n this.lastEvent = null;\n }\n\n getListenerCount(): number {\n return this.listeners.size;\n }\n\n getLastEvent(): PixelEvent | null {\n return this.lastEvent;\n }\n}\n","import type { PixelConfig } from '@/config';\nimport type { BrowserMetadataService } from '@/services/browser-metadata';\nimport type { StorageService } from '@/services/storage';\n\nimport type { FingerprintService } from './types';\n\nconst DEFAULT_FINGERPRINT_KEY = 'fingerprint';\n\nfunction hashFingerprintInput(input: string): string {\n let hash = 0;\n\n for (let index = 0; index < input.length; index++) {\n hash = (hash << 5) - hash + input.charCodeAt(index);\n hash |= 0;\n }\n\n const positiveHash = Math.abs(hash).toString(16).padStart(8, '0');\n let secondaryHash = 0;\n\n for (let index = input.length - 1; index >= 0; index--) {\n secondaryHash = (secondaryHash << 5) - secondaryHash + input.charCodeAt(index);\n secondaryHash |= 0;\n }\n\n return `fp_${positiveHash}${Math.abs(secondaryHash).toString(16).padStart(8, '0')}`;\n}\n\nfunction computeLightFingerprint(\n metadataService: BrowserMetadataService\n): string {\n const metadata = metadataService.getMetadata();\n\n const components = [\n metadata.userAgent ?? '',\n metadata.language ?? '',\n metadata.platform ?? '',\n String(metadata.screenWidth ?? ''),\n String(metadata.screenHeight ?? ''),\n String(metadata.colorDepth ?? ''),\n metadata.timezone ?? '',\n ];\n\n return hashFingerprintInput(components.join('|'));\n}\n\nexport class FingerprintServiceImpl implements FingerprintService {\n private readonly storage: StorageService;\n\n private readonly storageKey: string;\n\n private readonly metadataService: BrowserMetadataService;\n\n constructor(\n storage: StorageService,\n config: PixelConfig,\n metadataService: BrowserMetadataService\n ) {\n this.storage = storage;\n this.storageKey =\n config.storage.keys?.fingerprint ?? DEFAULT_FINGERPRINT_KEY;\n this.metadataService = metadataService;\n }\n\n getFingerprint(): string | null {\n return this.storage.get<string>(this.storageKey);\n }\n\n ensureFingerprint(): string {\n const existing = this.getFingerprint();\n if (existing) return existing;\n\n const fingerprint = computeLightFingerprint(this.metadataService);\n this.storage.set(this.storageKey, fingerprint);\n return fingerprint;\n }\n}\n","import type { StorageAdapter } from './types';\n\nexport class BrowserStorageAdapter implements StorageAdapter {\n private readonly storage: Storage | null;\n\n private readonly memoryFallback = new Map<string, string>();\n\n constructor(storage: Storage) {\n this.storage = typeof window === 'undefined' ? null : storage;\n }\n\n get(key: string): string | null {\n if (this.storage) {\n return this.storage.getItem(key);\n }\n\n return this.memoryFallback.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n if (this.storage) {\n this.storage.setItem(key, value);\n return;\n }\n\n this.memoryFallback.set(key, value);\n }\n\n remove(key: string): void {\n if (this.storage) {\n this.storage.removeItem(key);\n return;\n }\n\n this.memoryFallback.delete(key);\n }\n\n clear(): void {\n // Never clear entire browser storage — namespace removal uses removeKeysMatching.\n if (!this.storage) {\n this.memoryFallback.clear();\n }\n }\n\n removeKeysMatching(predicate: (key: string) => boolean): void {\n if (this.storage) {\n const keysToRemove: string[] = [];\n\n for (let index = 0; index < this.storage.length; index++) {\n const key = this.storage.key(index);\n if (key && predicate(key)) {\n keysToRemove.push(key);\n }\n }\n\n for (const key of keysToRemove) {\n this.storage.removeItem(key);\n }\n\n return;\n }\n\n for (const key of this.memoryFallback.keys()) {\n if (predicate(key)) {\n this.memoryFallback.delete(key);\n }\n }\n }\n}\n","import type { StorageAdapter } from './types';\n\nexport class MemoryStorageAdapter implements StorageAdapter {\n private readonly store = new Map<string, string>();\n\n get(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n\n removeKeysMatching(predicate: (key: string) => boolean): void {\n for (const key of this.store.keys()) {\n if (predicate(key)) {\n this.store.delete(key);\n }\n }\n }\n}\n","import type { StorageAdapter, StorageService } from './types';\n\ntype NamespaceClearableAdapter = StorageAdapter & {\n removeKeysMatching(predicate: (key: string) => boolean): void;\n};\n\nfunction supportsNamespaceClear(\n adapter: StorageAdapter\n): adapter is NamespaceClearableAdapter {\n return (\n 'removeKeysMatching' in adapter &&\n typeof adapter.removeKeysMatching === 'function'\n );\n}\n\nexport class StorageServiceImpl implements StorageService {\n private readonly adapter: StorageAdapter;\n\n private readonly namespace: string;\n\n private readonly prefix?: string;\n\n constructor(adapter: StorageAdapter, namespace: string, prefix?: string) {\n this.adapter = adapter;\n this.namespace = namespace;\n this.prefix = prefix;\n }\n\n get<T>(key: string): T | null {\n const raw = this.adapter.get(this.createKey(key));\n if (raw === null) return null;\n\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n }\n\n set<T>(key: string, value: T): void {\n this.adapter.set(this.createKey(key), JSON.stringify(value));\n }\n\n remove(key: string): void {\n this.adapter.remove(this.createKey(key));\n }\n\n has(key: string): boolean {\n return this.adapter.get(this.createKey(key)) !== null;\n }\n\n clear(): void {\n const namespaceKeyPrefix = this.getNamespaceKeyPrefix();\n\n if (supportsNamespaceClear(this.adapter)) {\n this.adapter.removeKeysMatching(key =>\n key.startsWith(namespaceKeyPrefix)\n );\n return;\n }\n\n this.adapter.clear();\n }\n\n createKey(key: string): string {\n if (this.prefix) {\n return `${this.prefix}:${this.namespace}:${key}`;\n }\n\n return `${this.namespace}:${key}`;\n }\n\n private getNamespaceKeyPrefix(): string {\n if (this.prefix) {\n return `${this.prefix}:${this.namespace}:`;\n }\n\n return `${this.namespace}:`;\n }\n}\n","import type {\n AttributionStoragePersistence,\n QueueStoragePersistence,\n SessionStoragePersistence,\n VisitorStoragePersistence,\n} from '@/config/shared/persistence';\n\nimport { BrowserStorageAdapter } from './BrowserStorageAdapter';\nimport { MemoryStorageAdapter } from './MemoryStorageAdapter';\nimport type { StorageAdapter } from './types';\n\nexport type StoragePersistence =\n | VisitorStoragePersistence\n | SessionStoragePersistence\n | AttributionStoragePersistence\n | QueueStoragePersistence;\n\nexport function createStorageAdapter(\n persistence?: StoragePersistence\n): StorageAdapter {\n const mode = persistence ?? 'memory';\n\n if (typeof window === 'undefined') {\n return new MemoryStorageAdapter();\n }\n\n switch (mode) {\n case 'memory':\n return new MemoryStorageAdapter();\n case 'localStorage':\n return new BrowserStorageAdapter(window.localStorage);\n case 'sessionStorage':\n return new BrowserStorageAdapter(window.sessionStorage);\n case 'cookie_localStorage':\n // TODO: implementar cookie fallback.\n return new BrowserStorageAdapter(window.localStorage);\n case 'cookie':\n return new MemoryStorageAdapter();\n case 'indexedDB':\n return new MemoryStorageAdapter();\n default:\n return new MemoryStorageAdapter();\n }\n}\n\nexport function resolveStorageAdapterName(\n persistence?: StoragePersistence\n): string {\n const mode = persistence ?? 'memory';\n\n switch (mode) {\n case 'localStorage':\n case 'sessionStorage':\n case 'cookie_localStorage':\n return 'BrowserStorageAdapter';\n default:\n return 'MemoryStorageAdapter';\n }\n}\n","function createRandomSuffix(): string {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID().replace(/-/g, '');\n }\n\n return `${Date.now()}${Math.random().toString(36).slice(2)}`;\n}\n\nexport function generateSessionId(): string {\n return `ses_${createRandomSuffix()}`;\n}\n","import type { PixelConfig } from '@/config';\nimport type { StorageService } from '@/services/storage';\n\nimport type { EnsureSessionResult, SessionData, SessionService } from './types';\nimport { generateSessionId } from './session-id';\n\nconst DEFAULT_SESSION_KEY = 'session';\n\nexport class SessionServiceImpl implements SessionService {\n private readonly storage: StorageService;\n\n private readonly storageKey: string;\n\n constructor(storage: StorageService, config: PixelConfig) {\n this.storage = storage;\n this.storageKey = config.storage.keys?.session ?? DEFAULT_SESSION_KEY;\n }\n\n getSessionId(): string | null {\n return this.getSessionData()?.sessionId ?? null;\n }\n\n getSessionData(): SessionData | null {\n const raw = this.storage.get<SessionData | string>(this.storageKey);\n if (!raw) return null;\n\n if (typeof raw === 'string') {\n const now = Date.now();\n return {\n sessionId: raw,\n lastActivityAt: now,\n createdAt: now,\n };\n }\n\n return raw;\n }\n\n getLastActivityAt(): number | null {\n return this.getSessionData()?.lastActivityAt ?? null;\n }\n\n isExpired(ttlMs: number): boolean {\n const data = this.getSessionData();\n if (!data) return true;\n\n return Date.now() - data.lastActivityAt > ttlMs;\n }\n\n ensureSession(ttlMs: number): EnsureSessionResult {\n const data = this.getSessionData();\n const now = Date.now();\n\n if (!data) {\n const sessionId = generateSessionId();\n this.writeSessionData({\n sessionId,\n lastActivityAt: now,\n createdAt: now,\n });\n\n return {\n sessionId,\n expired: false,\n created: true,\n };\n }\n\n if (now - data.lastActivityAt > ttlMs) {\n const previousSessionId = data.sessionId;\n const sessionId = generateSessionId();\n\n this.writeSessionData({\n sessionId,\n lastActivityAt: now,\n createdAt: now,\n });\n\n return {\n sessionId,\n expired: true,\n previousSessionId,\n created: false,\n };\n }\n\n return {\n sessionId: data.sessionId,\n expired: false,\n created: false,\n };\n }\n\n ensureSessionId(): string {\n return this.ensureSession(Number.MAX_SAFE_INTEGER).sessionId;\n }\n\n touchActivity(): void {\n const data = this.getSessionData();\n if (!data) return;\n\n this.writeSessionData({\n ...data,\n lastActivityAt: Date.now(),\n });\n }\n\n renew(): string {\n const now = Date.now();\n const sessionId = generateSessionId();\n\n this.writeSessionData({\n sessionId,\n lastActivityAt: now,\n createdAt: now,\n });\n\n return sessionId;\n }\n\n clear(): void {\n this.storage.remove(this.storageKey);\n }\n\n private writeSessionData(data: SessionData): void {\n this.storage.set(this.storageKey, data);\n }\n}\n","function createRandomSuffix(): string {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID().replace(/-/g, '');\n }\n\n return `${Date.now()}${Math.random().toString(36).slice(2)}`;\n}\n\nexport function generateVisitorId(): string {\n return `vst_${createRandomSuffix()}`;\n}\n","import type { PixelConfig } from '@/config';\nimport type { StorageService } from '@/services/storage';\n\nimport type { VisitorService } from './types';\nimport { generateVisitorId } from './visitor-id';\n\nconst DEFAULT_VISITOR_KEY = 'visitor';\n\nexport class VisitorServiceImpl implements VisitorService {\n private readonly storage: StorageService;\n\n private readonly storageKey: string;\n\n constructor(storage: StorageService, config: PixelConfig) {\n this.storage = storage;\n this.storageKey = config.storage.keys?.visitor ?? DEFAULT_VISITOR_KEY;\n }\n\n getVisitorId(): string | null {\n return this.storage.get<string>(this.storageKey);\n }\n\n ensureVisitorId(): string {\n const existing = this.getVisitorId();\n if (existing) return existing;\n\n const visitorId = generateVisitorId();\n this.storage.set(this.storageKey, visitorId);\n return visitorId;\n }\n\n clearVisitorId(): void {\n this.storage.remove(this.storageKey);\n }\n}\n","import type { PixelConfig } from '@/config';\nimport { BaseEventBuilder } from '@/events/builder';\nimport { ConsolePixelLogger, type PixelLogger } from '@/logger';\nimport {\n AttributionServiceImpl,\n DEFAULT_ATTRIBUTION_CONFIG,\n} from '@/services/attribution';\nimport { BrowserMetadataServiceImpl } from '@/services/browser-metadata/BrowserMetadataService';\nimport { DispatcherServiceImpl } from '@/services/dispatcher/DispatcherService';\nimport { FingerprintServiceImpl } from '@/services/fingerprint/FingerprintService';\nimport {\n createStorageAdapter,\n StorageServiceImpl,\n} from '@/services/storage';\nimport type { StoragePersistence } from '@/services/storage/StorageFactory';\nimport { SessionServiceImpl } from '@/services/session/SessionService';\nimport type { PixelRuntimeServices } from '@/services/types';\nimport { VisitorServiceImpl } from '@/services/visitor/VisitorService';\n\nimport { ModuleRegistry } from './ModuleRegistry';\nimport type { PixelRuntimeContext } from './PixelRuntimeContext';\nimport type { ModuleName } from './shared/module';\nimport type { PixelModule } from './types';\n\nexport class PixelRuntime {\n private initialized = false;\n\n private readonly initializedModules: PixelModule[] = [];\n\n private readonly registry: ModuleRegistry;\n\n private readonly config: PixelConfig;\n\n private readonly fallbackLogger: ConsolePixelLogger;\n\n private context: PixelRuntimeContext | null = null;\n\n constructor(config: PixelConfig) {\n this.config = config;\n this.registry = new ModuleRegistry();\n this.fallbackLogger = new ConsolePixelLogger(config.app.debug === true);\n }\n\n register(module: PixelModule): void {\n this.registry.register(module);\n }\n\n async init(): Promise<void> {\n if (this.initialized) {\n this.getLogger().debug('[PixelRuntime] Runtime already initialized');\n return;\n }\n\n this.fallbackLogger.debug('[PixelRuntime] Initializing runtime');\n\n this.context = this.createContext();\n this.context.services.attribution.init();\n\n for (const module of this.registry.getAll()) {\n if (!this.isModuleEnabled(module)) {\n this.fallbackLogger.debug(\n `[PixelRuntime] Skipping disabled module: ${module.name}`\n );\n continue;\n }\n\n this.fallbackLogger.debug(\n `[PixelRuntime] Initializing module: ${module.name}`\n );\n\n try {\n await module.init(this.context);\n this.initializedModules.push(module);\n } catch (error) {\n this.fallbackLogger.error(\n `[Pixel] Failed to initialize module \"${module.name}\"`,\n error\n );\n }\n }\n\n this.initialized = true;\n }\n\n async destroy(): Promise<void> {\n if (!this.initialized) return;\n\n const logger = this.getLogger();\n\n for (let index = this.initializedModules.length - 1; index >= 0; index--) {\n const module = this.initializedModules[index];\n\n logger.debug(`[PixelRuntime] Destroying module: ${module.name}`);\n\n try {\n await module.destroy?.();\n } catch (error) {\n logger.error(\n `[Pixel] Failed to destroy module \"${module.name}\"`,\n error\n );\n }\n }\n\n this.context?.services.attribution.destroy();\n this.context?.services.dispatcher.clear();\n\n this.initialized = false;\n this.initializedModules.length = 0;\n this.context = null;\n\n this.fallbackLogger.debug('[PixelRuntime] Runtime destroyed');\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /** @internal For playground and development only. Not part of the stable public API. */\n getDebugServices(): PixelRuntimeServices | null {\n return this.context?.services ?? null;\n }\n\n private createServices(): PixelRuntimeServices {\n const { namespace, prefix, persistence } = this.config.storage;\n\n const visitorStorage = this.createStorageService(\n namespace,\n prefix,\n persistence?.visitor\n );\n const sessionStorage = this.createStorageService(\n namespace,\n prefix,\n persistence?.session\n );\n const fingerprintStorage = this.createStorageService(\n namespace,\n prefix,\n persistence?.attribution\n );\n const attributionStorage = this.createStorageService(\n namespace,\n prefix,\n persistence?.attribution ?? 'localStorage'\n );\n const storage = this.createStorageService(namespace, prefix, 'memory');\n const browserMetadata = new BrowserMetadataServiceImpl();\n\n const attribution = new AttributionServiceImpl(\n attributionStorage,\n this.config.attribution ?? DEFAULT_ATTRIBUTION_CONFIG\n );\n\n const eventBuilder = new BaseEventBuilder(browserMetadata, attribution);\n\n const visitor = new VisitorServiceImpl(visitorStorage, this.config);\n const session = new SessionServiceImpl(sessionStorage, this.config);\n const fingerprint = new FingerprintServiceImpl(\n fingerprintStorage,\n this.config,\n browserMetadata\n );\n const dispatcher = new DispatcherServiceImpl();\n\n return {\n storage,\n visitor,\n session,\n fingerprint,\n dispatcher,\n browserMetadata,\n eventBuilder,\n attribution,\n };\n }\n\n private createStorageService(\n namespace: string,\n prefix: string | undefined,\n persistence: StoragePersistence | undefined\n ): StorageServiceImpl {\n return new StorageServiceImpl(\n createStorageAdapter(persistence),\n namespace,\n prefix\n );\n }\n\n private createContext(): PixelRuntimeContext {\n return {\n config: this.config,\n logger: this.fallbackLogger,\n services: this.createServices(),\n };\n }\n\n private getLogger(): PixelLogger {\n return this.context?.logger ?? this.fallbackLogger;\n }\n\n private isModuleEnabled(module: PixelModule): boolean {\n const enabledModules: Record<ModuleName, boolean> = {\n privacy: this.config.modules.privacy.enabled,\n core: this.config.modules.core.enabled,\n behavior: this.config.modules.behavior.enabled,\n conversion: this.config.modules.conversion.enabled,\n transport: this.config.modules.transport.enabled,\n integrations: this.config.modules.integrations.enabled,\n };\n\n return enabledModules[module.name];\n }\n}\n","import type { PixelConfig } from '@/config';\nimport type { PixelEvent } from '@/events';\nimport type {\n AddPaymentInfoData,\n AddToCartData,\n InitiateCheckoutData,\n LeadData,\n PurchaseData,\n RemoveFromCartData,\n SearchData,\n ViewContentData,\n} from '@/events/conversion';\nimport type { PixelRuntimeServices } from '@/services/types';\nimport {\n BehaviorModule,\n ConversionModule,\n CoreModule,\n IntegrationsModule,\n PrivacyModule,\n TransportModule,\n} from '@/modules';\nimport { PixelRuntime } from '@/runtime';\n\nexport class Pixel {\n private readonly runtime: PixelRuntime;\n\n private readonly conversionModule: ConversionModule;\n\n private readonly transportModule: TransportModule;\n\n private readonly integrationsModule: IntegrationsModule;\n\n constructor(config: PixelConfig) {\n this.runtime = new PixelRuntime(config);\n this.conversionModule = new ConversionModule();\n this.transportModule = new TransportModule();\n this.integrationsModule = new IntegrationsModule();\n\n // Ordem crítica: Transport + Integrations assinam Dispatcher\n // ANTES do Core emitir PAGE_VIEW.\n this.runtime.register(new PrivacyModule());\n this.runtime.register(this.transportModule);\n this.runtime.register(this.integrationsModule);\n this.runtime.register(new CoreModule());\n this.runtime.register(new BehaviorModule());\n this.runtime.register(this.conversionModule);\n }\n\n init(): Promise<void> {\n return this.runtime.init();\n }\n\n destroy(): Promise<void> {\n return this.runtime.destroy();\n }\n\n isInitialized(): boolean {\n return this.runtime.isInitialized();\n }\n\n purchase(data: PurchaseData): void {\n this.conversionModule.purchase(data);\n }\n\n lead(data: LeadData): void {\n this.conversionModule.lead(data);\n }\n\n addToCart(data: AddToCartData): void {\n this.conversionModule.addToCart(data);\n }\n\n removeFromCart(data: RemoveFromCartData): void {\n this.conversionModule.removeFromCart(data);\n }\n\n initiateCheckout(data: InitiateCheckoutData): void {\n this.conversionModule.initiateCheckout(data);\n }\n\n addPaymentInfo(data: AddPaymentInfoData): void {\n this.conversionModule.addPaymentInfo(data);\n }\n\n viewContent(data: ViewContentData): void {\n this.conversionModule.viewContent(data);\n }\n\n search(data: SearchData): void {\n this.conversionModule.search(data);\n }\n\n /** @internal For playground and development only. */\n getDebugDedupeKeys(): readonly string[] {\n return this.conversionModule.getDebugDedupeKeys();\n }\n\n /** @internal For playground and development only. */\n getDebugActiveDetectors(): readonly string[] {\n return this.conversionModule.getDebugActiveDetectors();\n }\n\n /** @internal For playground and development only. */\n getDebugTransportState() {\n return this.transportModule.getDebugState();\n }\n\n /** @internal For playground — flush manual do transport. */\n flushTransport(): void {\n this.transportModule.manualFlush?.();\n }\n\n /** @internal For playground — simular offline. */\n simulateTransportOffline(offline: boolean): void {\n this.transportModule.simulateOffline?.(offline);\n }\n\n /** @internal For playground — forçar falhas no MockSender (retry). */\n configureTransportMockSender(\n options: { delayMs?: number; failUntilAttempt?: number; simulateTimeout?: boolean }\n ): void {\n this.transportModule.configureMockSender?.(options);\n }\n\n /** @internal For playground — simular reload da página. */\n simulateTransportReload(): Promise<void> {\n return this.transportModule.simulateReload();\n }\n\n /** @internal For playground — simular restart do transport. */\n simulateTransportRestart(): Promise<void> {\n return this.transportModule.simulateRestart();\n }\n\n /** @internal For playground — abrir circuit breaker. */\n forceTransportCircuitOpen(): void {\n this.transportModule.forceCircuitOpen();\n }\n\n /** @internal For playground — fechar circuit breaker. */\n forceTransportCircuitClose(): void {\n this.transportModule.forceCircuitClose();\n }\n\n /** @internal For playground — replay manual da fila persistida. */\n manualTransportReplay(): Promise<number> {\n return this.transportModule.manualReplay();\n }\n\n /** @internal For playground — replay dead letter. */\n replayTransportDeadLetter(): PixelEvent[] {\n return this.transportModule.replayDeadLetter();\n }\n\n /** @internal For playground — limpar dead letter. */\n clearTransportDeadLetter(): void {\n this.transportModule.clearDeadLetter();\n }\n\n /** @internal For playground — exportar fila. */\n exportTransportQueue(): string {\n return this.transportModule.exportQueue();\n }\n\n /** @internal For playground — importar fila. */\n importTransportQueue(raw: string): number {\n return this.transportModule.importQueue(raw);\n }\n\n /** @internal For playground — Integration Engine debug state. */\n getDebugIntegrationState() {\n return this.integrationsModule.getDebugState();\n }\n\n /** @internal For playground — MemoryDestination records. */\n getDebugIntegrationMemoryRecords() {\n return this.integrationsModule.getMemoryRecords();\n }\n\n /** @internal For playground — Attribution snapshot. */\n getDebugAttributionSnapshot() {\n return this.runtime.getDebugServices()?.attribution.getSnapshot() ?? null;\n }\n\n /** @internal For playground — recolher attribution. */\n collectAttribution() {\n return this.runtime.getDebugServices()?.attribution.collect() ?? null;\n }\n\n /** @internal For playground — limpar attribution. */\n clearAttribution(): void {\n this.runtime.getDebugServices()?.attribution.clear();\n }\n\n /** @internal For playground and development only. Not part of the stable public API. */\n getDebugServices(): PixelRuntimeServices | null {\n return this.runtime.getDebugServices();\n }\n}\n","import type { AttributionConfig } from '../types/attribution';\n\nexport const DEFAULT_ATTRIBUTION_CONFIG: AttributionConfig = {\n enabled: true,\n ttlDays: 90,\n persist: true,\n captureUrlParams: true,\n captureCookies: true,\n customClickIdParams: [],\n};\n","import type { BehaviorModuleConfig } from '../../types/modules/behavior';\n\nexport const DEFAULT_BEHAVIOR_MODULE_CONFIG: BehaviorModuleConfig = {\n enabled: false,\n\n trackers: {\n scroll: {\n enabled: false,\n thresholds: [25, 50, 75, 100],\n debounceMs: 100,\n },\n\n click: {\n enabled: false,\n rageClick: {\n enabled: true,\n threshold: 3,\n windowMs: 500,\n },\n },\n\n idle: {\n enabled: false,\n thresholdMs: 60_000,\n },\n\n visibility: {\n enabled: false,\n },\n\n exitIntent: {\n enabled: false,\n },\n\n viewport: {\n enabled: false,\n selector: '',\n selectorType: 'attribute',\n visibilityThreshold: 0.5,\n },\n\n heartbeat: {\n enabled: false,\n intervalMs: 5_000,\n hiddenIntervalMs: 30_000,\n },\n\n engagement: {\n enabled: false,\n weights: {\n scroll: 0.3,\n click: 0.3,\n time: 0.25,\n },\n thresholds: {\n low: 30,\n medium: 70,\n },\n },\n },\n};\n","import type { ConversionModuleConfig } from '../../types/modules/conversion';\n\nexport const DEFAULT_CONVERSION_MODULE_CONFIG: ConversionModuleConfig = {\n enabled: false,\n\n commerce: {\n catalog: {\n products: [],\n },\n checkout: {\n selectedItems: [],\n allowDynamicItems: true,\n calculateValueFrom: 'selected_items',\n },\n mappings: {\n attributes: {},\n fields: {},\n },\n },\n\n manual: {\n pageView: {\n enabled: false,\n },\n purchase: {\n enabled: false,\n },\n lead: {\n enabled: false,\n },\n addToCart: {\n enabled: false,\n },\n removeFromCart: {\n enabled: false,\n },\n initiateCheckout: {\n enabled: false,\n },\n addPaymentInfo: {\n enabled: false,\n },\n search: {\n enabled: false,\n },\n viewContent: {\n enabled: false,\n },\n },\n\n auto: {\n enabled: false,\n\n detectors: {\n lead: {\n enabled: false,\n },\n purchase: {\n enabled: false,\n },\n addToCart: {\n enabled: false,\n },\n removeFromCart: {\n enabled: false,\n },\n initiateCheckout: {\n enabled: false,\n },\n addPaymentInfo: {\n enabled: false,\n paymentMethod: 'CREDIT_CARD',\n cardDetection: true,\n autoDispatch: true,\n },\n search: {\n enabled: false,\n },\n viewContent: {\n enabled: false,\n },\n },\n },\n\n rules: {\n enabled: false,\n selectors: ['[data-track]'],\n texts: ['Comprar', 'Comprar Agora', 'Finalizar Compra', 'Checkout'],\n urlPatterns: ['thank-you', 'purchase', 'success', 'order', 'checkout'],\n checkout: {\n enabled: false,\n },\n card: {\n enabled: false,\n },\n },\n};\n","import type { CoreModuleConfig } from '../../types/modules/core';\n\nexport const DEFAULT_CORE_MODULE_CONFIG: CoreModuleConfig = {\n enabled: true,\n\n pageView: {\n enabled: true,\n trackInitialPageView: true,\n spa: true,\n dedupeMs: 2000,\n },\n\n visitor: {\n enabled: true,\n persistence: 'cookie_localStorage',\n renew: false,\n },\n\n session: {\n enabled: true,\n ttlMs: 10800000,\n renewOnActivity: true,\n renewOnPageView: true,\n },\n\n fingerprint: {\n enabled: true,\n mode: 'light',\n cache: true,\n },\n\n consent: {\n enabled: false,\n required: false,\n waitForConsent: false,\n },\n\n dedupe: {\n enabled: true,\n windowMs: 2000,\n },\n\n coordination: {\n enabled: true,\n leaderElection: true,\n broadcastChannel: true,\n },\n\n ordering: {\n enabled: true,\n preserveOrder: true,\n },\n};\n","import type { IntegrationsModuleConfig } from '../../types/modules/integrations';\n\nexport const DEFAULT_INTEGRATIONS_MODULE_CONFIG: IntegrationsModuleConfig = {\n enabled: false,\n debug: false,\n concurrency: 3,\n timeoutMs: 5000,\n continueOnError: true,\n\n destinations: {\n console: { enabled: false },\n memory: { enabled: false },\n mock: { enabled: false },\n meta: {\n enabled: false,\n pixelIds: [],\n autoPageView: true,\n loadScript: true,\n },\n google: {\n enabled: false,\n tagIds: [],\n autoPageView: true,\n loadScript: true,\n },\n tiktok: {\n enabled: false,\n pixelIds: [],\n autoPageView: true,\n loadScript: true,\n },\n },\n};\n","import type { PrivacyModuleConfig } from '../../types/modules/privacy';\n\nexport const DEFAULT_PRIVACY_MODULE_CONFIG: PrivacyModuleConfig = {\n enabled: false,\n\n consent: {\n enabled: false,\n required: false,\n },\n\n pii: {\n enabled: false,\n hashEmail: true,\n hashPhone: true,\n },\n\n anonymization: {\n enabled: false,\n anonymizeIp: true,\n },\n};\n","import type { TransportModuleConfig } from '../../types/modules/transport';\n\nexport const DEFAULT_TRANSPORT_MODULE_CONFIG: TransportModuleConfig = {\n enabled: false,\n\n mockSender: {\n enabled: true,\n },\n\n sender: {\n mode: 'mock',\n },\n\n persistence: {\n enabled: true,\n },\n\n replay: {\n enabled: true,\n },\n\n ordering: {\n enabled: true,\n },\n\n coordination: {\n enabled: true,\n },\n\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeoutMs: 30_000,\n halfOpenMaxAttempts: 2,\n },\n\n backpressure: {\n enabled: true,\n maxQueueSize: 500,\n policy: 'drop_oldest',\n sampleRate: 0.5,\n },\n\n deadLetter: {\n enabled: true,\n maxEntries: 200,\n },\n\n compression: {\n enabled: true,\n strategy: 'identity',\n },\n\n retry: {\n enabled: true,\n maxAttempts: 4,\n baseDelayMs: 500,\n maxDelayMs: 4000,\n multiplier: 2,\n },\n\n batch: {\n enabled: true,\n batchSize: 10,\n flushIntervalMs: 2000,\n maxWaitMs: 5000,\n },\n\n timeout: {\n enabled: true,\n timeoutMs: 10000,\n },\n\n offline: {\n enabled: true,\n },\n\n flush: {\n enabled: true,\n flushIntervalMs: 2000,\n flushOnDestroy: true,\n prepareUnloadHooks: true,\n },\n};\n","import type { PixelConfig } from '../types/pixel';\nimport { DEFAULT_ATTRIBUTION_CONFIG } from './attribution';\nimport { DEFAULT_BEHAVIOR_MODULE_CONFIG } from './modules/behavior';\nimport { DEFAULT_CONVERSION_MODULE_CONFIG } from './modules/conversion';\nimport { DEFAULT_CORE_MODULE_CONFIG } from './modules/core';\nimport { DEFAULT_INTEGRATIONS_MODULE_CONFIG } from './modules/integrations';\nimport { DEFAULT_PRIVACY_MODULE_CONFIG } from './modules/privacy';\nimport { DEFAULT_TRANSPORT_MODULE_CONFIG } from './modules/transport';\n\nexport const DEFAULT_PIXEL_CONFIG: PixelConfig = {\n app: {\n source: 'custom',\n target: 'custom',\n environment: 'production',\n debug: false,\n },\n\n identity: {\n pixelId: '',\n },\n\n transport: {\n apiEndpoint: '',\n timeoutMs: 10000,\n },\n\n storage: {\n prefix: '__gmk',\n namespace: 'pixel',\n\n queue: {\n enabled: true,\n persistence: 'memory',\n index: true,\n },\n },\n\n attribution: { ...DEFAULT_ATTRIBUTION_CONFIG },\n\n modules: {\n core: DEFAULT_CORE_MODULE_CONFIG,\n behavior: DEFAULT_BEHAVIOR_MODULE_CONFIG,\n conversion: DEFAULT_CONVERSION_MODULE_CONFIG,\n transport: DEFAULT_TRANSPORT_MODULE_CONFIG,\n integrations: DEFAULT_INTEGRATIONS_MODULE_CONFIG,\n privacy: DEFAULT_PRIVACY_MODULE_CONFIG,\n },\n};\n"],"mappings":"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","names":["index_exports","__export","DEFAULT_PIXEL_CONFIG","Pixel","resolveStorageAdapterName","__toCommonJS","BehaviorTrackerBase","context","type","handler","options","listener","entry","timer","partial","event","SCROLL_THROTTLE_MS","ScrollTracker","BehaviorTrackerBase","context","doc","bodyScroll","scrollHeight","clientHeight","maxScroll","current","minIntervalMs","debounceMs","now","scrollY","percent","deltaSeconds","deltaY","velocity","thresholds","crossedNew","threshold","describeElement","element","htmlElement","classes","text","rawText","dataset","key","value","getElementFingerprint","el","tag","id","dataAttrs","name","ClickTracker","BehaviorTrackerBase","context","event","now","rageClick","target","currentTarget","targetDescriptor","describeElement","currentTargetDescriptor","fingerprint","getElementFingerprint","cooldownUntil","recent","ts","VisibilityTracker","BehaviorTrackerBase","context","now","isVisible","ACTIVITY_EVENTS","IdleTracker","BehaviorTrackerBase","context","eventName","now","previousIdleDurationMs","DEFAULT_EXIT_INTENT_THRESHOLD","ExitIntentTracker","BehaviorTrackerBase","context","event","now","BehaviorModule","context","enabled","trackerConfig","trackers","ScrollTracker","ClickTracker","VisibilityTracker","IdleTracker","ExitIntentTracker","tracker","i","BaseAutoTracker","context","type","handler","options","listener","callback","timer","entry","ProductCatalog","products","options","id","product","sku","defaultCurrency","raw","currency","quantity","CommerceState","initialItems","options","item","productId","quantity","previous","metadata","next","normalized","current","selectedItems","SENSITIVE_PATTERN","isBrowserElement","value","isHtmlFormElement","isHtmlInputElement","trimNonEmpty","text","normalizePrice","raw","cleaned","hasComma","hasDot","parsed","normalizeQuantity","isSensitiveField","el","haystack","readAttribute","element","names","name","attrName","readInputValue","findFieldValue","root","candidates","candidate","exact","cssEscape","inputs","needle","input","id","fieldNameMatches","mergeDefined","sources","result","source","key","uniqueNames","custom","defaults","seen","trimmed","DEFAULT_EMAIL_FIELDS","DEFAULT_PHONE_FIELDS","DEFAULT_NAME_FIELDS","DEFAULT_FIRST_NAME_FIELDS","DEFAULT_LAST_NAME_FIELDS","EMAIL_ATTRS","PHONE_ATTRS","NAME_ATTRS","FIRST_NAME_ATTRS","LAST_NAME_ATTRS","CustomerExtractor","options","element","isBrowserElement","fromSelf","form","fromForm","isHtmlFormElement","container","fromContainer","mergeDefined","root","email","readAttribute","findFieldValue","phone","name","firstName","lastName","trimNonEmpty","key","defaults","uniqueNames","type","selector","input","readInputValue","autocomplete","DEFAULT_PRODUCT_ID_ATTRS","DEFAULT_PRODUCT_NAME_ATTRS","DEFAULT_PRICE_ATTRS","DEFAULT_QUANTITY_ATTRS","DEFAULT_CURRENCY_ATTRS","DEFAULT_PRODUCT_ID_FIELDS","DEFAULT_PRODUCT_NAME_FIELDS","DEFAULT_PRICE_FIELDS","DEFAULT_QUANTITY_FIELDS","DEFAULT_CURRENCY_FIELDS","PRODUCT_CONTAINER_SELECTOR","ProductExtractor","options","element","isBrowserElement","fromSelf","form","fromForm","isHtmlFormElement","container","fromContainer","mergeDefined","root","productId","readAttribute","findFieldValue","productName","priceRaw","quantityRaw","currency","trimNonEmpty","normalizePrice","normalizeQuantity","key","defaults","uniqueNames","DEFAULT_MODE","DEFAULT_TRIGGER","VALID_TRIGGERS","FIELD_HEURISTICS","FormConditionEvaluator","config","normalizeSelectorFormConfig","input","scope","values","filledFields","missingFields","field","value","resolveFieldValue","matched","reason","filledCount","total","required","configured","received","isHtmlFormElement","element","isBrowserElement","ownerForm","getOwnerForm","closestForm","found","safeQuerySelector","partial","sanitizeFields","fields","mode","trigger","normalized","formSelector","trimNonEmpty","seen","result","trimmed","isHtmlInputElement","form","selector","key","heuristic","typed","readTypedInput","auto","readAutocomplete","fromAttr","readAttribute","fromFields","findFieldValue","kebab","toKebabCase","fromCustomAttr","root","type","readInputValue","autocomplete","OrderCalculator","input","items","item","value","currency","total","hasPriced","qty","CommerceResolver","options","trim","input","payload","extracted","productId","asString","catalogProduct","resolvedId","stateItem","productName","price","asNumber","quantity","currency","data","key","value","isPurchase","manualValue","manualCurrency","manualItems","resolvedItems","pixelItems","item","shouldCalculateValue","calc","raw","catalog","sku","trimmed","t","normalizeSelectorText","text","prepare","caseSensitive","normalized","elementMatchesText","element","options","raw","haystack","needle","isTextMatchLeaf","descendants","i","child","queryElementsByText","root","scope","containers","matched","container","collectTextMatches","results","nodes","el","PREFIX_TO_TYPE","SelectorResolver","logger","selector","selectorType","inputs","result","input","normalized","root","scope","matched","item","element","fallbackType","trimmed","prefixed","descriptor","value","raw","colon","prefix","type","queryElementsByText","css","nodes","el","error","isTextMatchLeaf","escapeCssIdent","escapeAttrValue","ConfiguredFormDetector","BaseAutoTracker","context","factory","options","FormConditionEvaluator","SelectorResolver","commerce","CustomerExtractor","ProductExtractor","normalized","trigger","events","type","event","domType","element","evaluation","data","current","formSelector","found","eventType","root","customer","isHtmlFormElement","product","ConfiguredSelectorDetector","BaseAutoTracker","context","factory","config","SelectorResolver","commerce","CustomerExtractor","ProductExtractor","event","matched","data","error","candidates","current","element","eventType","customer","product","query","CARD_NUMBER_IDS","CARD_NUMBER_NAMES","CVV_IDS","CVV_NAMES","isVisibleInput","el","inputHasValue","input","findStartedByIdOrName","ids","names","id","name","elements","findStartedByAutocomplete","value","scanPaymentInputStarted","FIELD_EVENTS","CardDetector","BaseAutoTracker","context","factory","eventName","scanPaymentInputStarted","CHECKOUT_SELECTORS","CheckoutDetector","BaseAutoTracker","context","factory","event","element","text","href","selector","form","DATA_TRACK_EVENT_MAP","resolveDataTrackEvent","value","normalized","buildSelector","selector","SelectorDetector","BaseAutoTracker","context","factory","selectors","event","element","match","selector","built","buildSelector","trackValue","type","resolveDataTrackEvent","data","valueAttr","dataTrack","DEFAULT_KEYWORD_EVENTS","TextDetector","BaseAutoTracker","context","factory","keywords","event","element","text","rule","k","keyword","normalized","HistoryNavigationPatch","listener","args","UrlDetector","BaseAutoTracker","context","factory","patterns","pattern","HistoryNavigationPatch","href","path","isPurchase","CONFIGURED_DETECTORS","FORM_DETECTORS","AutoTrackerFactory","context","factory","auto","rules","detectors","logger","SelectorDetector","TextDetector","UrlDetector","CheckoutDetector","CardDetector","paymentCfg","resolver","SelectorResolver","formKeys","entry","cfg","ConfiguredFormDetector","ConfiguredSelectorDetector","ConversionDeduper","key","buildAddToCartDedupeKey","data","now","windowMs","bucket","getInteractionBucket","productId","quantity","normalizeQuantity","productName","window","CLICK_ORIGINS","secondBucket","now","currentPath","buildCanonicalDedupeKey","type","data","origin","sessionId","payload","bucket","getInteractionBucket","purchase","lead","identity","buildAddToCartDedupeKey","remove","view","BaseTracker","factory","AddPaymentInfoTracker","BaseTracker","factory","data","AddToCartTracker","BaseTracker","factory","data","InitiateCheckoutTracker","BaseTracker","factory","data","LeadTracker","BaseTracker","factory","data","PurchaseTracker","BaseTracker","factory","data","RemoveFromCartTracker","BaseTracker","factory","data","SearchTracker","BaseTracker","factory","data","ViewContentTracker","BaseTracker","factory","data","COMMERCE_EVENT_TYPES","TrackerFactory","context","trackFn","dedupeSessionId","commerce","cfg","CommerceResolver","OrderCalculator","PurchaseTracker","LeadTracker","AddToCartTracker","RemoveFromCartTracker","InitiateCheckoutTracker","AddPaymentInfoTracker","ViewContentTracker","SearchTracker","type","data","options","search","query","purchase","lead","origin","buildCanonicalDedupeKey","key","enriched","normalized","isCommerceEventType","productId","quantity","ConversionEngine","context","ConversionDeduper","commerce","ProductCatalog","CommerceState","TrackerFactory","type","data","options","AutoTrackerFactory","detector","i","dedupeKey","key","event","ConversionModule","context","ConversionEngine","data","FingerprintEngine","context","NavigationObserver","onNavigate","args","PageViewDeduper","dedupeMs","path","timestamp","PageViewEngine","context","PageViewDeduper","pageView","NavigationObserver","path","timestamp","event","SessionEngine","context","ttlMs","event","renewOnActivity","session","result","expiredEvent","renewedEvent","VisitorEngine","context","CoreModule","context","VisitorEngine","SessionEngine","FingerprintEngine","PageViewEngine","DestinationRegistry","destination","name","existing","event","adapter","emptyCounters","DestinationMetrics","name","counters","count","adapter","result","sent","deduped","failed","pixelIds","tagIds","ids","id","kind","key","total","perDestination","destTotal","DestinationLogger","_DestinationLogger","logger","scope","name","message","args","DestinationErrorHandler","logger","continueOnError","adapter","error","duration","message","DestinationExecutor","options","adapter","event","startedAt","controller","timeoutId","context","result","enriched","error","failed","DestinationDispatcher","config","raw","event","destinations","results","batch","settled","adapter","j","outcome","failed","DestinationPipeline","_DestinationPipeline","stages","event","steps","current","stage","DestinationSubscriber","dispatcher","onEvent","event","DEFAULT_COMMERCE_EVENT_TYPES","BaseDestinationAdapter","options","event","status","duration","extras","ConsoleDestination","BaseDestinationAdapter","options","DEFAULT_COMMERCE_EVENT_TYPES","message","payload","context","startedAt","MemoryDestination","BaseDestinationAdapter","DEFAULT_COMMERCE_EVENT_TYPES","context","startedAt","payload","event","MockDestination","BaseDestinationAdapter","options","DEFAULT_COMMERCE_EVENT_TYPES","context","startedAt","ms","signal","resolve","reject","timer","cleanup","onAbort","globalSeen","buildExternalPageViewKey","destinationName","destinationId","eventType","pathOrUrl","sessionId","shouldSkipExternalPageView","key","scriptCache","loadScript","options","existing","timeoutMs","promise","resolve","reject","script","key","value","timer","cleanup","entry","releaseScript","src","META_PIXEL_SCRIPT_SRC","getWindow","ensureFbqStub","win","fbq","args","fn","MetaScriptLoader","timeoutMs","loadScript","META_PIXEL_SCRIPT_SRC","releaseScript","MetaBrowserDestination","BaseDestinationAdapter","deps","MetaScriptLoader","event","timeoutMs","error","fbq","initFailed","pixelId","context","startedAt","signal","path","sessionId","sent","deduped","key","buildExternalPageViewKey","shouldSkipExternalPageView","GOOGLE_GTAG_SCRIPT_BASE","getWindow","ensureGtagStub","win","args","GoogleScriptLoader","primaryTagId","timeoutMs","gtag","src","GOOGLE_GTAG_SCRIPT_BASE","loadScript","releaseScript","GoogleBrowserDestination","BaseDestinationAdapter","deps","GoogleScriptLoader","event","timeoutMs","primary","error","gtag","initFailed","tagId","context","startedAt","signal","path","url","title","sessionId","sent","deduped","key","buildExternalPageViewKey","shouldSkipExternalPageView","TIKTOK_PIXEL_SCRIPT_SRC","getWindow","ensureTtqStub","win","ttq","TikTokScriptLoader","timeoutMs","loadScript","TIKTOK_PIXEL_SCRIPT_SRC","releaseScript","TikTokBrowserDestination","BaseDestinationAdapter","deps","TikTokScriptLoader","event","timeoutMs","error","ttq","initFailed","pixelId","context","startedAt","signal","path","sessionId","sent","deduped","key","buildExternalPageViewKey","shouldSkipExternalPageView","dedupeId","IntegrationEngine","pixelLogger","config","hooks","extraAdapters","DestinationRegistry","DestinationMetrics","DestinationLogger","DestinationPipeline","errorHandler","DestinationErrorHandler","executor","DestinationExecutor","DestinationDispatcher","destinations","debug","ConsoleDestination","message","payload","MemoryDestination","MockDestination","MetaBrowserDestination","GoogleBrowserDestination","TikTokBrowserDestination","adapter","event","processed","name","removed","IntegrationsModule","context","moduleConfig","IntegrationEngine","DestinationSubscriber","event","adapter","name","PrivacyModule","context","DispatcherSubscriber","dispatcher","onEvent","event","BatchManager","events","maxSize","limit","batch","config","IdentityCompressionStrategy","payload","createCompressionStrategy","config","IdentityCompressionStrategy","getCompressionDebugState","strategy","lastResult","CoordinationManager","config","instanceId","onLeaderChange","event","message","tabId","wasLeader","DeadLetterManager","config","events","reason","attempts","lastError","entry","id","index","TransportDelivery","deps","events","batch","result","error","FlushManager","config","onFlush","handler","type","entry","OfflineDetector","onOnline","onOffline","handleOnline","handleOffline","entry","offline","OrderingManager","config","event","correlationId","transactionGroup","records","left","right","maxGlobal","max","record","maxSession","lastWithCorrelation","recordCount","EnqueueStage","queue","event","NormalizeStage","event","ValidateStage","event","TransportPipeline","_TransportPipeline","stages","queue","ValidateStage","NormalizeStage","EnqueueStage","event","steps","current","stage","PersistentQueue","storage","ordering","backpressure","loaded","event","decision","record","applied","predicate","before","removed","records","MemoryQueue","event","predicate","before","kept","MemoryQueueStorage","records","LocalStorageQueueStorage","storageKey","raw","parsed","records","testKey","STORE_NAME","IndexedDBQueueStorage","dbName","resolve","reject","request","database","records","transaction","store","clearRequest","record","buildStorageKey","options","prefix","namespace","pixelId","buildDbName","createByType","type","key","LocalStorageQueueStorage","IndexedDBQueueStorage","MemoryQueueStorage","resolveFallbackChain","preferred","order","rest","item","createQueueStorage","chain","storage","createQueueStorageFromConfig","config","ReplayManager","config","queue","handler","trigger","count","BackpressureManager","config","currentSize","rate","accept","items","incoming","decision","CircuitBreaker","config","CircuitBreakerSender","circuitBreaker","inner","events","options","result","error","calculateBackoffDelay","attempt","config","delay","RetryEngine","config","logger","task","taskId","id","resolve","reject","cancelled","entry","runAttempt","error","delay","calculateBackoffDelay","generateEventId","mapCategory","event","extractData","type","timestamp","category","path","url","hostname","language","timezone","identifiers","rest","mapIdentifiers","base","EventPayloadBuilder","context","eventId","config","services","metadata","visitorId","sessionId","fingerprint","events","first","apiEvents","fetchWithTimeout","url","options","timeoutMs","externalSignal","init","controller","timeoutId","SINGLE_ENDPOINT","BATCH_ENDPOINT","HttpSender","config","payloadBuilder","compression","logger","events","options","useBatch","url","rawBody","compressed","response","fetchWithTimeout","body","ack","error","message","log","MockSender","logger","options","events","batch","total","event","signal","delayMs","resolve","reject","timer","cleanup","onAbort","TimedSender","inner","config","events","options","controller","signals","combined","combineAbortSignals","timeoutId","signal","TransportEngine","context","queue","sender","moduleConfig","OrderingManager","BackpressureManager","DeadLetterManager","CircuitBreaker","CoordinationManager","storage","createQueueStorageFromConfig","PersistentQueue","MemoryQueue","TransportPipeline","compression","createCompressionStrategy","payloadBuilder","EventPayloadBuilder","useHttp","HttpSender","mockSender","MockSender","eventSender","CircuitBreakerSender","timedSender","TimedSender","ReplayManager","batchManager","BatchManager","flushManager","FlushManager","retryEngine","RetryEngine","offlineDetector","OfflineDetector","TransportDelivery","events","error","isLeader","event","offline","options","count","raw","parsed","senderState","getCompressionDebugState","TransportModule","context","TransportEngine","DispatcherSubscriber","event","offline","options","raw","ModuleRegistry","module","existing","BaseEventBuilder","metadataService","attribution","event","metadata","identifiers","hasIdentifiers","key","value","ConsolePixelLogger","debugEnabled","args","DEFAULT_ATTRIBUTION_CONFIG","ATTRIBUTION_STORAGE_KEY","BUILTIN_CLICK_PARAMS","ClickIdParser","customParams","params","result","customClickIds","key","value","fbclid","existingFbc","CookieCollector","cookies","result","map","cookieName","field","value","acc","part","rawKey","rest","AttributionCollector","options","ClickIdParser","CookieCollector","fromUrl","fromCookies","merged","customClickIds","fbc","existing","incoming","next","key","value","now","AttributionStore","storage","options","ATTRIBUTION_STORAGE_KEY","snapshot","anchor","AttributionServiceImpl","storage","config","DEFAULT_ATTRIBUTION_CONFIG","AttributionStore","AttributionCollector","stored","fresh","partial","BrowserMetadataServiceImpl","timezone","DispatcherServiceImpl","event","listener","DEFAULT_FINGERPRINT_KEY","hashFingerprintInput","input","hash","index","positiveHash","secondaryHash","computeLightFingerprint","metadataService","metadata","components","FingerprintServiceImpl","storage","config","existing","fingerprint","BrowserStorageAdapter","storage","key","value","predicate","keysToRemove","index","MemoryStorageAdapter","key","value","predicate","supportsNamespaceClear","adapter","StorageServiceImpl","namespace","prefix","key","raw","value","namespaceKeyPrefix","createStorageAdapter","persistence","mode","MemoryStorageAdapter","BrowserStorageAdapter","resolveStorageAdapterName","createRandomSuffix","generateSessionId","DEFAULT_SESSION_KEY","SessionServiceImpl","storage","config","raw","now","ttlMs","data","sessionId","generateSessionId","previousSessionId","createRandomSuffix","generateVisitorId","DEFAULT_VISITOR_KEY","VisitorServiceImpl","storage","config","existing","visitorId","generateVisitorId","PixelRuntime","config","ModuleRegistry","ConsolePixelLogger","module","error","logger","index","namespace","prefix","persistence","visitorStorage","sessionStorage","fingerprintStorage","attributionStorage","storage","browserMetadata","BrowserMetadataServiceImpl","attribution","AttributionServiceImpl","DEFAULT_ATTRIBUTION_CONFIG","eventBuilder","BaseEventBuilder","visitor","VisitorServiceImpl","session","SessionServiceImpl","fingerprint","FingerprintServiceImpl","dispatcher","DispatcherServiceImpl","StorageServiceImpl","createStorageAdapter","Pixel","config","PixelRuntime","ConversionModule","TransportModule","IntegrationsModule","PrivacyModule","CoreModule","BehaviorModule","data","offline","options","raw","DEFAULT_ATTRIBUTION_CONFIG","DEFAULT_BEHAVIOR_MODULE_CONFIG","DEFAULT_CONVERSION_MODULE_CONFIG","DEFAULT_CORE_MODULE_CONFIG","DEFAULT_INTEGRATIONS_MODULE_CONFIG","DEFAULT_PRIVACY_MODULE_CONFIG","DEFAULT_TRANSPORT_MODULE_CONFIG","DEFAULT_PIXEL_CONFIG","DEFAULT_ATTRIBUTION_CONFIG","DEFAULT_CORE_MODULE_CONFIG","DEFAULT_BEHAVIOR_MODULE_CONFIG","DEFAULT_CONVERSION_MODULE_CONFIG","DEFAULT_TRANSPORT_MODULE_CONFIG","DEFAULT_INTEGRATIONS_MODULE_CONFIG","DEFAULT_PRIVACY_MODULE_CONFIG"]}
|