@b10cks/client 1.9.0 → 1.10.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.
package/dist/index.d.ts CHANGED
@@ -265,7 +265,7 @@ export declare class B10cksDataApi {
265
265
  * separate one for news. Unknown names respond with 404.
266
266
  */
267
267
  getNamedSitemap(name: string, params?: Omit<IBContentQueryParams, 'token'>, options?: CollectionFetchOptions): Promise<IBSitemapEntry[]>;
268
- getDataEntries(source: string, params?: ApiQueryParams, options?: CollectionFetchOptions): Promise<IBDataEntry[]>;
268
+ getDataEntries(source: string, params?: IBDataEntryParams, options?: CollectionFetchOptions): Promise<IBDataEntry[]>;
269
269
  getDataSources(params?: ApiQueryParams, options?: CollectionFetchOptions): Promise<IBDataSource[]>;
270
270
  getSpace(params?: ApiQueryParams): Promise<IBSpace>;
271
271
  lookupRedirect(source: string): Promise<IBRedirectLookupResult | false>;
@@ -466,11 +466,18 @@ export declare type FieldUpdateEvent = {
466
466
  */
467
467
  export declare function filterSitemapEntries(entries: IBSitemapEntry[], options?: SitemapFilterOptions): IBSitemapEntry[];
468
468
 
469
+ /**
470
+ * Depth-first search for the path to the node carrying `id`. The root node
471
+ * itself is not considered a match — callers handle the root explicitly.
472
+ */
473
+ export declare function findPathById(root: unknown, id: string): FieldPath | null;
474
+
469
475
  /** Read the value at `path` within `target`, or undefined if absent. */
470
476
  export declare function getAtPath(target: unknown, path: FieldPath): unknown;
471
477
 
472
478
  export declare interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {
473
479
  slug?: string;
480
+ /** @deprecated Use `language_iso`, matching every other content param. */
474
481
  language?: string;
475
482
  bypassCache?: boolean;
476
483
  }
@@ -478,6 +485,12 @@ export declare interface GetConfigOptions extends Omit<IBContentQueryParams, 'to
478
485
  export declare interface IBBaseQueryParams extends IBPaginationParams, IBSortParams {
479
486
  vid?: string;
480
487
  version?: string;
488
+ /**
489
+ * Content revision to read at. Defaults to the client's current revision;
490
+ * pass it explicitly to pin a request (or `Date.now()` to bypass the
491
+ * delivery cache from a server route).
492
+ */
493
+ rv?: string | number;
481
494
  token: string;
482
495
  }
483
496
 
@@ -668,6 +681,14 @@ export declare interface IBDataEntry {
668
681
  updated_at: string;
669
682
  }
670
683
 
684
+ export declare type IBDataEntryParams = Omit<IBBaseQueryParams, 'token'> & {
685
+ /**
686
+ * Serves the entries mutated for this dimension (usually a locale), falling
687
+ * back to the stored base value for keys the dimension does not override.
688
+ */
689
+ dimension?: string;
690
+ };
691
+
671
692
  export declare interface IBDataSource {
672
693
  id: string;
673
694
  name: string;
@@ -801,6 +822,26 @@ export declare type IdFilter = string | {
801
822
 
802
823
  declare type Listener = () => void;
803
824
 
825
+ /**
826
+ * Merge a `CONTENT_UPDATE` payload into an existing content tree.
827
+ *
828
+ * The editor sends updates scoped to the edited item — the payload is the block
829
+ * that changed, carrying its own `id` — and only sends the whole tree when the
830
+ * root block itself is edited (as `{ id: entryId, ...entryContent }`). Blindly
831
+ * assigning the payload as the new root therefore collapses the page to the
832
+ * edited block, so the payload is instead matched by `id`:
833
+ *
834
+ * - payload without an `id` → treated as the whole tree (legacy/whole-tree push)
835
+ * - payload id equal to the root's id → replaces the root
836
+ * - payload id found in the tree → replaces that node in place, immutably
837
+ * - payload id found nowhere → ignored (an update for a block not rendered here)
838
+ *
839
+ * When the root is rendered without its entry id (`entry.content` alone, so the
840
+ * root has no `id` to match) an update that matches nothing nested but has the
841
+ * same `block` type as the root is taken as the root.
842
+ */
843
+ export declare function mergeContentUpdate<T>(root: T, update: Record<string, unknown>): T;
844
+
804
845
  export declare function normalizePathSegment(value: string | null | undefined): string;
805
846
 
806
847
  export declare class PreviewBridge {
@@ -842,7 +883,7 @@ export declare interface PreviewBridgeInitOptions {
842
883
 
843
884
  /**
844
885
  * A framework-agnostic, reactive holder for the content tree shown in the
845
- * preview. The editor pushes whole-tree (`CONTENT_UPDATE`) or granular
886
+ * preview. The editor pushes block-scoped (`CONTENT_UPDATE`) or granular
846
887
  * (`CONTENT_PATCH`) changes; subscribers re-render from the new snapshot.
847
888
  */
848
889
  export declare class PreviewStore<T = Record<string, unknown>> {
@@ -852,6 +893,12 @@ export declare class PreviewStore<T = Record<string, unknown>> {
852
893
  subscribe: (listener: Listener) => (() => void);
853
894
  getSnapshot: () => T;
854
895
  setContent(next: T): void;
896
+ /**
897
+ * Apply an editor `CONTENT_UPDATE` payload. See {@link mergeContentUpdate}:
898
+ * scoped payloads are merged by `id` instead of replacing the whole tree.
899
+ * Unknown ids are ignored and do not notify subscribers.
900
+ */
901
+ applyContentUpdate(update: Record<string, unknown>): void;
855
902
  patch(path: FieldPath, value: unknown): void;
856
903
  private emit;
857
904
  }
@@ -873,8 +920,11 @@ export declare function renderSitemapIndex(paths: string[], siteUrl?: string): s
873
920
  /**
874
921
  * Renders `IBSitemapEntry[]` as a `<urlset>` XML string.
875
922
  * Pass `siteUrl` to emit absolute `<loc>` values; without it, relative paths are used.
923
+ *
924
+ * Locale prefixing follows {@link SitemapPathOptions.localePrefix}, which
925
+ * defaults to `auto` — a mono-lingual entry set is emitted unprefixed.
876
926
  */
877
- export declare function renderSitemapXml(entries: IBSitemapEntry[], siteUrl?: string): string;
927
+ export declare function renderSitemapXml(entries: IBSitemapEntry[], siteUrl?: string, options?: SitemapPathOptions): string;
878
928
 
879
929
  /**
880
930
  * Resolves a B10cksLink value to a plain { href, target } object.
@@ -887,6 +937,11 @@ export declare function renderSitemapXml(entries: IBSitemapEntry[], siteUrl?: st
887
937
  */
888
938
  export declare function resolveB10cksLink(link: B10cksLink | undefined | null): B10cksLinkResolved | undefined;
889
939
 
940
+ export declare type RootBlock<T> = T & {
941
+ id: string;
942
+ block: string;
943
+ };
944
+
890
945
  export declare type SelectUpdateEvent = {
891
946
  selectedItem: string;
892
947
  };
@@ -903,13 +958,34 @@ export declare function setAtPath<T>(target: T, path: FieldPath, value: unknown)
903
958
  */
904
959
  export declare function setPreviewScrollOffset(offset: number | string): void;
905
960
 
906
- export declare interface SitemapFilterOptions {
961
+ export declare interface SitemapFilterOptions extends SitemapPathOptions {
907
962
  /** Absolute base URL used for deduplication. Without it, paths are compared as strings. */
908
963
  siteUrl?: string;
909
964
  /** Only include entries for this locale (ISO code). */
910
965
  locale?: string;
911
966
  }
912
967
 
968
+ /**
969
+ * How a locale segment is applied to an entry's stored `full_slug`. The SDK
970
+ * cannot infer the consuming app's routing, so this mirrors the usual i18n
971
+ * strategies.
972
+ *
973
+ * - `auto` (default) prefixes only when the entries span more than one
974
+ * `language_iso`. A mono-lingual space is served at `/about`, not `/en/about`,
975
+ * even though its entries still carry a language.
976
+ * - `always` prefixes every entry.
977
+ * - `never` uses paths as stored, for an app that routes the locale some other
978
+ * way (a route param, a domain).
979
+ * - `except-default` prefixes every locale but {@link SitemapPathOptions.defaultLocale}.
980
+ */
981
+ export declare type SitemapLocalePrefix = 'auto' | 'always' | 'never' | 'except-default';
982
+
983
+ export declare interface SitemapPathOptions {
984
+ localePrefix?: SitemapLocalePrefix;
985
+ /** The unprefixed locale under `localePrefix: 'except-default'`. */
986
+ defaultLocale?: string;
987
+ }
988
+
913
989
  export declare type StringFilter = string | {
914
990
  eq: string;
915
991
  } | {
@@ -925,13 +1001,30 @@ export declare type StringFilter = string | {
925
1001
  } | {
926
1002
  '^like': string;
927
1003
  } | {
928
- 'like$': string;
1004
+ like$: string;
929
1005
  } | {
930
1006
  null: true;
931
1007
  } | {
932
1008
  '!null': true;
933
1009
  };
934
1010
 
1011
+ /**
1012
+ * Flatten a content entry into a renderable root block.
1013
+ *
1014
+ * An entry's `content` object carries `block` but not `id` — the id lives on the
1015
+ * entry. Rendering `entry.content` directly therefore yields a root block the
1016
+ * visual editor cannot address: `v-editable` no-ops on it, and the editor's
1017
+ * root-level `CONTENT_UPDATE` (sent as `{ id: entryId, … }`) matches nothing.
1018
+ * Use this helper to carry the entry id into the tree:
1019
+ *
1020
+ * ```ts
1021
+ * const block = toRootBlock(entry) // { ...entry.content, id, block }
1022
+ * ```
1023
+ */
1024
+ export declare function toRootBlock<T extends Record<string, unknown>>(entry: IBContent<T>): RootBlock<T>;
1025
+
1026
+ export declare function toRootBlock<T extends Record<string, unknown>>(entry: IBContent<T> | null | undefined): RootBlock<T> | null;
1027
+
935
1028
  export declare namespace types {
936
1029
  export {
937
1030
  FetchClient,
@@ -951,6 +1044,7 @@ export declare namespace types {
951
1044
  IBBreadcrumbResponse,
952
1045
  IBBreadcrumbParams,
953
1046
  IBDataEntry,
1047
+ IBDataEntryParams,
954
1048
  IBPaginationParams,
955
1049
  IBSortParams,
956
1050
  IBBaseQueryParams,
package/dist/index.mjs CHANGED
@@ -33,6 +33,15 @@ function r(e, t = {}) {
33
33
  //#endregion
34
34
  //#region src/content.ts
35
35
  function i(e) {
36
+ if (!e) return null;
37
+ let t = e.content ?? {};
38
+ return {
39
+ ...t,
40
+ id: e.id,
41
+ block: t.block ?? e.block
42
+ };
43
+ }
44
+ function a(e) {
36
45
  if (!e) return;
37
46
  if (e.type === "email") {
38
47
  let t = new URLSearchParams();
@@ -52,7 +61,7 @@ function i(e) {
52
61
  }
53
62
  //#endregion
54
63
  //#region src/data-api.ts
55
- function a(e) {
64
+ function o(e) {
56
65
  if (e != null) {
57
66
  if (typeof e == "boolean" || typeof e == "number") return String(e);
58
67
  if (typeof e == "string") return e;
@@ -88,23 +97,23 @@ function a(e) {
88
97
  }
89
98
  }
90
99
  }
91
- function o(e) {
100
+ function s(e) {
92
101
  let t = {};
93
102
  for (let [n, r] of Object.entries(e)) {
94
- let e = a(r);
103
+ let e = o(r);
95
104
  e !== void 0 && (t[n] = e);
96
105
  }
97
106
  return t;
98
107
  }
99
- function s(e, t, n) {
100
- let r = t && typeof t == "object" ? o(t) : {}, i = Array.isArray(n) ? { sort: n.join(",") } : n == null ? {} : { sort: n };
108
+ function c(e, t, n) {
109
+ let r = t && typeof t == "object" ? s(t) : {}, i = Array.isArray(n) ? { sort: n.join(",") } : n == null ? {} : { sort: n };
101
110
  return {
102
111
  ...e,
103
112
  ...r,
104
113
  ...i
105
114
  };
106
115
  }
107
- var c = 128, l = class {
116
+ var l = 128, u = class {
108
117
  client;
109
118
  redirectsCache = /* @__PURE__ */ new Map();
110
119
  configCache = /* @__PURE__ */ new Map();
@@ -126,7 +135,7 @@ var c = 128, l = class {
126
135
  }
127
136
  async getContents(e = {}, t = {}) {
128
137
  let { filter: n, sort: r, ...i } = e;
129
- return this.getCollection("contents", s(i, n, r), t);
138
+ return this.getCollection("contents", c(i, n, r), t);
130
139
  }
131
140
  async getBreadcrumb(e, t = {}) {
132
141
  return (await this.getBreadcrumbResponse(e, t))?.breadcrumb ?? [];
@@ -140,7 +149,7 @@ var c = 128, l = class {
140
149
  }
141
150
  async getBlocks(e = {}, t = {}) {
142
151
  let { filter: n, ...r } = e;
143
- return this.getCollection("blocks", s(r, n, void 0), t);
152
+ return this.getCollection("blocks", c(r, n, void 0), t);
144
153
  }
145
154
  async search(e) {
146
155
  let t = await this.client.get("search", e);
@@ -182,7 +191,7 @@ var c = 128, l = class {
182
191
  let e = this.redirectsCache.get(i);
183
192
  if (e) return e;
184
193
  }
185
- let { filter: a, ...o } = e, c = s(o, a, void 0), l = await this.getCollection("redirects", c, { allPages: n }), u = Object.fromEntries(l.map(({ source: e, target: t, status_code: n }) => [e, {
194
+ let { filter: a, ...o } = e, s = c(o, a, void 0), l = await this.getCollection("redirects", s, { allPages: n }), u = Object.fromEntries(l.map(({ source: e, target: t, status_code: n }) => [e, {
186
195
  target: t,
187
196
  status_code: n
188
197
  }]));
@@ -205,7 +214,10 @@ var c = 128, l = class {
205
214
  ...i,
206
215
  language_iso: a
207
216
  }).then((e) => {
208
- let t = e.content ?? {};
217
+ let t = {
218
+ ...e.content ?? {},
219
+ id: e.id
220
+ };
209
221
  return r || this.setConfigCache(o, t), t;
210
222
  }).finally(() => {
211
223
  this.configInflight.delete(o);
@@ -213,7 +225,7 @@ var c = 128, l = class {
213
225
  return r || this.configInflight.set(o, c), c;
214
226
  }
215
227
  setConfigCache(e, t) {
216
- if (this.configCache.delete(e), this.configCache.set(e, t), this.configCache.size > c) {
228
+ if (this.configCache.delete(e), this.configCache.set(e, t), this.configCache.size > l) {
217
229
  let e = this.configCache.keys().next().value;
218
230
  e !== void 0 && this.configCache.delete(e);
219
231
  }
@@ -237,19 +249,19 @@ var c = 128, l = class {
237
249
  return [];
238
250
  }
239
251
  };
240
- function u(e) {
241
- return new l(e);
252
+ function d(e) {
253
+ return new u(e);
242
254
  }
243
255
  //#endregion
244
256
  //#region src/preview-bridge.ts
245
- var d = /* @__PURE__ */ new Set([
257
+ var f = /* @__PURE__ */ new Set([
246
258
  "CONTENT_UPDATE",
247
259
  "CONTENT_PATCH",
248
260
  "SELECT_UPDATE",
249
261
  "HOVER_UPDATE",
250
262
  "FIELD_UPDATE",
251
263
  "FIELD_SELECT"
252
- ]), f = "B10CKS_BRIDGE_READY", p = class e {
264
+ ]), p = "B10CKS_BRIDGE_READY", m = class e {
253
265
  static instance;
254
266
  listeners = {};
255
267
  initialized = !1;
@@ -265,7 +277,7 @@ var d = /* @__PURE__ */ new Set([
265
277
  e.allowedOrigins && !this.allowedOrigins && (this.allowedOrigins = e.allowedOrigins, this.parentOrigin && !this.allowedOrigins.includes(this.parentOrigin) && (this.parentOrigin = null));
266
278
  return;
267
279
  }
268
- this.allowedOrigins = e.allowedOrigins ?? null, window.addEventListener("message", this.handleMessage), this.initialized = !0, window.parent.postMessage({ type: f }, "*");
280
+ this.allowedOrigins = e.allowedOrigins ?? null, window.addEventListener("message", this.handleMessage), this.initialized = !0, window.parent.postMessage({ type: p }, "*");
269
281
  }
270
282
  }
271
283
  destroy() {
@@ -314,7 +326,7 @@ var d = /* @__PURE__ */ new Set([
314
326
  handleMessage = (e) => {
315
327
  if (!this.isOriginTrusted(e.origin) || !e.data || typeof e.data != "object") return;
316
328
  let { type: t, payload: n } = e.data;
317
- !t || !d.has(t) || !n || (!this.parentOrigin && e.origin && e.origin !== "null" && (this.parentOrigin = e.origin), this.notify(t, n));
329
+ !t || !f.has(t) || !n || (!this.parentOrigin && e.origin && e.origin !== "null" && (this.parentOrigin = e.origin), this.notify(t, n));
318
330
  };
319
331
  isOriginTrusted(e) {
320
332
  return this.parentOrigin ? e === this.parentOrigin : !this.allowedOrigins || this.allowedOrigins.includes(e);
@@ -323,12 +335,12 @@ var d = /* @__PURE__ */ new Set([
323
335
  let n = this.listeners[e];
324
336
  if (n) for (let e of n) e(t);
325
337
  }
326
- }, m = p.getInstance(), h = "b10cks-preview-style", g = "--b10cks-scroll-offset";
327
- function _() {
328
- if (typeof document > "u" || document.getElementById(h)) return;
338
+ }, h = m.getInstance(), g = "b10cks-preview-style", _ = "--b10cks-scroll-offset";
339
+ function v() {
340
+ if (typeof document > "u" || document.getElementById(g)) return;
329
341
  let e = document.createElement("style");
330
- e.id = h, e.textContent = `
331
- .b10cks-preview { scroll-margin-top: var(${g}, 0px); }
342
+ e.id = g, e.textContent = `
343
+ .b10cks-preview { scroll-margin-top: var(${_}, 0px); }
332
344
  .b10cks-hover,
333
345
  .b10cks-preview:hover {
334
346
  outline: 2px dashed rgba(59, 130, 246, 0.5);
@@ -340,38 +352,38 @@ function _() {
340
352
  }
341
353
  `, document.head.appendChild(e);
342
354
  }
343
- function v(e) {
355
+ function y(e) {
344
356
  if (typeof document > "u") return;
345
357
  let t = typeof e == "number" ? `${e}px` : e;
346
- document.documentElement.style.setProperty(g, t);
358
+ document.documentElement.style.setProperty(_, t);
347
359
  }
348
- function y(e, t) {
349
- if (!m.isInPreviewMode() || !t.id) return () => {};
350
- _();
360
+ function b(e, t) {
361
+ if (!h.isInPreviewMode() || !t.id) return () => {};
362
+ v();
351
363
  let { id: n, onSelectChange: r, onHoverChange: i, scrollOnSelect: a = !0 } = t;
352
364
  e.classList.add("b10cks-preview");
353
365
  let o = (e) => {
354
- e.preventDefault(), e.stopPropagation(), m.selectItem(n);
366
+ e.preventDefault(), e.stopPropagation(), h.selectItem(n);
355
367
  }, s = ({ selectedItem: t }) => {
356
368
  let i = t === n;
357
- e.classList.toggle("b10cks-selected", i), i && a && x(e), r?.(i);
369
+ e.classList.toggle("b10cks-selected", i), i && a && S(e), r?.(i);
358
370
  }, c = ({ selectedItem: t }) => {
359
371
  let r = t === n;
360
372
  e.classList.toggle("b10cks-hover", r), i?.(r);
361
373
  };
362
374
  e.addEventListener("click", o);
363
- let l = m.on("SELECT_UPDATE", s), u = m.on("HOVER_UPDATE", c);
375
+ let l = h.on("SELECT_UPDATE", s), u = h.on("HOVER_UPDATE", c);
364
376
  return () => {
365
377
  e.removeEventListener("click", o), l(), u(), e.classList.remove("b10cks-preview", "b10cks-selected", "b10cks-hover");
366
378
  };
367
379
  }
368
- function b(e, t) {
369
- if (!m.isInPreviewMode() || !t.id) return () => {};
380
+ function x(e, t) {
381
+ if (!h.isInPreviewMode() || !t.id) return () => {};
370
382
  let { id: n, field: r, path: i, mode: a = "inline" } = t;
371
383
  if (a === "select") {
372
- _(), e.classList.add("b10cks-preview");
384
+ v(), e.classList.add("b10cks-preview");
373
385
  let t = (e) => {
374
- e.preventDefault(), e.stopPropagation(), i ? m.selectField(n, i) : m.selectItem(n);
386
+ e.preventDefault(), e.stopPropagation(), i ? h.selectField(n, i) : h.selectItem(n);
375
387
  };
376
388
  return e.addEventListener("click", t), () => {
377
389
  e.removeEventListener("click", t), e.classList.remove("b10cks-preview");
@@ -380,13 +392,13 @@ function b(e, t) {
380
392
  e.setAttribute("contenteditable", "true");
381
393
  let o = (e) => {
382
394
  let t = e.target.innerText;
383
- i ? m.updateFieldAt(n, i, t) : m.updateField(n, r ?? "", t);
395
+ i ? h.updateFieldAt(n, i, t) : h.updateField(n, r ?? "", t);
384
396
  };
385
397
  return e.addEventListener("input", o), () => {
386
398
  e.removeEventListener("input", o), e.removeAttribute("contenteditable");
387
399
  };
388
400
  }
389
- function x(e) {
401
+ function S(e) {
390
402
  typeof e.scrollIntoView == "function" && e.scrollIntoView({
391
403
  block: "nearest",
392
404
  behavior: "smooth"
@@ -394,7 +406,7 @@ function x(e) {
394
406
  }
395
407
  //#endregion
396
408
  //#region src/preview-store.ts
397
- function S(e, t) {
409
+ function C(e, t) {
398
410
  let n = e;
399
411
  for (let e of t) {
400
412
  if (typeof n != "object" || !n) return;
@@ -402,18 +414,50 @@ function S(e, t) {
402
414
  }
403
415
  return n;
404
416
  }
405
- function C(e, t, n) {
417
+ function w(e, t, n) {
406
418
  if (t.length === 0) return n;
407
419
  let [r, ...i] = t;
408
420
  if (r === void 0) return n;
409
421
  if (typeof r == "number") {
410
422
  let t = Array.isArray(e) ? e.slice() : [];
411
- return t[r] = C(t[r], i, n), t;
423
+ return t[r] = w(t[r], i, n), t;
412
424
  }
413
425
  let a = e && typeof e == "object" && !Array.isArray(e) ? { ...e } : {};
414
- return a[r] = C(a[r], i, n), a;
426
+ return a[r] = w(a[r], i, n), a;
415
427
  }
416
- var w = class {
428
+ function T(e, t) {
429
+ let n = (e, r) => {
430
+ if (Array.isArray(e)) {
431
+ for (let t = 0; t < e.length; t++) {
432
+ let i = n(e[t], [...r, t]);
433
+ if (i) return i;
434
+ }
435
+ return null;
436
+ }
437
+ if (!e || typeof e != "object") return null;
438
+ let i = e;
439
+ if (r.length > 0 && i.id === t) return r;
440
+ for (let e of Object.keys(i)) {
441
+ let t = i[e];
442
+ if (t && typeof t == "object") {
443
+ let i = n(t, [...r, e]);
444
+ if (i) return i;
445
+ }
446
+ }
447
+ return null;
448
+ };
449
+ return n(e, []);
450
+ }
451
+ function E(e, t) {
452
+ if (!t || typeof t != "object") return e;
453
+ let n = typeof t.id == "string" ? t.id : void 0;
454
+ if (!n || !e || typeof e != "object") return t;
455
+ let r = e, i = typeof r.id == "string" ? r.id : void 0;
456
+ if (i === n) return t;
457
+ let a = T(e, n);
458
+ return a ? w(e, a, t) : !i && r.block !== void 0 && r.block === t.block ? t : e;
459
+ }
460
+ var D = class {
417
461
  content;
418
462
  listeners = /* @__PURE__ */ new Set();
419
463
  constructor(e) {
@@ -426,17 +470,21 @@ var w = class {
426
470
  setContent(e) {
427
471
  this.content = e, this.emit();
428
472
  }
473
+ applyContentUpdate(e) {
474
+ let t = E(this.content, e);
475
+ t !== this.content && (this.content = t, this.emit());
476
+ }
429
477
  patch(e, t) {
430
- this.content = C(this.content, e, t), this.emit();
478
+ this.content = w(this.content, e, t), this.emit();
431
479
  }
432
480
  emit() {
433
481
  for (let e of this.listeners) e();
434
482
  }
435
483
  };
436
- function T(e) {
437
- let t = m.on("CONTENT_UPDATE", ({ content: t }) => {
438
- e.setContent(t);
439
- }), n = m.on("CONTENT_PATCH", ({ path: t, value: n }) => {
484
+ function O(e) {
485
+ let t = h.on("CONTENT_UPDATE", ({ content: t }) => {
486
+ e.applyContentUpdate(t);
487
+ }), n = h.on("CONTENT_PATCH", ({ path: t, value: n }) => {
440
488
  e.patch(t, n);
441
489
  });
442
490
  return () => {
@@ -445,17 +493,17 @@ function T(e) {
445
493
  }
446
494
  //#endregion
447
495
  //#region src/sitemap.ts
448
- function E(e) {
496
+ function k(e) {
449
497
  return (e ?? "").trim().replace(/^\/+|\/+$/g, "");
450
498
  }
451
- function D(e, t) {
452
- let n = E(e), r = E(t);
499
+ function A(e, t) {
500
+ let n = k(e), r = k(t);
453
501
  if (!r) return n && n !== "home" ? `/${n}` : "/";
454
502
  if (!n || n === "home") return `/${r}`;
455
503
  let i = `${r}/`;
456
504
  return n === r || n.startsWith(i) ? `/${n}` : `/${r}/${n}`;
457
505
  }
458
- function O(e, t) {
506
+ function j(e, t) {
459
507
  if (!t) return null;
460
508
  try {
461
509
  return new URL(e, t).toString();
@@ -463,41 +511,51 @@ function O(e, t) {
463
511
  return null;
464
512
  }
465
513
  }
466
- function k(e) {
514
+ function M(e) {
467
515
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
468
516
  }
469
- function A(e, t = {}) {
470
- let { siteUrl: n, locale: r } = t, i = /* @__PURE__ */ new Set();
517
+ function N(e, t, n) {
518
+ let { localePrefix: r = "auto", defaultLocale: i } = t;
519
+ return r === "always" || r === "auto" && n || r === "except-default" && e.language_iso !== i ? A(e.full_slug, e.language_iso) : A(e.full_slug, null);
520
+ }
521
+ function P(e) {
522
+ let t = /* @__PURE__ */ new Set();
523
+ for (let n of e) if (n.language_iso && t.add(n.language_iso), t.size > 1) return !0;
524
+ return !1;
525
+ }
526
+ function F(e, t = {}) {
527
+ let { siteUrl: n, locale: r } = t, i = /* @__PURE__ */ new Set(), a = P(e);
471
528
  return e.filter((e) => {
472
529
  if (r && e.language_iso !== r) return !1;
473
- let t = e.meta?.robots?.toLowerCase();
474
- if (t?.includes("noindex") || t?.includes("none")) return !1;
475
- let a = D(e.full_slug, e.language_iso), o = n ? O(a, n) ?? a : a;
476
- return i.has(o) ? !1 : (i.add(o), !0);
530
+ let o = e.meta?.robots?.toLowerCase();
531
+ if (o?.includes("noindex") || o?.includes("none")) return !1;
532
+ let s = N(e, t, a), c = n ? j(s, n) ?? s : s;
533
+ return i.has(c) ? !1 : (i.add(c), !0);
477
534
  });
478
535
  }
479
- function j(e, t) {
536
+ function I(e, t, n = {}) {
537
+ let r = P(e);
480
538
  return [
481
539
  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
482
540
  "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">",
483
541
  e.map((e) => {
484
- let n = D(e.full_slug, e.language_iso), r = t ? O(n, t) : n;
485
- if (!r) return "";
486
- let i = [" <url>", ` <loc>${k(r)}</loc>`];
487
- return e.published_at && i.push(` <lastmod>${k(e.published_at)}</lastmod>`), i.push(" </url>"), i.join("\n");
542
+ let i = N(e, n, r), a = t ? j(i, t) : i;
543
+ if (!a) return "";
544
+ let o = [" <url>", ` <loc>${M(a)}</loc>`];
545
+ return e.published_at && o.push(` <lastmod>${M(e.published_at)}</lastmod>`), o.push(" </url>"), o.join("\n");
488
546
  }).filter(Boolean).join("\n"),
489
547
  "</urlset>"
490
548
  ].join("\n");
491
549
  }
492
- function M(e, t) {
550
+ function L(e, t) {
493
551
  return [
494
552
  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
495
553
  "<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">",
496
554
  e.map((e) => {
497
- let n = t ? O(e, t) : e;
555
+ let n = t ? j(e, t) : e;
498
556
  return n ? [
499
557
  " <sitemap>",
500
- ` <loc>${k(n)}</loc>`,
558
+ ` <loc>${M(n)}</loc>`,
501
559
  " </sitemap>"
502
560
  ].join("\n") : "";
503
561
  }).filter(Boolean).join("\n"),
@@ -506,14 +564,14 @@ function M(e, t) {
506
564
  }
507
565
  //#endregion
508
566
  //#region src/types.ts
509
- var N = /* @__PURE__ */ t({}), P = class extends Error {
567
+ var R = /* @__PURE__ */ t({}), z = class extends Error {
510
568
  status;
511
569
  endpoint;
512
570
  body;
513
571
  constructor(e, t, n, r) {
514
572
  super(e), this.status = t, this.endpoint = n, this.body = r, this.name = "ApiError";
515
573
  }
516
- }, F = (e) => e === 429 || e >= 500 && e <= 599, I = (e) => new Promise((t) => setTimeout(t, e)), L = class {
574
+ }, B = (e) => e === 429 || e >= 500 && e <= 599, V = (e) => new Promise((t) => setTimeout(t, e)), H = class {
517
575
  baseUrl;
518
576
  token;
519
577
  vid;
@@ -565,7 +623,7 @@ var N = /* @__PURE__ */ t({}), P = class extends Error {
565
623
  signal: n.signal
566
624
  });
567
625
  } catch (t) {
568
- throw t instanceof Error && t.name === "AbortError" ? new P(`Request timed out after ${this.timeoutMs}ms`, 0, e) : t;
626
+ throw t instanceof Error && t.name === "AbortError" ? new z(`Request timed out after ${this.timeoutMs}ms`, 0, e) : t;
569
627
  } finally {
570
628
  clearTimeout(r);
571
629
  }
@@ -576,8 +634,8 @@ var N = /* @__PURE__ */ t({}), P = class extends Error {
576
634
  let n = await this.fetchWithTimeout(e);
577
635
  return await this.parseResponse(n, t);
578
636
  } catch (e) {
579
- if (n = e, !(r < this.retries && (!(e instanceof P) || e.status === 0 || F(e.status)))) throw e;
580
- await I(200 * 2 ** r);
637
+ if (n = e, !(r < this.retries && (!(e instanceof z) || e.status === 0 || B(e.status)))) throw e;
638
+ await V(200 * 2 ** r);
581
639
  }
582
640
  throw n;
583
641
  }
@@ -612,7 +670,7 @@ var N = /* @__PURE__ */ t({}), P = class extends Error {
612
670
  if (this.isFetchResponse(e)) {
613
671
  if (!e.ok) {
614
672
  let n = await this.readErrorBody(e);
615
- throw new P(`Request to "${t}" failed with status ${e.status}`, e.status, t, n);
673
+ throw new z(`Request to "${t}" failed with status ${e.status}`, e.status, t, n);
616
674
  }
617
675
  return await e.json();
618
676
  }
@@ -679,6 +737,6 @@ var N = /* @__PURE__ */ t({}), P = class extends Error {
679
737
  }
680
738
  };
681
739
  //#endregion
682
- export { L as ApiClient, P as ApiError, l as B10cksDataApi, p as PreviewBridge, w as PreviewStore, y as attachEditable, b as attachEditableField, T as bindPreviewStore, r as breadcrumbJsonLd, D as buildLocalizedPath, u as createB10cksDataApi, _ as ensurePreviewStyles, A as filterSitemapEntries, S as getAtPath, E as normalizePathSegment, m as previewBridge, M as renderSitemapIndex, j as renderSitemapXml, i as resolveB10cksLink, o as serializeFilter, C as setAtPath, v as setPreviewScrollOffset, N as types };
740
+ export { H as ApiClient, z as ApiError, u as B10cksDataApi, m as PreviewBridge, D as PreviewStore, b as attachEditable, x as attachEditableField, O as bindPreviewStore, r as breadcrumbJsonLd, A as buildLocalizedPath, d as createB10cksDataApi, v as ensurePreviewStyles, F as filterSitemapEntries, T as findPathById, C as getAtPath, E as mergeContentUpdate, k as normalizePathSegment, h as previewBridge, L as renderSitemapIndex, I as renderSitemapXml, a as resolveB10cksLink, s as serializeFilter, w as setAtPath, y as setPreviewScrollOffset, i as toRootBlock, R as types };
683
741
 
684
742
  //# sourceMappingURL=index.mjs.map