@coframe/sdk 1.1.2 → 1.1.4

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.
@@ -1105,8 +1105,11 @@ function createSession(data) {
1105
1105
  console.warn('[Coframe] cannot send event beacon, feature unavailable');
1106
1106
  }
1107
1107
  }
1108
- async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, headers) {
1108
+ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, previewVariantId, headers) {
1109
1109
  const payload = { projectId, currentUrl };
1110
+ if (previewVariantId) {
1111
+ payload.previewVariantId = previewVariantId;
1112
+ }
1110
1113
  const safe = sanitizeUserContext(userContext);
1111
1114
  if (safe) {
1112
1115
  payload.userContext = safe;
@@ -1204,10 +1207,10 @@ const executeJs = (jsCode, args = {}, opts = {}) => {
1204
1207
  w.Coframe.vars[elKey] = opts.elementRef;
1205
1208
  }
1206
1209
  const invocation = opts.isExpression
1207
- ? `(${jsCode})(__args)`
1210
+ ? `(\n${jsCode}\n)(__args)`
1208
1211
  : opts.elementRef
1209
- ? `(function(el){ ${jsCode} })(__args.el)`
1210
- : `(function(){ ${jsCode} })()`;
1212
+ ? `(function(el){\n${jsCode}\n})(__args.el)`
1213
+ : `(function(){\n${jsCode}\n})()`;
1211
1214
  const ranKey = `${key}_ran`;
1212
1215
  const script = document.createElement('script');
1213
1216
  script.id = `coframe-script-${key}`;
@@ -1243,6 +1246,7 @@ const executeJs = (jsCode, args = {}, opts = {}) => {
1243
1246
  return value;
1244
1247
  };
1245
1248
  const applyJavascriptModification = (element, args, logger, nonce, logMetadata = {}) => {
1249
+ var _a, _b;
1246
1250
  const javascript = args.js;
1247
1251
  try {
1248
1252
  if (!javascript) {
@@ -1264,9 +1268,11 @@ const applyJavascriptModification = (element, args, logger, nonce, logMetadata =
1264
1268
  if (logger === null || logger === void 0 ? void 0 : logger.error) {
1265
1269
  logger.error('Error executing JavaScript:', 'error_execute_js', {
1266
1270
  ...logMetadata,
1267
- error,
1271
+ error: error instanceof Error
1272
+ ? error.stack || error.message
1273
+ : String(error),
1268
1274
  javascript,
1269
- element,
1275
+ element: (_b = (_a = element.outerHTML) === null || _a === void 0 ? void 0 : _a.slice(0, 200)) !== null && _b !== void 0 ? _b : element.tagName,
1270
1276
  });
1271
1277
  }
1272
1278
  else {
@@ -2293,7 +2299,7 @@ function checkAllAudiences(metadata, project, personalizationHeaders, currentPag
2293
2299
  }
2294
2300
  return result;
2295
2301
  }
2296
- async function getVariantsAndElements(personalizationHeaders, project, previewVariantId, userToken, currentPageUrl, languages, browserPlatform, logger, nonce, laneClaims = {}) {
2302
+ async function getVariantsAndElements(personalizationHeaders, project, previewVariantId, userToken, currentPageUrl, languages, browserPlatform, logger, nonce, laneClaims = {}, silentFallback = false) {
2297
2303
  var _a, _b;
2298
2304
  const experimentsInfo = [];
2299
2305
  const variantsAndElements = [];
@@ -2322,10 +2328,13 @@ async function getVariantsAndElements(personalizationHeaders, project, previewVa
2322
2328
  hasActivatedFrames: true,
2323
2329
  });
2324
2330
  }
2325
- if (!skipAlert) {
2331
+ if (!skipAlert && !silentFallback) {
2326
2332
  window.alert(`[Coframe] Variant preview unavailable: ${previewVariantId}.`);
2327
2333
  }
2328
- return buildResponse({});
2334
+ if (silentFallback) ;
2335
+ else {
2336
+ return buildResponse({});
2337
+ }
2329
2338
  }
2330
2339
  const userVisitCount = Number.parseInt(getCookie(VISIT_COUNT_COOKIE_KEY) || '0', 10);
2331
2340
  const validatedClaims = validateClaims(laneClaims, project.lanes);
@@ -2596,6 +2605,125 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
2596
2605
  patchHistoryMethod('replaceState');
2597
2606
  }
2598
2607
 
2608
+ const TIMEOUT_MAX_MS = 5000;
2609
+ function getFeatureFlagValue(cmd) {
2610
+ if (cmd.featureFlagSet !== undefined)
2611
+ return cmd.featureFlagSet;
2612
+ if (typeof cmd.emit === 'object' &&
2613
+ cmd.emit !== null &&
2614
+ 'featureFlagSet' in cmd.emit) {
2615
+ return cmd.emit.featureFlagSet;
2616
+ }
2617
+ return undefined;
2618
+ }
2619
+ async function resolveFeatureFlag(Coframe, timeoutMs) {
2620
+ const cmd = await waitForCmd((cmd) => typeof getFeatureFlagValue(cmd) === 'boolean', Coframe, timeoutMs);
2621
+ if (!cmd)
2622
+ return undefined;
2623
+ return getFeatureFlagValue(cmd);
2624
+ }
2625
+ async function resolveConfig(Coframe, revealPage) {
2626
+ const logger = Coframe.logger;
2627
+ const configCmd = await waitForCmd((cmd) => !!cmd.config, Coframe);
2628
+ if (!configCmd) {
2629
+ logger.error('Failed to wait for config cmd', 'wait_for_cmd_timeout');
2630
+ return null;
2631
+ }
2632
+ const config = configCmd.config;
2633
+ const timeoutMs = (config === null || config === void 0 ? void 0 : config.timeoutMs)
2634
+ ? Math.min(config.timeoutMs, TIMEOUT_MAX_MS)
2635
+ : TIMEOUT_MAX_MS;
2636
+ const integrationStartTime = (config === null || config === void 0 ? void 0 : config.startTime)
2637
+ ? new Date(config.startTime)
2638
+ : null;
2639
+ const executionStartTime = new Date();
2640
+ Coframe.batchSize = config.batchSize || 32;
2641
+ const gracefulExit = (msg) => {
2642
+ console.warn(`[Coframe] ${msg}`);
2643
+ revealPage();
2644
+ return null;
2645
+ };
2646
+ if (config.waitForFeatureFlag) {
2647
+ const flag = await resolveFeatureFlag(Coframe, timeoutMs);
2648
+ if (flag === undefined) {
2649
+ return gracefulExit('Feature flag was not set after timeout, graceful exit');
2650
+ }
2651
+ if (flag === false) {
2652
+ return gracefulExit('Feature flag is set to false, graceful exit');
2653
+ }
2654
+ }
2655
+ const projectId = config === null || config === void 0 ? void 0 : config.projectId;
2656
+ const warnMissingVariant = () => {
2657
+ if (applyVariantChangesStarted) {
2658
+ logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
2659
+ }
2660
+ };
2661
+ waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
2662
+ .then((cmd) => {
2663
+ if (!cmd) {
2664
+ warnMissingVariant();
2665
+ }
2666
+ })
2667
+ .finally(() => {
2668
+ revealPage();
2669
+ });
2670
+ if (!projectId) {
2671
+ logger.error('No project ID', 'no_project_id', {
2672
+ description: 'No Coframe Page ID',
2673
+ });
2674
+ variantRendered();
2675
+ return null;
2676
+ }
2677
+ Coframe.projectId = projectId;
2678
+ const urlParams = getCurrentUrlSearchParams();
2679
+ const urlVariantId = urlParams.get('coframe_variant_id');
2680
+ const shouldSendEventsParam = urlParams.get('coframe_should_send_events');
2681
+ const keepForSession = urlParams.get('keep_preview_for_session') === 'true';
2682
+ let previewVariantId = null;
2683
+ let isSessionVariant = false;
2684
+ if (urlVariantId) {
2685
+ previewVariantId = urlVariantId;
2686
+ if (keepForSession) {
2687
+ persistPreviewVariantId(urlVariantId);
2688
+ }
2689
+ }
2690
+ else {
2691
+ const stored = readPreviewVariantId();
2692
+ if (stored) {
2693
+ previewVariantId = stored;
2694
+ isSessionVariant = true;
2695
+ }
2696
+ }
2697
+ setForceSendEvents(shouldSendEventsParam === 'true');
2698
+ setIsPreviewVariant(!!previewVariantId);
2699
+ setWaitingForCookies(!!config.waitForCookiesEnabled);
2700
+ return {
2701
+ config,
2702
+ timeoutMs,
2703
+ projectId,
2704
+ previewVariantId,
2705
+ isSessionVariant,
2706
+ integrationStartTime,
2707
+ executionStartTime,
2708
+ };
2709
+ }
2710
+ const SESSION_VARIANT_KEY = 'coframe.preview_variant';
2711
+ function readPreviewVariantId() {
2712
+ try {
2713
+ return sessionStorage.getItem(SESSION_VARIANT_KEY);
2714
+ }
2715
+ catch (_a) {
2716
+ return null;
2717
+ }
2718
+ }
2719
+ function persistPreviewVariantId(variantId) {
2720
+ try {
2721
+ sessionStorage.setItem(SESSION_VARIANT_KEY, variantId);
2722
+ }
2723
+ catch (_a) {
2724
+ }
2725
+ }
2726
+
2599
2727
  function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders) {
2600
2728
  const sessionPayload = [
2601
2729
  Coframe,
@@ -2907,9 +3035,29 @@ function setupTracking(Coframe, projectResult, previewVariantId, executionStartT
2907
3035
  return analytics;
2908
3036
  }
2909
3037
 
2910
- async function awaitHydration(config, Coframe) {
3038
+ function resolvePreview(pageUrl, previewVariantId, isSessionVariant) {
3039
+ let urlPreviewVariantId = null;
3040
+ try {
3041
+ urlPreviewVariantId = new URL(pageUrl).searchParams.get('coframe_variant_id');
3042
+ }
3043
+ catch (_a) {
3044
+ urlPreviewVariantId = getCurrentUrlSearchParams().get('coframe_variant_id');
3045
+ }
3046
+ if (urlPreviewVariantId) {
3047
+ return { previewVariantId: urlPreviewVariantId, isSessionVariant: false };
3048
+ }
3049
+ if (previewVariantId) {
3050
+ return { previewVariantId, isSessionVariant };
3051
+ }
3052
+ const stored = readPreviewVariantId();
3053
+ return { previewVariantId: stored, isSessionVariant: !!stored };
3054
+ }
3055
+ async function awaitHydration(config, Coframe, project) {
3056
+ var _a, _b;
2911
3057
  if (!config.waitForHydration)
2912
3058
  return true;
3059
+ if (!((_a = project.frames) === null || _a === void 0 ? void 0 : _a.length) && !((_b = project.tags) === null || _b === void 0 ? void 0 : _b.length))
3060
+ return true;
2913
3061
  const cmd = await waitForCmd((cmd) => cmd.pageHydrated === true || cmd.emit === 'pageHydrated', Coframe);
2914
3062
  if (!cmd) {
2915
3063
  Coframe.logger.warn('Failed to wait for page hydrated command', 'wait_for_cmd_timeout');
@@ -2936,7 +3084,7 @@ function setupFlushInterval(projectId) {
2936
3084
  }
2937
3085
  flushInterval = setInterval(() => flushQueuedEvents(projectId), FLUSH_EVENTS_TIME);
2938
3086
  }
2939
- function setupSPANavigation(Coframe, project, config, applyVariants) {
3087
+ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessionVariant, applyVariants) {
2940
3088
  var _a;
2941
3089
  if (!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.mutation_observer_active))
2942
3090
  return;
@@ -2975,7 +3123,8 @@ function setupSPANavigation(Coframe, project, config, applyVariants) {
2975
3123
  }
2976
3124
  else {
2977
3125
  try {
2978
- const result = await fetchProjectFromEdge(Coframe.projectId, newPageUrl, signal, config.userContext);
3126
+ const preview = resolvePreview(newPageUrl, previewVariantId, isSessionVariant);
3127
+ const result = await fetchProjectFromEdge(Coframe.projectId, newPageUrl, signal, config.userContext, preview.previewVariantId || undefined);
2979
3128
  if (signal.aborted)
2980
3129
  return;
2981
3130
  if (result) {
@@ -3019,15 +3168,15 @@ function persistLaneClaims(claims, logger) {
3019
3168
  setCookie(LANE_COOKIE_KEY, encodeURIComponent(serialized), logger);
3020
3169
  }
3021
3170
  }
3022
- function createApplyVariants(Coframe, config, previewVariantId, executionStartTime, analytics, personalizationHeaders, laneStore) {
3171
+ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant, executionStartTime, analytics, personalizationHeaders, laneStore) {
3172
+ let isFirstApply = true;
3023
3173
  return async (pageUrl, pageProject) => {
3024
- const sessionId = generateUUID();
3174
+ const sessionId = isFirstApply ? Coframe.sessionId : generateUUID();
3175
+ isFirstApply = false;
3025
3176
  Coframe.sessionId = sessionId;
3026
- const urlPreviewVariantId = getCurrentUrlSearchParams().get('coframe_variant_id') || null;
3027
- const updatedPreviewVariantId = urlPreviewVariantId !== previewVariantId
3028
- ? urlPreviewVariantId
3029
- : previewVariantId;
3030
- const { variantsAndElements, experimentsInfo, hasActivatedFrames, laneClaims, } = await getVariantsAndElements(personalizationHeaders, pageProject, updatedPreviewVariantId, Coframe.userToken, pageUrl, getBrowserLanguages(), getBrowserPlatform(), Coframe.logger, config.nonce, laneStore.claims);
3177
+ const preview = resolvePreview(pageUrl, previewVariantId, isSessionVariant);
3178
+ setIsPreviewVariant(!!preview.previewVariantId);
3179
+ const { variantsAndElements, experimentsInfo, hasActivatedFrames, laneClaims, } = await getVariantsAndElements(personalizationHeaders, pageProject, preview.previewVariantId, Coframe.userToken, pageUrl, getBrowserLanguages(), getBrowserPlatform(), Coframe.logger, config.nonce, laneStore.claims, preview.isSessionVariant);
3031
3180
  laneStore.claims = laneClaims;
3032
3181
  persistLaneClaims(laneClaims, Coframe.logger);
3033
3182
  Coframe.experimentInfo = experimentsInfo;
@@ -3050,9 +3199,9 @@ function createApplyVariants(Coframe, config, previewVariantId, executionStartTi
3050
3199
  };
3051
3200
  }
3052
3201
  async function modifyPage(Coframe, configResult, projectResult, analytics) {
3053
- const { config, timeoutMs, previewVariantId, integrationStartTime, executionStartTime, } = configResult;
3202
+ const { config, timeoutMs, previewVariantId, isSessionVariant, integrationStartTime, executionStartTime, } = configResult;
3054
3203
  const { project: cdnProject, personalizationHeaders } = projectResult;
3055
- if (!(await awaitHydration(config, Coframe)))
3204
+ if (!(await awaitHydration(config, Coframe, cdnProject)))
3056
3205
  return;
3057
3206
  if (cdnProject.tags) {
3058
3207
  executeTags(cdnProject.tags, Coframe.logger, config.nonce);
@@ -3061,7 +3210,7 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3061
3210
  if (!(await ensureBody(Coframe, cdnProject, timeoutMs, config.nonce)))
3062
3211
  return;
3063
3212
  const laneStore = { claims: readLaneClaims() };
3064
- const applyVariants = createApplyVariants(Coframe, config, previewVariantId, executionStartTime, analytics, personalizationHeaders, laneStore);
3213
+ const applyVariants = createApplyVariants(Coframe, config, previewVariantId, isSessionVariant, executionStartTime, analytics, personalizationHeaders, laneStore);
3065
3214
  await applyVariants(getCurrentPageUrl(), cdnProject);
3066
3215
  if (!Coframe.variantsAndElements ||
3067
3216
  Coframe.variantsAndElements.length === 0) {
@@ -3069,96 +3218,10 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3069
3218
  variantRendered();
3070
3219
  }
3071
3220
  reportInitTiming(Coframe, cdnProject, integrationStartTime, executionStartTime);
3072
- setupSPANavigation(Coframe, cdnProject, config, applyVariants);
3221
+ setupSPANavigation(Coframe, cdnProject, config, previewVariantId, isSessionVariant, applyVariants);
3073
3222
  setupFlushInterval(Coframe.projectId);
3074
3223
  }
3075
3224
 
3076
- const TIMEOUT_MAX_MS = 5000;
3077
- function getFeatureFlagValue(cmd) {
3078
- if (cmd.featureFlagSet !== undefined)
3079
- return cmd.featureFlagSet;
3080
- if (typeof cmd.emit === 'object' &&
3081
- cmd.emit !== null &&
3082
- 'featureFlagSet' in cmd.emit) {
3083
- return cmd.emit.featureFlagSet;
3084
- }
3085
- return undefined;
3086
- }
3087
- async function resolveFeatureFlag(Coframe, timeoutMs) {
3088
- const cmd = await waitForCmd((cmd) => typeof getFeatureFlagValue(cmd) === 'boolean', Coframe, timeoutMs);
3089
- if (!cmd)
3090
- return undefined;
3091
- return getFeatureFlagValue(cmd);
3092
- }
3093
- async function resolveConfig(Coframe, revealPage) {
3094
- const logger = Coframe.logger;
3095
- const configCmd = await waitForCmd((cmd) => !!cmd.config, Coframe);
3096
- if (!configCmd) {
3097
- logger.error('Failed to wait for config cmd', 'wait_for_cmd_timeout');
3098
- return null;
3099
- }
3100
- const config = configCmd.config;
3101
- const timeoutMs = (config === null || config === void 0 ? void 0 : config.timeoutMs)
3102
- ? Math.min(config.timeoutMs, TIMEOUT_MAX_MS)
3103
- : TIMEOUT_MAX_MS;
3104
- const integrationStartTime = (config === null || config === void 0 ? void 0 : config.startTime)
3105
- ? new Date(config.startTime)
3106
- : null;
3107
- const executionStartTime = new Date();
3108
- Coframe.batchSize = config.batchSize || 32;
3109
- const gracefulExit = (msg) => {
3110
- console.warn(`[Coframe] ${msg}`);
3111
- revealPage();
3112
- return null;
3113
- };
3114
- if (config.waitForFeatureFlag) {
3115
- const flag = await resolveFeatureFlag(Coframe, timeoutMs);
3116
- if (flag === undefined) {
3117
- return gracefulExit('Feature flag was not set after timeout, graceful exit');
3118
- }
3119
- if (flag === false) {
3120
- return gracefulExit('Feature flag is set to false, graceful exit');
3121
- }
3122
- }
3123
- const projectId = config === null || config === void 0 ? void 0 : config.projectId;
3124
- const warnMissingVariant = () => {
3125
- if (applyVariantChangesStarted) {
3126
- logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
3127
- }
3128
- };
3129
- waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
3130
- .then((cmd) => {
3131
- if (!cmd) {
3132
- warnMissingVariant();
3133
- }
3134
- })
3135
- .finally(() => {
3136
- revealPage();
3137
- });
3138
- if (!projectId) {
3139
- logger.error('No project ID', 'no_project_id', {
3140
- description: 'No Coframe Page ID',
3141
- });
3142
- variantRendered();
3143
- return null;
3144
- }
3145
- Coframe.projectId = projectId;
3146
- const urlParams = getCurrentUrlSearchParams();
3147
- const previewVariantId = urlParams.get('coframe_variant_id');
3148
- const shouldSendEventsParam = urlParams.get('coframe_should_send_events');
3149
- setForceSendEvents(shouldSendEventsParam === 'true');
3150
- setIsPreviewVariant(!!previewVariantId);
3151
- setWaitingForCookies(!!config.waitForCookiesEnabled);
3152
- return {
3153
- config,
3154
- timeoutMs,
3155
- projectId,
3156
- previewVariantId,
3157
- integrationStartTime,
3158
- executionStartTime,
3159
- };
3160
- }
3161
-
3162
3225
  async function resolveIdentity(config, Coframe, timeoutMs, gracefulExit) {
3163
3226
  const logger = Coframe.logger;
3164
3227
  let userToken;
@@ -3215,14 +3278,14 @@ async function resolveIdentity(config, Coframe, timeoutMs, gracefulExit) {
3215
3278
  return { userToken, applyCookieConsent, onConsentChange };
3216
3279
  }
3217
3280
 
3218
- async function resolveProject(Coframe, previewVariantId, config) {
3281
+ async function resolveProject(Coframe, previewVariantId, isSessionVariant, config) {
3219
3282
  var _a;
3220
3283
  const logger = Coframe.logger;
3221
3284
  const projectData = (_a = findLastCmd((c) => !!c.projectData)) === null || _a === void 0 ? void 0 : _a.projectData;
3222
3285
  let personalizationHeaders = (projectData === null || projectData === void 0 ? void 0 : projectData.personalizationHeaders) || null;
3223
- let project = projectData === null || projectData === void 0 ? void 0 : projectData.project;
3286
+ let project = isSessionVariant ? undefined : projectData === null || projectData === void 0 ? void 0 : projectData.project;
3224
3287
  if (!project) {
3225
- const edgeResult = await fetchProjectFromEdge(Coframe.projectId, config.currentUrl || getCurrentPageUrl(), undefined, config.userContext);
3288
+ const edgeResult = await fetchProjectFromEdge(Coframe.projectId, config.currentUrl || getCurrentPageUrl(), undefined, config.userContext, previewVariantId || undefined);
3226
3289
  personalizationHeaders = (edgeResult === null || edgeResult === void 0 ? void 0 : edgeResult.personalizationHeaders) || null;
3227
3290
  project = (edgeResult === null || edgeResult === void 0 ? void 0 : edgeResult.project) || undefined;
3228
3291
  }
@@ -3314,7 +3377,7 @@ async function init(options) {
3314
3377
  const configResult = await resolveConfig(Coframe, revealPage);
3315
3378
  if (!configResult)
3316
3379
  return;
3317
- const projectResult = await resolveProject(Coframe, configResult.previewVariantId, configResult.config);
3380
+ const projectResult = await resolveProject(Coframe, configResult.previewVariantId, configResult.isSessionVariant, configResult.config);
3318
3381
  if (!projectResult)
3319
3382
  return;
3320
3383
  Coframe.orgId = projectResult.project.org_id || '';
@@ -1103,8 +1103,11 @@ function createSession(data) {
1103
1103
  console.warn('[Coframe] cannot send event beacon, feature unavailable');
1104
1104
  }
1105
1105
  }
1106
- async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, headers) {
1106
+ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, previewVariantId, headers) {
1107
1107
  const payload = { projectId, currentUrl };
1108
+ if (previewVariantId) {
1109
+ payload.previewVariantId = previewVariantId;
1110
+ }
1108
1111
  const safe = sanitizeUserContext(userContext);
1109
1112
  if (safe) {
1110
1113
  payload.userContext = safe;
@@ -1202,10 +1205,10 @@ const executeJs = (jsCode, args = {}, opts = {}) => {
1202
1205
  w.Coframe.vars[elKey] = opts.elementRef;
1203
1206
  }
1204
1207
  const invocation = opts.isExpression
1205
- ? `(${jsCode})(__args)`
1208
+ ? `(\n${jsCode}\n)(__args)`
1206
1209
  : opts.elementRef
1207
- ? `(function(el){ ${jsCode} })(__args.el)`
1208
- : `(function(){ ${jsCode} })()`;
1210
+ ? `(function(el){\n${jsCode}\n})(__args.el)`
1211
+ : `(function(){\n${jsCode}\n})()`;
1209
1212
  const ranKey = `${key}_ran`;
1210
1213
  const script = document.createElement('script');
1211
1214
  script.id = `coframe-script-${key}`;
@@ -1241,6 +1244,7 @@ const executeJs = (jsCode, args = {}, opts = {}) => {
1241
1244
  return value;
1242
1245
  };
1243
1246
  const applyJavascriptModification = (element, args, logger, nonce, logMetadata = {}) => {
1247
+ var _a, _b;
1244
1248
  const javascript = args.js;
1245
1249
  try {
1246
1250
  if (!javascript) {
@@ -1262,9 +1266,11 @@ const applyJavascriptModification = (element, args, logger, nonce, logMetadata =
1262
1266
  if (logger === null || logger === void 0 ? void 0 : logger.error) {
1263
1267
  logger.error('Error executing JavaScript:', 'error_execute_js', {
1264
1268
  ...logMetadata,
1265
- error,
1269
+ error: error instanceof Error
1270
+ ? error.stack || error.message
1271
+ : String(error),
1266
1272
  javascript,
1267
- element,
1273
+ element: (_b = (_a = element.outerHTML) === null || _a === void 0 ? void 0 : _a.slice(0, 200)) !== null && _b !== void 0 ? _b : element.tagName,
1268
1274
  });
1269
1275
  }
1270
1276
  else {
@@ -2291,7 +2297,7 @@ function checkAllAudiences(metadata, project, personalizationHeaders, currentPag
2291
2297
  }
2292
2298
  return result;
2293
2299
  }
2294
- async function getVariantsAndElements(personalizationHeaders, project, previewVariantId, userToken, currentPageUrl, languages, browserPlatform, logger, nonce, laneClaims = {}) {
2300
+ async function getVariantsAndElements(personalizationHeaders, project, previewVariantId, userToken, currentPageUrl, languages, browserPlatform, logger, nonce, laneClaims = {}, silentFallback = false) {
2295
2301
  var _a, _b;
2296
2302
  const experimentsInfo = [];
2297
2303
  const variantsAndElements = [];
@@ -2320,10 +2326,13 @@ async function getVariantsAndElements(personalizationHeaders, project, previewVa
2320
2326
  hasActivatedFrames: true,
2321
2327
  });
2322
2328
  }
2323
- if (!skipAlert) {
2329
+ if (!skipAlert && !silentFallback) {
2324
2330
  window.alert(`[Coframe] Variant preview unavailable: ${previewVariantId}.`);
2325
2331
  }
2326
- return buildResponse({});
2332
+ if (silentFallback) ;
2333
+ else {
2334
+ return buildResponse({});
2335
+ }
2327
2336
  }
2328
2337
  const userVisitCount = Number.parseInt(getCookie(VISIT_COUNT_COOKIE_KEY) || '0', 10);
2329
2338
  const validatedClaims = validateClaims(laneClaims, project.lanes);
@@ -2594,6 +2603,125 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
2594
2603
  patchHistoryMethod('replaceState');
2595
2604
  }
2596
2605
 
2606
+ const TIMEOUT_MAX_MS = 5000;
2607
+ function getFeatureFlagValue(cmd) {
2608
+ if (cmd.featureFlagSet !== undefined)
2609
+ return cmd.featureFlagSet;
2610
+ if (typeof cmd.emit === 'object' &&
2611
+ cmd.emit !== null &&
2612
+ 'featureFlagSet' in cmd.emit) {
2613
+ return cmd.emit.featureFlagSet;
2614
+ }
2615
+ return undefined;
2616
+ }
2617
+ async function resolveFeatureFlag(Coframe, timeoutMs) {
2618
+ const cmd = await waitForCmd((cmd) => typeof getFeatureFlagValue(cmd) === 'boolean', Coframe, timeoutMs);
2619
+ if (!cmd)
2620
+ return undefined;
2621
+ return getFeatureFlagValue(cmd);
2622
+ }
2623
+ async function resolveConfig(Coframe, revealPage) {
2624
+ const logger = Coframe.logger;
2625
+ const configCmd = await waitForCmd((cmd) => !!cmd.config, Coframe);
2626
+ if (!configCmd) {
2627
+ logger.error('Failed to wait for config cmd', 'wait_for_cmd_timeout');
2628
+ return null;
2629
+ }
2630
+ const config = configCmd.config;
2631
+ const timeoutMs = (config === null || config === void 0 ? void 0 : config.timeoutMs)
2632
+ ? Math.min(config.timeoutMs, TIMEOUT_MAX_MS)
2633
+ : TIMEOUT_MAX_MS;
2634
+ const integrationStartTime = (config === null || config === void 0 ? void 0 : config.startTime)
2635
+ ? new Date(config.startTime)
2636
+ : null;
2637
+ const executionStartTime = new Date();
2638
+ Coframe.batchSize = config.batchSize || 32;
2639
+ const gracefulExit = (msg) => {
2640
+ console.warn(`[Coframe] ${msg}`);
2641
+ revealPage();
2642
+ return null;
2643
+ };
2644
+ if (config.waitForFeatureFlag) {
2645
+ const flag = await resolveFeatureFlag(Coframe, timeoutMs);
2646
+ if (flag === undefined) {
2647
+ return gracefulExit('Feature flag was not set after timeout, graceful exit');
2648
+ }
2649
+ if (flag === false) {
2650
+ return gracefulExit('Feature flag is set to false, graceful exit');
2651
+ }
2652
+ }
2653
+ const projectId = config === null || config === void 0 ? void 0 : config.projectId;
2654
+ const warnMissingVariant = () => {
2655
+ if (applyVariantChangesStarted) {
2656
+ logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
2657
+ }
2658
+ };
2659
+ waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
2660
+ .then((cmd) => {
2661
+ if (!cmd) {
2662
+ warnMissingVariant();
2663
+ }
2664
+ })
2665
+ .finally(() => {
2666
+ revealPage();
2667
+ });
2668
+ if (!projectId) {
2669
+ logger.error('No project ID', 'no_project_id', {
2670
+ description: 'No Coframe Page ID',
2671
+ });
2672
+ variantRendered();
2673
+ return null;
2674
+ }
2675
+ Coframe.projectId = projectId;
2676
+ const urlParams = getCurrentUrlSearchParams();
2677
+ const urlVariantId = urlParams.get('coframe_variant_id');
2678
+ const shouldSendEventsParam = urlParams.get('coframe_should_send_events');
2679
+ const keepForSession = urlParams.get('keep_preview_for_session') === 'true';
2680
+ let previewVariantId = null;
2681
+ let isSessionVariant = false;
2682
+ if (urlVariantId) {
2683
+ previewVariantId = urlVariantId;
2684
+ if (keepForSession) {
2685
+ persistPreviewVariantId(urlVariantId);
2686
+ }
2687
+ }
2688
+ else {
2689
+ const stored = readPreviewVariantId();
2690
+ if (stored) {
2691
+ previewVariantId = stored;
2692
+ isSessionVariant = true;
2693
+ }
2694
+ }
2695
+ setForceSendEvents(shouldSendEventsParam === 'true');
2696
+ setIsPreviewVariant(!!previewVariantId);
2697
+ setWaitingForCookies(!!config.waitForCookiesEnabled);
2698
+ return {
2699
+ config,
2700
+ timeoutMs,
2701
+ projectId,
2702
+ previewVariantId,
2703
+ isSessionVariant,
2704
+ integrationStartTime,
2705
+ executionStartTime,
2706
+ };
2707
+ }
2708
+ const SESSION_VARIANT_KEY = 'coframe.preview_variant';
2709
+ function readPreviewVariantId() {
2710
+ try {
2711
+ return sessionStorage.getItem(SESSION_VARIANT_KEY);
2712
+ }
2713
+ catch (_a) {
2714
+ return null;
2715
+ }
2716
+ }
2717
+ function persistPreviewVariantId(variantId) {
2718
+ try {
2719
+ sessionStorage.setItem(SESSION_VARIANT_KEY, variantId);
2720
+ }
2721
+ catch (_a) {
2722
+ }
2723
+ }
2724
+
2597
2725
  function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders) {
2598
2726
  const sessionPayload = [
2599
2727
  Coframe,
@@ -2905,9 +3033,29 @@ function setupTracking(Coframe, projectResult, previewVariantId, executionStartT
2905
3033
  return analytics;
2906
3034
  }
2907
3035
 
2908
- async function awaitHydration(config, Coframe) {
3036
+ function resolvePreview(pageUrl, previewVariantId, isSessionVariant) {
3037
+ let urlPreviewVariantId = null;
3038
+ try {
3039
+ urlPreviewVariantId = new URL(pageUrl).searchParams.get('coframe_variant_id');
3040
+ }
3041
+ catch (_a) {
3042
+ urlPreviewVariantId = getCurrentUrlSearchParams().get('coframe_variant_id');
3043
+ }
3044
+ if (urlPreviewVariantId) {
3045
+ return { previewVariantId: urlPreviewVariantId, isSessionVariant: false };
3046
+ }
3047
+ if (previewVariantId) {
3048
+ return { previewVariantId, isSessionVariant };
3049
+ }
3050
+ const stored = readPreviewVariantId();
3051
+ return { previewVariantId: stored, isSessionVariant: !!stored };
3052
+ }
3053
+ async function awaitHydration(config, Coframe, project) {
3054
+ var _a, _b;
2909
3055
  if (!config.waitForHydration)
2910
3056
  return true;
3057
+ if (!((_a = project.frames) === null || _a === void 0 ? void 0 : _a.length) && !((_b = project.tags) === null || _b === void 0 ? void 0 : _b.length))
3058
+ return true;
2911
3059
  const cmd = await waitForCmd((cmd) => cmd.pageHydrated === true || cmd.emit === 'pageHydrated', Coframe);
2912
3060
  if (!cmd) {
2913
3061
  Coframe.logger.warn('Failed to wait for page hydrated command', 'wait_for_cmd_timeout');
@@ -2934,7 +3082,7 @@ function setupFlushInterval(projectId) {
2934
3082
  }
2935
3083
  flushInterval = setInterval(() => flushQueuedEvents(projectId), FLUSH_EVENTS_TIME);
2936
3084
  }
2937
- function setupSPANavigation(Coframe, project, config, applyVariants) {
3085
+ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessionVariant, applyVariants) {
2938
3086
  var _a;
2939
3087
  if (!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.mutation_observer_active))
2940
3088
  return;
@@ -2973,7 +3121,8 @@ function setupSPANavigation(Coframe, project, config, applyVariants) {
2973
3121
  }
2974
3122
  else {
2975
3123
  try {
2976
- const result = await fetchProjectFromEdge(Coframe.projectId, newPageUrl, signal, config.userContext);
3124
+ const preview = resolvePreview(newPageUrl, previewVariantId, isSessionVariant);
3125
+ const result = await fetchProjectFromEdge(Coframe.projectId, newPageUrl, signal, config.userContext, preview.previewVariantId || undefined);
2977
3126
  if (signal.aborted)
2978
3127
  return;
2979
3128
  if (result) {
@@ -3017,15 +3166,15 @@ function persistLaneClaims(claims, logger) {
3017
3166
  setCookie(LANE_COOKIE_KEY, encodeURIComponent(serialized), logger);
3018
3167
  }
3019
3168
  }
3020
- function createApplyVariants(Coframe, config, previewVariantId, executionStartTime, analytics, personalizationHeaders, laneStore) {
3169
+ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant, executionStartTime, analytics, personalizationHeaders, laneStore) {
3170
+ let isFirstApply = true;
3021
3171
  return async (pageUrl, pageProject) => {
3022
- const sessionId = generateUUID();
3172
+ const sessionId = isFirstApply ? Coframe.sessionId : generateUUID();
3173
+ isFirstApply = false;
3023
3174
  Coframe.sessionId = sessionId;
3024
- const urlPreviewVariantId = getCurrentUrlSearchParams().get('coframe_variant_id') || null;
3025
- const updatedPreviewVariantId = urlPreviewVariantId !== previewVariantId
3026
- ? urlPreviewVariantId
3027
- : previewVariantId;
3028
- const { variantsAndElements, experimentsInfo, hasActivatedFrames, laneClaims, } = await getVariantsAndElements(personalizationHeaders, pageProject, updatedPreviewVariantId, Coframe.userToken, pageUrl, getBrowserLanguages(), getBrowserPlatform(), Coframe.logger, config.nonce, laneStore.claims);
3175
+ const preview = resolvePreview(pageUrl, previewVariantId, isSessionVariant);
3176
+ setIsPreviewVariant(!!preview.previewVariantId);
3177
+ const { variantsAndElements, experimentsInfo, hasActivatedFrames, laneClaims, } = await getVariantsAndElements(personalizationHeaders, pageProject, preview.previewVariantId, Coframe.userToken, pageUrl, getBrowserLanguages(), getBrowserPlatform(), Coframe.logger, config.nonce, laneStore.claims, preview.isSessionVariant);
3029
3178
  laneStore.claims = laneClaims;
3030
3179
  persistLaneClaims(laneClaims, Coframe.logger);
3031
3180
  Coframe.experimentInfo = experimentsInfo;
@@ -3048,9 +3197,9 @@ function createApplyVariants(Coframe, config, previewVariantId, executionStartTi
3048
3197
  };
3049
3198
  }
3050
3199
  async function modifyPage(Coframe, configResult, projectResult, analytics) {
3051
- const { config, timeoutMs, previewVariantId, integrationStartTime, executionStartTime, } = configResult;
3200
+ const { config, timeoutMs, previewVariantId, isSessionVariant, integrationStartTime, executionStartTime, } = configResult;
3052
3201
  const { project: cdnProject, personalizationHeaders } = projectResult;
3053
- if (!(await awaitHydration(config, Coframe)))
3202
+ if (!(await awaitHydration(config, Coframe, cdnProject)))
3054
3203
  return;
3055
3204
  if (cdnProject.tags) {
3056
3205
  executeTags(cdnProject.tags, Coframe.logger, config.nonce);
@@ -3059,7 +3208,7 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3059
3208
  if (!(await ensureBody(Coframe, cdnProject, timeoutMs, config.nonce)))
3060
3209
  return;
3061
3210
  const laneStore = { claims: readLaneClaims() };
3062
- const applyVariants = createApplyVariants(Coframe, config, previewVariantId, executionStartTime, analytics, personalizationHeaders, laneStore);
3211
+ const applyVariants = createApplyVariants(Coframe, config, previewVariantId, isSessionVariant, executionStartTime, analytics, personalizationHeaders, laneStore);
3063
3212
  await applyVariants(getCurrentPageUrl(), cdnProject);
3064
3213
  if (!Coframe.variantsAndElements ||
3065
3214
  Coframe.variantsAndElements.length === 0) {
@@ -3067,96 +3216,10 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3067
3216
  variantRendered();
3068
3217
  }
3069
3218
  reportInitTiming(Coframe, cdnProject, integrationStartTime, executionStartTime);
3070
- setupSPANavigation(Coframe, cdnProject, config, applyVariants);
3219
+ setupSPANavigation(Coframe, cdnProject, config, previewVariantId, isSessionVariant, applyVariants);
3071
3220
  setupFlushInterval(Coframe.projectId);
3072
3221
  }
3073
3222
 
3074
- const TIMEOUT_MAX_MS = 5000;
3075
- function getFeatureFlagValue(cmd) {
3076
- if (cmd.featureFlagSet !== undefined)
3077
- return cmd.featureFlagSet;
3078
- if (typeof cmd.emit === 'object' &&
3079
- cmd.emit !== null &&
3080
- 'featureFlagSet' in cmd.emit) {
3081
- return cmd.emit.featureFlagSet;
3082
- }
3083
- return undefined;
3084
- }
3085
- async function resolveFeatureFlag(Coframe, timeoutMs) {
3086
- const cmd = await waitForCmd((cmd) => typeof getFeatureFlagValue(cmd) === 'boolean', Coframe, timeoutMs);
3087
- if (!cmd)
3088
- return undefined;
3089
- return getFeatureFlagValue(cmd);
3090
- }
3091
- async function resolveConfig(Coframe, revealPage) {
3092
- const logger = Coframe.logger;
3093
- const configCmd = await waitForCmd((cmd) => !!cmd.config, Coframe);
3094
- if (!configCmd) {
3095
- logger.error('Failed to wait for config cmd', 'wait_for_cmd_timeout');
3096
- return null;
3097
- }
3098
- const config = configCmd.config;
3099
- const timeoutMs = (config === null || config === void 0 ? void 0 : config.timeoutMs)
3100
- ? Math.min(config.timeoutMs, TIMEOUT_MAX_MS)
3101
- : TIMEOUT_MAX_MS;
3102
- const integrationStartTime = (config === null || config === void 0 ? void 0 : config.startTime)
3103
- ? new Date(config.startTime)
3104
- : null;
3105
- const executionStartTime = new Date();
3106
- Coframe.batchSize = config.batchSize || 32;
3107
- const gracefulExit = (msg) => {
3108
- console.warn(`[Coframe] ${msg}`);
3109
- revealPage();
3110
- return null;
3111
- };
3112
- if (config.waitForFeatureFlag) {
3113
- const flag = await resolveFeatureFlag(Coframe, timeoutMs);
3114
- if (flag === undefined) {
3115
- return gracefulExit('Feature flag was not set after timeout, graceful exit');
3116
- }
3117
- if (flag === false) {
3118
- return gracefulExit('Feature flag is set to false, graceful exit');
3119
- }
3120
- }
3121
- const projectId = config === null || config === void 0 ? void 0 : config.projectId;
3122
- const warnMissingVariant = () => {
3123
- if (applyVariantChangesStarted) {
3124
- logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
3125
- }
3126
- };
3127
- waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
3128
- .then((cmd) => {
3129
- if (!cmd) {
3130
- warnMissingVariant();
3131
- }
3132
- })
3133
- .finally(() => {
3134
- revealPage();
3135
- });
3136
- if (!projectId) {
3137
- logger.error('No project ID', 'no_project_id', {
3138
- description: 'No Coframe Page ID',
3139
- });
3140
- variantRendered();
3141
- return null;
3142
- }
3143
- Coframe.projectId = projectId;
3144
- const urlParams = getCurrentUrlSearchParams();
3145
- const previewVariantId = urlParams.get('coframe_variant_id');
3146
- const shouldSendEventsParam = urlParams.get('coframe_should_send_events');
3147
- setForceSendEvents(shouldSendEventsParam === 'true');
3148
- setIsPreviewVariant(!!previewVariantId);
3149
- setWaitingForCookies(!!config.waitForCookiesEnabled);
3150
- return {
3151
- config,
3152
- timeoutMs,
3153
- projectId,
3154
- previewVariantId,
3155
- integrationStartTime,
3156
- executionStartTime,
3157
- };
3158
- }
3159
-
3160
3223
  async function resolveIdentity(config, Coframe, timeoutMs, gracefulExit) {
3161
3224
  const logger = Coframe.logger;
3162
3225
  let userToken;
@@ -3213,14 +3276,14 @@ async function resolveIdentity(config, Coframe, timeoutMs, gracefulExit) {
3213
3276
  return { userToken, applyCookieConsent, onConsentChange };
3214
3277
  }
3215
3278
 
3216
- async function resolveProject(Coframe, previewVariantId, config) {
3279
+ async function resolveProject(Coframe, previewVariantId, isSessionVariant, config) {
3217
3280
  var _a;
3218
3281
  const logger = Coframe.logger;
3219
3282
  const projectData = (_a = findLastCmd((c) => !!c.projectData)) === null || _a === void 0 ? void 0 : _a.projectData;
3220
3283
  let personalizationHeaders = (projectData === null || projectData === void 0 ? void 0 : projectData.personalizationHeaders) || null;
3221
- let project = projectData === null || projectData === void 0 ? void 0 : projectData.project;
3284
+ let project = isSessionVariant ? undefined : projectData === null || projectData === void 0 ? void 0 : projectData.project;
3222
3285
  if (!project) {
3223
- const edgeResult = await fetchProjectFromEdge(Coframe.projectId, config.currentUrl || getCurrentPageUrl(), undefined, config.userContext);
3286
+ const edgeResult = await fetchProjectFromEdge(Coframe.projectId, config.currentUrl || getCurrentPageUrl(), undefined, config.userContext, previewVariantId || undefined);
3224
3287
  personalizationHeaders = (edgeResult === null || edgeResult === void 0 ? void 0 : edgeResult.personalizationHeaders) || null;
3225
3288
  project = (edgeResult === null || edgeResult === void 0 ? void 0 : edgeResult.project) || undefined;
3226
3289
  }
@@ -3312,7 +3375,7 @@ async function init(options) {
3312
3375
  const configResult = await resolveConfig(Coframe, revealPage);
3313
3376
  if (!configResult)
3314
3377
  return;
3315
- const projectResult = await resolveProject(Coframe, configResult.previewVariantId, configResult.config);
3378
+ const projectResult = await resolveProject(Coframe, configResult.previewVariantId, configResult.isSessionVariant, configResult.config);
3316
3379
  if (!projectResult)
3317
3380
  return;
3318
3381
  Coframe.orgId = projectResult.project.org_id || '';
@@ -22,7 +22,7 @@ function sanitizeUserContext(userContext) {
22
22
  return userContext;
23
23
  }
24
24
 
25
- async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, headers) {
25
+ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, previewVariantId, headers) {
26
26
  const payload = { projectId, currentUrl };
27
27
  const safe = sanitizeUserContext(userContext);
28
28
  if (safe) {
@@ -73,7 +73,7 @@ async function getProjectData(options) {
73
73
  const includeCSS = options.includeCSS !== false;
74
74
  const [projectResult, antiflickerCSS] = await Promise.all([
75
75
  includeProject
76
- ? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, options.headers)
76
+ ? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, undefined, options.headers)
77
77
  : Promise.resolve(null),
78
78
  includeCSS
79
79
  ? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.enableElementAntiFlicker, options.headers)
@@ -20,7 +20,7 @@ function sanitizeUserContext(userContext) {
20
20
  return userContext;
21
21
  }
22
22
 
23
- async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, headers) {
23
+ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext, previewVariantId, headers) {
24
24
  const payload = { projectId, currentUrl };
25
25
  const safe = sanitizeUserContext(userContext);
26
26
  if (safe) {
@@ -71,7 +71,7 @@ async function getProjectData(options) {
71
71
  const includeCSS = options.includeCSS !== false;
72
72
  const [projectResult, antiflickerCSS] = await Promise.all([
73
73
  includeProject
74
- ? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, options.headers)
74
+ ? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, undefined, options.headers)
75
75
  : Promise.resolve(null),
76
76
  includeCSS
77
77
  ? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.enableElementAntiFlicker, options.headers)
@@ -232,6 +232,7 @@ type ActivationCondition = {
232
232
  };
233
233
  type CoframeConfig = {
234
234
  projectId: string;
235
+ previewVariantId?: string;
235
236
  trackingOnly?: boolean;
236
237
  enableAntiFlickering?: boolean;
237
238
  enableElementAntiFlicker?: boolean;
@@ -235,6 +235,7 @@ type ActivationCondition = {
235
235
  };
236
236
  type CoframeConfig = {
237
237
  projectId: string;
238
+ previewVariantId?: string;
238
239
  trackingOnly?: boolean;
239
240
  enableAntiFlickering?: boolean;
240
241
  enableElementAntiFlicker?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coframe/sdk",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
5
5
  "main": "dist/pkg/cf.cjs.js",
6
6
  "module": "dist/pkg/cf.esm.mjs",