typebulb 0.13.0 → 0.13.2

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/render.js CHANGED
@@ -277,7 +277,7 @@ ${s.map(({variableName:n,uniqueLocalName:o})=>` reactHotLoader.register(${n}, "
277
277
  // otherwise fail with cryptic CORS/CSP errors. Detect it and fail clearly.
278
278
  //
279
279
  // The same sandboxed-iframe path also backs the CLI's default (untrusted) launch
280
- // (Specs/Typebulb-CLI-Trust.md), where the right message names \`--trust\` rather
280
+ // (TB-Trust.md), where the right message names \`--trust\` rather
281
281
  // than "no host bridge". The host injects window.__TB_EMBED_ERR__ to override the
282
282
  // text; absent it, the nested-bulb wording applies.
283
283
  const isEmbedded = window.parent !== window;
@@ -481,6 +481,7 @@ ${s.map(({variableName:n,uniqueLocalName:o})=>` reactHotLoader.register(${n}, "
481
481
  }
482
482
  })();
483
483
  `;function Of(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var $f=` *, *::before, *::after { box-sizing: border-box; }
484
+ canvas { max-width: 100%; }
484
485
  body { margin: 0; display: flow-root; font-family: system-ui, -apple-system, sans-serif; }
485
486
  html[data-theme="dark"] { color-scheme: dark; }
486
487
  html[data-theme="light"] { color-scheme: light; }`;function Ff(t,e){let s=n=>n.replace(/<\/script/gi,"<\\/script");return` <script>
@@ -551,6 +552,7 @@ ${qy}
551
552
 
552
553
  <script type="module">
553
554
  ${y(s)}
555
+ ${d?"globalThis.__tbEntryRan = true; /* load-failure backstop \u2014 see embedProtocol */":""}
554
556
  <\/script>
555
557
  </body>
556
558
  </html>`}var qy=`<script>
@@ -602,17 +604,25 @@ ${y(s)}
602
604
  };
603
605
  var update = function () { if (!raf) raf = requestAnimationFrame(apply); };
604
606
  de.style.overflow = 'hidden';
607
+ var errorPosted = false;
608
+ var postError = function (message) { errorPosted = true; post({ __typebulbEmbed: true, kind: 'error', message: String(message) }); };
609
+ // Capture phase: a resource/module load failure (a <script>/<link>/<img> that 404s) does NOT
610
+ // bubble, so it reaches window only here, carrying the failing element as e.target (no message).
611
+ window.addEventListener('error', function (e) {
612
+ var t = e && e.target;
613
+ if (t && t !== window && (t.src || t.href)) postError('Failed to load ' + (t.src || t.href));
614
+ }, true);
605
615
  window.addEventListener('error', function (e) {
606
616
  var m = String((e && e.message) || (e && e.error) || 'Error');
607
617
  // The benign "ResizeObserver loop completed\u2026" notice surfaces as a window error in
608
618
  // some browsers; it's not a bulb fault, so don't forward it to the host as one.
609
619
  if (m.indexOf('ResizeObserver') !== -1) return;
610
- post({ __typebulbEmbed: true, kind: 'error', message: m });
620
+ postError(m);
611
621
  });
612
622
  window.addEventListener('unhandledrejection', function (e) {
613
623
  var r = e && e.reason;
614
624
  var msg = r && r.message ? r.message : (r == null ? 'Unhandled rejection' : r);
615
- post({ __typebulbEmbed: true, kind: 'error', message: String(msg) });
625
+ postError(msg);
616
626
  });
617
627
  // Run at load (module mounted \u2192 real content, not the empty pre-mount body that would
618
628
  // collapse the frame and snap back). Observe BOTH body (content growth) and the root
@@ -622,6 +632,12 @@ ${y(s)}
622
632
  if (window.ResizeObserver) {
623
633
  try { var ro = new ResizeObserver(update); ro.observe(document.body); ro.observe(de); } catch (e) {}
624
634
  }
635
+ // Load-failure backstop: if the entry module never evaluated \u2014 its import graph failed to
636
+ // resolve (a 404'd dependency, which throws nothing catchable) \u2014 surface it. A module that
637
+ // only renders asynchronously still evaluates its top level, so this won't fire on a slow bulb.
638
+ if (!window.__tbEntryRan && !errorPosted) {
639
+ postError('Bulb failed to load: a module or dependency could not be fetched (see the browser console for the failing URL).');
640
+ }
625
641
  });
626
642
  })();
