@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.
Files changed (78) hide show
  1. package/README.md +415 -27
  2. package/dist/astro/chunk-O7N6GPAH.js +173 -0
  3. package/dist/astro/graphql.cjs +1030 -0
  4. package/dist/astro/graphql.d.cts +305 -0
  5. package/dist/astro/graphql.d.ts +305 -0
  6. package/dist/astro/graphql.js +936 -0
  7. package/dist/astro/index-XT_z-RYT.d.cts +130 -0
  8. package/dist/astro/index-XT_z-RYT.d.ts +130 -0
  9. package/dist/astro/index.cjs +14 -1
  10. package/dist/astro/index.d.cts +1 -120
  11. package/dist/astro/index.d.ts +1 -120
  12. package/dist/astro/index.js +15 -153
  13. package/dist/chunk-3JLWZQ37.js +179 -0
  14. package/dist/chunk-3NCEVJJ3.js +10 -0
  15. package/dist/chunk-S5RWVMDJ.js +148 -0
  16. package/dist/chunk-TBKSBXGH.js +452 -0
  17. package/dist/{chunk-FLPNN3CV.js → chunk-VI6QZTBM.js} +73 -276
  18. package/dist/chunk-YWIKKWBR.js +26 -0
  19. package/dist/graphql/codegen.cjs +510 -0
  20. package/dist/graphql/codegen.d.cts +23 -0
  21. package/dist/graphql/codegen.d.ts +23 -0
  22. package/dist/graphql/codegen.js +99 -0
  23. package/dist/graphql.cjs +941 -0
  24. package/dist/graphql.d.cts +305 -0
  25. package/dist/graphql.d.ts +305 -0
  26. package/dist/graphql.js +419 -0
  27. package/dist/index.cjs +76 -119
  28. package/dist/index.d.cts +12 -64
  29. package/dist/index.d.ts +12 -64
  30. package/dist/index.js +27 -167
  31. package/dist/nextjs/chunk-BQ6IGSH6.js +231 -0
  32. package/dist/nextjs/components.cjs +190 -122
  33. package/dist/nextjs/components.d.cts +33 -2
  34. package/dist/nextjs/components.d.ts +33 -2
  35. package/dist/nextjs/components.js +133 -4
  36. package/dist/nextjs/graphql.cjs +1362 -0
  37. package/dist/nextjs/graphql.d.cts +435 -0
  38. package/dist/nextjs/graphql.d.ts +435 -0
  39. package/dist/nextjs/graphql.js +1261 -0
  40. package/dist/nextjs/index.cjs +126 -6
  41. package/dist/nextjs/index.d.cts +53 -147
  42. package/dist/nextjs/index.d.ts +53 -147
  43. package/dist/nextjs/index.js +113 -203
  44. package/dist/nextjs/server-CjpELYvq.d.cts +156 -0
  45. package/dist/nextjs/server-CjpELYvq.d.ts +156 -0
  46. package/dist/nuxt/chunk-IQDSBPDN.js +417 -0
  47. package/dist/nuxt/graphql.cjs +1037 -0
  48. package/dist/nuxt/graphql.d.cts +302 -0
  49. package/dist/nuxt/graphql.d.ts +302 -0
  50. package/dist/nuxt/graphql.js +937 -0
  51. package/dist/nuxt/index.cjs +14 -1
  52. package/dist/nuxt/index.d.cts +3 -148
  53. package/dist/nuxt/index.d.ts +3 -148
  54. package/dist/nuxt/index.js +15 -391
  55. package/dist/nuxt/server-8v6OHbsw.d.cts +158 -0
  56. package/dist/nuxt/server-8v6OHbsw.d.ts +158 -0
  57. package/dist/pixel-DwW7cXJm.d.cts +49 -0
  58. package/dist/pixel-DwW7cXJm.d.ts +49 -0
  59. package/dist/react/components.cjs +88 -120
  60. package/dist/react/components.d.cts +2 -8
  61. package/dist/react/components.d.ts +2 -8
  62. package/dist/react/components.js +88 -120
  63. package/dist/server-Brr1UgtW.d.ts +59 -0
  64. package/dist/server-DJuS3YU0.d.cts +59 -0
  65. package/dist/sveltekit/chunk-OKYZ6HPH.js +413 -0
  66. package/dist/sveltekit/graphql.cjs +1043 -0
  67. package/dist/sveltekit/graphql.d.cts +307 -0
  68. package/dist/sveltekit/graphql.d.ts +307 -0
  69. package/dist/sveltekit/graphql.js +943 -0
  70. package/dist/sveltekit/index.cjs +14 -1
  71. package/dist/sveltekit/index.d.cts +3 -88
  72. package/dist/sveltekit/index.d.ts +3 -88
  73. package/dist/sveltekit/index.js +15 -387
  74. package/dist/sveltekit/server-CO847mEV.d.cts +98 -0
  75. package/dist/sveltekit/server-CO847mEV.d.ts +98 -0
  76. package/dist/{pixel-B3oQNbZ3.d.cts → types-BYH9XqmN.d.cts} +4 -58
  77. package/dist/{pixel-B3oQNbZ3.d.ts → types-BYH9XqmN.d.ts} +4 -58
  78. package/package.json +36 -1
