@b10cks/client 1.4.0 → 1.6.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/README.md CHANGED
@@ -158,9 +158,32 @@ interface B10cksApiClientOptions {
158
158
  fetchClient?: FetchClient // Custom fetch implementation (required in environments without globalThis.fetch)
159
159
  getRv?: () => string | number // Custom getter for the shared revision token
160
160
  setRv?: (value: string | number) => void // Custom setter for the shared revision token
161
+ timeoutMs?: number // Per-request timeout; aborts and throws ApiError when exceeded (default: none)
162
+ retries?: number // Retry attempts for transient GET failures (network/429/5xx) with backoff (default: 0)
163
+ maxConcurrency?: number // Max pages fetched concurrently by getAll/allPages (default: 6)
161
164
  }
162
165
  ```
163
166
 
167
+ ## Error handling
168
+
169
+ Non-2xx responses and transport failures throw an `ApiError` carrying the HTTP `status` (0 for network/timeout errors), the requested `endpoint`, and a best-effort parsed `body`, so you can branch on the status without string-matching the message:
170
+
171
+ ```typescript
172
+ import { ApiError } from '@b10cks/client'
173
+
174
+ try {
175
+ const content = await dataApi.getContent('missing-page')
176
+ } catch (error) {
177
+ if (error instanceof ApiError && error.status === 404) {
178
+ // render a 404 page
179
+ } else {
180
+ throw error
181
+ }
182
+ }
183
+ ```
184
+
185
+ Set `retries` to automatically retry transient failures (network errors, HTTP 429 and 5xx) on idempotent GET requests with exponential backoff, and `timeoutMs` to bound each request.
186
+
164
187
  ## Low-level `ApiClient`
165
188
 
166
189
  `ApiClient` implements the `DataApiClient` interface and can be used directly for one-off requests:
@@ -241,6 +264,96 @@ const xml = renderSitemapXml(filtered, 'https://example.com')
241
264
  const index = renderSitemapIndex(['/sitemap-en.xml', '/sitemap-de.xml'], 'https://example.com')
242
265
  ```
243
266
 
267
+ ## Preview bridge & visual editing
268
+
269
+ When a page is rendered inside the b10cks visual editor (in an `<iframe>`), the SDK exchanges `postMessage` events with the editor so blocks can be selected, hovered, and live-updated while editing. These are the framework-agnostic building blocks — the `@b10cks/vue`, `@b10cks/react`, `@b10cks/svelte`, `@b10cks/nuxt`, and `@b10cks/next` packages wrap them in idiomatic directives/hooks/actions.
270
+
271
+ ### `previewBridge`
272
+
273
+ A singleton that bridges the preview iframe and the editor.
274
+
275
+ ```typescript
276
+ import { previewBridge } from '@b10cks/client'
277
+
278
+ // Call once on the client when your app boots (the framework packages do this for you).
279
+ previewBridge.init({ allowedOrigins: ['https://app.b10cks.com'] })
280
+
281
+ previewBridge.isInPreviewMode() // true only inside the editor iframe
282
+ previewBridge.selectItem(blockId) // tell the editor to select a block
283
+ previewBridge.selectField(blockId, path) // deep-select a nested field (e.g. rich text)
284
+ previewBridge.updateFieldAt(blockId, ['headline'], 'New text') // stream an inline edit
285
+
286
+ // Subscribe to editor → preview events; returns an unsubscribe function.
287
+ const off = previewBridge.on('CONTENT_UPDATE', ({ content }) => { /* … */ })
288
+ ```
289
+
290
+ Event protocol:
291
+
292
+ | Event | Direction | Payload | Purpose |
293
+ |---|---|---|---|
294
+ | `SELECT_UPDATE` | both | `{ selectedItem }` | Select a block |
295
+ | `HOVER_UPDATE` | editor → preview | `{ selectedItem }` | Hover-highlight a block |
296
+ | `FIELD_SELECT` | preview → editor | `{ itemId, path }` | Deep-select a field so the editor opens its own editor |
297
+ | `FIELD_UPDATE` | preview → editor | `{ itemId, path?, field?, value }` | Stream an inline edit |
298
+ | `CONTENT_UPDATE` | editor → preview | `{ content }` | Replace the whole content tree |
299
+ | `CONTENT_PATCH` | editor → preview | `{ path, value }` | Replace a single value at `path` |
300
+
301
+ `path` is a `FieldPath` (`(string | number)[]`) that addresses any value at any depth, including array indices — e.g. `['body', 2, 'headline']`.
302
+
303
+ #### Security
304
+
305
+ By default the bridge locks onto the origin of the first message it receives (trust-on-first-use) and ignores everything else afterwards; outbound messages are then targeted to that origin instead of `*`. Pass `allowedOrigins` to `init()` to restrict the handshake to a known list of editor origins.
306
+
307
+ ### Editable DOM helpers
308
+
309
+ `attachEditable` and `attachEditableField` wire a DOM element to the bridge and return a cleanup function. Both are no-ops outside preview mode.
310
+
311
+ ```typescript
312
+ import { attachEditable, attachEditableField } from '@b10cks/client'
313
+
314
+ // Selectable block: click selects it; editor-driven select/hover toggle outline classes.
315
+ const detach = attachEditable(el, { id: block.id })
316
+
317
+ // Inline string field (contenteditable, streams plain-text edits):
318
+ attachEditableField(el, { id: block.id, field: 'headline' })
319
+
320
+ // Rich text / complex field — deep-select instead of editing inline:
321
+ attachEditableField(el, { id: block.id, path: ['body'], mode: 'select' })
322
+ ```
323
+
324
+ ### Scroll offset (fixed headers)
325
+
326
+ When a block is selected it is scrolled into view with `block: 'nearest'` (so it never jumps when already visible) and honors the `--b10cks-scroll-offset` CSS variable as `scroll-margin-top`. Set it to your fixed header's height so selection doesn't overshoot beneath it — either in CSS:
327
+
328
+ ```css
329
+ :root { --b10cks-scroll-offset: 80px; }
330
+ ```
331
+
332
+ or from JS (the framework packages expose a `scrollOffset` option that calls this):
333
+
334
+ ```typescript
335
+ import { ensurePreviewStyles, setPreviewScrollOffset } from '@b10cks/client'
336
+
337
+ ensurePreviewStyles() // inject the outline + scroll-margin styles once
338
+ setPreviewScrollOffset(80) // number → px, or pass a string like '5rem'
339
+ ```
340
+
341
+ ### `PreviewStore` — reactive live content
342
+
343
+ `PreviewStore` is a framework-agnostic, subscribable holder for the content tree. `bindPreviewStore` feeds `CONTENT_UPDATE`/`CONTENT_PATCH` events into it, so any complex field — including rich text — re-renders from the new snapshot. The framework packages expose this as `usePreviewContent` / `createPreviewContent`.
344
+
345
+ ```typescript
346
+ import { PreviewStore, bindPreviewStore, setAtPath, getAtPath } from '@b10cks/client'
347
+
348
+ const store = new PreviewStore(initialContent)
349
+ const offBridge = bindPreviewStore(store)
350
+ const off = store.subscribe(() => render(store.getSnapshot()))
351
+
352
+ // Immutable path helpers used internally — also exported for your own use:
353
+ const next = setAtPath(content, ['body', 0, 'headline'], 'New')
354
+ const value = getAtPath(content, ['body', 0, 'headline'])
355
+ ```
356
+
244
357
  ## TypeScript