627
643
  <\/script>`;function jy(t){let e={};for(let[s,n]of Object.entries(t))e[s]=n.startsWith("https://")?"/proxy/"+n:n;return e}var Kn="https://esm.sh",Un="https://cdn.jsdelivr.net/npm/",jc="https://data.jsdelivr.com/v1/package/npm/";function qf(t){let e=(t||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var ge=class t{constructor(e,s,n){let o=typeof e=="string"?t.parse(e):e;this.name=o.name,this.version=Ls(s??o.version),this.subpath=Ls(n??o.subpath)}static parse(e){let s=qf(e||"");if(!s.length)return new t({name:""});if(s[0].startsWith("@")){let o=s[0],[i,a]=jf(s[1]??""),l=Ls(s.slice(2).join("/"));return new t({name:`${o}/${i}`,version:a,subpath:l})}else{let[o,i]=jf(s[0]),a=Ls(s.slice(1).join("/"));return new t({name:o,version:i,subpath:a})}}static fromUrl(e){try{let s=new URL(e),n=new URL(Kn).host,o=new URL(Un).host;if(s.host===n){let i=qf(s.pathname.replace(/^\/v\d+\//,"/"));if(!i.length)return;let a=i[0].startsWith("@")?`${i[0]}/${i[1]??""}`:i[0];return t.parse(a)}if(s.host===o){let i=s.pathname.split("/npm/")[1];if(!i)return;let a=i.split("/")[0]||"";return t.parse(a)}return}catch{return}}static versionFromUrl(e){return t.fromUrl(e)?.version}format(){let e=this.version?`${this.name}@${this.version}`:this.name;return this.subpath?`${e}/${this.subpath}`:e}root(){return this.name}static rootOf(e){return t.parse(e).name}withVersion(e){return new t({name:this.name,version:Ls(e),subpath:this.subpath})}withPreferredVersion(e,s){let n=e||s;return n?this.withVersion(n):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let s=e.toLowerCase();return!s.startsWith("http://")&&!s.startsWith("https://")}},Ls=t=>t&&t.length?t:void 0,jf=t=>{let e=t.indexOf("@");return e<0?[t,void 0]:[t.slice(0,e),Ls(t.slice(e+1))]};async function Oe(t){try{return await t()}catch{return}}var Jn=class{constructor(e,s){this.cache=e,this.http=s,this.esmHost=Kn,this.jsDelivrBase=Un,this.jsDelivrMeta=jc,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let s=e||"";return s.startsWith("./")?s.slice(2):s.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let s=typeof e=="string"?new ge(e):e;return`${this.jsDelivrBase}${s.name}${s.version?`@${s.version}`:""}/`}file(e,s){return new URL(this.normalizeRelative(s),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,s={}){let{target:n="es2022",bundle:o=!1,external:i}=s,a=new URLSearchParams({target:n});return o&&a.append("bundle",""),i?.length&&a.append("external",i.join(",")),`${this.esmHost}/${e}?${a.toString()}`}async pinEsmUrl(e,s="es2022"){let n=this.buildEsmUrl(e,{target:s}),o=await Oe(()=>this.http.head(n));return o?.ok?o.url||n:void 0}async resolveExactVersion(e){let s=Date.now(),n=this.pinCache.get(e);if(n&&s-n.ts<this.pinMs)return n.value;let o=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:o,ts:s}),o}async tryResolveFromUrls(e){for(let s of e){let n=await Oe(()=>this.http.head(s)),o=this.parseVersionFromUrl(n?.url||s);if(o)return o}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let s=await this.cache.getIndex(e);if(s&&Date.now()-s.updatedAt<this.versionsIndexMs)return{versions:s.versions,distTags:s.distTags};let n=await Oe(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!n?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let o=n.distTags&&Object.keys(n.distTags).length?n.distTags:void 0;return await this.cache.setIndex(e,n.versions,o),n}parseVersionFromUrl(e){let s=ge.fromUrl(e)?.version;return s&&/\d+\.\d+\.\d+/.test(s)?s:void 0}async fetchPackageMeta(e,s){let n=await this.cache.getMeta(e,s);if(n&&Date.now()-n.updatedAt<this.metaTtlMs){let{dependencies:d,peerDependencies:h,peerDependenciesMeta:A}=n;return{name:e,version:s,dependencies:d,peerDependencies:h,peerDependenciesMeta:A}}let o=this.packageJson(new ge(`${e}@${s}`)),i=await Oe(()=>this.http.getJson(o));if(!i)return;let a=d=>d&&Object.keys(d).length?d:void 0,l=a(i.dependencies),u=a(i.peerDependencies),f=a(i.peerDependenciesMeta);return await this.cache.setMeta(e,s,l,u,f),{name:e,version:s,dependencies:l,peerDependencies:u,peerDependenciesMeta:f}}};var Kf=t=>t.startsWith("@types/"),Hn=t=>Object.keys(t?.peerDependencies||{}).filter(e=>!Kf(e)),Kc=t=>Object.keys(t?.dependencies||{}).filter(e=>!Kf(e)),Ky=t=>Hn(t).filter(e=>!t?.peerDependenciesMeta?.[e]?.optional),Gn=class{constructor(e){this.cdn=e}async resolve(e,s){let n=await this.fetchMeta(e),{allRoots:o,autoAddedPeers:i}=await this.expandWithPeers(n,s),a=this.computeFlags(o);return{allRoots:o,flags:a,autoAddedPeers:i}}async fetchMeta(e){return Promise.all(e.map(async({name:s,version:n})=>({name:s,version:n,meta:await this.cdn.fetchPackageMeta(s,n)})))}async expandWithPeers(e,s){let n=new Map(e.map(i=>[i.name,i])),o=[];for(let i of e)for(let a of Ky(i.meta))!n.has(a)&&!o.some(l=>l.name===a)&&o.push({name:a,requiredBy:i.name});for(let{name:i,requiredBy:a}of o)try{let l=await s(i),u=await this.cdn.fetchPackageMeta(i,l);n.set(i,{name:i,version:l,meta:u})}catch(l){console.warn(`[typebulb] Failed to resolve peer "${i}" for "${a}":`,l)}return{allRoots:[...n.values()],autoAddedPeers:o.filter(i=>n.has(i.name))}}computeFlags(e){let s=new Set(e.flatMap(i=>Hn(i.meta))),n=new Map;for(let i of e)for(let a of Kc(i.meta))n.set(a,(n.get(a)||0)+1);let o=new Set([...n.entries()].filter(([,i])=>i>=2).map(([i])=>i));return new Map(e.map(i=>[i.name,{isPeerRoot:s.has(i.name),hasPeers:Hn(i.meta).length>0,isSharedDep:o.has(i.name)}]))}};var Vn=class{constructor(e,s,n){this.cache=e,this.cdn=s,this.semver=n}selectVersionFromIndex(e,s,n){return this.semver.selectBestVersion(e,{range:s,distTags:n})}async learnExactVersion(e){let s=await Oe(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let n=this.semver.selectBestVersion(s.versions,{distTags:s.distTags});if(n)return n}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,s){if(!s)return this.learnExactVersion(e);let n=await this.cache.getPinnedExact(e,s);if(n){if(this.semver.isExactVersion(n))return n;console.debug("[typebulb] cached version for",e,"is not exact (",n,"); re-resolving from registry")}let o=await Oe(()=>this.cdn.fetchVersionsIndex(e));if(o?.versions?.length){let a=this.selectVersionFromIndex(o.versions,s,o.distTags);if(a){if(this.semver.isExactVersion(a))return await this.cache.setPinnedExact(e,s,a),a}else{console.debug("[typebulb] refreshing version cache for",e,"(",s,"not in cached set \u2014 likely a new release)"),await this.cache.invalidateVersionsCache(e);let l=await Oe(()=>this.cdn.fetchVersionsIndex(e));if(l?.versions?.length){let u=this.selectVersionFromIndex(l.versions,s,l.distTags);if(u&&this.semver.isExactVersion(u))return await this.cache.setPinnedExact(e,s,u),u}}}let i=await this.cdn.resolveExactVersion(`${e}@${s}`);if(i&&this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,s,i),i}async effectivePackage(e,s){let n=new ge(e),o=n.root(),i=s[o],a=i?await Oe(()=>this.cache.getPinnedExact(o,i))??await Oe(()=>this.resolveExactForRoot(o,i)):void 0;return{effectivePackage:a?n.withVersion(a).format():e,root:o,range:i,pinned:a}}};var Uf;(function(t){t[t.Static=1]="Static",t[t.Dynamic=2]="Dynamic",t[t.ImportMeta=3]="ImportMeta",t[t.StaticSourcePhase=4]="StaticSourcePhase",t[t.DynamicSourcePhase=5]="DynamicSourcePhase",t[t.StaticDeferPhase=6]="StaticDeferPhase",t[t.DynamicDeferPhase=7]="DynamicDeferPhase"})(Uf||(Uf={}));var Uy=new Uint8Array(new Uint16Array([1]).buffer)[0]===1;function Uc(t,e="@"){if(!oe)return Jc.then((()=>Uc(t)));let s=t.length+1,n=(oe.__heap_base.value||oe.__heap_base)+4*s-oe.memory.buffer.byteLength;n>0&&oe.memory.grow(Math.ceil(n/65536));let o=oe.sa(s-1);if((Uy?Hy:Jy)(t,new Uint16Array(oe.memory.buffer,o,s)),!oe.parse())throw Object.assign(new Error(`Parse error ${e}:${t.slice(0,oe.e()).split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "Typebulb CLI to run single-file markdown apps called bulbs, either as standalone web apps or embedded in agent responses.",
5
5
  "license": "MIT",
6
6
  "repository": {