@selwise/widget 0.0.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.
Files changed (552) hide show
  1. package/dist/npm/cjs/constants.js +167 -0
  2. package/dist/npm/cjs/constants.js.map +1 -0
  3. package/dist/npm/cjs/core/conflict-resolver.js +203 -0
  4. package/dist/npm/cjs/core/conflict-resolver.js.map +1 -0
  5. package/dist/npm/cjs/core/event-batcher.js +977 -0
  6. package/dist/npm/cjs/core/event-batcher.js.map +1 -0
  7. package/dist/npm/cjs/core/experiment-overrides.js +178 -0
  8. package/dist/npm/cjs/core/experiment-overrides.js.map +1 -0
  9. package/dist/npm/cjs/core/experiments.js +317 -0
  10. package/dist/npm/cjs/core/experiments.js.map +1 -0
  11. package/dist/npm/cjs/core/frequency-caps.js +297 -0
  12. package/dist/npm/cjs/core/frequency-caps.js.map +1 -0
  13. package/dist/npm/cjs/core/index.js +27 -0
  14. package/dist/npm/cjs/core/index.js.map +1 -0
  15. package/dist/npm/cjs/core/indexeddb-queue.js +333 -0
  16. package/dist/npm/cjs/core/indexeddb-queue.js.map +1 -0
  17. package/dist/npm/cjs/core/journey-tracker.js +243 -0
  18. package/dist/npm/cjs/core/journey-tracker.js.map +1 -0
  19. package/dist/npm/cjs/core/page-targeting/index.js +72 -0
  20. package/dist/npm/cjs/core/page-targeting/index.js.map +1 -0
  21. package/dist/npm/cjs/core/script-executor.js +80 -0
  22. package/dist/npm/cjs/core/script-executor.js.map +1 -0
  23. package/dist/npm/cjs/core/segments.js +172 -0
  24. package/dist/npm/cjs/core/segments.js.map +1 -0
  25. package/dist/npm/cjs/core/tracker.js +798 -0
  26. package/dist/npm/cjs/core/tracker.js.map +1 -0
  27. package/dist/npm/cjs/datalayer/basket.js +385 -0
  28. package/dist/npm/cjs/datalayer/basket.js.map +1 -0
  29. package/dist/npm/cjs/datalayer/cart-association.js +226 -0
  30. package/dist/npm/cjs/datalayer/cart-association.js.map +1 -0
  31. package/dist/npm/cjs/datalayer/checkout.js +382 -0
  32. package/dist/npm/cjs/datalayer/checkout.js.map +1 -0
  33. package/dist/npm/cjs/datalayer/constants.js +163 -0
  34. package/dist/npm/cjs/datalayer/constants.js.map +1 -0
  35. package/dist/npm/cjs/datalayer/index.js +1010 -0
  36. package/dist/npm/cjs/datalayer/index.js.map +1 -0
  37. package/dist/npm/cjs/datalayer/listener.js +416 -0
  38. package/dist/npm/cjs/datalayer/listener.js.map +1 -0
  39. package/dist/npm/cjs/datalayer/page.js +343 -0
  40. package/dist/npm/cjs/datalayer/page.js.map +1 -0
  41. package/dist/npm/cjs/datalayer/product.js +517 -0
  42. package/dist/npm/cjs/datalayer/product.js.map +1 -0
  43. package/dist/npm/cjs/datalayer/reverse-mappings.js +139 -0
  44. package/dist/npm/cjs/datalayer/reverse-mappings.js.map +1 -0
  45. package/dist/npm/cjs/datalayer/search.js +363 -0
  46. package/dist/npm/cjs/datalayer/search.js.map +1 -0
  47. package/dist/npm/cjs/datalayer/types.js +134 -0
  48. package/dist/npm/cjs/datalayer/types.js.map +1 -0
  49. package/dist/npm/cjs/datalayer/user.js +372 -0
  50. package/dist/npm/cjs/datalayer/user.js.map +1 -0
  51. package/dist/npm/cjs/debug/index.js +679 -0
  52. package/dist/npm/cjs/debug/index.js.map +1 -0
  53. package/dist/npm/cjs/entries/cdn.js +72 -0
  54. package/dist/npm/cjs/entries/cdn.js.map +1 -0
  55. package/dist/npm/cjs/index.js +10 -0
  56. package/dist/npm/cjs/index.js.map +1 -0
  57. package/dist/npm/cjs/modules/contract/recommendation-contract.js +119 -0
  58. package/dist/npm/cjs/modules/contract/recommendation-contract.js.map +1 -0
  59. package/dist/npm/cjs/modules/contract/search-contract.js +18 -0
  60. package/dist/npm/cjs/modules/contract/search-contract.js.map +1 -0
  61. package/dist/npm/cjs/modules/contract/tracking-contract.js +16 -0
  62. package/dist/npm/cjs/modules/contract/tracking-contract.js.map +1 -0
  63. package/dist/npm/cjs/modules/contract/widget-contract.js +10 -0
  64. package/dist/npm/cjs/modules/contract/widget-contract.js.map +1 -0
  65. package/dist/npm/cjs/modules/products/tracking.js +214 -0
  66. package/dist/npm/cjs/modules/products/tracking.js.map +1 -0
  67. package/dist/npm/cjs/modules/recommendation/cart-handlers.js +52 -0
  68. package/dist/npm/cjs/modules/recommendation/cart-handlers.js.map +1 -0
  69. package/dist/npm/cjs/modules/recommendation/components/product-card-renderer.js +287 -0
  70. package/dist/npm/cjs/modules/recommendation/components/product-card-renderer.js.map +1 -0
  71. package/dist/npm/cjs/modules/recommendation/index.js +678 -0
  72. package/dist/npm/cjs/modules/recommendation/index.js.map +1 -0
  73. package/dist/npm/cjs/modules/recommendation/renderers/grid.js +21 -0
  74. package/dist/npm/cjs/modules/recommendation/renderers/grid.js.map +1 -0
  75. package/dist/npm/cjs/modules/recommendation/renderers/list.js +22 -0
  76. package/dist/npm/cjs/modules/recommendation/renderers/list.js.map +1 -0
  77. package/dist/npm/cjs/modules/recommendation/renderers/masonry.js +22 -0
  78. package/dist/npm/cjs/modules/recommendation/renderers/masonry.js.map +1 -0
  79. package/dist/npm/cjs/modules/recommendation/renderers/slider-renderer.js +145 -0
  80. package/dist/npm/cjs/modules/recommendation/renderers/slider-renderer.js.map +1 -0
  81. package/dist/npm/cjs/modules/recommendation/slider-controls.js +201 -0
  82. package/dist/npm/cjs/modules/recommendation/slider-controls.js.map +1 -0
  83. package/dist/npm/cjs/modules/recommendation/tracking.js +247 -0
  84. package/dist/npm/cjs/modules/recommendation/tracking.js.map +1 -0
  85. package/dist/npm/cjs/modules/recommendation/utils/dom.js +70 -0
  86. package/dist/npm/cjs/modules/recommendation/utils/dom.js.map +1 -0
  87. package/dist/npm/cjs/modules/recommendation/utils/format.js +13 -0
  88. package/dist/npm/cjs/modules/recommendation/utils/format.js.map +1 -0
  89. package/dist/npm/cjs/modules/recommendation/utils/index.js +22 -0
  90. package/dist/npm/cjs/modules/recommendation/utils/index.js.map +1 -0
  91. package/dist/npm/cjs/modules/renderer/helpers.js +16 -0
  92. package/dist/npm/cjs/modules/renderer/helpers.js.map +1 -0
  93. package/dist/npm/cjs/modules/renderer/index.js +52 -0
  94. package/dist/npm/cjs/modules/renderer/index.js.map +1 -0
  95. package/dist/npm/cjs/modules/renderer/style-resolver.js +11 -0
  96. package/dist/npm/cjs/modules/renderer/style-resolver.js.map +1 -0
  97. package/dist/npm/cjs/modules/renderer/styles/index.js +254 -0
  98. package/dist/npm/cjs/modules/renderer/styles/index.js.map +1 -0
  99. package/dist/npm/cjs/modules/renderer/styles.js +7 -0
  100. package/dist/npm/cjs/modules/renderer/styles.js.map +1 -0
  101. package/dist/npm/cjs/modules/renderer/utils/helpers.js +243 -0
  102. package/dist/npm/cjs/modules/renderer/utils/helpers.js.map +1 -0
  103. package/dist/npm/cjs/modules/renderer/utils/image-renderer.js +65 -0
  104. package/dist/npm/cjs/modules/renderer/utils/image-renderer.js.map +1 -0
  105. package/dist/npm/cjs/modules/renderer/utils/placement.js +34 -0
  106. package/dist/npm/cjs/modules/renderer/utils/placement.js.map +1 -0
  107. package/dist/npm/cjs/modules/renderer/utils.js +61 -0
  108. package/dist/npm/cjs/modules/renderer/utils.js.map +1 -0
  109. package/dist/npm/cjs/modules/renderer/widgets/announcement-bar.js +84 -0
  110. package/dist/npm/cjs/modules/renderer/widgets/announcement-bar.js.map +1 -0
  111. package/dist/npm/cjs/modules/renderer/widgets/cart-count.js +211 -0
  112. package/dist/npm/cjs/modules/renderer/widgets/cart-count.js.map +1 -0
  113. package/dist/npm/cjs/modules/renderer/widgets/cookie-consent.js +459 -0
  114. package/dist/npm/cjs/modules/renderer/widgets/cookie-consent.js.map +1 -0
  115. package/dist/npm/cjs/modules/renderer/widgets/countdown-timer.js +132 -0
  116. package/dist/npm/cjs/modules/renderer/widgets/countdown-timer.js.map +1 -0
  117. package/dist/npm/cjs/modules/renderer/widgets/custom.js +58 -0
  118. package/dist/npm/cjs/modules/renderer/widgets/custom.js.map +1 -0
  119. package/dist/npm/cjs/modules/renderer/widgets/embedded-card.js +97 -0
  120. package/dist/npm/cjs/modules/renderer/widgets/embedded-card.js.map +1 -0
  121. package/dist/npm/cjs/modules/renderer/widgets/exit-intent-popup.js +151 -0
  122. package/dist/npm/cjs/modules/renderer/widgets/exit-intent-popup.js.map +1 -0
  123. package/dist/npm/cjs/modules/renderer/widgets/floating-button.js +70 -0
  124. package/dist/npm/cjs/modules/renderer/widgets/floating-button.js.map +1 -0
  125. package/dist/npm/cjs/modules/renderer/widgets/helpers.js +87 -0
  126. package/dist/npm/cjs/modules/renderer/widgets/helpers.js.map +1 -0
  127. package/dist/npm/cjs/modules/renderer/widgets/index.js +39 -0
  128. package/dist/npm/cjs/modules/renderer/widgets/index.js.map +1 -0
  129. package/dist/npm/cjs/modules/renderer/widgets/inline-banner.js +124 -0
  130. package/dist/npm/cjs/modules/renderer/widgets/inline-banner.js.map +1 -0
  131. package/dist/npm/cjs/modules/renderer/widgets/newsletter.js +280 -0
  132. package/dist/npm/cjs/modules/renderer/widgets/newsletter.js.map +1 -0
  133. package/dist/npm/cjs/modules/renderer/widgets/product-view-count.js +197 -0
  134. package/dist/npm/cjs/modules/renderer/widgets/product-view-count.js.map +1 -0
  135. package/dist/npm/cjs/modules/renderer/widgets/slide-in.js +105 -0
  136. package/dist/npm/cjs/modules/renderer/widgets/slide-in.js.map +1 -0
  137. package/dist/npm/cjs/modules/renderer/widgets/sticky-footer.js +47 -0
  138. package/dist/npm/cjs/modules/renderer/widgets/sticky-footer.js.map +1 -0
  139. package/dist/npm/cjs/modules/search/cart/index.js +42 -0
  140. package/dist/npm/cjs/modules/search/cart/index.js.map +1 -0
  141. package/dist/npm/cjs/modules/search/components/index.js +13 -0
  142. package/dist/npm/cjs/modules/search/components/index.js.map +1 -0
  143. package/dist/npm/cjs/modules/search/components/search-box.js +28 -0
  144. package/dist/npm/cjs/modules/search/components/search-box.js.map +1 -0
  145. package/dist/npm/cjs/modules/search/components/search-item.js +197 -0
  146. package/dist/npm/cjs/modules/search/components/search-item.js.map +1 -0
  147. package/dist/npm/cjs/modules/search/components/suggestions.js +132 -0
  148. package/dist/npm/cjs/modules/search/components/suggestions.js.map +1 -0
  149. package/dist/npm/cjs/modules/search/index.js +646 -0
  150. package/dist/npm/cjs/modules/search/index.js.map +1 -0
  151. package/dist/npm/cjs/modules/search/renderers/position-renderers.js +229 -0
  152. package/dist/npm/cjs/modules/search/renderers/position-renderers.js.map +1 -0
  153. package/dist/npm/cjs/modules/search/renderers/results-renderer.js +180 -0
  154. package/dist/npm/cjs/modules/search/renderers/results-renderer.js.map +1 -0
  155. package/dist/npm/cjs/modules/search/services/api-service.js +121 -0
  156. package/dist/npm/cjs/modules/search/services/api-service.js.map +1 -0
  157. package/dist/npm/cjs/modules/search/services/tracking-service.js +263 -0
  158. package/dist/npm/cjs/modules/search/services/tracking-service.js.map +1 -0
  159. package/dist/npm/cjs/modules/search/styles.js +864 -0
  160. package/dist/npm/cjs/modules/search/styles.js.map +1 -0
  161. package/dist/npm/cjs/modules/search/utils/helpers.js +100 -0
  162. package/dist/npm/cjs/modules/search/utils/helpers.js.map +1 -0
  163. package/dist/npm/cjs/modules/search/utils/icons.js +41 -0
  164. package/dist/npm/cjs/modules/search/utils/icons.js.map +1 -0
  165. package/dist/npm/cjs/modules/search/utils/index.js +22 -0
  166. package/dist/npm/cjs/modules/search/utils/index.js.map +1 -0
  167. package/dist/npm/cjs/modules/search/utils/storage.js +58 -0
  168. package/dist/npm/cjs/modules/search/utils/storage.js.map +1 -0
  169. package/dist/npm/cjs/selwise.js +1160 -0
  170. package/dist/npm/cjs/selwise.js.map +1 -0
  171. package/dist/npm/cjs/sentry-test.js +118 -0
  172. package/dist/npm/cjs/sentry-test.js.map +1 -0
  173. package/dist/npm/cjs/sentry.js +451 -0
  174. package/dist/npm/cjs/sentry.js.map +1 -0
  175. package/dist/npm/cjs/shared/cart/handlers.js +259 -0
  176. package/dist/npm/cjs/shared/cart/handlers.js.map +1 -0
  177. package/dist/npm/cjs/shared/cart/index.js +23 -0
  178. package/dist/npm/cjs/shared/cart/index.js.map +1 -0
  179. package/dist/npm/cjs/shared/cart/types.js +7 -0
  180. package/dist/npm/cjs/shared/cart/types.js.map +1 -0
  181. package/dist/npm/cjs/shared/product-card/index.js +24 -0
  182. package/dist/npm/cjs/shared/product-card/index.js.map +1 -0
  183. package/dist/npm/cjs/shared/product-card/renderer.js +341 -0
  184. package/dist/npm/cjs/shared/product-card/renderer.js.map +1 -0
  185. package/dist/npm/cjs/shared/product-card/styles.js +195 -0
  186. package/dist/npm/cjs/shared/product-card/styles.js.map +1 -0
  187. package/dist/npm/cjs/shared/product-card/types.js +67 -0
  188. package/dist/npm/cjs/shared/product-card/types.js.map +1 -0
  189. package/dist/npm/cjs/types/config.js +6 -0
  190. package/dist/npm/cjs/types/config.js.map +1 -0
  191. package/dist/npm/cjs/types/experiments.js +17 -0
  192. package/dist/npm/cjs/types/experiments.js.map +1 -0
  193. package/dist/npm/cjs/types/global-api.js +3 -0
  194. package/dist/npm/cjs/types/global-api.js.map +1 -0
  195. package/dist/npm/cjs/types/index.js +27 -0
  196. package/dist/npm/cjs/types/index.js.map +1 -0
  197. package/dist/npm/cjs/types/recommendation.js +6 -0
  198. package/dist/npm/cjs/types/recommendation.js.map +1 -0
  199. package/dist/npm/cjs/types/renderer.js +6 -0
  200. package/dist/npm/cjs/types/renderer.js.map +1 -0
  201. package/dist/npm/cjs/types/search.js +6 -0
  202. package/dist/npm/cjs/types/search.js.map +1 -0
  203. package/dist/npm/cjs/utils/api-url.js +35 -0
  204. package/dist/npm/cjs/utils/api-url.js.map +1 -0
  205. package/dist/npm/cjs/utils/debounce.js +74 -0
  206. package/dist/npm/cjs/utils/debounce.js.map +1 -0
  207. package/dist/npm/cjs/utils/event-id.js +23 -0
  208. package/dist/npm/cjs/utils/event-id.js.map +1 -0
  209. package/dist/npm/cjs/utils/index.js +28 -0
  210. package/dist/npm/cjs/utils/index.js.map +1 -0
  211. package/dist/npm/cjs/utils/logger.js +74 -0
  212. package/dist/npm/cjs/utils/logger.js.map +1 -0
  213. package/dist/npm/cjs/utils/sanitize.js +159 -0
  214. package/dist/npm/cjs/utils/sanitize.js.map +1 -0
  215. package/dist/npm/cjs/utils/storage.js +285 -0
  216. package/dist/npm/cjs/utils/storage.js.map +1 -0
  217. package/dist/npm/cjs/utils/tracking-metadata.js +18 -0
  218. package/dist/npm/cjs/utils/tracking-metadata.js.map +1 -0
  219. package/dist/npm/cjs/utils/url-matcher.js +11 -0
  220. package/dist/npm/cjs/utils/url-matcher.js.map +1 -0
  221. package/dist/npm/esm/constants.d.ts +130 -0
  222. package/dist/npm/esm/constants.js +164 -0
  223. package/dist/npm/esm/constants.js.map +1 -0
  224. package/dist/npm/esm/core/conflict-resolver.d.ts +96 -0
  225. package/dist/npm/esm/core/conflict-resolver.js +198 -0
  226. package/dist/npm/esm/core/conflict-resolver.js.map +1 -0
  227. package/dist/npm/esm/core/event-batcher.d.ts +253 -0
  228. package/dist/npm/esm/core/event-batcher.js +973 -0
  229. package/dist/npm/esm/core/event-batcher.js.map +1 -0
  230. package/dist/npm/esm/core/experiment-overrides.d.ts +7 -0
  231. package/dist/npm/esm/core/experiment-overrides.js +172 -0
  232. package/dist/npm/esm/core/experiment-overrides.js.map +1 -0
  233. package/dist/npm/esm/core/experiments.d.ts +90 -0
  234. package/dist/npm/esm/core/experiments.js +313 -0
  235. package/dist/npm/esm/core/experiments.js.map +1 -0
  236. package/dist/npm/esm/core/frequency-caps.d.ts +124 -0
  237. package/dist/npm/esm/core/frequency-caps.js +292 -0
  238. package/dist/npm/esm/core/frequency-caps.js.map +1 -0
  239. package/dist/npm/esm/core/index.d.ts +10 -0
  240. package/dist/npm/esm/core/index.js +11 -0
  241. package/dist/npm/esm/core/index.js.map +1 -0
  242. package/dist/npm/esm/core/indexeddb-queue.d.ts +83 -0
  243. package/dist/npm/esm/core/indexeddb-queue.js +328 -0
  244. package/dist/npm/esm/core/indexeddb-queue.js.map +1 -0
  245. package/dist/npm/esm/core/journey-tracker.d.ts +102 -0
  246. package/dist/npm/esm/core/journey-tracker.js +237 -0
  247. package/dist/npm/esm/core/journey-tracker.js.map +1 -0
  248. package/dist/npm/esm/core/page-targeting/index.d.ts +8 -0
  249. package/dist/npm/esm/core/page-targeting/index.js +67 -0
  250. package/dist/npm/esm/core/page-targeting/index.js.map +1 -0
  251. package/dist/npm/esm/core/script-executor.d.ts +31 -0
  252. package/dist/npm/esm/core/script-executor.js +76 -0
  253. package/dist/npm/esm/core/script-executor.js.map +1 -0
  254. package/dist/npm/esm/core/segments.d.ts +39 -0
  255. package/dist/npm/esm/core/segments.js +168 -0
  256. package/dist/npm/esm/core/segments.js.map +1 -0
  257. package/dist/npm/esm/core/tracker.d.ts +182 -0
  258. package/dist/npm/esm/core/tracker.js +794 -0
  259. package/dist/npm/esm/core/tracker.js.map +1 -0
  260. package/dist/npm/esm/datalayer/basket.d.ts +104 -0
  261. package/dist/npm/esm/datalayer/basket.js +381 -0
  262. package/dist/npm/esm/datalayer/basket.js.map +1 -0
  263. package/dist/npm/esm/datalayer/cart-association.d.ts +65 -0
  264. package/dist/npm/esm/datalayer/cart-association.js +222 -0
  265. package/dist/npm/esm/datalayer/cart-association.js.map +1 -0
  266. package/dist/npm/esm/datalayer/checkout.d.ts +96 -0
  267. package/dist/npm/esm/datalayer/checkout.js +378 -0
  268. package/dist/npm/esm/datalayer/checkout.js.map +1 -0
  269. package/dist/npm/esm/datalayer/constants.d.ts +77 -0
  270. package/dist/npm/esm/datalayer/constants.js +160 -0
  271. package/dist/npm/esm/datalayer/constants.js.map +1 -0
  272. package/dist/npm/esm/datalayer/index.d.ts +212 -0
  273. package/dist/npm/esm/datalayer/index.js +991 -0
  274. package/dist/npm/esm/datalayer/index.js.map +1 -0
  275. package/dist/npm/esm/datalayer/listener.d.ts +108 -0
  276. package/dist/npm/esm/datalayer/listener.js +411 -0
  277. package/dist/npm/esm/datalayer/listener.js.map +1 -0
  278. package/dist/npm/esm/datalayer/page.d.ts +94 -0
  279. package/dist/npm/esm/datalayer/page.js +339 -0
  280. package/dist/npm/esm/datalayer/page.js.map +1 -0
  281. package/dist/npm/esm/datalayer/product.d.ts +133 -0
  282. package/dist/npm/esm/datalayer/product.js +513 -0
  283. package/dist/npm/esm/datalayer/product.js.map +1 -0
  284. package/dist/npm/esm/datalayer/reverse-mappings.d.ts +62 -0
  285. package/dist/npm/esm/datalayer/reverse-mappings.js +135 -0
  286. package/dist/npm/esm/datalayer/reverse-mappings.js.map +1 -0
  287. package/dist/npm/esm/datalayer/search.d.ts +108 -0
  288. package/dist/npm/esm/datalayer/search.js +359 -0
  289. package/dist/npm/esm/datalayer/search.js.map +1 -0
  290. package/dist/npm/esm/datalayer/types.d.ts +292 -0
  291. package/dist/npm/esm/datalayer/types.js +131 -0
  292. package/dist/npm/esm/datalayer/types.js.map +1 -0
  293. package/dist/npm/esm/datalayer/user.d.ts +104 -0
  294. package/dist/npm/esm/datalayer/user.js +368 -0
  295. package/dist/npm/esm/datalayer/user.js.map +1 -0
  296. package/dist/npm/esm/debug/index.d.ts +173 -0
  297. package/dist/npm/esm/debug/index.js +673 -0
  298. package/dist/npm/esm/debug/index.js.map +1 -0
  299. package/dist/npm/esm/entries/cdn.d.ts +1 -0
  300. package/dist/npm/esm/entries/cdn.js +35 -0
  301. package/dist/npm/esm/entries/cdn.js.map +1 -0
  302. package/dist/npm/esm/index.d.ts +4 -0
  303. package/dist/npm/esm/index.js +4 -0
  304. package/dist/npm/esm/index.js.map +1 -0
  305. package/dist/npm/esm/modules/contract/recommendation-contract.d.ts +5 -0
  306. package/dist/npm/esm/modules/contract/recommendation-contract.js +107 -0
  307. package/dist/npm/esm/modules/contract/recommendation-contract.js.map +1 -0
  308. package/dist/npm/esm/modules/contract/search-contract.d.ts +1 -0
  309. package/dist/npm/esm/modules/contract/search-contract.js +2 -0
  310. package/dist/npm/esm/modules/contract/search-contract.js.map +1 -0
  311. package/dist/npm/esm/modules/contract/tracking-contract.d.ts +1 -0
  312. package/dist/npm/esm/modules/contract/tracking-contract.js +2 -0
  313. package/dist/npm/esm/modules/contract/tracking-contract.js.map +1 -0
  314. package/dist/npm/esm/modules/contract/widget-contract.d.ts +1 -0
  315. package/dist/npm/esm/modules/contract/widget-contract.js +2 -0
  316. package/dist/npm/esm/modules/contract/widget-contract.js.map +1 -0
  317. package/dist/npm/esm/modules/products/tracking.d.ts +122 -0
  318. package/dist/npm/esm/modules/products/tracking.js +203 -0
  319. package/dist/npm/esm/modules/products/tracking.js.map +1 -0
  320. package/dist/npm/esm/modules/recommendation/cart-handlers.d.ts +10 -0
  321. package/dist/npm/esm/modules/recommendation/cart-handlers.js +49 -0
  322. package/dist/npm/esm/modules/recommendation/cart-handlers.js.map +1 -0
  323. package/dist/npm/esm/modules/recommendation/components/product-card-renderer.d.ts +37 -0
  324. package/dist/npm/esm/modules/recommendation/components/product-card-renderer.js +281 -0
  325. package/dist/npm/esm/modules/recommendation/components/product-card-renderer.js.map +1 -0
  326. package/dist/npm/esm/modules/recommendation/index.d.ts +11 -0
  327. package/dist/npm/esm/modules/recommendation/index.js +674 -0
  328. package/dist/npm/esm/modules/recommendation/index.js.map +1 -0
  329. package/dist/npm/esm/modules/recommendation/renderers/grid.d.ts +5 -0
  330. package/dist/npm/esm/modules/recommendation/renderers/grid.js +18 -0
  331. package/dist/npm/esm/modules/recommendation/renderers/grid.js.map +1 -0
  332. package/dist/npm/esm/modules/recommendation/renderers/list.d.ts +5 -0
  333. package/dist/npm/esm/modules/recommendation/renderers/list.js +19 -0
  334. package/dist/npm/esm/modules/recommendation/renderers/list.js.map +1 -0
  335. package/dist/npm/esm/modules/recommendation/renderers/masonry.d.ts +5 -0
  336. package/dist/npm/esm/modules/recommendation/renderers/masonry.js +19 -0
  337. package/dist/npm/esm/modules/recommendation/renderers/masonry.js.map +1 -0
  338. package/dist/npm/esm/modules/recommendation/renderers/slider-renderer.d.ts +10 -0
  339. package/dist/npm/esm/modules/recommendation/renderers/slider-renderer.js +140 -0
  340. package/dist/npm/esm/modules/recommendation/renderers/slider-renderer.js.map +1 -0
  341. package/dist/npm/esm/modules/recommendation/slider-controls.d.ts +17 -0
  342. package/dist/npm/esm/modules/recommendation/slider-controls.js +187 -0
  343. package/dist/npm/esm/modules/recommendation/slider-controls.js.map +1 -0
  344. package/dist/npm/esm/modules/recommendation/tracking.d.ts +28 -0
  345. package/dist/npm/esm/modules/recommendation/tracking.js +237 -0
  346. package/dist/npm/esm/modules/recommendation/tracking.js.map +1 -0
  347. package/dist/npm/esm/modules/recommendation/utils/dom.d.ts +10 -0
  348. package/dist/npm/esm/modules/recommendation/utils/dom.js +63 -0
  349. package/dist/npm/esm/modules/recommendation/utils/dom.js.map +1 -0
  350. package/dist/npm/esm/modules/recommendation/utils/format.d.ts +4 -0
  351. package/dist/npm/esm/modules/recommendation/utils/format.js +10 -0
  352. package/dist/npm/esm/modules/recommendation/utils/format.js.map +1 -0
  353. package/dist/npm/esm/modules/recommendation/utils/index.d.ts +5 -0
  354. package/dist/npm/esm/modules/recommendation/utils/index.js +6 -0
  355. package/dist/npm/esm/modules/recommendation/utils/index.js.map +1 -0
  356. package/dist/npm/esm/modules/renderer/helpers.d.ts +5 -0
  357. package/dist/npm/esm/modules/renderer/helpers.js +6 -0
  358. package/dist/npm/esm/modules/renderer/helpers.js.map +1 -0
  359. package/dist/npm/esm/modules/renderer/index.d.ts +8 -0
  360. package/dist/npm/esm/modules/renderer/index.js +48 -0
  361. package/dist/npm/esm/modules/renderer/index.js.map +1 -0
  362. package/dist/npm/esm/modules/renderer/style-resolver.d.ts +1 -0
  363. package/dist/npm/esm/modules/renderer/style-resolver.js +8 -0
  364. package/dist/npm/esm/modules/renderer/style-resolver.js.map +1 -0
  365. package/dist/npm/esm/modules/renderer/styles/index.d.ts +12 -0
  366. package/dist/npm/esm/modules/renderer/styles/index.js +250 -0
  367. package/dist/npm/esm/modules/renderer/styles/index.js.map +1 -0
  368. package/dist/npm/esm/modules/renderer/styles.d.ts +1 -0
  369. package/dist/npm/esm/modules/renderer/styles.js +2 -0
  370. package/dist/npm/esm/modules/renderer/styles.js.map +1 -0
  371. package/dist/npm/esm/modules/renderer/utils/helpers.d.ts +58 -0
  372. package/dist/npm/esm/modules/renderer/utils/helpers.js +225 -0
  373. package/dist/npm/esm/modules/renderer/utils/helpers.js.map +1 -0
  374. package/dist/npm/esm/modules/renderer/utils/image-renderer.d.ts +17 -0
  375. package/dist/npm/esm/modules/renderer/utils/image-renderer.js +60 -0
  376. package/dist/npm/esm/modules/renderer/utils/image-renderer.js.map +1 -0
  377. package/dist/npm/esm/modules/renderer/utils/placement.d.ts +6 -0
  378. package/dist/npm/esm/modules/renderer/utils/placement.js +31 -0
  379. package/dist/npm/esm/modules/renderer/utils/placement.js.map +1 -0
  380. package/dist/npm/esm/modules/renderer/utils.d.ts +11 -0
  381. package/dist/npm/esm/modules/renderer/utils.js +44 -0
  382. package/dist/npm/esm/modules/renderer/utils.js.map +1 -0
  383. package/dist/npm/esm/modules/renderer/widgets/announcement-bar.d.ts +5 -0
  384. package/dist/npm/esm/modules/renderer/widgets/announcement-bar.js +81 -0
  385. package/dist/npm/esm/modules/renderer/widgets/announcement-bar.js.map +1 -0
  386. package/dist/npm/esm/modules/renderer/widgets/cart-count.d.ts +6 -0
  387. package/dist/npm/esm/modules/renderer/widgets/cart-count.js +208 -0
  388. package/dist/npm/esm/modules/renderer/widgets/cart-count.js.map +1 -0
  389. package/dist/npm/esm/modules/renderer/widgets/cookie-consent.d.ts +18 -0
  390. package/dist/npm/esm/modules/renderer/widgets/cookie-consent.js +454 -0
  391. package/dist/npm/esm/modules/renderer/widgets/cookie-consent.js.map +1 -0
  392. package/dist/npm/esm/modules/renderer/widgets/countdown-timer.d.ts +5 -0
  393. package/dist/npm/esm/modules/renderer/widgets/countdown-timer.js +129 -0
  394. package/dist/npm/esm/modules/renderer/widgets/countdown-timer.js.map +1 -0
  395. package/dist/npm/esm/modules/renderer/widgets/custom.d.ts +5 -0
  396. package/dist/npm/esm/modules/renderer/widgets/custom.js +55 -0
  397. package/dist/npm/esm/modules/renderer/widgets/custom.js.map +1 -0
  398. package/dist/npm/esm/modules/renderer/widgets/embedded-card.d.ts +5 -0
  399. package/dist/npm/esm/modules/renderer/widgets/embedded-card.js +94 -0
  400. package/dist/npm/esm/modules/renderer/widgets/embedded-card.js.map +1 -0
  401. package/dist/npm/esm/modules/renderer/widgets/exit-intent-popup.d.ts +6 -0
  402. package/dist/npm/esm/modules/renderer/widgets/exit-intent-popup.js +147 -0
  403. package/dist/npm/esm/modules/renderer/widgets/exit-intent-popup.js.map +1 -0
  404. package/dist/npm/esm/modules/renderer/widgets/floating-button.d.ts +5 -0
  405. package/dist/npm/esm/modules/renderer/widgets/floating-button.js +67 -0
  406. package/dist/npm/esm/modules/renderer/widgets/floating-button.js.map +1 -0
  407. package/dist/npm/esm/modules/renderer/widgets/helpers.d.ts +29 -0
  408. package/dist/npm/esm/modules/renderer/widgets/helpers.js +82 -0
  409. package/dist/npm/esm/modules/renderer/widgets/helpers.js.map +1 -0
  410. package/dist/npm/esm/modules/renderer/widgets/index.d.ts +17 -0
  411. package/dist/npm/esm/modules/renderer/widgets/index.js +19 -0
  412. package/dist/npm/esm/modules/renderer/widgets/index.js.map +1 -0
  413. package/dist/npm/esm/modules/renderer/widgets/inline-banner.d.ts +5 -0
  414. package/dist/npm/esm/modules/renderer/widgets/inline-banner.js +121 -0
  415. package/dist/npm/esm/modules/renderer/widgets/inline-banner.js.map +1 -0
  416. package/dist/npm/esm/modules/renderer/widgets/newsletter.d.ts +6 -0
  417. package/dist/npm/esm/modules/renderer/widgets/newsletter.js +277 -0
  418. package/dist/npm/esm/modules/renderer/widgets/newsletter.js.map +1 -0
  419. package/dist/npm/esm/modules/renderer/widgets/product-view-count.d.ts +6 -0
  420. package/dist/npm/esm/modules/renderer/widgets/product-view-count.js +194 -0
  421. package/dist/npm/esm/modules/renderer/widgets/product-view-count.js.map +1 -0
  422. package/dist/npm/esm/modules/renderer/widgets/slide-in.d.ts +5 -0
  423. package/dist/npm/esm/modules/renderer/widgets/slide-in.js +102 -0
  424. package/dist/npm/esm/modules/renderer/widgets/slide-in.js.map +1 -0
  425. package/dist/npm/esm/modules/renderer/widgets/sticky-footer.d.ts +5 -0
  426. package/dist/npm/esm/modules/renderer/widgets/sticky-footer.js +44 -0
  427. package/dist/npm/esm/modules/renderer/widgets/sticky-footer.js.map +1 -0
  428. package/dist/npm/esm/modules/search/cart/index.d.ts +26 -0
  429. package/dist/npm/esm/modules/search/cart/index.js +39 -0
  430. package/dist/npm/esm/modules/search/cart/index.js.map +1 -0
  431. package/dist/npm/esm/modules/search/components/index.d.ts +6 -0
  432. package/dist/npm/esm/modules/search/components/index.js +7 -0
  433. package/dist/npm/esm/modules/search/components/index.js.map +1 -0
  434. package/dist/npm/esm/modules/search/components/search-box.d.ts +11 -0
  435. package/dist/npm/esm/modules/search/components/search-box.js +25 -0
  436. package/dist/npm/esm/modules/search/components/search-box.js.map +1 -0
  437. package/dist/npm/esm/modules/search/components/search-item.d.ts +20 -0
  438. package/dist/npm/esm/modules/search/components/search-item.js +193 -0
  439. package/dist/npm/esm/modules/search/components/search-item.js.map +1 -0
  440. package/dist/npm/esm/modules/search/components/suggestions.d.ts +10 -0
  441. package/dist/npm/esm/modules/search/components/suggestions.js +129 -0
  442. package/dist/npm/esm/modules/search/components/suggestions.js.map +1 -0
  443. package/dist/npm/esm/modules/search/index.d.ts +67 -0
  444. package/dist/npm/esm/modules/search/index.js +642 -0
  445. package/dist/npm/esm/modules/search/index.js.map +1 -0
  446. package/dist/npm/esm/modules/search/renderers/position-renderers.d.ts +23 -0
  447. package/dist/npm/esm/modules/search/renderers/position-renderers.js +221 -0
  448. package/dist/npm/esm/modules/search/renderers/position-renderers.js.map +1 -0
  449. package/dist/npm/esm/modules/search/renderers/results-renderer.d.ts +20 -0
  450. package/dist/npm/esm/modules/search/renderers/results-renderer.js +176 -0
  451. package/dist/npm/esm/modules/search/renderers/results-renderer.js.map +1 -0
  452. package/dist/npm/esm/modules/search/services/api-service.d.ts +18 -0
  453. package/dist/npm/esm/modules/search/services/api-service.js +115 -0
  454. package/dist/npm/esm/modules/search/services/api-service.js.map +1 -0
  455. package/dist/npm/esm/modules/search/services/tracking-service.d.ts +16 -0
  456. package/dist/npm/esm/modules/search/services/tracking-service.js +250 -0
  457. package/dist/npm/esm/modules/search/services/tracking-service.js.map +1 -0
  458. package/dist/npm/esm/modules/search/styles.d.ts +13 -0
  459. package/dist/npm/esm/modules/search/styles.js +860 -0
  460. package/dist/npm/esm/modules/search/styles.js.map +1 -0
  461. package/dist/npm/esm/modules/search/utils/helpers.d.ts +24 -0
  462. package/dist/npm/esm/modules/search/utils/helpers.js +93 -0
  463. package/dist/npm/esm/modules/search/utils/helpers.js.map +1 -0
  464. package/dist/npm/esm/modules/search/utils/icons.d.ts +16 -0
  465. package/dist/npm/esm/modules/search/utils/icons.js +36 -0
  466. package/dist/npm/esm/modules/search/utils/icons.js.map +1 -0
  467. package/dist/npm/esm/modules/search/utils/index.d.ts +6 -0
  468. package/dist/npm/esm/modules/search/utils/index.js +7 -0
  469. package/dist/npm/esm/modules/search/utils/index.js.map +1 -0
  470. package/dist/npm/esm/modules/search/utils/storage.d.ts +7 -0
  471. package/dist/npm/esm/modules/search/utils/storage.js +52 -0
  472. package/dist/npm/esm/modules/search/utils/storage.js.map +1 -0
  473. package/dist/npm/esm/package.json +1 -0
  474. package/dist/npm/esm/selwise.d.ts +209 -0
  475. package/dist/npm/esm/selwise.js +1123 -0
  476. package/dist/npm/esm/selwise.js.map +1 -0
  477. package/dist/npm/esm/sentry-test.d.ts +45 -0
  478. package/dist/npm/esm/sentry-test.js +109 -0
  479. package/dist/npm/esm/sentry-test.js.map +1 -0
  480. package/dist/npm/esm/sentry.d.ts +86 -0
  481. package/dist/npm/esm/sentry.js +441 -0
  482. package/dist/npm/esm/sentry.js.map +1 -0
  483. package/dist/npm/esm/shared/cart/handlers.d.ts +46 -0
  484. package/dist/npm/esm/shared/cart/handlers.js +249 -0
  485. package/dist/npm/esm/shared/cart/handlers.js.map +1 -0
  486. package/dist/npm/esm/shared/cart/index.d.ts +6 -0
  487. package/dist/npm/esm/shared/cart/index.js +7 -0
  488. package/dist/npm/esm/shared/cart/index.js.map +1 -0
  489. package/dist/npm/esm/shared/cart/types.d.ts +30 -0
  490. package/dist/npm/esm/shared/cart/types.js +6 -0
  491. package/dist/npm/esm/shared/cart/types.js.map +1 -0
  492. package/dist/npm/esm/shared/product-card/index.d.ts +7 -0
  493. package/dist/npm/esm/shared/product-card/index.js +8 -0
  494. package/dist/npm/esm/shared/product-card/index.js.map +1 -0
  495. package/dist/npm/esm/shared/product-card/renderer.d.ts +35 -0
  496. package/dist/npm/esm/shared/product-card/renderer.js +334 -0
  497. package/dist/npm/esm/shared/product-card/renderer.js.map +1 -0
  498. package/dist/npm/esm/shared/product-card/styles.d.ts +17 -0
  499. package/dist/npm/esm/shared/product-card/styles.js +190 -0
  500. package/dist/npm/esm/shared/product-card/styles.js.map +1 -0
  501. package/dist/npm/esm/shared/product-card/types.d.ts +84 -0
  502. package/dist/npm/esm/shared/product-card/types.js +63 -0
  503. package/dist/npm/esm/shared/product-card/types.js.map +1 -0
  504. package/dist/npm/esm/types/config.d.ts +26 -0
  505. package/dist/npm/esm/types/config.js +5 -0
  506. package/dist/npm/esm/types/config.js.map +1 -0
  507. package/dist/npm/esm/types/experiments.d.ts +47 -0
  508. package/dist/npm/esm/types/experiments.js +14 -0
  509. package/dist/npm/esm/types/experiments.js.map +1 -0
  510. package/dist/npm/esm/types/global-api.d.ts +40 -0
  511. package/dist/npm/esm/types/global-api.js +2 -0
  512. package/dist/npm/esm/types/global-api.js.map +1 -0
  513. package/dist/npm/esm/types/index.d.ts +9 -0
  514. package/dist/npm/esm/types/index.js +11 -0
  515. package/dist/npm/esm/types/index.js.map +1 -0
  516. package/dist/npm/esm/types/recommendation.d.ts +186 -0
  517. package/dist/npm/esm/types/recommendation.js +5 -0
  518. package/dist/npm/esm/types/recommendation.js.map +1 -0
  519. package/dist/npm/esm/types/renderer.d.ts +99 -0
  520. package/dist/npm/esm/types/renderer.js +5 -0
  521. package/dist/npm/esm/types/renderer.js.map +1 -0
  522. package/dist/npm/esm/types/search.d.ts +186 -0
  523. package/dist/npm/esm/types/search.js +5 -0
  524. package/dist/npm/esm/types/search.js.map +1 -0
  525. package/dist/npm/esm/utils/api-url.d.ts +1 -0
  526. package/dist/npm/esm/utils/api-url.js +32 -0
  527. package/dist/npm/esm/utils/api-url.js.map +1 -0
  528. package/dist/npm/esm/utils/debounce.d.ts +27 -0
  529. package/dist/npm/esm/utils/debounce.js +70 -0
  530. package/dist/npm/esm/utils/debounce.js.map +1 -0
  531. package/dist/npm/esm/utils/event-id.d.ts +5 -0
  532. package/dist/npm/esm/utils/event-id.js +20 -0
  533. package/dist/npm/esm/utils/event-id.js.map +1 -0
  534. package/dist/npm/esm/utils/index.d.ts +11 -0
  535. package/dist/npm/esm/utils/index.js +12 -0
  536. package/dist/npm/esm/utils/index.js.map +1 -0
  537. package/dist/npm/esm/utils/logger.d.ts +31 -0
  538. package/dist/npm/esm/utils/logger.js +66 -0
  539. package/dist/npm/esm/utils/logger.js.map +1 -0
  540. package/dist/npm/esm/utils/sanitize.d.ts +38 -0
  541. package/dist/npm/esm/utils/sanitize.js +148 -0
  542. package/dist/npm/esm/utils/sanitize.js.map +1 -0
  543. package/dist/npm/esm/utils/storage.d.ts +72 -0
  544. package/dist/npm/esm/utils/storage.js +271 -0
  545. package/dist/npm/esm/utils/storage.js.map +1 -0
  546. package/dist/npm/esm/utils/tracking-metadata.d.ts +1 -0
  547. package/dist/npm/esm/utils/tracking-metadata.js +15 -0
  548. package/dist/npm/esm/utils/tracking-metadata.js.map +1 -0
  549. package/dist/npm/esm/utils/url-matcher.d.ts +4 -0
  550. package/dist/npm/esm/utils/url-matcher.js +8 -0
  551. package/dist/npm/esm/utils/url-matcher.js.map +1 -0
  552. package/package.json +62 -0
