@preprio/toolkit 0.5.0-rc.5 → 0.5.1-dom.0

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 (53) hide show
  1. package/README.md +218 -226
  2. package/dist/astro/index.cjs +1 -1
  3. package/dist/astro/index.js +1 -1
  4. package/dist/auto.cjs +4572 -0
  5. package/dist/auto.d.cts +42 -0
  6. package/dist/auto.d.ts +42 -0
  7. package/dist/auto.js +105 -0
  8. package/dist/browser/auto.js +117 -0
  9. package/dist/chunk-5I5TQ3NO.js +74 -0
  10. package/dist/chunk-AZC4BZJI.js +447 -0
  11. package/dist/{chunk-TG6N3C22.js → chunk-IKOOXTPM.js} +1 -1
  12. package/dist/{chunk-3X55JL52.js → chunk-IOSO232M.js} +4 -2
  13. package/dist/{chunk-SBLZANL5.js → chunk-RRM5762S.js} +2 -71
  14. package/dist/chunk-SZTHSJUA.js +326 -0
  15. package/dist/{chunk-CMUFTCG3.js → chunk-TEB7M7EM.js} +0 -4
  16. package/dist/chunk-UK664KSV.js +6 -0
  17. package/dist/{chunk-74KY5EAM.js → chunk-ZFGVP2GW.js} +28 -447
  18. package/dist/html-live-DzmEG9wU.d.cts +42 -0
  19. package/dist/html-live-DzmEG9wU.d.ts +42 -0
  20. package/dist/index.cjs +177 -2
  21. package/dist/index.d.cts +31 -28
  22. package/dist/index.d.ts +31 -28
  23. package/dist/index.js +21 -154
  24. package/dist/{live-preview-H4643QYF.js → live-preview-IYAS7PYV.js} +3 -2
  25. package/dist/nextjs/components.cjs +1 -1
  26. package/dist/nextjs/components.d.cts +2 -1
  27. package/dist/nextjs/components.d.ts +2 -1
  28. package/dist/nextjs/components.js +6 -3
  29. package/dist/nextjs/index.cjs +1 -1
  30. package/dist/nextjs/index.d.cts +0 -2
  31. package/dist/nextjs/index.d.ts +0 -2
  32. package/dist/nextjs/index.js +1 -1
  33. package/dist/nextjs/live-action.js +5 -3
  34. package/dist/nextjs/live.cjs +1 -4
  35. package/dist/nextjs/live.d.cts +1 -3
  36. package/dist/nextjs/live.d.ts +1 -3
  37. package/dist/nextjs/live.js +2 -5
  38. package/dist/nuxt/index.cjs +1 -1
  39. package/dist/nuxt/index.js +1 -1
  40. package/dist/pixel-DwW7cXJm.d.cts +49 -0
  41. package/dist/pixel-DwW7cXJm.d.ts +49 -0
  42. package/dist/react/components.cjs +1 -1
  43. package/dist/react/components.js +1 -1
  44. package/dist/sveltekit/index.cjs +1 -1
  45. package/dist/sveltekit/index.js +1 -1
  46. package/dist/{pixel-CX422dCO.d.cts → types-DtMa_-f2.d.cts} +1 -49
  47. package/dist/{pixel-CX422dCO.d.ts → types-DtMa_-f2.d.ts} +1 -49
  48. package/package.json +12 -7
  49. package/dist/sveltekit/live-preview-O2ZTJNW4.js +0 -1520
  50. package/dist/sveltekit/live.cjs +0 -1731
  51. package/dist/sveltekit/live.d.cts +0 -59
  52. package/dist/sveltekit/live.d.ts +0 -59
  53. package/dist/sveltekit/live.js +0 -97