@@ -1,161 +1,17 @@
1
- // src/version.ts
2
- var VERSION = "0.5.0-rc.2";
3
-
4
- // src/core/features.ts
5
- function isEnabled(config) {
6
- if (typeof config === "boolean") return config;
7
- return config?.enabled ?? true;
8
- }
9
- function resolveFeatures(features) {
10
- return {
11
- segments: isEnabled(features?.segments),
12
- abTesting: isEnabled(features?.abTesting),
13
- editMode: isEnabled(features?.editMode)
14
- };
15
- }
16
- var ALL_FEATURES_ENABLED = Object.freeze({
17
- segments: true,
18
- abTesting: true,
19
- editMode: true
20
- });
21
-
22
- // src/core/stega/clean.ts
23
- import { vercelStegaClean, vercelStegaDecode } from "@vercel/stega";
24
-
25
- // src/core/utils.ts
26
- var trustedParentOrigin = null;
27
- function setTrustedParentOrigin(origin) {
28
- trustedParentOrigin = origin;
29
- }
30
- function sendPreprEvent(event, data, options) {
31
- if (typeof window !== "undefined") {
32
- const message = {
33
- name: "prepr_preview_bar",
34
- event,
35
- ...data
36
- };
37
- window.dispatchEvent(
38
- new CustomEvent("prepr_preview_bar", { detail: message })
39
- );
40
- if (window.parent && window.parent !== window) {
41
- if (trustedParentOrigin) {
42
- window.parent.postMessage(message, trustedParentOrigin);
43
- } else if (options?.allowUntrustedTarget) {
44
- window.parent.postMessage(message, "*");
45
- }
46
- }
47
- }
48
- }
49
- var DebugLogger = class {
50
- constructor(options) {
51
- this.options = {
52
- prefix: "[Prepr]",
53
- ...options
54
- };
55
- }
56
- // A local `enabled` wins; otherwise defer to the global logger so scoped
57
- // loggers created before initDebugLogger() still pick up the setting.
58
- isEnabled() {
59
- if (this.options.enabled !== void 0) {
60
- return this.options.enabled;
61
- }
62
- return globalDebugLogger?.options?.enabled ?? false;
63
- }
64
- log(message, ...args) {
65
- if (!this.isEnabled()) return;
66
- const prefix = this.options.prefix;
67
- console.log(`${prefix} ${message}`, ...args);
68
- }
69
- warn(message, ...args) {
70
- if (!this.isEnabled()) return;
71
- const prefix = this.options.prefix;
72
- console.warn(`${prefix} ${message}`, ...args);
73
- }
74
- error(message, ...args) {
75
- if (!this.isEnabled()) return;
76
- const prefix = this.options.prefix;
77
- console.error(`${prefix} ${message}`, ...args);
78
- }
79
- };
80
- var globalDebugLogger = null;
81
- function initDebugLogger(enabled = false) {
82
- globalDebugLogger = new DebugLogger({ enabled });
83
- }
84
- function createScopedLogger(scopeName) {
85
- return new DebugLogger({
86
- prefix: `[Prepr][${scopeName}]`
87
- });
88
- }
89
- function throttle(func, delay) {
90
- let timeoutId = null;
91
- let lastExecTime = 0;
92
- const throttledFunc = ((...args) => {
93
- const currentTime = Date.now();
94
- const timeSinceLastExec = currentTime - lastExecTime;
95
- if (timeSinceLastExec >= delay) {
96
- func(...args);
97
- lastExecTime = currentTime;
98
- } else {
99
- if (timeoutId) {
100
- clearTimeout(timeoutId);
101
- }
102
- timeoutId = setTimeout(() => {
103
- func(...args);
104
- lastExecTime = Date.now();
105
- timeoutId = null;
106
- }, delay - timeSinceLastExec);
107
- }
108
- });
109
- throttledFunc.cancel = () => {
110
- if (timeoutId) {
111
- clearTimeout(timeoutId);
112
- timeoutId = null;
113
- }
114
- };
115
- return throttledFunc;
116
- }
117
- function createElementCache(query, ttl = 1e3) {
118
- let cache = null;
119
- let lastCacheTime = 0;
120
- return () => {
121
- const now = Date.now();
122
- if (!cache || now - lastCacheTime > ttl) {
123
- cache = document.querySelectorAll(query);
124
- lastCacheTime = now;
125
- }
126
- return cache;
127
- };
128
- }
129
-
130
- // src/core/stega/clean.ts
131
- var debug = createScopedLogger("stega:clean");
132
- function stegaClean(text) {
133
- if (!text) return text;
134
- return vercelStegaClean(text);
135
- }
136
- function decodeStega(str) {
137
- if (!str) return null;
138
- try {
139
- const decoded = vercelStegaDecode(str);
140
- if (decoded?.href) {
141
- return decoded;
142
- }
143
- } catch (error) {
144
- debug.log("error decoding stega data", error);
145
- const match = str.match(/{"origin.*?}/);
146
- if (match) {
147
- try {
148
- const decodedMatch = vercelStegaDecode(match[0]);
149
- if (decodedMatch?.href) {
150
- return decodedMatch;
151
- }
152
- } catch (innerError) {
153
- debug.log("error decoding stega regex match", innerError);
154
- }
155
- }
156
- }
157
- return null;
158
- }
1
+ import {
2
+ createElementCache,
3
+ createScopedLogger,
4
+ decodeStega,
5
+ initDebugLogger,
6
+ sendPreprEvent,
7
+ setTrustedParentOrigin,
8
+ throttle
9
+ } from "./chunk-S5RWVMDJ.js";
10
+ import {
11
+ ALL_FEATURES_ENABLED,
12
+ VERSION,
13
+ resolveFeatures
14
+ } from "./chunk-YWIKKWBR.js";
159
15
 
160
16
  // src/core/stega/dom.ts
161
17
  var IGNORED_ANCESTORS = "script, style, noscript";
@@ -186,37 +42,14 @@ function isRenderedElement(element) {
186
42
  if (!style) return true;
187
43
  return style.visibility !== "hidden" && style.display !== "none";
188
44
  }
189
- function parseEditHref(href) {
190
- try {
191
- const url = new URL(href, window.location.origin);
192
- return {
193
- id: url.pathname.split("/").pop() || void 0,
194
- field: url.searchParams.get("field") || void 0,
195
- locale: url.searchParams.get("locale") || void 0
196
- };
197
- } catch {
198
- return {};
199
- }
200
- }
201
- function setOrRemove(element, name, value) {
202
- if (value) {
203
- element.setAttribute(name, value);
204
- } else {
205
- element.removeAttribute(name);
206
- }
207
- }
208
45
  function tagEncodedElement(element, decoded) {
209
46
  element.setAttribute("data-prepr-encoded", "");
210
47
  element.setAttribute("data-prepr-href", decoded.href);
211
48
  element.setAttribute("data-prepr-origin", decoded.origin);
212
- const { id, field, locale } = parseEditHref(decoded.href);
213
- setOrRemove(element, "data-prepr-id", id);
214
- setOrRemove(element, "data-prepr-field", field);
215
- setOrRemove(element, "data-prepr-locale", locale);
216
49
  }
217
50
 
218
51
  // src/core/stega/elements.ts
219
- var debug2 = createScopedLogger("stega:elements");
52
+ var debug = createScopedLogger("stega:elements");
220
53
  var StegaElements = class {
221
54
  constructor(decode = decodeStega) {
222
55
  this.observer = null;
@@ -261,7 +94,7 @@ var StegaElements = class {
261
94
  walkTextNodes(document.body, (textNode) => {
262
95
  if (this.tagFromTextNode(textNode)) encodedCount++;
263
96
  });
264
- debug2.log("document scan complete, encoded", encodedCount, "elements");
97
+ debug.log("document scan complete, encoded", encodedCount, "elements");
265
98
  this.elements = document.querySelectorAll("[data-prepr-encoded]");
266
99
  }
267
100
  /** `onUpdate` fires after each debounced batch, for refreshing derived state. */
@@ -317,9 +150,6 @@ var StegaElements = class {
317
150
  element.removeAttribute("data-prepr-encoded");
318
151
  element.removeAttribute("data-prepr-href");
319
152
  element.removeAttribute("data-prepr-origin");
320
- element.removeAttribute("data-prepr-id");
321
- element.removeAttribute("data-prepr-field");
322
- element.removeAttribute("data-prepr-locale");
323
153
  element.classList.remove("prepr-overlay-active");
324
154
  });
325
155
  this.elements = void 0;
@@ -327,7 +157,7 @@ var StegaElements = class {
327
157
  };
328
158
 
329
159
  // src/core/stega/overlay.ts
330
- var debug3 = createScopedLogger("stega:overlay");
160
+ var debug2 = createScopedLogger("stega:overlay");
331
161
  var StegaOverlay = class {
332
162
  constructor(onEdit) {
333
163
  this.overlay = null;
@@ -372,8 +202,7 @@ var StegaOverlay = class {
372
202
  const origin = element.getAttribute("data-prepr-origin");
373
203
  const id = element.getAttribute("data-prepr-id") ?? void 0;
374
204
  const field = element.getAttribute("data-prepr-field") ?? void 0;
375
- const locale = element.getAttribute("data-prepr-locale") ?? void 0;
376
- debug3.log("showing overlay", { href, origin });
205
+ debug2.log("showing overlay", { href, origin });
377
206
  const overlay = this.overlay;
378
207
  overlay.style.display = "block";
379
208
  overlay.style.top = `${rect.top + window.scrollY - 2}px`;
@@ -405,7 +234,7 @@ var StegaOverlay = class {
405
234
  tooltip.style.left = `${left}px`;
406
235
  });
407
236
  tooltip.onclick = () => {
408
- this.onEdit({ href, origin, id, field, locale });
237
+ this.onEdit({ href, origin, id, field });
409
238
  };
410
239
  }
411
240
  this.currentElement = element;
@@ -445,7 +274,7 @@ var StegaOverlay = class {
445
274
  };
446
275
 
447
276
  // src/core/stega/proximity.ts
448
- var debug4 = createScopedLogger("stega:proximity");
277
+ var debug3 = createScopedLogger("stega:proximity");
449
278
  var StegaProximity = class {
450
279
  constructor() {
451
280
  this.highlighted = /* @__PURE__ */ new Set();
@@ -480,9 +309,9 @@ var StegaProximity = class {
480
309
  );
481
310
  const nodes = this.getEncodedElements();
482
311
  nodes.forEach((el) => this.observer.observe(el));
483
- debug4.log("observing", nodes.length, "encoded elements");
312
+ debug3.log("observing", nodes.length, "encoded elements");
484
313
  } catch (error) {
485
- debug4.log("error setting up IntersectionObserver", error);
314
+ debug3.log("error setting up IntersectionObserver", error);
486
315
  }
487
316
  }
488
317
  stopObserving() {
@@ -552,7 +381,7 @@ function removeStegaStyles() {
552
381
  }
553
382
 
554
383
  // src/core/stega/scan.ts
555
- var debug5 = createScopedLogger("stega:scan");
384
+ var debug4 = createScopedLogger("stega:scan");
556
385
  var EDITOR_MODE_STYLES = "[data-prepr-encoded]{cursor:pointer}";
557
386
  function createStegaController(opts) {
558
387
  const tooltipEnabled = opts.tooltip ?? true;
@@ -585,13 +414,12 @@ function createStegaController(opts) {
585
414
  href: encoded.getAttribute("data-prepr-href") ?? "",
586
415
  origin: encoded.getAttribute("data-prepr-origin") ?? "",
587
416
  id: encoded.getAttribute("data-prepr-id") ?? void 0,
588
- field: encoded.getAttribute("data-prepr-field") ?? void 0,
589
- locale: encoded.getAttribute("data-prepr-locale") ?? void 0
417
+ field: encoded.getAttribute("data-prepr-field") ?? void 0
590
418
  });
591
419
  };
592
420
  const start = () => {
593
421
  if (initialized) {
594
- debug5.log("already initialized, skipping setup");
422
+ debug4.log("already initialized, skipping setup");
595
423
  return;
596
424
  }
597
425
  if (!tooltipEnabled) {
@@ -601,7 +429,7 @@ function createStegaController(opts) {
601
429
  });
602
430
  document.addEventListener("click", handleClick, { capture: true });
603
431
  initialized = true;
604
- debug5.log("stega controller started (editor mode)");
432
+ debug4.log("stega controller started (editor mode)");
605
433
  return;
606
434
  }
607
435
  injectStegaStyles();
@@ -632,7 +460,7 @@ function createStegaController(opts) {
632
460
  passive: true
633
461
  });
634
462
  initialized = true;
635
- debug5.log("stega controller started");
463
+ debug4.log("stega controller started");
636
464
  };
637
465
  const stop = () => {
638
466
  if (!initialized) return;
@@ -641,7 +469,7 @@ function createStegaController(opts) {
641
469
  elements.cleanup();
642
470
  removeStegaStyles();
643
471
  initialized = false;
644
- debug5.log("stega controller stopped (editor mode)");
472
+ debug4.log("stega controller stopped (editor mode)");
645
473
  return;
646
474
  }
647
475
  if (throttledMouseMove) {
@@ -661,14 +489,15 @@ function createStegaController(opts) {
661
489
  elements.cleanup();
662
490
  removeStegaStyles();
663
491
  initialized = false;
664
- debug5.log("stega controller stopped");
492
+ debug4.log("stega controller stopped");
665
493
  };
666
494
  return { start, stop };
667
495
  }
668
496
 
669
497
  // src/core/stega/auto-clean.ts
670
498
  import { vercelStegaSplit } from "@vercel/stega";
671
- var debug6 = createScopedLogger("stega:auto-clean");
499
+ var debug5 = createScopedLogger("stega:auto-clean");
500
+ var HYDRATION_RETRY_MS = 100;
672
501
  function createStegaAutoClean(options) {
673
502
  const stripText = options?.enabled ?? true;
674
503
  let observer = null;
@@ -677,8 +506,29 @@ function createStegaAutoClean(options) {
677
506
  let pendingHidden = /* @__PURE__ */ new Set();
678
507
  let pendingDirty = /* @__PURE__ */ new Set();
679
508
  let debounceTimeout = null;
509
+ const isHydrated = options?.isHydrated;
510
+ let pendingHydration = /* @__PURE__ */ new Set();
511
+ let hydrationTimeout = null;
512
+ function retryPendingHydration() {
513
+ hydrationTimeout = null;
514
+ processing = true;
515
+ const batch = [...pendingHydration];
516
+ pendingHydration.clear();
517
+ batch.forEach((textNode) => {
518
+ if (textNode.isConnected) cleanTextNode(textNode);
519
+ });
520
+ processing = false;
521
+ }
680
522
  function cleanTextNode(textNode) {
681
523
  if (isIgnoredTextNode(textNode)) return false;
524
+ if (isHydrated && !isHydrated(textNode)) {
525
+ pendingHydration.add(textNode);
526
+ hydrationTimeout ?? (hydrationTimeout = setTimeout(
527
+ retryPendingHydration,
528
+ HYDRATION_RETRY_MS
529
+ ));
530
+ return false;
531
+ }
682
532
  const textContent = textNode.textContent;
683
533
  const info = cleaned.get(textNode);
684
534
  const settled = stripText ? info?.cleaned : info?.original;
@@ -711,7 +561,7 @@ function createStegaAutoClean(options) {
711
561
  }
712
562
  pendingHidden.add(textNode);
713
563
  } catch (error) {
714
- debug6.log("error cleaning text node", error);
564
+ debug5.log("error cleaning text node", error);
715
565
  }
716
566
  return false;
717
567
  }
@@ -797,13 +647,17 @@ function createStegaAutoClean(options) {
797
647
  if (observer || typeof window === "undefined") return;
798
648
  scanAndClean();
799
649
  setupObserver();
800
- debug6.log("stega auto-clean started");
650
+ debug5.log("stega auto-clean started");
801
651
  }
802
652
  function stop() {
803
653
  if (debounceTimeout) {
804
654
  clearTimeout(debounceTimeout);
805
655
  debounceTimeout = null;
806
656
  }
657
+ if (hydrationTimeout) {
658
+ clearTimeout(hydrationTimeout);
659
+ hydrationTimeout = null;
660
+ }
807
661
  if (observer) {
808
662
  observer.disconnect();
809
663
  observer = null;
@@ -811,43 +665,12 @@ function createStegaAutoClean(options) {
811
665
  cleaned = /* @__PURE__ */ new WeakMap();
812
666
  pendingHidden = /* @__PURE__ */ new Set();
813
667
  pendingDirty = /* @__PURE__ */ new Set();
814
- debug6.log("stega auto-clean stopped");
668
+ pendingHydration = /* @__PURE__ */ new Set();
669
+ debug5.log("stega auto-clean stopped");
815
670
  }
816
671
  return { start, stop };
817
672
  }
818
673
 
819
- // src/core/stega/scroll-to-field.ts
820
- var debug7 = createScopedLogger("stega:scroll");
821
- var FLASH_DURATION_MS = 1200;
822
- var flashTimeout = null;
823
- function scrollToField(request) {
824
- const { field, id } = request;
825
- if (!field) return false;
826
- const candidates = document.querySelectorAll(
827
- "[data-prepr-encoded]"
828
- );
829
- let target = null;
830
- for (const candidate of candidates) {
831
- if (candidate.getAttribute("data-prepr-field") !== field) continue;
832
- if (id && candidate.getAttribute("data-prepr-id") !== id) continue;
833
- target = candidate;
834
- break;
835
- }
836
- if (!target) {
837
- debug7.log("no element found for field", field);
838
- return false;
839
- }
840
- target.scrollIntoView({ behavior: "smooth", block: "center" });
841
- if (flashTimeout) clearTimeout(flashTimeout);
842
- document.querySelectorAll(".prepr-overlay-active").forEach((el) => el.classList.remove("prepr-overlay-active"));
843
- target.classList.add("prepr-overlay-active");
844
- flashTimeout = setTimeout(() => {
845
- target.classList.remove("prepr-overlay-active");
846
- flashTimeout = null;
847
- }, FLASH_DURATION_MS);
848
- return true;
849
- }
850
-
851
674
  // src/core/store.ts
852
675
  var DEFAULT_STATE = {
853
676
  locale: "en",
@@ -2004,13 +1827,9 @@ function t2(key, locale, vars) {
2004
1827
  }
2005
1828
 
2006
1829
  // src/core/iframe-bridge.ts
2007
- var debug8 = createScopedLogger("iframe-bridge");
2008
1830
  var EDITOR_BASE_DOMAIN = "prepr.io";
2009
1831
  function isAllowedEditorOrigin(origin, allowed) {
2010
- if (allowed) {
2011
- if (allowed.includes("*")) return origin !== "null";
2012
- return allowed.includes(origin);
2013
- }
1832
+ if (allowed) return allowed.includes(origin);
2014
1833
  let url;
2015
1834
  try {
2016
1835
  url = new URL(origin);
@@ -2025,7 +1844,6 @@ function isAllowedEditorOrigin(origin, allowed) {
2025
1844
  }
2026
1845
  function createIframeBridge(store, options = {}) {
2027
1846
  const allowedOrigins = options.allowedEditorOrigins;
2028
- const onScrollToField = options.onScrollToField;
2029
1847
  let parentOrigin = null;
2030
1848
  const onKeyDown = (event) => {
2031
1849
  const key = event.key.toLowerCase();
@@ -2035,10 +1853,7 @@ function createIframeBridge(store, options = {}) {
2035
1853
  const onMessage = (evt) => {
2036
1854
  const data = evt?.data;
2037
1855
  if (data?.event === "prepr:initVE" && !parentOrigin) {
2038
- if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) {
2039
- debug8.warn("ignored editor handshake from origin", evt.origin);
2040
- return;
2041
- }
1856
+ if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) return;
2042
1857
  parentOrigin = evt.origin;
2043
1858
  setTrustedParentOrigin(parentOrigin);
2044
1859
  if (data.scrollPosition != null) {
@@ -2052,15 +1867,6 @@ function createIframeBridge(store, options = {}) {
2052
1867
  const currentScrollY = window.scrollY || document.documentElement.scrollTop;
2053
1868
  sendPreprEvent("getScrollPosition", { value: currentScrollY });
2054
1869
  }
2055
- if (data?.event === "prepr:scrollToField") {
2056
- if (typeof data.field !== "string" || !data.field) return;
2057
- if (data.id !== void 0 && typeof data.id !== "string") return;
2058
- try {
2059
- onScrollToField?.({ field: data.field, id: data.id });
2060
- } catch (error) {
2061
- debug8.warn("scrollToField handler failed", error);
2062
- }
2063
- }
2064
1870
  };
2065
1871
  return {
2066
1872
  start() {
@@ -2179,7 +1985,7 @@ function splitPath(full) {
2179
1985
  }
2180
1986
 
2181
1987
  // src/core/create-preview.ts
2182
- var debug9 = createScopedLogger("create-preview");
1988
+ var debug6 = createScopedLogger("create-preview");
2183
1989
  var controllerStores = /* @__PURE__ */ new WeakMap();
2184
1990
  function defaultNavigation() {
2185
1991
  return {
@@ -2221,7 +2027,7 @@ function createPreprPreview(opts = {}) {
2221
2027
  const search = new URLSearchParams(window.location.search);
2222
2028
  const hideBar = search.get(PARAM_HIDE_BAR) === "true";
2223
2029
  if (hideBar) {
2224
- debug9.log(`${PARAM_HIDE_BAR}=true \u2014 no visible toolbar`);
2030
+ debug6.log(`${PARAM_HIDE_BAR}=true \u2014 no visible toolbar`);
2225
2031
  }
2226
2032
  const mountUi = (options?.ui ?? true) && !isIframe && !hideBar;
2227
2033
  const locale = resolveLocale(options);
@@ -2257,17 +2063,18 @@ function createPreprPreview(opts = {}) {
2257
2063
  tooltip: mountUi,
2258
2064
  // In the editor, ask the parent to focus the field instead of opening a new
2259
2065
  // tab. Standalone previews keep the window.open behaviour.
2260
- onEdit: ({ href, id, field, locale: contentLocale }) => {
2066
+ onEdit: ({ href, origin, id, field }) => {
2261
2067
  const safeHref = href ? safeEditUrl(href) : null;
2262
2068
  if (href && !safeHref) {
2263
- debug9.warn("ignored edit request with unsupported href scheme");
2069
+ debug6.warn("ignored edit request with unsupported href scheme");
2264
2070
  return;
2265
2071
  }
2266
2072
  if (isIframe) {
2267
2073
  sendPreprEvent("field_edit_requested", {
2074
+ href: safeHref ?? void 0,
2075
+ origin,
2268
2076
  id,
2269
- field,
2270
- locale: contentLocale
2077
+ field
2271
2078
  });
2272
2079
  } else if (safeHref) {
2273
2080
  window.open(safeHref, "_blank", "noopener,noreferrer");
@@ -2275,7 +2082,8 @@ function createPreprPreview(opts = {}) {
2275
2082
  }
2276
2083
  });
2277
2084
  const autoClean = createStegaAutoClean({
2278
- enabled: options?.autoClean
2085
+ enabled: options?.autoClean,
2086
+ isHydrated: opts.isHydrated
2279
2087
  });
2280
2088
  autoClean.start();
2281
2089
  const handleChange = createChangeHandler({
@@ -2294,15 +2102,7 @@ function createPreprPreview(opts = {}) {
2294
2102
  handleChange(before, state);
2295
2103
  });
2296
2104
  const bridge = createIframeBridge(store, {
2297
- allowedEditorOrigins: options?.allowedEditorOrigins,
2298
- // The editor selecting a field scrolls the matching element into view. The
2299
- // lookup relies on the attributes the stega scan writes, so it finds
2300
- // nothing until encoded content has been tagged.
2301
- onScrollToField: ({ field, id }) => {
2302
- if (!scrollToField({ field, id })) {
2303
- debug9.log("no element on this page renders field", field);
2304
- }
2305
- }
2105
+ allowedEditorOrigins: options?.allowedEditorOrigins
2306
2106
  });
2307
2107
  sendPreprEvent(
2308
2108
  "getScrollPosition",
@@ -2322,7 +2122,7 @@ function createPreprPreview(opts = {}) {
2322
2122
  bridge.stop();
2323
2123
  }
2324
2124
  el?.remove();
2325
- debug9.log("preview destroyed");
2125
+ debug6.log("preview destroyed");
2326
2126
  }
2327
2127
  const controller = { destroy };
2328
2128
  controllerStores.set(controller, store);
@@ -2395,8 +2195,6 @@ function setTrackingParam(key, value) {
2395
2195
  }
2396
2196
 
2397
2197
  export {
2398
- VERSION,
2399
- resolveFeatures,
2400
2198
  COOKIE_PREVIEW_MODE,
2401
2199
  COOKIE_SEGMENT,
2402
2200
  COOKIE_VARIANT,
@@ -2406,7 +2204,6 @@ export {
2406
2204
  PARAM_VARIANT,
2407
2205
  PARAM_HIDE_BAR,
2408
2206
  ONE_YEAR_SECONDS,
2409
- stegaClean,
2410
2207
  createToolbarStore,
2411
2208
  PreprToolbarElement,
2412
2209
  definePreprToolbar,
@@ -0,0 +1,26 @@
1
+ // src/version.ts
2
+ var VERSION = "0.6.0-alpha.1";
3
+
4
+ // src/core/features.ts
5
+ function isEnabled(config) {
6
+ if (typeof config === "boolean") return config;
7
+ return config?.enabled ?? true;
8
+ }
9
+ function resolveFeatures(features) {
10
+ return {
11
+ segments: isEnabled(features?.segments),
12
+ abTesting: isEnabled(features?.abTesting),
13
+ editMode: isEnabled(features?.editMode)
14
+ };
15
+ }
16
+ var ALL_FEATURES_ENABLED = Object.freeze({
17
+ segments: true,
18
+ abTesting: true,
19
+ editMode: true
20
+ });
21
+
22
+ export {
23
+ VERSION,
24
+ resolveFeatures,
25
+ ALL_FEATURES_ENABLED
26
+ };