typebulb 0.7.2 → 0.9.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 +6 -4
- package/dist/index.js +166 -53
- package/dist/render.d.ts +28 -0
- package/dist/render.js +428 -0
- package/package.json +9 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as
|
|
3
|
-
`),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let n=
|
|
4
|
-
`))}else t++}return{frontmatter:n,files:i}}catch{return null}}function xr(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),i=t.slice(r+1).trim();switch(n){case"format":e.format=i;break;case"name":e.name=Pr(i);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Pr(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function St(s){let e=t=>s.files.get(br[t].path)||"";return{name:s.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function Sr(s){try{return JSON.parse(s),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(s)||/^---\s*$/m.test(s)||/^\w[\w\s]*:[ \t]/m.test(s))}function Rt(s){let e=s.trim();return e?Sr(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function Et(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as Rr}from"sucrase";function qe(s,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=Rr(s,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var ae="https://esm.sh",ce="https://cdn.jsdelivr.net/npm/",Ge="https://data.jsdelivr.com/v1/package/npm/";function kt(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var y=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=X(t??n.version),this.subpath=X(r??n.subpath)}static parse(e){let t=kt(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[i,o]=Tt(t[1]??""),a=X(t.slice(2).join("/"));return new s({name:`${n}/${i}`,version:o,subpath:a})}else{let[n,i]=Tt(t[0]),o=X(t.slice(1).join("/"));return new s({name:n,version:i,subpath:o})}}static fromUrl(e){try{let t=new URL(e),r=new URL(ae).host,n=new URL(ce).host;if(t.host===r){let i=kt(t.pathname.replace(/^\/v\d+\//,"/"));if(!i.length)return;let o=i[0].startsWith("@")?`${i[0]}/${i[1]??""}`:i[0];return s.parse(o)}if(t.host===n){let i=t.pathname.split("/npm/")[1];if(!i)return;let o=i.split("/")[0]||"";return s.parse(o)}return}catch{return}}static versionFromUrl(e){return s.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 s.parse(e).name}withVersion(e){return new s({name:this.name,version:X(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},X=s=>s&&s.length?s:void 0,Tt=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),X(s.slice(e+1))]};async function k(s){try{return await s()}catch{return}}var le=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=ae,this.jsDelivrBase=ce,this.jsDelivrMeta=Ge,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new y(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:r="es2022",bundle:n=!1,external:i}=t,o=new URLSearchParams({target:r});return n&&o.append("bundle",""),i?.length&&o.append("external",i.join(",")),`${this.esmHost}/${e}?${o.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),n=await k(()=>this.http.head(r));return n?.ok?n.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let n=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:n,ts:t}),n}async tryResolveFromUrls(e){for(let t of e){let r=await k(()=>this.http.head(t)),n=this.parseVersionFromUrl(r?.url||t);if(n)return n}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let r=await k(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let n=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,n),r}parseVersionFromUrl(e){let t=y.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:p,peerDependencies:u,peerDependenciesMeta:m}=r;return{name:e,version:t,dependencies:p,peerDependencies:u,peerDependenciesMeta:m}}let n=this.packageJson(new y(`${e}@${t}`)),i=await k(()=>this.http.getJson(n));if(!i)return;let o=p=>p&&Object.keys(p).length?p:void 0,a=o(i.dependencies),c=o(i.peerDependencies),d=o(i.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,c,d),{name:e,version:t,dependencies:a,peerDependencies:c,peerDependenciesMeta:d}}};var Ct=s=>s.startsWith("@types/"),de=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!Ct(e)),ze=s=>Object.keys(s?.dependencies||{}).filter(e=>!Ct(e)),Er=s=>de(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),pe=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:i}=await this.expandWithPeers(r,t),o=this.computeFlags(n);return{allRoots:n,flags:o,autoAddedPeers:i}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(i=>[i.name,i])),n=[];for(let i of e)for(let o of Er(i.meta))!r.has(o)&&!n.some(a=>a.name===o)&&n.push({name:o,requiredBy:i.name});for(let{name:i,requiredBy:o}of n)try{let a=await t(i),c=await this.cdn.fetchPackageMeta(i,a);r.set(i,{name:i,version:a,meta:c})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${i}" for "${o}":`,a)}return{allRoots:[...r.values()],autoAddedPeers:n.filter(i=>r.has(i.name))}}computeFlags(e){let t=new Set(e.flatMap(i=>de(i.meta))),r=new Map;for(let i of e)for(let o of ze(i.meta))r.set(o,(r.get(o)||0)+1);let n=new Set([...r.entries()].filter(([,i])=>i>=2).map(([i])=>i));return new Map(e.map(i=>[i.name,{isPeerRoot:t.has(i.name),hasPeers:de(i.meta).length>0,isSharedDep:n.has(i.name)}]))}};var ue=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await k(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let n=await k(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let o=this.selectVersionFromIndex(n.versions,t,n.distTags);if(o){if(this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let a=await k(()=>this.cdn.fetchVersionsIndex(e));if(a?.versions?.length){let c=this.selectVersionFromIndex(a.versions,t,a.distTags);if(c&&this.semver.isExactVersion(c))return await this.cache.setPinnedExact(e,t,c),c}}}let i=await this.cdn.resolveExactVersion(`${e}@${t}`);if(i&&this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}async effectivePackage(e,t){let r=new y(e),n=r.root(),i=t[n],o=i?await k(()=>this.cache.getPinnedExact(n,i))??await k(()=>this.resolveExactForRoot(n,i)):void 0;return{effectivePackage:o?r.withVersion(o).format():e,root:n,range:i,pinned:o}}};import{init as kr,parse as Tr}from"es-module-lexer";var Q=class s{constructor(e,t,r,n){this.version=e,this.cdn=t,this.peer=r,this.cache=n}extractImportsSync(e){let t=new Set;for(let r of s.importPatterns){r.lastIndex=0;for(let n of e.matchAll(r))y.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{y.isBare(n)&&t.add(n)};try{await kr;let[n]=Tr(e);n.forEach(i=>r(e.slice(i.s,i.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,r){let n=(await this.extractImports(e)).filter(u=>!r?.has(y.rootOf(u))),i=[...new Set(n.map(y.rootOf))],o=await Promise.all(i.map(async u=>({name:u,version:await this.resolveVersion(u,t)}))),{allRoots:a,flags:c,autoAddedPeers:d}=await this.peer.resolve(o,u=>this.resolveVersion(u,t)),p=this.buildEntries([...n,...d.map(u=>u.name)],a,c,t);return{importMap:{imports:Object.fromEntries(p)},prefetchUrls:p.map(([,u])=>u)}}async resolveVersion(e,t){let r=t[e],n=r?`${e}@${r}`:e,i=await this.version.resolveExactForRoot(e,r);if(!i){let o=await k(()=>this.cdn.pinEsmUrl(n));if(!o)throw new Error(`Cannot resolve ${n}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);i=y.versionFromUrl(o),i&&r&&await k(()=>this.cache.setPinnedExact(e,r,i))}if(!i)throw new Error(`Cannot resolve ${n}: no concrete version found.`);return i}buildEntries(e,t,r,n){let i=new Map(t.map(f=>[f.name,f])),o=f=>{let l=i.get(y.rootOf(f));return new y(f).withPreferredVersion(l.version,n[l.name]).format()},a=new Set([...r.entries()].filter(([,f])=>f.isPeerRoot||f.isSharedDep).map(([f])=>f)),c=new Set(e.filter(f=>f!==y.rootOf(f)).map(y.rootOf)),d=[],p=new Set,u=new Set(e.filter(f=>f===y.rootOf(f))),m=new Set;for(let f of e){let l=y.rootOf(f),h=i.get(l),{isPeerRoot:g,hasPeers:b,isSharedDep:v}=r.get(l),D=c.has(l),J=f!==l,ie=!(g||v)&&(D||!b),F=this.singletonDepsOf(h,a),oe=J&&u.has(l);oe&&m.add(l);let Y=oe?[...F,l]:F.length?F:void 0;d.push([f,this.cdn.buildEsmUrl(o(f),{bundle:ie,external:Y})]),p.add(f)}let w=new Set([...a,...m]);for(let f of w)i.has(f)&&(p.has(f)||d.push([f,this.cdn.buildEsmUrl(o(f),{})]),d.push([`${f}/`,`${this.cdn.esmHost}/${o(f)}/`]));return d}singletonDepsOf(e,t){return[...new Set([...de(e.meta),...ze(e.meta)])].filter(r=>t.has(r))}};Q.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as _t,satisfies as Cr,maxSatisfying as Ke,major as _r,prerelease as Ir,rsort as Dr,valid as Or}from"semver";var _e=class{cmp(e,t){return e===t?0:_t(e,t)?1:_t(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Cr(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Ke(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Dr(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,i=t?.distTags?.latest;if(i&&e.includes(i)&&this.satisfies(r,i))return i;if(n){let a=Ke(e,r,{includePrerelease:!1});if(a)return a}return Ke(e,r,{includePrerelease:!0})??void 0}majorOf(e){return _r(e)}isPrerelease(e){return Ir(e)!==null}isExactVersion(e){return Or(e)!==null}},V=new _e;function It(s,e){let t=new le(s,e),r=new pe(t),n=new ue(s,t,V);return{packageService:new Q(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}import*as Ht from"fs/promises";import*as A from"path";var Ye=[{name:"es5"},{name:"es2015.core"},{name:"es2015.collection"},{name:"es2015.promise"},{name:"es2015.iterable"},{name:"es2015.symbol"},{name:"es2015.symbol.wellknown"},{name:"es2015.generator"},{name:"es2015.proxy"},{name:"es2015.reflect"},{name:"es2016.array.include"},{name:"es2016.intl"},{name:"es2017.object"},{name:"es2017.string"},{name:"es2017.sharedmemory"},{name:"es2017.typedarrays"},{name:"es2017.date"},{name:"es2017.intl"},{name:"es2018.asynciterable"},{name:"es2018.asyncgenerator"},{name:"es2018.promise"},{name:"es2018.regexp"},{name:"es2018.intl"},{name:"es2019.array"},{name:"es2019.object"},{name:"es2019.string"},{name:"es2019.symbol"},{name:"es2019.intl"},{name:"es2020.bigint"},{name:"es2020.promise"},{name:"es2020.string"},{name:"es2020.sharedmemory"},{name:"es2020.date"},{name:"es2020.number"},{name:"es2020.symbol.wellknown"},{name:"es2020.intl"},{name:"es2021.promise"},{name:"es2021.string"},{name:"es2021.weakref"},{name:"es2021.intl"},{name:"es2022.array"},{name:"es2022.object"},{name:"es2022.error"},{name:"es2022.string"},{name:"es2022.regexp"},{name:"es2022.intl"},{name:"es2023.array"},{name:"es2023.collection"},{name:"es2023.intl",since:"5.5"},{name:"es2024.arraybuffer",since:"5.5"},{name:"es2024.collection",since:"5.5"},{name:"es2024.object",since:"5.5"},{name:"es2024.promise",since:"5.5"},{name:"es2024.regexp",since:"5.5"},{name:"es2024.sharedmemory",since:"5.5"},{name:"es2024.string",since:"5.5"},{name:"esnext.array",since:"5.5"},{name:"esnext.collection"},{name:"esnext.decorators"},{name:"esnext.disposable"},{name:"esnext.error",since:"5.5"},{name:"esnext.float16",since:"5.5"},{name:"esnext.iterator",since:"5.5"},{name:"esnext.object"},{name:"esnext.promise"},{name:"esnext.sharedmemory",since:"5.5"},{name:"esnext.intl"}],Xe=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var Dt=`
|
|
2
|
+
import*as M from"fs/promises";import{readFileSync as Hn}from"fs";import*as S from"path";import{pathToFileURL as Jn}from"url";import{execFile as Vn,spawn as qn}from"child_process";import{promisify as Gn}from"util";import{EventEmitter as Rt}from"events";var Tr={code:{path:"code.tsx",language:"typescript"},css:{path:"styles.css",language:"css"},html:{path:"index.html",language:"html"},config:{path:"config.json",language:"json"},notes:{path:"notes.md",language:"markdown"},data:{path:"data.txt",language:"text"},infer:{path:"infer.md",language:"markdown"},insight:{path:"insight.json",language:"json"},server:{path:"server.ts",language:"typescript"}};function Tt(s){try{let e=s.split(`
|
|
3
|
+
`),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let n=_r(r);if(!n)return null;let i=new Map;for(;t<e.length;){let a=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(a){let l=a[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let c=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!c){t++;continue}let d=c[1];t++;let p=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${d}\\s*$`));)p.push(e[t]),t++;t++,i.set(l,p.join(`
|
|
4
|
+
`))}else t++}return{frontmatter:n,files:i}}catch{return null}}function _r(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),i=t.slice(r+1).trim();switch(n){case"format":e.format=i;break;case"name":e.name=Cr(i);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Cr(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function _t(s){let e=t=>s.files.get(Tr[t].path)||"";return{name:s.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function Ir(s){try{return JSON.parse(s),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(s)||/^---\s*$/m.test(s)||/^\w[\w\s]*:[ \t]/m.test(s))}function Ct(s){let e=s.trim();return e?Ir(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function It(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as Or}from"sucrase";function Ke(s,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=Or(s,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var ce="https://esm.sh",le="https://cdn.jsdelivr.net/npm/",Ye="https://data.jsdelivr.com/v1/package/npm/";function Ot(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=Z(t??n.version),this.subpath=Z(r??n.subpath)}static parse(e){let t=Ot(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[i,o]=Dt(t[1]??""),a=Z(t.slice(2).join("/"));return new s({name:`${n}/${i}`,version:o,subpath:a})}else{let[n,i]=Dt(t[0]),o=Z(t.slice(1).join("/"));return new s({name:n,version:i,subpath:o})}}static fromUrl(e){try{let t=new URL(e),r=new URL(ce).host,n=new URL(le).host;if(t.host===r){let i=Ot(t.pathname.replace(/^\/v\d+\//,"/"));if(!i.length)return;let o=i[0].startsWith("@")?`${i[0]}/${i[1]??""}`:i[0];return s.parse(o)}if(t.host===n){let i=t.pathname.split("/npm/")[1];if(!i)return;let o=i.split("/")[0]||"";return s.parse(o)}return}catch{return}}static versionFromUrl(e){return s.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 s.parse(e).name}withVersion(e){return new s({name:this.name,version:Z(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},Z=s=>s&&s.length?s:void 0,Dt=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),Z(s.slice(e+1))]};async function C(s){try{return await s()}catch{return}}var de=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=ce,this.jsDelivrBase=le,this.jsDelivrMeta=Ye,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new g(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:r="es2022",bundle:n=!1,external:i}=t,o=new URLSearchParams({target:r});return n&&o.append("bundle",""),i?.length&&o.append("external",i.join(",")),`${this.esmHost}/${e}?${o.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),n=await C(()=>this.http.head(r));return n?.ok?n.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let n=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:n,ts:t}),n}async tryResolveFromUrls(e){for(let t of e){let r=await C(()=>this.http.head(t)),n=this.parseVersionFromUrl(r?.url||t);if(n)return n}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let r=await C(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let n=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,n),r}parseVersionFromUrl(e){let t=g.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:d,peerDependencies:p,peerDependenciesMeta:m}=r;return{name:e,version:t,dependencies:d,peerDependencies:p,peerDependenciesMeta:m}}let n=this.packageJson(new g(`${e}@${t}`)),i=await C(()=>this.http.getJson(n));if(!i)return;let o=d=>d&&Object.keys(d).length?d:void 0,a=o(i.dependencies),l=o(i.peerDependencies),c=o(i.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,l,c),{name:e,version:t,dependencies:a,peerDependencies:l,peerDependenciesMeta:c}}};var At=s=>s.startsWith("@types/"),pe=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!At(e)),Xe=s=>Object.keys(s?.dependencies||{}).filter(e=>!At(e)),Dr=s=>pe(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),ue=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:i}=await this.expandWithPeers(r,t),o=this.computeFlags(n);return{allRoots:n,flags:o,autoAddedPeers:i}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(i=>[i.name,i])),n=[];for(let i of e)for(let o of Dr(i.meta))!r.has(o)&&!n.some(a=>a.name===o)&&n.push({name:o,requiredBy:i.name});for(let{name:i,requiredBy:o}of n)try{let a=await t(i),l=await this.cdn.fetchPackageMeta(i,a);r.set(i,{name:i,version:a,meta:l})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${i}" for "${o}":`,a)}return{allRoots:[...r.values()],autoAddedPeers:n.filter(i=>r.has(i.name))}}computeFlags(e){let t=new Set(e.flatMap(i=>pe(i.meta))),r=new Map;for(let i of e)for(let o of Xe(i.meta))r.set(o,(r.get(o)||0)+1);let n=new Set([...r.entries()].filter(([,i])=>i>=2).map(([i])=>i));return new Map(e.map(i=>[i.name,{isPeerRoot:t.has(i.name),hasPeers:pe(i.meta).length>0,isSharedDep:n.has(i.name)}]))}};var he=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await C(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let n=await C(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let o=this.selectVersionFromIndex(n.versions,t,n.distTags);if(o){if(this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let a=await C(()=>this.cdn.fetchVersionsIndex(e));if(a?.versions?.length){let l=this.selectVersionFromIndex(a.versions,t,a.distTags);if(l&&this.semver.isExactVersion(l))return await this.cache.setPinnedExact(e,t,l),l}}}let i=await this.cdn.resolveExactVersion(`${e}@${t}`);if(i&&this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}async effectivePackage(e,t){let r=new g(e),n=r.root(),i=t[n],o=i?await C(()=>this.cache.getPinnedExact(n,i))??await C(()=>this.resolveExactForRoot(n,i)):void 0;return{effectivePackage:o?r.withVersion(o).format():e,root:n,range:i,pinned:o}}};import{init as Ar,parse as Mr}from"es-module-lexer";var ee=class s{constructor(e,t,r,n){this.version=e,this.cdn=t,this.peer=r,this.cache=n}extractImportsSync(e){let t=new Set;for(let r of s.importPatterns){r.lastIndex=0;for(let n of e.matchAll(r))g.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{g.isBare(n)&&t.add(n)};try{await Ar;let[n]=Mr(e);n.forEach(i=>r(e.slice(i.s,i.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,r){let n=(await this.extractImports(e)).filter(p=>!r?.has(g.rootOf(p))),i=[...new Set(n.map(g.rootOf))],o=await Promise.all(i.map(async p=>({name:p,version:await this.resolveVersion(p,t)}))),{allRoots:a,flags:l,autoAddedPeers:c}=await this.peer.resolve(o,p=>this.resolveVersion(p,t)),d=this.buildEntries([...n,...c.map(p=>p.name)],a,l,t);return{importMap:{imports:Object.fromEntries(d)},prefetchUrls:d.map(([,p])=>p)}}async resolveVersion(e,t){let r=t[e],n=r?`${e}@${r}`:e,i=await this.version.resolveExactForRoot(e,r);if(!i){let o=await C(()=>this.cdn.pinEsmUrl(n));if(!o)throw new Error(`Cannot resolve ${n}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);i=g.versionFromUrl(o),i&&r&&await C(()=>this.cache.setPinnedExact(e,r,i))}if(!i)throw new Error(`Cannot resolve ${n}: no concrete version found.`);return i}buildEntries(e,t,r,n){let i=new Map(t.map(f=>[f.name,f])),o=f=>{let R=i.get(g.rootOf(f));return new g(f).withPreferredVersion(R.version,n[R.name]).format()},a=new Set([...r.entries()].filter(([,f])=>f.isPeerRoot||f.isSharedDep).map(([f])=>f)),l=new Set(e.filter(f=>f!==g.rootOf(f)).map(g.rootOf)),c=[],d=new Set,p=new Set(e.filter(f=>f===g.rootOf(f))),m=new Set;for(let f of e){let R=g.rootOf(f),v=i.get(R),{isPeerRoot:E,hasPeers:ae,isSharedDep:u}=r.get(R),h=l.has(R),y=f!==R,b=!(E||u)&&(h||!ae),I=this.singletonDepsOf(v,a),W=y&&p.has(R);W&&m.add(R);let L=W?[...I,R]:I.length?I:void 0;c.push([f,this.cdn.buildEsmUrl(o(f),{bundle:b,external:L})]),d.add(f)}let w=new Set([...a,...m]);for(let f of w)i.has(f)&&(d.has(f)||c.push([f,this.cdn.buildEsmUrl(o(f),{})]),c.push([`${f}/`,`${this.cdn.esmHost}/${o(f)}/`]));return c}singletonDepsOf(e,t){return[...new Set([...pe(e.meta),...Xe(e.meta)])].filter(r=>t.has(r))}};ee.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as Mt,satisfies as $r,maxSatisfying as Qe,major as Fr,prerelease as jr,rsort as Nr,valid as Lr}from"semver";var Oe=class{cmp(e,t){return e===t?0:Mt(e,t)?1:Mt(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!$r(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Qe(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Nr(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,i=t?.distTags?.latest;if(i&&e.includes(i)&&this.satisfies(r,i))return i;if(n){let a=Qe(e,r,{includePrerelease:!1});if(a)return a}return Qe(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Fr(e)}isPrerelease(e){return jr(e)!==null}isExactVersion(e){return Lr(e)!==null}},q=new Oe;function $t(s,e){let t=new de(s,e),r=new ue(t),n=new he(s,t,q);return{packageService:new ee(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}import*as Yt from"fs/promises";import*as F from"path";var Ze=[{name:"es5"},{name:"es2015.core"},{name:"es2015.collection"},{name:"es2015.promise"},{name:"es2015.iterable"},{name:"es2015.symbol"},{name:"es2015.symbol.wellknown"},{name:"es2015.generator"},{name:"es2015.proxy"},{name:"es2015.reflect"},{name:"es2016.array.include"},{name:"es2016.intl"},{name:"es2017.object"},{name:"es2017.string"},{name:"es2017.sharedmemory"},{name:"es2017.typedarrays"},{name:"es2017.date"},{name:"es2017.intl"},{name:"es2018.asynciterable"},{name:"es2018.asyncgenerator"},{name:"es2018.promise"},{name:"es2018.regexp"},{name:"es2018.intl"},{name:"es2019.array"},{name:"es2019.object"},{name:"es2019.string"},{name:"es2019.symbol"},{name:"es2019.intl"},{name:"es2020.bigint"},{name:"es2020.promise"},{name:"es2020.string"},{name:"es2020.sharedmemory"},{name:"es2020.date"},{name:"es2020.number"},{name:"es2020.symbol.wellknown"},{name:"es2020.intl"},{name:"es2021.promise"},{name:"es2021.string"},{name:"es2021.weakref"},{name:"es2021.intl"},{name:"es2022.array"},{name:"es2022.object"},{name:"es2022.error"},{name:"es2022.string"},{name:"es2022.regexp"},{name:"es2022.intl"},{name:"es2023.array"},{name:"es2023.collection"},{name:"es2023.intl",since:"5.5"},{name:"es2024.arraybuffer",since:"5.5"},{name:"es2024.collection",since:"5.5"},{name:"es2024.object",since:"5.5"},{name:"es2024.promise",since:"5.5"},{name:"es2024.regexp",since:"5.5"},{name:"es2024.sharedmemory",since:"5.5"},{name:"es2024.string",since:"5.5"},{name:"esnext.array",since:"5.5"},{name:"esnext.collection"},{name:"esnext.decorators"},{name:"esnext.disposable"},{name:"esnext.error",since:"5.5"},{name:"esnext.float16",since:"5.5"},{name:"esnext.iterator",since:"5.5"},{name:"esnext.object"},{name:"esnext.promise"},{name:"esnext.sharedmemory",since:"5.5"},{name:"esnext.intl"}],et=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var Ft=`
|
|
5
5
|
/**
|
|
6
6
|
* Get raw data chunk from the Data tab.
|
|
7
7
|
* @param index - Chunk index (0-based). Separate chunks with 2 blank lines.
|
|
@@ -12,7 +12,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
12
12
|
* @param index - Chunk index (0-based)
|
|
13
13
|
* @throws If chunk is not valid JSON/JSON-ish
|
|
14
14
|
*/
|
|
15
|
-
json<T = unknown>(index: number): T;`,
|
|
15
|
+
json<T = unknown>(index: number): T;`,jt=`
|
|
16
16
|
/**
|
|
17
17
|
* Get the insight data produced by the inference layer.
|
|
18
18
|
*
|
|
@@ -21,7 +21,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
21
21
|
*
|
|
22
22
|
* @returns The parsed insight JSON, or undefined if no insight is available
|
|
23
23
|
*/
|
|
24
|
-
insight<T = unknown>(): T | undefined;`,
|
|
24
|
+
insight<T = unknown>(): T | undefined;`,Nt=`
|
|
25
25
|
/**
|
|
26
26
|
* General-purpose AI call.
|
|
27
27
|
*
|
|
@@ -38,7 +38,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
38
38
|
model?: string;
|
|
39
39
|
/** Enable/disable web search. Default: on for BYOK, always off for free model. */
|
|
40
40
|
webSearch?: boolean;
|
|
41
|
-
}): Promise<{ text: string }>;`,
|
|
41
|
+
}): Promise<{ text: string }>;`,Lt=`
|
|
42
42
|
/**
|
|
43
43
|
* Returns AI models available to the current user.
|
|
44
44
|
* Models are filtered by the user's configured API keys.
|
|
@@ -53,15 +53,17 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
53
53
|
friendlyName: string;
|
|
54
54
|
/** Provider display name, e.g. "Anthropic" */
|
|
55
55
|
providerName: string;
|
|
56
|
-
}>>;`,
|
|
56
|
+
}>>;`,Br="\n /**\n * The bulb's theme override (`<html data-theme>`).\n *\n * - Get: the current override \u2014 `'dark'` | `'light'`, or `undefined` when\n * following the OS preference.\n * - Set `'dark'`/`'light'` to force and persist it (per-bulb); set\n * `undefined` to clear the override and follow the OS again.\n *\n * Drives `<html data-theme>`, so render off `html[data-theme=\"\u2026\"]` selectors\n * (or observe the attribute) rather than reading `tb.theme`.\n */\n theme: 'light' | 'dark' | undefined;",Bt=`
|
|
57
57
|
/**
|
|
58
58
|
* The mode this bulb is running in.
|
|
59
59
|
*
|
|
60
60
|
* - \`'local'\` \u2014 Running via the typebulb CLI
|
|
61
61
|
* - \`'editor'\` \u2014 Running in the typebulb.com editor
|
|
62
62
|
* - \`'published'\` \u2014 Running as a published/standalone bulb on typebulb.com
|
|
63
|
+
* - \`'embedded'\` \u2014 Running as a bulb embedded inside another bulb (sandboxed,
|
|
64
|
+
* client-only: AI, filesystem, and server RPC are unavailable)
|
|
63
65
|
*/
|
|
64
|
-
mode: 'local' | 'editor' | 'published';`,
|
|
66
|
+
mode: 'local' | 'editor' | 'published' | 'embedded';`,Ut=`
|
|
65
67
|
/**
|
|
66
68
|
* Local filesystem access (CLI only).
|
|
67
69
|
*
|
|
@@ -75,7 +77,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
75
77
|
readBytes(path: string): Promise<Uint8Array>;
|
|
76
78
|
/** Write text or raw bytes to a file. Creates parent directories if needed. */
|
|
77
79
|
write(path: string, content: string | Uint8Array): Promise<boolean>;
|
|
78
|
-
};`,
|
|
80
|
+
};`,Ur=`
|
|
79
81
|
/**
|
|
80
82
|
* Server-side function proxy. The built-in \`log\` prints to CLI stdout
|
|
81
83
|
* (falls back to console.log on web). On the server side, this object only
|
|
@@ -83,7 +85,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
83
85
|
*/
|
|
84
86
|
server: {
|
|
85
87
|
log(...args: any[]): Promise<void>;
|
|
86
|
-
}
|
|
88
|
+
};`,Wr=`
|
|
87
89
|
/**
|
|
88
90
|
* Async value inspector for tensor-like objects.
|
|
89
91
|
*
|
|
@@ -150,7 +152,7 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
150
152
|
*
|
|
151
153
|
* @returns The full canonical URL
|
|
152
154
|
*/
|
|
153
|
-
url(): Promise<string>;`,
|
|
155
|
+
url(): Promise<string>;`,Hr=`
|
|
154
156
|
/**
|
|
155
157
|
* Server-side function proxy.
|
|
156
158
|
*
|
|
@@ -158,24 +160,39 @@ import*as I from"fs/promises";import{readFileSync as jn}from"fs";import*as S fro
|
|
|
158
160
|
* \`tb.server.log(...)\` is a built-in that prints to CLI stdout (falls back to console.log on web).
|
|
159
161
|
* User exports override built-ins of the same name.
|
|
160
162
|
*/
|
|
161
|
-
server: Record<string, (...args: any[]) => Promise<any>>;`,
|
|
163
|
+
server: Record<string, (...args: any[]) => Promise<any>>;`,tt=`
|
|
162
164
|
/**
|
|
163
165
|
* Typebulb utilities namespace.
|
|
164
166
|
* Type \`tb.\` to discover available helpers.
|
|
165
167
|
*/
|
|
166
|
-
declare const tb: {${
|
|
168
|
+
declare const tb: {${Ft}${Wr}${jt}${Hr}${Nt}${Ut}${Lt}${Br}${Bt}
|
|
167
169
|
};
|
|
168
|
-
`,
|
|
170
|
+
`,rt=`
|
|
169
171
|
/**
|
|
170
172
|
* Typebulb utilities namespace (server-side).
|
|
171
173
|
* Type \`tb.\` to discover available helpers.
|
|
172
174
|
*/
|
|
173
|
-
declare const tb: {${
|
|
175
|
+
declare const tb: {${Ft}${jt}${Nt}${Ut}${Ur}${Lt}${Bt}
|
|
174
176
|
};
|
|
175
|
-
`;var H=class{constructor(e){this.store=e}async isNegative(e){let t=await Ie(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let r=((await Ie(()=>this.store.get(e)))?.attempts||0)+1;await Ie(()=>this.store.set(e,{until:Date.now()+jr(r),attempts:r}))}async clearNegative(e){await Ie(()=>this.store.delete(e))}};function jr(s){return Math.min(9e5*Math.pow(2,Math.max(0,s-1)),864e5)}async function Ie(s){try{return await s()}catch{return}}import Jr from"p-limit";import{resolve as jt}from"resolve.exports";var Z=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let r=await this.fetchDts(t);if(r&&(this.looksLikeDts(r.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(r.url)||/[?&]dts(?:[&#]|$)/i.test(r.url)))return r}}looksLikeDts(e){return/^\s*export\s*\{\s*\}\s*;?\s*$/m.test(e)?!0:/declare\s+(module|namespace|class|interface|function|const|var|let)/.test(e)||/interface\s+\w+/.test(e)||/type\s+\w+\s*=/.test(e)}};var U={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},fe=["index.d.ts","index.d.mts"],he=/\.d\.(ts|mts)$/i;function et(s){if(he.test(s))return!0;try{return new URL(s,"file://").search.includes("dts")}catch{return s.includes("?")&&s.includes("dts")}}function De(s){return[`${s}.d.ts`,`${s}.d.mts`]}async function me(s,{retries:e=2,timeoutMs:t=15e3,init:r}={}){for(let n=0;n<=e;n++){let i=new AbortController,o=setTimeout(()=>i.abort(),t);try{let a=await fetch(s,{...r,signal:i.signal});if(Nr(a.status)&&n<e)continue;return a}catch{if(n<e)continue;return}finally{clearTimeout(o)}}}function Nr(s){return s===408||s===429||s>=500&&s<600}var ge=class extends Z{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let r=this.cdnClient.packageJson(new y({name:e,version:t})),n=await me(r);if(!n?.ok)return;let i;try{i=await n.json()}catch{return}if(i)return{pkg:i,baseDir:this.cdnClient.baseDir(new y({name:e,version:t??i.version})),version:t}}extractPathFromResult(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.find(t=>typeof t=="string")}async tryUntilSuccess(e,t){for(let r of e){let n=await t(r);if(n)return n}}async resolveFromSelected(e,t){if(e.kind==="types"){let n=this.cdnClient.normalizeRelative(e.path);if(!n||n==="/"||n===".")return this.tryUntilSuccess([...fe],t);if(!he.test(n)){let i=await this.tryUntilSuccess(this.declarationCandidatesFor(n),t);if(i)return i}return t(n)}let r=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...fe,...r],t)}toResolutionResult(e){return{kind:he.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let r=t||".",n=e;try{let i=this.extractPathFromResult(jt(n,r,{conditions:["types"]}));if(i)return i}catch{}try{return this.extractPathFromResult(jt(n,r,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=y.parse(e),{pkg:r,baseDir:n}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!r||!n)return;let i={name:t.name,version:t.version},o=new y(i).format(),a=new y({...i,subpath:t.subpath}).format(),c=u=>this.fetchCandidateFrom(n,t.name,u);if(t.subpath){let u=this.cdnClient.ensureLeadingDotSlash(t.subpath),m=this.resolveExportsPath(r,u);if(m){let f=await this.resolveFromSelected(this.toResolutionResult(m),c);if(f)return{...f,resolvedPkg:a}}let w=await this.tryUntilSuccess(this.declarationCandidatesFor(u),c);if(w)return{...w,resolvedPkg:a}}let d=r.types??r.typings;if(d){let u=await this.resolveFromSelected({kind:"types",path:d},c);if(u)return{...u,resolvedPkg:o}}let p=this.resolveExportsPath(r,".");if(p){let u=await this.resolveFromSelected(this.toResolutionResult(p),c);if(u)return{...u,resolvedPkg:o}}return}catch{return}}async fetchCandidateFrom(e,t,r){let n=this.cdnClient.normalizeRelative(r),i=new URL(n,e).toString(),o=await this.fetchDtsText(i);return o?{dts:o.dts,url:o.url,resolvedPkg:t}:void 0}declarationCandidatesFor(e){if(!e||e==="./"||e==="/")return[...fe];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),r=De(t),n=t.endsWith("/")?t:`${t}/`;return r.push(...De(`${n}index`)),r}};import{gunzipSync as Lr}from"fflate";var ee=class{async fetchAndExtract(e,t){let r=this.getTarballUrl(e,t),n=await me(r,{timeoutMs:3e4});if(!n?.ok)return new Map;let i=new Uint8Array(await n.arrayBuffer());return this.extractDtsFiles(i)}getTarballUrl(e,t){return`https://registry.npmjs.org/${e.replace("/","%2F")}/-/${e.split("/").pop()}-${t}.tgz`}normalizeTarPath(e){let t=e.replace(/^package\//,""),r=t.indexOf("/");return r>0?t.substring(r+1):t}extractDtsFiles(e){let t=new Map;try{let r=Lr(e),n=new TextDecoder("utf-8"),i=0;for(;i<r.length-512;){let o=r.slice(i,i+512);if(o[0]===0)break;let a=o.slice(0,100),c=a.indexOf(0),d=n.decode(a.slice(0,c>0?c:100)).trim(),p=o.slice(124,136),u=n.decode(p).trim().replace(/\0/g,""),m=parseInt(u,8)||0,w=String.fromCharCode(o[156]);if(i+=512,(w==="0"||w==="\0")&&(d.endsWith(".d.ts")||d.endsWith(".d.mts"))){let f=r.slice(i,i+m);t.set(this.normalizeTarPath(d),n.decode(f))}i+=Math.ceil(m/512)*512}}catch{}return t}},Ur=new ee;var ye=class extends Z{constructor(e,t,r,n=new ee){super(e),this.cdnClient=t,this.cache=r,this.tarballFetcher=n}typesNameCandidates(e){let t=e.startsWith("@")?e.slice(1).replace("/","__"):e;return t.includes(".")?[t,t.split(".").join("-"),t.split(".").join("")]:[t]}selectTypesVersion(e,t,r){try{if(r){let i=V.majorOf(r),o=e.filter(a=>V.majorOf(a)===i);if(o.length)return o.sort((a,c)=>V.cmp(c,a))[0]}let n=t?.latest;return n&&e.includes(n)?n:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let r=new y(e),n=r.version;if(!n)return;let i;try{i=await this.tarballFetcher.fetchAndExtract(r.name,n)}catch{return}if(!i||i.size===0)return;for(let[a,c]of i.entries()){let d=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(d,c)}catch{}}let o=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of o){let c=i.get(a);if(c)return{dts:c,url:this.cdnClient.file(e,a),resolvedPkg:t.subpath?new y(t).format():t.name}}}async resolve(e){let t=y.parse(e);if(t.name)for(let r of this.typesNameCandidates(t.name)){let n=`@types/${r}`,i;try{i=await this.cdnClient.fetchVersionsIndex(n)}catch{continue}if(!i?.versions?.length)continue;let o=this.selectTypesVersion(i.versions,i.distTags,t.version),a=await this.fetchFromVersionedRoot(`${n}@${o}`,t);if(a)return a}}};var we=class{collectRelativeTypeRefs(e){return this.collectRefs(e).filter(t=>t.startsWith("./")||t.startsWith("../"))}collectBareModuleRefs(e){return this.collectRefs(e).filter(t=>this.isBare(t))}collectRefs(e){let t=new Set,r=(n,i)=>(t.add(n[i]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,n=>r(n,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,n=>r(n,1)),Array.from(t)}matchAll(e,t,r){let n=[];try{let i=new RegExp(t.source,"g"),o;for(;o=i.exec(e);){let a=r(o);a!==null&&n.push(a)}}catch{}return n}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var Nt="file:///node_modules",ve=class{constructor(){this.epoch=0,this.listeners=new Set}getEpoch(){return this.epoch}bumpEpoch(){this.epoch+=1;for(let e of this.listeners)try{e(this.epoch)}catch{}return this.epoch}onEpochChange(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}epochDir(){return`__tsepoch_${this.epoch}`}pathForMain(e){return`${Nt}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let r=Br(t);return`${Nt}/${this.epochDir()}/${e}/${r}`}};function Br(s){let e=s||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Wr}from"lru-cache";function tt(s){let e=new Wr({ttl:1e4,max:500}),t=new Map;return async function(n){try{if(await s.isNegative(n))return;let i=e.get(n);if(i&&Date.now()-i<1e4)return;let o=await s.getCachedFile(n);if(o)return{dts:o,url:n};let a=t.get(n);if(a)return a;let c=(async()=>{let d=await fetch(n,{cache:"no-store"});if(!d.ok){d.status===404&&(e.set(n,Date.now()),await s.recordNegative(n));return}let p=await d.text(),u=d.url||n;return await s.clearNegative(n),await s.setCachedFile(u,p),{dts:p,url:u}})();return t.set(n,c),await c.finally(()=>t.delete(n))}catch{return}}}var Oe=class{constructor(e){this.inFlight=new Map,this.scanner=new we,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=tt(e.cache),this.typescriptProvider=new ge(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new ye(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new ve}withInFlight(e,t){let r=this.inFlight.get(e);if(r)return r;let n=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,n),n}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,r){e.some(n=>n.path===t)||e.push({path:t,content:r})}createStubDef(e){let t=this.virtualFs.pathForMain(e);return{pkg:e,mainPath:t,files:[{path:t,content:"export const _shim: any; export default _shim;"}],shims:[{module:e,path:t}]}}async trySubpathWithRootFallback(e,t){let r=new y(e);return r.subpath?this.fetchRootDts(r.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let r=await t.resolve(e);if(r?.dts)return r}catch{}}subpathsMatch(e,t){return new y(e).subpath===new y(t).subpath}async fetchRootDts(e,t){let{effectivePackage:r,root:n,pinned:i}=await this.versionResolver.effectivePackage(e,t),o=await this.cache.getCachedDts(r);if(o?.content){let c=o.url??this.cdnClient.file(i?`${n}@${i}`:n,"index.d.ts");return{dts:o.content,url:c,resolvedPkg:r}}let a;try{a=await this.fetchViaProviders(r)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(r,a.resolvedPkg||r)){try{await this.cache.setCachedDts(r,a.dts,a.url)}catch{}return a}}}extractPackageRootUrl(e){let t=e.pathname.match(/^(.+@[^/]+\/)/);return t?new URL(t[1],e.origin):new URL("./",e)}toVirtualPath(e,t,r){let n=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(r,n)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let r=new URL(e),n=this.extractPackageRootUrl(r);return{mainPath:this.toVirtualPath(n,r,t),packageRootUrl:n}}async expandRelativeRefs(e,t,r,n,i=new Set,o){if(!i.has(t)&&(i.add(t),!(i.size>U.maxRelativeTypeRefs)))try{let a=new URL(t),c=new URL("./",a);o??(o=this.extractPackageRootUrl(a));let d=this.capArray(this.scanner.collectRelativeTypeRefs(e),U.maxRelativeTypeRefs);for(let p of d)await this.tryRelativeRef(p,c,o,r,n,i)}catch{}}async tryRelativeRef(e,t,r,n,i,o){try{let a=new URL(e,t),c=a.pathname+a.search,d=et(c)?[c]:this.typescriptProvider.declarationCandidatesFor(c);for(let p of d){let m=new URL(p,a).toString();if(o.has(m))return;let w=await this.fetchDts(m);if(w?.dts){let f=this.toVirtualPath(r,new URL(w.url),n);this.pushFileIfNew(i,f,w.dts),await this.expandRelativeRefs(w.dts,w.url,n,i,o,r);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new y(e).name!==new y(t).name}async prefetchBareDeps(e,t,r,n,i){try{let o=this.capArray(this.scanner.collectBareModuleRefs(e),U.maxBareDeps).filter(d=>this.isDifferentPackage(d,t));if(!o.length)return;let a=new Set([t]),c=Jr(U.prefetchConcurrency);await Promise.all(o.map(d=>c(()=>this.prefetchBareDepsRecursive(d,r,n,U.maxBareDepth,a,i).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,r,n,i,o){if(n<=0||i.has(e))return;i.add(e);let a=await this.fetchRootDts(e,o);if(!a?.dts)return;let c=a.resolvedPkg||e,d=this.virtualFs.pathForMain(c);this.pushFileIfNew(t,d,a.dts),r.push({module:e,path:d}),a.url&&await this.expandRelativeRefs(a.dts,a.url,c,t);let p=this.capArray(this.scanner.collectBareModuleRefs(a.dts),U.maxBareDeps).filter(u=>!i.has(u));for(let u of p)await this.prefetchBareDepsRecursive(u,t,r,n-1,i,o)}async resolve(e,t,r){let n=await this.packageService.extractImports(e),i=r?[...n,...r]:n;return(await Promise.all(i.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:r}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(r,async()=>{let n=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return n?this.buildDefFromContent(e,n,n.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,r,n){let{dts:i,url:o,resolvedPkg:a}=t,c=new y(a||r),d=c.version?`${c.name}@${c.version}`:c.name,{mainPath:p,packageRootUrl:u}=this.computeEntryPath(o,d),m=[{path:p,content:i}],w=[];o&&await this.expandRelativeRefs(i,o,d,m,void 0,u);let f=m.map(g=>g.content).join(`
|
|
176
|
-
`);await this.prefetchBareDeps(f,
|
|
177
|
-
`,"utf8")}async function
|
|
177
|
+
`;var G=class{constructor(e){this.store=e}async isNegative(e){let t=await De(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let r=((await De(()=>this.store.get(e)))?.attempts||0)+1;await De(()=>this.store.set(e,{until:Date.now()+Jr(r),attempts:r}))}async clearNegative(e){await De(()=>this.store.delete(e))}};function Jr(s){return Math.min(9e5*Math.pow(2,Math.max(0,s-1)),864e5)}async function De(s){try{return await s()}catch{return}}import Yr from"p-limit";import{resolve as Wt}from"resolve.exports";var te=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let r=await this.fetchDts(t);if(r&&(this.looksLikeDts(r.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(r.url)||/[?&]dts(?:[&#]|$)/i.test(r.url)))return r}}looksLikeDts(e){return/^\s*export\s*\{\s*\}\s*;?\s*$/m.test(e)?!0:/declare\s+(module|namespace|class|interface|function|const|var|let)/.test(e)||/interface\s+\w+/.test(e)||/type\s+\w+\s*=/.test(e)}};var H={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},me=["index.d.ts","index.d.mts"],fe=/\.d\.(ts|mts)$/i;function nt(s){if(fe.test(s))return!0;try{return new URL(s,"file://").search.includes("dts")}catch{return s.includes("?")&&s.includes("dts")}}function Ae(s){return[`${s}.d.ts`,`${s}.d.mts`]}async function ge(s,{retries:e=2,timeoutMs:t=15e3,init:r}={}){for(let n=0;n<=e;n++){let i=new AbortController,o=setTimeout(()=>i.abort(),t);try{let a=await fetch(s,{...r,signal:i.signal});if(Vr(a.status)&&n<e)continue;return a}catch{if(n<e)continue;return}finally{clearTimeout(o)}}}function Vr(s){return s===408||s===429||s>=500&&s<600}var ye=class extends te{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let r=this.cdnClient.packageJson(new g({name:e,version:t})),n=await ge(r);if(!n?.ok)return;let i;try{i=await n.json()}catch{return}if(i)return{pkg:i,baseDir:this.cdnClient.baseDir(new g({name:e,version:t??i.version})),version:t}}extractPathFromResult(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.find(t=>typeof t=="string")}async tryUntilSuccess(e,t){for(let r of e){let n=await t(r);if(n)return n}}async resolveFromSelected(e,t){if(e.kind==="types"){let n=this.cdnClient.normalizeRelative(e.path);if(!n||n==="/"||n===".")return this.tryUntilSuccess([...me],t);if(!fe.test(n)){let i=await this.tryUntilSuccess(this.declarationCandidatesFor(n),t);if(i)return i}return t(n)}let r=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...me,...r],t)}toResolutionResult(e){return{kind:fe.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let r=t||".",n=e;try{let i=this.extractPathFromResult(Wt(n,r,{conditions:["types"]}));if(i)return i}catch{}try{return this.extractPathFromResult(Wt(n,r,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=g.parse(e),{pkg:r,baseDir:n}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!r||!n)return;let i={name:t.name,version:t.version},o=new g(i).format(),a=new g({...i,subpath:t.subpath}).format(),l=p=>this.fetchCandidateFrom(n,t.name,p);if(t.subpath){let p=this.cdnClient.ensureLeadingDotSlash(t.subpath),m=this.resolveExportsPath(r,p);if(m){let f=await this.resolveFromSelected(this.toResolutionResult(m),l);if(f)return{...f,resolvedPkg:a}}let w=await this.tryUntilSuccess(this.declarationCandidatesFor(p),l);if(w)return{...w,resolvedPkg:a}}let c=r.types??r.typings;if(c){let p=await this.resolveFromSelected({kind:"types",path:c},l);if(p)return{...p,resolvedPkg:o}}let d=this.resolveExportsPath(r,".");if(d){let p=await this.resolveFromSelected(this.toResolutionResult(d),l);if(p)return{...p,resolvedPkg:o}}return}catch{return}}async fetchCandidateFrom(e,t,r){let n=this.cdnClient.normalizeRelative(r),i=new URL(n,e).toString(),o=await this.fetchDtsText(i);return o?{dts:o.dts,url:o.url,resolvedPkg:t}:void 0}declarationCandidatesFor(e){if(!e||e==="./"||e==="/")return[...me];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),r=Ae(t),n=t.endsWith("/")?t:`${t}/`;return r.push(...Ae(`${n}index`)),r}};import{gunzipSync as qr}from"fflate";var re=class{async fetchAndExtract(e,t){let r=this.getTarballUrl(e,t),n=await ge(r,{timeoutMs:3e4});if(!n?.ok)return new Map;let i=new Uint8Array(await n.arrayBuffer());return this.extractDtsFiles(i)}getTarballUrl(e,t){return`https://registry.npmjs.org/${e.replace("/","%2F")}/-/${e.split("/").pop()}-${t}.tgz`}normalizeTarPath(e){let t=e.replace(/^package\//,""),r=t.indexOf("/");return r>0?t.substring(r+1):t}extractDtsFiles(e){let t=new Map;try{let r=qr(e),n=new TextDecoder("utf-8"),i=0;for(;i<r.length-512;){let o=r.slice(i,i+512);if(o[0]===0)break;let a=o.slice(0,100),l=a.indexOf(0),c=n.decode(a.slice(0,l>0?l:100)).trim(),d=o.slice(124,136),p=n.decode(d).trim().replace(/\0/g,""),m=parseInt(p,8)||0,w=String.fromCharCode(o[156]);if(i+=512,(w==="0"||w==="\0")&&(c.endsWith(".d.ts")||c.endsWith(".d.mts"))){let f=r.slice(i,i+m);t.set(this.normalizeTarPath(c),n.decode(f))}i+=Math.ceil(m/512)*512}}catch{}return t}},Gr=new re;var we=class extends te{constructor(e,t,r,n=new re){super(e),this.cdnClient=t,this.cache=r,this.tarballFetcher=n}typesNameCandidates(e){let t=e.startsWith("@")?e.slice(1).replace("/","__"):e;return t.includes(".")?[t,t.split(".").join("-"),t.split(".").join("")]:[t]}selectTypesVersion(e,t,r){try{if(r){let i=q.majorOf(r),o=e.filter(a=>q.majorOf(a)===i);if(o.length)return o.sort((a,l)=>q.cmp(l,a))[0]}let n=t?.latest;return n&&e.includes(n)?n:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let r=new g(e),n=r.version;if(!n)return;let i;try{i=await this.tarballFetcher.fetchAndExtract(r.name,n)}catch{return}if(!i||i.size===0)return;for(let[a,l]of i.entries()){let c=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(c,l)}catch{}}let o=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of o){let l=i.get(a);if(l)return{dts:l,url:this.cdnClient.file(e,a),resolvedPkg:t.subpath?new g(t).format():t.name}}}async resolve(e){let t=g.parse(e);if(t.name)for(let r of this.typesNameCandidates(t.name)){let n=`@types/${r}`,i;try{i=await this.cdnClient.fetchVersionsIndex(n)}catch{continue}if(!i?.versions?.length)continue;let o=this.selectTypesVersion(i.versions,i.distTags,t.version),a=await this.fetchFromVersionedRoot(`${n}@${o}`,t);if(a)return a}}};var be=class{collectRelativeTypeRefs(e){return this.collectRefs(e).filter(t=>t.startsWith("./")||t.startsWith("../"))}collectBareModuleRefs(e){return this.collectRefs(e).filter(t=>this.isBare(t))}collectRefs(e){let t=new Set,r=(n,i)=>(t.add(n[i]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,n=>r(n,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,n=>r(n,1)),Array.from(t)}matchAll(e,t,r){let n=[];try{let i=new RegExp(t.source,"g"),o;for(;o=i.exec(e);){let a=r(o);a!==null&&n.push(a)}}catch{}return n}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var Ht="file:///node_modules",ve=class{constructor(){this.epoch=0,this.listeners=new Set}getEpoch(){return this.epoch}bumpEpoch(){this.epoch+=1;for(let e of this.listeners)try{e(this.epoch)}catch{}return this.epoch}onEpochChange(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}epochDir(){return`__tsepoch_${this.epoch}`}pathForMain(e){return`${Ht}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let r=zr(t);return`${Ht}/${this.epochDir()}/${e}/${r}`}};function zr(s){let e=s||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Kr}from"lru-cache";function st(s){let e=new Kr({ttl:1e4,max:500}),t=new Map;return async function(n){try{if(await s.isNegative(n))return;let i=e.get(n);if(i&&Date.now()-i<1e4)return;let o=await s.getCachedFile(n);if(o)return{dts:o,url:n};let a=t.get(n);if(a)return a;let l=(async()=>{let c=await fetch(n,{cache:"no-store"});if(!c.ok){c.status===404&&(e.set(n,Date.now()),await s.recordNegative(n));return}let d=await c.text(),p=c.url||n;return await s.clearNegative(n),await s.setCachedFile(p,d),{dts:d,url:p}})();return t.set(n,l),await l.finally(()=>t.delete(n))}catch{return}}}var Me=class{constructor(e){this.inFlight=new Map,this.scanner=new be,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=st(e.cache),this.typescriptProvider=new ye(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new we(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new ve}withInFlight(e,t){let r=this.inFlight.get(e);if(r)return r;let n=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,n),n}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,r){e.some(n=>n.path===t)||e.push({path:t,content:r})}createStubDef(e){let t=this.virtualFs.pathForMain(e);return{pkg:e,mainPath:t,files:[{path:t,content:"export const _shim: any; export default _shim;"}],shims:[{module:e,path:t}]}}async trySubpathWithRootFallback(e,t){let r=new g(e);return r.subpath?this.fetchRootDts(r.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let r=await t.resolve(e);if(r?.dts)return r}catch{}}subpathsMatch(e,t){return new g(e).subpath===new g(t).subpath}async fetchRootDts(e,t){let{effectivePackage:r,root:n,pinned:i}=await this.versionResolver.effectivePackage(e,t),o=await this.cache.getCachedDts(r);if(o?.content){let l=o.url??this.cdnClient.file(i?`${n}@${i}`:n,"index.d.ts");return{dts:o.content,url:l,resolvedPkg:r}}let a;try{a=await this.fetchViaProviders(r)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(r,a.resolvedPkg||r)){try{await this.cache.setCachedDts(r,a.dts,a.url)}catch{}return a}}}extractPackageRootUrl(e){let t=e.pathname.match(/^(.+@[^/]+\/)/);return t?new URL(t[1],e.origin):new URL("./",e)}toVirtualPath(e,t,r){let n=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(r,n)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let r=new URL(e),n=this.extractPackageRootUrl(r);return{mainPath:this.toVirtualPath(n,r,t),packageRootUrl:n}}async expandRelativeRefs(e,t,r,n,i=new Set,o){if(!i.has(t)&&(i.add(t),!(i.size>H.maxRelativeTypeRefs)))try{let a=new URL(t),l=new URL("./",a);o??(o=this.extractPackageRootUrl(a));let c=this.capArray(this.scanner.collectRelativeTypeRefs(e),H.maxRelativeTypeRefs);for(let d of c)await this.tryRelativeRef(d,l,o,r,n,i)}catch{}}async tryRelativeRef(e,t,r,n,i,o){try{let a=new URL(e,t),l=a.pathname+a.search,c=nt(l)?[l]:this.typescriptProvider.declarationCandidatesFor(l);for(let d of c){let m=new URL(d,a).toString();if(o.has(m))return;let w=await this.fetchDts(m);if(w?.dts){let f=this.toVirtualPath(r,new URL(w.url),n);this.pushFileIfNew(i,f,w.dts),await this.expandRelativeRefs(w.dts,w.url,n,i,o,r);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new g(e).name!==new g(t).name}async prefetchBareDeps(e,t,r,n,i){try{let o=this.capArray(this.scanner.collectBareModuleRefs(e),H.maxBareDeps).filter(c=>this.isDifferentPackage(c,t));if(!o.length)return;let a=new Set([t]),l=Yr(H.prefetchConcurrency);await Promise.all(o.map(c=>l(()=>this.prefetchBareDepsRecursive(c,r,n,H.maxBareDepth,a,i).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,r,n,i,o){if(n<=0||i.has(e))return;i.add(e);let a=await this.fetchRootDts(e,o);if(!a?.dts)return;let l=a.resolvedPkg||e,c=this.virtualFs.pathForMain(l);this.pushFileIfNew(t,c,a.dts),r.push({module:e,path:c}),a.url&&await this.expandRelativeRefs(a.dts,a.url,l,t);let d=this.capArray(this.scanner.collectBareModuleRefs(a.dts),H.maxBareDeps).filter(p=>!i.has(p));for(let p of d)await this.prefetchBareDepsRecursive(p,t,r,n-1,i,o)}async resolve(e,t,r){let n=await this.packageService.extractImports(e),i=r?[...n,...r]:n;return(await Promise.all(i.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:r}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(r,async()=>{let n=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return n?this.buildDefFromContent(e,n,n.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,r,n){let{dts:i,url:o,resolvedPkg:a}=t,l=new g(a||r),c=l.version?`${l.name}@${l.version}`:l.name,{mainPath:d,packageRootUrl:p}=this.computeEntryPath(o,c),m=[{path:d,content:i}],w=[];o&&await this.expandRelativeRefs(i,o,c,m,void 0,p);let f=m.map(E=>E.content).join(`
|
|
178
|
+
`);await this.prefetchBareDeps(f,c,m,w,n);let R=l.format(),v=e===R?[e]:[e,R];return w.push(...v.map(E=>({module:E,path:d}))),{pkg:e,mainPath:d,files:m,shims:w}}};function it(s){return new Me(s)}import*as B from"fs/promises";import*as U from"path";import*as qt from"os";import*as ot from"fs/promises";import*as Jt from"crypto";function $(s){return Jt.createHash("sha1").update(s).digest("hex")}async function z(s){try{return JSON.parse(await ot.readFile(s,"utf8"))}catch{return}}async function $e(s){try{return await ot.readFile(s,"utf8")}catch{return}}var Vt=1,J=U.join(qt.homedir(),".typebulb","cache"),xe=U.join(J,"packages"),Pe=U.join(J,"proxy"),Fe=U.join(J,"dts"),Xr=U.join(J,"emit"),at;function P(){return at||(at=Qr()),at}function je(s,e){return U.join(Xr,$(s),e)}async function Qr(){await B.mkdir(J,{recursive:!0});let s=U.join(J,"version.json");if((await Zr(s))?.version===Vt)return;let t=await B.readdir(J).catch(()=>[]);await Promise.all(t.map(r=>B.rm(U.join(J,r),{recursive:!0,force:!0}))),await B.writeFile(s,JSON.stringify({version:Vt})+`
|
|
179
|
+
`,"utf8")}async function Zr(s){try{let e=await B.readFile(s,"utf8");return JSON.parse(e)}catch{return}}import*as V from"fs/promises";import*as Gt from"path";async function O(s,e){await V.mkdir(Gt.dirname(s),{recursive:!0});let t=`${s}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await V.writeFile(t,e,"utf8"),await V.rename(t,s).catch(async r=>{throw await V.rm(t,{force:!0}).catch(()=>{}),r})}var ne=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=z(this.filePath).then(e=>(this.mem=new Map(Object.entries(e??{})),this.mem))),this.loadPromise)}async get(e){return(await this.load()).get(e)}async set(e,t){let r=await this.load();r.set(e,t),await this.persist(r)}async delete(e){let t=await this.load();t.delete(e)&&await this.persist(t)}async persist(e){await O(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var ct=F.join(xe,"indexes"),zt=F.join(xe,"pinned"),en=F.join(xe,"meta"),tn=F.join(xe,"negative.json"),se=Symbol("missing"),Le=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new G(new ne(tn));async getPinnedExact(e,t){let r=`${e}@${t}`,n=this.pinnedMem.get(r);if(n!==void 0)return n===se?void 0:n;await P();let i=await $e(F.join(zt,$(r)+".txt"));return this.pinnedMem.set(r,i??se),i}async setPinnedExact(e,t,r){let n=`${e}@${t}`;this.pinnedMem.set(n,r),await P(),await O(F.join(zt,$(n)+".txt"),r)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===se?void 0:t;await P();let r=await z(F.join(ct,Ne(e)+".json"));return this.indexMem.set(e,r??se),r}async setIndex(e,t,r){let n={versions:t,distTags:r,updatedAt:Date.now()};this.indexMem.set(e,n),await P(),await O(F.join(ct,Ne(e)+".json"),JSON.stringify(n))}async invalidateVersionsCache(e){this.indexMem.delete(e),await Yt.rm(F.join(ct,Ne(e)+".json"),{force:!0})}async isNegative(e){return await P(),this.negativeCache.isNegative(e)}async recordNegative(e){await P(),await this.negativeCache.recordNegative(e)}async clearNegative(e){await this.negativeCache.clearNegative(e)}async getMeta(e,t){let r=`${e}@${t}`,n=this.metaMem.get(r);if(n!==void 0)return n===se?void 0:n;await P();let i=await z(Kt(e,t));return this.metaMem.set(r,i??se),i}async setMeta(e,t,r,n,i){let o={dependencies:r,peerDependencies:n,peerDependenciesMeta:i,updatedAt:Date.now()};this.metaMem.set(`${e}@${t}`,o),await P(),await O(Kt(e,t),JSON.stringify(o))}};function Kt(s,e){return F.join(en,Ne(s),encodeURIComponent(e)+".json")}function Ne(s){return s.replace(/\//g,"__")}var Xt={async getJson(s){try{let e=await fetch(s,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(s){try{let e=await fetch(s,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}};var rn=new Le,{packageService:Be,versionResolver:Qt,cdnClient:Zt,peerResolver:Gi}=$t(rn,Xt);var er=`
|
|
178
180
|
(() => {
|
|
181
|
+
// Embedded (bulb-in-a-bulb): runs inside a sandboxed iframe with no parent
|
|
182
|
+
// bridge, so privileged tb.* (AI, fs, server RPC) can't reach a host and would
|
|
183
|
+
// otherwise fail with cryptic CORS/CSP errors. Detect it and fail clearly.
|
|
184
|
+
//
|
|
185
|
+
// The same sandboxed-iframe path also backs the CLI's default (untrusted) launch
|
|
186
|
+
// (Specs/Typebulb-CLI-Trust.md), where the right message names \`--trust\` rather
|
|
187
|
+
// than "no host bridge". The host injects window.__TB_EMBED_ERR__ to override the
|
|
188
|
+
// text; absent it, the nested-bulb wording applies.
|
|
189
|
+
const isEmbedded = window.parent !== window;
|
|
190
|
+
const embedErr = (name) => new Error(
|
|
191
|
+
typeof window.__TB_EMBED_ERR__ === 'function'
|
|
192
|
+
? window.__TB_EMBED_ERR__(name)
|
|
193
|
+
: name + ' is not available in an embedded bulb (no host bridge).'
|
|
194
|
+
);
|
|
195
|
+
|
|
179
196
|
// JSON parser (handles jsonish - unquoted keys)
|
|
180
197
|
const parseJson = (str) => {
|
|
181
198
|
try {
|
|
@@ -197,6 +214,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
197
214
|
throw new Error(err.error || 'Failed to ' + action + ' file: ' + path);
|
|
198
215
|
};
|
|
199
216
|
const fetchFileBytes = async (path) => {
|
|
217
|
+
if (isEmbedded) throw embedErr('tb.fs');
|
|
200
218
|
const resp = await fetch('/__fs/read', {
|
|
201
219
|
method: 'POST',
|
|
202
220
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -216,6 +234,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
216
234
|
},
|
|
217
235
|
readBytes: async (path) => new Uint8Array(await fetchFileBytes(path)),
|
|
218
236
|
write: async (path, content) => {
|
|
237
|
+
if (isEmbedded) throw embedErr('tb.fs');
|
|
219
238
|
const resp = await fetch('/__fs/write?path=' + encodeURIComponent(path), {
|
|
220
239
|
method: 'POST',
|
|
221
240
|
body: content
|
|
@@ -243,6 +262,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
243
262
|
|
|
244
263
|
// Inference not available locally
|
|
245
264
|
infer: () => {
|
|
265
|
+
if (isEmbedded) return Promise.reject(embedErr('tb.infer()'));
|
|
246
266
|
alert('This bulb uses AI inference.\\n\\nFor local bulbs, simply ask your AI assistant (e.g. Claude Code) to read your .bulb.md file and edit the data.txt and insight.json blocks directly.');
|
|
247
267
|
return Promise.reject(new Error('tb.infer() is not available in the local CLI.'));
|
|
248
268
|
},
|
|
@@ -252,6 +272,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
252
272
|
|
|
253
273
|
// AI - calls local server which proxies to LLM provider
|
|
254
274
|
ai: async ({ messages, system, reasoning, provider, model, webSearch }) => {
|
|
275
|
+
if (isEmbedded) throw embedErr('tb.ai()');
|
|
255
276
|
const resp = await fetch('/__ai', {
|
|
256
277
|
method: 'POST',
|
|
257
278
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -269,6 +290,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
269
290
|
|
|
270
291
|
// Model discovery - fetches catalog from typebulb.com, filtered by local API keys
|
|
271
292
|
models: async () => {
|
|
293
|
+
if (isEmbedded) return [];
|
|
272
294
|
const resp = await fetch('/__models');
|
|
273
295
|
if (!resp.ok) return [];
|
|
274
296
|
return resp.json();
|
|
@@ -283,17 +305,20 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
283
305
|
// URL
|
|
284
306
|
url: () => Promise.resolve(location.href),
|
|
285
307
|
|
|
286
|
-
// Proxy: rewrite CDN URLs to local server
|
|
308
|
+
// Proxy: rewrite CDN URLs to the local server's /proxy/. Relative on purpose \u2014
|
|
309
|
+
// it resolves against the served page on the CLI, and against the host page
|
|
310
|
+
// inside a srcdoc embed, where location.origin is the string "null".
|
|
287
311
|
proxy: (url) => {
|
|
288
312
|
if (!url) return url;
|
|
289
313
|
const i = url.lastIndexOf('https://');
|
|
290
314
|
const clean = i !== -1 ? url.slice(i) : url;
|
|
291
315
|
if (!clean.startsWith('https://')) return url;
|
|
292
|
-
return
|
|
316
|
+
return '/proxy/' + clean;
|
|
293
317
|
},
|
|
294
318
|
|
|
295
319
|
// Server API - call functions from **server.ts**
|
|
296
320
|
api: async (name, ...args) => {
|
|
321
|
+
if (isEmbedded) throw embedErr('tb.server.' + name + '()');
|
|
297
322
|
const resp = await fetch('/__api/' + name, {
|
|
298
323
|
method: 'POST',
|
|
299
324
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -312,8 +337,8 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
312
337
|
// Filesystem - local CLI extension
|
|
313
338
|
fs,
|
|
314
339
|
|
|
315
|
-
// Environment
|
|
316
|
-
mode: 'local',
|
|
340
|
+
// Environment ('embedded' when running as a bulb-in-a-bulb)
|
|
341
|
+
mode: isEmbedded ? 'embedded' : 'local',
|
|
317
342
|
|
|
318
343
|
// Theme accessor - delegates to the head-script engine (window.__tbTheme).
|
|
319
344
|
// Get: override slot ('dark'|'light'|undefined). Set applies + persists
|
|
@@ -335,12 +360,12 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
335
360
|
};
|
|
336
361
|
}
|
|
337
362
|
})();
|
|
338
|
-
`;function
|
|
363
|
+
`;function tr(s){let{name:e,code:t,css:r,html:n,data:i,insight:o,importMap:a,watch:l,theme:c,trustHint:d}=s,p=n.trim()||'<div id="app"></div>',m=f=>f.replace(/<\/script/gi,"<\\/script"),w={imports:sn(a.imports)};return`<!DOCTYPE html>
|
|
339
364
|
<html>
|
|
340
365
|
<head>
|
|
341
366
|
<meta charset="utf-8">
|
|
342
367
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
343
|
-
<title>${
|
|
368
|
+
<title>${lt(e)} - typebulb</title>
|
|
344
369
|
<script>
|
|
345
370
|
// Theme engine. Sets html[data-theme] before stylesheets paint (no flash) and
|
|
346
371
|
// exposes the tb.theme accessor via window.__tbTheme. The override is persisted
|
|
@@ -348,16 +373,19 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
348
373
|
// toggles the effective theme. See Specs/Theme.md.
|
|
349
374
|
(function() {
|
|
350
375
|
try {
|
|
351
|
-
var KEY = ${
|
|
376
|
+
var KEY = ${m(JSON.stringify("tb-theme:"+e))};
|
|
352
377
|
var doc = document.documentElement;
|
|
353
378
|
var mq = window.matchMedia('(prefers-color-scheme: dark)');
|
|
354
379
|
var os = function() { return mq.matches ? 'dark' : 'light'; };
|
|
380
|
+
// A host-forced theme (bulb-in-a-bulb) outranks the OS but not an explicit
|
|
381
|
+
// in-iframe override, so the user can still toggle the embed independently.
|
|
382
|
+
var FORCED = ${m(JSON.stringify(c??null))};
|
|
355
383
|
var stored = function() {
|
|
356
384
|
try { var v = localStorage.getItem(KEY); return (v === 'dark' || v === 'light') ? v : undefined; }
|
|
357
385
|
catch (e) { return undefined; }
|
|
358
386
|
};
|
|
359
387
|
var apply = function(t) { doc.setAttribute('data-theme', t); };
|
|
360
|
-
var effective = function() { return stored() || os(); };
|
|
388
|
+
var effective = function() { return stored() || FORCED || os(); };
|
|
361
389
|
var set = function(v) {
|
|
362
390
|
if (v === 'dark' || v === 'light') {
|
|
363
391
|
try { localStorage.setItem(KEY, v); } catch (e) {}
|
|
@@ -382,7 +410,7 @@ declare const tb: {${Dt}${Ot}${At}${Ft}${Mr}${Mt}${$t}
|
|
|
382
410
|
})();
|
|
383
411
|
</script>
|
|
384
412
|
<script type="importmap">
|
|
385
|
-
${JSON.stringify(
|
|
413
|
+
${JSON.stringify(w,null,2)}
|
|
386
414
|
</script>
|
|
387
415
|
<style>
|
|
388
416
|
/* Reset and base styles */
|
|
@@ -396,37 +424,117 @@ ${r}
|
|
|
396
424
|
</style>
|
|
397
425
|
</head>
|
|
398
426
|
<body>
|
|
399
|
-
${
|
|
427
|
+
${p}
|
|
400
428
|
|
|
401
|
-
${i.length>0?`<script>window.__TB_DATA__ = ${
|
|
402
|
-
${o?`<script>window.__TB_INSIGHT__ = ${
|
|
403
|
-
${
|
|
429
|
+
${i.length>0?`<script>window.__TB_DATA__ = ${m(JSON.stringify(i))};</script>`:""}
|
|
430
|
+
${o?`<script>window.__TB_INSIGHT__ = ${m(JSON.stringify(o))};</script>`:""}
|
|
431
|
+
${l?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
|
|
432
|
+
${d?`<script>window.__TB_EMBED_ERR__ = function (name) { return name + ' is blocked in sandboxed mode. Re-run with --trust to allow it:\\n ' + ${m(JSON.stringify(d))}; };</script>`:""}
|
|
404
433
|
|
|
405
434
|
<script>
|
|
406
|
-
${
|
|
435
|
+
${er}
|
|
407
436
|
</script>
|
|
408
437
|
|
|
438
|
+
${nn}
|
|
439
|
+
|
|
409
440
|
<script type="module">
|
|
410
|
-
${
|
|
441
|
+
${m(t)}
|
|
411
442
|
</script>
|
|
412
443
|
</body>
|
|
413
|
-
</html>`}
|
|
444
|
+
</html>`}var nn=`<script>
|
|
445
|
+
(function () {
|
|
446
|
+
if (window.parent === window) return;
|
|
447
|
+
// Embedded: the host iframe owns sizing (auto-height below), so the document
|
|
448
|
+
// must not scroll itself \u2014 otherwise sub-pixel rounding (the frame landing a
|
|
449
|
+
// fraction shorter than content) leaves a phantom scrollbar. scrollHeight still
|
|
450
|
+
// reports true content, so this is invisible to auto-height. A +1px report buffer
|
|
451
|
+
// would seem simpler but runs away on full-bleed (height:100%) bulbs.
|
|
452
|
+
document.documentElement.style.overflow = 'hidden';
|
|
453
|
+
var post = function (m) { try { parent.postMessage(m, '*'); } catch (e) {} };
|
|
454
|
+
var sendHeight = function () {
|
|
455
|
+
post({ __typebulbEmbed: true, kind: 'height', height: Math.ceil(document.documentElement.scrollHeight) });
|
|
456
|
+
};
|
|
457
|
+
window.addEventListener('error', function (e) {
|
|
458
|
+
post({ __typebulbEmbed: true, kind: 'error', message: String((e && e.message) || (e && e.error) || 'Error') });
|
|
459
|
+
});
|
|
460
|
+
window.addEventListener('unhandledrejection', function (e) {
|
|
461
|
+
var r = e && e.reason;
|
|
462
|
+
var msg = r && r.message ? r.message : (r == null ? 'Unhandled rejection' : r);
|
|
463
|
+
post({ __typebulbEmbed: true, kind: 'error', message: String(msg) });
|
|
464
|
+
});
|
|
465
|
+
window.addEventListener('load', sendHeight);
|
|
466
|
+
if (window.ResizeObserver) { try { new ResizeObserver(sendHeight).observe(document.documentElement); } catch (e) {} }
|
|
467
|
+
})();
|
|
468
|
+
</script>`;function rr(s){let{bulbHtml:e,name:t,watch:r}=s;return`<!DOCTYPE html>
|
|
469
|
+
<html>
|
|
470
|
+
<head>
|
|
471
|
+
<meta charset="utf-8">
|
|
472
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
473
|
+
<title>${lt(t)} - typebulb</title>
|
|
474
|
+
<style>
|
|
475
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
476
|
+
body { margin: 0; }
|
|
477
|
+
/* The frame paints its own themed background and fills the viewport, so the
|
|
478
|
+
host backdrop shows only at sub-pixel edges / behind the denial bar.
|
|
479
|
+
color-scheme: light dark lets that backdrop and the scrollbar follow the OS
|
|
480
|
+
with no script \u2014 the bulb's own theme engine (template head) is unaffected. */
|
|
481
|
+
html { color-scheme: light dark; }
|
|
482
|
+
/* The frame auto-grows to content (height messages below); min-height keeps a
|
|
483
|
+
short bulb filling the viewport so it reads as a page, not a widget. */
|
|
484
|
+
#tb-frame { display: block; width: 100%; min-height: 100dvh; border: 0; }
|
|
485
|
+
#tb-deny {
|
|
486
|
+
position: fixed; left: 0; right: 0; bottom: 0; z-index: 2147483647;
|
|
487
|
+
margin: 0; padding: 10px 14px; font: 13px/1.5 system-ui, -apple-system, sans-serif;
|
|
488
|
+
white-space: pre-wrap; background: #7f1d1d; color: #fff;
|
|
489
|
+
border-top: 1px solid #b91c1c; display: none;
|
|
490
|
+
}
|
|
491
|
+
</style>
|
|
492
|
+
</head>
|
|
493
|
+
<body>
|
|
494
|
+
<iframe id="tb-frame" sandbox="allow-scripts" srcdoc="${lt(e)}"></iframe>
|
|
495
|
+
<pre id="tb-deny"></pre>
|
|
496
|
+
<script>
|
|
497
|
+
(function () {
|
|
498
|
+
var frame = document.getElementById('tb-frame');
|
|
499
|
+
var deny = document.getElementById('tb-deny');
|
|
500
|
+
// Authenticate by window identity, not origin (opaque-origin frames post
|
|
501
|
+
// from 'null'). Treat the payload as untrusted: clamp height, render error
|
|
502
|
+
// text only (never HTML).
|
|
503
|
+
window.addEventListener('message', function (e) {
|
|
504
|
+
if (e.source !== frame.contentWindow) return;
|
|
505
|
+
var d = e.data;
|
|
506
|
+
if (!d || d.__typebulbEmbed !== true) return;
|
|
507
|
+
if (d.kind === 'height' && typeof d.height === 'number' && Number.isFinite(d.height)) {
|
|
508
|
+
frame.style.height = Math.max(0, Math.min(100000, Math.ceil(d.height))) + 'px';
|
|
509
|
+
} else if (d.kind === 'error') {
|
|
510
|
+
deny.textContent = '\u26A0 ' + String(d.message == null ? 'error' : d.message);
|
|
511
|
+
deny.style.display = 'block';
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
${r?`var es = new EventSource('/__reload');
|
|
515
|
+
es.addEventListener('reload', function () { location.reload(); });
|
|
516
|
+
es.onerror = function () { es.close(); };`:""}
|
|
517
|
+
})();
|
|
518
|
+
</script>
|
|
519
|
+
</body>
|
|
520
|
+
</html>`}function lt(s){return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function sn(s){let e={};for(let[t,r]of Object.entries(s))e[t]=r.startsWith("https://")?"/proxy/"+r:r;return e}import{Hono as an}from"hono";import{serve as cn}from"@hono/node-server";import{streamSSE as ln}from"hono/streaming";import*as Y from"fs/promises";import*as N from"path";var D=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},j=class{getPath(e,t){return this.path}parseStreamChunk(e){return this.checkAndThrowError(e),this.parseProviderStreamChunk(e)}isReasoningEnabled(e){return e?.reasoning!==void 0&&e.reasoning>0}extractSystemMessages(e,t=`
|
|
414
521
|
|
|
415
|
-
`){let r=e.filter(n=>n.role==="system").map(n=>n.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(n=>n.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let n=JSON.parse(e);if(n.error&&typeof n.error=="object"){let i={message:n.error.message||`HTTP ${t}`,type:n.error.type};return r&&(i.code=n.error.code),i}return n.message?{message:n.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",n=!!e.retryable;throw new
|
|
522
|
+
`){let r=e.filter(n=>n.role==="system").map(n=>n.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(n=>n.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let n=JSON.parse(e);if(n.error&&typeof n.error=="object"){let i={message:n.error.message||`HTTP ${t}`,type:n.error.type};return r&&(i.code=n.error.code),i}return n.message?{message:n.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",n=!!e.retryable;throw new D(t,r,n)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new D(t)}}extractErrorMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);return t.error?.message||t.message||e}catch{return e}return typeof e=="object"&&e!==null?e.message||JSON.stringify(e):`${this.providerName} returned an error`}};var Se=class extends j{constructor(){super(...arguments),this.providerName="Anthropic",this.defaultBaseUrl="https://api.anthropic.com",this.path="/v1/messages"}buildHeaders(e){return{"x-api-key":e,"anthropic-version":"2023-06-01","Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,n){let{system:i,conversationMessages:o}=this.extractSystemMessages(e),a={model:t,max_tokens:this.getMaxTokens(t),messages:this.withLastMessageCached(o),stream:n};if(r?.webSearch!==!1&&(a.tools=[{type:"web_search_20250305",name:"web_search"}]),i&&(a.system=[{type:"text",text:i,cache_control:{type:"ephemeral"}}]),this.isReasoningEnabled(r)){let l=r.reasoning;if(this.isModernModel(t)){let c={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:c[l]}}else{let c={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:c[l]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(""),r=e.content.filter(n=>n.type==="thinking").map(n=>n.thinking).join(`
|
|
416
523
|
|
|
417
|
-
`);return{text:t,reasoning:r||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}withLastMessageCached(e){let t=e.length-1;return e.map((r,n)=>n===t?{role:r.role,content:[{type:"text",text:r.content,cache_control:{type:"ephemeral"}}]}:r)}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var
|
|
418
|
-
`)),!t&&n.type==="message"&&n.content&&(t=n.content.filter(i=>i.type==="output_text").map(i=>i.text).join(""));return{text:t,reasoning:r}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let n=e.response?.error,i=n?.message||"Response failed",o=n?.code==="insufficient_quota"||n?.code==="rate_limit_exceeded";throw new
|
|
524
|
+
`);return{text:t,reasoning:r||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}withLastMessageCached(e){let t=e.length-1;return e.map((r,n)=>n===t?{role:r.role,content:[{type:"text",text:r.content,cache_control:{type:"ephemeral"}}]}:r)}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var Re=class extends j{constructor(){super(...arguments),this.providerName="OpenAI",this.defaultBaseUrl="https://api.openai.com",this.path="/v1/responses",this.effortMap={0:"minimal",1:"low",2:"medium",3:"high"}}buildHeaders(e){return{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,n){let i=this.convertMessagesToInput(e),o={model:t,input:i,stream:n};return r?.webSearch!==!1&&(o.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",r;if(e.output&&Array.isArray(e.output))for(let n of e.output)n.type==="reasoning"&&n.summary&&(r=n.summary.map(i=>i.text).join(`
|
|
525
|
+
`)),!t&&n.type==="message"&&n.content&&(t=n.content.filter(i=>i.type==="output_text").map(i=>i.text).join(""));return{text:t,reasoning:r}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let n=e.response?.error,i=n?.message||"Response failed",o=n?.code==="insufficient_quota"||n?.code==="rate_limit_exceeded";throw new D(i,o?"rate_limit":"unknown",o)}case"response.output_text.delta":return{text:e.delta};case"response.reasoning_summary_text.delta":return{reasoning:e.delta};case"response.created":case"response.in_progress":case"response.output_item.added":case"response.output_item.done":case"response.content_part.added":case"response.content_part.done":case"response.output_text.done":case"response.output_text.annotation.added":case"response.reasoning_summary_text.done":case"response.completed":case"response.web_search_call.in_progress":case"response.web_search_call.searching":case"response.web_search_call.completed":return null;default:return null}}convertMessagesToInput(e){return e.map(t=>t.role==="system"?`System: ${t.content}`:t.role==="user"?`User: ${t.content}`:t.role==="assistant"?`Assistant: ${t.content}`:t.content).join(`
|
|
419
526
|
|
|
420
|
-
`)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var
|
|
421
|
-
`),
|
|
422
|
-
`)[0],type:n.status,code:n.code?.toString()}:r.message?{message:r.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",r=e.candidates?.[0]?.finishReason,n="complete";return r==="MAX_TOKENS"?n="interrupted":(r==="SAFETY"||r==="RECITATION")&&(n="failed"),{text:t,status:n}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let n=t;r=n.message||n.status||"Gemini returned an error"}else r="Gemini returned an error";throw new
|
|
527
|
+
`)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var Ee=class extends j{constructor(){super(...arguments),this.providerName="Gemini",this.defaultBaseUrl="https://generativelanguage.googleapis.com",this.path="/v1beta/models"}getPath(e,t){return`/v1beta/models/${e}:${t?"streamGenerateContent":"generateContent"}${t?"?alt=sse":""}`}buildHeaders(e){return{"Content-Type":"application/json","x-goog-api-key":e}}buildPayload(e,t,r,n){let{system:i,conversationMessages:o}=this.extractSystemMessages(e,`
|
|
528
|
+
`),l={contents:o.map(c=>({role:c.role==="assistant"?"model":"user",parts:[{text:c.content}]}))};return r?.webSearch!==!1&&(l.tools=[{google_search:{}}]),i&&(l.systemInstruction={role:"system",parts:[{text:i}]}),this.isReasoningEnabled(r)&&(l.generationConfig={temperature:.7+r.reasoning*.1}),l}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let r=JSON.parse(e),n=Array.isArray(r)?r[0]?.error:r?.error;return n&&typeof n=="object"?{message:(n.message||`HTTP ${t}`).split(`
|
|
529
|
+
`)[0],type:n.status,code:n.code?.toString()}:r.message?{message:r.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",r=e.candidates?.[0]?.finishReason,n="complete";return r==="MAX_TOKENS"?n="interrupted":(r==="SAFETY"||r==="RECITATION")&&(n="failed"),{text:t,status:n}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let n=t;r=n.message||n.status||"Gemini returned an error"}else r="Gemini returned an error";throw new D(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new D(`Prompt blocked: ${t}`)}}};var ke=class extends j{constructor(){super(...arguments),this.providerName="OpenRouter",this.defaultBaseUrl="https://openrouter.ai/api",this.path="/api/v1/chat/completions",this.effortMap={0:"low",1:"low",2:"medium",3:"high"}}buildHeaders(e,t){let r={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(r["HTTP-Referer"]=t,r.Referer=t,r.Origin=t),r}buildPayload(e,t,r,n){let i={model:t,messages:e,stream:n};return r?.webSearch===!0&&(i.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning]}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],r=t?.message?.content??t?.text??"",n=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:n}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let r=t.delta||t.message;if(!r)return null;let n=r.content||void 0,i=r.reasoning||void 0;return!n&&!i?null:{text:n,reasoning:i}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var on=new Map([["openai",new Re],["openrouter",new ke],["anthropic",new Se],["gemini",new Ee]]);function K(s){let e=on.get(s);if(!e)throw new Error(`Unsupported protocol: ${s}`);return e}async function dt(s,e){let t=K(s.protocol),r=t.getPath(e.model,e.stream),n=new URL(r,s.baseUrl).toString(),i=t.buildHeaders(s.apiKey,e.origin),o=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(o),fetch(n,{method:"POST",headers:i,body:JSON.stringify(o),signal:e.signal})}async function pt(s,e){let t=K(e),r=await s.text().catch(()=>""),{message:n}=t.parseError(r,s.status),i=s.status,o="unknown";return i===429?o="rate_limit":i===413&&(o="context_exceeded"),{code:o,message:n,retryable:i===429}}function nr(s){let e=s.indexOf(`\r
|
|
423
530
|
\r
|
|
424
531
|
`),t=s.indexOf(`
|
|
425
532
|
|
|
426
|
-
`);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function
|
|
427
|
-
`).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Xt(s,e,t){let r=new TextDecoder,n="",i=!1,o=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=o?await Promise.race([s.read(),o]):await s.read(),{done:c,value:d}=a;if(c){if(n.trim()){let m=ct(n);m!==null&&m!=="done"&&e(m)}break}i=!0,n+=r.decode(d,{stream:!0});let{pos:p,len:u}=Yt(n);for(;p!==-1;){let m=n.slice(0,p);n=n.slice(p+u);let w=ct(m);if(w==="done"){n="";break}w!==null&&e(w),{pos:p,len:u}=Yt(n)}}return{receivedAnyData:i}}async function lt(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=G(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await Xt(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as dt from"fs/promises";import*as ke from"path";var Le=class{async get(e){let t=O(e),r=ke.join(xe,t+".bin"),n=ke.join(xe,t+".json");try{let[i,o]=await Promise.all([dt.readFile(r),dt.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await x();let r=O(e),n=ke.join(xe,r+".bin"),i=ke.join(xe,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([T(n,t.body),T(i,JSON.stringify(o))])}};var er="127.0.0.1",nn=new Set(["localhost","127.0.0.1","::1"]);function sn(s){if(s)try{return new URL(s.includes("://")?s:`http://${s}`).hostname}catch{return}}function Qt(s){let e=sn(s);return!!e&&nn.has(e)}function Ue(s){return s instanceof Error?s.message:"Unknown error"}async function tr(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i,localOverride:o}=s,a=new en;a.use("*",async(l,h)=>{if(!Qt(l.req.header("host")))return l.text("Forbidden: untrusted Host",403);await h()}),a.use("*",async(l,h)=>{await h(),l.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),l.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let c=async(l,h)=>{let g=l.req.header("sec-fetch-site");if(g){if(g==="cross-site")return l.text("Forbidden: cross-site request",403)}else{let b=l.req.header("origin");if(b&&!Qt(b))return l.text("Forbidden: cross-origin request",403)}await h()};a.use("/__fs/*",c),a.use("/__api/*",c),a.use("/__ai",c),a.get("/",l=>l.html(e())),a.post("/__fs/read",async l=>{try{let{path:h}=await l.req.json(),g=ut(h,t),b=await z.readFile(g);return new Response(new Uint8Array(b),{headers:{"Content-Type":"application/octet-stream"}})}catch(h){let g=Ue(h);return l.json({error:g},400)}}),a.post("/__fs/write",async l=>{try{let h=l.req.query("path");if(!h)return l.json({error:"Missing path"},400);let g=ut(h,t);return await z.mkdir($.dirname(g),{recursive:!0}),await z.writeFile(g,Buffer.from(await l.req.arrayBuffer())),l.json({success:!0})}catch(h){let g=Ue(h);return l.json({error:g},400)}});let d={log:console.log};a.post("/__api/:name",async l=>{try{let h=i?.(),g=l.req.param("name"),b=h?.[g]??d[g];if(!b||typeof b!="function")return l.json({error:`API function '${g}' not found`},404);let{args:v}=await l.req.json(),D=await b(...v||[]);return l.json({result:D})}catch(h){let g=Ue(h);return l.json({error:g},500)}}),a.post("/__ai",async l=>{try{let{messages:h,system:g,reasoning:b,provider:v,model:D,webSearch:J}=await l.req.json();if(!h||!Array.isArray(h)||h.length===0)return l.json({message:"messages array is required",code:"unknown",retryable:!1},400);let N=on(v,D);if(typeof N=="string")return l.json({message:N,code:"unknown",retryable:!1},400);let ie=[...g?[{role:"system",content:g}]:[],...h.map(Y=>({role:Y.role,content:Y.content}))],F=await ot(N,{model:N.model,messages:ie,stream:!0,reasoning:b??0,webSearch:J??!0});if(!F.ok){let Y=await at(F,N.protocol);return l.json(Y,F.status)}let oe=await lt(F,N.protocol);return oe||console.warn("[tb.ai] Empty response from provider"),l.json({text:oe})}catch(h){if(h instanceof C)return l.json({message:h.message,code:h.code,retryable:h.retryable},500);let g=Ue(h);return l.json({message:g,code:"unknown",retryable:!1},500)}}),a.get("/__models",async l=>{try{let h=await ln();return l.json(h)}catch{return l.json([],200)}});let p=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],u=new Le;if(a.get("/proxy/*",async l=>{let h=new URL(l.req.url),b=(h.pathname+h.search).slice(7),v=b.lastIndexOf("https://");return v===-1?l.text("Invalid proxy URL",400):m(l,b.slice(v))}),o){let l=`/local/${o.name}/`;a.get("/local/*",async h=>{let{pathname:g}=new URL(h.req.url);if(!g.startsWith(l))return h.text("Not Found",404);let b=decodeURIComponent(g.slice(l.length));try{let v=ut(b,o.serveDir),D=await z.readFile(v);return new Response(D,{headers:{"Content-Type":dn(v)}})}catch{return h.text("Not Found",404)}})}async function m(l,h){let g;try{g=new URL(h)}catch{return l.text("Invalid URL",400)}if(g.protocol!=="https:")return l.text("HTTPS only",400);if(!p.includes(g.hostname))return l.text("Host not allowed",403);let b=await u.get(h);if(b)return new Response(b.body,{status:200,headers:pt(b.contentType,b.cacheControl)});try{let v=await fetch(h,{headers:{Accept:l.req.header("Accept")||"*/*"},redirect:"follow"});if(!v.ok)return l.text(`Upstream ${v.status}`,v.status);let D=v.headers.get("Content-Type")||void 0,J=v.headers.get("Cache-Control")||void 0;if(v.body){let[N,ie]=v.body.tee();return(async()=>{try{let F=await new Response(ie).arrayBuffer();await u.set(h,{body:Buffer.from(F),contentType:D,cacheControl:J})}catch{}})(),new Response(N,{status:v.status,headers:pt(D,J)})}return new Response(null,{status:v.status,headers:pt(D,J)})}catch(v){return l.text(`Proxy fetch failed: ${v instanceof Error?v.message:v}`,502)}}n&&a.get("/__reload",l=>rn(l,async h=>{let g=()=>{h.writeSSE({event:"reload",data:""})};for(n.on("reload",g),h.onAbort(()=>{n.removeListener("reload",g)});;)await h.sleep(3e4)}));let w=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;a.notFound(async l=>{if(l.req.method!=="GET")return l.text("Not Found",404);let h=new URL(l.req.url);return w.test(h.pathname)?m(l,"https://esm.sh"+h.pathname+h.search):l.text("Not Found",404)});let f=tn({fetch:a.fetch,port:r,hostname:er});return{port:r,close:()=>f.close()}}var rr={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function on(s,e){let t=s??process.env.TB_AI_PROVIDER,r=e??process.env.TB_AI_MODEL;if(!t)return"No provider specified. Set TB_AI_PROVIDER in your .env file or pass provider in the tb.ai() call.";if(!r)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let n;try{n=G(t)}catch{return`Unknown provider '${t}'.`}let i=rr[t],o=process.env[i];return o?{apiKey:o,baseUrl:n.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${i} in your .env file.`}var an="https://api.typebulb.com/api/models",cn=1440*60*1e3,ne=null;async function ln(){if(!ne||Date.now()-ne.fetchedAt>cn){let s=await fetch(an);if(!s.ok)return ne?Zt(ne.models):[];ne={models:await s.json(),fetchedAt:Date.now()}}return Zt(ne.models)}function Zt(s){let e=new Set(Object.entries(rr).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function pt(s,e){let t=new Headers;return s&&t.set("Content-Type",s),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function dn(s){switch($.extname(s).toLowerCase()){case".js":case".mjs":return"text/javascript";case".wasm":return"application/wasm";case".json":case".map":return"application/json";default:return"application/octet-stream"}}function ut(s,e){let t=$.resolve(e,s),r=$.normalize(e),n=$.normalize(t);if(n!==r&&!n.startsWith(r+$.sep))throw new Error("Path traversal detected - access denied");return t}async function ft(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,er,()=>{let n=r.address(),i=typeof n=="object"&&n?n.port:s;r.close(()=>t(i))}),r.on("error",()=>{t(ft(s+1))})})}import pn from"open";async function nr(s){await pn(s)}import sr from"chokidar";var ir={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function ht(s){let{bulbPath:e,emitter:t}=s,r=sr.watch(e,ir);return r.on("change",()=>{t.emit("reload")}),()=>r.close()}function or(s){let{dir:e,onChange:t,debounceMs:r=150}=s,n,i=sr.watch(e,ir);return i.on("all",()=>{n&&clearTimeout(n),n=setTimeout(t,r)}),()=>{n&&clearTimeout(n),i.close()}}import*as E from"fs/promises";import*as R from"path";import*as se from"path";var un=se.join(Me,"pkg"),fn=se.join(Me,"files"),hn=se.join(Me,"negative.json"),We=class{pkgMem=new Map;fileMem=new Map;negativeCache=new H(new te(hn));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await x();let t=await q(ar(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let n={content:t,url:r};this.pkgMem.set(e,n),await Be(async()=>{await x(),await T(ar(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await x();let t=await Ae(cr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await Be(async()=>{await x(),await T(cr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await Be(async()=>{await x(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return Be(()=>this.negativeCache.clearNegative(e))}};async function Be(s){try{await s()}catch{}}function ar(s){return se.join(un,O(s)+".json")}function cr(s){return se.join(fn,O(s)+".txt")}var mt;function mn(){return mt||(mt=rt({cache:new We,cdnClient:Gt,packageService:Ne,versionResolver:qt})),mt}var lr="file:///node_modules/";async function dr(s){let e=$e(s.emitKey,"typecheck");await x(),await E.rm(e,{recursive:!0,force:!0}),await E.mkdir(e,{recursive:!0});let t=vn(s.jsxImportSource,s.dependencies),r=await mn().resolve(s.code,s.dependencies,t),n=s.local?.name,i=n?r.filter(d=>d.pkg!==n):r,o=new Set;for(let d of i)for(let p of d.files){let u=gt(p.path);if(!u||o.has(u))continue;o.add(u);let m=R.join(e,"node_modules",u);await E.mkdir(R.dirname(m),{recursive:!0}),await E.writeFile(m,p.content,"utf8")}let a={};for(let d of i)for(let p of d.shims){let u=gt(p.path);u&&(a[p.module]=[`./node_modules/${u}`])}for(let d of i){let p=gt(d.mainPath);p&&(a[d.pkg]=[`./node_modules/${p}`])}if(s.local){delete a[s.local.name];let d=await bn(s.local,e);d?a[s.local.name]=[`./node_modules/${s.local.name}/${d}`]:console.warn(` local: '${s.local.name}' ships no type defs; check cannot type against it.`)}let c=gn(s.jsxImportSource,a);return await E.writeFile(R.join(e,"tsconfig.json"),JSON.stringify(c,null,2)+`
|
|
428
|
-
|
|
429
|
-
`,"utf8"),{dir:e}}function
|
|
533
|
+
`);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function ut(s){let t=s.split(/\r?\n/).filter(n=>n.startsWith("data:"));if(!t.length)return null;let r=t.map(n=>n.replace(/^data:\s?/,"")).join(`
|
|
534
|
+
`).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function sr(s,e,t){let r=new TextDecoder,n="",i=!1,o=t?new Promise((a,l)=>{t.aborted&&l(new Error("Aborted")),t.addEventListener("abort",()=>l(new Error("Aborted")),{once:!0})}):null;for(;;){let a=o?await Promise.race([s.read(),o]):await s.read(),{done:l,value:c}=a;if(l){if(n.trim()){let m=ut(n);m!==null&&m!=="done"&&e(m)}break}i=!0,n+=r.decode(c,{stream:!0});let{pos:d,len:p}=nr(n);for(;d!==-1;){let m=n.slice(0,d);n=n.slice(d+p);let w=ut(m);if(w==="done"){n="";break}w!==null&&e(w),{pos:d,len:p}=nr(n)}}return{receivedAnyData:i}}async function ht(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=K(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await sr(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as mt from"fs/promises";import*as Te from"path";var Ue=class{async get(e){let t=$(e),r=Te.join(Pe,t+".bin"),n=Te.join(Pe,t+".json");try{let[i,o]=await Promise.all([mt.readFile(r),mt.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await P();let r=$(e),n=Te.join(Pe,r+".bin"),i=Te.join(Pe,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([O(n,t.body),O(i,JSON.stringify(o))])}};var ar="127.0.0.1",dn=new Set(["localhost","127.0.0.1","::1"]);function pn(s){if(s)try{return new URL(s.includes("://")?s:`http://${s}`).hostname}catch{return}}function ir(s){let e=pn(s);return!!e&&dn.has(e)}function We(s){return s instanceof Error?s.message:"Unknown error"}async function cr(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i,localOverride:o,trusted:a=!1,trustHint:l}=s,c=new an;c.use("*",async(u,h)=>{if(!ir(u.req.header("host")))return u.text("Forbidden: untrusted Host",403);await h()}),c.use("*",async(u,h)=>{await h(),u.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),u.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let d=["/__fs/*","/__api/*","/__ai"],p=async(u,h)=>{if(!a){let y=l?`
|
|
535
|
+
${l}`:"";return u.text(`Forbidden: this capability requires --trust.${y}`,403)}await h()},m=async(u,h)=>{let y=u.req.header("sec-fetch-site");if(y){if(y==="cross-site")return u.text("Forbidden: cross-site request",403)}else{let x=u.req.header("origin");if(x&&!ir(x))return u.text("Forbidden: cross-origin request",403)}await h()};for(let u of d)c.use(u,p),c.use(u,m);c.get("/",u=>u.html(e())),c.post("/__fs/read",async u=>{try{let{path:h}=await u.req.json(),y=gt(h,t),x=await Y.readFile(y);return new Response(new Uint8Array(x),{headers:{"Content-Type":"application/octet-stream"}})}catch(h){let y=We(h);return u.json({error:y},400)}}),c.post("/__fs/write",async u=>{try{let h=u.req.query("path");if(!h)return u.json({error:"Missing path"},400);let y=gt(h,t);return await Y.mkdir(N.dirname(y),{recursive:!0}),await Y.writeFile(y,Buffer.from(await u.req.arrayBuffer())),u.json({success:!0})}catch(h){let y=We(h);return u.json({error:y},400)}});let w={log:console.log};c.post("/__api/:name",async u=>{try{let h=i?.(),y=u.req.param("name"),x=h?.[y]??w[y];if(!x||typeof x!="function")return u.json({error:`API function '${y}' not found`},404);let{args:b}=await u.req.json(),I=await x(...b||[]);return u.json({result:I})}catch(h){let y=We(h);return u.json({error:y},500)}}),c.post("/__ai",async u=>{try{let{messages:h,system:y,reasoning:x,provider:b,model:I,webSearch:W}=await u.req.json();if(!h||!Array.isArray(h)||h.length===0)return u.json({message:"messages array is required",code:"unknown",retryable:!1},400);let L=un(b,I);if(typeof L=="string")return u.json({message:L,code:"unknown",retryable:!1},400);let ze=[...y?[{role:"system",content:y}]:[],...h.map(Ie=>({role:Ie.role,content:Ie.content}))],Q=await dt(L,{model:L.model,messages:ze,stream:!0,reasoning:x??0,webSearch:W??!0});if(!Q.ok){let Ie=await pt(Q,L.protocol);return u.json(Ie,Q.status)}let kt=await ht(Q,L.protocol);return kt||console.warn("[tb.ai] Empty response from provider"),u.json({text:kt})}catch(h){if(h instanceof D)return u.json({message:h.message,code:h.code,retryable:h.retryable},500);let y=We(h);return u.json({message:y,code:"unknown",retryable:!1},500)}}),c.get("/__models",async u=>{try{let h=await fn();return u.json(h)}catch{return u.json([],200)}});let f=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],R=new Ue;if(c.get("/proxy/*",async u=>{let h=new URL(u.req.url),x=(h.pathname+h.search).slice(7),b=x.lastIndexOf("https://");return b===-1?u.text("Invalid proxy URL",400):v(u,x.slice(b))}),o){let u=`/local/${o.name}/`;c.get("/local/*",async h=>{let{pathname:y}=new URL(h.req.url);if(!y.startsWith(u))return h.text("Not Found",404);let x=decodeURIComponent(y.slice(u.length));try{let b=gt(x,o.serveDir),I=await Y.readFile(b);return new Response(I,{headers:{"Content-Type":gn(b)}})}catch{return h.text("Not Found",404)}})}async function v(u,h){let y;try{y=new URL(h)}catch{return u.text("Invalid URL",400)}if(y.protocol!=="https:")return u.text("HTTPS only",400);if(!f.includes(y.hostname))return u.text("Host not allowed",403);let x=await R.get(h);if(x)return new Response(x.body,{status:200,headers:ft(x.contentType,x.cacheControl)});try{let b=await fetch(h,{headers:{Accept:u.req.header("Accept")||"*/*"},redirect:"follow"});if(!b.ok)return u.text(`Upstream ${b.status}`,b.status);let I=b.headers.get("Content-Type")||void 0,W=b.headers.get("Cache-Control")||void 0;if(b.body){let[L,ze]=b.body.tee();return(async()=>{try{let Q=await new Response(ze).arrayBuffer();await R.set(h,{body:Buffer.from(Q),contentType:I,cacheControl:W})}catch{}})(),new Response(L,{status:b.status,headers:ft(I,W)})}return new Response(null,{status:b.status,headers:ft(I,W)})}catch(b){return u.text(`Proxy fetch failed: ${b instanceof Error?b.message:b}`,502)}}n&&c.get("/__reload",u=>ln(u,async h=>{let y=()=>{h.writeSSE({event:"reload",data:""})};for(n.on("reload",y),h.onAbort(()=>{n.removeListener("reload",y)});;)await h.sleep(3e4)}));let E=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;c.notFound(async u=>{if(u.req.method!=="GET")return u.text("Not Found",404);let h=new URL(u.req.url);return E.test(h.pathname)?v(u,"https://esm.sh"+h.pathname+h.search):u.text("Not Found",404)});let ae=cn({fetch:c.fetch,port:r,hostname:ar});return{port:r,close:()=>ae.close()}}var lr={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function un(s,e){let t=s??process.env.TB_AI_PROVIDER,r=e??process.env.TB_AI_MODEL;if(!t)return"No provider specified. Set TB_AI_PROVIDER in your .env file or pass provider in the tb.ai() call.";if(!r)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let n;try{n=K(t)}catch{return`Unknown provider '${t}'.`}let i=lr[t],o=process.env[i];return o?{apiKey:o,baseUrl:n.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${i} in your .env file.`}var hn="https://api.typebulb.com/api/models",mn=1440*60*1e3,ie=null;async function fn(){if(!ie||Date.now()-ie.fetchedAt>mn){let s=await fetch(hn);if(!s.ok)return ie?or(ie.models):[];ie={models:await s.json(),fetchedAt:Date.now()}}return or(ie.models)}function or(s){let e=new Set(Object.entries(lr).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function ft(s,e){let t=new Headers;return s&&t.set("Content-Type",s),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function gn(s){switch(N.extname(s).toLowerCase()){case".js":case".mjs":return"text/javascript";case".wasm":return"application/wasm";case".json":case".map":return"application/json";default:return"application/octet-stream"}}function gt(s,e){let t=N.resolve(e,s),r=N.normalize(e),n=N.normalize(t);if(n!==r&&!n.startsWith(r+N.sep))throw new Error("Path traversal detected - access denied");return t}async function yt(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,ar,()=>{let n=r.address(),i=typeof n=="object"&&n?n.port:s;r.close(()=>t(i))}),r.on("error",()=>{t(yt(s+1))})})}import yn from"open";async function dr(s){await yn(s)}import pr from"chokidar";var ur={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function wt(s){let{bulbPath:e,emitter:t}=s,r=pr.watch(e,ur);return r.on("change",()=>{t.emit("reload")}),()=>r.close()}function hr(s){let{dir:e,onChange:t,debounceMs:r=150}=s,n,i=pr.watch(e,ur);return i.on("all",()=>{n&&clearTimeout(n),n=setTimeout(t,r)}),()=>{n&&clearTimeout(n),i.close()}}import*as _ from"fs/promises";import*as T from"path";import*as oe from"path";var wn=oe.join(Fe,"pkg"),bn=oe.join(Fe,"files"),vn=oe.join(Fe,"negative.json"),Je=class{pkgMem=new Map;fileMem=new Map;negativeCache=new G(new ne(vn));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await P();let t=await z(mr(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let n={content:t,url:r};this.pkgMem.set(e,n),await He(async()=>{await P(),await O(mr(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await P();let t=await $e(fr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await He(async()=>{await P(),await O(fr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await He(async()=>{await P(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return He(()=>this.negativeCache.clearNegative(e))}};async function He(s){try{await s()}catch{}}function mr(s){return oe.join(wn,$(s)+".json")}function fr(s){return oe.join(bn,$(s)+".txt")}var bt;function xn(){return bt||(bt=it({cache:new Je,cdnClient:Zt,packageService:Be,versionResolver:Qt})),bt}var gr="file:///node_modules/";async function yr(s){let e=je(s.emitKey,"typecheck");await P(),await _.rm(e,{recursive:!0,force:!0}),await _.mkdir(e,{recursive:!0});let t=En(s.jsxImportSource,s.dependencies),r=await xn().resolve(s.code,s.dependencies,t),n=s.local?.name,i=n?r.filter(c=>c.pkg!==n):r,o=new Set;for(let c of i)for(let d of c.files){let p=vt(d.path);if(!p||o.has(p))continue;o.add(p);let m=T.join(e,"node_modules",p);await _.mkdir(T.dirname(m),{recursive:!0}),await _.writeFile(m,d.content,"utf8")}let a={};for(let c of i)for(let d of c.shims){let p=vt(d.path);p&&(a[d.module]=[`./node_modules/${p}`])}for(let c of i){let d=vt(c.mainPath);d&&(a[c.pkg]=[`./node_modules/${d}`])}if(s.local){delete a[s.local.name];let c=await kn(s.local,e);c?a[s.local.name]=[`./node_modules/${s.local.name}/${c}`]:console.warn(` local: '${s.local.name}' ships no type defs; check cannot type against it.`)}let l=Pn(s.jsxImportSource,a);return await _.writeFile(T.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
|
|
536
|
+
`,"utf8"),await _.writeFile(T.join(e,"code.tsx"),s.code,"utf8"),await _.writeFile(T.join(e,"tb.d.ts"),tt,"utf8"),{dir:e}}function Pn(s,e){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:Sn([...Ze,...et]),jsx:"react-jsx",jsxImportSource:s??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts"]}}function Sn(s){return s.filter(e=>!e.since).map(e=>Rn(e.name))}function Rn(s){return s.split(".").map(e=>/^es\d+$/i.test(e)?e.toUpperCase():e==="dom"?"DOM":e==="esnext"?"ESNext":e.charAt(0).toUpperCase()+e.slice(1)).join(".")}function En(s,e){let t=s??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function vt(s){if(!s.startsWith(gr))return;let e=s.slice(gr.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function kn(s,e){if(!s.typesAbs)return;let t=T.dirname(s.typesAbs),r=T.join(e,"node_modules",s.name);for(let n of await Tn(t)){let i=T.join(r,T.relative(t,n));await _.mkdir(T.dirname(i),{recursive:!0}),await _.copyFile(n,i)}return T.basename(s.typesAbs)}async function Tn(s){let e=[];async function t(r){let n=await _.readdir(r,{withFileTypes:!0});for(let i of n){let o=T.join(r,i.name);i.isDirectory()?await t(o):/\.d\.ts(\.map)?$/.test(i.name)&&e.push(o)}}return await t(s),e}import*as A from"fs/promises";import*as X from"path";import{existsSync as An}from"fs";import*as Ve from"fs/promises";import*as xt from"path";import{existsSync as wr}from"fs";import{execFile as _n}from"child_process";import{promisify as Cn}from"util";var In=Cn(_n);async function qe(s,e){let t=s.filter(n=>!On(n,e));if(t.length===0)return;await Ve.mkdir(e,{recursive:!0});let r=xt.join(e,"package.json");wr(r)||await Ve.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await In("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}function On(s,e){return wr(xt.join(e,"node_modules",Dn(s)))}function Ge(s){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(s);){let n=r[1];if(n.startsWith("node:"))continue;let i=n.startsWith("@")?n.split("/").slice(0,2).join("/"):n.split("/")[0];e.add(i)}return[...e]}function Dn(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t<0)return s;let r=s.indexOf("@",t+1);return r<0?s:s.slice(0,r)}let e=s.indexOf("@");return e<0?s:s.slice(0,e)}var Mn="^22";async function br(s){let e=je(s.emitKey,"typecheck-server");await P(),await A.rm(e,{recursive:!0,force:!0}),await A.mkdir(e,{recursive:!0});let t=X.join(s.bulbDir,".typebulb"),r=Ge(s.server);await qe([`@types/node@${Mn}`,...r],t);let n=X.join(t,"node_modules"),i=X.join(e,"node_modules");return await Fn(n,i),await A.writeFile(X.join(e,"server.ts"),s.server,"utf8"),await A.writeFile(X.join(e,"tb.d.ts"),rt,"utf8"),await A.writeFile(X.join(e,"tsconfig.json"),JSON.stringify($n(),null,2)+`
|
|
537
|
+
`,"utf8"),{dir:e}}function $n(){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"node",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0},include:["server.ts","tb.d.ts"]}}async function Fn(s,e){if(!An(s)){await A.mkdir(e,{recursive:!0});return}await A.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await A.symlink(s,e,t)}import*as St from"fs/promises";import{existsSync as _e}from"fs";import*as k from"path";import{resolve as vr}from"resolve.exports";import{init as jn,parse as Nn}from"es-module-lexer";var Pt=["browser","import","default"];function xr(s){let e=s.indexOf("=");if(e===-1)throw new Error(`--replace must be <name>=<path> (got '${s}')`);let t=s.slice(0,e).trim(),r=s.slice(e+1).trim();if(!t)throw new Error(`--replace missing package name (got '${s}')`);if(!r)throw new Error(`--replace missing path for '${t}'`);if(t.startsWith("@"))throw new Error(`--replace does not support scoped names yet; '${t}' is scoped`);return{name:t,dir:k.resolve(r)}}async function Pr(s){let{name:e,dir:t}=s;if(!_e(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let r=k.join(t,"package.json"),n;try{n=JSON.parse(await St.readFile(r,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${r}`)}let i=Ln(n,e),o=k.resolve(t,i);if(!_e(o))throw new Error(`--replace package '${e}' entry not found on disk: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);let a=k.dirname(o),l=`/local/${e}/${k.basename(o)}`,c=Bn(n,t);return await Un(e,o,a),{name:e,dir:t,entryAbs:o,serveDir:a,entryUrl:l,typesAbs:c}}function Ln(s,e){if(s.exports!==void 0){let r;try{r=vr(s,".",{browser:!0,conditions:Pt})}catch(i){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${Pt.join(", ")}): ${i instanceof Error?i.message:i}`)}let n=Sr(r);if(!n)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${Pt.join(", ")}); too complex to override.`);return n}let t=s.module??s.main;if(!t)throw new Error(`--replace package '${e}' has no "exports", "module", or "main" entry to resolve.`);return t}function Bn(s,e){if(s.exports!==void 0)try{let r=vr(s,".",{conditions:["types"]}),n=Sr(r);if(n){let i=k.resolve(e,n);if(_e(i))return i}}catch{}let t=s.types??s.typings;if(t){let r=k.resolve(e,t);if(_e(r))return r}}function Sr(s){if(typeof s=="string")return s;if(Array.isArray(s))return s.find(e=>typeof e=="string")}async function Un(s,e,t){await jn;let r=k.normalize(t),n=new Set,i=[e];for(;i.length;){let o=i.shift();if(n.has(o))continue;n.add(o);let a;try{a=await St.readFile(o,"utf8")}catch{continue}let l,c;try{[l,,,c]=Nn(a,o)}catch{continue}if(o===e&&!c)throw new Error(`override package '${s}' entry is not an ES module (no import/export syntax); CommonJS or non-module entries aren't supported (esm.sh would have to transform it).`);for(let d of l){if(d.d===-2)continue;let p=d.n;if(p&&!p.startsWith("node:")){if(p.startsWith("./")||p.startsWith("../")||p.startsWith("/")){let m=Wn(o,p,r);m&&!n.has(m)&&i.push(m);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${s} externalizes '${p}'`)}}}}function Wn(s,e,t){let r=e.replace(/[?#].*$/,""),n=k.resolve(k.dirname(s),r),i=[n,n+".js",n+".mjs",k.join(n,"index.js"),k.join(n,"index.mjs")];for(let o of i)if(k.normalize(o).startsWith(t)&&_e(o))return o}var ha=Gn(Vn),zn="0.9.0";function Kn(s){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,trust:!1,help:!1,version:!1};s[0]==="check"&&(e.subcommand="check",s=s.slice(1));for(let t=0;t<s.length;t++){let r=s[t];if(r==="--help"||r==="-h")e.help=!0;else if(r==="--version"||r==="-V")e.version=!0;else if(r==="--no-watch")e.watch=!1;else if(r==="--no-open")e.open=!1;else if(r==="--server")e.server=!0;else if(r==="--trust")e.trust=!0;else if(r==="--port"||r==="-p"){let n=s[++t],i=parseInt(n,10);isNaN(i)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=i}else if(r==="--replace"||r.startsWith("--replace=")){let n=r.startsWith("--replace=")?r.slice(10):s[++t]??"";try{let i=xr(n);if(e.local)throw new Error(`--replace can only be used once (got '${e.local.name}' and '${i.name}')`);e.local=i}catch(i){console.error(i instanceof Error?i.message:String(i)),process.exit(1)}}else r.startsWith("-")||(e.file=r)}return e}function Yn(){console.log(`
|
|
430
538
|
typebulb - Local bulb runner for Typebulb
|
|
431
539
|
|
|
432
540
|
Usage:
|
|
@@ -437,7 +545,11 @@ Options:
|
|
|
437
545
|
--no-watch Disable hot reload (watch is on by default)
|
|
438
546
|
-p, --port <port> Use a specific port (default: 3000)
|
|
439
547
|
--no-open Don't auto-open browser
|
|
440
|
-
--
|
|
548
|
+
--trust Grant privileged capabilities (filesystem, AI,
|
|
549
|
+
and server.ts). Without it a bulb runs sandboxed:
|
|
550
|
+
tb.fs / tb.ai / tb.server are blocked and the page
|
|
551
|
+
shows the exact --trust command to unlock them.
|
|
552
|
+
--server Run server.ts only, no web server (needs --trust)
|
|
441
553
|
--replace <name>=<path> Replace a declared dependency with a local built
|
|
442
554
|
package folder instead of a CDN (dev only).
|
|
443
555
|
Applies to both run and check. Watched for
|
|
@@ -479,12 +591,13 @@ Examples:
|
|
|
479
591
|
typebulb my-editor.bulb.md
|
|
480
592
|
typebulb --no-watch --port 8080 my-editor.bulb.md
|
|
481
593
|
typebulb .
|
|
482
|
-
`)}async function
|
|
483
|
-
`)){let a=o.trim();if(!a||a.startsWith("#"))continue;let
|
|
484
|
-
`);let r=new
|
|
485
|
-
${
|
|
594
|
+
`)}async function Xn(s){let t=(await M.readdir(s)).find(r=>r.endsWith(".bulb.md"));return t?S.join(s,t):null}function Er(){Et([".env",".env.local"],process.cwd(),!0)}function Et(s,e,t=!1){for(let r of s){let n=S.resolve(e,r);try{let i=Hn(n,"utf-8");for(let o of i.split(`
|
|
595
|
+
`)){let a=o.trim();if(!a||a.startsWith("#"))continue;let l=a.indexOf("=");if(l===-1)continue;let c=a.slice(0,l).trim(),d=a.slice(l+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),process.env[c]??=d}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}async function kr(s,e){let t=Ke(s,{serverOnly:!0});if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=S.join(e,".typebulb");await M.mkdir(r,{recursive:!0});let n=Ge(t.code);n.length>0&&await qe(n,r);let i=S.join(r,"server.mjs");return await M.writeFile(i,t.code,"utf-8"),await import(`${Jn(i).href}?t=${Date.now()}`)}async function Ce(s){let e=await M.readFile(s,"utf-8"),t=Tt(e);if(!t)throw new Error("Invalid .bulb.md file format");let r=_t(t);return{bulb:r,config:It(r.config)}}async function Rr(s,e,t,r,n){let{bulb:i,config:o}=await Ce(s),a=Ct(i.data),l=Ke(i.code,{jsxImportSource:o.jsxImportSource});l.error&&console.error("Compilation error:",l.error);let{importMap:c}=await Be.buildImportMap(l.code,o.dependencies??{},n?new Set([n.name]):void 0);n&&(c.imports[n.name]=n.entryUrl);let d=tr({name:i.name,code:l.code,css:i.css,html:i.html,data:a,insight:i.insight,importMap:c,watch:t?e:!1,trustHint:t?void 0:r}),p=t?d:rr({bulbHtml:d,name:i.name,watch:e}),m=S.dirname(s);o.env?.length&&Et(o.env,m);let w=null;return i.server&&t&&(w=await kr(i.server,m)),{html:p,bulb:i,serverExports:w}}async function Qn(s,e){let{bulb:t,config:r}=await Ce(s);!t.code&&!t.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let n=[];if(t.code){let{dir:o}=await yr({code:t.code,dependencies:r.dependencies??{},jsxImportSource:r.jsxImportSource,emitKey:s,local:e});n.push({role:"client",dir:o})}if(t.server){let{dir:o}=await br({server:t.server,bulbDir:S.dirname(s),emitKey:s});n.push({role:"server",dir:o})}let i=!1;for(let{role:o,dir:a}of n){let{stdout:l,exitCode:c}=await Zn(a);for(let d of l.split(/\r?\n/))d.trim()&&console.log(`${o} ${d}`);c!==0&&(i=!0)}i&&process.exit(1)}function Zn(s){return new Promise(e=>{let t=qn("npx",["tsc","--noEmit"],{cwd:s,shell:!0}),r="";t.stdout?.on("data",n=>{r+=n.toString()}),t.stderr?.on("data",n=>{r+=n.toString()}),t.on("close",n=>e({stdout:r,exitCode:n??1}))})}async function es(s,e){Er();let t=async()=>{let{bulb:r,config:n}=await Ce(s),i=S.dirname(s);n.env?.length&&Et(n.env,i),await kr(r.server,i)};if(console.log(`Running ${S.basename(s)}...`),await t(),e){console.log(`Watching for changes...
|
|
596
|
+
`);let r=new Rt;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),wt({bulbPath:s,emitter:r})}}async function ts(){let s=Kn(process.argv.slice(2));s.version&&(console.log(`typebulb ${zn}`),process.exit(0)),s.help&&(Yn(),process.exit(0));let e;if(!s.file||s.file==="."){let v=await Xn(process.cwd());v||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=v}else e=S.resolve(s.file);try{await M.access(e)}catch{console.error(`File not found: ${e}`),process.exit(1)}e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let t=s.file&&s.file!=="."?s.file:S.relative(process.cwd(),e)||S.basename(e),r=`npx typebulb --trust ${t.includes(" ")?`"${t}"`:t}`,n;if(s.local){let v;try{v=await Ce(e)}catch{}v&&!(s.local.name in(v.config.dependencies??{}))&&(console.error(`--replace: '${s.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),v&&(!v.bulb.code||s.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{n=await Pr(s.local)}catch(E){console.error(E instanceof Error?E.message:String(E)),process.exit(1)}console.log(`replace: ${n.name} \u2192 ${S.relative(process.cwd(),n.dir)||"."}`)}if(s.subcommand==="check"){await Qn(e,n);return}try{let{bulb:v}=await Ce(e);if(v.server&&(!v.code||s.server)){s.trust||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
|
|
597
|
+
${r}`),process.exit(1)),await es(e,s.watch);return}}catch{}let i=process.cwd(),o=s.watch?new Rt:void 0;Er(),console.log(`Loading ${S.basename(e)}...`);let{html:a,bulb:l,serverExports:c}=await Rr(e,s.watch,s.trust,r,n),d=await yt(s.port),p=await cr({getHtml:()=>a,basePath:i,port:d,reloadEmitter:o,getServerExports:()=>c,localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:s.trust,trustHint:r}),m=`http://localhost:${d}`;console.log(`
|
|
598
|
+
${l.name}`),console.log(` ${m}`),console.log(s.trust?" trust: granted (filesystem, AI, server.ts enabled)":` trust: sandboxed \u2014 re-run with --trust to enable filesystem / AI / server.ts
|
|
486
599
|
`),s.watch&&console.log(` Watching for changes...
|
|
487
|
-
`);let
|
|
488
|
-
`)}catch(
|
|
489
|
-
`),
|
|
490
|
-
Shutting down...`),
|
|
600
|
+
`);let w,f;if(s.watch&&o){let v=new Rt;if(v.on("reload",async()=>{try{console.log("Recompiling...");let E=await Rr(e,!0,s.trust,r,n);a=E.html,c=E.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
|
|
601
|
+
`)}catch(E){console.error("Compile error:",E)}}),w=wt({bulbPath:e,emitter:v}),n){let{name:E,serveDir:ae}=n;f=hr({dir:ae,onChange:()=>{console.log(`Local package '${E}' changed. Browser reloading...
|
|
602
|
+
`),o.emit("reload")}})}}s.open&&await dr(m);let R=async()=>{console.log(`
|
|
603
|
+
Shutting down...`),p.close(),w?.(),f?.();let v=S.join(S.dirname(e),".typebulb","server.mjs");await M.rm(v,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",R),process.on("SIGTERM",R)}ts().catch(s=>{console.error("Error:",s.message),process.exit(1)});
|