package/dist/index.cjs CHANGED
@@ -23,6 +23,7 @@ __export(src_exports, {
23
23
  PreprError: () => PreprError,
24
24
  PreprToolbarElement: () => PreprToolbarElement,
25
25
  VERSION: () => VERSION,
26
+ applyPatchLogToDom: () => applyPatchLogToDom,
26
27
  createPreprPreview: () => createPreprPreview,
27
28
  createToolbarStore: () => createToolbarStore,
28
29
  definePreprToolbar: () => definePreprToolbar,
@@ -49,7 +50,7 @@ __export(src_exports, {
49
50
  module.exports = __toCommonJS(src_exports);
50
51
 
51
52
  // src/version.ts
52
- var VERSION = "0.5.0-rc.5";
53
+ var VERSION = "0.5.1-dom.0";
53
54
 
54
55
  // src/core/features.ts
55
56
  function isEnabled(config) {
@@ -4817,6 +4818,173 @@ function createLiveBridge(store, options = {}) {
4817
4818
  };
4818
4819
  }
4819
4820
 
4821
+ // src/core/live-preview/dom-patch.ts
4822
+ var INDEX_SEGMENT4 = /^\d+$/;
4823
+ var LIVE_ATTRIBUTE = "data-prepr-live";
4824
+ function fieldKey(path) {
4825
+ return path.split(".").filter((segment) => segment && segment !== "items").map(
4826
+ (segment) => INDEX_SEGMENT4.test(segment) ? String(Number.parseInt(segment, 10)) : segment
4827
+ ).join(".");
4828
+ }
4829
+ function patchTargets(patch) {
4830
+ if (patch.type !== "field") return [];
4831
+ const targets = [{ item: patch.itemId, field: patch.field }];
4832
+ if (patch.edit) targets.unshift(patch.edit);
4833
+ return targets;
4834
+ }
4835
+ function matchingElements(candidates, item, field) {
4836
+ const wanted = fieldKey(field);
4837
+ return candidates.filter((element) => {
4838
+ if (element.getAttribute("data-prepr-id") !== item) return false;
4839
+ const tagged = element.getAttribute("data-prepr-field");
4840
+ return tagged !== null && fieldKey(tagged) === wanted;
4841
+ });
4842
+ }
4843
+ var DROPPED_ELEMENTS = /* @__PURE__ */ new Set([
4844
+ "SCRIPT",
4845
+ "STYLE",
4846
+ "IFRAME",
4847
+ "OBJECT",
4848
+ "EMBED",
4849
+ "TEMPLATE",
4850
+ "NOSCRIPT",
4851
+ "SVG",
4852
+ "MATH",
4853
+ "LINK",
4854
+ "META",
4855
+ "BASE",
4856
+ "FORM",
4857
+ "INPUT",
4858
+ "BUTTON",
4859
+ "TEXTAREA",
4860
+ "SELECT"
4861
+ ]);
4862
+ var ALLOWED_ELEMENTS = /* @__PURE__ */ new Set([
4863
+ "A",
4864
+ "ABBR",
4865
+ "B",
4866
+ "BLOCKQUOTE",
4867
+ "BR",
4868
+ "CODE",
4869
+ "DEL",
4870
+ "DIV",
4871
+ "EM",
4872
+ "H1",
4873
+ "H2",
4874
+ "H3",
4875
+ "H4",
4876
+ "H5",
4877
+ "H6",
4878
+ "HR",
4879
+ "I",
4880
+ "INS",
4881
+ "LI",
4882
+ "MARK",
4883
+ "OL",
4884
+ "P",
4885
+ "PRE",
4886
+ "S",
4887
+ "SMALL",
4888
+ "SPAN",
4889
+ "STRONG",
4890
+ "SUB",
4891
+ "SUP",
4892
+ "TABLE",
4893
+ "TBODY",
4894
+ "TD",
4895
+ "TH",
4896
+ "THEAD",
4897
+ "TR",
4898
+ "U",
4899
+ "UL"
4900
+ ]);
4901
+ var SAFE_HREF = /^(?:https?:|mailto:|tel:|\/|#|\.{0,2}\/|[^:]*$)/i;
4902
+ function sanitizeRichText(html) {
4903
+ const template = document.createElement("template");
4904
+ template.innerHTML = html;
4905
+ const out = document.createDocumentFragment();
4906
+ const copy = (source, target) => {
4907
+ for (const child of Array.from(source.childNodes)) {
4908
+ if (child.nodeType === Node.TEXT_NODE) {
4909
+ target.appendChild(document.createTextNode(child.textContent ?? ""));
4910
+ continue;
4911
+ }
4912
+ if (child.nodeType !== Node.ELEMENT_NODE) continue;
4913
+ const element = child;
4914
+ const tag = element.tagName.toUpperCase();
4915
+ if (DROPPED_ELEMENTS.has(tag)) continue;
4916
+ if (!ALLOWED_ELEMENTS.has(tag)) {
4917
+ copy(element, target);
4918
+ continue;
4919
+ }
4920
+ const clean = document.createElement(tag.toLowerCase());
4921
+ if (tag === "A") {
4922
+ const href = element.getAttribute("href")?.trim();
4923
+ if (href && SAFE_HREF.test(href.replace(/[\t\n\r]/g, ""))) {
4924
+ clean.setAttribute("href", href);
4925
+ }
4926
+ if (element.getAttribute("target") === "_blank") {
4927
+ clean.setAttribute("target", "_blank");
4928
+ clean.setAttribute("rel", "noopener noreferrer");
4929
+ }
4930
+ }
4931
+ copy(element, clean);
4932
+ target.appendChild(clean);
4933
+ }
4934
+ };
4935
+ copy(template.content, out);
4936
+ return out;
4937
+ }
4938
+ var RICH_TEXT = /^\s*<[a-z!/]/i;
4939
+ function writeText(element, text) {
4940
+ if (!element.children.length) {
4941
+ if (element.textContent !== text) element.textContent = text;
4942
+ return true;
4943
+ }
4944
+ for (const node of Array.from(element.childNodes)) {
4945
+ const current = node.textContent ?? "";
4946
+ if (node.nodeType !== Node.TEXT_NODE || !current.trim()) continue;
4947
+ const next = current.match(/^\s*/)[0] + text + current.match(/\s*$/)[0];
4948
+ if (current !== next) node.textContent = next;
4949
+ return true;
4950
+ }
4951
+ return false;
4952
+ }
4953
+ function applyPatchLogToDom(log, root = document) {
4954
+ const candidates = Array.from(
4955
+ root.querySelectorAll("[data-prepr-encoded]")
4956
+ );
4957
+ let applied = 0;
4958
+ let skipped = 0;
4959
+ for (const patch of log) {
4960
+ if (patch.type !== "field" || typeof patch.value !== "string") {
4961
+ skipped++;
4962
+ continue;
4963
+ }
4964
+ let elements = [];
4965
+ for (const { item, field } of patchTargets(patch)) {
4966
+ elements = matchingElements(candidates, item, field);
4967
+ if (elements.length) break;
4968
+ }
4969
+ let written = false;
4970
+ for (const element of elements) {
4971
+ const mode = element.closest(`[${LIVE_ATTRIBUTE}]`)?.getAttribute(LIVE_ATTRIBUTE);
4972
+ if (mode === "off") continue;
4973
+ if (mode === "html") {
4974
+ element.replaceChildren(sanitizeRichText(patch.value));
4975
+ written = true;
4976
+ } else if (RICH_TEXT.test(patch.value)) {
4977
+ continue;
4978
+ } else if (writeText(element, patch.value)) {
4979
+ written = true;
4980
+ }
4981
+ }
4982
+ if (written) applied++;
4983
+ else skipped++;
4984
+ }
4985
+ return { applied, skipped };
4986
+ }
4987
+
4820
4988
  // src/core/live-preview/live-store.ts
4821
4989
  var debug13 = createScopedLogger("live-preview");
4822
4990
  var INVALIDATE_DEBOUNCE_MS = 150;
@@ -5107,8 +5275,14 @@ function startHtmlLivePreview(options = {}) {
5107
5275
  else void render(log);
5108
5276
  }, SYNC_DEBOUNCE_MS);
5109
5277
  };
5278
+ const apply = options.apply ?? "server";
5110
5279
  const offLog = store.onLogChange((log) => {
5111
- if (log.length) schedule(log);
5280
+ if (!log.length) return;
5281
+ if (apply === "server") {
5282
+ schedule(log);
5283
+ return;
5284
+ }
5285
+ applyPatchLogToDom(log);
5112
5286
  });
5113
5287
  const offInvalidate = store.onInvalidate(() => schedule([]));
5114
5288
  return {
@@ -5530,6 +5704,7 @@ function setTrackingParam(key, value) {
5530
5704
  PreprError,
5531
5705
  PreprToolbarElement,
5532
5706
  VERSION,
5707
+ applyPatchLogToDom,
5533
5708
  createPreprPreview,
5534
5709
  createToolbarStore,
5535
5710
  definePreprToolbar,
package/dist/index.d.cts CHANGED
@@ -1,11 +1,13 @@
1
- import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-CX422dCO.cjs';
2
- export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-CX422dCO.cjs';
1
+ import { b as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, c as PreprSegment, d as PreprVariant, P as PreprToolbarProps, a as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './types-DtMa_-f2.cjs';
2
+ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprToolbarComponentProps, l as PreprToolbarOptions } from './types-DtMa_-f2.cjs';
3
+ export { a as HtmlLivePreview, H as HtmlLivePreviewOptions, s as startHtmlLivePreview } from './html-live-DzmEG9wU.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.5.0-rc.5";
10
+ declare const VERSION = "0.5.1-dom.0";
9
11
 
10
12
  /**
11
13
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
@@ -355,30 +357,6 @@ declare function parsePatchLog(raw: unknown): LivePatch[];
355
357
  */
356
358
  declare function normalizeQuery<T>(query: QueryInput, result: T, options?: NormalizeQueryOptions): T;
357
359
 
358
- interface HtmlLivePreviewOptions {
359
- /**
360
- * Replace the `*.prepr.io` editor-origin wildcard with an exact list, as
361
- * the toolbar's option of the same name.
362
- */
363
- allowedEditorOrigins?: string[];
364
- /** See the toolbar's `strictMode`. */
365
- strictMode?: boolean;
366
- }
367
- interface HtmlLivePreview {
368
- stop(): void;
369
- }
370
- /**
371
- * Live preview for server-rendered pages without a client framework (Astro,
372
- * or any HTML-first site): while an editor types, the page is requested
373
- * again from the server with the unsaved changes in the request body, and
374
- * only the parts of the DOM that changed are updated. On save the page is
375
- * requested without changes. The server applies them with `normalizeQuery`;
376
- * see `readLiveLogFromRequest`.
377
- *
378
- * A no-op outside the Prepr editor's preview iframe.
379
- */
380
- declare function startHtmlLivePreview(options?: HtmlLivePreviewOptions): HtmlLivePreview;
381
-
382
360
  /**
383
361
  * The editor's unsaved changes carried by a live-preview re-render request
384
362
  * (sent by `startHtmlLivePreview`), or an empty list for any other request.
@@ -391,6 +369,31 @@ declare function startHtmlLivePreview(options?: HtmlLivePreviewOptions): HtmlLiv
391
369
  */
392
370
  declare function readLiveLogFromRequest(request: Request): Promise<LivePatch[]>;
393
371
 
372
+ interface DomPatchResult {
373
+ /** Changes written to the page. */
374
+ applied: number;
375
+ /**
376
+ * Changes the page could not show: structured values (assets, links),
377
+ * list changes, rich text outside `data-prepr-live="html"`, and text no
378
+ * element on the page renders. They appear when the page is rendered
379
+ * again.
380
+ */
381
+ skipped: number;
382
+ }
383
+ /**
384
+ * Show the editor's unsaved text changes by writing them into the elements
385
+ * whose edit links point at the changed field, with no server round trip.
386
+ *
387
+ * Plain text is written as text. Rich text (HTML) is written only where the
388
+ * element or an ancestor carries `data-prepr-live="html"`, reduced to
389
+ * formatting markup first; elsewhere it waits for save rather than lose its
390
+ * formatting. `data-prepr-live="off"` leaves an element alone, for values the
391
+ * template reformats (dates, truncation) and that should wait for save.
392
+ *
393
+ * Replays the whole log, so applying the same log twice changes nothing.
394
+ */
395
+ declare function applyPatchLogToDom(log: readonly LivePatch[], root?: ParentNode): DomPatchResult;
396
+
394
397
  /** Error thrown by the token helpers and the segments fetch. */
395
398
  declare class PreprError extends Error {
396
399
  readonly code: PreprErrorCode;
@@ -476,4 +479,4 @@ interface PreprMiddlewareOptions {
476
479
  */
477
480
  declare function processPreprRequest(request: Request, opts?: PreprMiddlewareOptions): PreprMiddlewareResult;
478
481
 
479
- export { type CookieSpec, type CreatePreprPreviewOptions, type HtmlLivePreview, type HtmlLivePreviewOptions, type IframeBridgeOptions, type LivePatch, type NormalizeQueryOptions, PreprError, PreprErrorCode, PreprFeatures, PreprHeaders, type PreprMiddlewareOptions, type PreprMiddlewareResult, type PreprNavigationAdapter, type PreprPreviewController, PreprPreviewOptions, PreprSegment, PreprToolbarElement, PreprToolbarProps, PreprVariant, type PreviewAttrsOptions, type PreviewAttrsTarget, type QueryInput, ResolvedPreprFeatures, type ToolbarState, type ToolbarStore, VERSION, createPreprPreview, createToolbarStore, definePreprToolbar, extractAccessToken, getActiveSegmentFromHeaders, getActiveVariantFromHeaders, getPreprEnvironmentSegments, getPreprHeadersFromHeaders, getPreprUUIDFromHeaders, getToolbarPropsFromHeaders, normalizeQuery, parsePatchLog, previewAttrs, processPreprRequest, readLiveLogFromRequest, resolveFeatures, startHtmlLivePreview, stegaClean, validatePreprToken };
482
+ export { type CookieSpec, type CreatePreprPreviewOptions, type DomPatchResult, type IframeBridgeOptions, type LivePatch, type NormalizeQueryOptions, PreprError, PreprErrorCode, PreprFeatures, PreprHeaders, type PreprMiddlewareOptions, type PreprMiddlewareResult, type PreprNavigationAdapter, type PreprPreviewController, PreprPreviewOptions, PreprSegment, PreprToolbarElement, PreprToolbarProps, PreprVariant, type PreviewAttrsOptions, type PreviewAttrsTarget, type QueryInput, ResolvedPreprFeatures, type ToolbarState, type ToolbarStore, VERSION, applyPatchLogToDom, createPreprPreview, createToolbarStore, definePreprToolbar, extractAccessToken, getActiveSegmentFromHeaders, getActiveVariantFromHeaders, getPreprEnvironmentSegments, getPreprHeadersFromHeaders, getPreprUUIDFromHeaders, getToolbarPropsFromHeaders, normalizeQuery, parsePatchLog, previewAttrs, processPreprRequest, readLiveLogFromRequest, resolveFeatures, stegaClean, validatePreprToken };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-CX422dCO.js';
2
- export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-CX422dCO.js';
1
+ import { b as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, c as PreprSegment, d as PreprVariant, P as PreprToolbarProps, a as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './types-DtMa_-f2.js';
2
+ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprToolbarComponentProps, l as PreprToolbarOptions } from './types-DtMa_-f2.js';
3
+ export { a as HtmlLivePreview, H as HtmlLivePreviewOptions, s as startHtmlLivePreview } from './html-live-DzmEG9wU.js';
4
+ export { P as PreprPixelConfig, l as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-DwW7cXJm.js';
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.5.0-rc.5";
10
+ declare const VERSION = "0.5.1-dom.0";
9
11
 
10
12
  /**
11
13
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
@@ -355,30 +357,6 @@ declare function parsePatchLog(raw: unknown): LivePatch[];
355
357
  */
356
358
  declare function normalizeQuery<T>(query: QueryInput, result: T, options?: NormalizeQueryOptions): T;
357
359
 
358
- interface HtmlLivePreviewOptions {
359
- /**
360
- * Replace the `*.prepr.io` editor-origin wildcard with an exact list, as
361
- * the toolbar's option of the same name.
362
- */
363
- allowedEditorOrigins?: string[];
364
- /** See the toolbar's `strictMode`. */
365
- strictMode?: boolean;
366
- }
367
- interface HtmlLivePreview {
368
- stop(): void;
369
- }
370
- /**
371
- * Live preview for server-rendered pages without a client framework (Astro,
372
- * or any HTML-first site): while an editor types, the page is requested
373
- * again from the server with the unsaved changes in the request body, and
374
- * only the parts of the DOM that changed are updated. On save the page is
375
- * requested without changes. The server applies them with `normalizeQuery`;
376
- * see `readLiveLogFromRequest`.
377
- *
378
- * A no-op outside the Prepr editor's preview iframe.
379
- */
380
- declare function startHtmlLivePreview(options?: HtmlLivePreviewOptions): HtmlLivePreview;
381
-
382
360
  /**
383
361
  * The editor's unsaved changes carried by a live-preview re-render request
384
362
  * (sent by `startHtmlLivePreview`), or an empty list for any other request.
@@ -391,6 +369,31 @@ declare function startHtmlLivePreview(options?: HtmlLivePreviewOptions): HtmlLiv
391
369
  */
392
370
  declare function readLiveLogFromRequest(request: Request): Promise<LivePatch[]>;
393
371
 
372
+ interface DomPatchResult {
373
+ /** Changes written to the page. */
374
+ applied: number;
375
+ /**
376
+ * Changes the page could not show: structured values (assets, links),
377
+ * list changes, rich text outside `data-prepr-live="html"`, and text no
378
+ * element on the page renders. They appear when the page is rendered
379
+ * again.
380
+ */
381
+ skipped: number;
382
+ }
383
+ /**
384
+ * Show the editor's unsaved text changes by writing them into the elements
385
+ * whose edit links point at the changed field, with no server round trip.
386
+ *
387
+ * Plain text is written as text. Rich text (HTML) is written only where the
388
+ * element or an ancestor carries `data-prepr-live="html"`, reduced to
389
+ * formatting markup first; elsewhere it waits for save rather than lose its
390
+ * formatting. `data-prepr-live="off"` leaves an element alone, for values the
391
+ * template reformats (dates, truncation) and that should wait for save.
392
+ *
393
+ * Replays the whole log, so applying the same log twice changes nothing.
394
+ */
395
+ declare function applyPatchLogToDom(log: readonly LivePatch[], root?: ParentNode): DomPatchResult;
396
+
394
397
  /** Error thrown by the token helpers and the segments fetch. */
395
398
  declare class PreprError extends Error {
396
399
  readonly code: PreprErrorCode;
@@ -476,4 +479,4 @@ interface PreprMiddlewareOptions {
476
479
  */
477
480
  declare function processPreprRequest(request: Request, opts?: PreprMiddlewareOptions): PreprMiddlewareResult;
478
481
 
479
- export { type CookieSpec, type CreatePreprPreviewOptions, type HtmlLivePreview, type HtmlLivePreviewOptions, type IframeBridgeOptions, type LivePatch, type NormalizeQueryOptions, PreprError, PreprErrorCode, PreprFeatures, PreprHeaders, type PreprMiddlewareOptions, type PreprMiddlewareResult, type PreprNavigationAdapter, type PreprPreviewController, PreprPreviewOptions, PreprSegment, PreprToolbarElement, PreprToolbarProps, PreprVariant, type PreviewAttrsOptions, type PreviewAttrsTarget, type QueryInput, ResolvedPreprFeatures, type ToolbarState, type ToolbarStore, VERSION, createPreprPreview, createToolbarStore, definePreprToolbar, extractAccessToken, getActiveSegmentFromHeaders, getActiveVariantFromHeaders, getPreprEnvironmentSegments, getPreprHeadersFromHeaders, getPreprUUIDFromHeaders, getToolbarPropsFromHeaders, normalizeQuery, parsePatchLog, previewAttrs, processPreprRequest, readLiveLogFromRequest, resolveFeatures, startHtmlLivePreview, stegaClean, validatePreprToken };
482
+ export { type CookieSpec, type CreatePreprPreviewOptions, type DomPatchResult, type IframeBridgeOptions, type LivePatch, type NormalizeQueryOptions, PreprError, PreprErrorCode, PreprFeatures, PreprHeaders, type PreprMiddlewareOptions, type PreprMiddlewareResult, type PreprNavigationAdapter, type PreprPreviewController, PreprPreviewOptions, PreprSegment, PreprToolbarElement, PreprToolbarProps, PreprVariant, type PreviewAttrsOptions, type PreviewAttrsTarget, type QueryInput, ResolvedPreprFeatures, type ToolbarState, type ToolbarStore, VERSION, applyPatchLogToDom, createPreprPreview, createToolbarStore, definePreprToolbar, extractAccessToken, getActiveSegmentFromHeaders, getActiveVariantFromHeaders, getPreprEnvironmentSegments, getPreprHeadersFromHeaders, getPreprUUIDFromHeaders, getToolbarPropsFromHeaders, normalizeQuery, parsePatchLog, previewAttrs, processPreprRequest, readLiveLogFromRequest, resolveFeatures, stegaClean, validatePreprToken };
package/dist/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ import {
2
+ applyPatchLogToDom,
3
+ startHtmlLivePreview
4
+ } from "./chunk-SZTHSJUA.js";
5
+ import {
6
+ loadTrackingPixel,
7
+ setTrackingParam,
8
+ trackEvent
9
+ } from "./chunk-5I5TQ3NO.js";
1
10
  import {
2
11
  COOKIE_HUBSPOT,
3
12
  COOKIE_PREVIEW_MODE,
@@ -13,11 +22,8 @@ import {
13
22
  createPreprPreview,
14
23
  createToolbarStore,
15
24
  definePreprToolbar,
16
- loadTrackingPixel,
17
- setTrackingParam,
18
- stegaClean,
19
- trackEvent
20
- } from "./chunk-SBLZANL5.js";
25
+ stegaClean
26
+ } from "./chunk-RRM5762S.js";
21
27
  import {
22
28
  PreprError,
23
29
  extractAccessToken,
@@ -28,23 +34,21 @@ import {
28
34
  getPreprUUIDFromHeaders,
29
35
  getToolbarPropsFromHeaders,
30
36
  validatePreprToken
31
- } from "./chunk-3X55JL52.js";
37
+ } from "./chunk-IOSO232M.js";
32
38
  import {
33
- VERSION,
34
- resolveFeatures
35
- } from "./chunk-CMUFTCG3.js";
39
+ VERSION
40
+ } from "./chunk-UK664KSV.js";
36
41
  import {
37
- createLiveBridge,
38
- createLiveStore
39
- } from "./chunk-TG6N3C22.js";
42
+ resolveFeatures
43
+ } from "./chunk-TEB7M7EM.js";
44
+ import "./chunk-IKOOXTPM.js";
40
45
  import "./chunk-URXSDJOU.js";
41
46
  import {
42
47
  normalizeQuery,
43
48
  parsePatchLog
44
- } from "./chunk-74KY5EAM.js";
45
- import {
46
- createScopedLogger
47
- } from "./chunk-S3VT4UWM.js";
49
+ } from "./chunk-ZFGVP2GW.js";
50
+ import "./chunk-AZC4BZJI.js";
51
+ import "./chunk-S3VT4UWM.js";
48
52
 
49
53
  // src/core/preview-attrs.ts
50
54
  function previewAttrs(target, options) {
@@ -59,144 +63,6 @@ function previewAttrs(target, options) {
59
63
  return attrs;
60
64
  }
61
65
 
62
- // src/core/live-preview/morph.ts
63
- function morphElement(current, next) {
64
- syncAttributes(current, next);
65
- morphChildren(current, next);
66
- }
67
- var SKIP_ATTR = "data-prepr-morph-skip";
68
- var RUNTIME_ATTR_PREFIXES = ["data-prepr-"];
69
- function isRuntimeAttribute(name) {
70
- return RUNTIME_ATTR_PREFIXES.some((prefix) => name.startsWith(prefix));
71
- }
72
- function syncAttributes(current, next) {
73
- for (const { name } of Array.from(current.attributes)) {
74
- if (!next.hasAttribute(name) && !isRuntimeAttribute(name)) {
75
- current.removeAttribute(name);
76
- }
77
- }
78
- for (const { name, value } of Array.from(next.attributes)) {
79
- if (current.getAttribute(name) !== value) current.setAttribute(name, value);
80
- }
81
- }
82
- function isSkipped(node) {
83
- return node.nodeType === Node.ELEMENT_NODE && (node.hasAttribute(SKIP_ATTR) || node.localName === "prepr-toolbar");
84
- }
85
- function sameKind(a, b) {
86
- if (a.nodeType !== b.nodeType) return false;
87
- if (a.nodeType !== Node.ELEMENT_NODE) return true;
88
- const ea = a;
89
- const eb = b;
90
- return ea.localName === eb.localName && ea.id === eb.id;
91
- }
92
- function morphChildren(current, next) {
93
- const wanted = Array.from(next.childNodes).filter((n) => !isSkipped(n));
94
- const existing = Array.from(current.childNodes).filter((n) => !isSkipped(n));
95
- wanted.forEach((target, i) => {
96
- const node = existing[i];
97
- if (node && sameKind(node, target)) {
98
- if (node.nodeType === Node.ELEMENT_NODE) {
99
- const element = node;
100
- if (element.localName === "script") return;
101
- if (element.localName === "astro-island" && !element.isEqualNode(target)) {
102
- element.replaceWith(adopt(target, current));
103
- return;
104
- }
105
- morphElement(element, target);
106
- } else if (node.nodeValue !== target.nodeValue) {
107
- node.nodeValue = target.nodeValue;
108
- }
109
- return;
110
- }
111
- const replacement = adopt(target, current);
112
- if (node) node.replaceWith(replacement);
113
- else current.appendChild(replacement);
114
- });
115
- for (const extra of existing.slice(wanted.length)) extra.remove();
116
- }
117
- function adopt(node, parent) {
118
- const copy = parent.ownerDocument.importNode(node, true);
119
- if (copy.nodeType === Node.ELEMENT_NODE) {
120
- const element = copy;
121
- const scripts = element.localName === "script" ? [element] : Array.from(element.querySelectorAll("script"));
122
- scripts.forEach((s) => s.setAttribute("data-prepr-morphed", ""));
123
- }
124
- return copy;
125
- }
126
-
127
- // src/core/live-preview/html-live.ts
128
- var debug = createScopedLogger("live-preview:html");
129
- var COMPLETE_DOCUMENT = /<\/html>\s*$/i;
130
- var SYNC_DEBOUNCE_MS = 150;
131
- function startHtmlLivePreview(options = {}) {
132
- if (typeof window === "undefined" || window.self === window.top) {
133
- return { stop() {
134
- } };
135
- }
136
- const store = createLiveStore();
137
- const bridge = createLiveBridge(store, {
138
- allowedEditorOrigins: () => options.allowedEditorOrigins,
139
- strictMode: () => options.strictMode
140
- });
141
- bridge.start();
142
- let timer = null;
143
- let inFlight = false;
144
- let pending = null;
145
- let stopped = false;
146
- const render = async (log) => {
147
- inFlight = true;
148
- try {
149
- const response = await fetch(window.location.href, {
150
- method: log.length ? "POST" : "GET",
151
- headers: log.length ? { "Content-Type": "application/json", [HEADER_LIVE_RENDER]: "1" } : {},
152
- body: log.length ? JSON.stringify({ log }) : void 0,
153
- credentials: "same-origin",
154
- cache: "no-store"
155
- });
156
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
157
- const html = await response.text();
158
- if (stopped) return;
159
- if (!COMPLETE_DOCUMENT.test(html)) {
160
- throw new Error("incomplete page; a component failed to render");
161
- }
162
- const next = new DOMParser().parseFromString(html, "text/html");
163
- if (next.title && next.title !== document.title)
164
- document.title = next.title;
165
- morphElement(document.body, next.body);
166
- } catch (error) {
167
- debug.log("re-render failed", error);
168
- } finally {
169
- inFlight = false;
170
- }
171
- if (pending && !stopped) {
172
- const queued = pending;
173
- pending = null;
174
- void render(queued);
175
- }
176
- };
177
- const schedule = (log) => {
178
- if (timer) clearTimeout(timer);
179
- timer = setTimeout(() => {
180
- timer = null;
181
- if (inFlight) pending = log;
182
- else void render(log);
183
- }, SYNC_DEBOUNCE_MS);
184
- };
185
- const offLog = store.onLogChange((log) => {
186
- if (log.length) schedule(log);
187
- });
188
- const offInvalidate = store.onInvalidate(() => schedule([]));
189
- return {
190
- stop() {
191
- stopped = true;
192
- if (timer) clearTimeout(timer);
193
- offLog();
194
- offInvalidate();
195
- bridge.stop();
196
- }
197
- };
198
- }
199
-
200
66
  // src/core/live-preview/live-request.ts
201
67
  var MAX_BODY_BYTES = 1e6;
202
68
  async function readLiveLogFromRequest(request) {
@@ -376,6 +242,7 @@ export {
376
242
  PreprError,
377
243
  PreprToolbarElement,
378
244
  VERSION,
245
+ applyPatchLogToDom,
379
246
  createPreprPreview,
380
247
  createToolbarStore,
381
248
  definePreprToolbar,
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  createLiveBridge,
3
3
  createLiveStore
4
- } from "./chunk-TG6N3C22.js";
4
+ } from "./chunk-IKOOXTPM.js";
5
5
  import "./chunk-URXSDJOU.js";
6
6
  import {
7
7
  applyPatchLog,
8
8
  normalizeQuery,
9
9
  parsePatchLog
10
- } from "./chunk-74KY5EAM.js";
10
+ } from "./chunk-ZFGVP2GW.js";
11
+ import "./chunk-AZC4BZJI.js";
11
12
  import "./chunk-S3VT4UWM.js";
12
13
  export {
13
14
  applyPatchLog,
@@ -3517,7 +3517,7 @@ function createPreprPreview(opts = {}) {
3517
3517
  var import_react = require("react");
3518
3518
 
3519
3519
  // src/version.ts
3520
- var VERSION = "0.5.0-rc.5";
3520
+ var VERSION = "0.5.1-dom.0";
3521
3521
 
3522
3522
  // src/core/pixel.ts
3523
3523
  var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
@@ -1,4 +1,5 @@
1
- import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-CX422dCO.cjs';
1
+ import { k as PreprToolbarComponentProps } from '../types-DtMa_-f2.cjs';
2
+ import { P as PreprPixelConfig } from '../pixel-DwW7cXJm.cjs';
2
3
 
3
4
  interface PreprTrackingPixelProps {
4
5
  /** Prepr tracking/access token. */
@@ -1,4 +1,5 @@
1
- import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-CX422dCO.js';
1
+ import { k as PreprToolbarComponentProps } from '../types-DtMa_-f2.js';
2
+ import { P as PreprPixelConfig } from '../pixel-DwW7cXJm.js';
2
3
 
3
4
  interface PreprTrackingPixelProps {
4
5
  /** Prepr tracking/access token. */
@@ -1,9 +1,12 @@
1
1
  "use client";
2
2
  import {
3
- createPreprPreview,
4
3
  loadTrackingPixel
5
- } from "../chunk-SBLZANL5.js";
6
- import "../chunk-CMUFTCG3.js";
4
+ } from "../chunk-5I5TQ3NO.js";
5
+ import {
6
+ createPreprPreview
7
+ } from "../chunk-RRM5762S.js";
8
+ import "../chunk-UK664KSV.js";
9
+ import "../chunk-TEB7M7EM.js";
7
10
  import "../chunk-URXSDJOU.js";
8
11
  import "../chunk-S3VT4UWM.js";
9
12
 
@@ -49,7 +49,7 @@ module.exports = __toCommonJS(nextjs_exports);
49
49
  var import_server = require("next/server");
50
50
 
51
51
  // src/version.ts
52
- var VERSION = "0.5.0-rc.5";
52
+ var VERSION = "0.5.1-dom.0";
53
53
 
54
54
  // src/core/constants.ts
55
55
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -311,8 +311,6 @@ interface LivePreviewConfig {
311
311
  interface PreprRefreshProps {
312
312
  /** Pass your preview flag; never `true` on a production deployment. */
313
313
  enabled?: boolean;
314
- /** Exact editor origins, replacing the `*.prepr.io` default. */
315
- allowedEditorOrigins?: string[];
316
314
  /** Your preview token uses GraphQL strict mode; see the toolbar option. */
317
315
  strictMode?: boolean;
318
316
  }