@preprio/toolkit 0.5.0-rc.2 → 0.6.0-alpha.1
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 +415 -27
- package/dist/astro/chunk-O7N6GPAH.js +173 -0
- package/dist/astro/graphql.cjs +1030 -0
- package/dist/astro/graphql.d.cts +305 -0
- package/dist/astro/graphql.d.ts +305 -0
- package/dist/astro/graphql.js +936 -0
- package/dist/astro/index-XT_z-RYT.d.cts +130 -0
- package/dist/astro/index-XT_z-RYT.d.ts +130 -0
- package/dist/astro/index.cjs +14 -1
- package/dist/astro/index.d.cts +1 -120
- package/dist/astro/index.d.ts +1 -120
- package/dist/astro/index.js +15 -153
- package/dist/chunk-3JLWZQ37.js +179 -0
- package/dist/chunk-3NCEVJJ3.js +10 -0
- package/dist/chunk-S5RWVMDJ.js +148 -0
- package/dist/chunk-TBKSBXGH.js +452 -0
- package/dist/{chunk-FLPNN3CV.js → chunk-VI6QZTBM.js} +73 -276
- package/dist/chunk-YWIKKWBR.js +26 -0
- package/dist/graphql/codegen.cjs +510 -0
- package/dist/graphql/codegen.d.cts +23 -0
- package/dist/graphql/codegen.d.ts +23 -0
- package/dist/graphql/codegen.js +99 -0
- package/dist/graphql.cjs +941 -0
- package/dist/graphql.d.cts +305 -0
- package/dist/graphql.d.ts +305 -0
- package/dist/graphql.js +419 -0
- package/dist/index.cjs +76 -119
- package/dist/index.d.cts +12 -64
- package/dist/index.d.ts +12 -64
- package/dist/index.js +27 -167
- package/dist/nextjs/chunk-BQ6IGSH6.js +231 -0
- package/dist/nextjs/components.cjs +190 -122
- package/dist/nextjs/components.d.cts +33 -2
- package/dist/nextjs/components.d.ts +33 -2
- package/dist/nextjs/components.js +133 -4
- package/dist/nextjs/graphql.cjs +1362 -0
- package/dist/nextjs/graphql.d.cts +435 -0
- package/dist/nextjs/graphql.d.ts +435 -0
- package/dist/nextjs/graphql.js +1261 -0
- package/dist/nextjs/index.cjs +126 -6
- package/dist/nextjs/index.d.cts +53 -147
- package/dist/nextjs/index.d.ts +53 -147
- package/dist/nextjs/index.js +113 -203
- package/dist/nextjs/server-CjpELYvq.d.cts +156 -0
- package/dist/nextjs/server-CjpELYvq.d.ts +156 -0
- package/dist/nuxt/chunk-IQDSBPDN.js +417 -0
- package/dist/nuxt/graphql.cjs +1037 -0
- package/dist/nuxt/graphql.d.cts +302 -0
- package/dist/nuxt/graphql.d.ts +302 -0
- package/dist/nuxt/graphql.js +937 -0
- package/dist/nuxt/index.cjs +14 -1
- package/dist/nuxt/index.d.cts +3 -148
- package/dist/nuxt/index.d.ts +3 -148
- package/dist/nuxt/index.js +15 -391
- package/dist/nuxt/server-8v6OHbsw.d.cts +158 -0
- package/dist/nuxt/server-8v6OHbsw.d.ts +158 -0
- package/dist/pixel-DwW7cXJm.d.cts +49 -0
- package/dist/pixel-DwW7cXJm.d.ts +49 -0
- package/dist/react/components.cjs +88 -120
- package/dist/react/components.d.cts +2 -8
- package/dist/react/components.d.ts +2 -8
- package/dist/react/components.js +88 -120
- package/dist/server-Brr1UgtW.d.ts +59 -0
- package/dist/server-DJuS3YU0.d.cts +59 -0
- package/dist/sveltekit/chunk-OKYZ6HPH.js +413 -0
- package/dist/sveltekit/graphql.cjs +1043 -0
- package/dist/sveltekit/graphql.d.cts +307 -0
- package/dist/sveltekit/graphql.d.ts +307 -0
- package/dist/sveltekit/graphql.js +943 -0
- package/dist/sveltekit/index.cjs +14 -1
- package/dist/sveltekit/index.d.cts +3 -88
- package/dist/sveltekit/index.d.ts +3 -88
- package/dist/sveltekit/index.js +15 -387
- package/dist/sveltekit/server-CO847mEV.d.cts +98 -0
- package/dist/sveltekit/server-CO847mEV.d.ts +98 -0
- package/dist/{pixel-B3oQNbZ3.d.cts → types-BYH9XqmN.d.cts} +4 -58
- package/dist/{pixel-B3oQNbZ3.d.ts → types-BYH9XqmN.d.ts} +4 -58
- package/package.json +36 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
getPreprHeadersFromHeaders: () => getPreprHeadersFromHeaders,
|
|
34
34
|
getPreprUUIDFromHeaders: () => getPreprUUIDFromHeaders,
|
|
35
35
|
getToolbarPropsFromHeaders: () => getToolbarPropsFromHeaders,
|
|
36
|
+
isPersonalizedResponse: () => isPersonalizedResponse,
|
|
36
37
|
loadTrackingPixel: () => loadTrackingPixel,
|
|
37
38
|
processPreprRequest: () => processPreprRequest,
|
|
38
39
|
resolveFeatures: () => resolveFeatures,
|
|
@@ -44,7 +45,7 @@ __export(src_exports, {
|
|
|
44
45
|
module.exports = __toCommonJS(src_exports);
|
|
45
46
|
|
|
46
47
|
// src/version.ts
|
|
47
|
-
var VERSION = "0.
|
|
48
|
+
var VERSION = "0.6.0-alpha.1";
|
|
48
49
|
|
|
49
50
|
// src/core/features.ts
|
|
50
51
|
function isEnabled(config) {
|
|
@@ -312,13 +313,9 @@ function createElementCache(query, ttl = 1e3) {
|
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
// src/core/iframe-bridge.ts
|
|
315
|
-
var debug = createScopedLogger("iframe-bridge");
|
|
316
316
|
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
317
317
|
function isAllowedEditorOrigin(origin, allowed) {
|
|
318
|
-
if (allowed)
|
|
319
|
-
if (allowed.includes("*")) return origin !== "null";
|
|
320
|
-
return allowed.includes(origin);
|
|
321
|
-
}
|
|
318
|
+
if (allowed) return allowed.includes(origin);
|
|
322
319
|
let url;
|
|
323
320
|
try {
|
|
324
321
|
url = new URL(origin);
|
|
@@ -333,7 +330,6 @@ function isAllowedEditorOrigin(origin, allowed) {
|
|
|
333
330
|
}
|
|
334
331
|
function createIframeBridge(store, options = {}) {
|
|
335
332
|
const allowedOrigins = options.allowedEditorOrigins;
|
|
336
|
-
const onScrollToField = options.onScrollToField;
|
|
337
333
|
let parentOrigin = null;
|
|
338
334
|
const onKeyDown = (event) => {
|
|
339
335
|
const key = event.key.toLowerCase();
|
|
@@ -343,10 +339,7 @@ function createIframeBridge(store, options = {}) {
|
|
|
343
339
|
const onMessage = (evt) => {
|
|
344
340
|
const data = evt?.data;
|
|
345
341
|
if (data?.event === "prepr:initVE" && !parentOrigin) {
|
|
346
|
-
if (!isAllowedEditorOrigin(evt.origin, allowedOrigins))
|
|
347
|
-
debug.warn("ignored editor handshake from origin", evt.origin);
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
342
|
+
if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) return;
|
|
350
343
|
parentOrigin = evt.origin;
|
|
351
344
|
setTrustedParentOrigin(parentOrigin);
|
|
352
345
|
if (data.scrollPosition != null) {
|
|
@@ -360,15 +353,6 @@ function createIframeBridge(store, options = {}) {
|
|
|
360
353
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
361
354
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
362
355
|
}
|
|
363
|
-
if (data?.event === "prepr:scrollToField") {
|
|
364
|
-
if (typeof data.field !== "string" || !data.field) return;
|
|
365
|
-
if (data.id !== void 0 && typeof data.id !== "string") return;
|
|
366
|
-
try {
|
|
367
|
-
onScrollToField?.({ field: data.field, id: data.id });
|
|
368
|
-
} catch (error) {
|
|
369
|
-
debug.warn("scrollToField handler failed", error);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
356
|
};
|
|
373
357
|
return {
|
|
374
358
|
start() {
|
|
@@ -393,7 +377,7 @@ var import_stega2 = require("@vercel/stega");
|
|
|
393
377
|
|
|
394
378
|
// src/core/stega/clean.ts
|
|
395
379
|
var import_stega = require("@vercel/stega");
|
|
396
|
-
var
|
|
380
|
+
var debug = createScopedLogger("stega:clean");
|
|
397
381
|
function stegaClean(text) {
|
|
398
382
|
if (!text) return text;
|
|
399
383
|
return (0, import_stega.vercelStegaClean)(text);
|
|
@@ -406,7 +390,7 @@ function decodeStega(str) {
|
|
|
406
390
|
return decoded;
|
|
407
391
|
}
|
|
408
392
|
} catch (error) {
|
|
409
|
-
|
|
393
|
+
debug.log("error decoding stega data", error);
|
|
410
394
|
const match = str.match(/{"origin.*?}/);
|
|
411
395
|
if (match) {
|
|
412
396
|
try {
|
|
@@ -415,7 +399,7 @@ function decodeStega(str) {
|
|
|
415
399
|
return decodedMatch;
|
|
416
400
|
}
|
|
417
401
|
} catch (innerError) {
|
|
418
|
-
|
|
402
|
+
debug.log("error decoding stega regex match", innerError);
|
|
419
403
|
}
|
|
420
404
|
}
|
|
421
405
|
}
|
|
@@ -451,37 +435,15 @@ function isRenderedElement(element) {
|
|
|
451
435
|
if (!style) return true;
|
|
452
436
|
return style.visibility !== "hidden" && style.display !== "none";
|
|
453
437
|
}
|
|
454
|
-
function parseEditHref(href) {
|
|
455
|
-
try {
|
|
456
|
-
const url = new URL(href, window.location.origin);
|
|
457
|
-
return {
|
|
458
|
-
id: url.pathname.split("/").pop() || void 0,
|
|
459
|
-
field: url.searchParams.get("field") || void 0,
|
|
460
|
-
locale: url.searchParams.get("locale") || void 0
|
|
461
|
-
};
|
|
462
|
-
} catch {
|
|
463
|
-
return {};
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
function setOrRemove(element, name, value) {
|
|
467
|
-
if (value) {
|
|
468
|
-
element.setAttribute(name, value);
|
|
469
|
-
} else {
|
|
470
|
-
element.removeAttribute(name);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
438
|
function tagEncodedElement(element, decoded) {
|
|
474
439
|
element.setAttribute("data-prepr-encoded", "");
|
|
475
440
|
element.setAttribute("data-prepr-href", decoded.href);
|
|
476
441
|
element.setAttribute("data-prepr-origin", decoded.origin);
|
|
477
|
-
const { id, field, locale } = parseEditHref(decoded.href);
|
|
478
|
-
setOrRemove(element, "data-prepr-id", id);
|
|
479
|
-
setOrRemove(element, "data-prepr-field", field);
|
|
480
|
-
setOrRemove(element, "data-prepr-locale", locale);
|
|
481
442
|
}
|
|
482
443
|
|
|
483
444
|
// src/core/stega/auto-clean.ts
|
|
484
|
-
var
|
|
445
|
+
var debug2 = createScopedLogger("stega:auto-clean");
|
|
446
|
+
var HYDRATION_RETRY_MS = 100;
|
|
485
447
|
function createStegaAutoClean(options) {
|
|
486
448
|
const stripText = options?.enabled ?? true;
|
|
487
449
|
let observer = null;
|
|
@@ -490,8 +452,29 @@ function createStegaAutoClean(options) {
|
|
|
490
452
|
let pendingHidden = /* @__PURE__ */ new Set();
|
|
491
453
|
let pendingDirty = /* @__PURE__ */ new Set();
|
|
492
454
|
let debounceTimeout = null;
|
|
455
|
+
const isHydrated = options?.isHydrated;
|
|
456
|
+
let pendingHydration = /* @__PURE__ */ new Set();
|
|
457
|
+
let hydrationTimeout = null;
|
|
458
|
+
function retryPendingHydration() {
|
|
459
|
+
hydrationTimeout = null;
|
|
460
|
+
processing = true;
|
|
461
|
+
const batch = [...pendingHydration];
|
|
462
|
+
pendingHydration.clear();
|
|
463
|
+
batch.forEach((textNode) => {
|
|
464
|
+
if (textNode.isConnected) cleanTextNode(textNode);
|
|
465
|
+
});
|
|
466
|
+
processing = false;
|
|
467
|
+
}
|
|
493
468
|
function cleanTextNode(textNode) {
|
|
494
469
|
if (isIgnoredTextNode(textNode)) return false;
|
|
470
|
+
if (isHydrated && !isHydrated(textNode)) {
|
|
471
|
+
pendingHydration.add(textNode);
|
|
472
|
+
hydrationTimeout ?? (hydrationTimeout = setTimeout(
|
|
473
|
+
retryPendingHydration,
|
|
474
|
+
HYDRATION_RETRY_MS
|
|
475
|
+
));
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
495
478
|
const textContent = textNode.textContent;
|
|
496
479
|
const info = cleaned.get(textNode);
|
|
497
480
|
const settled = stripText ? info?.cleaned : info?.original;
|
|
@@ -524,7 +507,7 @@ function createStegaAutoClean(options) {
|
|
|
524
507
|
}
|
|
525
508
|
pendingHidden.add(textNode);
|
|
526
509
|
} catch (error) {
|
|
527
|
-
|
|
510
|
+
debug2.log("error cleaning text node", error);
|
|
528
511
|
}
|
|
529
512
|
return false;
|
|
530
513
|
}
|
|
@@ -610,13 +593,17 @@ function createStegaAutoClean(options) {
|
|
|
610
593
|
if (observer || typeof window === "undefined") return;
|
|
611
594
|
scanAndClean();
|
|
612
595
|
setupObserver();
|
|
613
|
-
|
|
596
|
+
debug2.log("stega auto-clean started");
|
|
614
597
|
}
|
|
615
598
|
function stop() {
|
|
616
599
|
if (debounceTimeout) {
|
|
617
600
|
clearTimeout(debounceTimeout);
|
|
618
601
|
debounceTimeout = null;
|
|
619
602
|
}
|
|
603
|
+
if (hydrationTimeout) {
|
|
604
|
+
clearTimeout(hydrationTimeout);
|
|
605
|
+
hydrationTimeout = null;
|
|
606
|
+
}
|
|
620
607
|
if (observer) {
|
|
621
608
|
observer.disconnect();
|
|
622
609
|
observer = null;
|
|
@@ -624,13 +611,14 @@ function createStegaAutoClean(options) {
|
|
|
624
611
|
cleaned = /* @__PURE__ */ new WeakMap();
|
|
625
612
|
pendingHidden = /* @__PURE__ */ new Set();
|
|
626
613
|
pendingDirty = /* @__PURE__ */ new Set();
|
|
627
|
-
|
|
614
|
+
pendingHydration = /* @__PURE__ */ new Set();
|
|
615
|
+
debug2.log("stega auto-clean stopped");
|
|
628
616
|
}
|
|
629
617
|
return { start, stop };
|
|
630
618
|
}
|
|
631
619
|
|
|
632
620
|
// src/core/stega/elements.ts
|
|
633
|
-
var
|
|
621
|
+
var debug3 = createScopedLogger("stega:elements");
|
|
634
622
|
var StegaElements = class {
|
|
635
623
|
constructor(decode = decodeStega) {
|
|
636
624
|
this.observer = null;
|
|
@@ -675,7 +663,7 @@ var StegaElements = class {
|
|
|
675
663
|
walkTextNodes(document.body, (textNode) => {
|
|
676
664
|
if (this.tagFromTextNode(textNode)) encodedCount++;
|
|
677
665
|
});
|
|
678
|
-
|
|
666
|
+
debug3.log("document scan complete, encoded", encodedCount, "elements");
|
|
679
667
|
this.elements = document.querySelectorAll("[data-prepr-encoded]");
|
|
680
668
|
}
|
|
681
669
|
/** `onUpdate` fires after each debounced batch, for refreshing derived state. */
|
|
@@ -731,9 +719,6 @@ var StegaElements = class {
|
|
|
731
719
|
element.removeAttribute("data-prepr-encoded");
|
|
732
720
|
element.removeAttribute("data-prepr-href");
|
|
733
721
|
element.removeAttribute("data-prepr-origin");
|
|
734
|
-
element.removeAttribute("data-prepr-id");
|
|
735
|
-
element.removeAttribute("data-prepr-field");
|
|
736
|
-
element.removeAttribute("data-prepr-locale");
|
|
737
722
|
element.classList.remove("prepr-overlay-active");
|
|
738
723
|
});
|
|
739
724
|
this.elements = void 0;
|
|
@@ -741,7 +726,7 @@ var StegaElements = class {
|
|
|
741
726
|
};
|
|
742
727
|
|
|
743
728
|
// src/core/stega/overlay.ts
|
|
744
|
-
var
|
|
729
|
+
var debug4 = createScopedLogger("stega:overlay");
|
|
745
730
|
var StegaOverlay = class {
|
|
746
731
|
constructor(onEdit) {
|
|
747
732
|
this.overlay = null;
|
|
@@ -786,8 +771,7 @@ var StegaOverlay = class {
|
|
|
786
771
|
const origin = element.getAttribute("data-prepr-origin");
|
|
787
772
|
const id = element.getAttribute("data-prepr-id") ?? void 0;
|
|
788
773
|
const field = element.getAttribute("data-prepr-field") ?? void 0;
|
|
789
|
-
|
|
790
|
-
debug5.log("showing overlay", { href, origin });
|
|
774
|
+
debug4.log("showing overlay", { href, origin });
|
|
791
775
|
const overlay = this.overlay;
|
|
792
776
|
overlay.style.display = "block";
|
|
793
777
|
overlay.style.top = `${rect.top + window.scrollY - 2}px`;
|
|
@@ -819,7 +803,7 @@ var StegaOverlay = class {
|
|
|
819
803
|
tooltip.style.left = `${left}px`;
|
|
820
804
|
});
|
|
821
805
|
tooltip.onclick = () => {
|
|
822
|
-
this.onEdit({ href, origin, id, field
|
|
806
|
+
this.onEdit({ href, origin, id, field });
|
|
823
807
|
};
|
|
824
808
|
}
|
|
825
809
|
this.currentElement = element;
|
|
@@ -859,7 +843,7 @@ var StegaOverlay = class {
|
|
|
859
843
|
};
|
|
860
844
|
|
|
861
845
|
// src/core/stega/proximity.ts
|
|
862
|
-
var
|
|
846
|
+
var debug5 = createScopedLogger("stega:proximity");
|
|
863
847
|
var StegaProximity = class {
|
|
864
848
|
constructor() {
|
|
865
849
|
this.highlighted = /* @__PURE__ */ new Set();
|
|
@@ -894,9 +878,9 @@ var StegaProximity = class {
|
|
|
894
878
|
);
|
|
895
879
|
const nodes = this.getEncodedElements();
|
|
896
880
|
nodes.forEach((el) => this.observer.observe(el));
|
|
897
|
-
|
|
881
|
+
debug5.log("observing", nodes.length, "encoded elements");
|
|
898
882
|
} catch (error) {
|
|
899
|
-
|
|
883
|
+
debug5.log("error setting up IntersectionObserver", error);
|
|
900
884
|
}
|
|
901
885
|
}
|
|
902
886
|
stopObserving() {
|
|
@@ -966,7 +950,7 @@ function removeStegaStyles() {
|
|
|
966
950
|
}
|
|
967
951
|
|
|
968
952
|
// src/core/stega/scan.ts
|
|
969
|
-
var
|
|
953
|
+
var debug6 = createScopedLogger("stega:scan");
|
|
970
954
|
var EDITOR_MODE_STYLES = "[data-prepr-encoded]{cursor:pointer}";
|
|
971
955
|
function createStegaController(opts) {
|
|
972
956
|
const tooltipEnabled = opts.tooltip ?? true;
|
|
@@ -999,13 +983,12 @@ function createStegaController(opts) {
|
|
|
999
983
|
href: encoded.getAttribute("data-prepr-href") ?? "",
|
|
1000
984
|
origin: encoded.getAttribute("data-prepr-origin") ?? "",
|
|
1001
985
|
id: encoded.getAttribute("data-prepr-id") ?? void 0,
|
|
1002
|
-
field: encoded.getAttribute("data-prepr-field") ?? void 0
|
|
1003
|
-
locale: encoded.getAttribute("data-prepr-locale") ?? void 0
|
|
986
|
+
field: encoded.getAttribute("data-prepr-field") ?? void 0
|
|
1004
987
|
});
|
|
1005
988
|
};
|
|
1006
989
|
const start = () => {
|
|
1007
990
|
if (initialized) {
|
|
1008
|
-
|
|
991
|
+
debug6.log("already initialized, skipping setup");
|
|
1009
992
|
return;
|
|
1010
993
|
}
|
|
1011
994
|
if (!tooltipEnabled) {
|
|
@@ -1015,7 +998,7 @@ function createStegaController(opts) {
|
|
|
1015
998
|
});
|
|
1016
999
|
document.addEventListener("click", handleClick, { capture: true });
|
|
1017
1000
|
initialized = true;
|
|
1018
|
-
|
|
1001
|
+
debug6.log("stega controller started (editor mode)");
|
|
1019
1002
|
return;
|
|
1020
1003
|
}
|
|
1021
1004
|
injectStegaStyles();
|
|
@@ -1046,7 +1029,7 @@ function createStegaController(opts) {
|
|
|
1046
1029
|
passive: true
|
|
1047
1030
|
});
|
|
1048
1031
|
initialized = true;
|
|
1049
|
-
|
|
1032
|
+
debug6.log("stega controller started");
|
|
1050
1033
|
};
|
|
1051
1034
|
const stop = () => {
|
|
1052
1035
|
if (!initialized) return;
|
|
@@ -1055,7 +1038,7 @@ function createStegaController(opts) {
|
|
|
1055
1038
|
elements.cleanup();
|
|
1056
1039
|
removeStegaStyles();
|
|
1057
1040
|
initialized = false;
|
|
1058
|
-
|
|
1041
|
+
debug6.log("stega controller stopped (editor mode)");
|
|
1059
1042
|
return;
|
|
1060
1043
|
}
|
|
1061
1044
|
if (throttledMouseMove) {
|
|
@@ -1075,43 +1058,11 @@ function createStegaController(opts) {
|
|
|
1075
1058
|
elements.cleanup();
|
|
1076
1059
|
removeStegaStyles();
|
|
1077
1060
|
initialized = false;
|
|
1078
|
-
|
|
1061
|
+
debug6.log("stega controller stopped");
|
|
1079
1062
|
};
|
|
1080
1063
|
return { start, stop };
|
|
1081
1064
|
}
|
|
1082
1065
|
|
|
1083
|
-
// src/core/stega/scroll-to-field.ts
|
|
1084
|
-
var debug8 = createScopedLogger("stega:scroll");
|
|
1085
|
-
var FLASH_DURATION_MS = 1200;
|
|
1086
|
-
var flashTimeout = null;
|
|
1087
|
-
function scrollToField(request) {
|
|
1088
|
-
const { field, id } = request;
|
|
1089
|
-
if (!field) return false;
|
|
1090
|
-
const candidates = document.querySelectorAll(
|
|
1091
|
-
"[data-prepr-encoded]"
|
|
1092
|
-
);
|
|
1093
|
-
let target = null;
|
|
1094
|
-
for (const candidate of candidates) {
|
|
1095
|
-
if (candidate.getAttribute("data-prepr-field") !== field) continue;
|
|
1096
|
-
if (id && candidate.getAttribute("data-prepr-id") !== id) continue;
|
|
1097
|
-
target = candidate;
|
|
1098
|
-
break;
|
|
1099
|
-
}
|
|
1100
|
-
if (!target) {
|
|
1101
|
-
debug8.log("no element found for field", field);
|
|
1102
|
-
return false;
|
|
1103
|
-
}
|
|
1104
|
-
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
1105
|
-
if (flashTimeout) clearTimeout(flashTimeout);
|
|
1106
|
-
document.querySelectorAll(".prepr-overlay-active").forEach((el) => el.classList.remove("prepr-overlay-active"));
|
|
1107
|
-
target.classList.add("prepr-overlay-active");
|
|
1108
|
-
flashTimeout = setTimeout(() => {
|
|
1109
|
-
target.classList.remove("prepr-overlay-active");
|
|
1110
|
-
flashTimeout = null;
|
|
1111
|
-
}, FLASH_DURATION_MS);
|
|
1112
|
-
return true;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
1066
|
// src/core/store.ts
|
|
1116
1067
|
var DEFAULT_STATE = {
|
|
1117
1068
|
locale: "en",
|
|
@@ -2224,7 +2175,7 @@ function definePreprToolbar() {
|
|
|
2224
2175
|
}
|
|
2225
2176
|
|
|
2226
2177
|
// src/core/create-preview.ts
|
|
2227
|
-
var
|
|
2178
|
+
var debug7 = createScopedLogger("create-preview");
|
|
2228
2179
|
var controllerStores = /* @__PURE__ */ new WeakMap();
|
|
2229
2180
|
function defaultNavigation() {
|
|
2230
2181
|
return {
|
|
@@ -2266,7 +2217,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2266
2217
|
const search = new URLSearchParams(window.location.search);
|
|
2267
2218
|
const hideBar = search.get(PARAM_HIDE_BAR) === "true";
|
|
2268
2219
|
if (hideBar) {
|
|
2269
|
-
|
|
2220
|
+
debug7.log(`${PARAM_HIDE_BAR}=true \u2014 no visible toolbar`);
|
|
2270
2221
|
}
|
|
2271
2222
|
const mountUi = (options?.ui ?? true) && !isIframe && !hideBar;
|
|
2272
2223
|
const locale = resolveLocale(options);
|
|
@@ -2302,17 +2253,18 @@ function createPreprPreview(opts = {}) {
|
|
|
2302
2253
|
tooltip: mountUi,
|
|
2303
2254
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2304
2255
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2305
|
-
onEdit: ({ href, id, field
|
|
2256
|
+
onEdit: ({ href, origin, id, field }) => {
|
|
2306
2257
|
const safeHref = href ? safeEditUrl(href) : null;
|
|
2307
2258
|
if (href && !safeHref) {
|
|
2308
|
-
|
|
2259
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2309
2260
|
return;
|
|
2310
2261
|
}
|
|
2311
2262
|
if (isIframe) {
|
|
2312
2263
|
sendPreprEvent("field_edit_requested", {
|
|
2264
|
+
href: safeHref ?? void 0,
|
|
2265
|
+
origin,
|
|
2313
2266
|
id,
|
|
2314
|
-
field
|
|
2315
|
-
locale: contentLocale
|
|
2267
|
+
field
|
|
2316
2268
|
});
|
|
2317
2269
|
} else if (safeHref) {
|
|
2318
2270
|
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
@@ -2320,7 +2272,8 @@ function createPreprPreview(opts = {}) {
|
|
|
2320
2272
|
}
|
|
2321
2273
|
});
|
|
2322
2274
|
const autoClean = createStegaAutoClean({
|
|
2323
|
-
enabled: options?.autoClean
|
|
2275
|
+
enabled: options?.autoClean,
|
|
2276
|
+
isHydrated: opts.isHydrated
|
|
2324
2277
|
});
|
|
2325
2278
|
autoClean.start();
|
|
2326
2279
|
const handleChange = createChangeHandler({
|
|
@@ -2339,15 +2292,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2339
2292
|
handleChange(before, state);
|
|
2340
2293
|
});
|
|
2341
2294
|
const bridge = createIframeBridge(store, {
|
|
2342
|
-
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2343
|
-
// The editor selecting a field scrolls the matching element into view. The
|
|
2344
|
-
// lookup relies on the attributes the stega scan writes, so it finds
|
|
2345
|
-
// nothing until encoded content has been tagged.
|
|
2346
|
-
onScrollToField: ({ field, id }) => {
|
|
2347
|
-
if (!scrollToField({ field, id })) {
|
|
2348
|
-
debug9.log("no element on this page renders field", field);
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2295
|
+
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2351
2296
|
});
|
|
2352
2297
|
sendPreprEvent(
|
|
2353
2298
|
"getScrollPosition",
|
|
@@ -2367,13 +2312,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2367
2312
|
bridge.stop();
|
|
2368
2313
|
}
|
|
2369
2314
|
el?.remove();
|
|
2370
|
-
|
|
2315
|
+
debug7.log("preview destroyed");
|
|
2371
2316
|
}
|
|
2372
2317
|
const controller = { destroy };
|
|
2373
2318
|
controllerStores.set(controller, store);
|
|
2374
2319
|
return controller;
|
|
2375
2320
|
}
|
|
2376
2321
|
|
|
2322
|
+
// src/core/personalization.ts
|
|
2323
|
+
var PERSONALIZED_VARY = /\bPrepr-(Segments|ABTesting)/i;
|
|
2324
|
+
function isPersonalizedResponse(source) {
|
|
2325
|
+
const headers = "headers" in source ? source.headers : source;
|
|
2326
|
+
return PERSONALIZED_VARY.test(headers.get("vary") ?? "");
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2377
2329
|
// src/core/server.ts
|
|
2378
2330
|
var PreprError = class extends Error {
|
|
2379
2331
|
constructor(message, code, context, originalError) {
|
|
@@ -2689,6 +2641,10 @@ function processFrameworkRequest(request, opts, framework) {
|
|
|
2689
2641
|
});
|
|
2690
2642
|
}
|
|
2691
2643
|
}
|
|
2644
|
+
if (requestHeaders.has("Prepr-Segments")) {
|
|
2645
|
+
requestHeaders.delete("Prepr-Customer-Id");
|
|
2646
|
+
requestHeaders.delete("Prepr-Customer-Id-Created");
|
|
2647
|
+
}
|
|
2692
2648
|
return { requestHeaders, responseCookies };
|
|
2693
2649
|
}
|
|
2694
2650
|
|
|
@@ -2771,6 +2727,7 @@ function setTrackingParam(key, value) {
|
|
|
2771
2727
|
getPreprHeadersFromHeaders,
|
|
2772
2728
|
getPreprUUIDFromHeaders,
|
|
2773
2729
|
getToolbarPropsFromHeaders,
|
|
2730
|
+
isPersonalizedResponse,
|
|
2774
2731
|
loadTrackingPixel,
|
|
2775
2732
|
processPreprRequest,
|
|
2776
2733
|
resolveFeatures,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName,
|
|
1
|
+
import { b as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, c as PreprSegment, d as PreprVariant, e as PreprToolbarProps, f as PreprPreviewOptions } from './types-BYH9XqmN.cjs';
|
|
2
|
+
export { g as PreprEnvironment, a as PreprErrorCode, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, P as PreprHeaders, k as PreprToolbarComponentProps, l as PreprToolbarOptions } from './types-BYH9XqmN.cjs';
|
|
3
|
+
export { P as PreprError, e as extractAccessToken, g as getActiveSegmentFromHeaders, a as getActiveVariantFromHeaders, b as getPreprEnvironmentSegments, c as getPreprHeadersFromHeaders, d as getPreprUUIDFromHeaders, f as getToolbarPropsFromHeaders, i as isPersonalizedResponse, v as validatePreprToken } from './server-DJuS3YU0.cjs';
|
|
4
|
+
export { P as PreprPixelConfig, l as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-DwW7cXJm.cjs';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
6
8
|
* core can import it without cycling through the barrel.
|
|
7
9
|
*/
|
|
8
|
-
declare const VERSION = "0.
|
|
10
|
+
declare const VERSION = "0.6.0-alpha.1";
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
|
|
@@ -65,6 +67,11 @@ interface CreatePreprPreviewOptions {
|
|
|
65
67
|
props?: PreprToolbarProps;
|
|
66
68
|
options?: PreprPreviewOptions;
|
|
67
69
|
navigation?: PreprNavigationAdapter;
|
|
70
|
+
/**
|
|
71
|
+
* @internal Supplied by framework wrappers so stega stripping waits until
|
|
72
|
+
* the framework has hydrated the text it would change.
|
|
73
|
+
*/
|
|
74
|
+
isHydrated?: (node: Text) => boolean;
|
|
68
75
|
}
|
|
69
76
|
interface PreprPreviewController {
|
|
70
77
|
destroy(): void;
|
|
@@ -137,73 +144,14 @@ declare class PreprToolbarElement extends HTMLElementBase {
|
|
|
137
144
|
/** Idempotent, including across bundles that each try to define the element. */
|
|
138
145
|
declare function definePreprToolbar(): void;
|
|
139
146
|
|
|
140
|
-
/** Which field the editor asked the preview to bring on screen. */
|
|
141
|
-
interface ScrollToFieldMessage {
|
|
142
|
-
field: string;
|
|
143
|
-
id?: string;
|
|
144
|
-
}
|
|
145
147
|
interface IframeBridgeOptions {
|
|
146
148
|
/**
|
|
147
149
|
* Replace the `*.prepr.io` wildcard with an exact origin list. Intended for
|
|
148
|
-
* self-hosted editors; when set, the wildcard no longer applies.
|
|
149
|
-
* accepts any editor origin — see `PreprPreviewOptions.allowedEditorOrigins`.
|
|
150
|
+
* self-hosted editors; when set, the wildcard no longer applies.
|
|
150
151
|
*/
|
|
151
152
|
allowedEditorOrigins?: string[];
|
|
152
|
-
/**
|
|
153
|
-
* Called when the editor selects a field and wants the preview to scroll to
|
|
154
|
-
* it. Only fires for messages from the handshaked editor origin. The bridge
|
|
155
|
-
* stays free of DOM lookups: the preview runtime supplies `scrollToField`.
|
|
156
|
-
*/
|
|
157
|
-
onScrollToField?: (message: ScrollToFieldMessage) => void;
|
|
158
153
|
}
|
|
159
154
|
|
|
160
|
-
/** Error thrown by the token helpers and the segments fetch. */
|
|
161
|
-
declare class PreprError extends Error {
|
|
162
|
-
readonly code: PreprErrorCode;
|
|
163
|
-
readonly context?: string | undefined;
|
|
164
|
-
readonly originalError?: Error | undefined;
|
|
165
|
-
constructor(message: string, code: PreprErrorCode, context?: string | undefined, originalError?: Error | undefined);
|
|
166
|
-
}
|
|
167
|
-
/** Prepr Customer ID, or null if the middleware did not run for this request. */
|
|
168
|
-
declare function getPreprUUIDFromHeaders(headers: Headers): string | null;
|
|
169
|
-
/** Active segment ID, or null when no segment is selected. */
|
|
170
|
-
declare function getActiveSegmentFromHeaders(headers: Headers): string | null;
|
|
171
|
-
/** Active A/B variant (`'A'`/`'B'`), or null when no test is running. */
|
|
172
|
-
declare function getActiveVariantFromHeaders(headers: Headers): string | null;
|
|
173
|
-
/**
|
|
174
|
-
* Collect the Prepr headers into a `PreprHeaders`. Lookups are case-insensitive
|
|
175
|
-
* per the Fetch spec, but the returned keys use the declared casing.
|
|
176
|
-
*/
|
|
177
|
-
declare function getPreprHeadersFromHeaders(headers: Headers): PreprHeaders;
|
|
178
|
-
/**
|
|
179
|
-
* Asserts `token` is the full `https://graphql.prepr.io/<token>` URL.
|
|
180
|
-
* @throws PreprError if the token is missing or not an HTTPS URL.
|
|
181
|
-
*/
|
|
182
|
-
declare function validatePreprToken(token: string): void;
|
|
183
|
-
/**
|
|
184
|
-
* Pulls the access token out of a GraphQL URL: `https://graphql.prepr.io/abc123`
|
|
185
|
-
* -> `abc123`.
|
|
186
|
-
* @throws PreprError if the URL is not a valid `graphql.prepr.io` URL.
|
|
187
|
-
*/
|
|
188
|
-
declare function extractAccessToken(graphqlUrl: string): string;
|
|
189
|
-
/**
|
|
190
|
-
* Fetches the environment's segments from the Prepr API.
|
|
191
|
-
*
|
|
192
|
-
* `token` must be a Prepr GraphQL URL with scope 'segments'.
|
|
193
|
-
* @throws PreprError if the token is invalid or the request fails.
|
|
194
|
-
*/
|
|
195
|
-
declare function getPreprEnvironmentSegments(token: string): Promise<PreprSegment[]>;
|
|
196
|
-
/**
|
|
197
|
-
* Never throws: a failed segments fetch yields an empty list so the toolbar
|
|
198
|
-
* still renders. The list is returned under both `segments` and the deprecated
|
|
199
|
-
* `data` alias.
|
|
200
|
-
*
|
|
201
|
-
* Pass the same `features` object you give the toolbar and the middleware: with
|
|
202
|
-
* segments disabled the `_Segments` request is skipped entirely, saving a
|
|
203
|
-
* round-trip per page.
|
|
204
|
-
*/
|
|
205
|
-
declare function getToolbarPropsFromHeaders(headers: Headers, token: string, features?: PreprFeatures): Promise<PreprToolbarProps>;
|
|
206
|
-
|
|
207
155
|
interface CookieSpec {
|
|
208
156
|
name: string;
|
|
209
157
|
value: string;
|
|
@@ -242,4 +190,4 @@ interface PreprMiddlewareOptions {
|
|
|
242
190
|
*/
|
|
243
191
|
declare function processPreprRequest(request: Request, opts?: PreprMiddlewareOptions): PreprMiddlewareResult;
|
|
244
192
|
|
|
245
|
-
export { type CookieSpec, type CreatePreprPreviewOptions, type IframeBridgeOptions,
|
|
193
|
+
export { type CookieSpec, type CreatePreprPreviewOptions, type IframeBridgeOptions, PreprFeatures, type PreprMiddlewareOptions, type PreprMiddlewareResult, type PreprNavigationAdapter, type PreprPreviewController, PreprPreviewOptions, PreprSegment, PreprToolbarElement, PreprToolbarProps, PreprVariant, ResolvedPreprFeatures, type ToolbarState, type ToolbarStore, VERSION, createPreprPreview, createToolbarStore, definePreprToolbar, processPreprRequest, resolveFeatures, stegaClean };
|