@absmartly/sdk-plugins 1.2.2 → 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 (122) 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/core/DOMChangesPluginLite.js +203 -100
  17. package/es/core/DOMChangesPluginLite.js.map +1 -1
  18. package/es/core/DOMManipulatorLite.js +187 -131
  19. package/es/core/DOMManipulatorLite.js.map +1 -1
  20. package/es/core/ExposureTracker.js +310 -108
  21. package/es/core/ExposureTracker.js.map +1 -1
  22. package/es/core/HTMLInjector.js +11 -1
  23. package/es/core/HTMLInjector.js.map +1 -1
  24. package/es/core/PendingChangeManager.js +114 -54
  25. package/es/core/PendingChangeManager.js.map +1 -1
  26. package/es/generated/buildInfo.js +1 -1
  27. package/es/index.js +1 -0
  28. package/es/index.js.map +1 -1
  29. package/es/overrides/BrowserCookieAdapter.js +3 -31
  30. package/es/overrides/BrowserCookieAdapter.js.map +1 -1
  31. package/es/overrides/OverridesPlugin.js +39 -107
  32. package/es/overrides/OverridesPlugin.js.map +1 -1
  33. package/es/overrides/OverridesPluginLite.js +5 -136
  34. package/es/overrides/OverridesPluginLite.js.map +1 -1
  35. package/es/parsers/VariantExtractor.js +21 -18
  36. package/es/parsers/VariantExtractor.js.map +1 -1
  37. package/es/url-redirect/URLRedirectExtractor.js +8 -2
  38. package/es/url-redirect/URLRedirectExtractor.js.map +1 -1
  39. package/es/url-redirect/URLRedirectMatcher.js +130 -0
  40. package/es/url-redirect/URLRedirectMatcher.js.map +1 -1
  41. package/es/url-redirect/URLRedirectPlugin.js +14 -5
  42. package/es/url-redirect/URLRedirectPlugin.js.map +1 -1
  43. package/es/utils/URLMatcher.js.map +1 -1
  44. package/es/utils/debug.js +11 -0
  45. package/es/utils/debug.js.map +1 -1
  46. package/es/utils/persistence.js +143 -75
  47. package/es/utils/persistence.js.map +1 -1
  48. package/es/utils/plugin-registry.js.map +1 -1
  49. package/es/vitals/WebVitalsPlugin.js +9 -4
  50. package/es/vitals/WebVitalsPlugin.js.map +1 -1
  51. package/lib/analytics/AnalyticsPlugin.d.ts +8 -0
  52. package/lib/analytics/AnalyticsPlugin.js +99 -0
  53. package/lib/analytics/AnalyticsPlugin.js.map +1 -0
  54. package/lib/analytics/index.d.ts +2 -0
  55. package/lib/analytics/index.js +6 -0
  56. package/lib/analytics/index.js.map +1 -0
  57. package/lib/analytics/types.d.ts +5 -0
  58. package/lib/analytics/types.js +3 -0
  59. package/lib/analytics/types.js.map +1 -0
  60. package/lib/cookies/CookiePlugin.js +59 -18
  61. package/lib/cookies/CookiePlugin.js.map +1 -1
  62. package/lib/core/DOMChangesPluginLite.d.ts +3 -0
  63. package/lib/core/DOMChangesPluginLite.js +203 -100
  64. package/lib/core/DOMChangesPluginLite.js.map +1 -1
  65. package/lib/core/DOMManipulatorLite.js +187 -131
  66. package/lib/core/DOMManipulatorLite.js.map +1 -1
  67. package/lib/core/ExposureTracker.js +310 -108
  68. package/lib/core/ExposureTracker.js.map +1 -1
  69. package/lib/core/HTMLInjector.d.ts +1 -0
  70. package/lib/core/HTMLInjector.js +11 -1
  71. package/lib/core/HTMLInjector.js.map +1 -1
  72. package/lib/core/PendingChangeManager.js +114 -54
  73. package/lib/core/PendingChangeManager.js.map +1 -1
  74. package/lib/generated/buildInfo.d.ts +1 -1
  75. package/lib/generated/buildInfo.js +1 -1
  76. package/lib/index.d.ts +2 -0
  77. package/lib/index.js +3 -1
  78. package/lib/index.js.map +1 -1
  79. package/lib/overrides/BrowserCookieAdapter.js +3 -31
  80. package/lib/overrides/BrowserCookieAdapter.js.map +1 -1
  81. package/lib/overrides/OverridesPlugin.js +39 -107
  82. package/lib/overrides/OverridesPlugin.js.map +1 -1
  83. package/lib/overrides/OverridesPluginLite.d.ts +5 -1
  84. package/lib/overrides/OverridesPluginLite.js +5 -136
  85. package/lib/overrides/OverridesPluginLite.js.map +1 -1
  86. package/lib/parsers/VariantExtractor.js +21 -18
  87. package/lib/parsers/VariantExtractor.js.map +1 -1
  88. package/lib/types/index.d.ts +5 -0
  89. package/lib/url-redirect/URLRedirectExtractor.js +8 -2
  90. package/lib/url-redirect/URLRedirectExtractor.js.map +1 -1
  91. package/lib/url-redirect/URLRedirectMatcher.d.ts +3 -0
  92. package/lib/url-redirect/URLRedirectMatcher.js +130 -0
  93. package/lib/url-redirect/URLRedirectMatcher.js.map +1 -1
  94. package/lib/url-redirect/URLRedirectPlugin.js +13 -4
  95. package/lib/url-redirect/URLRedirectPlugin.js.map +1 -1
  96. package/lib/url-redirect/types.d.ts +1 -1
  97. package/lib/utils/URLMatcher.d.ts +1 -7
  98. package/lib/utils/URLMatcher.js.map +1 -1
  99. package/lib/utils/debug.d.ts +5 -0
  100. package/lib/utils/debug.js +12 -0
  101. package/lib/utils/debug.js.map +1 -1
  102. package/lib/utils/persistence.js +143 -75
  103. package/lib/utils/persistence.js.map +1 -1
  104. package/lib/utils/plugin-registry.d.ts +1 -0
  105. package/lib/utils/plugin-registry.js.map +1 -1
  106. package/lib/vitals/WebVitalsPlugin.js +9 -4
  107. package/lib/vitals/WebVitalsPlugin.js.map +1 -1
  108. package/package.json +9 -3
  109. package/types/analytics/AnalyticsPlugin.d.ts +8 -0
  110. package/types/analytics/index.d.ts +2 -0
  111. package/types/analytics/types.d.ts +5 -0
  112. package/types/core/DOMChangesPluginLite.d.ts +3 -0
  113. package/types/core/HTMLInjector.d.ts +1 -0
  114. package/types/generated/buildInfo.d.ts +1 -1
  115. package/types/index.d.ts +2 -0
  116. package/types/overrides/OverridesPluginLite.d.ts +5 -1
  117. package/types/types/index.d.ts +5 -0
  118. package/types/url-redirect/URLRedirectMatcher.d.ts +3 -0
  119. package/types/url-redirect/types.d.ts +1 -1
  120. package/types/utils/URLMatcher.d.ts +1 -7
  121. package/types/utils/debug.d.ts +5 -0
  122. package/types/utils/plugin-registry.d.ts +1 -0
