@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.
@@ -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
- const url = getCurrentPageUrl();
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
- let urlPreviewVariantId = null;
3210
- try {
3211
- urlPreviewVariantId = new URL(pageUrl).searchParams.get('coframe_variant_id');
3212
- }
3213
- catch (_a) {
3214
- urlPreviewVariantId = getCurrentUrlSearchParams().get('coframe_variant_id');
3086
+ const previewSource = resolvePreviewSource(pageUrl);
3087
+ if (previewSource.urlVariantId) {
3088
+ return {
3089
+ previewVariantId: previewSource.urlVariantId,
3090
+ isSessionVariant: previewSource.isKeptForSession,
3091
+ };
3215
3092
  }
3216
- if (urlPreviewVariantId) {
3217
- return { previewVariantId: urlPreviewVariantId, isSessionVariant: false };
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
- const stored = readPreviewVariantId();
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(urlParams);
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
- if (previewSource.keepForSession) {
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;
@@ -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);
@@ -1,13 +1,20 @@
1
1
  'use client';
2
- import { onTreatmentApplied, onLog, init } from '@coframe/sdk';
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);
@@ -45,14 +45,14 @@ async function fetchProjectFromEdge(projectId, currentUrl, signal, userContext,
45
45
  }
46
46
  }
47
47
 
48
- async function fetchAntiflickerFromEdge(projectId, currentUrl, userContext, enableElementAntiFlicker, headers) {
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 (enableElementAntiFlicker) {
55
- payload.enableElementAntiFlicker = enableElementAntiFlicker;
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.enableElementAntiFlicker, options.headers)
86
+ ? fetchAntiflickerFromEdge(options.projectId, options.currentUrl, options.userContext, options.antiflickerMode, options.headers)
80
87
  : Promise.resolve(null),
81
88
  ]);
82
89
  const config = {};