@preprio/toolkit 0.6.0-alpha.1 → 0.6.0-alpha.10

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.
Files changed (55) hide show
  1. package/README.md +163 -61
  2. package/dist/astro/{chunk-O7N6GPAH.js → chunk-CG2QBHNU.js} +1 -1
  3. package/dist/astro/graphql.cjs +58 -10
  4. package/dist/astro/graphql.d.cts +33 -38
  5. package/dist/astro/graphql.d.ts +33 -38
  6. package/dist/astro/graphql.js +59 -11
  7. package/dist/astro/index.cjs +1 -1
  8. package/dist/astro/index.js +1 -1
  9. package/dist/{chunk-VI6QZTBM.js → chunk-LIDUJWWJ.js} +1 -1
  10. package/dist/{chunk-TBKSBXGH.js → chunk-M3RBYJ5J.js} +52 -5
  11. package/dist/{chunk-3JLWZQ37.js → chunk-SF6TN4JR.js} +1 -1
  12. package/dist/{chunk-YWIKKWBR.js → chunk-TN6SNAR2.js} +1 -1
  13. package/dist/graphql/codegen.cjs +51 -4
  14. package/dist/graphql/codegen.js +3 -3
  15. package/dist/graphql.cjs +89 -10
  16. package/dist/graphql.d.cts +69 -39
  17. package/dist/graphql.d.ts +69 -39
  18. package/dist/graphql.js +38 -9
  19. package/dist/index.cjs +1 -1
  20. package/dist/index.d.cts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +3 -3
  23. package/dist/nextjs/chunk-B4GVZEOL.js +549 -0
  24. package/dist/nextjs/components.cjs +297 -81
  25. package/dist/nextjs/components.d.cts +26 -11
  26. package/dist/nextjs/components.d.ts +26 -11
  27. package/dist/nextjs/components.js +288 -73
  28. package/dist/nextjs/graphql.cjs +856 -266
  29. package/dist/nextjs/graphql.d.cts +184 -116
  30. package/dist/nextjs/graphql.d.ts +184 -116
  31. package/dist/nextjs/graphql.js +543 -266
  32. package/dist/nextjs/index.cjs +116 -54
  33. package/dist/nextjs/index.d.cts +61 -23
  34. package/dist/nextjs/index.d.ts +61 -23
  35. package/dist/nextjs/index.js +97 -299
  36. package/dist/nextjs/{server-CjpELYvq.d.ts → server-BL-sqZvu.d.cts} +1 -1
  37. package/dist/nextjs/{server-CjpELYvq.d.cts → server-BL-sqZvu.d.ts} +1 -1
  38. package/dist/nuxt/{chunk-IQDSBPDN.js → chunk-FMC3DP7N.js} +1 -1
  39. package/dist/nuxt/graphql.cjs +58 -10
  40. package/dist/nuxt/graphql.d.cts +33 -38
  41. package/dist/nuxt/graphql.d.ts +33 -38
  42. package/dist/nuxt/graphql.js +59 -11
  43. package/dist/nuxt/index.cjs +1 -1
  44. package/dist/nuxt/index.js +1 -1
  45. package/dist/react/components.cjs +1 -1
  46. package/dist/react/components.js +1 -1
  47. package/dist/sveltekit/{chunk-OKYZ6HPH.js → chunk-AJPKBAHO.js} +1 -1
  48. package/dist/sveltekit/graphql.cjs +58 -10
  49. package/dist/sveltekit/graphql.d.cts +33 -38
  50. package/dist/sveltekit/graphql.d.ts +33 -38
  51. package/dist/sveltekit/graphql.js +59 -11
  52. package/dist/sveltekit/index.cjs +1 -1
  53. package/dist/sveltekit/index.js +1 -1
  54. package/package.json +1 -1
  55. package/dist/nextjs/chunk-BQ6IGSH6.js +0 -231
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/nextjs/components.ts
22
22
  var components_exports = {};