@@ -94,6 +94,9 @@ var DOMChangesPluginLite = /** @class */ (function () {
94
94
  this.persistenceManager = null;
95
95
  this.antiFlickerTimeout = null;
96
96
  this.antiFlickerStyleId = 'absmartly-antiflicker';
97
+ this.originalPushState = null;
98
+ this.originalReplaceState = null;
99
+ this.popstateHandler = null;
97
100
  this.config = {
98
101
  context: config.context,
99
102
  autoApply: (_a = config.autoApply) !== null && _a !== void 0 ? _a : true,
@@ -200,6 +203,10 @@ var DOMChangesPluginLite = /** @class */ (function () {
200
203
  case 4:
201
204
  error_1 = _a.sent();
202
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
+ });
203
210
  throw error_1;
204
211
  case 5: return [2 /*return*/];
205
212
  }
@@ -209,45 +216,96 @@ var DOMChangesPluginLite = /** @class */ (function () {
209
216
  DOMChangesPluginLite.prototype.setupMutationObserver = function () {
210
217
  var _this = this;
211
218
  var observer = new MutationObserver(function (mutations) {
212
- // Re-apply ALL changes to elements that were replaced by React (hydration mismatch)
213
- mutations.forEach(function (mutation) {
214
- if (mutation.type === 'childList') {
215
- // Check if any added nodes match our applied change selectors
216
- mutation.addedNodes.forEach(function (node) {
217
- var _a;
218
- if (node.nodeType === Node.ELEMENT_NODE) {
219
- var element_1 = node;
220
- // Check all experiments with applied changes (not just style changes)
221
- var appliedChanges = ((_a = _this.persistenceManager) === null || _a === void 0 ? void 0 : _a.getAppliedChanges()) || new Map();
222
- appliedChanges.forEach(function (changes, experimentName) {
223
- 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();
224
234
  try {
225
- // Check if this new element or any of its descendants match the selector
226
- var matchingElements = element_1.matches(change.selector)
227
- ? [element_1]
228
- : Array.from(element_1.querySelectorAll(change.selector));
229
- matchingElements.forEach(function (matchingEl) {
230
- if (_this.config.debug) {
231
- logDebug('[SPA-REAPPLY] Re-applying change to newly added element (React hydration recovery)', {
232
- experimentName: experimentName,
233
- selector: change.selector,
234
- element: matchingEl.tagName,
235
- changeType: change.type,
236
- });
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
+ }
237
272
  }
238
- // Re-apply the change to the new element (ALL types: style, class, attribute, html, text, etc.)
239
- _this.domManipulator.applyChange(change, experimentName);
240
- });
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
+ }
241
281
  }
242
- catch (e) {
243
- // 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; }
244
288
  }
245
- });
246
- });
289
+ }
290
+ }
247
291
  }
248
- });
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
+ }
249
300
  }
250
- });
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
+ }
251
309
  });
