@absmartly/sdk-plugins 1.2.1 → 1.3.0

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 (134) hide show
  1. package/dist/absmartly-cookie.min.js +1 -1
  2. package/dist/absmartly-dom-changes-core.min.js +1 -1
  3. package/dist/absmartly-dom-changes-lite.min.js +1 -1
  4. package/dist/absmartly-overrides-full.min.js +1 -1
  5. package/dist/absmartly-overrides-lite.min.js +1 -1
  6. package/dist/absmartly-sdk-plugins.min.js +1 -1
  7. package/dist/absmartly-vitals.min.js +1 -1
  8. package/es/analytics/AnalyticsPlugin.js +96 -0
  9. package/es/analytics/AnalyticsPlugin.js.map +1 -0
  10. package/es/analytics/index.js +2 -0
  11. package/es/analytics/index.js.map +1 -0
  12. package/es/analytics/types.js +2 -0
  13. package/es/analytics/types.js.map +1 -0
  14. package/es/cookies/CookiePlugin.js +59 -18
  15. package/es/cookies/CookiePlugin.js.map +1 -1
  16. package/es/cookies/cookieUtils.js +2 -1
  17. package/es/cookies/cookieUtils.js.map +1 -1
  18. package/es/core/DOMChangesPluginLite.js +206 -101
  19. package/es/core/DOMChangesPluginLite.js.map +1 -1
  20. package/es/core/DOMManipulatorLite.js +187 -122
  21. package/es/core/DOMManipulatorLite.js.map +1 -1
  22. package/es/core/ExposureTracker.js +310 -108
  23. package/es/core/ExposureTracker.js.map +1 -1
  24. package/es/core/HTMLInjector.js +11 -1
  25. package/es/core/HTMLInjector.js.map +1 -1
  26. package/es/core/PendingChangeManager.js +125 -65
  27. package/es/core/PendingChangeManager.js.map +1 -1
  28. package/es/generated/buildInfo.js +3 -0
  29. package/es/generated/buildInfo.js.map +1 -0
  30. package/es/index.js +1 -0
  31. package/es/index.js.map +1 -1
  32. package/es/overrides/BrowserCookieAdapter.js +3 -31
  33. package/es/overrides/BrowserCookieAdapter.js.map +1 -1
  34. package/es/overrides/OverridesPlugin.js +39 -107
  35. package/es/overrides/OverridesPlugin.js.map +1 -1
  36. package/es/overrides/OverridesPluginLite.js +5 -136
  37. package/es/overrides/OverridesPluginLite.js.map +1 -1
  38. package/es/parsers/VariantExtractor.js +21 -18
  39. package/es/parsers/VariantExtractor.js.map +1 -1
  40. package/es/url-redirect/URLRedirectExtractor.js +8 -2
  41. package/es/url-redirect/URLRedirectExtractor.js.map +1 -1
  42. package/es/url-redirect/URLRedirectMatcher.js +136 -5
  43. package/es/url-redirect/URLRedirectMatcher.js.map +1 -1
  44. package/es/url-redirect/URLRedirectPlugin.js +16 -6
  45. package/es/url-redirect/URLRedirectPlugin.js.map +1 -1
  46. package/es/utils/URLMatcher.js +4 -3
  47. package/es/utils/URLMatcher.js.map +1 -1
  48. package/es/utils/debug.js +15 -3
  49. package/es/utils/debug.js.map +1 -1
  50. package/es/utils/persistence.js +143 -75
  51. package/es/utils/persistence.js.map +1 -1
  52. package/es/utils/plugin-registry.js.map +1 -1
  53. package/es/vitals/WebVitalsPlugin.js +9 -4
  54. package/es/vitals/WebVitalsPlugin.js.map +1 -1
  55. package/lib/analytics/AnalyticsPlugin.d.ts +8 -0
  56. package/lib/analytics/AnalyticsPlugin.js +99 -0
  57. package/lib/analytics/AnalyticsPlugin.js.map +1 -0
  58. package/lib/analytics/index.d.ts +2 -0
  59. package/lib/analytics/index.js +6 -0
  60. package/lib/analytics/index.js.map +1 -0
  61. package/lib/analytics/types.d.ts +5 -0
  62. package/lib/analytics/types.js +3 -0
  63. package/lib/analytics/types.js.map +1 -0
  64. package/lib/cookies/CookiePlugin.js +59 -18
  65. package/lib/cookies/CookiePlugin.js.map +1 -1
  66. package/lib/cookies/cookieUtils.d.ts +0 -4
  67. package/lib/cookies/cookieUtils.js +6 -5
  68. package/lib/cookies/cookieUtils.js.map +1 -1
  69. package/lib/core/DOMChangesPluginLite.d.ts +3 -0
  70. package/lib/core/DOMChangesPluginLite.js +206 -101
  71. package/lib/core/DOMChangesPluginLite.js.map +1 -1
  72. package/lib/core/DOMManipulatorLite.js +187 -122
  73. package/lib/core/DOMManipulatorLite.js.map +1 -1
  74. package/lib/core/ExposureTracker.js +310 -108
  75. package/lib/core/ExposureTracker.js.map +1 -1
  76. package/lib/core/HTMLInjector.d.ts +1 -0
  77. package/lib/core/HTMLInjector.js +11 -1
  78. package/lib/core/HTMLInjector.js.map +1 -1
  79. package/lib/core/PendingChangeManager.d.ts +0 -1
  80. package/lib/core/PendingChangeManager.js +125 -65
  81. package/lib/core/PendingChangeManager.js.map +1 -1
  82. package/lib/generated/buildInfo.d.ts +2 -0
  83. package/lib/generated/buildInfo.js +6 -0
  84. package/lib/generated/buildInfo.js.map +1 -0
  85. package/lib/index.d.ts +2 -0
  86. package/lib/index.js +3 -1
  87. package/lib/index.js.map +1 -1
  88. package/lib/overrides/BrowserCookieAdapter.js +3 -31
  89. package/lib/overrides/BrowserCookieAdapter.js.map +1 -1
  90. package/lib/overrides/OverridesPlugin.js +39 -107
  91. package/lib/overrides/OverridesPlugin.js.map +1 -1
  92. package/lib/overrides/OverridesPluginLite.d.ts +5 -1
  93. package/lib/overrides/OverridesPluginLite.js +5 -136
  94. package/lib/overrides/OverridesPluginLite.js.map +1 -1
  95. package/lib/parsers/VariantExtractor.js +21 -18
  96. package/lib/parsers/VariantExtractor.js.map +1 -1
  97. package/lib/types/index.d.ts +5 -0
  98. package/lib/url-redirect/URLRedirectExtractor.js +8 -2
  99. package/lib/url-redirect/URLRedirectExtractor.js.map +1 -1
  100. package/lib/url-redirect/URLRedirectMatcher.d.ts +3 -0
  101. package/lib/url-redirect/URLRedirectMatcher.js +136 -5
  102. package/lib/url-redirect/URLRedirectMatcher.js.map +1 -1
  103. package/lib/url-redirect/URLRedirectPlugin.js +15 -5
  104. package/lib/url-redirect/URLRedirectPlugin.js.map +1 -1
  105. package/lib/url-redirect/types.d.ts +1 -1
  106. package/lib/utils/URLMatcher.d.ts +1 -7
  107. package/lib/utils/URLMatcher.js +4 -3
  108. package/lib/utils/URLMatcher.js.map +1 -1
  109. package/lib/utils/debug.d.ts +6 -1
  110. package/lib/utils/debug.js +16 -3
  111. package/lib/utils/debug.js.map +1 -1
  112. package/lib/utils/persistence.js +143 -75
  113. package/lib/utils/persistence.js.map +1 -1
  114. package/lib/utils/plugin-registry.d.ts +1 -0
  115. package/lib/utils/plugin-registry.js.map +1 -1
  116. package/lib/vitals/WebVitalsPlugin.js +9 -4
  117. package/lib/vitals/WebVitalsPlugin.js.map +1 -1
  118. package/package.json +14 -6
  119. package/types/analytics/AnalyticsPlugin.d.ts +8 -0
  120. package/types/analytics/index.d.ts +2 -0
  121. package/types/analytics/types.d.ts +5 -0
  122. package/types/cookies/cookieUtils.d.ts +0 -4
  123. package/types/core/DOMChangesPluginLite.d.ts +3 -0
  124. package/types/core/HTMLInjector.d.ts +1 -0
  125. package/types/core/PendingChangeManager.d.ts +0 -1
  126. package/types/generated/buildInfo.d.ts +2 -0
  127. package/types/index.d.ts +2 -0
  128. package/types/overrides/OverridesPluginLite.d.ts +5 -1
  129. package/types/types/index.d.ts +5 -0
  130. package/types/url-redirect/URLRedirectMatcher.d.ts +3 -0
  131. package/types/url-redirect/types.d.ts +1 -1
  132. package/types/utils/URLMatcher.d.ts +1 -7
  133. package/types/utils/debug.d.ts +6 -1
  134. package/types/utils/plugin-registry.d.ts +1 -0
