@elevateab/sdk 1.2.6 → 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.
package/dist/next.d.cts CHANGED
@@ -122,12 +122,119 @@ interface ProductViewTrackerProps {
122
122
  */
123
123
  declare function ProductViewTracker({ productId, productVendor, productPrice, productSku, currency, }: ProductViewTrackerProps): null;
124
124
 
125
+ /**
126
+ * Content change - modifies existing elements (text, styles, attributes)
127
+ */
128
+ interface ContentChange {
129
+ /** CSS selector to target the element */
130
+ selector: string;
131
+ /** Text/HTML content to replace - supports responsive variants */
132
+ content?: {
133
+ /** Desktop/large screen content */
134
+ lg: string;
135
+ /** Mobile/small screen content (optional) */
136
+ sm?: string;
137
+ };
138
+ /** CSS styles to apply - supports responsive variants */
139
+ style?: {
140
+ /** Desktop/large screen styles */
141
+ lg: Record<string, string>;
142
+ /** Mobile/small screen styles (optional) */
143
+ sm?: Record<string, string>;
144
+ };
145
+ /** HTML attributes to set on the element */
146
+ attributes?: Record<string, string>;
147
+ /** Pathnames where this change applies (supports wildcards like "*", "*\/products\/*") */
148
+ pathnames?: string[];
149
+ /** If true, applies to all matching elements; otherwise only first match */
150
+ applyAll?: boolean;
151
+ }
152
+ /**
153
+ * Content element - injects new HTML elements into the page
154
+ */
155
+ interface ContentElement {
156
+ /** Unique identifier for this element */
157
+ id: string;
158
+ /** HTML tag name (e.g., "div", "span", "p") */
159
+ tagName: string;
160
+ /** Element type: "text" for text content, "container" for nested elements */
161
+ kind: "text" | "container";
162
+ /** Text content (for kind="text") */
163
+ content?: string;
164
+ /** Inline styles to apply */
165
+ style?: Record<string, string>;
166
+ /** HTML attributes to set */
167
+ attributes?: Record<string, string>;
168
+ /** Child elements (for kind="container") */
169
+ childrens?: ContentElement[];
170
+ /** Selector configuration for placement */
171
+ selector: {
172
+ /** CSS selector for the target element */
173
+ target: string;
174
+ /** Where to place relative to target */
175
+ placement: "before" | "after";
176
+ /** Pathnames where this element should appear */
177
+ pathnames?: string[];
178
+ };
179
+ }
180
+ /**
181
+ * Content block - renders a component (future: React components)
182
+ * Currently deferred to v2 - blocks require dynamic component loading
183
+ */
184
+ interface ContentBlock {
185
+ /** Unique identifier for this block */
186
+ id: string;
187
+ /** Block type identifier (maps to a component) */
188
+ type: string;
189
+ /** URL to load the block component from */
190
+ url: string;
191
+ /** Options/props to pass to the block component */
192
+ options: Record<string, unknown>;
193
+ /** Selector configuration for placement */
194
+ selector: {
195
+ /** CSS selector for the target element */
196
+ target: string;
197
+ /** Where to place relative to target */
198
+ placement: "before" | "after";
199
+ /** Pathnames where this block should appear */
200
+ pathnames?: string[];
201
+ };
202
+ }
203
+ /**
204
+ * Custom code injection - CSS and/or JavaScript to inject
205
+ */
206
+ interface ContentCustomCode {
207
+ /** Unique identifier for this code block */
208
+ id: string;
209
+ /** CSS code to inject into <head> */
210
+ css?: string;
211
+ /** JavaScript code to inject and execute */
212
+ js?: string;
213
+ /** Pathnames where this code should run (supports wildcards) */
214
+ pathnames?: string[];
215
+ /** Pathnames to exclude from running this code */
216
+ excludePathnames?: string[];
217
+ }
218
+ /**
219
+ * Complete content test data structure
220
+ */
221
+ interface ContentTestData {
222
+ /** Text/style/attribute modifications to existing elements */
223
+ changes: ContentChange[];
224
+ /** New HTML elements to inject */
225
+ elements: ContentElement[];
226
+ /** Component blocks to render (v2 feature) */
227
+ blocks: ContentBlock[];
228
+ /** Custom CSS/JS code to inject */
229
+ customCodes: ContentCustomCode[];
230
+ }
125
231
  interface Test {
126
232
  testId: string;
127
233
  name: string;
128
234
  enabled: boolean;
129
235
  type: string;
130
236
  variations: Variation[];
237
+ data?: any;
131
238
  }
132
239
  interface Variation {
133
240
  id: string;
@@ -137,6 +244,16 @@ interface Variation {
137
244
  productId?: string;
138
245
  handle?: string;
139
246
  price?: string;
247
+ /** Variant-specific prices for PRICE_PLUS tests: { [variantId]: { main, price, compare } } */
248
+ prices?: Record<string, {
249
+ main: string;
250
+ price: Record<string, string>;
251
+ compare: Record<string, string | null>;
252
+ }>;
253
+ /** URLs for SPLIT_URL tests */
254
+ splitUrlTestLinks?: string[];
255
+ /** Content test data for CONTENT tests */
256
+ content?: ContentTestData;
140
257
  /** Convenience flag: true if this is variation A (index 0) */
141
258
  isA?: boolean;
142
259
  /** Convenience flag: true if this is variation B (index 1) */
@@ -160,6 +277,15 @@ interface ElevateContextValue {
160
277
  isPreviewMode?: boolean;
161
278
  /** Current preview test ID if in preview mode */
162
279
  previewTestId?: string | null;
280
+ /** Full preview state with forced assignments */
281
+ previewState?: {
282
+ isPreview: boolean;
283
+ previewTestId: string | null;
284
+ forcedAssignments: Record<string, string>;
285
+ previewedViews: Record<string, boolean>;
286
+ } | null;
287
+ /** Selectors configuration for DOM manipulation */
288
+ selectors?: unknown;
163
289
  /** User's detected country code */
164
290
  countryCode?: string | null;
165
291
  }
@@ -499,18 +625,6 @@ declare function matchesGeoTargeting(rules: {
499
625
  excludeCountries?: string[];
500
626
  }): boolean;
501
627
 
502
- /**
503
- * Script snippet for inline injection in <head>
504
- * Use this when you need synchronous flicker prevention before React hydrates
505
- *
506
- * @example
507
- * ```tsx
508
- * // In your _document.tsx or layout.tsx
509
- * <script dangerouslySetInnerHTML={{ __html: getFlickerPreventionScript() }} />
510
- * ```
511
- */
512
- declare function getFlickerPreventionScript(timeout?: number): string;
513
-
514
628
  /**
515
629
  * Shopify-specific utilities
516
630
  */
@@ -698,8 +812,8 @@ declare function trackCheckoutCompleted(params: Omit<TrackCheckoutCompletedParam
698
812
  }): Promise<void>;
699
813
 
700
814
  interface UseExperimentResult {
701
- /** The full variant object (null if not assigned) */
702
- variant: Variation | null;
815
+ /** The full variant object with handler data (null if not assigned) */
816
+ variant: (Variation & Record<string, unknown>) | null;
703
817
  /** True while loading config */
704
818
  isLoading: boolean;
705
819
  /** True if assigned to control group */
@@ -727,65 +841,9 @@ interface UseExperimentResult {
727
841
  */
728
842
  declare function useExperiment(testId: string): UseExperimentResult;
729
843
 
730
- interface AntiFlickerScriptProps {
731
- /**
732
- * Maximum time (ms) to wait before showing content anyway (failsafe)
733
- * @default 3000
734
- */
735
- timeout?: number;
736
- }
737
- /**
738
- * Anti-flicker script component
739
- *
740
- * Renders a script tag that prevents content flash during A/B test loading.
741
- * Place this in your <head> element before any other scripts.
742
- *
743
- * @example Hydrogen (app/root.tsx)
744
- * ```tsx
745
- * import { AntiFlickerScript, ElevateProvider } from "@elevateab/sdk";
746
- *
747
- * export default function Root() {
748
- * return (
749
- * <html>
750
- * <head>
751
- * <AntiFlickerScript />
752
- * </head>
753
- * <body>
754
- * <ElevateProvider storeId="..." preventFlickering={true}>
755
- * <Outlet />
756
- * </ElevateProvider>
757
- * </body>
758
- * </html>
759
- * );
760
- * }
761
- * ```
762
- *
763
- * @example Next.js (app/layout.tsx)
764
- * ```tsx
765
- * import { AntiFlickerScript } from "@elevateab/sdk";
766
- * import { ElevateNextProvider } from "@elevateab/sdk/next";
767
- *
768
- * export default function RootLayout({ children }) {
769
- * return (
770
- * <html>
771
- * <head>
772
- * <AntiFlickerScript />
773
- * </head>
774
- * <body>
775
- * <ElevateNextProvider storeId="..." preventFlickering={true}>
776
- * {children}
777
- * </ElevateNextProvider>
778
- * </body>
779
- * </html>
780
- * );
781
- * }
782
- * ```
783
- */
784
- declare function AntiFlickerScript({ timeout }: AntiFlickerScriptProps): react_jsx_runtime.JSX.Element;
785
-
786
844
  /**
787
845
  * Hook to access Elevate config from context
788
846
  */
789
847
  declare function useElevateConfig(): ElevateContextValue;
790
848
 
791
- export { AntiFlickerScript, type CartItemInput, type ElevateConfig, type ElevateContextValue, ElevateNextProvider, type PreviewState, ProductViewTracker, type TrackAddToCartParams, type TrackPageViewParams, type TrackProductViewParams, type UseExperimentResult, clearPreviewMode, extractShopifyId, extractShopifyType, getCountryCode, getFlickerPreventionScript, getPreviewState, isInPreviewMode, isShopifyGid, matchesGeoTargeting, trackAddToCart, trackCartView, trackCheckoutCompleted, trackCheckoutStarted, trackPageView, trackProductView, trackRemoveFromCart, trackSearchSubmitted, useElevateConfig, useExperiment };
849
+ export { type CartItemInput, type ElevateConfig, type ElevateContextValue, ElevateNextProvider, type PreviewState, ProductViewTracker, type TrackAddToCartParams, type TrackPageViewParams, type TrackProductViewParams, type UseExperimentResult, clearPreviewMode, extractShopifyId, extractShopifyType, getCountryCode, getPreviewState, isInPreviewMode, isShopifyGid, matchesGeoTargeting, trackAddToCart, trackCartView, trackCheckoutCompleted, trackCheckoutStarted, trackPageView, trackProductView, trackRemoveFromCart, trackSearchSubmitted, useElevateConfig, useExperiment };
package/dist/next.d.ts CHANGED
@@ -122,12 +122,119 @@ interface ProductViewTrackerProps {
122
122
  */
123
123
  declare function ProductViewTracker({ productId, productVendor, productPrice, productSku, currency, }: ProductViewTrackerProps): null;
124
124
 
125
+ /**
126
+ * Content change - modifies existing elements (text, styles, attributes)
127
+ */
128
+ interface ContentChange {
129
+ /** CSS selector to target the element */
130
+ selector: string;
131
+ /** Text/HTML content to replace - supports responsive variants */
132
+ content?: {
133
+ /** Desktop/large screen content */
134
+ lg: string;
135
+ /** Mobile/small screen content (optional) */
136
+ sm?: string;
137
+ };
138
+ /** CSS styles to apply - supports responsive variants */
139
+ style?: {
140
+ /** Desktop/large screen styles */
141
+ lg: Record<string, string>;
142
+ /** Mobile/small screen styles (optional) */
143
+ sm?: Record<string, string>;
144
+ };
145
+ /** HTML attributes to set on the element */
146
+ attributes?: Record<string, string>;
147
+ /** Pathnames where this change applies (supports wildcards like "*", "*\/products\/*") */
148
+ pathnames?: string[];
149
+ /** If true, applies to all matching elements; otherwise only first match */
150
+ applyAll?: boolean;
151
+ }
152
+ /**
153
+ * Content element - injects new HTML elements into the page
154
+ */
155
+ interface ContentElement {
156
+ /** Unique identifier for this element */
157
+ id: string;
158
+ /** HTML tag name (e.g., "div", "span", "p") */
159
+ tagName: string;
160
+ /** Element type: "text" for text content, "container" for nested elements */
161
+ kind: "text" | "container";
162
+ /** Text content (for kind="text") */
163
+ content?: string;
164
+ /** Inline styles to apply */
165
+ style?: Record<string, string>;
166
+ /** HTML attributes to set */
167
+ attributes?: Record<string, string>;
168
+ /** Child elements (for kind="container") */
169
+ childrens?: ContentElement[];
170
+ /** Selector configuration for placement */
171
+ selector: {
172
+ /** CSS selector for the target element */
173
+ target: string;
174
+ /** Where to place relative to target */
175
+ placement: "before" | "after";
176
+ /** Pathnames where this element should appear */
177
+ pathnames?: string[];
178
+ };
179
+ }
180
+ /**
181
+ * Content block - renders a component (future: React components)
182
+ * Currently deferred to v2 - blocks require dynamic component loading
183
+ */
184
+ interface ContentBlock {
185
+ /** Unique identifier for this block */
186
+ id: string;
187
+ /** Block type identifier (maps to a component) */
188
+ type: string;
189
+ /** URL to load the block component from */
190
+ url: string;
191
+ /** Options/props to pass to the block component */
192
+ options: Record<string, unknown>;
193
+ /** Selector configuration for placement */
194
+ selector: {
195
+ /** CSS selector for the target element */
196
+ target: string;
197
+ /** Where to place relative to target */
198
+ placement: "before" | "after";
199
+ /** Pathnames where this block should appear */
200
+ pathnames?: string[];
201
+ };
202
+ }
203
+ /**
204
+ * Custom code injection - CSS and/or JavaScript to inject
205
+ */
206
+ interface ContentCustomCode {
207
+ /** Unique identifier for this code block */
208
+ id: string;
209
+ /** CSS code to inject into <head> */
210
+ css?: string;
211
+ /** JavaScript code to inject and execute */
212
+ js?: string;
213
+ /** Pathnames where this code should run (supports wildcards) */
214
+ pathnames?: string[];
215
+ /** Pathnames to exclude from running this code */
216
+ excludePathnames?: string[];
217
+ }
218
+ /**
219
+ * Complete content test data structure
220
+ */
221
+ interface ContentTestData {
222
+ /** Text/style/attribute modifications to existing elements */
223
+ changes: ContentChange[];
224
+ /** New HTML elements to inject */
225
+ elements: ContentElement[];
226
+ /** Component blocks to render (v2 feature) */
227
+ blocks: ContentBlock[];
228
+ /** Custom CSS/JS code to inject */
229
+ customCodes: ContentCustomCode[];
230
+ }
125
231
  interface Test {
126
232
  testId: string;
127
233
  name: string;
128
234
  enabled: boolean;
129
235
  type: string;
130
236
  variations: Variation[];
237
+ data?: any;
131
238
  }
132
239
  interface Variation {
133
240
  id: string;
@@ -137,6 +244,16 @@ interface Variation {
137
244
  productId?: string;
138
245
  handle?: string;
139
246
  price?: string;
247
+ /** Variant-specific prices for PRICE_PLUS tests: { [variantId]: { main, price, compare } } */
248
+ prices?: Record<string, {
249
+ main: string;
250
+ price: Record<string, string>;
251
+ compare: Record<string, string | null>;
252
+ }>;
253
+ /** URLs for SPLIT_URL tests */
254
+ splitUrlTestLinks?: string[];
255
+ /** Content test data for CONTENT tests */
256
+ content?: ContentTestData;
140
257
  /** Convenience flag: true if this is variation A (index 0) */
141
258
  isA?: boolean;
142
259
  /** Convenience flag: true if this is variation B (index 1) */
@@ -160,6 +277,15 @@ interface ElevateContextValue {
160
277
  isPreviewMode?: boolean;
161
278
  /** Current preview test ID if in preview mode */
162
279
  previewTestId?: string | null;
280
+ /** Full preview state with forced assignments */
281
+ previewState?: {
282
+ isPreview: boolean;
283
+ previewTestId: string | null;
284
+ forcedAssignments: Record<string, string>;
285
+ previewedViews: Record<string, boolean>;
286
+ } | null;
287
+ /** Selectors configuration for DOM manipulation */
288
+ selectors?: unknown;
163
289
  /** User's detected country code */
164
290
  countryCode?: string | null;
165
291
  }
@@ -499,18 +625,6 @@ declare function matchesGeoTargeting(rules: {
499
625
  excludeCountries?: string[];
500
626
  }): boolean;
501
627
 
502
- /**
503
- * Script snippet for inline injection in <head>
504
- * Use this when you need synchronous flicker prevention before React hydrates
505
- *
506
- * @example
507
- * ```tsx
508
- * // In your _document.tsx or layout.tsx
509
- * <script dangerouslySetInnerHTML={{ __html: getFlickerPreventionScript() }} />
510
- * ```
511
- */
512
- declare function getFlickerPreventionScript(timeout?: number): string;
513
-
514
628
  /**
515
629
  * Shopify-specific utilities
516
630
  */
@@ -698,8 +812,8 @@ declare function trackCheckoutCompleted(params: Omit<TrackCheckoutCompletedParam
698
812
  }): Promise<void>;
699
813
 
700
814
  interface UseExperimentResult {
701
- /** The full variant object (null if not assigned) */
702
- variant: Variation | null;
815
+ /** The full variant object with handler data (null if not assigned) */
816
+ variant: (Variation & Record<string, unknown>) | null;
703
817
  /** True while loading config */
704
818
  isLoading: boolean;
705
819
  /** True if assigned to control group */
@@ -727,65 +841,9 @@ interface UseExperimentResult {
727
841
  */
728
842
  declare function useExperiment(testId: string): UseExperimentResult;
729
843
 
730
- interface AntiFlickerScriptProps {
731
- /**
732
- * Maximum time (ms) to wait before showing content anyway (failsafe)
733
- * @default 3000
734
- */
735
- timeout?: number;
736
- }
737
- /**
738
- * Anti-flicker script component
739
- *
740
- * Renders a script tag that prevents content flash during A/B test loading.
741
- * Place this in your <head> element before any other scripts.
742
- *
743
- * @example Hydrogen (app/root.tsx)
744
- * ```tsx
745
- * import { AntiFlickerScript, ElevateProvider } from "@elevateab/sdk";
746
- *
747
- * export default function Root() {
748
- * return (
749
- * <html>
750
- * <head>
751
- * <AntiFlickerScript />
752
- * </head>
753
- * <body>
754
- * <ElevateProvider storeId="..." preventFlickering={true}>
755
- * <Outlet />
756
- * </ElevateProvider>
757
- * </body>
758
- * </html>
759
- * );
760
- * }
761
- * ```
762
- *
763
- * @example Next.js (app/layout.tsx)
764
- * ```tsx
765
- * import { AntiFlickerScript } from "@elevateab/sdk";
766
- * import { ElevateNextProvider } from "@elevateab/sdk/next";
767
- *
768
- * export default function RootLayout({ children }) {
769
- * return (
770
- * <html>
771
- * <head>
772
- * <AntiFlickerScript />
773
- * </head>
774
- * <body>
775
- * <ElevateNextProvider storeId="..." preventFlickering={true}>
776
- * {children}
777
- * </ElevateNextProvider>
778
- * </body>
779
- * </html>
780
- * );
781
- * }
782
- * ```
783
- */
784
- declare function AntiFlickerScript({ timeout }: AntiFlickerScriptProps): react_jsx_runtime.JSX.Element;
785
-
786
844
  /**
787
845
  * Hook to access Elevate config from context
788
846
  */
789
847
  declare function useElevateConfig(): ElevateContextValue;
790
848
 
791
- export { AntiFlickerScript, type CartItemInput, type ElevateConfig, type ElevateContextValue, ElevateNextProvider, type PreviewState, ProductViewTracker, type TrackAddToCartParams, type TrackPageViewParams, type TrackProductViewParams, type UseExperimentResult, clearPreviewMode, extractShopifyId, extractShopifyType, getCountryCode, getFlickerPreventionScript, getPreviewState, isInPreviewMode, isShopifyGid, matchesGeoTargeting, trackAddToCart, trackCartView, trackCheckoutCompleted, trackCheckoutStarted, trackPageView, trackProductView, trackRemoveFromCart, trackSearchSubmitted, useElevateConfig, useExperiment };
849
+ export { type CartItemInput, type ElevateConfig, type ElevateContextValue, ElevateNextProvider, type PreviewState, ProductViewTracker, type TrackAddToCartParams, type TrackPageViewParams, type TrackProductViewParams, type UseExperimentResult, clearPreviewMode, extractShopifyId, extractShopifyType, getCountryCode, getPreviewState, isInPreviewMode, isShopifyGid, matchesGeoTargeting, trackAddToCart, trackCartView, trackCheckoutCompleted, trackCheckoutStarted, trackPageView, trackProductView, trackRemoveFromCart, trackSearchSubmitted, useElevateConfig, useExperiment };