245
358
 
246
359
  Common types exported from the package root:
package/dist/index.cjs ADDED
@@ -0,0 +1,19 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};function n(e){if(!e)return;if(e.type===`email`){let t=new URLSearchParams;e.subject&&t.set(`subject`,e.subject),e.body&&t.set(`body`,e.body),e.cc&&t.set(`cc`,e.cc),e.bcc&&t.set(`bcc`,e.bcc);let n=t.toString();return{href:`mailto:${e.email}${n?`?${n}`:``}`,target:`_self`}}if(e.type===`asset`)return;let t=e.target??`_self`,n=e.url??``;return`anchor`in e&&e.anchor&&(n=`${n.trimEnd()}#${e.anchor}`),{href:n,target:t}}function r(e){if(e!=null){if(typeof e==`boolean`||typeof e==`number`)return String(e);if(typeof e==`string`)return e;if(typeof e==`object`&&!Array.isArray(e)){let t=e;if(`null`in t)return`null:`;if(`!null`in t)return`!null:`;if(`between`in t){let e=t.between;if(!Array.isArray(e)||e.length!==2)return;let[n,r]=e;return`${n}...${r}`}for(let e of[`eq`,`neq`,`like`,`!like`,`^like`,`like$`,`lt`,`gt`,`lte`,`gte`,`in`,`!in`,`empty`,`!empty`])if(e in t){let n=t[e];return Array.isArray(n)?`${e}:${n.join(`,`)}`:`${e}:${String(n)}`}}}}function i(e){let t={};for(let[n,i]of Object.entries(e)){let e=r(i);e!==void 0&&(t[n]=e)}return t}function a(e,t,n){let r=t&&typeof t==`object`?i(t):{},a=Array.isArray(n)?{sort:n.join(`,`)}:n==null?{}:{sort:n};return{...e,...r,...a}}var o=128,s=class{client;redirectsCache=new Map;configCache=new Map;configInflight=new Map;constructor(e){this.client=e}async getResource(e,t={}){let n=await this.client.get(e,t);return this.unwrapResource(n)}async getCollection(e,t={},n={}){if(n.allPages)return this.client.getAll(e,t);let r=await this.client.get(e,t);return this.unwrapCollection(r)}async getContent(e,t={}){return this.getResource(`contents/${e}`,t)}async getContents(e={},t={}){let{filter:n,sort:r,...i}=e;return this.getCollection(`contents`,a(i,n,r),t)}async getBlock(e,t={}){return this.getResource(`blocks/${e}`,t)}async getBlocks(e={},t={}){let{filter:n,...r}=e;return this.getCollection(`blocks`,a(r,n,void 0),t)}async search(e){let t=await this.client.get(`search`,e);if(typeof t==`object`&&t&&`data`in t&&`meta`in t)return t;if(typeof t==`object`&&t&&`data`in t){let e=t.data;if(typeof e==`object`&&e&&`meta`in e&&`data`in e)return e}return t}async getSitemap(e={},t={}){return this.getCollection(`sitemap`,e,t)}async getDataEntries(e,t={},n={}){return this.getCollection(`datasources/${e}/entries`,t,n)}async getDataSources(e={},t={}){return this.getCollection(`datasources`,e,t)}async getSpace(e={}){return this.getResource(`spaces/me`,e)}async lookupRedirect(e){if(!this.client.post)throw Error(`lookupRedirect requires a client that supports POST. Use ApiClient from @b10cks/client.`);return this.client.post(`redirects/lookup`,{source:e})}async getRedirects(e={},t=!1){let{allPages:n=!1,forceRefresh:r=!1}=typeof t==`boolean`?{allPages:!0,forceRefresh:t}:t,i=JSON.stringify({params:e,rv:this.currentRv()});if(n&&!r){let e=this.redirectsCache.get(i);if(e)return e}let{filter:o,...s}=e,c=a(s,o,void 0),l=await this.getCollection(`redirects`,c,{allPages:n}),u=Object.fromEntries(l.map(({source:e,target:t,status_code:n})=>[e,{target:t,status_code:n}]));return n&&this.redirectsCache.set(i,u),u}currentRv(){return typeof this.client.getRv==`function`?this.client.getRv():``}async getConfig({slug:e=`_config`,language_iso:t,language:n,bypassCache:r=!1,...i}={}){let a=t??n,o=JSON.stringify({slug:e,language_iso:a,rv:this.currentRv(),...i});if(!r&&this.configCache.has(o))return this.configCache.get(o);let s=this.configInflight.get(o);if(!r&&s)return s;let c=this.getContent(e,{...i,language_iso:a}).then(e=>{let t=e.content??{};return r||this.setConfigCache(o,t),t}).finally(()=>{this.configInflight.delete(o)});return r||this.configInflight.set(o,c),c}setConfigCache(e,t){if(this.configCache.delete(e),this.configCache.set(e,t),this.configCache.size>o){let e=this.configCache.keys().next().value;e!==void 0&&this.configCache.delete(e)}}async syncRevision(e=426713400){let t=(await this.getSpace()).rv||e;return this.client.setRv(t),t}clearCache(){this.redirectsCache.clear(),this.configCache.clear(),this.configInflight.clear()}unwrapResource(e){return typeof e==`object`&&e&&`data`in e?e.data:e}unwrapCollection(e){if(Array.isArray(e))return e;if(typeof e==`object`&&e&&`data`in e){if(Array.isArray(e.data))return e.data;if(typeof e.data==`object`&&e.data!==null&&`data`in e.data&&Array.isArray(e.data.data))return e.data.data}return[]}};function c(e){return new s(e)}var l=new Set([`CONTENT_UPDATE`,`CONTENT_PATCH`,`SELECT_UPDATE`,`HOVER_UPDATE`,`FIELD_UPDATE`,`FIELD_SELECT`]),u=`B10CKS_BRIDGE_READY`,d=class e{static instance;listeners={};initialized=!1;allowedOrigins=null;parentOrigin=null;constructor(){}static getInstance(){return e.instance||=new e,e.instance}init(e={}){!this.isInPreviewMode()||this.initialized||(this.allowedOrigins=e.allowedOrigins??null,window.addEventListener(`message`,this.handleMessage),this.initialized=!0,window.parent.postMessage({type:u},`*`))}destroy(){this.initialized&&typeof window<`u`&&window.removeEventListener(`message`,this.handleMessage),this.initialized=!1,this.parentOrigin=null;for(let e of Object.keys(this.listeners))this.listeners[e]?.clear()}isInPreviewMode(){return typeof window<`u`&&window.self!==window.top}on(e,t){if(!this.isInPreviewMode())return()=>{};let n=this.listeners[e]||new Set;return this.listeners[e]=n,n.add(t),()=>{n.delete(t)}}selectItem(e){this.post(`SELECT_UPDATE`,{selectedItem:e})}selectField(e,t){this.post(`FIELD_SELECT`,{itemId:e,path:t})}updateField(e,t,n){this.post(`FIELD_UPDATE`,{itemId:e,field:t,value:n})}updateFieldAt(e,t,n){this.post(`FIELD_UPDATE`,{itemId:e,path:t,value:n})}post(e,t){this.isInPreviewMode()&&window.parent.postMessage({type:e,payload:t},this.parentOrigin??`*`)}handleMessage=e=>{if(!this.isOriginTrusted(e.origin)||!e.data||typeof e.data!=`object`)return;let{type:t,payload:n}=e.data;!t||!l.has(t)||!n||(!this.parentOrigin&&e.origin&&e.origin!==`null`&&(this.parentOrigin=e.origin),this.notify(t,n))};isOriginTrusted(e){return this.parentOrigin?e===this.parentOrigin:this.allowedOrigins?this.allowedOrigins.includes(e):!0}notify(e,t){let n=this.listeners[e];if(n)for(let e of n)e(t)}},f=d.getInstance(),p=`b10cks-preview-style`,m=`--b10cks-scroll-offset`;function h(){if(typeof document>`u`||document.getElementById(p))return;let e=document.createElement(`style`);e.id=p,e.textContent=`
2
+ .b10cks-preview { scroll-margin-top: var(${m}, 0px); }
3
+ .b10cks-hover,
4
+ .b10cks-preview:hover {
5
+ outline: 2px dashed rgba(59, 130, 246, 0.5);
6
+ outline-offset: 2px;
7
+ }
8
+ .b10cks-selected {
9
+ outline: 2px solid rgb(59, 130, 246) !important;
10
+ outline-offset: 2px;
11
+ }
12
+ `,document.head.appendChild(e)}function g(e){if(typeof document>`u`)return;let t=typeof e==`number`?`${e}px`:e;document.documentElement.style.setProperty(m,t)}function _(e,t){if(!f.isInPreviewMode()||!t.id)return()=>{};h();let{id:n,onSelectChange:r,onHoverChange:i,scrollOnSelect:a=!0}=t;e.classList.add(`b10cks-preview`);let o=e=>{e.preventDefault(),e.stopPropagation(),f.selectItem(n)},s=({selectedItem:t})=>{let i=t===n;e.classList.toggle(`b10cks-selected`,i),i&&a&&y(e),r?.(i)},c=({selectedItem:t})=>{let r=t===n;e.classList.toggle(`b10cks-hover`,r),i?.(r)};e.addEventListener(`click`,o);let l=f.on(`SELECT_UPDATE`,s),u=f.on(`HOVER_UPDATE`,c);return()=>{e.removeEventListener(`click`,o),l(),u(),e.classList.remove(`b10cks-preview`,`b10cks-selected`,`b10cks-hover`)}}function v(e,t){if(!f.isInPreviewMode()||!t.id)return()=>{};let{id:n,field:r,path:i,mode:a=`inline`}=t;if(a===`select`){h(),e.classList.add(`b10cks-preview`);let t=e=>{e.preventDefault(),e.stopPropagation(),i?f.selectField(n,i):f.selectItem(n)};return e.addEventListener(`click`,t),()=>{e.removeEventListener(`click`,t),e.classList.remove(`b10cks-preview`)}}e.setAttribute(`contenteditable`,`true`);let o=e=>{let t=e.target.innerText;i?f.updateFieldAt(n,i,t):f.updateField(n,r??``,t)};return e.addEventListener(`input`,o),()=>{e.removeEventListener(`input`,o),e.removeAttribute(`contenteditable`)}}function y(e){typeof e.scrollIntoView==`function`&&e.scrollIntoView({block:`nearest`,behavior:`smooth`})}function b(e,t){let n=e;for(let e of t){if(typeof n!=`object`||!n)return;n=n[e]}return n}function x(e,t,n){if(t.length===0)return n;let[r,...i]=t;if(r===void 0)return n;if(typeof r==`number`){let t=Array.isArray(e)?e.slice():[];return t[r]=x(t[r],i,n),t}let a=e&&typeof e==`object`&&!Array.isArray(e)?{...e}:{};return a[r]=x(a[r],i,n),a}var S=class{content;listeners=new Set;constructor(e){this.content=e}subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getSnapshot=()=>this.content;setContent(e){this.content=e,this.emit()}patch(e,t){this.content=x(this.content,e,t),this.emit()}emit(){for(let e of this.listeners)e()}};function C(e){let t=f.on(`CONTENT_UPDATE`,({content:t})=>{e.setContent(t)}),n=f.on(`CONTENT_PATCH`,({path:t,value:n})=>{e.patch(t,n)});return()=>{t(),n()}}function w(e){return(e??``).trim().replace(/^\/+|\/+$/g,``)}function T(e,t){let n=w(e),r=w(t);if(!r)return n&&n!==`home`?`/${n}`:`/`;if(!n||n===`home`)return`/${r}`;let i=`${r}/`;return n===r||n.startsWith(i)?`/${n}`:`/${r}/${n}`}function E(e,t){if(!t)return null;try{return new URL(e,t).toString()}catch{return null}}function D(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function O(e,t={}){let{siteUrl:n,locale:r}=t,i=new Set;return e.filter(e=>{if(r&&e.language_iso!==r||e.meta?.robots?.toLowerCase().includes(`noindex`))return!1;let t=T(e.full_slug,e.language_iso),a=n?E(t,n)??t:t;return i.has(a)?!1:(i.add(a),!0)})}function k(e,t){return[`<?xml version="1.0" encoding="UTF-8"?>`,`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`,e.map(e=>{let n=T(e.full_slug,e.language_iso),r=t?E(n,t):n;if(!r)return``;let i=[` <url>`,` <loc>${D(r)}</loc>`];return e.published_at&&i.push(` <lastmod>${D(e.published_at)}</lastmod>`),i.push(` </url>`),i.join(`
13
+ `)}).filter(Boolean).join(`
14
+ `),`</urlset>`].join(`
15
+ `)}function A(e,t){return[`<?xml version="1.0" encoding="UTF-8"?>`,`<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`,e.map(e=>{let n=t?E(e,t):e;return n?[` <sitemap>`,` <loc>${D(n)}</loc>`,` </sitemap>`].join(`
16
+ `):``}).filter(Boolean).join(`
17
+ `),`</sitemapindex>`].join(`
18
+ `)}var j=t({}),M=class extends Error{status;endpoint;body;constructor(e,t,n,r){super(e),this.status=t,this.endpoint=n,this.body=r,this.name=`ApiError`}},N=e=>e===429||e>=500&&e<=599,P=e=>new Promise(t=>setTimeout(t,e)),F=class{baseUrl;token;vid;fetchClient;getRvFn;setRvFn;timeoutMs;retries;maxConcurrency;rvValue=0;constructor(e,t){this.baseUrl=e.baseUrl.endsWith(`/`)?e.baseUrl.slice(0,-1):e.baseUrl,this.token=e.token;let n=typeof globalThis.fetch==`function`?globalThis.fetch.bind(globalThis):null;if(e.fetchClient)this.fetchClient=e.fetchClient;else if(n)this.fetchClient=n;else throw Error("No fetch implementation available. Provide `fetchClient` in ApiClient options.");this.getRvFn=e.getRv,this.setRvFn=e.setRv,this.timeoutMs=e.timeoutMs,this.retries=Math.max(0,e.retries??0),this.maxConcurrency=Math.max(1,e.maxConcurrency??6);let r=this.resolveRequestUrl(t);this.vid=e.version||`published`,this.setRv(r?.searchParams.get(`b10cks_rv`)||e.rv||0)}async get(e,t={}){let n=this.buildUrl(e,{vid:this.vid,rv:this.getRv(),...t,token:this.token}),r=await this.requestWithRetry(n,e);return this.hasRevision(r)&&this.setRv(r.rv),r}async post(e,t,n={}){let r=this.buildUrl(e,{vid:this.vid,rv:this.getRv(),...n,token:this.token}),i=await this.fetchWithTimeout(r,{method:`POST`,headers:{"Content-Type":`application/json`},body:t===void 0?void 0:JSON.stringify(t)});return this.parseResponse(i,e)}async fetchWithTimeout(e,t){if(!this.timeoutMs)return this.fetchClient(e,t);let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeoutMs);try{return await this.fetchClient(e,{...t,signal:n.signal})}catch(t){throw t instanceof Error&&t.name===`AbortError`?new M(`Request timed out after ${this.timeoutMs}ms`,0,e):t}finally{clearTimeout(r)}}async requestWithRetry(e,t){let n;for(let r=0;r<=this.retries;r++)try{let n=await this.fetchWithTimeout(e);return await this.parseResponse(n,t)}catch(e){if(n=e,!(r<this.retries&&(!(e instanceof M)||e.status===0||N(e.status))))throw e;await P(200*2**r)}throw n}async getAll(e,t={}){let n=await this.get(e,{...t,page:1}),r=this.normalizeCollectionResponse(n);if(r.rv&&this.setRv(r.rv),!r.meta||r.meta.last_page<=1)return r.data;let i=Array.from({length:r.meta.last_page-1},(e,t)=>t+2),a=await this.mapWithConcurrency(i,n=>this.get(e,{...t,page:n}));return r.data.concat(a.flatMap(e=>this.normalizeCollectionResponse(e).data))}async mapWithConcurrency(e,t){let n=Array.from({length:e.length}),r=0,i=async()=>{for(;r<e.length;){let i=r++;n[i]=await t(e[i])}},a=Array.from({length:Math.min(this.maxConcurrency,e.length)},()=>i());return await Promise.all(a),n}setRv(e){this.setRvFn?this.setRvFn(e):this.rvValue=e}getRv(){return this.getRvFn?this.getRvFn():this.rvValue}async parseResponse(e,t){if(this.isFetchResponse(e)){if(!e.ok){let n=await this.readErrorBody(e);throw new M(`Request to "${t}" failed with status ${e.status}`,e.status,t,n)}return await e.json()}return e}async readErrorBody(e){try{let t=await e.text();if(!t)return;try{return JSON.parse(t)}catch{return t}}catch{return}}normalizeCollectionResponse(e){if(this.isCollectionResponseEnvelope(e)){let t=e.data;return{data:t.data,meta:t.meta,rv:e.rv||t.rv}}if(Array.isArray(e))return{data:e,meta:void 0,rv:void 0};if(typeof e==`object`&&e&&`data`in e){let{data:t,meta:n,rv:r}=e;return{data:t,meta:n,rv:r}}return{data:[],meta:void 0,rv:void 0}}buildUrl(e,t){let n=new URL(`${this.baseUrl}/v1/${e}`);return Object.entries(t).forEach(([e,t])=>{t!=null&&n.searchParams.append(e,String(t))}),n.toString()}resolveRequestUrl(e){return e?e instanceof URL?e:new URL(e,`http://localhost`):null}isFetchResponse(e){return typeof e==`object`&&!!e&&`json`in e&&typeof e.json==`function`&&`ok`in e}hasRevision(e){return typeof e==`object`&&!!e&&`rv`in e&&e.rv!=null}isCollectionResponseEnvelope(e){return typeof e==`object`&&!!e&&`data`in e&&typeof e.data==`object`&&e.data!==null&&`data`in e.data&&Array.isArray(e.data.data)}};exports.ApiClient=F,exports.ApiError=M,exports.B10cksDataApi=s,exports.PreviewBridge=d,exports.PreviewStore=S,exports.attachEditable=_,exports.attachEditableField=v,exports.bindPreviewStore=C,exports.buildLocalizedPath=T,exports.createB10cksDataApi=c,exports.ensurePreviewStyles=h,exports.filterSitemapEntries=O,exports.getAtPath=b,exports.normalizePathSegment=w,exports.previewBridge=f,exports.renderSitemapIndex=A,exports.renderSitemapXml=k,exports.resolveB10cksLink=n,exports.serializeFilter=i,exports.setAtPath=x,exports.setPreviewScrollOffset=g,Object.defineProperty(exports,"types",{enumerable:!0,get:function(){return j}});
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/content.ts","../src/data-api.ts","../src/preview-bridge.ts","../src/editable.ts","../src/preview-store.ts","../src/sitemap.ts","../src/types.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,13 +5,32 @@ export declare class ApiClient {
5
5
  private readonly fetchClient;
6
6
  private readonly getRvFn?;
7
7
  private readonly setRvFn?;
8
+ private readonly timeoutMs?;
9
+ private readonly retries;
10
+ private readonly maxConcurrency;
11
+ /**
12
+ * Per-instance revision store, used when no `getRv`/`setRv` callbacks are
13
+ * supplied. Kept on the instance (not module scope) so concurrent requests
14
+ * in a server runtime cannot leak revisions into one another. Server callers
15
+ * that need request-scoped persistence should pass `getRv`/`setRv`.
16
+ */
17
+ private rvValue;
8
18
  constructor(options: B10cksApiClientOptions, requestUrl?: URL | string);
9
19
  get<T>(endpoint: Endpoint, params?: Omit<IBBaseQueryParams, 'token'> & Record<string, unknown>): Promise<ApiResourceResponse<T>>;
10
20
  post<T>(endpoint: string, body?: unknown, params?: Omit<IBBaseQueryParams, 'token'> & Record<string, unknown>): Promise<T>;
21
+ private fetchWithTimeout;
22
+ private requestWithRetry;
11
23
  getAll<T>(endpoint: Endpoint, params?: Omit<IBBaseQueryParams, 'token'> & Record<string, unknown>): Promise<T[]>;
24
+ /**
25
+ * Runs `task` over `items` preserving order, with at most `maxConcurrency`
26
+ * requests in flight, so paginated fan-out cannot open hundreds of sockets
27
+ * at once and trip API rate limits.
28
+ */
29
+ private mapWithConcurrency;
12
30
  setRv(value: string | number): void;
13
31
  getRv(): string | number;
14
32
  private parseResponse;
33
+ private readErrorBody;
15
34
  private normalizeCollectionResponse;
16
35
  private buildUrl;
17
36
  private resolveRequestUrl;
@@ -20,10 +39,61 @@ export declare class ApiClient {
20
39
  private isCollectionResponseEnvelope;
21
40
  }
22
41
 
42
+ /**
43
+ * Error thrown for non-2xx API responses and transport failures. Carries the
44
+ * HTTP `status` (0 for network/timeout errors), the requested `endpoint`, and a
45
+ * best-effort parsed `body` so callers can branch on status (e.g. render a 404
46
+ * page) without string-matching the message.
47
+ */
48
+ export declare class ApiError extends Error {
49
+ readonly status: number;
50
+ readonly endpoint: string;
51
+ readonly body?: unknown | undefined;
52
+ constructor(message: string, status: number, endpoint: string, body?: unknown | undefined);
53
+ }
54
+
23
55
  declare type ApiQueryParams = Omit<IBBaseQueryParams, 'token'> & Record<string, unknown>;
24
56
 
25
57
  declare type ApiResourceResponse<T> = IBResponse<T> | T;
26
58
 
59
+ /**
60
+ * Wire a DOM element as a selectable block: click selects it in the editor,
61
+ * and editor-driven select/hover toggle outline classes. Honors the configured
62
+ * scroll offset and only scrolls when the element isn't already in view.
63
+ * Returns a cleanup function. No-op outside preview mode.
64
+ */
65
+ export declare function attachEditable(el: HTMLElement, options: AttachEditableOptions): () => void;
66
+
67
+ /**
68
+ * Wire a DOM element for field editing. Returns a cleanup function. No-op
69
+ * outside preview mode. See {@link AttachEditableFieldOptions.mode}.
70
+ */
71
+ export declare function attachEditableField(el: HTMLElement, options: AttachEditableFieldOptions): () => void;
72
+
73
+ export declare interface AttachEditableFieldOptions {
74
+ id: string;
75
+ /** @deprecated Use `path`. Kept for flat string fields. */
76
+ field?: string;
77
+ path?: FieldPath;
78
+ /**
79
+ * `inline` makes the element contenteditable and streams plain-text edits
80
+ * back to the editor — suitable for simple string fields only. `select`
81
+ * instead deep-selects the field so the editor opens its own editor, which
82
+ * is the right choice for rich text and other complex types. Default
83
+ * `inline`, or `select` automatically when no `field` is given but a `path`
84
+ * targets a complex value.
85
+ */
86
+ mode?: EditableFieldMode;
87
+ }
88
+
89
+ export declare interface AttachEditableOptions {
90
+ id: string;
91
+ onSelectChange?: (selected: boolean) => void;
92
+ onHoverChange?: (hovered: boolean) => void;
93
+ /** Scroll the element into view when it becomes selected. Default true. */
94
+ scrollOnSelect?: boolean;
95
+ }
96
+
27
97
  export declare interface B10cksApiClientOptions {
28
98
  baseUrl: string;
29
99
  token: string;
@@ -32,6 +102,21 @@ export declare interface B10cksApiClientOptions {
32
102
  fetchClient?: FetchClient;
33
103
  getRv?: () => string | number;
34
104
  setRv?: (value: string | number) => void;
105
+ /**
106
+ * Per-request timeout in milliseconds. When exceeded the request is aborted
107
+ * and rejected with an {@link ApiError}. Defaults to no timeout.
108
+ */
109
+ timeoutMs?: number;
110
+ /**
111
+ * Number of retry attempts for transient failures (network errors, HTTP 429
112
+ * and 5xx) on idempotent GET requests, using exponential backoff. Defaults
113
+ * to 0 (no retries).
114
+ */
115
+ retries?: number;
116
+ /**
117
+ * Maximum number of pages fetched concurrently by `getAll`. Defaults to 6.
118
+ */
119
+ maxConcurrency?: number;
35
120
  }
36
121
 
37
122
  export declare interface B10cksApiClientRvOptions {
@@ -41,8 +126,10 @@ export declare interface B10cksApiClientRvOptions {
41
126
 
42
127
  export declare class B10cksDataApi {
43
128
  private readonly client;
44
- private redirectsCache;
129
+ private readonly redirectsCache;
45
130
  private readonly configCache;
131
+ /** In-flight config requests, keyed like `configCache`, to dedupe stampedes. */
132
+ private readonly configInflight;
46
133
  constructor(client: DataApiClient);
47
134
  getResource<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T>;
48
135
  getCollection<T>(endpoint: Endpoint, params?: ApiQueryParams, options?: CollectionFetchOptions): Promise<T[]>;
@@ -58,7 +145,9 @@ export declare class B10cksDataApi {
58
145
  lookupRedirect(source: string): Promise<IBRedirectLookupResult | false>;
59
146
  getRedirects(params?: IBGetRedirectsParams, forceRefresh?: boolean): Promise<RedirectMap>;
60
147
  getRedirects(params?: IBGetRedirectsParams, options?: RedirectFetchOptions): Promise<RedirectMap>;
148
+ private currentRv;
61
149
  getConfig<T = Record<string, unknown>>({ slug, language_iso, language, bypassCache, ...params }?: GetConfigOptions): Promise<T>;
150
+ private setConfigCache;
62
151
  syncRevision(fallbackRv?: number): Promise<string | number>;
63
152
  clearCache(): void;
64
153
  private unwrapResource;
@@ -96,6 +185,12 @@ export declare interface B10cksLinkResolved {
96
185
  target: string;
97
186
  }
98
187
 
188
+ /**
189
+ * Feed the singleton bridge's content events into a {@link PreviewStore}.
190
+ * Returns an unsubscribe function. No-op outside preview mode.
191
+ */
192
+ export declare function bindPreviewStore<T>(store: PreviewStore<T>): () => void;
193
+
99
194
  export declare type BridgeEvent = {
100
195
  type: EventType;
101
196
  payload: EventPayloadMap[EventType];
@@ -114,6 +209,12 @@ export declare interface CollectionFetchOptions {
114
209
  allPages?: boolean;
115
210
  }
116
211
 
212
+ /** Granular update: replace the value at `path` within the content tree. */
213
+ export declare type ContentPatchEvent = {
214
+ path: FieldPath;
215
+ value: unknown;
216
+ };
217
+
117
218
  export declare type ContentSortField = 'published_at' | 'updated_at' | 'created_at' | `content.${string}`;
118
219
 
119
220
  export declare type ContentSortItem = ContentSortField | `-${ContentSortField}`;
@@ -132,6 +233,7 @@ export declare interface DataApiClient {
132
233
  getAll<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T[]>;
133
234
  post?<T>(endpoint: string, body?: unknown, params?: ApiQueryParams): Promise<T>;
134
235
  setRv(value: string | number): void;
236
+ getRv?(): string | number;
135
237
  }
136
238
 
137
239
  export declare type DateFilter = string | {
@@ -154,25 +256,52 @@ export declare type DateFilter = string | {
154
256
  '!null': true;
155
257
  };
156
258
 
259
+ export declare type EditableFieldMode = 'inline' | 'select';
260
+
157
261
  export declare type Endpoint = 'blocks' | `blocks/${string}` | 'contents' | `contents/${string}` | `datasources/${string}/entries` | 'datasources' | 'redirects' | 'search' | 'sitemap' | 'spaces/me';
158
262
 
263
+ /**
264
+ * Inject the preview outline styles once. Selected/hovered blocks get an
265
+ * outline; `.b10cks-preview` carries a `scroll-margin-top` so scroll-into-view
266
+ * clears a fixed app header. Set the offset via {@link setPreviewScrollOffset}
267
+ * or the `--b10cks-scroll-offset` CSS variable.
268
+ */
269
+ export declare function ensurePreviewStyles(): void;
270
+
159
271
  declare type EventCallback<T> = (payload: T) => void;
160
272
 
161
273
  export declare type EventPayloadMap = {
162
274
  CONTENT_UPDATE: ContentUpdateEvent;
275
+ CONTENT_PATCH: ContentPatchEvent;
163
276
  SELECT_UPDATE: SelectUpdateEvent;
164
277
  HOVER_UPDATE: SelectUpdateEvent;
165
278
  FIELD_UPDATE: FieldUpdateEvent;
279
+ FIELD_SELECT: FieldSelectEvent;
166
280
  };
167
281
 
168
- export declare type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE';
282
+ export declare type EventType = 'CONTENT_UPDATE' | 'CONTENT_PATCH' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE' | 'FIELD_SELECT';
169
283
 
170
284
  export declare type FetchClient = (input: URL | string | RequestInfo, init?: RequestInit) => Promise<unknown>;
171
285
 
286
+ /** Addresses a field within a block, supporting nested objects and arrays. */
287
+ export declare type FieldPath = (string | number)[];
288
+
289
+ /**
290
+ * Deep-select a specific field (e.g. a rich text field) so the editor opens
291
+ * its own editor for that field instead of editing it inline in the preview.
292
+ */
293
+ export declare type FieldSelectEvent = {
294
+ itemId: string;
295
+ path: FieldPath;
296
+ };
297
+
172
298
  export declare type FieldUpdateEvent = {
173
299
  itemId: string;
174
- field: string;
175
- value: string;
300
+ /** Path to the field within the block. Preferred over `field`. */
301
+ path?: FieldPath;
302
+ /** @deprecated Use `path`. Kept for flat string fields. */
303
+ field?: string;
304
+ value: unknown;
176
305
  };
177
306
 
178
307
  /**
@@ -180,6 +309,9 @@ export declare type FieldUpdateEvent = {
180
309
  */
181
310
  export declare function filterSitemapEntries(entries: IBSitemapEntry[], options?: SitemapFilterOptions): IBSitemapEntry[];
182
311
 
312
+ /** Read the value at `path` within `target`, or undefined if absent. */
313
+ export declare function getAtPath(target: unknown, path: FieldPath): unknown;
314
+
183
315
  export declare interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {
184
316
  slug?: string;
185
317
  language?: string;
@@ -418,26 +550,63 @@ export declare type IdFilter = string | {
418
550
  '!null': true;
419
551
  };
420
552
 
553
+ declare type Listener = () => void;
554
+
421
555
  export declare function normalizePathSegment(value: string | null | undefined): string;
422
556
 
423
557
  export declare class PreviewBridge {
424
558
  private static instance;
425
559
  private readonly listeners;
426
560
  private initialized;
561
+ private allowedOrigins;
562
+ /** Origin of the editor, captured from the first trusted message. */
563
+ private parentOrigin;
427
564
  private constructor();
428
565
  static getInstance(): PreviewBridge;
429
- init(): void;
566
+ init(options?: PreviewBridgeInitOptions): void;
430
567
  destroy(): void;
431
568
  isInPreviewMode(): boolean;
432
569
  on<T extends EventType>(eventType: T, callback: EventCallback<EventPayloadMap[T]>): () => void;
433
570
  selectItem(selectedItem: string): void;
571
+ /** Deep-select a nested field (e.g. a rich text field) in the editor. */
572
+ selectField(itemId: string, path: FieldPath): void;
573
+ /** @deprecated Prefer {@link updateFieldAt} with a path. */
434
574
  updateField(itemId: string, field: string, value: string): void;
575
+ /** Stream an inline edit back to the editor, addressed by path. */
576
+ updateFieldAt(itemId: string, path: FieldPath, value: unknown): void;
577
+ private post;
435
578
  private handleMessage;
579
+ private isOriginTrusted;
436
580
  private notify;
437
581
  }
438
582
 
439
583
  export declare const previewBridge: PreviewBridge;
440
584
 
585
+ export declare interface PreviewBridgeInitOptions {
586
+ /**
587
+ * Origins the editor is allowed to post from. When provided, messages from
588
+ * any other origin are ignored. When omitted, the bridge locks onto the
589
+ * origin of the first valid message it receives (trust-on-first-use).
590
+ */
591
+ allowedOrigins?: string[];
592
+ }
593
+
594
+ /**
595
+ * A framework-agnostic, reactive holder for the content tree shown in the
596
+ * preview. The editor pushes whole-tree (`CONTENT_UPDATE`) or granular
597
+ * (`CONTENT_PATCH`) changes; subscribers re-render from the new snapshot.
598
+ */
599
+ export declare class PreviewStore<T = Record<string, unknown>> {
600
+ private content;
601
+ private readonly listeners;
602
+ constructor(initial: T);
603
+ subscribe: (listener: Listener) => (() => void);
604
+ getSnapshot: () => T;
605
+ setContent(next: T): void;
606
+ patch(path: FieldPath, value: unknown): void;
607
+ private emit;
608
+ }
609
+
441
610
  export declare interface RedirectFetchOptions extends CollectionFetchOptions {
442
611
  forceRefresh?: boolean;
443
612
  }
@@ -475,6 +644,16 @@ export declare type SelectUpdateEvent = {
475
644
 
476
645
  export declare function serializeFilter(filter: Record<string, unknown>): Record<string, string>;
477
646
 
647
+ /** Return a copy of `target` with the value at `path` replaced. Immutable. */
648
+ export declare function setAtPath<T>(target: T, path: FieldPath, value: unknown): T;
649
+
650
+ /**
651
+ * Set the scroll offset used when a selected block is scrolled into view.
652
+ * Pass your fixed header's height so selection no longer overshoots beneath it.
653
+ * A number is treated as pixels; strings are used verbatim (e.g. `"5rem"`).
654
+ */
655
+ export declare function setPreviewScrollOffset(offset: number | string): void;
656
+
478
657
  export declare interface SitemapFilterOptions {
479
658
  /** Absolute base URL used for deduplication. Without it, paths are compared as strings. */
480
659
  siteUrl?: string;