23
23
  __export(components_exports, {
24
- PreprAbSwitch: () => PreprAbSwitch,
24
+ PreprDecisionApplier: () => PreprDecisionApplier,
25
+ PreprPersonalizationSwitch: () => PreprPersonalizationSwitch,
25
26
  PreprToolbar: () => PreprToolbar,
26
27
  PreprTrackingPixel: () => PreprTrackingPixel,
27
28
  PreprVariantTracking: () => PreprVariantTracking
@@ -457,11 +458,11 @@ function createStegaAutoClean(options) {
457
458
  const settled = stripText ? info?.cleaned : info?.original;
458
459
  if (info && textContent === settled) {
459
460
  if (!info.decoded) return false;
460
- const shown = resolveEditTarget(textNode);
461
- if (!shown) return false;
461
+ const shown2 = resolveEditTarget(textNode);
462
+ if (!shown2) return false;
462
463
  pendingHidden.delete(textNode);
463
- if (shown.hasAttribute("data-prepr-encoded")) return false;
464
- tagEncodedElement(shown, info.decoded);
464
+ if (shown2.hasAttribute("data-prepr-encoded")) return false;
465
+ tagEncodedElement(shown2, info.decoded);
465
466
  return true;
466
467
  }
467
468
  try {
@@ -1054,7 +1055,7 @@ var DEFAULT_STATE = {
1054
1055
  };
1055
1056
  function createToolbarStore(initial = {}) {
1056
1057
  let state = { ...DEFAULT_STATE, ...initial };
1057
- const listeners = /* @__PURE__ */ new Set();
1058
+ const listeners2 = /* @__PURE__ */ new Set();
1058
1059
  function get() {
1059
1060
  return state;
1060
1061
  }
@@ -1063,14 +1064,14 @@ function createToolbarStore(initial = {}) {
1063
1064
  const hasChange = keys.some((key) => patch[key] !== state[key]);
1064
1065
  if (!hasChange) return;
1065
1066
  state = { ...state, ...patch };
1066
- for (const listener of listeners) {
1067
+ for (const listener of listeners2) {
1067
1068
  listener(state);
1068
1069
  }
1069
1070
  }
1070
1071
  function subscribe(fn) {
1071
- listeners.add(fn);
1072
+ listeners2.add(fn);
1072
1073
  return () => {
1073
- listeners.delete(fn);
1074
+ listeners2.delete(fn);
1074
1075
  };
1075
1076
  }
1076
1077
  return { get, set, subscribe };
@@ -2315,75 +2316,156 @@ function isReactHydrated(text) {
2315
2316
  return true;
2316
2317
  }
2317
2318
 
2318
- // src/nextjs/ab-switch.ts
2319
- function applyPreprAbBucket() {
2320
- const match = document.cookie.match(/(?:^|; )prepr_ab_bucket=([AB])(?:;|$)/);
2321
- const bucket = match ? match[1] : "A";
2319
+ // src/nextjs/decision-switch.ts
2320
+ function applyPreprDecisions(decision, options = {}) {
2322
2321
  const state = window;
2323
- if (state.__preprAbBucket === bucket) return;
2324
- state.__preprAbBucket = bucket;
2325
- const css = bucket === "A" ? "" : '[data-prepr-ab="A"]{display:none!important}[data-prepr-ab="' + bucket + '"]{display:contents!important}';
2326
- try {
2327
- if (!state.__preprAbSheet) {
2328
- const sheet = new CSSStyleSheet();
2329
- document.adoptedStyleSheets = document.adoptedStyleSheets.concat(sheet);
2330
- state.__preprAbSheet = sheet;
2331
- }
2332
- state.__preprAbSheet.replaceSync(css);
2333
- } catch {
2334
- if (!state.__preprAbSheet) {
2335
- state.__preprAbSheet = document.createElement("style");
2336
- document.head.appendChild(state.__preprAbSheet);
2337
- }
2338
- state.__preprAbSheet.textContent = css;
2339
- }
2340
- }
2341
- function applyPreprDecisions() {
2342
- const match = document.cookie.match(/(?:^|; )prepr_decisions=([^;]*)/);
2343
- let raw;
2344
- try {
2345
- raw = match ? decodeURIComponent(match[1]) : "";
2346
- } catch {
2347
- raw = "";
2322
+ const key = location.pathname + location.search;
2323
+ const previous = state.__preprDecision;
2324
+ let value = decision;
2325
+ if (value !== void 0 && value !== "*" && options.refresh && previous && previous.key === key && previous.value !== "*") {
2326
+ const pairs = (from) => {
2327
+ const out = {};
2328
+ from.split("~").forEach((pair) => {
2329
+ const colon = pair.indexOf(":");
2330
+ if (colon > 0) out[pair.slice(0, colon)] = pair;
2331
+ });
2332
+ return out;
2333
+ };
2334
+ const before = pairs(previous.value);
2335
+ const after = pairs(value);
2336
+ document.querySelectorAll("[data-prepr-v][data-prepr-show]").forEach((element) => {
2337
+ const range = document.createRange();
2338
+ range.selectNodeContents(element);
2339
+ if (range.getBoundingClientRect().top >= window.innerHeight) return;
2340
+ (element.getAttribute("data-prepr-v") || "").split(" ").forEach((token) => {
2341
+ const group = token.slice(0, token.indexOf(":"));
2342
+ if (before[group]) after[group] = before[group];
2343
+ });
2344
+ });
2345
+ value = Object.keys(after).map((group) => after[group]).join("~");
2348
2346
  }
2349
- const state = window;
2350
- if (state.__preprDecisions === raw) return;
2351
- state.__preprDecisions = raw;
2352
- const id = /^[\w-]+$/;
2353
- let css = "";
2354
- raw.split("~").forEach((pair) => {
2355
- const at = pair.indexOf(":");
2356
- const group = pair.slice(0, at);
2357
- if (at < 1 || !id.test(group)) return;
2358
- const selector = '[data-prepr-group="' + group + '"]';
2359
- css += selector + "{display:none!important}";
2360
- pair.slice(at + 1).split("|").forEach((variant) => {
2361
- if (id.test(variant)) {
2362
- css += selector + '[data-prepr-variant="' + variant + '"]{display:contents!important}';
2363
- }
2347
+ if (value !== void 0) state.__preprDecision = { key, value };
2348
+ const current = state.__preprDecision;
2349
+ if (!current || current.key !== key) return false;
2350
+ document.querySelectorAll("[data-prepr-decision]").forEach((marker) => {
2351
+ marker.setAttribute("data-prepr-decided", "");
2352
+ });
2353
+ const defaults = current.value === "*";
2354
+ const chosen = {};
2355
+ current.value.split("~").forEach((pair) => {
2356
+ const colon = pair.indexOf(":");
2357
+ if (colon > 0)
2358
+ chosen[pair.slice(0, colon)] = pair.slice(colon + 1).split("|");
2359
+ });
2360
+ document.querySelectorAll("[data-prepr-v]").forEach((element) => {
2361
+ const nested = element.hasAttribute("data-prepr-nested");
2362
+ const show = defaults ? element.hasAttribute("data-prepr-default") : (element.getAttribute("data-prepr-v") || "").split(" ").every((token) => {
2363
+ const colon = token.indexOf(":");
2364
+ const variant = token.slice(colon + 1);
2365
+ const variants = chosen[token.slice(0, colon)];
2366
+ return !!variants && (nested ? variants[0] === variant : variants.indexOf(variant) >= 0);
2364
2367
  });
2368
+ if (show) element.setAttribute("data-prepr-show", "");
2369
+ else element.removeAttribute("data-prepr-show");
2365
2370
  });
2366
- try {
2367
- if (!state.__preprDecisionSheet) {
2368
- const sheet = new CSSStyleSheet();
2369
- document.adoptedStyleSheets = document.adoptedStyleSheets.concat(sheet);
2370
- state.__preprDecisionSheet = sheet;
2371
+ return true;
2372
+ }
2373
+ function requestPreprDecision(key, options = {}) {
2374
+ const fresh = 1e4;
2375
+ const keep = 18e5;
2376
+ const keepStatic = 36e5;
2377
+ const state = window;
2378
+ const asking = state.__preprAsking = state.__preprAsking || {};
2379
+ const read = () => {
2380
+ const all = {};
2381
+ try {
2382
+ const match = document.cookie.match(/(?:^|; )prepr_decisions=([^;]*)/);
2383
+ const parsed = match ? JSON.parse(decodeURIComponent(match[1])) : null;
2384
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
2385
+ Object.keys(parsed).forEach((stored) => {
2386
+ const entry = parsed[stored];
2387
+ if (stored.charAt(0) === "/" && Array.isArray(entry) && typeof entry[0] === "string" && typeof entry[1] === "number")
2388
+ all[stored] = [entry[0], entry[1]];
2389
+ });
2390
+ } catch {
2371
2391
  }
2372
- state.__preprDecisionSheet.replaceSync(css);
2373
- } catch {
2374
- if (!state.__preprDecisionSheet) {
2375
- state.__preprDecisionSheet = document.createElement("style");
2376
- document.head.appendChild(state.__preprDecisionSheet);
2392
+ return all;
2393
+ };
2394
+ const usable = (entry, now) => {
2395
+ if (!entry) return false;
2396
+ const age = now - entry[1];
2397
+ return age >= 0 && age < (entry[0] === "*" ? fresh : entry[0] === "" ? keepStatic : keep);
2398
+ };
2399
+ const store = (answer) => {
2400
+ const all = read();
2401
+ const now = Date.now();
2402
+ const kept = all[key];
2403
+ const entries = Object.keys(all).filter((stored) => stored !== key && usable(all[stored], now)).map((stored) => [stored, all[stored]]);
2404
+ entries.push([
2405
+ key,
2406
+ answer === "*" && kept && usable(kept, now) && kept[0] !== "*" ? kept : [answer, now]
2407
+ ]);
2408
+ entries.sort((a2, b2) => b2[1][1] - a2[1][1]);
2409
+ entries.length = Math.min(entries.length, 20);
2410
+ const encode = () => {
2411
+ const out = {};
2412
+ entries.forEach((entry) => {
2413
+ out[entry[0]] = entry[1];
2414
+ });
2415
+ return encodeURIComponent(JSON.stringify(out));
2416
+ };
2417
+ let value = encode();
2418
+ while (entries.length > 1 && value.length > 3e3) {
2419
+ entries.pop();
2420
+ value = encode();
2421
+ }
2422
+ document.cookie = "prepr_decisions=" + value + "; path=/; max-age=3600; samesite=lax" + (location.protocol === "https:" ? "; secure" : "");
2423
+ };
2424
+ const ask = () => {
2425
+ if (!asking[key]) {
2426
+ asking[key] = fetch(key, {
2427
+ headers: { "Prepr-Decide": "1" },
2428
+ cache: "no-store",
2429
+ credentials: "same-origin",
2430
+ // The proxy gives up on Prepr after its own `timeoutMs`; this only
2431
+ // covers a proxy that never answers.
2432
+ signal: AbortSignal.timeout ? AbortSignal.timeout(6e3) : void 0
2433
+ }).then((response) => response.ok ? response.text() : "*").catch(() => "*").then((answer) => {
2434
+ delete asking[key];
2435
+ try {
2436
+ store(answer);
2437
+ } catch {
2438
+ }
2439
+ return answer;
2440
+ });
2377
2441
  }
2378
- state.__preprDecisionSheet.textContent = css;
2442
+ return asking[key];
2443
+ };
2444
+ const last = read()[key];
2445
+ if (last && !(last[0] === "" && options.personalized) && usable(last, Date.now())) {
2446
+ const value = last[0];
2447
+ if (value !== "" && Date.now() - last[1] >= fresh) {
2448
+ ask().then((answer) => {
2449
+ if (answer !== "*" && answer !== value && options.onChange)
2450
+ options.onChange(answer);
2451
+ });
2452
+ }
2453
+ return { result: value, value: Promise.resolve(value) };
2379
2454
  }
2455
+ const pending = {
2456
+ value: ask()
2457
+ };
2458
+ pending.value.then((answer) => {
2459
+ pending.result = answer;
2460
+ });
2461
+ return pending;
2380
2462
  }
2381
2463
 
2382
2464
  // src/react/components.ts
2383
2465
  var import_react = require("react");
2384
2466
 
2385
2467
  // src/version.ts
2386
- var VERSION = "0.6.0-alpha.1";
2468
+ var VERSION = "0.6.0-alpha.10";
2387
2469
 
2388
2470
  // src/core/pixel.ts
2389
2471
  var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
@@ -2458,45 +2540,179 @@ function PreprToolbar({
2458
2540
  }, []);
2459
2541
  return null;
2460
2542
  }
2461
- function PreprAbSwitch() {
2543
+ var shown = /* @__PURE__ */ new Map();
2544
+ var historyStep = false;
2545
+ var onPopState = () => {
2546
+ historyStep = true;
2547
+ };
2548
+ function requestDecision(key, personalized = false) {
2549
+ return requestPreprDecision(key, {
2550
+ personalized,
2551
+ onChange: (value) => {
2552
+ if (location.pathname + location.search !== key) return;
2553
+ applyPreprDecisions(value, { refresh: true });
2554
+ const state = window.__preprDecision;
2555
+ if (state) shown.set(key, state.value);
2556
+ }
2557
+ });
2558
+ }
2559
+ function linkTarget(event) {
2560
+ const anchor = event.target?.closest?.("a[href]");
2561
+ if (!(anchor instanceof HTMLAnchorElement)) return null;
2562
+ if (anchor.target && anchor.target !== "_self" || anchor.hasAttribute("download")) {
2563
+ return null;
2564
+ }
2565
+ const url = new URL(anchor.href, location.href);
2566
+ const key = url.pathname + url.search;
2567
+ if (url.origin !== location.origin || key === location.pathname + location.search) {
2568
+ return null;
2569
+ }
2570
+ return key;
2571
+ }
2572
+ var HOVER_DELAY_MS = 65;
2573
+ var hovering = null;
2574
+ function onPointerOver(event) {
2575
+ if (event.pointerType !== "mouse") return;
2576
+ const key = linkTarget(event);
2577
+ if (hovering?.key === key) return;
2578
+ if (hovering) clearTimeout(hovering.timer);
2579
+ hovering = key ? { key, timer: setTimeout(() => requestDecision(key), HOVER_DELAY_MS) } : null;
2580
+ }
2581
+ function onPointerDown(event) {
2582
+ if (event.button !== 0) return;
2583
+ const key = linkTarget(event);
2584
+ if (key) requestDecision(key);
2585
+ }
2586
+ var replaying = null;
2587
+ function onClick(event) {
2588
+ const key = linkTarget(event);
2589
+ if (!key) return;
2590
+ const anchor = event.target.closest("a[href]");
2591
+ if (replaying === anchor) {
2592
+ replaying = null;
2593
+ return;
2594
+ }
2595
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
2596
+ return;
2597
+ }
2598
+ const pending = requestDecision(key);
2599
+ if (pending.result !== void 0) return;
2600
+ event.preventDefault();
2601
+ event.stopImmediatePropagation();
2602
+ void pending.value.then(() => {
2603
+ replaying = anchor;
2604
+ anchor.click();
2605
+ });
2606
+ }
2607
+ var listeners = 0;
2608
+ function useDecisionRequests() {
2609
+ (0, import_react2.useEffect)(() => {
2610
+ if (listeners++ === 0) {
2611
+ window.addEventListener("pointerover", onPointerOver, { passive: true });
2612
+ window.addEventListener("pointerdown", onPointerDown, {
2613
+ capture: true,
2614
+ passive: true
2615
+ });
2616
+ window.addEventListener("click", onClick, true);
2617
+ window.addEventListener("popstate", onPopState);
2618
+ }
2619
+ return () => {
2620
+ if (--listeners === 0) {
2621
+ window.removeEventListener("pointerover", onPointerOver);
2622
+ window.removeEventListener("pointerdown", onPointerDown, true);
2623
+ window.removeEventListener("click", onClick, true);
2624
+ window.removeEventListener("popstate", onPopState);
2625
+ }
2626
+ };
2627
+ }, []);
2628
+ }
2629
+ function PreprPersonalizationSwitch() {
2630
+ useDecisionRequests();
2631
+ return null;
2632
+ }
2633
+ function PreprDecisionApplier() {
2634
+ useDecisionRequests();
2462
2635
  (0, import_react2.useLayoutEffect)(() => {
2463
- applyPreprAbBucket();
2464
- applyPreprDecisions();
2636
+ const key = location.pathname + location.search;
2637
+ const remember = () => {
2638
+ const state = window.__preprDecision;
2639
+ if (state) shown.set(key, state.value);
2640
+ };
2641
+ const previous = historyStep ? shown.get(key) : void 0;
2642
+ historyStep = false;
2643
+ if (applyPreprDecisions(previous)) {
2644
+ remember();
2645
+ return;
2646
+ }
2647
+ const pending = requestDecision(key, true);
2648
+ if (pending.result !== void 0) {
2649
+ applyPreprDecisions(pending.result);
2650
+ remember();
2651
+ return;
2652
+ }
2653
+ let live = true;
2654
+ void pending.value.then((value) => {
2655
+ if (live && location.pathname + location.search === key) {
2656
+ applyPreprDecisions(value);
2657
+ remember();
2658
+ }
2659
+ });
2660
+ return () => {
2661
+ live = false;
2662
+ };
2465
2663
  });
2466
2664
  return null;
2467
2665
  }
2468
2666
  var VARIANT_KEY_ATTRIBUTE = "data-prepr-variant-key";
2469
2667
  function PreprVariantTracking({
2470
2668
  variantKeys,
2471
- ab,
2472
2669
  children
2473
2670
  }) {
2474
2671
  const ref = (0, import_react2.useRef)(null);
2475
2672
  const keys = variantKeys.join(" ");
2476
2673
  (0, import_react2.useLayoutEffect)(() => {
2477
- const elements = [...ref.current?.children ?? []];
2478
- const list = keys.split(" ");
2479
- const pairs = elements.length === list.length ? elements.map((element, i2) => [element, list[i2]]) : elements.slice(0, 1).map((element) => [element, list[0]]);
2480
- const tagged = pairs.filter(([element, key]) => {
2481
- if (element.hasAttribute(VARIANT_KEY_ATTRIBUTE)) return false;
2482
- element.setAttribute(VARIANT_KEY_ATTRIBUTE, key);
2483
- return true;
2674
+ let tagged = [];
2675
+ const wrapper = ref.current?.closest("[data-prepr-v]");
2676
+ const shown2 = () => !wrapper || wrapper.hasAttribute("data-prepr-show");
2677
+ const untag = () => {
2678
+ for (const [element] of tagged)
2679
+ element.removeAttribute(VARIANT_KEY_ATTRIBUTE);
2680
+ tagged = [];
2681
+ };
2682
+ const tag = () => {
2683
+ if (!shown2()) return untag();
2684
+ if (tagged.length > 0) return;
2685
+ const elements = [...ref.current?.children ?? []];
2686
+ const list = keys.split(" ");
2687
+ const pairs = elements.length === list.length ? elements.map((element, i2) => [element, list[i2]]) : elements.slice(0, 1).map((element) => [element, list[0]]);
2688
+ tagged = pairs.filter(([element, key]) => {
2689
+ if (element.hasAttribute(VARIANT_KEY_ATTRIBUTE)) return false;
2690
+ element.setAttribute(VARIANT_KEY_ATTRIBUTE, key);
2691
+ return true;
2692
+ });
2693
+ };
2694
+ const timer = setTimeout(tag);
2695
+ const observer = wrapper && new MutationObserver(tag);
2696
+ observer?.observe(wrapper, {
2697
+ attributes: true,
2698
+ attributeFilter: ["data-prepr-show"]
2484
2699
  });
2485
2700
  return () => {
2486
- for (const [element] of tagged) {
2487
- element.removeAttribute(VARIANT_KEY_ATTRIBUTE);
2488
- }
2701
+ clearTimeout(timer);
2702
+ observer?.disconnect();
2703
+ untag();
2489
2704
  };
2490
2705
  }, [keys]);
2491
2706
  return (0, import_react2.createElement)(
2492
2707
  "div",
2493
- ab === void 0 ? { ref, style: { display: "contents" } } : { ref, "data-prepr-ab": ab },
2708
+ { ref, style: { display: "contents" } },
2494
2709
  children
2495
2710
  );
2496
2711
  }
2497
2712
  // Annotate the CommonJS export names for ESM import in node:
2498
2713
  0 && (module.exports = {
2499
- PreprAbSwitch,
2714
+ PreprDecisionApplier,
2715
+ PreprPersonalizationSwitch,
2500
2716
  PreprToolbar,
2501
2717
  PreprTrackingPixel,
2502
2718
  PreprVariantTracking
@@ -23,14 +23,31 @@ declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): n
23
23
  */
24
24
  declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
25
25
  /**
26
- * Applies the visitor's A/B bucket, and the segment variants decided in the
27
- * proxy, after client-side navigation. A full page
28
- * load is covered by the inline script `PreprStack` renders, but React does
29
- * not run inline scripts that arrive with a client-side navigation; a layout
30
- * effect still runs before the browser paints the new page. Rendered by
31
- * `PreprStack`; you do not need it yourself.
26
+ * Gets each client-side navigation's decision in before the click: when the
27
+ * visitor hovers over a same-site link (or presses it, on touch devices), it
28
+ * asks `createPreprProxy` which variants they get on that page, so the new
29
+ * page paints with them. A click whose decision is not in yet (a quick tap,
30
+ * a link reached by keyboard) waits for it; one the visitor's recent
31
+ * decisions already cover, or one to a page without personalization, goes
32
+ * through at once.
33
+ *
34
+ * Mount it once in the root layout, so links on pages without a
35
+ * `PreprStack` are covered too. Clicks with a modifier key, links to other
36
+ * sites and links that open a new tab or download are left alone.
37
+ *
38
+ * @example
39
+ * <PreprPersonalizationSwitch />
40
+ */
41
+ declare function PreprPersonalizationSwitch(): null;
42
+ /**
43
+ * Applies this page view's decision to the variant wrappers of the
44
+ * `PreprStack` it is rendered by, before the page paints when the decision is
45
+ * already in: asked for on hover, or kept from an earlier view of the page.
46
+ * Back and Forward show the page as this tab last showed it. Any other view
47
+ * keeps its personalized sections hidden until the decision request answers.
48
+ * Rendered by `PreprStack`; you do not need it yourself.
32
49
  */
33
- declare function PreprAbSwitch(): null;
50
+ declare function PreprDecisionApplier(): null;
34
51
  /**
35
52
  * Wraps one rendered variant and, once hydrated, puts the variant keys on the
36
53
  * elements inside, where Prepr's tracking pixel counts impressions and the
@@ -45,11 +62,9 @@ declare function PreprAbSwitch(): null;
45
62
  * carries a variant key is left alone. Rendered by `PreprStack` with
46
63
  * `trackVariants`; you do not need it yourself.
47
64
  */
48
- declare function PreprVariantTracking({ variantKeys, ab, children, }: {
65
+ declare function PreprVariantTracking({ variantKeys, children, }: {
49
66
  variantKeys: string[];
50
- /** The A/B bucket wrapper this also serves as; its CSS decides `display`. */
51
- ab?: string;
52
67
  children?: ReactNode;
53
68
  }): ReactElement;
54
69
 
55
- export { PreprAbSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };
70
+ export { PreprDecisionApplier, PreprPersonalizationSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };
@@ -23,14 +23,31 @@ declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): n
23
23
  */
24
24
  declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
25
25
  /**
26
- * Applies the visitor's A/B bucket, and the segment variants decided in the
27
- * proxy, after client-side navigation. A full page
28
- * load is covered by the inline script `PreprStack` renders, but React does
29
- * not run inline scripts that arrive with a client-side navigation; a layout
30
- * effect still runs before the browser paints the new page. Rendered by
31
- * `PreprStack`; you do not need it yourself.
26
+ * Gets each client-side navigation's decision in before the click: when the
27
+ * visitor hovers over a same-site link (or presses it, on touch devices), it
28
+ * asks `createPreprProxy` which variants they get on that page, so the new
29
+ * page paints with them. A click whose decision is not in yet (a quick tap,
30
+ * a link reached by keyboard) waits for it; one the visitor's recent
31
+ * decisions already cover, or one to a page without personalization, goes
32
+ * through at once.
33
+ *
34
+ * Mount it once in the root layout, so links on pages without a
35
+ * `PreprStack` are covered too. Clicks with a modifier key, links to other
36
+ * sites and links that open a new tab or download are left alone.
37
+ *
38
+ * @example
39
+ * <PreprPersonalizationSwitch />
40
+ */
41
+ declare function PreprPersonalizationSwitch(): null;
42
+ /**
43
+ * Applies this page view's decision to the variant wrappers of the
44
+ * `PreprStack` it is rendered by, before the page paints when the decision is
45
+ * already in: asked for on hover, or kept from an earlier view of the page.
46
+ * Back and Forward show the page as this tab last showed it. Any other view
47
+ * keeps its personalized sections hidden until the decision request answers.
48
+ * Rendered by `PreprStack`; you do not need it yourself.
32
49
  */
33
- declare function PreprAbSwitch(): null;
50
+ declare function PreprDecisionApplier(): null;
34
51
  /**
35
52
  * Wraps one rendered variant and, once hydrated, puts the variant keys on the
36
53
  * elements inside, where Prepr's tracking pixel counts impressions and the
@@ -45,11 +62,9 @@ declare function PreprAbSwitch(): null;
45
62
  * carries a variant key is left alone. Rendered by `PreprStack` with
46
63
  * `trackVariants`; you do not need it yourself.
47
64
  */
48
- declare function PreprVariantTracking({ variantKeys, ab, children, }: {
65
+ declare function PreprVariantTracking({ variantKeys, children, }: {
49
66
  variantKeys: string[];
50
- /** The A/B bucket wrapper this also serves as; its CSS decides `display`. */
51
- ab?: string;
52
67
  children?: ReactNode;
53
68
  }): ReactElement;
54
69
 
55
- export { PreprAbSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };
70
+ export { PreprDecisionApplier, PreprPersonalizationSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };