@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.
- package/dist/pkg/cf.cjs.js +176 -113
- package/dist/pkg/cf.esm.mjs +176 -113
- package/dist/pkg/server.cjs.js +2 -2
- package/dist/pkg/server.esm.mjs +2 -2
- package/dist/pkg/types/index.d.ts +1 -0
- package/dist/pkg/types/react.d.ts +1 -0
- package/package.json +1 -1
package/dist/pkg/cf.cjs.js
CHANGED
|
@@ -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){
|
|
1210
|
-
: `(function(){
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
3027
|
-
|
|
3028
|
-
|
|
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 || '';
|
package/dist/pkg/cf.esm.mjs
CHANGED
|
@@ -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){
|
|
1208
|
-
: `(function(){
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
3025
|
-
|
|
3026
|
-
|
|
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 || '';
|
package/dist/pkg/server.cjs.js
CHANGED
|
@@ -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)
|
package/dist/pkg/server.esm.mjs
CHANGED
|
@@ -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)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coframe/sdk",
|
|
3
|
-
"version": "1.1.
|
|
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",
|