@bettercms-ai/preview-runtime 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1,2 @@
1
- "use strict";(()=>{function U(e){let o=new ArrayBuffer(e.byteLength);return new Uint8Array(o).set(e),o}function P(e){let{protocol:o,...t}=e;return{...t,runtimeProtocol:o,nativeViewports:e.nativeViewports.map(n=>({...n}))}}function O(e){if(e===null||typeof e=="boolean"||typeof e=="string")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("Canonical JSON only supports finite numbers");if(Object.is(e,-0))return"0";let o=JSON.stringify(e),t=/^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(o);if(!t)return o;let[,n,r,c="",m]=t,a=`${r}${c}`,d=r.length+Number(m);return d<=0?`${n}0.${"0".repeat(-d)}${a}`:d>=a.length?`${n}${a}${"0".repeat(d-a.length)}`:`${n}${a.slice(0,d)}.${a.slice(d)}`}if(Array.isArray(e))return`[${e.map(o=>{try{return O(o)}catch{return"null"}}).join(",")}]`;if(e&&typeof e=="object"){let o=Object.entries(e).filter(([,n])=>n!==void 0&&typeof n!="function").sort(([n],[r])=>n<r?-1:n>r?1:0),t=[];for(let[n,r]of o)try{t.push(`${JSON.stringify(n)}:${O(r)}`)}catch{}return`{${t.join(",")}}`}throw new TypeError("Unsupported canonical JSON value")}async function x(e){let o=new TextEncoder().encode(O(e)),t=await crypto.subtle.digest("SHA-256",U(o));return`sha256:${[...new Uint8Array(t)].map(r=>r.toString(16).padStart(2,"0")).join("")}`}var f="bcms-component-preview/2";function L(e){let{claims:o,dashboardOrigin:t,onProps:n,onStatus:r=()=>{},onError:c=()=>{},retryIntervalMs:m=400,maxAnnounces:a=10,ackDeadlineMs:d=250}=e,S=P(o),u=null,k=!1,I=0,M=0,h=null,l=s=>{u?.postMessage({protocol:f,binding:S,...s})},E=()=>{h!==null&&clearInterval(h),h=null};if(typeof window>"u"||window.parent===window)return r({kind:"not-embedded",dashboardOrigin:t}),{dispose:()=>{}};let v=()=>{if(!k){if(I>=a){E(),console.warn(`[bcms] no BetterCMS dashboard answered at ${t}. If the dashboard is on another origin, dashboardOrigin is misconfigured.`),r({kind:"unanswered",dashboardOrigin:t});return}I+=1,window.parent.postMessage({protocol:f,kind:"runtime:ready",binding:S},t)}},H=async s=>{let i=s.data;if(i?.protocol!==f||i.kind!=="props")return;let p=i.propsRevision;if(typeof p!="number"||p<=M)return;let C=await x(i.props);if(C!==i.propsHash){l({kind:"runtime:error",error:{code:"PROPS_HASH_MISMATCH",message:"Props did not match their hash."}});return}M=p;try{await n(i.props)}catch(K){console.error("[bcms] component render failed:",K),l({kind:"runtime:error",error:{code:"RENDER_FAILED",message:"The component could not be rendered."}});return}let R=!1,_=()=>{R||(R=!0,l({kind:"props:ack",propsRevision:p,propsHash:C}))};requestAnimationFrame(()=>requestAnimationFrame(_)),setTimeout(_,d)},N=s=>{if(s.origin!==t){let C=s.data;s.source===window.parent&&C?.kind==="runtime:connect"&&console.warn(`[bcms] a BetterCMS dashboard at ${s.origin} tried to connect, but dashboardOrigin is ${t}. Refusing \u2014 set dashboardOrigin to ${s.origin} if that is your dashboard.`);return}if(s.source!==window.parent)return;let i=s.data;if(i?.protocol!==f||i.kind!=="runtime:connect")return;let p=s.ports[0];p&&(k=!0,E(),u=p,u.onmessage=H,u.start?.(),r({kind:"connected"}),l({kind:"runtime:connected"}))},T=s=>{let i={code:"RUNTIME_ERROR",message:String(s.message).slice(0,300)};c(i),l({kind:"runtime:error",error:i})},A=s=>{let i={code:"UNHANDLED_REJECTION",message:String(s.reason).slice(0,300)};c(i),l({kind:"runtime:error",error:i})};return r({kind:"connecting",dashboardOrigin:t}),window.addEventListener("message",N),window.addEventListener("error",T),window.addEventListener("unhandledrejection",A),v(),h=setInterval(v,m),{dispose:()=>{E(),window.removeEventListener("message",N),window.removeEventListener("error",T),window.removeEventListener("unhandledrejection",A),u?.close(),u=null,k=!1}}}function B(e){typeof window>"u"||window.parent===window||window.parent.postMessage({protocol:f,kind:"runtime:refused",cause:e.cause},e.dashboardOrigin)}var F=15e3,b=document.getElementById("bcms-status"),g=document.getElementById("bcms-frame"),y=JSON.parse(document.getElementById("bcms-preview-config").textContent),w=e=>{b.textContent=e,b.hidden=!1},D=(e,o)=>fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(o),credentials:"omit",cache:"no-store"}),J=50;function $(){try{let e=g.contentDocument;return!e||e.readyState==="loading"||e.location.href==="about:blank"?!1:!!e.querySelector("[data-bcms-preview-render]")}catch{return!1}}function V(e){return new Promise((o,t)=>{let n=!1,r=a=>{if(!n){if(n=!0,clearInterval(m),clearTimeout(c),g.onload=null,a){t(a);return}b.hidden=!0,g.hidden=!1,o()}},c=setTimeout(()=>r(new Error("render timed out")),F),m=setInterval(()=>{$()&&r()},J);g.onload=()=>r($()?void 0:new Error("the render page did not render (blocked, not found, or failed)")),g.src=`${y.routes.render}?id=${encodeURIComponent(e)}`})}async function j(){let e=new URL(location.href).searchParams.get("bcmsSession");history.replaceState(null,"",location.pathname);let t=await(await D(y.routes.session,{token:e})).json().catch(()=>null);if(!t||!t.ok){let n=t&&!t.ok&&t.cause==="keys-unreachable"?"keys-unreachable":"session-refused";B({dashboardOrigin:y.dashboardOrigin,cause:n}),w("This preview session was refused. The runtime log records why.");return}L({claims:t.claims,dashboardOrigin:y.dashboardOrigin,onProps:async n=>{let r=await D(y.routes.props,{renderKey:t.renderKey,props:n});if(!r.ok)throw new Error(`props were refused (HTTP ${r.status})`);let{id:c}=await r.json();await V(c)},onStatus:n=>{n.kind!=="connected"&&(n.kind==="connecting"?w("Connecting to BetterCMS\u2026"):n.kind==="unanswered"?w(`${n.dashboardOrigin} did not answer.`):w("This page is meant to be opened from BetterCMS."))}})}j().catch(e=>{console.error("[bcms-preview]",e),w("The preview could not start. The browser console records why.")});})();
1
+ "use strict";(()=>{function z(e){let n=new ArrayBuffer(e.byteLength);return new Uint8Array(n).set(e),n}function L(e){let{protocol:n,...r}=e;return{...r,runtimeProtocol:n,nativeViewports:e.nativeViewports.map(t=>({...t}))}}function O(e){if(e===null||typeof e=="boolean"||typeof e=="string")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("Canonical JSON only supports finite numbers");if(Object.is(e,-0))return"0";let n=JSON.stringify(e),r=/^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(n);if(!r)return n;let[,t,o,c="",m]=r,a=`${o}${c}`,d=o.length+Number(m);return d<=0?`${t}0.${"0".repeat(-d)}${a}`:d>=a.length?`${t}${a}${"0".repeat(d-a.length)}`:`${t}${a.slice(0,d)}.${a.slice(d)}`}if(Array.isArray(e))return`[${e.map(n=>{try{return O(n)}catch{return"null"}}).join(",")}]`;if(e&&typeof e=="object"){let n=Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!="function").sort(([t],[o])=>t<o?-1:t>o?1:0),r=[];for(let[t,o]of n)try{r.push(`${JSON.stringify(t)}:${O(o)}`)}catch{}return`{${r.join(",")}}`}throw new TypeError("Unsupported canonical JSON value")}async function $(e){let n=new TextEncoder().encode(O(e)),r=await crypto.subtle.digest("SHA-256",z(n));return`sha256:${[...new Uint8Array(r)].map(o=>o.toString(16).padStart(2,"0")).join("")}`}var B=/^(chrome-extension|moz-extension|safari-web-extension|safari-extension):\/\//i,X=/^at .*?\(?([a-z][a-z0-9+.-]*:\/\/[^\s()]+?):\d+(?::\d+)?\)?$/i,Y=/@([a-z][a-z0-9+.-]*:\/\/[^\s()]+?):\d+(?::\d+)?$/i;function D(e){if(!e)return[];let n=[];for(let r of e.split(`
2
+ `)){let t=r.trim(),o=t.startsWith("at ")?X.exec(t):Y.exec(t);o?.[1]&&n.push(o[1])}return n}var K=e=>e.every(n=>B.test(n));function b(e){let n=e?.stack;return typeof n=="string"?n:void 0}function H(e,n){return!e||!B.test(e)?!1:K(D(n))}function F(e){let n=D(e);return n.length>0&&K(n)}var f="bcms-component-preview/2";function U(e){let{claims:n,dashboardOrigin:r,onProps:t,onStatus:o=()=>{},onError:c=()=>{},retryIntervalMs:m=400,maxAnnounces:a=10,ackDeadlineMs:d=250}=e,I=L(n),p=null,k=!1,M=0,N=0,h=null,l=s=>{p?.postMessage({protocol:f,binding:I,...s})},C=()=>{h!==null&&clearInterval(h),h=null};if(typeof window>"u"||window.parent===window)return o({kind:"not-embedded",dashboardOrigin:r}),{dispose:()=>{}};let v=()=>{if(!k){if(M>=a){C(),console.warn(`[bcms] no BetterCMS dashboard answered at ${r}. If the dashboard is on another origin, dashboardOrigin is misconfigured.`),o({kind:"unanswered",dashboardOrigin:r});return}M+=1,window.parent.postMessage({protocol:f,kind:"runtime:ready",binding:I},r)}},W=async s=>{let i=s.data;if(i?.protocol!==f||i.kind!=="props")return;let u=i.propsRevision;if(typeof u!="number"||u<=N)return;let E=await $(i.props);if(E!==i.propsHash){l({kind:"runtime:error",error:{code:"PROPS_HASH_MISMATCH",message:"Props did not match their hash."}});return}N=u;try{await t(i.props)}catch(G){console.error("[bcms] component render failed:",G),l({kind:"runtime:error",error:{code:"RENDER_FAILED",message:"The component could not be rendered."}});return}let x=!1,P=()=>{x||(x=!0,l({kind:"props:ack",propsRevision:u,propsHash:E}))};requestAnimationFrame(()=>requestAnimationFrame(P)),setTimeout(P,d)},T=s=>{if(s.origin!==r){let E=s.data;s.source===window.parent&&E?.kind==="runtime:connect"&&console.warn(`[bcms] a BetterCMS dashboard at ${s.origin} tried to connect, but dashboardOrigin is ${r}. Refusing \u2014 set dashboardOrigin to ${s.origin} if that is your dashboard.`);return}if(s.source!==window.parent)return;let i=s.data;if(i?.protocol!==f||i.kind!=="runtime:connect")return;let u=s.ports[0];u&&(k=!0,C(),p=u,p.onmessage=W,p.start?.(),o({kind:"connected"}),l({kind:"runtime:connected"}))},A=s=>console.warn(`[bcms] ignored an error from a browser extension: ${String(s).slice(0,300)}`),R=s=>{if(H(s.filename,b(s.error)))return A(s.message);let i={code:"RUNTIME_ERROR",message:String(s.message).slice(0,300)};c(i),l({kind:"runtime:error",error:i})},_=s=>{if(F(b(s.reason)))return A(s.reason);let i={code:"UNHANDLED_REJECTION",message:String(s.reason).slice(0,300)};c(i),l({kind:"runtime:error",error:i})};return o({kind:"connecting",dashboardOrigin:r}),window.addEventListener("message",T),window.addEventListener("error",R),window.addEventListener("unhandledrejection",_),v(),h=setInterval(v,m),{dispose:()=>{C(),window.removeEventListener("message",T),window.removeEventListener("error",R),window.removeEventListener("unhandledrejection",_),p?.close(),p=null,k=!1}}}function V(e){typeof window>"u"||window.parent===window||window.parent.postMessage({protocol:f,kind:"runtime:refused",cause:e.cause},e.dashboardOrigin)}var q=15e3,S=document.getElementById("bcms-status"),g=document.getElementById("bcms-frame"),y=JSON.parse(document.getElementById("bcms-preview-config").textContent),w=e=>{S.textContent=e,S.hidden=!1},J=(e,n)=>fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n),credentials:"omit",cache:"no-store"}),Z=50;function j(){try{let e=g.contentDocument;return!e||e.readyState==="loading"||e.location.href==="about:blank"?!1:!!e.querySelector("[data-bcms-preview-render]")}catch{return!1}}function Q(e){return new Promise((n,r)=>{let t=!1,o=a=>{if(!t){if(t=!0,clearInterval(m),clearTimeout(c),g.onload=null,a){r(a);return}S.hidden=!0,g.hidden=!1,n()}},c=setTimeout(()=>o(new Error("render timed out")),q),m=setInterval(()=>{j()&&o()},Z);g.onload=()=>o(j()?void 0:new Error("the render page did not render (blocked, not found, or failed)")),g.src=`${y.routes.render}?id=${encodeURIComponent(e)}`})}async function ee(){let e=new URL(location.href).searchParams.get("bcmsSession");history.replaceState(null,"",location.pathname);let r=await(await J(y.routes.session,{token:e})).json().catch(()=>null);if(!r||!r.ok){let t=r&&!r.ok&&r.cause==="keys-unreachable"?"keys-unreachable":"session-refused";V({dashboardOrigin:y.dashboardOrigin,cause:t}),w("This preview session was refused. The runtime log records why.");return}U({claims:r.claims,dashboardOrigin:y.dashboardOrigin,onProps:async t=>{let o=await J(y.routes.props,{renderKey:r.renderKey,props:t});if(!o.ok)throw new Error(`props were refused (HTTP ${o.status})`);let{id:c}=await o.json();await Q(c)},onStatus:t=>{t.kind!=="connected"&&(t.kind==="connecting"?w("Connecting to BetterCMS\u2026"):t.kind==="unanswered"?w(`${t.dashboardOrigin} did not answer.`):w("This page is meant to be opened from BetterCMS."))}})}ee().catch(e=>{console.error("[bcms-preview]",e),w("The preview could not start. The browser console records why.")});})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettercms-ai/preview-runtime",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Zero-config BetterCMS component previews: builds a preview runtime for Next.js and Astro apps and validates components in CI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,7 @@
23
23
  "prepublishOnly": "bun run build"
24
24
  },
25
25
  "dependencies": {
26
- "@bettercms-ai/component-output": "^0.2.0",
26
+ "@bettercms-ai/component-output": "^0.2.1",
27
27
  "playwright": "^1.55.0"
28
28
  },
29
29
  "devDependencies": {