252
310
  // Wait for document.body to exist before observing
253
311
  // This prevents "parameter 1 is not of type 'Node'" errors when SDK loads in <head>
@@ -302,24 +360,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
302
360
  });
303
361
  }); };
304
362
  // Listen to popstate (back/forward navigation)
305
- window.addEventListener('popstate', handleURLChange);
363
+ this.popstateHandler = handleURLChange;
364
+ window.addEventListener('popstate', this.popstateHandler);
306
365
  // Intercept pushState and replaceState
307
- var originalPushState = history.pushState;
308
- var originalReplaceState = history.replaceState;
309
- history.pushState = function () {
310
- var args = [];
311
- for (var _i = 0; _i < arguments.length; _i++) {
312
- 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);
313
373
  }
314
- originalPushState.apply(history, args);
315
374
  handleURLChange();
316
375
  };
317
- history.replaceState = function () {
318
- var args = [];
319
- for (var _i = 0; _i < arguments.length; _i++) {
320
- args[_i] = arguments[_i];
376
+ history.replaceState = function (data, unused, url) {
377
+ if (self.originalReplaceState) {
378
+ self.originalReplaceState.call(history, data, unused, url);
321
379
  }
322
- originalReplaceState.apply(history, args);
323
380
  handleURLChange();
324
381
  };
325
382
  if (this.config.debug) {
@@ -333,18 +390,14 @@ var DOMChangesPluginLite = /** @class */ (function () {
333
390
  DOMChangesPluginLite.prototype.removeAllChanges = function () {
334
391
  return __awaiter(this, void 0, void 0, function () {
335
392
  return __generator(this, function (_a) {
336
- // Clear exposed experiments - ExposureTracker will re-register on next applyChanges
393
+ // ExposureTracker will re-register on next applyChanges
337
394
  this.exposedExperiments.clear();
338
- // Clear style managers - StyleSheetManager doesn't have a remove method
339
- // 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
340
396
  this.styleManagers.clear();
341
- // Clear applied changes
342
397
  if (this.persistenceManager) {
343
398
  this.persistenceManager.clearAll();
344
399
  }
345
- // Clear HTML injections
346
400
  this.htmlInjector.destroy();
347
- // Clear variant extractor cache to force re-extraction
348
401
  this.variantExtractor.clearCache();
349
402
  if (this.config.debug) {
350
403
  logDebug('[ABsmartly] All change tracking cleared for URL change');
@@ -424,10 +477,10 @@ var DOMChangesPluginLite = /** @class */ (function () {
424
477
  };
425
478
  DOMChangesPluginLite.prototype.applyChanges = function (experimentName) {
426
479
  return __awaiter(this, void 0, void 0, function () {
427
- 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;
428
- var e_1, _c, e_2, _d, e_3, _e, e_4, _f;
429
- return __generator(this, function (_g) {
430
- 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) {
431
484
  case 0:
432
485
  startTime = performance.now();
433
486
  currentURL = window.location.href;
@@ -442,15 +495,15 @@ var DOMChangesPluginLite = /** @class */ (function () {
442
495
  logDebug('[ABsmartly] Current URL:', currentURL);
443
496
  logDebug('[ABsmartly] Context ready:', true);
444
497
  }
445
- _g.label = 1;
498
+ _j.label = 1;
446
499
  case 1:
447
- _g.trys.push([1, 3, , 4]);
500
+ _j.trys.push([1, 3, , 4]);
448
501
  return [4 /*yield*/, this.config.context.ready()];
449
502
  case 2:
450
- _g.sent();
503
+ _j.sent();
451
504
  return [3 /*break*/, 4];
452
505
  case 3:
453
- error_3 = _g.sent();
506
+ error_3 = _j.sent();
454
507
  logDebug('[ABsmartly] Failed to wait for context ready:', error_3);
455
508
  return [2 /*return*/];
456
509
  case 4:
@@ -536,8 +589,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
536
589
  // Apply visual changes only if URL matches for user's variant AND user has changes
537
590
  if (shouldApplyVisualChanges && changes && changes.length > 0) {
538
591
  try {
539
- 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()) {
540
- 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;
541
594
  // Skip delete changes with viewport triggers - they must be applied AFTER exposure
542
595
  // Otherwise the element is removed before it can be observed
543
596
  if (change.type === 'delete' && change.trigger_on_view) {
@@ -567,12 +620,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
567
620
  }
568
621
  }
569
622
  }
570
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
623
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
571
624
  finally {
572
625
  try {
573
- 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);
574
627
  }
575
- finally { if (e_2) throw e_2.error; }
628
+ finally { if (e_7) throw e_7.error; }
576
629
  }
577
630
  }
578
631
  else if (changes && changes.length > 0) {
@@ -586,21 +639,31 @@ var DOMChangesPluginLite = /** @class */ (function () {
586
639
  allVariantsDataSize: allVariantsData.size,
587
640
  allVariantChangesLength: allVariantChanges.length,
588
641
  });
589
- // Log the structure of each variant's data
590
- allVariantsData.forEach(function (data, idx) {
591
- logDebug("[ABsmartly] Variant ".concat(idx, " data structure:"), {
592
- isArray: Array.isArray(data),
593
- isObject: typeof data === 'object',
594
- hasUrlFilter: data && typeof data === 'object' && !Array.isArray(data) && 'urlFilter' in data,
595
- keys: data && typeof data === 'object' && !Array.isArray(data) ? Object.keys(data) : 'N/A',
596
- });
597
- });
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
+ }
598
661
  }
599
662
  try {
600
663
  // Loop through ALL variants (not just ones with changes)
601
664
  // We need to check URL filters from the raw data, which includes variants without changes
602
- 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()) {
603
- _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];
604
667
  variantChanges = allVariantChanges[variantIndex];
605
668
  if (!variantChanges || variantChanges.length === 0) {
606
669
  continue;
@@ -620,7 +683,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
620
683
  // Only collect trigger types from variants whose URL filters match
621
684
  if (variantMatchesURL) {
622
685
  try {
623
- 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()) {
624
687
  change = variantChanges_1_1.value;
625
688
  if (change.trigger_on_view) {
626
689
  hasAnyViewportTriggerInAnyVariant = true;
@@ -634,12 +697,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
634
697
  }
635
698
  }
636
699
  }
637
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
700
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
638
701
  finally {
639
702
  try {
640
- 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);
641
704
  }
642
- finally { if (e_4) throw e_4.error; }
705
+ finally { if (e_10) throw e_10.error; }
643
706
  }
644
707
  if (this.config.debug) {
645
708
  logDebug("[ABsmartly] Variant ".concat(variantIndex, " matches URL - hasImmediate: ").concat(hasAnyImmediateTriggerInAnyVariant, ", hasViewport: ").concat(hasAnyViewportTriggerInAnyVariant));
@@ -655,12 +718,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
655
718
  }
656
719
  }
657
720
  }
658
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
721
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
659
722
  finally {
660
723
  try {
661
- 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);
662
725
  }
663
- finally { if (e_3) throw e_3.error; }
726
+ finally { if (e_9) throw e_9.error; }
664
727
  }
665
728
  if (this.config.debug) {
666
729
  logDebug("[TRIGGER-DETECTION] [".concat(expName, "] Final trigger decision for '").concat(expName, "':"), {
@@ -706,12 +769,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
706
769
  logExperimentSummary(expName, stats.total, stats.success, stats.pending);
707
770
  }
708
771
  }
709
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
772
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
710
773
  finally {
711
774
  try {
712
- 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);
713
776
  }
714
- finally { if (e_1) throw e_1.error; }
777
+ finally { if (e_6) throw e_6.error; }
715
778
  }
716
779
  duration = performance.now() - startTime;
717
780
  logPerformance('Apply changes', duration, {
@@ -751,7 +814,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
751
814
  * Get all experiments with their variant data and metadata
752
815
  */
753
816
  DOMChangesPluginLite.prototype.getAllExperimentsData = function () {
754
- var e_5, _a;
817
+ var e_11, _a;
755
818
  var experiments = new Map();
756
819
  var allVariants = this.variantExtractor.extractAllChanges();
757
820
  logDebug('[GET-EXPERIMENTS] Extracting experiment data from context', {
@@ -803,6 +866,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
803
866
  globalDefaults = {
804
867
  waitForElement: config.waitForElement,
805
868
  persistStyle: config.persistStyle,
869
+ persistAttribute: config.persistAttribute,
870
+ persistScript: config.persistScript,
806
871
  important: config.important,
807
872
  observerRoot: config.observerRoot,
808
873
  };
@@ -810,12 +875,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
810
875
  experiments.set(expName, { variantData: variantData, urlFilter: urlFilter, globalDefaults: globalDefaults });
811
876
  }
812
877
  }
813
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
878
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
814
879
  finally {
815
880
  try {
816
881
  if (allVariants_1_1 && !allVariants_1_1.done && (_a = allVariants_1.return)) _a.call(allVariants_1);
817
882
  }
818
- finally { if (e_5) throw e_5.error; }
883
+ finally { if (e_11) throw e_11.error; }
819
884
  }
820
885
  return experiments;
821
886
  };
@@ -839,8 +904,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
839
904
  }
840
905
  // Apply global defaults to each change
841
906
  return changes.map(function (change) {
842
- var _a, _b, _c, _d;
843
- 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 }));
844
909
  });
845
910
  };
846
911
  /**
@@ -868,14 +933,16 @@ var DOMChangesPluginLite = /** @class */ (function () {
868
933
  globalDefaults = {
869
934
  waitForElement: config.waitForElement,
870
935
  persistStyle: config.persistStyle,
936
+ persistAttribute: config.persistAttribute,
937
+ persistScript: config.persistScript,
871
938
  important: config.important,
872
939
  observerRoot: config.observerRoot,
873
940
  };
874
941
  }
875
942
  // Apply global defaults
876
943
  var processedChanges = variantChanges.map(function (change) {
877
- var _a, _b, _c, _d;
878
- 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 }));
879
946
  });
880
947
  processedVariants.push(processedChanges);
881
948
  };
@@ -920,12 +987,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
920
987
  change: change,
921
988
  });
922
989
  }
990
+ else {
991
+ this.emit('change_failed', {
992
+ experimentName: experimentName,
993
+ change: change,
994
+ reason: 'selector_not_found_or_apply_failed',
995
+ });
996
+ }
923
997
  return success;
924
998
  }
925
999
  catch (error) {
926
- if (this.config.debug) {
927
- logDebug('[ABsmartly] Error applying change:', error);
928
- }
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
+ });
929
1007
  return false;
930
1008
  }