@@ -0,0 +1,991 @@
1
+ /**
2
+ * Data Layer Manager for Selwise Client Widget
3
+ * Provides GTM-style data layer functionality with window.selwiseLayer
4
+ */
5
+ import { DEFAULT_CONFIG, DEFAULT_PAGE_PATTERNS, DATA_SOURCE } from './constants.js';
6
+ import { PageTracker } from './page.js';
7
+ import { ProductTracker } from './product.js';
8
+ import { BasketTracker } from './basket.js';
9
+ import { CheckoutTracker } from './checkout.js';
10
+ import { UserTracker } from './user.js';
11
+ import { SearchTracker } from './search.js';
12
+ import { ExternalDataLayerListener } from './listener.js';
13
+ import { CartAssociationTracker } from './cart-association.js';
14
+ import { testModeError, testModeLog } from '../utils/logger.js';
15
+ import { TRACKING_MODULES } from '../modules/contract/tracking-contract.js';
16
+ // Event throttle tracking to prevent duplicate events
17
+ const EVENT_THROTTLE_MAP = new Map();
18
+ const EVENT_THROTTLE_MS = 1000; // 1 second throttle for similar events
19
+ /**
20
+ * Check if an event should be throttled
21
+ */
22
+ function shouldThrottleEvent(eventName, entityId) {
23
+ const key = entityId ? `${eventName}:${entityId}` : eventName;
24
+ const lastTime = EVENT_THROTTLE_MAP.get(key) || 0;
25
+ const now = Date.now();
26
+ if (now - lastTime < EVENT_THROTTLE_MS) {
27
+ return true;
28
+ }
29
+ EVENT_THROTTLE_MAP.set(key, now);
30
+ return false;
31
+ }
32
+ /**
33
+ * Generate a throttle key from data layer event data
34
+ */
35
+ function getEventThrottleKey(data) {
36
+ if (data.product?.id)
37
+ return `${data.event}:${data.product.id}`;
38
+ if (data.basket?.id)
39
+ return `${data.event}:${data.basket.id}`;
40
+ if (data.checkout?.orderNo)
41
+ return `${data.event}:${data.checkout.orderNo}`;
42
+ if (data.user?.id)
43
+ return `${data.event}:${data.user.id}`;
44
+ if (data.search?.query)
45
+ return `${data.event}:${data.search.query}`;
46
+ return data.event || 'unknown';
47
+ }
48
+ export class DataLayerManager {
49
+ constructor(tracker, siteKey, apiUrl, options = {}) {
50
+ this.isInitialized = false;
51
+ this.isDestroyed = false;
52
+ // DOM observation
53
+ this.observer = null;
54
+ this.debounceTimer = null;
55
+ this.lastProcessedIndex = 0;
56
+ this.originalPush = null;
57
+ // Last tracked page info for change detection
58
+ this.lastPageUrl = '';
59
+ this.lastPageTitle = '';
60
+ this.consentState = null;
61
+ this.consentTimeoutTimer = null;
62
+ this.lastConsentValue = null; // For change detection
63
+ // Event buffering
64
+ this.eventBuffer = [];
65
+ this.flushTimer = null;
66
+ this.tracker = tracker;
67
+ this.siteKey = siteKey;
68
+ this.apiUrl = apiUrl;
69
+ // Get variable name or use default
70
+ this.dataLayerName = options.variableName || 'selwiseLayer';
71
+ const normalizedTrackingModules = this.normalizeTrackingModules(options.trackingModules);
72
+ const normalizedPageTypePatterns = this.normalizePageTypePatterns(options.pageTypePatterns);
73
+ // Merge config with defaults
74
+ this.config = {
75
+ enabled: options.enabled ?? true,
76
+ variableName: options.variableName,
77
+ pageDetection: options.pageDetection ?? 'auto',
78
+ autoPageTracking: options.autoPageTracking ?? true,
79
+ cartAbandonmentTimeout: options.cartAbandonmentTimeout ?? 30,
80
+ pageTypePatterns: normalizedPageTypePatterns,
81
+ debugMode: options.debugMode ?? false,
82
+ cookieConsent: options.cookieConsent,
83
+ trackingModules: normalizedTrackingModules,
84
+ bufferSize: options.bufferSize ?? 10,
85
+ flushInterval: options.flushInterval ?? 1000,
86
+ reverseEventMapping: options.reverseEventMapping,
87
+ externalDataLayerName: options.externalDataLayerName,
88
+ };
89
+ // Store references for quick access
90
+ this.cookieConsent = options.cookieConsent;
91
+ this.trackingModules = normalizedTrackingModules;
92
+ this.log('DataLayerManager constructor called with config:', this.config);
93
+ }
94
+ normalizeTrackingModules(modules) {
95
+ return {
96
+ page: { ...TRACKING_MODULES.page, ...(modules?.page || {}) },
97
+ product: { ...TRACKING_MODULES.product, ...(modules?.product || {}) },
98
+ basket: { ...TRACKING_MODULES.basket, ...(modules?.basket || {}) },
99
+ checkout: { ...TRACKING_MODULES.checkout, ...(modules?.checkout || {}) },
100
+ user: { ...TRACKING_MODULES.user, ...(modules?.user || {}) },
101
+ search: { ...TRACKING_MODULES.search, ...(modules?.search || {}) },
102
+ };
103
+ }
104
+ normalizePageTypePatterns(patterns) {
105
+ const source = patterns && Object.keys(patterns).length > 0 ? patterns : DEFAULT_PAGE_PATTERNS;
106
+ const normalized = {};
107
+ for (const [pageType, pattern] of Object.entries(source)) {
108
+ if (pattern instanceof RegExp) {
109
+ normalized[pageType] = pattern;
110
+ continue;
111
+ }
112
+ if (typeof pattern === 'string' && pattern.trim().length > 0) {
113
+ try {
114
+ normalized[pageType] = new RegExp(pattern, 'i');
115
+ }
116
+ catch {
117
+ this.log(`Invalid regex for page type "${pageType}", using default pattern`);
118
+ normalized[pageType] = DEFAULT_PAGE_PATTERNS[pageType] || DEFAULT_PAGE_PATTERNS.home;
119
+ }
120
+ }
121
+ }
122
+ return Object.keys(normalized).length > 0 ? normalized : { ...DEFAULT_PAGE_PATTERNS };
123
+ }
124
+ isModuleEnabled(module) {
125
+ return Boolean(this.trackingModules?.[module]?.enabled);
126
+ }
127
+ shouldAutoTrackPageViews() {
128
+ if (!this.config.autoPageTracking || !this.pageTracker || !this.isModuleEnabled('page')) {
129
+ return false;
130
+ }
131
+ if (this.config.pageDetection === 'manual') {
132
+ return false;
133
+ }
134
+ if (this.config.pageDetection === 'patterns') {
135
+ const fullPath = `${window.location.pathname}${window.location.search}`;
136
+ return Object.values(this.config.pageTypePatterns || {}).some((pattern) => pattern.test(fullPath));
137
+ }
138
+ return true;
139
+ }
140
+ shouldObservePageChanges() {
141
+ return (this.shouldAutoTrackPageViews() ||
142
+ this.isModuleEnabled('product') ||
143
+ this.isModuleEnabled('checkout'));
144
+ }
145
+ /**
146
+ * Initialize the data layer
147
+ */
148
+ init() {
149
+ if (this.isInitialized) {
150
+ this.log('DataLayerManager already initialized');
151
+ return;
152
+ }
153
+ if (this.isDestroyed) {
154
+ this.log('DataLayerManager was destroyed, cannot reinitialize');
155
+ return;
156
+ }
157
+ if (!this.config.enabled) {
158
+ this.log('Data layer is disabled by config');
159
+ return;
160
+ }
161
+ this.log('Initializing DataLayerManager...');
162
+ try {
163
+ // Initialize the data layer array on window
164
+ this.initializeDataLayer();
165
+ // Setup push interception
166
+ this.setupPushInterception();
167
+ // Setup SPA navigation observer
168
+ this.setupObserver();
169
+ // Initialize sub-trackers
170
+ this.initializeSubTrackers();
171
+ // Process any existing events in the layer
172
+ this.processLayer();
173
+ // Track initial page view based on page detection mode
174
+ if (this.shouldAutoTrackPageViews()) {
175
+ this.trackInitialPageView();
176
+ }
177
+ // Run auto-detection hooks for product/checkout modules on first load
178
+ this.runAutomaticModuleTracking();
179
+ // Expose public API
180
+ this.exposePublicApi();
181
+ // Check for abandoned cart on session start
182
+ this.checkCartAbandonment();
183
+ // Initialize external data layer listener if reverse mapping is configured
184
+ this.initExternalListener();
185
+ // Initialize cookie consent tracking (Phase 8)
186
+ this.initConsentTracking();
187
+ this.isInitialized = true;
188
+ this.log('DataLayerManager initialized successfully');
189
+ }
190
+ catch (error) {
191
+ // Log error but don't crash the entire widget
192
+ testModeError('DataLayerManager', 'Initialization failed:', error);
193
+ this.isInitialized = false;
194
+ }
195
+ }
196
+ /**
197
+ * Initialize the data layer array with configured variable name
198
+ */
199
+ initializeDataLayer() {
200
+ const layerName = this.dataLayerName;
201
+ // Create the data layer on window with the configured name
202
+ if (!window[layerName]) {
203
+ window[layerName] = [];
204
+ this.log(`Created window.${layerName} array`);
205
+ }
206
+ else {
207
+ this.log(`window.${layerName} already exists, length:`, window[layerName].length);
208
+ }
209
+ }
210
+ /**
211
+ * Get the data layer array
212
+ */
213
+ getDataLayer() {
214
+ return window[this.dataLayerName] || [];
215
+ }
216
+ /**
217
+ * Setup Array.prototype.push interception to catch data layer pushes
218
+ */
219
+ setupPushInterception() {
220
+ const layer = this.getDataLayer();
221
+ if (!layer || !layer.push)
222
+ return;
223
+ // Store the original push method
224
+ this.originalPush = layer.push.bind(layer);
225
+ // Override push to intercept events
226
+ layer.push = (...items) => {
227
+ const result = this.originalPush(...items);
228
+ // Schedule processing of new items
229
+ this.scheduleProcess();
230
+ return result;
231
+ };
232
+ this.log('Setup push interception');
233
+ }
234
+ /**
235
+ * Setup MutationObserver for SPA navigation detection
236
+ */
237
+ setupObserver() {
238
+ // Observer for detecting page changes in SPAs
239
+ this.observer = new MutationObserver(() => {
240
+ if (this.shouldObservePageChanges()) {
241
+ this.checkPageChange();
242
+ }
243
+ });
244
+ this.observer.observe(document, {
245
+ childList: true,
246
+ subtree: true,
247
+ });
248
+ // Also listen to History API changes
249
+ const originalPushState = history.pushState;
250
+ const originalReplaceState = history.replaceState;
251
+ history.pushState = (...args) => {
252
+ originalPushState.apply(history, args);
253
+ this.onHistoryChange();
254
+ };
255
+ history.replaceState = (...args) => {
256
+ originalReplaceState.apply(history, args);
257
+ this.onHistoryChange();
258
+ };
259
+ // Listen to popstate (back/forward buttons)
260
+ window.addEventListener('popstate', () => {
261
+ this.onHistoryChange();
262
+ });
263
+ this.log('Setup MutationObserver and History API listeners');
264
+ }
265
+ /**
266
+ * Handle History API changes (SPA navigation)
267
+ */
268
+ onHistoryChange() {
269
+ if (this.shouldObservePageChanges()) {
270
+ this.checkPageChange();
271
+ }
272
+ // Also process any pushed events around navigation.
273
+ this.scheduleProcess();
274
+ }
275
+ /**
276
+ * Check if page has changed and track new page view
277
+ */
278
+ checkPageChange() {
279
+ const currentUrl = window.location.href;
280
+ const currentTitle = document.title;
281
+ if (currentUrl !== this.lastPageUrl || currentTitle !== this.lastPageTitle) {
282
+ this.log('Page change detected:', currentUrl);
283
+ if (this.shouldAutoTrackPageViews()) {
284
+ // Clear throttle for page views to allow tracking
285
+ EVENT_THROTTLE_MAP.delete('page_view:');
286
+ }
287
+ this.lastPageUrl = currentUrl;
288
+ this.lastPageTitle = currentTitle;
289
+ // Cleanup dwell time tracking on SPA navigation
290
+ if (this.productTracker) {
291
+ this.productTracker.stopDwellTimeTracking();
292
+ }
293
+ if (this.shouldAutoTrackPageViews() && this.pageTracker) {
294
+ this.pageTracker.trackPageView();
295
+ }
296
+ this.runAutomaticModuleTracking();
297
+ }
298
+ }
299
+ /**
300
+ * Initialize all sub-tracker modules based on tracking modules config
301
+ */
302
+ initializeSubTrackers() {
303
+ const commonConfig = {
304
+ siteKey: this.siteKey,
305
+ apiUrl: this.apiUrl,
306
+ tracker: this.tracker,
307
+ config: this.config,
308
+ scheduleProcess: () => this.scheduleProcess(),
309
+ };
310
+ if (this.isModuleEnabled('page')) {
311
+ this.pageTracker = new PageTracker(commonConfig);
312
+ this.log('Page tracker enabled');
313
+ }
314
+ if (this.isModuleEnabled('product')) {
315
+ this.productTracker = new ProductTracker(commonConfig);
316
+ this.log('Product tracker enabled');
317
+ }
318
+ if (this.isModuleEnabled('basket')) {
319
+ this.basketTracker = new BasketTracker(commonConfig);
320
+ this.log('Basket tracker enabled');
321
+ }
322
+ if (this.isModuleEnabled('checkout')) {
323
+ this.checkoutTracker = new CheckoutTracker(commonConfig);
324
+ this.log('Checkout tracker enabled');
325
+ }
326
+ if (this.isModuleEnabled('user')) {
327
+ this.userTracker = new UserTracker(commonConfig);
328
+ this.log('User tracker enabled');
329
+ }
330
+ if (this.isModuleEnabled('search')) {
331
+ this.searchTracker = new SearchTracker(commonConfig);
332
+ this.log('Search tracker enabled');
333
+ }
334
+ // Cart association tracker follows basket module toggle.
335
+ if (this.isModuleEnabled('basket')) {
336
+ this.cartAssociationTracker = new CartAssociationTracker(commonConfig);
337
+ this.log('Cart association tracker enabled');
338
+ }
339
+ this.log('Initialized sub-trackers');
340
+ }
341
+ /**
342
+ * Track the initial page view on load
343
+ */
344
+ trackInitialPageView() {
345
+ this.lastPageUrl = window.location.href;
346
+ this.lastPageTitle = document.title;
347
+ if (this.pageTracker) {
348
+ this.pageTracker.trackPageView();
349
+ }
350
+ }
351
+ /**
352
+ * Check for abandoned cart on session start
353
+ */
354
+ checkCartAbandonment() {
355
+ if (this.basketTracker) {
356
+ this.basketTracker.checkCartAbandonment();
357
+ this.basketTracker.startCartMonitoring();
358
+ }
359
+ }
360
+ runAutomaticModuleTracking() {
361
+ if (this.checkoutTracker) {
362
+ this.checkoutTracker.autoTrackCheckoutStep();
363
+ }
364
+ if (this.productTracker && this.productTracker.isProductPage()) {
365
+ this.productTracker.trackProductView();
366
+ }
367
+ }
368
+ /**
369
+ * Initialize external data layer listener for listening to site's existing dataLayer
370
+ */
371
+ initExternalListener() {
372
+ // Get the reverse mapping from config
373
+ const reverseMapping = this.config.reverseEventMapping;
374
+ const externalDataLayerName = this.config.externalDataLayerName || 'dataLayer';
375
+ if (!reverseMapping || Object.keys(reverseMapping).length === 0) {
376
+ this.log('No reverse event mapping configured, skipping external listener');
377
+ return;
378
+ }
379
+ try {
380
+ this.externalListener = new ExternalDataLayerListener({
381
+ tracker: this.tracker,
382
+ reverseMapping,
383
+ dataLayerName: externalDataLayerName,
384
+ debugMode: this.config.debugMode,
385
+ enabled: true,
386
+ });
387
+ this.externalListener.init();
388
+ this.log('External dataLayer listener initialized with mapping:', reverseMapping);
389
+ }
390
+ catch (error) {
391
+ this.log('Failed to initialize external dataLayer listener:', error);
392
+ }
393
+ }
394
+ /**
395
+ * Schedule processing of the data layer
396
+ */
397
+ scheduleProcess() {
398
+ if (this.debounceTimer) {
399
+ clearTimeout(this.debounceTimer);
400
+ }
401
+ this.debounceTimer = window.setTimeout(() => {
402
+ this.processLayer();
403
+ this.debounceTimer = null;
404
+ }, DEFAULT_CONFIG.DEBOUNCE_MS);
405
+ }
406
+ /**
407
+ * Process all new events in the data layer
408
+ */
409
+ processLayer() {
410
+ if (this.isDestroyed)
411
+ return;
412
+ const layer = this.getDataLayer();
413
+ if (!layer)
414
+ return;
415
+ // Process events from lastProcessedIndex to current length
416
+ const newEvents = layer.slice(this.lastProcessedIndex);
417
+ if (newEvents.length === 0)
418
+ return;
419
+ this.log('Processing', newEvents.length, 'new data layer events');
420
+ for (const eventData of newEvents) {
421
+ this.enqueueEvent(eventData);
422
+ }
423
+ this.lastProcessedIndex = layer.length;
424
+ }
425
+ enqueueEvent(eventData) {
426
+ this.eventBuffer.push(eventData);
427
+ const maxBufferSize = Math.max(1, this.config.bufferSize || 1);
428
+ const flushIntervalMs = Math.max(100, this.config.flushInterval || 1000);
429
+ if (this.eventBuffer.length >= maxBufferSize) {
430
+ this.flushEventBuffer();
431
+ return;
432
+ }
433
+ if (this.flushTimer) {
434
+ return;
435
+ }
436
+ this.flushTimer = window.setTimeout(() => {
437
+ this.flushEventBuffer();
438
+ }, flushIntervalMs);
439
+ }
440
+ flushEventBuffer() {
441
+ if (this.flushTimer) {
442
+ clearTimeout(this.flushTimer);
443
+ this.flushTimer = null;
444
+ }
445
+ if (this.eventBuffer.length === 0) {
446
+ return;
447
+ }
448
+ const eventsToProcess = [...this.eventBuffer];
449
+ this.eventBuffer = [];
450
+ for (const eventData of eventsToProcess) {
451
+ this.processEvent(eventData);
452
+ }
453
+ }
454
+ /**
455
+ * Check if cookie consent is given
456
+ * Enhanced with granular consent support (Phase 8)
457
+ */
458
+ hasConsent(requiredCategory) {
459
+ if (!this.cookieConsent?.enabled) {
460
+ return true; // No consent check required
461
+ }
462
+ // Load current consent state
463
+ const currentConsent = this.loadConsentState();
464
+ if (!currentConsent) {
465
+ // No consent state yet
466
+ const consentVarName = this.cookieConsent.variableName || '__wcmp_consent';
467
+ const consentValue = window[consentVarName];
468
+ // Simple consent mode
469
+ if (consentValue === true || consentValue === 'granted' || consentValue === 1) {
470
+ return true;
471
+ }
472
+ if (this.cookieConsent.defaultConsent && consentValue === undefined) {
473
+ return true;
474
+ }
475
+ this.log('Cookie consent not given, blocking event');
476
+ return false;
477
+ }
478
+ // Granular consent mode
479
+ if (this.cookieConsent.granularEnabled && requiredCategory) {
480
+ // Check specific category
481
+ const hasCategoryConsent = currentConsent[requiredCategory];
482
+ if (!hasCategoryConsent) {
483
+ this.log(`Consent denied for category: ${requiredCategory}`);
484
+ }
485
+ return hasCategoryConsent;
486
+ }
487
+ // Check if analytics category is granted (default for tracking)
488
+ return currentConsent.analytics || currentConsent.necessary;
489
+ }
490
+ /**
491
+ * Initialize cookie consent tracking with timeout and change detection (Phase 8)
492
+ */
493
+ initConsentTracking() {
494
+ if (!this.cookieConsent?.enabled) {
495
+ return;
496
+ }
497
+ this.log('Initializing cookie consent tracking...');
498
+ // Load stored consent state
499
+ this.consentState = this.loadConsentState();
500
+ // Set up timeout for consent waiting
501
+ if (this.cookieConsent.waitForConsent && this.cookieConsent.timeoutMs) {
502
+ this.consentTimeoutTimer = window.setTimeout(() => {
503
+ this.log('Consent timeout reached, using default consent');
504
+ if (!this.consentState && this.cookieConsent?.defaultConsent) {
505
+ // Apply default consent
506
+ this.consentState = {
507
+ necessary: true,
508
+ analytics: this.cookieConsent.defaultConsent,
509
+ marketing: false,
510
+ preferences: false,
511
+ };
512
+ }
513
+ // Process queued and buffered events
514
+ this.processLayer();
515
+ this.flushEventBuffer();
516
+ }, this.cookieConsent.timeoutMs);
517
+ }
518
+ // Set up consent change detection
519
+ this.setupConsentChangeDetection();
520
+ // Initialize from window variable if available
521
+ const consentVarName = this.cookieConsent.variableName || '__wcmp_consent';
522
+ const consentValue = window[consentVarName];
523
+ if (consentValue !== undefined) {
524
+ this.updateConsentFromWindow(consentValue);
525
+ }
526
+ this.log('Cookie consent tracking initialized');
527
+ }
528
+ /**
529
+ * Setup consent change detection using polling (Phase 8)
530
+ */
531
+ setupConsentChangeDetection() {
532
+ // Check for consent changes every second
533
+ const checkInterval = setInterval(() => {
534
+ if (this.isDestroyed) {
535
+ clearInterval(checkInterval);
536
+ return;
537
+ }
538
+ const consentVarName = this.cookieConsent?.variableName || '__wcmp_consent';
539
+ const currentConsentValue = window[consentVarName];
540
+ // Check if consent value changed
541
+ if (currentConsentValue !== this.lastConsentValue) {
542
+ this.lastConsentValue = currentConsentValue;
543
+ this.updateConsentFromWindow(currentConsentValue);
544
+ }
545
+ // Also check localStorage for changes
546
+ const storageKey = this.cookieConsent?.storageKey || 'selwise_consent';
547
+ const storedConsent = this.loadStoredConsent(storageKey);
548
+ if (storedConsent) {
549
+ const oldStateJson = JSON.stringify(this.consentState);
550
+ this.consentState = storedConsent.granted;
551
+ const newStateJson = JSON.stringify(this.consentState);
552
+ if (oldStateJson !== newStateJson) {
553
+ this.log('Consent state changed from storage');
554
+ this.onConsentChange(storedConsent);
555
+ }
556
+ }
557
+ }, 1000);
558
+ // Store interval ID for cleanup (not tracked as class property to avoid type issues)
559
+ this.consentCheckInterval = checkInterval;
560
+ }
561
+ /**
562
+ * Update consent state from window variable (Phase 8)
563
+ */
564
+ updateConsentFromWindow(value) {
565
+ this.log('Updating consent from window variable:', value);
566
+ if (typeof value === 'boolean') {
567
+ // Simple consent mode
568
+ this.consentState = {
569
+ necessary: true,
570
+ analytics: value,
571
+ marketing: value,
572
+ preferences: value,
573
+ };
574
+ }
575
+ else if (value && typeof value === 'object') {
576
+ // Granular consent mode
577
+ this.consentState = {
578
+ necessary: true, // Always true
579
+ analytics: value.analytics ?? value.all ?? false,
580
+ marketing: value.marketing ?? value.all ?? false,
581
+ preferences: value.preferences ?? value.all ?? false,
582
+ };
583
+ }
584
+ else if (value === 'granted' || value === 1) {
585
+ this.consentState = {
586
+ necessary: true,
587
+ analytics: true,
588
+ marketing: true,
589
+ preferences: true,
590
+ };
591
+ }
592
+ else if (value === 'denied' || value === 0) {
593
+ this.consentState = {
594
+ necessary: true,
595
+ analytics: false,
596
+ marketing: false,
597
+ preferences: false,
598
+ };
599
+ }
600
+ // Call consent change callback if configured
601
+ this.callConsentChangeCallback();
602
+ // Process any buffered events
603
+ this.processLayer();
604
+ this.flushEventBuffer();
605
+ }
606
+ /**
607
+ * Load stored consent from localStorage (Phase 8)
608
+ */
609
+ loadStoredConsent(storageKey) {
610
+ try {
611
+ const stored = localStorage.getItem(storageKey);
612
+ if (!stored)
613
+ return null;
614
+ const parsed = JSON.parse(stored);
615
+ // Check if expired
616
+ if (parsed.expiresAt && Date.now() > parsed.expiresAt) {
617
+ localStorage.removeItem(storageKey);
618
+ return null;
619
+ }
620
+ return parsed;
621
+ }
622
+ catch {
623
+ return null;
624
+ }
625
+ }
626
+ /**
627
+ * Load consent state from storage or window (Phase 8)
628
+ */
629
+ loadConsentState() {
630
+ if (this.consentState) {
631
+ return this.consentState;
632
+ }
633
+ // Try loading from localStorage
634
+ const storageKey = this.cookieConsent?.storageKey || 'selwise_consent';
635
+ const storedConsent = this.loadStoredConsent(storageKey);
636
+ if (storedConsent) {
637
+ return storedConsent.granted;
638
+ }
639
+ return null;
640
+ }
641
+ /**
642
+ * Handle consent change event (Phase 8)
643
+ */
644
+ onConsentChange(consent) {
645
+ this.log('Consent changed:', consent);
646
+ // Call user-defined callback if available
647
+ this.callConsentChangeCallback();
648
+ // Process any buffered events that may now be allowed
649
+ this.processLayer();
650
+ this.flushEventBuffer();
651
+ }
652
+ /**
653
+ * Call user-defined consent change callback (Phase 8)
654
+ */
655
+ callConsentChangeCallback() {
656
+ const callbackName = this.cookieConsent?.consentChangeCallback;
657
+ if (!callbackName)
658
+ return;
659
+ try {
660
+ const callback = window[callbackName];
661
+ if (typeof callback === 'function') {
662
+ callback(this.consentState);
663
+ this.log(`Called consent change callback: ${callbackName}`);
664
+ }
665
+ }
666
+ catch (error) {
667
+ this.log('Error calling consent change callback:', error);
668
+ }
669
+ }
670
+ /**
671
+ * Get current consent state (public API for Phase 8)
672
+ */
673
+ getConsentState() {
674
+ return this.consentState;
675
+ }
676
+ /**
677
+ * Grant consent programmatically (public API for Phase 8)
678
+ */
679
+ grantConsent(categories) {
680
+ this.consentState = {
681
+ necessary: true,
682
+ analytics: true,
683
+ marketing: false,
684
+ preferences: false,
685
+ ...categories,
686
+ };
687
+ // Store in localStorage
688
+ const storageKey = this.cookieConsent?.storageKey || 'selwise_consent';
689
+ const stored = {
690
+ granted: this.consentState,
691
+ timestamp: Date.now(),
692
+ expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000, // 1 year
693
+ };
694
+ localStorage.setItem(storageKey, JSON.stringify(stored));
695
+ this.log('Consent granted:', this.consentState);
696
+ // Call callback
697
+ this.callConsentChangeCallback();
698
+ // Process buffered events
699
+ this.processLayer();
700
+ this.flushEventBuffer();
701
+ }
702
+ /**
703
+ * Revoke consent programmatically (public API for Phase 8)
704
+ */
705
+ revokeConsent(categories) {
706
+ if (!this.consentState) {
707
+ return; // Nothing to revoke
708
+ }
709
+ if (categories) {
710
+ // Revoke specific categories
711
+ for (const category of categories) {
712
+ if (category !== 'necessary') {
713
+ this.consentState[category] = false;
714
+ }
715
+ }
716
+ }
717
+ else {
718
+ // Revoke all except necessary
719
+ this.consentState.analytics = false;
720
+ this.consentState.marketing = false;
721
+ this.consentState.preferences = false;
722
+ }
723
+ // Store in localStorage
724
+ const storageKey = this.cookieConsent?.storageKey || 'selwise_consent';
725
+ const stored = {
726
+ granted: this.consentState,
727
+ timestamp: Date.now(),
728
+ expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000, // 1 year
729
+ };
730
+ localStorage.setItem(storageKey, JSON.stringify(stored));
731
+ this.log('Consent revoked:', this.consentState);
732
+ // Call callback
733
+ this.callConsentChangeCallback();
734
+ }
735
+ /**
736
+ * Process a single data layer event
737
+ */
738
+ processEvent(data) {
739
+ if (!data.event) {
740
+ this.log('Skipping event without event name:', data);
741
+ return;
742
+ }
743
+ // Check cookie consent before processing
744
+ if (!this.hasConsent()) {
745
+ this.log('Event blocked due to cookie consent:', data.event);
746
+ return;
747
+ }
748
+ // Check throttle
749
+ const throttleKey = getEventThrottleKey(data);
750
+ if (shouldThrottleEvent(throttleKey)) {
751
+ this.log('Throttled event:', throttleKey);
752
+ return;
753
+ }
754
+ this.log('Processing event:', data.event);
755
+ // Route to appropriate tracker based on event type
756
+ switch (data.event) {
757
+ // Page events
758
+ case 'page_view':
759
+ case 'virtual_page_view':
760
+ this.pageTracker?.processDataLayer(data);
761
+ break;
762
+ // Product events
763
+ case 'product_view':
764
+ case 'product_click':
765
+ case 'product_impression':
766
+ this.productTracker?.processDataLayer(data);
767
+ break;
768
+ // Basket events
769
+ case 'add_to_cart':
770
+ case 'remove_from_cart':
771
+ case 'update_cart':
772
+ case 'cart_abandon':
773
+ case 'cart_restore':
774
+ this.basketTracker?.processDataLayer(data);
775
+ // Also process through cart association tracker for "added to cart together" analytics
776
+ this.cartAssociationTracker?.processDataLayer(data);
777
+ break;
778
+ // Checkout events
779
+ case 'checkout_begin':
780
+ case 'checkout_progress':
781
+ case 'checkout_option':
782
+ case 'purchase':
783
+ this.checkoutTracker?.processDataLayer(data);
784
+ break;
785
+ // User events
786
+ case 'user_signup':
787
+ case 'user_login':
788
+ case 'user_logout':
789
+ case 'user_update':
790
+ this.userTracker?.processDataLayer(data);
791
+ break;
792
+ // Search events
793
+ case 'search_instant_open':
794
+ case 'search_query':
795
+ case 'search_filter':
796
+ case 'search_sort':
797
+ case 'search_page':
798
+ case 'search_results':
799
+ this.searchTracker?.processDataLayer(data);
800
+ break;
801
+ // Custom events
802
+ case 'custom':
803
+ this.trackCustomEvent(data);
804
+ break;
805
+ default:
806
+ // Unknown event type - track as custom
807
+ this.log('Unknown event type, tracking as custom:', data.event);
808
+ this.trackCustomEvent(data);
809
+ }
810
+ }
811
+ /**
812
+ * Track a custom event
813
+ */
814
+ trackCustomEvent(data) {
815
+ const eventName = data.custom?.type || data.custom?.name || data.event || 'custom';
816
+ this.tracker.track(eventName, {
817
+ entityType: 'custom',
818
+ entityId: data.custom?.name || undefined,
819
+ metadata: {
820
+ dataSource: DATA_SOURCE,
821
+ pageUrl: window.location.href,
822
+ referrer: document.referrer,
823
+ timestamp: Date.now(),
824
+ ...data.custom?.params,
825
+ ...data,
826
+ },
827
+ });
828
+ }
829
+ /**
830
+ * Expose public API methods to window.Selwise
831
+ */
832
+ exposePublicApi() {
833
+ if (!window.Selwise) {
834
+ window.Selwise = {};
835
+ }
836
+ const layerName = this.dataLayerName;
837
+ // Manual push method for external scripts
838
+ window.Selwise.pushDataLayer = (data) => {
839
+ if (!Array.isArray(window[layerName])) {
840
+ window[layerName] = [];
841
+ }
842
+ window[layerName].push(data);
843
+ };
844
+ // Get current data layer state
845
+ window.Selwise.getDataLayer = () => {
846
+ return this.getDataLayer();
847
+ };
848
+ // Phase 8: Cookie consent API
849
+ // Get current consent state
850
+ window.Selwise.getConsentState = () => {
851
+ return this.getConsentState();
852
+ };
853
+ // Grant consent programmatically
854
+ window.Selwise.grantConsent = (categories) => {
855
+ this.grantConsent(categories);
856
+ };
857
+ // Revoke consent programmatically
858
+ window.Selwise.revokeConsent = (categories) => {
859
+ this.revokeConsent(categories);
860
+ };
861
+ this.log('Exposed public API');
862
+ }
863
+ /**
864
+ * Update configuration dynamically
865
+ */
866
+ updateConfig(options) {
867
+ if (options.enabled !== undefined) {
868
+ this.config.enabled = options.enabled;
869
+ }
870
+ if (options.variableName !== undefined) {
871
+ this.config.variableName = options.variableName;
872
+ this.dataLayerName = options.variableName || 'selwiseLayer';
873
+ }
874
+ if (options.pageDetection !== undefined) {
875
+ this.config.pageDetection = options.pageDetection;
876
+ }
877
+ if (options.autoPageTracking !== undefined) {
878
+ this.config.autoPageTracking = options.autoPageTracking;
879
+ }
880
+ if (options.cartAbandonmentTimeout !== undefined) {
881
+ this.config.cartAbandonmentTimeout = options.cartAbandonmentTimeout;
882
+ }
883
+ if (options.pageTypePatterns !== undefined) {
884
+ this.config.pageTypePatterns = this.normalizePageTypePatterns(options.pageTypePatterns);
885
+ }
886
+ if (options.debugMode !== undefined) {
887
+ this.config.debugMode = options.debugMode;
888
+ }
889
+ if (options.cookieConsent !== undefined) {
890
+ this.config.cookieConsent = options.cookieConsent;
891
+ this.cookieConsent = options.cookieConsent;
892
+ }
893
+ if (options.trackingModules !== undefined) {
894
+ const normalizedTrackingModules = this.normalizeTrackingModules(options.trackingModules);
895
+ this.config.trackingModules = normalizedTrackingModules;
896
+ this.trackingModules = normalizedTrackingModules;
897
+ }
898
+ if (options.bufferSize !== undefined) {
899
+ this.config.bufferSize = options.bufferSize;
900
+ }
901
+ if (options.flushInterval !== undefined) {
902
+ this.config.flushInterval = options.flushInterval;
903
+ }
904
+ this.log('Config updated:', this.config);
905
+ }
906
+ /**
907
+ * Get current configuration
908
+ */
909
+ getConfig() {
910
+ return { ...this.config };
911
+ }
912
+ /**
913
+ * Get data layer state (last N events)
914
+ */
915
+ getLayerState(maxEvents = 100) {
916
+ const layer = this.getDataLayer();
917
+ if (!layer.length)
918
+ return [];
919
+ return layer.slice(-maxEvents);
920
+ }
921
+ /**
922
+ * Manually push an event to the data layer
923
+ */
924
+ push(data) {
925
+ if (!Array.isArray(window[this.dataLayerName])) {
926
+ window[this.dataLayerName] = [];
927
+ }
928
+ window[this.dataLayerName].push(data);
929
+ }
930
+ /**
931
+ * Log messages in debug mode or test mode
932
+ */
933
+ log(...args) {
934
+ testModeLog('DataLayerManager', ...args);
935
+ }
936
+ /**
937
+ * Cleanup and destroy the data layer manager
938
+ */
939
+ destroy() {
940
+ this.log('Destroying DataLayerManager...');
941
+ // Disconnect observer
942
+ if (this.observer) {
943
+ this.observer.disconnect();
944
+ this.observer = null;
945
+ }
946
+ // Clear debounce timer
947
+ if (this.debounceTimer) {
948
+ clearTimeout(this.debounceTimer);
949
+ this.debounceTimer = null;
950
+ }
951
+ // Flush buffered events before shutting down trackers.
952
+ this.flushEventBuffer();
953
+ // Clear consent timeout timer (Phase 8)
954
+ if (this.consentTimeoutTimer) {
955
+ clearTimeout(this.consentTimeoutTimer);
956
+ this.consentTimeoutTimer = null;
957
+ }
958
+ // Clear consent check interval (Phase 8)
959
+ const consentCheckInterval = this.consentCheckInterval;
960
+ if (consentCheckInterval) {
961
+ clearInterval(consentCheckInterval);
962
+ this.consentCheckInterval = null;
963
+ }
964
+ // Restore original push method on the dynamic layer
965
+ const layer = this.getDataLayer();
966
+ if (layer.length && this.originalPush) {
967
+ window[this.dataLayerName].push = this.originalPush;
968
+ this.originalPush = null;
969
+ }
970
+ // Cleanup sub-trackers
971
+ this.pageTracker?.destroy();
972
+ this.productTracker?.destroy();
973
+ this.basketTracker?.destroy();
974
+ this.checkoutTracker?.destroy();
975
+ this.userTracker?.destroy();
976
+ this.searchTracker?.destroy();
977
+ this.cartAssociationTracker?.destroy();
978
+ // Cleanup external data layer listener
979
+ this.externalListener?.destroy();
980
+ // Clear throttle map
981
+ EVENT_THROTTLE_MAP.clear();
982
+ // Clear event buffer
983
+ this.eventBuffer = [];
984
+ this.isDestroyed = true;
985
+ this.isInitialized = false;
986
+ this.log('DataLayerManager destroyed');
987
+ }
988
+ }
989
+ export { ConsentCategory } from './types.js';
990
+ export * from './constants.js';
991
+ //# sourceMappingURL=index.js.map