@absmartly/sdk-plugins 1.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.
- package/README.md +1101 -0
- package/dist/absmartly-cookie.min.js +1 -0
- package/dist/absmartly-dom-changes-core.min.js +1 -0
- package/dist/absmartly-dom-changes-lite.min.js +1 -0
- package/dist/absmartly-overrides-full.min.js +1 -0
- package/dist/absmartly-overrides-lite.min.js +1 -0
- package/dist/absmartly-sdk-plugins.min.js +1 -0
- package/dist/absmartly-vitals.min.js +1 -0
- package/es/cookies/CookiePlugin.js +410 -0
- package/es/cookies/CookiePlugin.js.map +1 -0
- package/es/cookies/index.js +2 -0
- package/es/cookies/index.js.map +1 -0
- package/es/core/DOMChangesPluginLite.js +1124 -0
- package/es/core/DOMChangesPluginLite.js.map +1 -0
- package/es/core/DOMManipulatorLite.js +410 -0
- package/es/core/DOMManipulatorLite.js.map +1 -0
- package/es/core/ExposureTracker.js +501 -0
- package/es/core/ExposureTracker.js.map +1 -0
- package/es/core/HTMLInjector.js +333 -0
- package/es/core/HTMLInjector.js.map +1 -0
- package/es/core/PendingChangeManager.js +440 -0
- package/es/core/PendingChangeManager.js.map +1 -0
- package/es/core/StyleSheetManager.js +78 -0
- package/es/core/StyleSheetManager.js.map +1 -0
- package/es/entries/cookie-only.js +10 -0
- package/es/entries/cookie-only.js.map +1 -0
- package/es/entries/dom-only.js +13 -0
- package/es/entries/dom-only.js.map +1 -0
- package/es/entries/dom-with-overrides-full.js +19 -0
- package/es/entries/dom-with-overrides-full.js.map +1 -0
- package/es/entries/dom-with-overrides-lite.js +15 -0
- package/es/entries/dom-with-overrides-lite.js.map +1 -0
- package/es/entries/overrides-full-only.js +15 -0
- package/es/entries/overrides-full-only.js.map +1 -0
- package/es/entries/overrides-lite-only.js +12 -0
- package/es/entries/overrides-lite-only.js.map +1 -0
- package/es/entries/vitals-only.js +10 -0
- package/es/entries/vitals-only.js.map +1 -0
- package/es/index.js +17 -0
- package/es/index.js.map +1 -0
- package/es/overrides/BrowserCookieAdapter.js +76 -0
- package/es/overrides/BrowserCookieAdapter.js.map +1 -0
- package/es/overrides/OverridesPlugin.js +903 -0
- package/es/overrides/OverridesPlugin.js.map +1 -0
- package/es/overrides/OverridesPluginFull.js +32 -0
- package/es/overrides/OverridesPluginFull.js.map +1 -0
- package/es/overrides/OverridesPluginLite.js +352 -0
- package/es/overrides/OverridesPluginLite.js.map +1 -0
- package/es/overrides/index.js +4 -0
- package/es/overrides/index.js.map +1 -0
- package/es/overrides/types.js +2 -0
- package/es/overrides/types.js.map +1 -0
- package/es/parsers/VariantExtractor.js +570 -0
- package/es/parsers/VariantExtractor.js.map +1 -0
- package/es/types/index.js +2 -0
- package/es/types/index.js.map +1 -0
- package/es/utils/URLMatcher.js +114 -0
- package/es/utils/URLMatcher.js.map +1 -0
- package/es/utils/debug.js +184 -0
- package/es/utils/debug.js.map +1 -0
- package/es/vitals/WebVitalsPlugin.js +379 -0
- package/es/vitals/WebVitalsPlugin.js.map +1 -0
- package/es/vitals/index.js +2 -0
- package/es/vitals/index.js.map +1 -0
- package/lib/cookies/CookiePlugin.d.ts +55 -0
- package/lib/cookies/CookiePlugin.js +413 -0
- package/lib/cookies/CookiePlugin.js.map +1 -0
- package/lib/cookies/index.d.ts +2 -0
- package/lib/cookies/index.js +6 -0
- package/lib/cookies/index.js.map +1 -0
- package/lib/core/DOMChangesPluginLite.d.ts +89 -0
- package/lib/core/DOMChangesPluginLite.js +1127 -0
- package/lib/core/DOMChangesPluginLite.js.map +1 -0
- package/lib/core/DOMManipulatorLite.d.ts +21 -0
- package/lib/core/DOMManipulatorLite.js +413 -0
- package/lib/core/DOMManipulatorLite.js.map +1 -0
- package/lib/core/ExposureTracker.d.ts +81 -0
- package/lib/core/ExposureTracker.js +504 -0
- package/lib/core/ExposureTracker.js.map +1 -0
- package/lib/core/HTMLInjector.d.ts +19 -0
- package/lib/core/HTMLInjector.js +336 -0
- package/lib/core/HTMLInjector.js.map +1 -0
- package/lib/core/PendingChangeManager.d.ts +31 -0
- package/lib/core/PendingChangeManager.js +443 -0
- package/lib/core/PendingChangeManager.js.map +1 -0
- package/lib/core/StyleSheetManager.d.ts +16 -0
- package/lib/core/StyleSheetManager.js +81 -0
- package/lib/core/StyleSheetManager.js.map +1 -0
- package/lib/entries/cookie-only.d.ts +8 -0
- package/lib/entries/cookie-only.js +12 -0
- package/lib/entries/cookie-only.js.map +1 -0
- package/lib/entries/dom-only.d.ts +9 -0
- package/lib/entries/dom-only.js +29 -0
- package/lib/entries/dom-only.js.map +1 -0
- package/lib/entries/dom-with-overrides-full.d.ts +15 -0
- package/lib/entries/dom-with-overrides-full.js +39 -0
- package/lib/entries/dom-with-overrides-full.js.map +1 -0
- package/lib/entries/dom-with-overrides-lite.d.ts +11 -0
- package/lib/entries/dom-with-overrides-lite.js +32 -0
- package/lib/entries/dom-with-overrides-lite.js.map +1 -0
- package/lib/entries/overrides-full-only.d.ts +11 -0
- package/lib/entries/overrides-full-only.js +33 -0
- package/lib/entries/overrides-full-only.js.map +1 -0
- package/lib/entries/overrides-lite-only.d.ts +8 -0
- package/lib/entries/overrides-lite-only.js +28 -0
- package/lib/entries/overrides-lite-only.js.map +1 -0
- package/lib/entries/vitals-only.d.ts +8 -0
- package/lib/entries/vitals-only.js +12 -0
- package/lib/entries/vitals-only.js.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +34 -0
- package/lib/index.js.map +1 -0
- package/lib/overrides/BrowserCookieAdapter.d.ts +6 -0
- package/lib/overrides/BrowserCookieAdapter.js +79 -0
- package/lib/overrides/BrowserCookieAdapter.js.map +1 -0
- package/lib/overrides/OverridesPlugin.d.ts +33 -0
- package/lib/overrides/OverridesPlugin.js +906 -0
- package/lib/overrides/OverridesPlugin.js.map +1 -0
- package/lib/overrides/OverridesPluginFull.d.ts +9 -0
- package/lib/overrides/OverridesPluginFull.js +35 -0
- package/lib/overrides/OverridesPluginFull.js.map +1 -0
- package/lib/overrides/OverridesPluginLite.d.ts +27 -0
- package/lib/overrides/OverridesPluginLite.js +355 -0
- package/lib/overrides/OverridesPluginLite.js.map +1 -0
- package/lib/overrides/index.d.ts +3 -0
- package/lib/overrides/index.js +23 -0
- package/lib/overrides/index.js.map +1 -0
- package/lib/overrides/types.d.ts +43 -0
- package/lib/overrides/types.js +3 -0
- package/lib/overrides/types.js.map +1 -0
- package/lib/parsers/VariantExtractor.d.ts +49 -0
- package/lib/parsers/VariantExtractor.js +573 -0
- package/lib/parsers/VariantExtractor.js.map +1 -0
- package/lib/types/index.d.ts +177 -0
- package/lib/types/index.js +3 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/URLMatcher.d.ts +20 -0
- package/lib/utils/URLMatcher.js +117 -0
- package/lib/utils/URLMatcher.js.map +1 -0
- package/lib/utils/debug.d.ts +41 -0
- package/lib/utils/debug.js +195 -0
- package/lib/utils/debug.js.map +1 -0
- package/lib/vitals/WebVitalsPlugin.d.ts +37 -0
- package/lib/vitals/WebVitalsPlugin.js +382 -0
- package/lib/vitals/WebVitalsPlugin.js.map +1 -0
- package/lib/vitals/index.d.ts +2 -0
- package/lib/vitals/index.js +6 -0
- package/lib/vitals/index.js.map +1 -0
- package/package.json +94 -0
- package/types/cookies/CookiePlugin.d.ts +55 -0
- package/types/cookies/index.d.ts +2 -0
- package/types/core/DOMChangesPluginLite.d.ts +89 -0
- package/types/core/DOMManipulatorLite.d.ts +21 -0
- package/types/core/ExposureTracker.d.ts +81 -0
- package/types/core/HTMLInjector.d.ts +19 -0
- package/types/core/PendingChangeManager.d.ts +31 -0
- package/types/core/StyleSheetManager.d.ts +16 -0
- package/types/entries/cookie-only.d.ts +8 -0
- package/types/entries/dom-only.d.ts +9 -0
- package/types/entries/dom-with-overrides-full.d.ts +15 -0
- package/types/entries/dom-with-overrides-lite.d.ts +11 -0
- package/types/entries/overrides-full-only.d.ts +11 -0
- package/types/entries/overrides-lite-only.d.ts +8 -0
- package/types/entries/vitals-only.d.ts +8 -0
- package/types/index.d.ts +13 -0
- package/types/overrides/BrowserCookieAdapter.d.ts +6 -0
- package/types/overrides/OverridesPlugin.d.ts +33 -0
- package/types/overrides/OverridesPluginFull.d.ts +9 -0
- package/types/overrides/OverridesPluginLite.d.ts +27 -0
- package/types/overrides/index.d.ts +3 -0
- package/types/overrides/types.d.ts +43 -0
- package/types/parsers/VariantExtractor.d.ts +49 -0
- package/types/types/index.d.ts +177 -0
- package/types/utils/URLMatcher.d.ts +20 -0
- package/types/utils/debug.d.ts +41 -0
- package/types/vitals/WebVitalsPlugin.d.ts +37 -0
- package/types/vitals/index.d.ts +2 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DOMChange } from '../types';
|
|
2
|
+
import type { DOMChangesPluginLite } from './DOMChangesPluginLite';
|
|
3
|
+
import { PendingChangeManager } from './PendingChangeManager';
|
|
4
|
+
export declare class DOMManipulatorLite {
|
|
5
|
+
protected debug: boolean;
|
|
6
|
+
protected plugin: DOMChangesPluginLite;
|
|
7
|
+
protected pendingManager: PendingChangeManager;
|
|
8
|
+
private appliedChanges;
|
|
9
|
+
constructor(debug: boolean | undefined, plugin: DOMChangesPluginLite);
|
|
10
|
+
applyChange(change: DOMChange, experimentName: string): boolean;
|
|
11
|
+
protected moveElement(element: Element, target: Element, position?: string): void;
|
|
12
|
+
private createElement;
|
|
13
|
+
private applyStyleRules;
|
|
14
|
+
applyChangeToElement(element: Element, change: DOMChange): void;
|
|
15
|
+
private applyChangeToSpecificElement;
|
|
16
|
+
private trackAppliedChange;
|
|
17
|
+
hasChanges(experimentName: string): boolean;
|
|
18
|
+
clearTracking(experimentName?: string): void;
|
|
19
|
+
removeAllPending(experimentName: string): void;
|
|
20
|
+
destroy(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ABsmartlyContext, DOMChange } from '../types';
|
|
2
|
+
export declare class ExposureTracker {
|
|
3
|
+
private context;
|
|
4
|
+
private experiments;
|
|
5
|
+
private trackedElements;
|
|
6
|
+
private observer;
|
|
7
|
+
private mutationObserver;
|
|
8
|
+
private debug;
|
|
9
|
+
private placeholders;
|
|
10
|
+
constructor(context: ABsmartlyContext, debug?: boolean);
|
|
11
|
+
/**
|
|
12
|
+
* Register an experiment with all its variants' changes for comprehensive tracking
|
|
13
|
+
*/
|
|
14
|
+
registerExperiment(experimentName: string, currentVariant: number, currentChanges: DOMChange[], allVariantsChanges: DOMChange[][]): void;
|
|
15
|
+
/**
|
|
16
|
+
* Create a container-based placeholder at the hypothetical position
|
|
17
|
+
* Uses inline-block with minimal dimensions to be observable but not affect layout
|
|
18
|
+
*/
|
|
19
|
+
private createContainerPlaceholder;
|
|
20
|
+
/**
|
|
21
|
+
* Get the original parent selector for move changes
|
|
22
|
+
* This should be called BEFORE the move is applied
|
|
23
|
+
*/
|
|
24
|
+
getOriginalParentForMove(selector: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Get a stable selector for a parent element
|
|
27
|
+
*/
|
|
28
|
+
private getStableParentSelector;
|
|
29
|
+
/**
|
|
30
|
+
* Set up observers for the given selectors
|
|
31
|
+
*/
|
|
32
|
+
private observeSelectors;
|
|
33
|
+
/**
|
|
34
|
+
* Track an element for viewport visibility
|
|
35
|
+
*/
|
|
36
|
+
private trackElement;
|
|
37
|
+
/**
|
|
38
|
+
* Watch for elements matching a selector to appear
|
|
39
|
+
*/
|
|
40
|
+
private watchForSelector;
|
|
41
|
+
/**
|
|
42
|
+
* Set up the IntersectionObserver for viewport tracking
|
|
43
|
+
*/
|
|
44
|
+
private setupIntersectionObserver;
|
|
45
|
+
/**
|
|
46
|
+
* Set up MutationObserver for dynamic elements
|
|
47
|
+
*/
|
|
48
|
+
private setupMutationObserver;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a newly added element needs tracking
|
|
51
|
+
*/
|
|
52
|
+
private checkNewElement;
|
|
53
|
+
/**
|
|
54
|
+
* Handle when an element becomes visible
|
|
55
|
+
*/
|
|
56
|
+
private handleElementVisible;
|
|
57
|
+
/**
|
|
58
|
+
* Trigger exposure for an experiment
|
|
59
|
+
*/
|
|
60
|
+
private triggerExposure;
|
|
61
|
+
/**
|
|
62
|
+
* Clean up tracking for an experiment that has been triggered
|
|
63
|
+
*/
|
|
64
|
+
private cleanupExperiment;
|
|
65
|
+
/**
|
|
66
|
+
* Get a selector string for an element (for debugging)
|
|
67
|
+
*/
|
|
68
|
+
private getElementSelector;
|
|
69
|
+
/**
|
|
70
|
+
* Check if an experiment needs viewport tracking
|
|
71
|
+
*/
|
|
72
|
+
needsViewportTracking(experimentName: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Check if an experiment has been triggered
|
|
75
|
+
*/
|
|
76
|
+
isTriggered(experimentName: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Clean up all resources
|
|
79
|
+
*/
|
|
80
|
+
destroy(): void;
|
|
81
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { InjectionItem, InjectionLocation, InjectionDataWithFilter } from '../types';
|
|
2
|
+
export declare class HTMLInjector {
|
|
3
|
+
private debug;
|
|
4
|
+
private injectedIds;
|
|
5
|
+
constructor(debug?: boolean);
|
|
6
|
+
parseInjectionKey(key: string): {
|
|
7
|
+
location: InjectionLocation;
|
|
8
|
+
priority: number;
|
|
9
|
+
} | null;
|
|
10
|
+
collectInjections(allInjectHTML: Map<string, Map<number, InjectionDataWithFilter>>, currentUrl?: string): Map<InjectionLocation, InjectionItem[]>;
|
|
11
|
+
inject(injectionsByLocation: Map<InjectionLocation, InjectionItem[]>): void;
|
|
12
|
+
private injectAtLocation;
|
|
13
|
+
private injectHeadStart;
|
|
14
|
+
private injectHeadEnd;
|
|
15
|
+
private injectBodyStart;
|
|
16
|
+
private injectBodyEnd;
|
|
17
|
+
private createContainer;
|
|
18
|
+
destroy(): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DOMChange } from '../types';
|
|
2
|
+
export interface PendingChange {
|
|
3
|
+
change: DOMChange;
|
|
4
|
+
experimentName: string;
|
|
5
|
+
observerRoot?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class PendingChangeManager {
|
|
8
|
+
private applyFn;
|
|
9
|
+
private pending;
|
|
10
|
+
private observers;
|
|
11
|
+
private appliedSelectors;
|
|
12
|
+
private debug;
|
|
13
|
+
private batchTimer;
|
|
14
|
+
private batchedWork;
|
|
15
|
+
constructor(applyFn: (change: DOMChange, experimentName: string, element?: Element) => boolean, debug?: boolean);
|
|
16
|
+
addPending(pendingChange: PendingChange): void;
|
|
17
|
+
removePending(selector: string, experimentName: string, observerRoot?: string): void;
|
|
18
|
+
removeAllPending(experimentName: string): void;
|
|
19
|
+
private ensureObserver;
|
|
20
|
+
private handleMutations;
|
|
21
|
+
private batchWork;
|
|
22
|
+
private processBatchedWork;
|
|
23
|
+
private applyChange;
|
|
24
|
+
private getObserverRoot;
|
|
25
|
+
private checkObserverCleanup;
|
|
26
|
+
private cleanupObservers;
|
|
27
|
+
destroy(): void;
|
|
28
|
+
getPendingCount(): number;
|
|
29
|
+
getAppliedCount(): number;
|
|
30
|
+
hasPendingForExperiment(experimentName: string): boolean;
|
|
31
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class StyleSheetManager {
|
|
2
|
+
private id;
|
|
3
|
+
private styleEl;
|
|
4
|
+
private rules;
|
|
5
|
+
private debug;
|
|
6
|
+
constructor(id: string, debug?: boolean);
|
|
7
|
+
ensure(): HTMLStyleElement;
|
|
8
|
+
setRule(key: string, css: string): void;
|
|
9
|
+
deleteRule(key: string): void;
|
|
10
|
+
hasRule(key: string): boolean;
|
|
11
|
+
clear(): void;
|
|
12
|
+
destroy(): void;
|
|
13
|
+
private render;
|
|
14
|
+
getRulesCount(): number;
|
|
15
|
+
getCssText(): string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for CookiePlugin only
|
|
3
|
+
* Standalone cookie management and tracking functionality
|
|
4
|
+
*/
|
|
5
|
+
import { CookiePlugin } from '../cookies/CookiePlugin';
|
|
6
|
+
export type { CookiePluginOptions } from '../cookies/CookiePlugin';
|
|
7
|
+
export { CookiePlugin };
|
|
8
|
+
export default CookiePlugin;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for DOM Changes Plugin only
|
|
3
|
+
* Smallest bundle - just core DOM manipulation functionality
|
|
4
|
+
*/
|
|
5
|
+
import { DOMChangesPluginLite } from '../core/DOMChangesPluginLite';
|
|
6
|
+
export * from '../types';
|
|
7
|
+
export { DOMChangesPluginLite };
|
|
8
|
+
export { DOMChangesPluginLite as DOMChangesPlugin };
|
|
9
|
+
export default DOMChangesPluginLite;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for DOM Changes Plugin + Overrides Full
|
|
3
|
+
* Full bundle - DOM manipulation + full override capabilities with API support
|
|
4
|
+
*/
|
|
5
|
+
import { DOMChangesPluginLite } from '../core/DOMChangesPluginLite';
|
|
6
|
+
import { OverridesPluginFull } from '../overrides/OverridesPluginFull';
|
|
7
|
+
import { BrowserCookieAdapter } from '../overrides/BrowserCookieAdapter';
|
|
8
|
+
import { CookiePlugin } from '../cookies/CookiePlugin';
|
|
9
|
+
import { WebVitalsPlugin } from '../vitals/WebVitalsPlugin';
|
|
10
|
+
export * from '../types';
|
|
11
|
+
export * from '../overrides/types';
|
|
12
|
+
export { DOMChangesPluginLite, DOMChangesPluginLite as DOMChangesPlugin, // Alias for backward compatibility
|
|
13
|
+
OverridesPluginFull, OverridesPluginFull as OverridesPlugin, // Alias for backward compatibility
|
|
14
|
+
BrowserCookieAdapter, CookiePlugin, WebVitalsPlugin, };
|
|
15
|
+
export default DOMChangesPluginLite;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for DOM Changes Plugin + Overrides Lite
|
|
3
|
+
* Medium bundle - DOM manipulation + lightweight override detection
|
|
4
|
+
*/
|
|
5
|
+
import { DOMChangesPluginLite } from '../core/DOMChangesPluginLite';
|
|
6
|
+
import { OverridesPluginLite } from '../overrides/OverridesPluginLite';
|
|
7
|
+
export * from '../types';
|
|
8
|
+
export * from '../overrides/types';
|
|
9
|
+
export { DOMChangesPluginLite, OverridesPluginLite };
|
|
10
|
+
export { DOMChangesPluginLite as DOMChangesPlugin };
|
|
11
|
+
export default DOMChangesPluginLite;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for Overrides Full Plugin only
|
|
3
|
+
* Full override capabilities with API support, no DOM manipulation
|
|
4
|
+
*/
|
|
5
|
+
import { OverridesPluginFull } from '../overrides/OverridesPluginFull';
|
|
6
|
+
import { BrowserCookieAdapter } from '../overrides/BrowserCookieAdapter';
|
|
7
|
+
import { CookiePlugin } from '../cookies/CookiePlugin';
|
|
8
|
+
export * from '../overrides/types';
|
|
9
|
+
export { OverridesPluginFull, OverridesPluginFull as OverridesPlugin, // Alias for backward compatibility
|
|
10
|
+
BrowserCookieAdapter, CookiePlugin, };
|
|
11
|
+
export default OverridesPluginFull;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for Overrides Lite Plugin only
|
|
3
|
+
* Minimal bundle - just lightweight override detection and application
|
|
4
|
+
*/
|
|
5
|
+
import { OverridesPluginLite } from '../overrides/OverridesPluginLite';
|
|
6
|
+
export * from '../overrides/types';
|
|
7
|
+
export { OverridesPluginLite };
|
|
8
|
+
export default OverridesPluginLite;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for WebVitalsPlugin only
|
|
3
|
+
* Standalone web vitals and page metrics tracking
|
|
4
|
+
*/
|
|
5
|
+
import { WebVitalsPlugin } from '../vitals/WebVitalsPlugin';
|
|
6
|
+
export type { WebVitalsPluginOptions, Metric } from '../vitals/WebVitalsPlugin';
|
|
7
|
+
export { WebVitalsPlugin };
|
|
8
|
+
export default WebVitalsPlugin;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DOMChangesPluginLite } from './core/DOMChangesPluginLite';
|
|
2
|
+
import { OverridesPlugin } from './overrides/OverridesPlugin';
|
|
3
|
+
import { BrowserCookieAdapter } from './overrides/BrowserCookieAdapter';
|
|
4
|
+
import { CookiePlugin } from './cookies/CookiePlugin';
|
|
5
|
+
import { WebVitalsPlugin } from './vitals/WebVitalsPlugin';
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './overrides/types';
|
|
8
|
+
export type { CookiePluginOptions } from './cookies/CookiePlugin';
|
|
9
|
+
export type { WebVitalsPluginOptions, Metric } from './vitals/WebVitalsPlugin';
|
|
10
|
+
export { DOMChangesPluginLite, DOMChangesPluginLite as DOMChangesPlugin, // Alias for backward compatibility
|
|
11
|
+
OverridesPlugin, // Legacy export - this is the original full-featured version
|
|
12
|
+
BrowserCookieAdapter, CookiePlugin, WebVitalsPlugin, };
|
|
13
|
+
export default DOMChangesPluginLite;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CookieAdapter, CookieOptions } from './types';
|
|
2
|
+
export declare class BrowserCookieAdapter implements CookieAdapter {
|
|
3
|
+
get(name: string): string | null;
|
|
4
|
+
set(name: string, value: string, options?: CookieOptions): void;
|
|
5
|
+
delete(name: string, options?: CookieOptions): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-featured version of OverridesPlugin
|
|
3
|
+
* Extends OverridesPluginLite with API fetching for non-running experiments
|
|
4
|
+
* Supports server-side rendering, cookie adapters, and dev environments
|
|
5
|
+
*/
|
|
6
|
+
import { OverridesPluginLite } from './OverridesPluginLite';
|
|
7
|
+
import { OverridesPluginConfig, CookieAdapter } from './types';
|
|
8
|
+
export declare class OverridesPlugin extends OverridesPluginLite {
|
|
9
|
+
protected fullConfig: Required<Omit<OverridesPluginConfig, 'cookieName' | 'url' | 'cookieAdapter'>> & {
|
|
10
|
+
cookieName?: string;
|
|
11
|
+
url?: string | URL;
|
|
12
|
+
cookieAdapter?: CookieAdapter;
|
|
13
|
+
};
|
|
14
|
+
protected isServerSide: boolean;
|
|
15
|
+
private onExperimentsAddedCallbacks;
|
|
16
|
+
constructor(config: OverridesPluginConfig);
|
|
17
|
+
ready(): Promise<void>;
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
private getOverrides;
|
|
20
|
+
private getEnhancedQueryStringOverrides;
|
|
21
|
+
private getEnhancedCookieOverrides;
|
|
22
|
+
private parseEnhancedCookieValue;
|
|
23
|
+
private persistEnhancedOverridesToCookie;
|
|
24
|
+
private applyOverridesWithFetching;
|
|
25
|
+
private fetchFromAPI;
|
|
26
|
+
private fetchFromDevSDK;
|
|
27
|
+
private injectExperimentsIntoContext;
|
|
28
|
+
onExperimentsAdded(callback: () => void): void;
|
|
29
|
+
private notifyExperimentsAdded;
|
|
30
|
+
protected registerWithContext(): void;
|
|
31
|
+
protected unregisterFromContext(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-featured version of OverridesPlugin
|
|
3
|
+
* This is now just an alias for OverridesPlugin to maintain backward compatibility.
|
|
4
|
+
*
|
|
5
|
+
* @deprecated Use OverridesPlugin directly instead
|
|
6
|
+
*/
|
|
7
|
+
import { OverridesPlugin } from './OverridesPlugin';
|
|
8
|
+
export declare class OverridesPluginFull extends OverridesPlugin {
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface ABSmartlyContextLite {
|
|
2
|
+
override?: (experimentName: string, variant: number) => void;
|
|
3
|
+
__plugins?: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
interface LiteConfig {
|
|
6
|
+
context: ABSmartlyContextLite;
|
|
7
|
+
cookieName?: string;
|
|
8
|
+
useQueryString?: boolean;
|
|
9
|
+
queryPrefix?: string;
|
|
10
|
+
persistQueryToCookie?: boolean;
|
|
11
|
+
debug?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class OverridesPluginLite {
|
|
14
|
+
private config;
|
|
15
|
+
protected initialized: boolean;
|
|
16
|
+
constructor(config: LiteConfig);
|
|
17
|
+
ready(): Promise<void>;
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
private getQueryStringOverrides;
|
|
20
|
+
private getCookieOverrides;
|
|
21
|
+
private parseCookieValue;
|
|
22
|
+
private persistOverridesToCookie;
|
|
23
|
+
protected registerWithContext(): void;
|
|
24
|
+
protected unregisterFromContext(): void;
|
|
25
|
+
destroy(): void;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface OverrideValue {
|
|
2
|
+
variant: number;
|
|
3
|
+
env?: number;
|
|
4
|
+
id?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface CookieOverrides {
|
|
7
|
+
[experimentName: string]: number | OverrideValue;
|
|
8
|
+
}
|
|
9
|
+
export interface ParsedCookie {
|
|
10
|
+
overrides: CookieOverrides;
|
|
11
|
+
devEnv: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface CookieOptions {
|
|
14
|
+
httpOnly?: boolean;
|
|
15
|
+
secure?: boolean;
|
|
16
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
17
|
+
domain?: string;
|
|
18
|
+
path?: string;
|
|
19
|
+
maxAge?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface CookieAdapter {
|
|
22
|
+
get(name: string): string | null;
|
|
23
|
+
set(name: string, value: string, options?: CookieOptions): void;
|
|
24
|
+
delete(name: string, options?: CookieOptions): void;
|
|
25
|
+
}
|
|
26
|
+
export interface OverridesPluginConfig {
|
|
27
|
+
context: any;
|
|
28
|
+
cookieName?: string;
|
|
29
|
+
cookieAdapter?: CookieAdapter;
|
|
30
|
+
cookieOptions?: CookieOptions;
|
|
31
|
+
useQueryString?: boolean;
|
|
32
|
+
queryPrefix?: string;
|
|
33
|
+
envParam?: string;
|
|
34
|
+
persistQueryToCookie?: boolean;
|
|
35
|
+
url?: string | URL;
|
|
36
|
+
absmartlyEndpoint?: string;
|
|
37
|
+
sdkEndpoint?: string;
|
|
38
|
+
domChangesFieldName?: string;
|
|
39
|
+
sdkApiKey?: string;
|
|
40
|
+
application?: string;
|
|
41
|
+
environment?: string;
|
|
42
|
+
debug?: boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { DOMChange, ABsmartlyContext, ExperimentData, DOMChangesData, InjectionDataWithFilter } from '../types';
|
|
2
|
+
export declare class VariantExtractor {
|
|
3
|
+
private context;
|
|
4
|
+
private dataSource;
|
|
5
|
+
private dataFieldName;
|
|
6
|
+
private debug;
|
|
7
|
+
private cachedAllChanges;
|
|
8
|
+
constructor(context: ABsmartlyContext, dataSource?: 'variable' | 'customField', dataFieldName?: string, debug?: boolean);
|
|
9
|
+
clearCache(): void;
|
|
10
|
+
extractAllChanges(): Map<string, Map<number, DOMChange[]>>;
|
|
11
|
+
private extractAllVariantsForExperiment;
|
|
12
|
+
/**
|
|
13
|
+
* Extract changes from DOMChangesData (handles both legacy array and new wrapped format)
|
|
14
|
+
*/
|
|
15
|
+
private extractChangesFromData;
|
|
16
|
+
getExperimentChanges(experimentName: string): DOMChange[] | null;
|
|
17
|
+
private parseChanges;
|
|
18
|
+
private isValidChange;
|
|
19
|
+
/**
|
|
20
|
+
* Get all variant changes for an experiment (not just the current variant)
|
|
21
|
+
* This is needed for proper exposure tracking across variants
|
|
22
|
+
*/
|
|
23
|
+
getAllVariantChanges(experimentName: string): DOMChange[][];
|
|
24
|
+
/**
|
|
25
|
+
* Get the experiment data by name
|
|
26
|
+
* Note: This requires the context to be ready, otherwise it will throw
|
|
27
|
+
*/
|
|
28
|
+
getExperiment(experimentName: string): ExperimentData | null;
|
|
29
|
+
/**
|
|
30
|
+
* Get the raw DOMChangesData for all variants of an experiment (includes URL filters and metadata)
|
|
31
|
+
* This is needed for URL filtering logic
|
|
32
|
+
*/
|
|
33
|
+
getAllVariantsData(experimentName: string): Map<number, DOMChangesData>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if any variant of an experiment has changes that match the current URL
|
|
36
|
+
* This is critical for SRM prevention - if ANY variant matches URL, ALL variants must be tracked
|
|
37
|
+
*/
|
|
38
|
+
anyVariantMatchesURL(experimentName: string, url?: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Extract __inject_html from all variants for all experiments
|
|
41
|
+
* Only extracts from variant.variables (not from config)
|
|
42
|
+
*/
|
|
43
|
+
extractAllInjectHTML(): Map<string, Map<number, InjectionDataWithFilter>>;
|
|
44
|
+
/**
|
|
45
|
+
* Extract __inject_html for a single experiment
|
|
46
|
+
* Only from variant.variables (not from config)
|
|
47
|
+
*/
|
|
48
|
+
private extractInjectHTMLForExperiment;
|
|
49
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export type ChangeType = 'text' | 'html' | 'style' | 'styleRules' | 'class' | 'attribute' | 'javascript' | 'move' | 'create' | 'delete';
|
|
2
|
+
export type DOMChangeValue = string | number | boolean | Record<string, string> | undefined;
|
|
3
|
+
export interface URLFilterConfig {
|
|
4
|
+
include?: string[];
|
|
5
|
+
exclude?: string[];
|
|
6
|
+
mode?: 'simple' | 'regex';
|
|
7
|
+
matchType?: 'full-url' | 'path' | 'domain' | 'query' | 'hash';
|
|
8
|
+
}
|
|
9
|
+
export type URLFilter = string | string[] | URLFilterConfig;
|
|
10
|
+
export interface StyleRuleStates {
|
|
11
|
+
normal?: Record<string, string>;
|
|
12
|
+
hover?: Record<string, string>;
|
|
13
|
+
active?: Record<string, string>;
|
|
14
|
+
focus?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
export interface DOMChange {
|
|
17
|
+
selector: string;
|
|
18
|
+
type: ChangeType;
|
|
19
|
+
value?: DOMChangeValue;
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
add?: string[];
|
|
22
|
+
remove?: string[];
|
|
23
|
+
targetSelector?: string;
|
|
24
|
+
position?: 'before' | 'after' | 'firstChild' | 'lastChild';
|
|
25
|
+
element?: string;
|
|
26
|
+
states?: StyleRuleStates;
|
|
27
|
+
important?: boolean;
|
|
28
|
+
observerRoot?: string;
|
|
29
|
+
waitForElement?: boolean;
|
|
30
|
+
persistStyle?: boolean;
|
|
31
|
+
trigger_on_view?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface DOMChangesConfig {
|
|
34
|
+
changes: DOMChange[];
|
|
35
|
+
urlFilter?: URLFilter;
|
|
36
|
+
waitForElement?: boolean;
|
|
37
|
+
persistStyle?: boolean;
|
|
38
|
+
important?: boolean;
|
|
39
|
+
observerRoot?: string;
|
|
40
|
+
}
|
|
41
|
+
export type DOMChangesData = DOMChange[] | DOMChangesConfig;
|
|
42
|
+
export interface InjectionData {
|
|
43
|
+
headStart?: string;
|
|
44
|
+
headEnd?: string;
|
|
45
|
+
bodyStart?: string;
|
|
46
|
+
bodyEnd?: string;
|
|
47
|
+
}
|
|
48
|
+
export type InjectionLocation = 'headStart' | 'headEnd' | 'bodyStart' | 'bodyEnd';
|
|
49
|
+
export interface InjectionItem {
|
|
50
|
+
code: string;
|
|
51
|
+
priority: number;
|
|
52
|
+
location: InjectionLocation;
|
|
53
|
+
}
|
|
54
|
+
export type RawInjectionData = Record<string, string | URLFilter>;
|
|
55
|
+
export interface InjectionDataWithFilter {
|
|
56
|
+
data: RawInjectionData;
|
|
57
|
+
urlFilter?: URLFilter;
|
|
58
|
+
}
|
|
59
|
+
export interface ElementState {
|
|
60
|
+
selector: string;
|
|
61
|
+
type: string;
|
|
62
|
+
originalState: {
|
|
63
|
+
text?: string;
|
|
64
|
+
html?: string;
|
|
65
|
+
style?: string;
|
|
66
|
+
classList?: string[];
|
|
67
|
+
attributes?: Record<string, string>;
|
|
68
|
+
parent?: Element | null;
|
|
69
|
+
nextSibling?: Element | null;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export interface ABsmartlyContext {
|
|
73
|
+
ready(): Promise<void>;
|
|
74
|
+
data(): ContextData | null;
|
|
75
|
+
peek(experimentName: string): number | undefined;
|
|
76
|
+
treatment(experimentName: string): number;
|
|
77
|
+
override(experimentName: string, variant: number): void;
|
|
78
|
+
customFieldValue(experimentName: string, fieldName: string): unknown;
|
|
79
|
+
__plugins?: {
|
|
80
|
+
[key: string]: PluginRegistration | undefined;
|
|
81
|
+
};
|
|
82
|
+
__domPlugin?: PluginRegistration;
|
|
83
|
+
}
|
|
84
|
+
export interface PluginRegistration {
|
|
85
|
+
name: string;
|
|
86
|
+
version: string;
|
|
87
|
+
initialized: boolean;
|
|
88
|
+
capabilities: string[];
|
|
89
|
+
instance: unknown;
|
|
90
|
+
timestamp: number;
|
|
91
|
+
}
|
|
92
|
+
export interface PluginConfig {
|
|
93
|
+
context: ABsmartlyContext;
|
|
94
|
+
autoApply?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* SPA mode - Enables features for Single Page Applications (React, Vue, Angular, etc.)
|
|
97
|
+
* When enabled, automatically activates:
|
|
98
|
+
* - Wait for element: Observes DOM for elements that don't exist yet
|
|
99
|
+
* - Style persistence: Re-applies styles when frameworks overwrite them (e.g., on hover)
|
|
100
|
+
*
|
|
101
|
+
* Set to true for dynamic apps where DOM changes after page load
|
|
102
|
+
*/
|
|
103
|
+
spa?: boolean;
|
|
104
|
+
visibilityTracking?: boolean;
|
|
105
|
+
extensionBridge?: boolean;
|
|
106
|
+
dataSource?: 'variable' | 'customField';
|
|
107
|
+
dataFieldName?: string;
|
|
108
|
+
debug?: boolean;
|
|
109
|
+
hideUntilReady?: boolean | 'body' | 'elements';
|
|
110
|
+
hideTimeout?: number;
|
|
111
|
+
hideSelector?: string;
|
|
112
|
+
hideTransition?: string | false;
|
|
113
|
+
}
|
|
114
|
+
export interface AppliedChange {
|
|
115
|
+
experimentName: string;
|
|
116
|
+
change: DOMChange;
|
|
117
|
+
elements: Element[];
|
|
118
|
+
timestamp: number;
|
|
119
|
+
}
|
|
120
|
+
export interface PendingChange {
|
|
121
|
+
experimentName: string;
|
|
122
|
+
change: DOMChange;
|
|
123
|
+
retryCount: number;
|
|
124
|
+
}
|
|
125
|
+
export type MessagePayloadData = {
|
|
126
|
+
changes?: DOMChange[];
|
|
127
|
+
experimentName?: string;
|
|
128
|
+
count?: number;
|
|
129
|
+
version?: string;
|
|
130
|
+
capabilities?: string[];
|
|
131
|
+
experiments?: ExperimentData[];
|
|
132
|
+
overrides?: Record<string, unknown>;
|
|
133
|
+
locations?: string[];
|
|
134
|
+
error?: string;
|
|
135
|
+
variant?: number;
|
|
136
|
+
changeCount?: number;
|
|
137
|
+
headStart?: string;
|
|
138
|
+
headEnd?: string;
|
|
139
|
+
bodyStart?: string;
|
|
140
|
+
bodyEnd?: string;
|
|
141
|
+
};
|
|
142
|
+
export interface MessagePayload {
|
|
143
|
+
source: string;
|
|
144
|
+
type: string;
|
|
145
|
+
payload?: MessagePayloadData;
|
|
146
|
+
}
|
|
147
|
+
export interface ExperimentVariant {
|
|
148
|
+
variables?: Record<string, unknown>;
|
|
149
|
+
config?: string | Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
export interface ExperimentData {
|
|
152
|
+
name: string;
|
|
153
|
+
variants?: ExperimentVariant[];
|
|
154
|
+
}
|
|
155
|
+
export interface ContextData {
|
|
156
|
+
experiments?: ExperimentData[];
|
|
157
|
+
}
|
|
158
|
+
export type EventCallback = (data?: EventCallbackData) => void;
|
|
159
|
+
export interface EventCallbackData {
|
|
160
|
+
count?: number;
|
|
161
|
+
experimentName?: string;
|
|
162
|
+
changeCount?: number;
|
|
163
|
+
locations?: string[];
|
|
164
|
+
error?: string;
|
|
165
|
+
removedChanges?: AppliedChange[];
|
|
166
|
+
change?: DOMChange;
|
|
167
|
+
}
|
|
168
|
+
export type MessageHandler = (payload: MessagePayloadData) => void;
|
|
169
|
+
export interface ExperimentTracking {
|
|
170
|
+
experimentName: string;
|
|
171
|
+
variant: number;
|
|
172
|
+
changes: DOMChange[];
|
|
173
|
+
allPossibleSelectors: Set<string>;
|
|
174
|
+
triggered: boolean;
|
|
175
|
+
hasImmediateTrigger: boolean;
|
|
176
|
+
hasViewportTrigger: boolean;
|
|
177
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface URLFilterConfig {
|
|
2
|
+
include?: string[];
|
|
3
|
+
exclude?: string[];
|
|
4
|
+
mode?: 'simple' | 'regex';
|
|
5
|
+
matchType?: 'full-url' | 'path' | 'domain' | 'query' | 'hash';
|
|
6
|
+
}
|
|
7
|
+
export type URLFilter = string | string[] | URLFilterConfig;
|
|
8
|
+
export declare class URLMatcher {
|
|
9
|
+
/**
|
|
10
|
+
* Check if current URL matches the filter
|
|
11
|
+
*/
|
|
12
|
+
static matches(filter: URLFilter, url?: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Extract the relevant part of the URL based on matchType
|
|
15
|
+
*/
|
|
16
|
+
private static extractURLPart;
|
|
17
|
+
private static matchesPatterns;
|
|
18
|
+
private static matchSimplePattern;
|
|
19
|
+
private static normalizeFilter;
|
|
20
|
+
}
|