@coframe/sdk 1.1.9 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/pkg/cf.cjs.js +209 -272
- package/dist/pkg/cf.esm.mjs +209 -272
- package/dist/pkg/react.cjs.js +9 -1
- package/dist/pkg/react.esm.mjs +10 -2
- package/dist/pkg/server.cjs.js +11 -4
- package/dist/pkg/server.esm.mjs +11 -4
- package/dist/pkg/types/index.d.ts +4 -1
- package/dist/pkg/types/react.d.ts +5 -2
- package/dist/pkg/types/server.d.ts +2 -1
- package/package.json +4 -3
package/dist/pkg/cf.esm.mjs
CHANGED
|
@@ -857,6 +857,88 @@ const isSegmentEmpty = (segment) => {
|
|
|
857
857
|
return segment.xpath === '';
|
|
858
858
|
};
|
|
859
859
|
|
|
860
|
+
function parseQueryString(query) {
|
|
861
|
+
const params = {};
|
|
862
|
+
const cleanQuery = query.startsWith('?') ? query.slice(1) : query;
|
|
863
|
+
if (!cleanQuery)
|
|
864
|
+
return params;
|
|
865
|
+
for (const pair of cleanQuery.split('&')) {
|
|
866
|
+
if (!pair)
|
|
867
|
+
continue;
|
|
868
|
+
const [key, value = ''] = pair.split('=').map(decodeURIComponent);
|
|
869
|
+
if (!(key in params)) {
|
|
870
|
+
params[key] = value;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return params;
|
|
874
|
+
}
|
|
875
|
+
function createURLSearchParams(query) {
|
|
876
|
+
if (typeof URLSearchParams !== 'undefined') {
|
|
877
|
+
const nativeParams = new URLSearchParams(query);
|
|
878
|
+
return {
|
|
879
|
+
get: (key) => nativeParams.get(key),
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
const simpleParams = parseQueryString(query);
|
|
883
|
+
return {
|
|
884
|
+
get: (key) => { var _a; return (_a = simpleParams[key]) !== null && _a !== void 0 ? _a : null; },
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
function getUrlSearchParams(url) {
|
|
888
|
+
const searchIndex = url.indexOf('?');
|
|
889
|
+
const firstHashIndex = url.indexOf('#');
|
|
890
|
+
if (searchIndex === -1 ||
|
|
891
|
+
(firstHashIndex !== -1 && firstHashIndex < searchIndex)) {
|
|
892
|
+
return createURLSearchParams('');
|
|
893
|
+
}
|
|
894
|
+
const hashIndex = url.indexOf('#', searchIndex);
|
|
895
|
+
const search = hashIndex !== -1
|
|
896
|
+
? url.substring(searchIndex, hashIndex)
|
|
897
|
+
: url.substring(searchIndex);
|
|
898
|
+
return createURLSearchParams(search);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
const COFRAME_DEBUG_QUERY_PARAM = 'cf_debug';
|
|
902
|
+
const COFRAME_TOOL_INTERACTION_ATTRIBUTE = 'data-cf-t';
|
|
903
|
+
const COFRAME_DEBUG_TOOLS_SESSION_STORAGE_KEY = 'cf.tools.enabled';
|
|
904
|
+
const COFRAME_DEBUG_TOOLS_STATE_STORAGE_KEY = 'cf.tools.session';
|
|
905
|
+
const ENABLED_VALUE = 'true';
|
|
906
|
+
function enableDebugToolsSession() {
|
|
907
|
+
try {
|
|
908
|
+
window.sessionStorage.setItem(COFRAME_DEBUG_TOOLS_SESSION_STORAGE_KEY, ENABLED_VALUE);
|
|
909
|
+
}
|
|
910
|
+
catch (_a) {
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
function clearDebugToolsSession() {
|
|
914
|
+
try {
|
|
915
|
+
window.sessionStorage.removeItem(COFRAME_DEBUG_TOOLS_SESSION_STORAGE_KEY);
|
|
916
|
+
window.sessionStorage.removeItem(COFRAME_DEBUG_TOOLS_STATE_STORAGE_KEY);
|
|
917
|
+
}
|
|
918
|
+
catch (_a) {
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
function isDebugToolsSessionEnabled(allowed) {
|
|
922
|
+
if (!allowed) {
|
|
923
|
+
clearDebugToolsSession();
|
|
924
|
+
return false;
|
|
925
|
+
}
|
|
926
|
+
const enabledByUrl = getUrlSearchParams(getCurrentPageUrl()).get(COFRAME_DEBUG_QUERY_PARAM) ===
|
|
927
|
+
ENABLED_VALUE;
|
|
928
|
+
if (enabledByUrl) {
|
|
929
|
+
enableDebugToolsSession();
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
try {
|
|
933
|
+
const enabled = window.sessionStorage.getItem(COFRAME_DEBUG_TOOLS_SESSION_STORAGE_KEY) ===
|
|
934
|
+
ENABLED_VALUE;
|
|
935
|
+
return enabled;
|
|
936
|
+
}
|
|
937
|
+
catch (_a) {
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
860
942
|
const USER_CONTEXT_KEY_PREFIX = 'x-ctx-';
|
|
861
943
|
const MAX_USER_CONTEXT_JSON_BYTES = 4096;
|
|
862
944
|
function userContextJsonByteLength(userContext) {
|
|
@@ -1035,6 +1117,12 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
|
|
|
1035
1117
|
}
|
|
1036
1118
|
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
|
|
1037
1119
|
var _a;
|
|
1120
|
+
if (event
|
|
1121
|
+
.composedPath()
|
|
1122
|
+
.some((target) => target instanceof Element &&
|
|
1123
|
+
target.hasAttribute(COFRAME_TOOL_INTERACTION_ATTRIBUTE))) {
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1038
1126
|
const startTime = performance.now();
|
|
1039
1127
|
const x = event.clientX + window.scrollX;
|
|
1040
1128
|
const y = event.clientY + window.scrollY;
|
|
@@ -1821,6 +1909,7 @@ const waitForBody = (timeout = 10000) => {
|
|
|
1821
1909
|
function revealPage() {
|
|
1822
1910
|
document.dispatchEvent(new CustomEvent('coframe:show', {}));
|
|
1823
1911
|
document.documentElement.style.setProperty('--cf-show', '1');
|
|
1912
|
+
document.documentElement.style.setProperty('--cf-visibility', 'visible');
|
|
1824
1913
|
}
|
|
1825
1914
|
async function replaceVariants(variants, orgId, logger, nonce) {
|
|
1826
1915
|
const failedReplacements = [];
|
|
@@ -2213,44 +2302,8 @@ function debounce(func, wait) {
|
|
|
2213
2302
|
}, wait);
|
|
2214
2303
|
};
|
|
2215
2304
|
}
|
|
2216
|
-
function parseQueryString(query) {
|
|
2217
|
-
const params = {};
|
|
2218
|
-
const cleanQuery = query.startsWith('?') ? query.slice(1) : query;
|
|
2219
|
-
if (!cleanQuery)
|
|
2220
|
-
return params;
|
|
2221
|
-
for (const pair of cleanQuery.split('&')) {
|
|
2222
|
-
if (!pair)
|
|
2223
|
-
continue;
|
|
2224
|
-
const [key, value = ''] = pair.split('=').map(decodeURIComponent);
|
|
2225
|
-
if (!(key in params)) {
|
|
2226
|
-
params[key] = value;
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
return params;
|
|
2230
|
-
}
|
|
2231
|
-
function createURLSearchParams(query) {
|
|
2232
|
-
if (typeof URLSearchParams !== 'undefined') {
|
|
2233
|
-
const nativeParams = new URLSearchParams(query);
|
|
2234
|
-
return {
|
|
2235
|
-
get: (key) => nativeParams.get(key),
|
|
2236
|
-
};
|
|
2237
|
-
}
|
|
2238
|
-
const simpleParams = parseQueryString(query);
|
|
2239
|
-
return {
|
|
2240
|
-
get: (key) => { var _a; return (_a = simpleParams[key]) !== null && _a !== void 0 ? _a : null; },
|
|
2241
|
-
};
|
|
2242
|
-
}
|
|
2243
2305
|
function getCurrentUrlSearchParams() {
|
|
2244
|
-
|
|
2245
|
-
const searchIndex = url.indexOf('?');
|
|
2246
|
-
if (searchIndex === -1) {
|
|
2247
|
-
return createURLSearchParams('');
|
|
2248
|
-
}
|
|
2249
|
-
const hashIndex = url.indexOf('#', searchIndex);
|
|
2250
|
-
const search = hashIndex !== -1
|
|
2251
|
-
? url.substring(searchIndex, hashIndex)
|
|
2252
|
-
: url.substring(searchIndex);
|
|
2253
|
-
return createURLSearchParams(search);
|
|
2306
|
+
return getUrlSearchParams(getCurrentPageUrl());
|
|
2254
2307
|
}
|
|
2255
2308
|
|
|
2256
2309
|
const defaultScale = 100000;
|
|
@@ -2485,6 +2538,44 @@ async function getVariantsAndElements(personalizationHeaders, project, previewVa
|
|
|
2485
2538
|
});
|
|
2486
2539
|
}
|
|
2487
2540
|
|
|
2541
|
+
const COFRAME_PREVIEW_SESSION_STORAGE_KEY = 'coframe.preview_variant';
|
|
2542
|
+
const COFRAME_PREVIEW_VARIANT_QUERY_PARAM = 'coframe_variant_id';
|
|
2543
|
+
function normalizePreviewVariantId(raw) {
|
|
2544
|
+
if (!raw)
|
|
2545
|
+
return null;
|
|
2546
|
+
const ids = raw
|
|
2547
|
+
.split(',')
|
|
2548
|
+
.map((id) => id.trim())
|
|
2549
|
+
.filter(Boolean);
|
|
2550
|
+
return ids.length > 0 ? ids.join(',') : null;
|
|
2551
|
+
}
|
|
2552
|
+
function readPreviewVariantIdFromUrl(url = window.location.href) {
|
|
2553
|
+
try {
|
|
2554
|
+
return normalizePreviewVariantId(getUrlSearchParams(url).get(COFRAME_PREVIEW_VARIANT_QUERY_PARAM));
|
|
2555
|
+
}
|
|
2556
|
+
catch (_a) {
|
|
2557
|
+
return null;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
function readStoredPreviewVariantId() {
|
|
2561
|
+
try {
|
|
2562
|
+
return normalizePreviewVariantId(window.sessionStorage.getItem(COFRAME_PREVIEW_SESSION_STORAGE_KEY));
|
|
2563
|
+
}
|
|
2564
|
+
catch (_a) {
|
|
2565
|
+
return null;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
function resolvePreviewSource(url = window.location.href) {
|
|
2569
|
+
const urlVariantId = readPreviewVariantIdFromUrl(url);
|
|
2570
|
+
const storedVariantId = readStoredPreviewVariantId();
|
|
2571
|
+
return {
|
|
2572
|
+
effectiveVariantId: urlVariantId || storedVariantId,
|
|
2573
|
+
isKeptForSession: Boolean(storedVariantId && storedVariantId === (urlVariantId || storedVariantId)),
|
|
2574
|
+
storedVariantId,
|
|
2575
|
+
urlVariantId,
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2488
2579
|
function buildSessionContext(isInitialApply) {
|
|
2489
2580
|
const context = {};
|
|
2490
2581
|
const viewport = getScreenSize();
|
|
@@ -2638,220 +2729,6 @@ function rebindMetrics(coframe, logger, metrics, nonce) {
|
|
|
2638
2729
|
}
|
|
2639
2730
|
}
|
|
2640
2731
|
|
|
2641
|
-
function getActivePreviewModes(sessionPreview) {
|
|
2642
|
-
if (!sessionPreview.isSessionPreviewActive ||
|
|
2643
|
-
!sessionPreview.previewVariantId) {
|
|
2644
|
-
return [];
|
|
2645
|
-
}
|
|
2646
|
-
return [
|
|
2647
|
-
{
|
|
2648
|
-
id: 'session-preview',
|
|
2649
|
-
label: 'Preview on',
|
|
2650
|
-
title: `Session preview is active for ${sessionPreview.previewVariantId}`,
|
|
2651
|
-
variantIds: sessionPreview.previewVariantId
|
|
2652
|
-
.split(',')
|
|
2653
|
-
.map((id) => id.trim())
|
|
2654
|
-
.filter(Boolean),
|
|
2655
|
-
},
|
|
2656
|
-
];
|
|
2657
|
-
}
|
|
2658
|
-
|
|
2659
|
-
const PREVIEW_UI_PROTOCOL_VERSION = 1;
|
|
2660
|
-
|
|
2661
|
-
const SESSION_VARIANT_KEY = 'coframe.preview_variant';
|
|
2662
|
-
const PREVIEW_VARIANT_QUERY_PARAM = 'coframe_variant_id';
|
|
2663
|
-
const KEEP_PREVIEW_FOR_SESSION_QUERY_PARAM = 'keep_preview_for_session';
|
|
2664
|
-
let previewDismissed = false;
|
|
2665
|
-
function dismissSessionPreview() {
|
|
2666
|
-
previewDismissed = true;
|
|
2667
|
-
clearPreviewVariantId();
|
|
2668
|
-
const url = new URL(window.location.href);
|
|
2669
|
-
url.searchParams.delete(PREVIEW_VARIANT_QUERY_PARAM);
|
|
2670
|
-
url.searchParams.delete(KEEP_PREVIEW_FOR_SESSION_QUERY_PARAM);
|
|
2671
|
-
window.history.replaceState(window.history.state, '', url);
|
|
2672
|
-
window.location.reload();
|
|
2673
|
-
}
|
|
2674
|
-
function normalizeVariantIds(raw) {
|
|
2675
|
-
if (!raw)
|
|
2676
|
-
return null;
|
|
2677
|
-
const ids = raw
|
|
2678
|
-
.split(',')
|
|
2679
|
-
.map((id) => id.trim())
|
|
2680
|
-
.filter(Boolean);
|
|
2681
|
-
return ids.length > 0 ? ids.join(',') : null;
|
|
2682
|
-
}
|
|
2683
|
-
function readPreviewVariantId() {
|
|
2684
|
-
try {
|
|
2685
|
-
return sessionStorage.getItem(SESSION_VARIANT_KEY);
|
|
2686
|
-
}
|
|
2687
|
-
catch (_a) {
|
|
2688
|
-
return null;
|
|
2689
|
-
}
|
|
2690
|
-
}
|
|
2691
|
-
function persistPreviewVariantId(variantId) {
|
|
2692
|
-
const normalized = normalizeVariantIds(variantId);
|
|
2693
|
-
if (!normalized)
|
|
2694
|
-
return;
|
|
2695
|
-
try {
|
|
2696
|
-
sessionStorage.setItem(SESSION_VARIANT_KEY, normalized);
|
|
2697
|
-
}
|
|
2698
|
-
catch (_a) {
|
|
2699
|
-
}
|
|
2700
|
-
}
|
|
2701
|
-
function clearPreviewVariantId() {
|
|
2702
|
-
try {
|
|
2703
|
-
sessionStorage.removeItem(SESSION_VARIANT_KEY);
|
|
2704
|
-
}
|
|
2705
|
-
catch (_a) {
|
|
2706
|
-
}
|
|
2707
|
-
}
|
|
2708
|
-
function resolvePreviewSource(urlParams = getCurrentUrlSearchParams()) {
|
|
2709
|
-
return {
|
|
2710
|
-
urlVariantId: urlParams.get(PREVIEW_VARIANT_QUERY_PARAM),
|
|
2711
|
-
storedVariantId: readPreviewVariantId(),
|
|
2712
|
-
keepForSession: urlParams.get(KEEP_PREVIEW_FOR_SESSION_QUERY_PARAM) === 'true',
|
|
2713
|
-
};
|
|
2714
|
-
}
|
|
2715
|
-
function resolveSessionPreviewState() {
|
|
2716
|
-
if (previewDismissed) {
|
|
2717
|
-
return { isSessionPreviewActive: false, previewVariantId: null };
|
|
2718
|
-
}
|
|
2719
|
-
const previewSource = resolvePreviewSource();
|
|
2720
|
-
const urlVariantId = normalizeVariantIds(previewSource.urlVariantId);
|
|
2721
|
-
if (urlVariantId && previewSource.keepForSession) {
|
|
2722
|
-
return {
|
|
2723
|
-
isSessionPreviewActive: true,
|
|
2724
|
-
previewVariantId: urlVariantId,
|
|
2725
|
-
};
|
|
2726
|
-
}
|
|
2727
|
-
if (urlVariantId) {
|
|
2728
|
-
return { isSessionPreviewActive: false, previewVariantId: null };
|
|
2729
|
-
}
|
|
2730
|
-
const storedVariantId = normalizeVariantIds(previewSource.storedVariantId);
|
|
2731
|
-
return {
|
|
2732
|
-
isSessionPreviewActive: !!storedVariantId,
|
|
2733
|
-
previewVariantId: storedVariantId,
|
|
2734
|
-
};
|
|
2735
|
-
}
|
|
2736
|
-
|
|
2737
|
-
const PREVIEW_UI_SCRIPT_ID = 'coframe-preview-ui-script';
|
|
2738
|
-
const PREVIEW_UI_URL = "https://edge.cofra.me/preview-ui/latest.js";
|
|
2739
|
-
let loadPromise = null;
|
|
2740
|
-
let latestState = { modes: [] };
|
|
2741
|
-
let nonce;
|
|
2742
|
-
let logger;
|
|
2743
|
-
let mounted = false;
|
|
2744
|
-
function reportError(message, error) {
|
|
2745
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2746
|
-
if (logger) {
|
|
2747
|
-
logger.warn(message, 'preview_ui_unavailable', { error: errorMessage });
|
|
2748
|
-
return;
|
|
2749
|
-
}
|
|
2750
|
-
console.warn(`[Coframe] ${message}`, error);
|
|
2751
|
-
}
|
|
2752
|
-
function getPreviewUI() {
|
|
2753
|
-
const api = window.CoframePreviewUI;
|
|
2754
|
-
return (api === null || api === void 0 ? void 0 : api.protocolVersion) === PREVIEW_UI_PROTOCOL_VERSION ? api : undefined;
|
|
2755
|
-
}
|
|
2756
|
-
function loadPreviewUI() {
|
|
2757
|
-
const existing = getPreviewUI();
|
|
2758
|
-
if (existing)
|
|
2759
|
-
return Promise.resolve(existing);
|
|
2760
|
-
if (loadPromise)
|
|
2761
|
-
return loadPromise;
|
|
2762
|
-
loadPromise = new Promise((resolve, reject) => {
|
|
2763
|
-
const script = document.createElement('script');
|
|
2764
|
-
script.id = PREVIEW_UI_SCRIPT_ID;
|
|
2765
|
-
script.async = true;
|
|
2766
|
-
script.src = PREVIEW_UI_URL;
|
|
2767
|
-
if (nonce)
|
|
2768
|
-
script.nonce = nonce;
|
|
2769
|
-
script.onload = () => {
|
|
2770
|
-
const api = getPreviewUI();
|
|
2771
|
-
if (!api) {
|
|
2772
|
-
reject(new Error('Preview UI protocol is missing or incompatible'));
|
|
2773
|
-
return;
|
|
2774
|
-
}
|
|
2775
|
-
resolve(api);
|
|
2776
|
-
};
|
|
2777
|
-
script.onerror = () => {
|
|
2778
|
-
reject(new Error('Preview UI script failed to load'));
|
|
2779
|
-
};
|
|
2780
|
-
document.head.appendChild(script);
|
|
2781
|
-
});
|
|
2782
|
-
return loadPromise;
|
|
2783
|
-
}
|
|
2784
|
-
function renderPreviewUI(api) {
|
|
2785
|
-
try {
|
|
2786
|
-
if (latestState.modes.length === 0) {
|
|
2787
|
-
api.unmount();
|
|
2788
|
-
mounted = false;
|
|
2789
|
-
}
|
|
2790
|
-
else if (mounted) {
|
|
2791
|
-
api.update(latestState);
|
|
2792
|
-
}
|
|
2793
|
-
else {
|
|
2794
|
-
api.mount({ state: latestState, nonce, onDismiss: dismissPreviewPanel });
|
|
2795
|
-
mounted = true;
|
|
2796
|
-
}
|
|
2797
|
-
}
|
|
2798
|
-
catch (error) {
|
|
2799
|
-
reportError('Preview UI could not be rendered', error);
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
|
-
function dismissPreviewPanel() {
|
|
2803
|
-
dismissSessionPreview();
|
|
2804
|
-
latestState = { modes: [] };
|
|
2805
|
-
const api = getPreviewUI();
|
|
2806
|
-
if (api)
|
|
2807
|
-
renderPreviewUI(api);
|
|
2808
|
-
}
|
|
2809
|
-
function modesWithVariants(sessionPreview, variantsAndElements, applied = true) {
|
|
2810
|
-
const activeModes = getActivePreviewModes(sessionPreview);
|
|
2811
|
-
if (activeModes.length === 0)
|
|
2812
|
-
return [];
|
|
2813
|
-
const currentPageVariantIds = new Set((variantsAndElements === null || variantsAndElements === void 0 ? void 0 : variantsAndElements.map(({ variant }) => variant.id)) || []);
|
|
2814
|
-
const slugById = new Map((variantsAndElements === null || variantsAndElements === void 0 ? void 0 : variantsAndElements.map(({ variant }) => [variant.id, variant.slug])) || []);
|
|
2815
|
-
return activeModes.map((mode) => ({
|
|
2816
|
-
id: mode.id,
|
|
2817
|
-
label: mode.label,
|
|
2818
|
-
title: mode.title,
|
|
2819
|
-
variants: mode.variantIds.map((id) => ({
|
|
2820
|
-
id,
|
|
2821
|
-
slug: slugById.get(id) || null,
|
|
2822
|
-
status: variantsAndElements
|
|
2823
|
-
? applied && currentPageVariantIds.has(id)
|
|
2824
|
-
? 'active'
|
|
2825
|
-
: 'inactive'
|
|
2826
|
-
: 'pending',
|
|
2827
|
-
})),
|
|
2828
|
-
}));
|
|
2829
|
-
}
|
|
2830
|
-
function resolveSessionPreviewPanel(sessionPreview, previewNonce, previewLogger) {
|
|
2831
|
-
const modes = modesWithVariants(sessionPreview);
|
|
2832
|
-
if (modes.length === 0)
|
|
2833
|
-
return;
|
|
2834
|
-
nonce = previewNonce;
|
|
2835
|
-
logger = previewLogger;
|
|
2836
|
-
latestState = { modes };
|
|
2837
|
-
const existing = getPreviewUI();
|
|
2838
|
-
if (existing) {
|
|
2839
|
-
renderPreviewUI(existing);
|
|
2840
|
-
return;
|
|
2841
|
-
}
|
|
2842
|
-
void loadPreviewUI()
|
|
2843
|
-
.then(renderPreviewUI)
|
|
2844
|
-
.catch((error) => reportError('Preview UI could not be loaded', error));
|
|
2845
|
-
}
|
|
2846
|
-
function updatePreviewPanel(variantsAndElements, sessionPreview, applied = true) {
|
|
2847
|
-
latestState = {
|
|
2848
|
-
modes: modesWithVariants(sessionPreview, variantsAndElements, applied),
|
|
2849
|
-
};
|
|
2850
|
-
const api = getPreviewUI();
|
|
2851
|
-
if (api)
|
|
2852
|
-
renderPreviewUI(api);
|
|
2853
|
-
}
|
|
2854
|
-
|
|
2855
2732
|
let lastUrl = null;
|
|
2856
2733
|
function observeUrlChanges(baseUrlMatch, onUrlChange) {
|
|
2857
2734
|
const tryTrack = () => {
|
|
@@ -3206,21 +3083,23 @@ function setupTracking(Coframe, projectResult, previewVariantId, executionStartT
|
|
|
3206
3083
|
}
|
|
3207
3084
|
|
|
3208
3085
|
function resolvePreview(pageUrl, previewVariantId, isSessionVariant) {
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3086
|
+
const previewSource = resolvePreviewSource(pageUrl);
|
|
3087
|
+
if (previewSource.urlVariantId) {
|
|
3088
|
+
return {
|
|
3089
|
+
previewVariantId: previewSource.urlVariantId,
|
|
3090
|
+
isSessionVariant: previewSource.isKeptForSession,
|
|
3091
|
+
};
|
|
3215
3092
|
}
|
|
3216
|
-
if (
|
|
3217
|
-
return {
|
|
3093
|
+
if (previewSource.storedVariantId) {
|
|
3094
|
+
return {
|
|
3095
|
+
previewVariantId: previewSource.storedVariantId,
|
|
3096
|
+
isSessionVariant: true,
|
|
3097
|
+
};
|
|
3218
3098
|
}
|
|
3219
3099
|
if (previewVariantId) {
|
|
3220
3100
|
return { previewVariantId, isSessionVariant };
|
|
3221
3101
|
}
|
|
3222
|
-
|
|
3223
|
-
return { previewVariantId: stored, isSessionVariant: !!stored };
|
|
3102
|
+
return { previewVariantId: null, isSessionVariant: false };
|
|
3224
3103
|
}
|
|
3225
3104
|
async function awaitHydration(config, Coframe, project) {
|
|
3226
3105
|
var _a, _b;
|
|
@@ -3353,8 +3232,6 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
|
|
|
3353
3232
|
Coframe.experimentInfo = experimentsInfo;
|
|
3354
3233
|
Coframe.variantsAndElements = variantsAndElements;
|
|
3355
3234
|
setFrameActivated(hasActivatedFrames);
|
|
3356
|
-
const sessionPreview = resolveSessionPreviewState();
|
|
3357
|
-
updatePreviewPanel(variantsAndElements, sessionPreview, !config.trackingOnly);
|
|
3358
3235
|
if (Coframe.debug) {
|
|
3359
3236
|
Coframe.debug.project = pageProject;
|
|
3360
3237
|
Coframe.debug.frames = pageProject.frames;
|
|
@@ -3374,11 +3251,6 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
|
|
|
3374
3251
|
async function modifyPage(Coframe, configResult, projectResult, analytics) {
|
|
3375
3252
|
const { config, timeoutMs, previewVariantId, isSessionVariant, integrationStartTime, executionStartTime, } = configResult;
|
|
3376
3253
|
const { project: cdnProject, personalizationHeaders } = projectResult;
|
|
3377
|
-
if (resolveSessionPreviewState().isSessionPreviewActive) {
|
|
3378
|
-
waitForBody(timeoutMs)
|
|
3379
|
-
.then(() => resolveSessionPreviewPanel(resolveSessionPreviewState(), config.nonce, Coframe.logger))
|
|
3380
|
-
.catch(() => { });
|
|
3381
|
-
}
|
|
3382
3254
|
if (!(await awaitHydration(config, Coframe, cdnProject)))
|
|
3383
3255
|
return;
|
|
3384
3256
|
if (cdnProject.tags) {
|
|
@@ -3471,15 +3343,13 @@ async function resolveConfig(Coframe, revealPage) {
|
|
|
3471
3343
|
}
|
|
3472
3344
|
Coframe.projectId = projectId;
|
|
3473
3345
|
const urlParams = getCurrentUrlSearchParams();
|
|
3474
|
-
const previewSource = resolvePreviewSource(
|
|
3346
|
+
const previewSource = resolvePreviewSource();
|
|
3475
3347
|
const shouldSendEventsParam = urlParams.get('coframe_should_send_events');
|
|
3476
3348
|
let previewVariantId = null;
|
|
3477
3349
|
let isSessionVariant = false;
|
|
3478
3350
|
if (previewSource.urlVariantId) {
|
|
3479
3351
|
previewVariantId = previewSource.urlVariantId;
|
|
3480
|
-
|
|
3481
|
-
persistPreviewVariantId(previewSource.urlVariantId);
|
|
3482
|
-
}
|
|
3352
|
+
isSessionVariant = previewSource.isKeptForSession;
|
|
3483
3353
|
}
|
|
3484
3354
|
else if (previewSource.storedVariantId) {
|
|
3485
3355
|
previewVariantId = previewSource.storedVariantId;
|
|
@@ -3579,6 +3449,66 @@ async function resolveProject(Coframe, previewVariantId, isSessionVariant, confi
|
|
|
3579
3449
|
};
|
|
3580
3450
|
}
|
|
3581
3451
|
|
|
3452
|
+
const COFRAME_LAUNCHER_PROTOCOL_VERSION = 1;
|
|
3453
|
+
|
|
3454
|
+
const LAUNCHER_SCRIPT_ID = 'coframe-tools-launcher-script';
|
|
3455
|
+
const LAUNCHER_URL = "https://edge.cofra.me/launcher/latest.js";
|
|
3456
|
+
let loading = false;
|
|
3457
|
+
function getLauncher() {
|
|
3458
|
+
const launcher = window.CoframeLauncher;
|
|
3459
|
+
return (launcher === null || launcher === void 0 ? void 0 : launcher.protocolVersion) === COFRAME_LAUNCHER_PROTOCOL_VERSION
|
|
3460
|
+
? launcher
|
|
3461
|
+
: undefined;
|
|
3462
|
+
}
|
|
3463
|
+
function exitDebugSession() {
|
|
3464
|
+
clearDebugToolsSession();
|
|
3465
|
+
const url = new URL(window.location.href);
|
|
3466
|
+
url.searchParams.delete(COFRAME_DEBUG_QUERY_PARAM);
|
|
3467
|
+
window.history.replaceState(window.history.state, '', url);
|
|
3468
|
+
}
|
|
3469
|
+
function mountLauncher(nonce) {
|
|
3470
|
+
const launcher = getLauncher();
|
|
3471
|
+
if (!launcher)
|
|
3472
|
+
return false;
|
|
3473
|
+
launcher.mount({ nonce, onExitDebugSession: exitDebugSession });
|
|
3474
|
+
return true;
|
|
3475
|
+
}
|
|
3476
|
+
function loadLauncherIfEnabled(enabled, nonce) {
|
|
3477
|
+
if (typeof window === 'undefined')
|
|
3478
|
+
return;
|
|
3479
|
+
let sessionEnabled = false;
|
|
3480
|
+
try {
|
|
3481
|
+
sessionEnabled = isDebugToolsSessionEnabled(enabled);
|
|
3482
|
+
}
|
|
3483
|
+
catch (error) {
|
|
3484
|
+
console.warn('[Coframe] Unable to determine Debug Tools session', error);
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
if (!sessionEnabled || mountLauncher(nonce) || loading) {
|
|
3488
|
+
return;
|
|
3489
|
+
}
|
|
3490
|
+
loading = true;
|
|
3491
|
+
const script = document.createElement('script');
|
|
3492
|
+
script.id = LAUNCHER_SCRIPT_ID;
|
|
3493
|
+
script.async = true;
|
|
3494
|
+
script.src = LAUNCHER_URL;
|
|
3495
|
+
if (nonce)
|
|
3496
|
+
script.nonce = nonce;
|
|
3497
|
+
script.onload = () => {
|
|
3498
|
+
loading = false;
|
|
3499
|
+
if (!mountLauncher(nonce)) {
|
|
3500
|
+
document.head.removeChild(script);
|
|
3501
|
+
console.warn('[Coframe] Launcher protocol is missing or incompatible');
|
|
3502
|
+
}
|
|
3503
|
+
};
|
|
3504
|
+
script.onerror = () => {
|
|
3505
|
+
loading = false;
|
|
3506
|
+
document.head.removeChild(script);
|
|
3507
|
+
console.warn('[Coframe] Launcher script failed to load');
|
|
3508
|
+
};
|
|
3509
|
+
document.head.appendChild(script);
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3582
3512
|
function injectOptions(options) {
|
|
3583
3513
|
var _a;
|
|
3584
3514
|
if (options.config) {
|
|
@@ -3644,6 +3574,12 @@ const Coframe = {
|
|
|
3644
3574
|
};
|
|
3645
3575
|
Coframe.logger = createLogger(() => Coframe);
|
|
3646
3576
|
async function init(options) {
|
|
3577
|
+
if (typeof window !== 'undefined' &&
|
|
3578
|
+
/cf_disable/.test(window.location.search)) {
|
|
3579
|
+
console.warn('[Coframe] Disabled via URL parameter');
|
|
3580
|
+
revealPage();
|
|
3581
|
+
return;
|
|
3582
|
+
}
|
|
3647
3583
|
if (options)
|
|
3648
3584
|
injectOptions(options);
|
|
3649
3585
|
const gracefulExit = (msg) => {
|
|
@@ -3654,6 +3590,7 @@ async function init(options) {
|
|
|
3654
3590
|
const configResult = await resolveConfig(Coframe, revealPage);
|
|
3655
3591
|
if (!configResult)
|
|
3656
3592
|
return;
|
|
3593
|
+
loadLauncherIfEnabled(configResult.config.enableDebug === true, configResult.config.nonce);
|
|
3657
3594
|
const projectResult = await resolveProject(Coframe, configResult.previewVariantId, configResult.isSessionVariant, configResult.config);
|
|
3658
3595
|
if (!projectResult)
|
|
3659
3596
|
return;
|
package/dist/pkg/react.cjs.js
CHANGED
|
@@ -5,10 +5,17 @@ var sdk = require('@coframe/sdk');
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
|
|
7
7
|
const CoframeContext = React.createContext({ treatments: null });
|
|
8
|
-
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onLog: onLogProp, children, }) {
|
|
8
|
+
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onTreatmentAppliedBulkV2WithoutConsent, onLog: onLogProp, children, }) {
|
|
9
9
|
const [treatments, setTreatments] = React.useState(null);
|
|
10
10
|
React.useEffect(() => {
|
|
11
11
|
var _a, _b;
|
|
12
|
+
if (/cf_disable/.test(window.location.search)) {
|
|
13
|
+
sdk.init().catch((e) => {
|
|
14
|
+
console.error('[Coframe] Error disabling SDK', e);
|
|
15
|
+
});
|
|
16
|
+
setTreatments([]);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
12
19
|
sdk.onTreatmentApplied({
|
|
13
20
|
callback: onTreatmentAppliedProp,
|
|
14
21
|
bulkCallback: (data) => {
|
|
@@ -16,6 +23,7 @@ function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTre
|
|
|
16
23
|
onTreatmentAppliedBulkProp === null || onTreatmentAppliedBulkProp === void 0 ? void 0 : onTreatmentAppliedBulkProp(data);
|
|
17
24
|
},
|
|
18
25
|
bulkCallbackV2: onTreatmentAppliedBulkV2,
|
|
26
|
+
bulkCallbackV2WithoutConsent: onTreatmentAppliedBulkV2WithoutConsent,
|
|
19
27
|
});
|
|
20
28
|
if (onLogProp) {
|
|
21
29
|
sdk.onLog(onLogProp);
|
package/dist/pkg/react.esm.mjs
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { onTreatmentApplied, onLog
|
|
2
|
+
import { init, onTreatmentApplied, onLog } from '@coframe/sdk';
|
|
3
3
|
export { init, onLog, onTreatmentApplied, setConsent, setFeatureFlag, setPageHydrated, setUserToken, trackConversion } from '@coframe/sdk';
|
|
4
4
|
import React, { createContext, useState, useEffect, useContext } from 'react';
|
|
5
5
|
|
|
6
6
|
const CoframeContext = createContext({ treatments: null });
|
|
7
|
-
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onLog: onLogProp, children, }) {
|
|
7
|
+
function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTreatmentAppliedProp, onTreatmentAppliedBulk: onTreatmentAppliedBulkProp, onTreatmentAppliedBulkV2, onTreatmentAppliedBulkV2WithoutConsent, onLog: onLogProp, children, }) {
|
|
8
8
|
const [treatments, setTreatments] = useState(null);
|
|
9
9
|
useEffect(() => {
|
|
10
10
|
var _a, _b;
|
|
11
|
+
if (/cf_disable/.test(window.location.search)) {
|
|
12
|
+
init().catch((e) => {
|
|
13
|
+
console.error('[Coframe] Error disabling SDK', e);
|
|
14
|
+
});
|
|
15
|
+
setTreatments([]);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
11
18
|
onTreatmentApplied({
|
|
12
19
|
callback: onTreatmentAppliedProp,
|
|
13
20
|
bulkCallback: (data) => {
|
|
@@ -15,6 +22,7 @@ function CoframeProvider({ projectConfig, projectData, onTreatmentApplied: onTre
|
|
|
15
22
|
onTreatmentAppliedBulkProp === null || onTreatmentAppliedBulkProp === void 0 ? void 0 : onTreatmentAppliedBulkProp(data);
|
|
16
23
|
},
|
|
17
24
|
bulkCallbackV2: onTreatmentAppliedBulkV2,
|
|
25
|
+
bulkCallbackV2WithoutConsent: onTreatmentAppliedBulkV2WithoutConsent,
|
|
18
26
|
});
|
|
19
27
|
if (onLogProp) {
|
|
20
28
|
onLog(onLogProp);
|
package/dist/pkg/server.cjs.js
CHANGED
|
@@ -45,14 +45,14 @@ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext,
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext,
|
|
48
|
+
async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, antiflickerMode, headers) {
|
|
49
49
|
try {
|
|
50
50
|
const payload = { projectId, currentUrl };
|
|
51
51
|
if (userContext) {
|
|
52
52
|
payload.userContext = userContext;
|
|
53
53
|
}
|
|
54
|
-
if (
|
|
55
|
-
payload.
|
|
54
|
+
if (antiflickerMode) {
|
|
55
|
+
payload.antiflickerMode = antiflickerMode;
|
|
56
56
|
}
|
|
57
57
|
const config = encodeURIComponent(JSON.stringify(payload));
|
|
58
58
|
const edgeUrl = new URL(`${"https://edge.cofra.me"}/cf.css`);
|
|
@@ -69,6 +69,13 @@ async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, enab
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
async function getProjectData(options) {
|
|
72
|
+
try {
|
|
73
|
+
if (/cf_disable/.test(new URL(options.currentUrl).search)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
}
|
|
72
79
|
const includeProject = options.includeProject !== false;
|
|
73
80
|
const includeCSS = options.includeCSS !== false;
|
|
74
81
|
const [projectResult, antiflickerCSS] = await Promise.all([
|
|
@@ -76,7 +83,7 @@ async function getProjectData(options) {
|
|
|
76
83
|
? fetchProjectFromEdge(options.projectId, options.currentUrl, undefined, options.userContext, undefined, options.headers)
|
|
77
84
|
: Promise.resolve(null),
|
|
78
85
|
includeCSS
|
|
79
|
-
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.
|
|
86
|
+
? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.antiflickerMode, options.headers)
|
|
80
87
|
: Promise.resolve(null),
|
|
81
88
|
]);
|
|
82
89
|
const config = {};
|