@@ -81,6 +81,7 @@ import { logDebug, logExperimentSummary, logPerformance, DEBUG } from '../utils/
81
81
  import { URLMatcher } from '../utils/URLMatcher';
82
82
  import { DOMPersistenceManager } from '../utils/persistence';
83
83
  import { registerPlugin, unregisterPlugin } from '../utils/plugin-registry';
84
+ import { BUILD_VERSION } from '../generated/buildInfo';
84
85
  var DOMChangesPluginLite = /** @class */ (function () {
85
86
  function DOMChangesPluginLite(config) {
86
87
  var _this = this;
@@ -93,6 +94,9 @@ var DOMChangesPluginLite = /** @class */ (function () {
93
94
  this.persistenceManager = null;
94
95
  this.antiFlickerTimeout = null;
95
96
  this.antiFlickerStyleId = 'absmartly-antiflicker';
97
+ this.originalPushState = null;
98
+ this.originalReplaceState = null;
99
+ this.popstateHandler = null;
96
100
  this.config = {
97
101
  context: config.context,
98
102
  autoApply: (_a = config.autoApply) !== null && _a !== void 0 ? _a : true,
@@ -199,6 +203,10 @@ var DOMChangesPluginLite = /** @class */ (function () {
199
203
  case 4:
200
204
  error_1 = _a.sent();
201
205
  logDebug('[ABsmartly] Failed to initialize plugin:', error_1);
206
+ this.emit('error', {
207
+ type: 'initialization_error',
208
+ error: (error_1 === null || error_1 === void 0 ? void 0 : error_1.message) || String(error_1),
209
+ });
202
210
  throw error_1;
203
211
  case 5: return [2 /*return*/];
204
212
  }
@@ -208,45 +216,96 @@ var DOMChangesPluginLite = /** @class */ (function () {
208
216
  DOMChangesPluginLite.prototype.setupMutationObserver = function () {
209
217
  var _this = this;
210
218
  var observer = new MutationObserver(function (mutations) {
211
- // Re-apply ALL changes to elements that were replaced by React (hydration mismatch)
212
- mutations.forEach(function (mutation) {
213
- if (mutation.type === 'childList') {
214
- // Check if any added nodes match our applied change selectors
215
- mutation.addedNodes.forEach(function (node) {
216
- var _a;
217
- if (node.nodeType === Node.ELEMENT_NODE) {
218
- var element_1 = node;
219
- // Check all experiments with applied changes (not just style changes)
220
- var appliedChanges = ((_a = _this.persistenceManager) === null || _a === void 0 ? void 0 : _a.getAppliedChanges()) || new Map();
221
- appliedChanges.forEach(function (changes, experimentName) {
222
- changes.forEach(function (change) {
219
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e;
220
+ var _f;
221
+ try {
222
+ // Re-apply ALL changes to elements that were replaced by React (hydration mismatch)
223
+ for (var mutations_1 = __values(mutations), mutations_1_1 = mutations_1.next(); !mutations_1_1.done; mutations_1_1 = mutations_1.next()) {
224
+ var mutation = mutations_1_1.value;
225
+ if (mutation.type === 'childList') {
226
+ try {
227
+ // Check if any added nodes match our applied change selectors
228
+ for (var _g = (e_2 = void 0, __values(mutation.addedNodes)), _h = _g.next(); !_h.done; _h = _g.next()) {
229
+ var node = _h.value;
230
+ if (node.nodeType === Node.ELEMENT_NODE) {
231
+ var element = node;
232
+ // Check all experiments with applied changes (not just style changes)
233
+ var appliedChanges = ((_f = _this.persistenceManager) === null || _f === void 0 ? void 0 : _f.getAppliedChanges()) || new Map();
223
234
  try {
224
- // Check if this new element or any of its descendants match the selector
225
- var matchingElements = element_1.matches(change.selector)
226
- ? [element_1]
227
- : Array.from(element_1.querySelectorAll(change.selector));
228
- matchingElements.forEach(function (matchingEl) {
229
- if (_this.config.debug) {
230
- logDebug('[SPA-REAPPLY] Re-applying change to newly added element (React hydration recovery)', {
231
- experimentName: experimentName,
232
- selector: change.selector,
233
- element: matchingEl.tagName,
234
- changeType: change.type,
235
- });
235
+ for (var appliedChanges_1 = (e_3 = void 0, __values(appliedChanges)), appliedChanges_1_1 = appliedChanges_1.next(); !appliedChanges_1_1.done; appliedChanges_1_1 = appliedChanges_1.next()) {
236
+ var _j = __read(appliedChanges_1_1.value, 2), experimentName = _j[0], changes = _j[1];
237
+ try {
238
+ for (var changes_1 = (e_4 = void 0, __values(changes)), changes_1_1 = changes_1.next(); !changes_1_1.done; changes_1_1 = changes_1.next()) {
239
+ var change = changes_1_1.value;
240
+ try {
241
+ // Check if this new element or any of its descendants match the selector
242
+ var matchingElements = element.matches(change.selector)
243
+ ? [element]
244
+ : Array.from(element.querySelectorAll(change.selector));
245
+ try {
246
+ for (var matchingElements_1 = (e_5 = void 0, __values(matchingElements)), matchingElements_1_1 = matchingElements_1.next(); !matchingElements_1_1.done; matchingElements_1_1 = matchingElements_1.next()) {
247
+ var matchingEl = matchingElements_1_1.value;
248
+ if (_this.config.debug) {
249
+ logDebug('[SPA-REAPPLY] Re-applying change to newly added element (React hydration recovery)', {
250
+ experimentName: experimentName,
251
+ selector: change.selector,
252
+ element: matchingEl.tagName,
253
+ changeType: change.type,
254
+ });
255
+ }
256
+ // Re-apply the change to the new element (ALL types: style, class, attribute, html, text, etc.)
257
+ _this.domManipulator.applyChange(change, experimentName);
258
+ }
259
+ }
260
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
261
+ finally {
262
+ try {
263
+ if (matchingElements_1_1 && !matchingElements_1_1.done && (_e = matchingElements_1.return)) _e.call(matchingElements_1);
264
+ }
265
+ finally { if (e_5) throw e_5.error; }
266
+ }
267
+ }
268
+ catch (e) {
269
+ // Invalid selector, skip
270
+ }
271
+ }
236
272
  }
237
- // Re-apply the change to the new element (ALL types: style, class, attribute, html, text, etc.)
238
- _this.domManipulator.applyChange(change, experimentName);
239
- });
273
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
274
+ finally {
275
+ try {
276
+ if (changes_1_1 && !changes_1_1.done && (_d = changes_1.return)) _d.call(changes_1);
277
+ }
278
+ finally { if (e_4) throw e_4.error; }
279
+ }
280
+ }
240
281
  }
241
- catch (e) {
242
- // Invalid selector, skip
282
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
283
+ finally {
284
+ try {
285
+ if (appliedChanges_1_1 && !appliedChanges_1_1.done && (_c = appliedChanges_1.return)) _c.call(appliedChanges_1);
286
+ }
287
+ finally { if (e_3) throw e_3.error; }
243
288
  }
244
- });
245
- });
289
+ }
290
+ }
246
291
  }
247
- });
292
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
293
+ finally {
294
+ try {
295
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
296
+ }
297
+ finally { if (e_2) throw e_2.error; }
298
+ }
299
+ }
248
300
  }
249
- });
301
+ }
302
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
303
+ finally {
304
+ try {
305
+ if (mutations_1_1 && !mutations_1_1.done && (_a = mutations_1.return)) _a.call(mutations_1);
306
+ }
307
+ finally { if (e_1) throw e_1.error; }
308
+ }
250
309
  });
251
310
  // Wait for document.body to exist before observing
252
311
  // This prevents "parameter 1 is not of type 'Node'" errors when SDK loads in <head>
@@ -301,24 +360,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
301
360
  });
302
361
  }); };
303
362
  // Listen to popstate (back/forward navigation)
304
- window.addEventListener('popstate', handleURLChange);
363
+ this.popstateHandler = handleURLChange;
364
+ window.addEventListener('popstate', this.popstateHandler);
305
365
  // Intercept pushState and replaceState
306
- var originalPushState = history.pushState;
307
- var originalReplaceState = history.replaceState;
308
- history.pushState = function () {
309
- var args = [];
310
- for (var _i = 0; _i < arguments.length; _i++) {
311
- args[_i] = arguments[_i];
366
+ this.originalPushState = history.pushState;
367
+ this.originalReplaceState = history.replaceState;
368
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
369
+ var self = this;
370
+ history.pushState = function (data, unused, url) {
371
+ if (self.originalPushState) {
372
+ self.originalPushState.call(history, data, unused, url);
312
373
  }
313
- originalPushState.apply(history, args);
314
374
  handleURLChange();
315
375
  };
316
- history.replaceState = function () {
317
- var args = [];
318
- for (var _i = 0; _i < arguments.length; _i++) {
319
- args[_i] = arguments[_i];
376
+ history.replaceState = function (data, unused, url) {
377
+ if (self.originalReplaceState) {
378
+ self.originalReplaceState.call(history, data, unused, url);
320
379
  }
321
- originalReplaceState.apply(history, args);
322
380
  handleURLChange();
323
381
  };
324
382
  if (this.config.debug) {
@@ -332,18 +390,14 @@ var DOMChangesPluginLite = /** @class */ (function () {
332
390
  DOMChangesPluginLite.prototype.removeAllChanges = function () {
333
391
  return __awaiter(this, void 0, void 0, function () {
334
392
  return __generator(this, function (_a) {
335
- // Clear exposed experiments - ExposureTracker will re-register on next applyChanges
393
+ // ExposureTracker will re-register on next applyChanges
336
394
  this.exposedExperiments.clear();
337
- // Clear style managers - StyleSheetManager doesn't have a remove method
338
- // The stylesheets will be reused or cleared on next applyChanges
395
+ // StyleSheetManager doesn't have a remove method, stylesheets will be reused on next applyChanges
339
396
  this.styleManagers.clear();
340
- // Clear applied changes
341
397
  if (this.persistenceManager) {
342
398
  this.persistenceManager.clearAll();
343
399
  }
344
- // Clear HTML injections
345
400
  this.htmlInjector.destroy();
346
- // Clear variant extractor cache to force re-extraction
347
401
  this.variantExtractor.clearCache();
348
402
  if (this.config.debug) {
349
403
  logDebug('[ABsmartly] All change tracking cleared for URL change');
@@ -423,10 +477,10 @@ var DOMChangesPluginLite = /** @class */ (function () {
423
477
  };
424
478
  DOMChangesPluginLite.prototype.applyChanges = function (experimentName) {
425
479
  return __awaiter(this, void 0, void 0, function () {
426
- var startTime, currentURL, error_3, allExperiments, totalApplied, experimentStats, allExperiments_1, allExperiments_1_1, _a, expName, experimentData, currentVariant, variantData, urlFilter, globalDefaults, anyVariantMatchesURL, shouldApplyVisualChanges, changes, allVariantChanges, hasAnyChangesInAnyVariant, stats, changes_1, changes_1_1, change, success, elements, hasAnyViewportTriggerInAnyVariant, hasAnyImmediateTriggerInAnyVariant, allVariantsData, allVariantsData_1, allVariantsData_1_1, _b, variantIndex, variantData_1, variantChanges, variantMatchesURL, config, urlFilterConfig, variantChanges_1, variantChanges_1_1, change, duration;
427
- var e_1, _c, e_2, _d, e_3, _e, e_4, _f;
428
- return __generator(this, function (_g) {
429
- switch (_g.label) {
480
+ var startTime, currentURL, error_3, allExperiments, totalApplied, experimentStats, allExperiments_1, allExperiments_1_1, _a, expName, experimentData, currentVariant, variantData, urlFilter, globalDefaults, anyVariantMatchesURL, shouldApplyVisualChanges, changes, allVariantChanges, hasAnyChangesInAnyVariant, stats, changes_2, changes_2_1, change, success, elements, hasAnyViewportTriggerInAnyVariant, hasAnyImmediateTriggerInAnyVariant, allVariantsData, allVariantsData_1, allVariantsData_1_1, _b, idx, data, allVariantsData_2, allVariantsData_2_1, _c, variantIndex, variantData_1, variantChanges, variantMatchesURL, config, urlFilterConfig, variantChanges_1, variantChanges_1_1, change, duration;
481
+ var e_6, _d, e_7, _e, e_8, _f, e_9, _g, e_10, _h;
482
+ return __generator(this, function (_j) {
483
+ switch (_j.label) {
430
484
  case 0:
431
485
  startTime = performance.now();
432
486
  currentURL = window.location.href;
@@ -441,15 +495,15 @@ var DOMChangesPluginLite = /** @class */ (function () {
441
495
  logDebug('[ABsmartly] Current URL:', currentURL);
442
496
  logDebug('[ABsmartly] Context ready:', true);
443
497
  }
444
- _g.label = 1;
498
+ _j.label = 1;
445
499
  case 1:
446
- _g.trys.push([1, 3, , 4]);
500
+ _j.trys.push([1, 3, , 4]);
447
501
  return [4 /*yield*/, this.config.context.ready()];
448
502
  case 2:
449
- _g.sent();
503
+ _j.sent();
450
504
  return [3 /*break*/, 4];
451
505
  case 3:
452
- error_3 = _g.sent();
506
+ error_3 = _j.sent();
453
507
  logDebug('[ABsmartly] Failed to wait for context ready:', error_3);
454
508
  return [2 /*return*/];
455
509
  case 4:
@@ -535,8 +589,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
535
589
  // Apply visual changes only if URL matches for user's variant AND user has changes
536
590
  if (shouldApplyVisualChanges && changes && changes.length > 0) {
537
591
  try {
538
- for (changes_1 = (e_2 = void 0, __values(changes)), changes_1_1 = changes_1.next(); !changes_1_1.done; changes_1_1 = changes_1.next()) {
539
- change = changes_1_1.value;
592
+ for (changes_2 = (e_7 = void 0, __values(changes)), changes_2_1 = changes_2.next(); !changes_2_1.done; changes_2_1 = changes_2.next()) {
593
+ change = changes_2_1.value;
540
594
  // Skip delete changes with viewport triggers - they must be applied AFTER exposure
541
595
  // Otherwise the element is removed before it can be observed
542
596
  if (change.type === 'delete' && change.trigger_on_view) {
@@ -566,12 +620,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
566
620
  }
567
621
  }
568
622
  }
569
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
623
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
570
624
  finally {
571
625
  try {
572
- if (changes_1_1 && !changes_1_1.done && (_d = changes_1.return)) _d.call(changes_1);
626
+ if (changes_2_1 && !changes_2_1.done && (_e = changes_2.return)) _e.call(changes_2);
573
627
  }
574
- finally { if (e_2) throw e_2.error; }
628
+ finally { if (e_7) throw e_7.error; }
575
629
  }
576
630
  }
577
631
  else if (changes && changes.length > 0) {
@@ -585,21 +639,31 @@ var DOMChangesPluginLite = /** @class */ (function () {
585
639
  allVariantsDataSize: allVariantsData.size,
586
640
  allVariantChangesLength: allVariantChanges.length,
587
641
  });
588
- // Log the structure of each variant's data
589
- allVariantsData.forEach(function (data, idx) {
590
- logDebug("[ABsmartly] Variant ".concat(idx, " data structure:"), {
591
- isArray: Array.isArray(data),
592
- isObject: typeof data === 'object',
593
- hasUrlFilter: data && typeof data === 'object' && !Array.isArray(data) && 'urlFilter' in data,
594
- keys: data && typeof data === 'object' && !Array.isArray(data) ? Object.keys(data) : 'N/A',
595
- });
596
- });
642
+ try {
643
+ // Log the structure of each variant's data
644
+ for (allVariantsData_1 = (e_8 = void 0, __values(allVariantsData)), allVariantsData_1_1 = allVariantsData_1.next(); !allVariantsData_1_1.done; allVariantsData_1_1 = allVariantsData_1.next()) {
645
+ _b = __read(allVariantsData_1_1.value, 2), idx = _b[0], data = _b[1];
646
+ logDebug("[ABsmartly] Variant ".concat(idx, " data structure:"), {
647
+ isArray: Array.isArray(data),
648
+ isObject: typeof data === 'object',
649
+ hasUrlFilter: data && typeof data === 'object' && !Array.isArray(data) && 'urlFilter' in data,
650
+ keys: data && typeof data === 'object' && !Array.isArray(data) ? Object.keys(data) : 'N/A',
651
+ });
652
+ }
653
+ }
654
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
655
+ finally {
656
+ try {
657
+ if (allVariantsData_1_1 && !allVariantsData_1_1.done && (_f = allVariantsData_1.return)) _f.call(allVariantsData_1);
658
+ }
659
+ finally { if (e_8) throw e_8.error; }
660
+ }
597
661
  }
598
662
  try {
599
663
  // Loop through ALL variants (not just ones with changes)
600
664
  // We need to check URL filters from the raw data, which includes variants without changes
601
- for (allVariantsData_1 = (e_3 = void 0, __values(allVariantsData)), allVariantsData_1_1 = allVariantsData_1.next(); !allVariantsData_1_1.done; allVariantsData_1_1 = allVariantsData_1.next()) {
602
- _b = __read(allVariantsData_1_1.value, 2), variantIndex = _b[0], variantData_1 = _b[1];
665
+ for (allVariantsData_2 = (e_9 = void 0, __values(allVariantsData)), allVariantsData_2_1 = allVariantsData_2.next(); !allVariantsData_2_1.done; allVariantsData_2_1 = allVariantsData_2.next()) {
666
+ _c = __read(allVariantsData_2_1.value, 2), variantIndex = _c[0], variantData_1 = _c[1];
603
667
  variantChanges = allVariantChanges[variantIndex];
604
668
  if (!variantChanges || variantChanges.length === 0) {
605
669
  continue;
@@ -619,7 +683,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
619
683
  // Only collect trigger types from variants whose URL filters match
620
684
  if (variantMatchesURL) {
621
685
  try {
622
- for (variantChanges_1 = (e_4 = void 0, __values(variantChanges)), variantChanges_1_1 = variantChanges_1.next(); !variantChanges_1_1.done; variantChanges_1_1 = variantChanges_1.next()) {
686
+ for (variantChanges_1 = (e_10 = void 0, __values(variantChanges)), variantChanges_1_1 = variantChanges_1.next(); !variantChanges_1_1.done; variantChanges_1_1 = variantChanges_1.next()) {
623
687
  change = variantChanges_1_1.value;
624
688
  if (change.trigger_on_view) {
625
689
  hasAnyViewportTriggerInAnyVariant = true;
@@ -633,12 +697,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
633
697
  }
634
698
  }
635
699
  }
636
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
700
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
637
701
  finally {
638
702
  try {
639
- if (variantChanges_1_1 && !variantChanges_1_1.done && (_f = variantChanges_1.return)) _f.call(variantChanges_1);
703
+ if (variantChanges_1_1 && !variantChanges_1_1.done && (_h = variantChanges_1.return)) _h.call(variantChanges_1);
640
704
  }
641
- finally { if (e_4) throw e_4.error; }
705
+ finally { if (e_10) throw e_10.error; }
642
706
  }
643
707
  if (this.config.debug) {
644
708
  logDebug("[ABsmartly] Variant ".concat(variantIndex, " matches URL - hasImmediate: ").concat(hasAnyImmediateTriggerInAnyVariant, ", hasViewport: ").concat(hasAnyViewportTriggerInAnyVariant));
@@ -654,12 +718,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
654
718
  }
655
719
  }
656
720
  }
657
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
721
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
658
722
  finally {
659
723
  try {
660
- if (allVariantsData_1_1 && !allVariantsData_1_1.done && (_e = allVariantsData_1.return)) _e.call(allVariantsData_1);
724
+ if (allVariantsData_2_1 && !allVariantsData_2_1.done && (_g = allVariantsData_2.return)) _g.call(allVariantsData_2);
661
725
  }
662
- finally { if (e_3) throw e_3.error; }
726
+ finally { if (e_9) throw e_9.error; }
663
727
  }
664
728
  if (this.config.debug) {
665
729
  logDebug("[TRIGGER-DETECTION] [".concat(expName, "] Final trigger decision for '").concat(expName, "':"), {
@@ -705,12 +769,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
705
769
  logExperimentSummary(expName, stats.total, stats.success, stats.pending);
706
770
  }
707
771
  }
708
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
772
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
709
773
  finally {
710
774
  try {
711
- if (allExperiments_1_1 && !allExperiments_1_1.done && (_c = allExperiments_1.return)) _c.call(allExperiments_1);
775
+ if (allExperiments_1_1 && !allExperiments_1_1.done && (_d = allExperiments_1.return)) _d.call(allExperiments_1);
712
776
  }
713
- finally { if (e_1) throw e_1.error; }
777
+ finally { if (e_6) throw e_6.error; }
714
778
  }
715
779
  duration = performance.now() - startTime;
716
780
  logPerformance('Apply changes', duration, {
@@ -739,6 +803,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
739
803
  if (this.config.hideUntilReady) {
740
804
  this.showContent();
741
805
  }
806
+ logDebug('[ABsmartly] DOM changes applied');
742
807
  this.emit('changes-applied', { count: totalApplied, experimentName: experimentName });
743
808
  return [2 /*return*/];
744
809
  }
@@ -749,7 +814,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
749
814
  * Get all experiments with their variant data and metadata
750
815
  */
751
816
  DOMChangesPluginLite.prototype.getAllExperimentsData = function () {
752
- var e_5, _a;
817
+ var e_11, _a;
753
818
  var experiments = new Map();
754
819
  var allVariants = this.variantExtractor.extractAllChanges();
755
820
  logDebug('[GET-EXPERIMENTS] Extracting experiment data from context', {
@@ -801,6 +866,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
801
866
  globalDefaults = {
802
867
  waitForElement: config.waitForElement,
803
868
  persistStyle: config.persistStyle,
869
+ persistAttribute: config.persistAttribute,
870
+ persistScript: config.persistScript,
804
871
  important: config.important,
805
872
  observerRoot: config.observerRoot,
806
873
  };
@@ -808,12 +875,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
808
875
  experiments.set(expName, { variantData: variantData, urlFilter: urlFilter, globalDefaults: globalDefaults });
809
876
  }
810
877
  }
811
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
878
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
812
879
  finally {
813
880
  try {
814
881
  if (allVariants_1_1 && !allVariants_1_1.done && (_a = allVariants_1.return)) _a.call(allVariants_1);
815
882
  }
816
- finally { if (e_5) throw e_5.error; }
883
+ finally { if (e_11) throw e_11.error; }
817
884
  }
818
885
  return experiments;
819
886
  };
@@ -837,8 +904,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
837
904
  }
838
905
  // Apply global defaults to each change
839
906
  return changes.map(function (change) {
840
- var _a, _b, _c, _d;
841
- return (__assign(__assign({}, change), { waitForElement: (_a = change.waitForElement) !== null && _a !== void 0 ? _a : globalDefaults.waitForElement, persistStyle: (_b = change.persistStyle) !== null && _b !== void 0 ? _b : globalDefaults.persistStyle, important: (_c = change.important) !== null && _c !== void 0 ? _c : globalDefaults.important, observerRoot: (_d = change.observerRoot) !== null && _d !== void 0 ? _d : globalDefaults.observerRoot }));
907
+ var _a, _b, _c, _d, _e, _f;
908
+ return (__assign(__assign({}, change), { waitForElement: (_a = change.waitForElement) !== null && _a !== void 0 ? _a : globalDefaults.waitForElement, persistStyle: (_b = change.persistStyle) !== null && _b !== void 0 ? _b : globalDefaults.persistStyle, persistAttribute: (_c = change.persistAttribute) !== null && _c !== void 0 ? _c : globalDefaults.persistAttribute, persistScript: (_d = change.persistScript) !== null && _d !== void 0 ? _d : globalDefaults.persistScript, important: (_e = change.important) !== null && _e !== void 0 ? _e : globalDefaults.important, observerRoot: (_f = change.observerRoot) !== null && _f !== void 0 ? _f : globalDefaults.observerRoot }));
842
909
  });
843
910
  };
844
911
  /**
@@ -866,14 +933,16 @@ var DOMChangesPluginLite = /** @class */ (function () {
866
933
  globalDefaults = {
867
934
  waitForElement: config.waitForElement,
868
935
  persistStyle: config.persistStyle,
936
+ persistAttribute: config.persistAttribute,
937
+ persistScript: config.persistScript,
869
938
  important: config.important,
870
939
  observerRoot: config.observerRoot,
871
940
  };
872
941
  }
873
942
  // Apply global defaults
874
943
  var processedChanges = variantChanges.map(function (change) {
875
- var _a, _b, _c, _d;
876
- return (__assign(__assign({}, change), { waitForElement: (_a = change.waitForElement) !== null && _a !== void 0 ? _a : globalDefaults.waitForElement, persistStyle: (_b = change.persistStyle) !== null && _b !== void 0 ? _b : globalDefaults.persistStyle, important: (_c = change.important) !== null && _c !== void 0 ? _c : globalDefaults.important, observerRoot: (_d = change.observerRoot) !== null && _d !== void 0 ? _d : globalDefaults.observerRoot }));
944
+ var _a, _b, _c, _d, _e, _f;
945
+ return (__assign(__assign({}, change), { waitForElement: (_a = change.waitForElement) !== null && _a !== void 0 ? _a : globalDefaults.waitForElement, persistStyle: (_b = change.persistStyle) !== null && _b !== void 0 ? _b : globalDefaults.persistStyle, persistAttribute: (_c = change.persistAttribute) !== null && _c !== void 0 ? _c : globalDefaults.persistAttribute, persistScript: (_d = change.persistScript) !== null && _d !== void 0 ? _d : globalDefaults.persistScript, important: (_e = change.important) !== null && _e !== void 0 ? _e : globalDefaults.important, observerRoot: (_f = change.observerRoot) !== null && _f !== void 0 ? _f : globalDefaults.observerRoot }));
877
946
  });
878
947
  processedVariants.push(processedChanges);
879
948
  };
@@ -918,12 +987,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
918
987
  change: change,
919
988
  });
920
989
  }
990
+ else {
991
+ this.emit('change_failed', {
992
+ experimentName: experimentName,
993
+ change: change,
994
+ reason: 'selector_not_found_or_apply_failed',
995
+ });
996
+ }
921
997
  return success;
922
998
  }
923
999
  catch (error) {
924
- if (this.config.debug) {
925
- logDebug('[ABsmartly] Error applying change:', error);
926
- }
1000
+ logDebug('[ABsmartly] Error applying change:', error);
1001
+ this.emit('error', {
1002
+ type: 'change_apply_error',
1003
+ experimentName: experimentName,
1004
+ change: change,
1005
+ error: (error === null || error === void 0 ? void 0 : error.message) || String(error),
1006
+ });
927
1007
  return false;
928
1008
  }
929
1009
  };
@@ -945,7 +1025,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
945
1025
  }
946
1026
  };
947
1027
  DOMChangesPluginLite.prototype.emit = function (event, data) {
948
- var e_6, _a;
1028
+ var e_12, _a;
949
1029
  var listeners = this.eventListeners.get(event) || [];
950
1030
  try {
951
1031
  for (var listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next(); !listeners_1_1.done; listeners_1_1 = listeners_1.next()) {
@@ -958,12 +1038,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
958
1038
  }
959
1039
  }
960
1040
  }
961
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
1041
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
962
1042
  finally {
963
1043
  try {
964
1044
  if (listeners_1_1 && !listeners_1_1.done && (_a = listeners_1.return)) _a.call(listeners_1);
965
1045
  }
966
- finally { if (e_6) throw e_6.error; }
1046
+ finally { if (e_12) throw e_12.error; }
967
1047
  }
968
1048
  };
969
1049
  DOMChangesPluginLite.prototype.getStyleManager = function (experimentName) {
@@ -1014,10 +1094,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
1014
1094
  }
1015
1095
  };
1016
1096
  DOMChangesPluginLite.prototype.destroy = function () {
1097
+ var e_13, _a;
1017
1098
  this.domManipulator.destroy();
1018
1099
  this.exposureTracker.destroy();
1019
1100
  this.htmlInjector.destroy();
1020
- this.styleManagers.forEach(function (manager) { return manager.destroy(); });
1101
+ try {
1102
+ for (var _b = __values(this.styleManagers.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
1103
+ var manager = _c.value;
1104
+ manager.destroy();
1105
+ }
1106
+ }
1107
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
1108
+ finally {
1109
+ try {
1110
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1111
+ }
1112
+ finally { if (e_13) throw e_13.error; }
1113
+ }
1021
1114
  this.styleManagers.clear();
1022
1115
  if (this.mutationObserver) {
1023
1116
  this.mutationObserver.disconnect();
@@ -1036,6 +1129,18 @@ var DOMChangesPluginLite = /** @class */ (function () {
1036
1129
  if (antiFlickerStyle) {
1037
1130
  antiFlickerStyle.remove();
1038
1131
  }
1132
+ // Restore history methods
1133
+ if (this.originalPushState) {
1134
+ history.pushState = this.originalPushState;
1135
+ }
1136
+ if (this.originalReplaceState) {
1137
+ history.replaceState = this.originalReplaceState;
1138
+ }
1139
+ // Remove popstate listener
1140
+ if (this.popstateHandler) {
1141
+ window.removeEventListener('popstate', this.popstateHandler);
1142
+ this.popstateHandler = null;
1143
+ }
1039
1144
  this.eventListeners.clear();
1040
1145
  this.exposedExperiments.clear();
1041
1146
  this.unregisterFromContext();
@@ -1191,7 +1296,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
1191
1296
  this.persistenceManager.unwatchElement(element, experimentName);
1192
1297
  }
1193
1298
  };
1194
- DOMChangesPluginLite.VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '1.1.2';
1299
+ DOMChangesPluginLite.VERSION = BUILD_VERSION;
1195
1300
  return DOMChangesPluginLite;
1196
1301
  }());
1197
1302
  export { DOMChangesPluginLite };