931
1009
  };
@@ -947,7 +1025,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
947
1025
  }
948
1026
  };
949
1027
  DOMChangesPluginLite.prototype.emit = function (event, data) {
950
- var e_6, _a;
1028
+ var e_12, _a;
951
1029
  var listeners = this.eventListeners.get(event) || [];
952
1030
  try {
953
1031
  for (var listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next(); !listeners_1_1.done; listeners_1_1 = listeners_1.next()) {
@@ -960,12 +1038,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
960
1038
  }
961
1039
  }
962
1040
  }
963
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
1041
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
964
1042
  finally {
965
1043
  try {
966
1044
  if (listeners_1_1 && !listeners_1_1.done && (_a = listeners_1.return)) _a.call(listeners_1);
967
1045
  }
968
- finally { if (e_6) throw e_6.error; }
1046
+ finally { if (e_12) throw e_12.error; }
969
1047
  }
970
1048
  };
971
1049
  DOMChangesPluginLite.prototype.getStyleManager = function (experimentName) {
@@ -1016,10 +1094,23 @@ var DOMChangesPluginLite = /** @class */ (function () {
1016
1094
  }
1017
1095
  };
1018
1096
  DOMChangesPluginLite.prototype.destroy = function () {
1097
+ var e_13, _a;
1019
1098
  this.domManipulator.destroy();
1020
1099
  this.exposureTracker.destroy();
1021
1100
  this.htmlInjector.destroy();
1022
- 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
+ }
1023
1114
  this.styleManagers.clear();
1024
1115
  if (this.mutationObserver) {
1025
1116
  this.mutationObserver.disconnect();
@@ -1038,6 +1129,18 @@ var DOMChangesPluginLite = /** @class */ (function () {
1038
1129
  if (antiFlickerStyle) {
1039
1130
  antiFlickerStyle.remove();
1040
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
+ }
1041
1144
  this.eventListeners.clear();
1042
1145
  this.exposedExperiments.clear();
1043
1146
  this.unregisterFromContext();