typebulb 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +23 -18
  2. package/package.json +38 -38
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import*as v from"fs/promises";import{readFileSync as et,existsSync as Se}from"fs";import*as y from"path";import{pathToFileURL as tt}from"url";import{execFile as rt}from"child_process";import{promisify as st}from"util";import{EventEmitter as se}from"events";var Ae={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 W(n){try{let e=n.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 s=ke(r);if(!s)return null;let o=new Map;for(;t<e.length;){let l=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(l){let d=l[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let u=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!u){t++;continue}let a=u[1];t++;let p=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${a}\\s*$`));)p.push(e[t]),t++;t++,o.set(d,p.join(`
4
- `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function ke(n){let e={};for(let t of n){let r=t.indexOf(":");if(r===-1)continue;let s=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=Te(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Te(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function J(n){let e=t=>n.files.get(Ae[t].path)||"";return{name:n.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 Oe(n){try{return JSON.parse(n),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(n)||/^---\s*$/m.test(n)||/^\w[\w\s]*:[ \t]/m.test(n))}function oe(n){let e=n.trim();return e?Oe(e)?[e]:n.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function G(n){if(!n.trim())return{};try{return JSON.parse(n)}catch{return{}}}import{transform as ie}from"sucrase";function Me(n,e){try{let{code:t}=ie(n,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function ae(n,e={}){return Me(n,e)}function ce(n){try{let{code:e}=ie(n,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var M="https://esm.sh",$="https://cdn.jsdelivr.net/npm/",z="https://data.jsdelivr.com/v1/package/npm/";function le(n){let e=(n||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class n{constructor(e,t,r){let s=typeof e=="string"?n.parse(e):e;this.name=s.name,this.version=I(t??s.version),this.subpath=I(r??s.subpath)}static parse(e){let t=le(e||"");if(!t.length)return new n({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=pe(t[1]??""),l=I(t.slice(2).join("/"));return new n({name:`${s}/${o}`,version:i,subpath:l})}else{let[s,o]=pe(t[0]),i=I(t.slice(1).join("/"));return new n({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL(M).host,s=new URL($).host;if(t.host===r){let o=le(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return n.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return n.parse(i)}return}catch{return}}static versionFromUrl(e){return n.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 n.parse(e).name}withVersion(e){return new n({name:this.name,version:I(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://")}},I=n=>n&&n.length?n:void 0,pe=n=>{let e=n.indexOf("@");return e<0?[n,void 0]:[n.slice(0,e),I(n.slice(e+1))]};async function b(n){try{return await n()}catch{return}}var C=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=M,this.jsDelivrBase=$,this.jsDelivrMeta=z,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:s=!1,external:o}=t,i=new URLSearchParams({target:r});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),s=await b(()=>this.http.head(r));return s?.ok?s.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 s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let r=await b(()=>this.http.head(t)),s=this.parseVersionFromUrl(r?.url||t);if(s)return s}}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 b(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,s),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:a,peerDependencies:p,peerDependenciesMeta:c}=r;return{name:e,version:t,dependencies:a,peerDependencies:p,peerDependenciesMeta:c}}let s=this.packageJson(new g(`${e}@${t}`)),o=await b(()=>this.http.getJson(s));if(!o)return;let i=a=>a&&Object.keys(a).length?a:void 0,l=i(o.dependencies),d=i(o.peerDependencies),u=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,l,d,u),{name:e,version:t,dependencies:l,peerDependencies:d,peerDependenciesMeta:u}}};var de=n=>n.startsWith("@types/"),D=n=>Object.keys(n?.peerDependencies||{}).filter(e=>!de(e)),K=n=>Object.keys(n?.dependencies||{}).filter(e=>!de(e)),$e=n=>D(n).filter(e=>!n?.peerDependenciesMeta?.[e]?.optional),B=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}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(o=>[o.name,o])),s=[];for(let o of e)for(let i of $e(o.meta))!r.has(i)&&!s.some(l=>l.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let l=await t(o),d=await this.cdn.fetchPackageMeta(o,l);r.set(o,{name:o,version:l,meta:d})}catch(l){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,l)}return{allRoots:[...r.values()],autoAddedPeers:s.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>D(o.meta))),r=new Map;for(let o of e)for(let i of K(o.meta))r.set(i,(r.get(i)||0)+1);let s=new Set([...r.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:D(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var N=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 b(()=>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 s=await b(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let l=await b(()=>this.cdn.fetchVersionsIndex(e));if(l?.versions?.length){let d=this.selectVersionFromIndex(l.versions,t,l.distTags);if(d&&this.semver.isExactVersion(d))return await this.cache.setPinnedExact(e,t,d),d}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let r=new g(e),s=r.root(),o=t[s],i=o?await b(()=>this.cache.getPinnedExact(s,o))??await b(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as Ce,parse as De}from"es-module-lexer";var A=class n{constructor(e,t,r,s){this.version=e,this.cdn=t,this.peer=r,this.cache=s}extractImportsSync(e){let t=new Set;for(let r of n.importPatterns){r.lastIndex=0;for(let s of e.matchAll(r))g.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=s=>{g.isBare(s)&&t.add(s)};try{await Ce;let[s]=De(e);s.forEach(o=>r(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t){let r=await this.extractImports(e),s=[...new Set(r.map(g.rootOf))],o=await Promise.all(s.map(async a=>({name:a,version:await this.resolveVersion(a,t)}))),{allRoots:i,flags:l,autoAddedPeers:d}=await this.peer.resolve(o,a=>this.resolveVersion(a,t)),u=this.buildEntries([...r,...d.map(a=>a.name)],i,l,t);return{importMap:{imports:Object.fromEntries(u)},prefetchUrls:u.map(([,a])=>a)}}async resolveVersion(e,t){let r=t[e],s=await this.version.resolveExactForRoot(e,r);if(!s){let o=r?`${e}@${r}`:e,i=await b(()=>this.cdn.pinEsmUrl(o));if(!i)throw new Error(`Cannot resolve version for ${e} - network may be unavailable.`);s=g.versionFromUrl(i),s&&r&&await b(()=>this.cache.setPinnedExact(e,r,s))}if(!s)throw new Error(`Cannot resolve version for ${e}`);return s}buildEntries(e,t,r,s){let o=new Map(t.map(c=>[c.name,c])),i=c=>{let f=o.get(g.rootOf(c));return new g(c).withPreferredVersion(f.version,s[f.name]).format()},l=new Set([...r.entries()].filter(([,c])=>c.isPeerRoot||c.isSharedDep).map(([c])=>c)),d=new Set(e.filter(c=>c!==g.rootOf(c)).map(g.rootOf)),u=[],a=new Set,p=new Set(e.filter(c=>c===g.rootOf(c)));for(let c of e){let f=g.rootOf(c),h=o.get(f),{isPeerRoot:m,hasPeers:w,isSharedDep:R}=r.get(f),P=d.has(f),V=c!==f,H=!(m||R)&&(P||!w),E=this.singletonDepsOf(h,l),Ie=V&&p.has(f)?[...E,f]:E.length?E:void 0;u.push([c,this.cdn.buildEsmUrl(i(c),{bundle:H,external:Ie})]),a.add(c)}for(let c of l)o.has(c)&&(a.has(c)||u.push([c,this.cdn.buildEsmUrl(i(c),{})]),u.push([`${c}/`,`${this.cdn.esmHost}/${i(c)}/`]));return u}singletonDepsOf(e,t){return[...new Set([...D(e.meta),...K(e.meta)])].filter(r=>t.has(r))}};A.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as ue,satisfies as Be,maxSatisfying as Y,major as Ne,prerelease as je,rsort as Fe,valid as Ue}from"semver";var q=class{cmp(e,t){return e===t?0:ue(e,t)?1:ue(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Be(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Y(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Fe(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(s){let l=Y(e,r,{includePrerelease:!1});if(l)return l}return Y(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Ne(e)}isPrerelease(e){return je(e)!==null}isExactVersion(e){return Ue(e)!==null}},X=new q;function fe(n,e){let t=new C(n,e),r=new B(t),s=new N(n,t,X);return{packageService:new A(s,t,r,n),versionResolver:s,cdnClient:t,peerResolver:r}}var Z=class{pins=new Map;indexes=new Map;negatives=new Set;meta=new Map;async getPinnedExact(e,t){return this.pins.get(`${e}@${t}`)}async setPinnedExact(e,t,r){this.pins.set(`${e}@${t}`,r)}async getIndex(e){return this.indexes.get(e)}async setIndex(e,t,r){this.indexes.set(e,{versions:t,distTags:r,updatedAt:Date.now()})}async invalidateVersionsCache(e){this.indexes.delete(e)}async isNegative(e){return this.negatives.has(e)}async recordNegative(e){this.negatives.add(e)}async clearNegative(e){this.negatives.delete(e)}async getMeta(e,t){return this.meta.get(`${e}@${t}`)}async setMeta(e,t,r,s,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()})}},Le={async getJson(n){try{let e=await fetch(n,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(n){try{let e=await fetch(n,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}},Ve=new Z,{packageService:me,versionResolver:Yt,cdnClient:Xt,peerResolver:Zt}=fe(Ve,Le);var he=`
2
+ import*as v from"fs/promises";import{readFileSync as nt,existsSync as Re}from"fs";import*as y from"path";import{pathToFileURL as ot}from"url";import{execFile as it}from"child_process";import{promisify as at}from"util";import{EventEmitter as oe}from"events";var Me={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 H(n){try{let e=n.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 s=$e(r);if(!s)return null;let o=new Map;for(;t<e.length;){let l=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(l){let d=l[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let u=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!u){t++;continue}let a=u[1];t++;let p=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${a}\\s*$`));)p.push(e[t]),t++;t++,o.set(d,p.join(`
4
+ `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function $e(n){let e={};for(let t of n){let r=t.indexOf(":");if(r===-1)continue;let s=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=Ce(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Ce(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function W(n){let e=t=>n.files.get(Me[t].path)||"";return{name:n.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 De(n){try{return JSON.parse(n),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(n)||/^---\s*$/m.test(n)||/^\w[\w\s]*:[ \t]/m.test(n))}function ae(n){let e=n.trim();return e?De(e)?[e]:n.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function G(n){if(!n.trim())return{};try{return JSON.parse(n)}catch{return{}}}import{transform as ce}from"sucrase";function Be(n,e){try{let{code:t}=ce(n,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function le(n,e={}){return Be(n,e)}function pe(n){try{let{code:e}=ce(n,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var M="https://esm.sh",$="https://cdn.jsdelivr.net/npm/",z="https://data.jsdelivr.com/v1/package/npm/";function de(n){let e=(n||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class n{constructor(e,t,r){let s=typeof e=="string"?n.parse(e):e;this.name=s.name,this.version=A(t??s.version),this.subpath=A(r??s.subpath)}static parse(e){let t=de(e||"");if(!t.length)return new n({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=ue(t[1]??""),l=A(t.slice(2).join("/"));return new n({name:`${s}/${o}`,version:i,subpath:l})}else{let[s,o]=ue(t[0]),i=A(t.slice(1).join("/"));return new n({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL(M).host,s=new URL($).host;if(t.host===r){let o=de(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return n.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return n.parse(i)}return}catch{return}}static versionFromUrl(e){return n.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 n.parse(e).name}withVersion(e){return new n({name:this.name,version:A(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://")}},A=n=>n&&n.length?n:void 0,ue=n=>{let e=n.indexOf("@");return e<0?[n,void 0]:[n.slice(0,e),A(n.slice(e+1))]};async function b(n){try{return await n()}catch{return}}var C=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=M,this.jsDelivrBase=$,this.jsDelivrMeta=z,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:s=!1,external:o}=t,i=new URLSearchParams({target:r});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),s=await b(()=>this.http.head(r));return s?.ok?s.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 s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let r=await b(()=>this.http.head(t)),s=this.parseVersionFromUrl(r?.url||t);if(s)return s}}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 b(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,s),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:a,peerDependencies:p,peerDependenciesMeta:c}=r;return{name:e,version:t,dependencies:a,peerDependencies:p,peerDependenciesMeta:c}}let s=this.packageJson(new g(`${e}@${t}`)),o=await b(()=>this.http.getJson(s));if(!o)return;let i=a=>a&&Object.keys(a).length?a:void 0,l=i(o.dependencies),d=i(o.peerDependencies),u=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,l,d,u),{name:e,version:t,dependencies:l,peerDependencies:d,peerDependenciesMeta:u}}};var fe=n=>n.startsWith("@types/"),D=n=>Object.keys(n?.peerDependencies||{}).filter(e=>!fe(e)),K=n=>Object.keys(n?.dependencies||{}).filter(e=>!fe(e)),Ne=n=>D(n).filter(e=>!n?.peerDependenciesMeta?.[e]?.optional),B=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}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(o=>[o.name,o])),s=[];for(let o of e)for(let i of Ne(o.meta))!r.has(i)&&!s.some(l=>l.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let l=await t(o),d=await this.cdn.fetchPackageMeta(o,l);r.set(o,{name:o,version:l,meta:d})}catch(l){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,l)}return{allRoots:[...r.values()],autoAddedPeers:s.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>D(o.meta))),r=new Map;for(let o of e)for(let i of K(o.meta))r.set(i,(r.get(i)||0)+1);let s=new Set([...r.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:D(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var N=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 b(()=>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 s=await b(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let l=await b(()=>this.cdn.fetchVersionsIndex(e));if(l?.versions?.length){let d=this.selectVersionFromIndex(l.versions,t,l.distTags);if(d&&this.semver.isExactVersion(d))return await this.cache.setPinnedExact(e,t,d),d}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let r=new g(e),s=r.root(),o=t[s],i=o?await b(()=>this.cache.getPinnedExact(s,o))??await b(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as je,parse as Fe}from"es-module-lexer";var I=class n{constructor(e,t,r,s){this.version=e,this.cdn=t,this.peer=r,this.cache=s}extractImportsSync(e){let t=new Set;for(let r of n.importPatterns){r.lastIndex=0;for(let s of e.matchAll(r))g.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=s=>{g.isBare(s)&&t.add(s)};try{await je;let[s]=Fe(e);s.forEach(o=>r(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t){let r=await this.extractImports(e),s=[...new Set(r.map(g.rootOf))],o=await Promise.all(s.map(async a=>({name:a,version:await this.resolveVersion(a,t)}))),{allRoots:i,flags:l,autoAddedPeers:d}=await this.peer.resolve(o,a=>this.resolveVersion(a,t)),u=this.buildEntries([...r,...d.map(a=>a.name)],i,l,t);return{importMap:{imports:Object.fromEntries(u)},prefetchUrls:u.map(([,a])=>a)}}async resolveVersion(e,t){let r=t[e],s=await this.version.resolveExactForRoot(e,r);if(!s){let o=r?`${e}@${r}`:e,i=await b(()=>this.cdn.pinEsmUrl(o));if(!i)throw new Error(`Cannot resolve version for ${e} - network may be unavailable.`);s=g.versionFromUrl(i),s&&r&&await b(()=>this.cache.setPinnedExact(e,r,s))}if(!s)throw new Error(`Cannot resolve version for ${e}`);return s}buildEntries(e,t,r,s){let o=new Map(t.map(c=>[c.name,c])),i=c=>{let f=o.get(g.rootOf(c));return new g(c).withPreferredVersion(f.version,s[f.name]).format()},l=new Set([...r.entries()].filter(([,c])=>c.isPeerRoot||c.isSharedDep).map(([c])=>c)),d=new Set(e.filter(c=>c!==g.rootOf(c)).map(g.rootOf)),u=[],a=new Set,p=new Set(e.filter(c=>c===g.rootOf(c)));for(let c of e){let f=g.rootOf(c),h=o.get(f),{isPeerRoot:m,hasPeers:w,isSharedDep:R}=r.get(f),P=d.has(f),V=c!==f,Te=!(m||R)&&(P||!w),q=this.singletonDepsOf(h,l),Oe=V&&p.has(f)?[...q,f]:q.length?q:void 0;u.push([c,this.cdn.buildEsmUrl(i(c),{bundle:Te,external:Oe})]),a.add(c)}for(let c of l)o.has(c)&&(a.has(c)||u.push([c,this.cdn.buildEsmUrl(i(c),{})]),u.push([`${c}/`,`${this.cdn.esmHost}/${i(c)}/`]));return u}singletonDepsOf(e,t){return[...new Set([...D(e.meta),...K(e.meta)])].filter(r=>t.has(r))}};I.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as me,satisfies as Ue,maxSatisfying as Y,major as Le,prerelease as Ve,rsort as He,valid as We}from"semver";var J=class{cmp(e,t){return e===t?0:me(e,t)?1:me(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Ue(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Y(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?He(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(s){let l=Y(e,r,{includePrerelease:!1});if(l)return l}return Y(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Le(e)}isPrerelease(e){return Ve(e)!==null}isExactVersion(e){return We(e)!==null}},X=new J;function he(n,e){let t=new C(n,e),r=new B(t),s=new N(n,t,X);return{packageService:new I(s,t,r,n),versionResolver:s,cdnClient:t,peerResolver:r}}var Z=class{pins=new Map;indexes=new Map;negatives=new Set;meta=new Map;async getPinnedExact(e,t){return this.pins.get(`${e}@${t}`)}async setPinnedExact(e,t,r){this.pins.set(`${e}@${t}`,r)}async getIndex(e){return this.indexes.get(e)}async setIndex(e,t,r){this.indexes.set(e,{versions:t,distTags:r,updatedAt:Date.now()})}async invalidateVersionsCache(e){this.indexes.delete(e)}async isNegative(e){return this.negatives.has(e)}async recordNegative(e){this.negatives.add(e)}async clearNegative(e){this.negatives.delete(e)}async getMeta(e,t){return this.meta.get(`${e}@${t}`)}async setMeta(e,t,r,s,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()})}},Je={async getJson(n){try{let e=await fetch(n,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(n){try{let e=await fetch(n,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}},qe=new Z,{packageService:ge,versionResolver:er,cdnClient:tr,peerResolver:rr}=he(qe,Je);var ye=`
5
5
  (() => {
6
6
  // JSON parser (handles jsonish - unquoted keys)
7
7
  const parseJson = (str) => {
@@ -149,12 +149,12 @@ import*as v from"fs/promises";import{readFileSync as et,existsSync as Se}from"fs
149
149
  };
150
150
  }
151
151
  })();
152
- `;function ge(n){let{name:e,code:t,css:r,html:s,data:o,insight:i,importMap:l,watch:d}=n,u=s.trim()||'<div id="app"></div>',a=p=>p.replace(/<\/script/gi,"<\\/script");return`<!DOCTYPE html>
152
+ `;function ve(n){let{name:e,code:t,css:r,html:s,data:o,insight:i,importMap:l,watch:d}=n,u=s.trim()||'<div id="app"></div>',a=p=>p.replace(/<\/script/gi,"<\\/script");return`<!DOCTYPE html>
153
153
  <html>
154
154
  <head>
155
155
  <meta charset="utf-8">
156
156
  <meta name="viewport" content="width=device-width, initial-scale=1">
157
- <title>${He(e)} - typebulb</title>
157
+ <title>${Ge(e)} - typebulb</title>
158
158
  <script type="importmap">
159
159
  ${JSON.stringify(l,null,2)}
160
160
  </script>
@@ -175,23 +175,28 @@ ${i?`<script>window.__TB_INSIGHT__ = ${a(JSON.stringify(i))};</script>`:""}
175
175
  ${d?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
176
176
 
177
177
  <script>
178
- ${he}
178
+ ${ye}
179
179
  </script>
180
180
 
181
181
  <script type="module">
182
182
  ${a(t)}
183
183
  </script>
184
184
  </body>
185
- </html>`}function He(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}import{Hono as Je}from"hono";import{serve as qe}from"@hono/node-server";import{streamSSE as Ge}from"hono/streaming";import*as O from"fs/promises";import*as _ from"path";var S=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},x=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=`
185
+ </html>`}function Ge(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}import{Hono as Ke}from"hono";import{serve as Ye}from"@hono/node-server";import{streamSSE as Xe}from"hono/streaming";import*as T from"fs/promises";import*as _ from"path";var x=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},S=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=`
186
186
 
187
- `){let r=e.filter(s=>s.role==="system").map(s=>s.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return r&&(o.code=s.error.code),o}return s.message?{message:s.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",s=!!e.retryable;throw new S(t,r,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new S(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 j=class extends x{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,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),l={model:t,max_tokens:this.getMaxTokens(t),messages:i,stream:s};if(r?.webSearch!==!1&&(l.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(l.system=o),this.isReasoningEnabled(r)){let d=r.reasoning;if(this.isAdaptiveModel(t)){let u={0:"low",1:"low",2:"medium",3:"high"};l.thinking={type:"adaptive"},l.output_config={effort:u[d]}}else{let u={0:0,1:2048,2:4096,3:8192};l.thinking={type:"enabled",budget_tokens:u[d]}}}return l}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),r=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
187
+ `){let r=e.filter(s=>s.role==="system").map(s=>s.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return r&&(o.code=s.error.code),o}return s.message?{message:s.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",s=!!e.retryable;throw new x(t,r,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new x(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 j=class extends S{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,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),l={model:t,max_tokens:this.getMaxTokens(t),messages:i,stream:s};if(r?.webSearch!==!1&&(l.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(l.system=o),this.isReasoningEnabled(r)){let d=r.reasoning;if(this.isModernModel(t)){let u={0:"low",1:"low",2:"medium",3:"high"};l.thinking={type:"adaptive"},l.output_config={effort:u[d]}}else{let u={0:0,1:2048,2:4096,3:8192};l.thinking={type:"enabled",budget_tokens:u[d]}}}return l}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),r=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
188
188
 
189
- `);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}}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isAdaptiveModel(e){return e.startsWith("claude-opus-4-6")}getMaxTokens(e){return e.startsWith("claude-opus-4-6")?64e3:32e3}};var F=class extends x{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,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return r?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),i}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 s of e.output)s.type==="reasoning"&&s.summary&&(r=s.summary.map(o=>o.text).join(`
190
- `)),!t&&s.type==="message"&&s.content&&(t=s.content.filter(o=>o.type==="output_text").map(o=>o.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 s=e.response?.error,o=s?.message||"Response failed",i=s?.code==="insufficient_quota"||s?.code==="rate_limit_exceeded";throw new S(o,i?"rate_limit":"unknown",i)}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(`
189
+ `);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}}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 F=class extends S{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,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return r?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),i}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 s of e.output)s.type==="reasoning"&&s.summary&&(r=s.summary.map(o=>o.text).join(`
190
+ `)),!t&&s.type==="message"&&s.content&&(t=s.content.filter(o=>o.type==="output_text").map(o=>o.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 s=e.response?.error,o=s?.message||"Response failed",i=s?.code==="insufficient_quota"||s?.code==="rate_limit_exceeded";throw new x(o,i?"rate_limit":"unknown",i)}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(`
191
191
 
192
- `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var U=class extends x{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,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
192
+ `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var U=class extends S{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,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
193
193
  `),d={contents:i.map(u=>({role:u.role==="assistant"?"model":"user",parts:[{text:u.content}]}))};return r?.webSearch!==!1&&(d.tools=[{google_search:{}}]),o&&(d.systemInstruction={role:"system",parts:[{text:o}]}),this.isReasoningEnabled(r)&&(d.generationConfig={temperature:.7+r.reasoning*.1}),d}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let r=JSON.parse(e),s=Array.isArray(r)?r[0]?.error:r?.error;return s&&typeof s=="object"?{message:(s.message||`HTTP ${t}`).split(`
194
- `)[0],type:s.status,code:s.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,s="complete";return r==="MAX_TOKENS"?s="interrupted":(r==="SAFETY"||r==="RECITATION")&&(s="failed"),{text:t,status:s}}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 s=t;r=s.message||s.status||"Gemini returned an error"}else r="Gemini returned an error";throw new S(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new S(`Prompt blocked: ${t}`)}}};var L=class extends x{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,s){let o={model:t,messages:e,stream:s};return r?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning]}),o}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??"",s=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:s}}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 s=r.content||void 0,o=r.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var We=new Map([["openai",new F],["openrouter",new L],["anthropic",new j],["gemini",new U]]);function k(n){let e=We.get(n);if(!e)throw new Error(`Unsupported protocol: ${n}`);return e}async function Q(n,e){let t=k(n.protocol),r=t.getPath(e.model,e.stream),s=new URL(r,n.baseUrl).toString(),o=t.buildHeaders(n.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function ee(n,e){let t=k(e),r=await n.text().catch(()=>""),{message:s}=t.parseError(r,n.status),o=n.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}async function we(n){let{getHtml:e,basePath:t,port:r,reloadEmitter:s,getServerExports:o}=n,i=new Je;i.use("*",async(a,p)=>{await p(),a.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),a.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),i.get("/",a=>a.html(e())),i.post("/__fs/read",async a=>{try{let{path:p}=await a.req.json(),c=ve(p,t),f=await O.readFile(c,"utf-8");return a.json({content:f})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},400)}}),i.post("/__fs/write",async a=>{try{let{path:p,content:c}=await a.req.json(),f=ve(p,t);return await O.mkdir(_.dirname(f),{recursive:!0}),await O.writeFile(f,c,"utf-8"),a.json({success:!0})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},400)}});let l={log:console.log};i.post("/__api/:name",async a=>{try{let p=o?.(),c=a.req.param("name"),f=p?.[c]??l[c];if(!f||typeof f!="function")return a.json({error:`API function '${c}' not found`},404);let{args:h}=await a.req.json(),m=await f(...h||[]);return a.json({result:m})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},500)}}),i.post("/__ai",async a=>{try{let{messages:p,system:c,reasoning:f,provider:h,model:m}=await a.req.json();if(!p||!Array.isArray(p)||p.length===0)return a.json({message:"messages array is required",code:"unknown",retryable:!1},400);let w=ze(h,m);if(typeof w=="string")return a.json({message:w,code:"unknown",retryable:!1},400);let R=[...c?[{role:"system",content:c}]:[],...p.map(E=>({role:E.role,content:E.content}))],P=await Q(w,{model:w.model,messages:R,stream:!1,reasoning:f??0,webSearch:!1});if(!P.ok){let E=await ee(P,w.protocol);return a.json(E,P.status)}let V=await P.json(),H=k(w.protocol).parseNonStreamingResponse(V);return H.text||console.warn("[tb.ai] Empty response from provider. Raw response:",JSON.stringify(V).slice(0,500)),a.json({text:H.text})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({message:c,code:"unknown",retryable:!1},500)}}),i.get("/__models",async a=>{try{let p=await Xe();return a.json(p)}catch{return a.json([],200)}});let d=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"];i.get("/proxy/*",async a=>{let p=a.req.path.slice(7),c=p.lastIndexOf("https://");if(c===-1)return a.text("Invalid proxy URL",400);let f=p.slice(c),h;try{h=new URL(f)}catch{return a.text("Invalid URL",400)}if(h.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(h.hostname))return a.text("Host not allowed",403);try{let m=await fetch(f,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!m.ok)return a.text(`Upstream ${m.status}`,m.status);let w=new Headers,R=m.headers.get("Content-Type");R&&w.set("Content-Type",R);let P=m.headers.get("Cache-Control");return P&&w.set("Cache-Control",P),w.set("Access-Control-Allow-Origin","*"),w.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(m.body,{status:m.status,headers:w})}catch(m){return a.text(`Proxy fetch failed: ${m instanceof Error?m.message:m}`,502)}}),s&&i.get("/__reload",a=>Ge(a,async p=>{let c=()=>{p.writeSSE({event:"reload",data:""})};for(s.on("reload",c),p.onAbort(()=>{s.removeListener("reload",c)});;)await p.sleep(3e4)}));let u=qe({fetch:i.fetch,port:r});return{port:r,close:()=>u.close()}}var be={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function ze(n,e){let t=n??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 s;try{s=k(t)}catch{return`Unknown provider '${t}'.`}let o=be[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}var Ke="https://api.typebulb.com/api/models",Ye=1440*60*1e3,T=null;async function Xe(){if(!T||Date.now()-T.fetchedAt>Ye){let n=await fetch(Ke);if(!n.ok)return T?ye(T.models):[];T={models:await n.json(),fetchedAt:Date.now()}}return ye(T.models)}function ye(n){let e=new Set(Object.entries(be).filter(([,t])=>!!process.env[t]).map(([t])=>t));return n.filter(t=>e.has(t.provider))}function ve(n,e){let t=_.resolve(e,n),r=_.normalize(e);if(!_.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function te(n){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(n,()=>{let s=r.address(),o=typeof s=="object"&&s?s.port:n;r.close(()=>t(o))}),r.on("error",()=>{t(te(n+1))})})}import Ze from"open";async function xe(n){await Ze(n)}import Qe from"chokidar";function re(n){let{bulbPath:e,emitter:t}=n,r=Qe.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var nt=st(rt),ot="0.1.3";function it(n){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};for(let t=0;t<n.length;t++){let r=n[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==="--port"||r==="-p"){let s=n[++t],o=parseInt(s,10);isNaN(o)&&(console.error(`Invalid port: ${s}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function at(){console.log(`
194
+ `)[0],type:s.status,code:s.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,s="complete";return r==="MAX_TOKENS"?s="interrupted":(r==="SAFETY"||r==="RECITATION")&&(s="failed"),{text:t,status:s}}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 s=t;r=s.message||s.status||"Gemini returned an error"}else r="Gemini returned an error";throw new x(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new x(`Prompt blocked: ${t}`)}}};var L=class extends S{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,s){let o={model:t,messages:e,stream:s};return r?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning]}),o}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??"",s=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:s}}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 s=r.content||void 0,o=r.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var ze=new Map([["openai",new F],["openrouter",new L],["anthropic",new j],["gemini",new U]]);function E(n){let e=ze.get(n);if(!e)throw new Error(`Unsupported protocol: ${n}`);return e}async function Q(n,e){let t=E(n.protocol),r=t.getPath(e.model,e.stream),s=new URL(r,n.baseUrl).toString(),o=t.buildHeaders(n.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function ee(n,e){let t=E(e),r=await n.text().catch(()=>""),{message:s}=t.parseError(r,n.status),o=n.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}function we(n){let e=n.indexOf(`\r
195
+ \r
196
+ `),t=n.indexOf(`
197
+
198
+ `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function te(n){let t=n.split(/\r?\n/).filter(s=>s.startsWith("data:"));if(!t.length)return null;let r=t.map(s=>s.replace(/^data:\s?/,"")).join(`
199
+ `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function be(n,e,t){let r=new TextDecoder,s="",o=!1,i=t?new Promise((l,d)=>{t.aborted&&d(new Error("Aborted")),t.addEventListener("abort",()=>d(new Error("Aborted")),{once:!0})}):null;for(;;){let l=i?await Promise.race([n.read(),i]):await n.read(),{done:d,value:u}=l;if(d){if(s.trim()){let c=te(s);c!==null&&c!=="done"&&e(c)}break}o=!0,s+=r.decode(u,{stream:!0});let{pos:a,len:p}=we(s);for(;a!==-1;){let c=s.slice(0,a);s=s.slice(a+p);let f=te(c);if(f==="done"){s="";break}f!==null&&e(f),{pos:a,len:p}=we(s)}}return{receivedAnyData:o}}async function re(n,e){let t=e??(n.headers.get("X-Provider-Protocol")||"openai"),r=E(t);if(!n.body)throw new Error("Response body is missing");let s=n.body.getReader(),o="";return await be(s,i=>{let l=r.parseStreamChunk(i);l?.text&&(o+=l.text)}),o}async function Pe(n){let{getHtml:e,basePath:t,port:r,reloadEmitter:s,getServerExports:o}=n,i=new Ke;i.use("*",async(a,p)=>{await p(),a.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),a.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),i.get("/",a=>a.html(e())),i.post("/__fs/read",async a=>{try{let{path:p}=await a.req.json(),c=Se(p,t),f=await T.readFile(c,"utf-8");return a.json({content:f})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},400)}}),i.post("/__fs/write",async a=>{try{let{path:p,content:c}=await a.req.json(),f=Se(p,t);return await T.mkdir(_.dirname(f),{recursive:!0}),await T.writeFile(f,c,"utf-8"),a.json({success:!0})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},400)}});let l={log:console.log};i.post("/__api/:name",async a=>{try{let p=o?.(),c=a.req.param("name"),f=p?.[c]??l[c];if(!f||typeof f!="function")return a.json({error:`API function '${c}' not found`},404);let{args:h}=await a.req.json(),m=await f(...h||[]);return a.json({result:m})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},500)}}),i.post("/__ai",async a=>{try{let{messages:p,system:c,reasoning:f,provider:h,model:m}=await a.req.json();if(!p||!Array.isArray(p)||p.length===0)return a.json({message:"messages array is required",code:"unknown",retryable:!1},400);let w=Ze(h,m);if(typeof w=="string")return a.json({message:w,code:"unknown",retryable:!1},400);let R=[...c?[{role:"system",content:c}]:[],...p.map(O=>({role:O.role,content:O.content}))],P=await Q(w,{model:w.model,messages:R,stream:!0,reasoning:f??0,webSearch:!1});if(!P.ok){let O=await ee(P,w.protocol);return a.json(O,P.status)}let V=await re(P,w.protocol);return V||console.warn("[tb.ai] Empty response from provider"),a.json({text:V})}catch(p){if(p instanceof x)return a.json({message:p.message,code:p.code,retryable:p.retryable},500);let c=p instanceof Error?p.message:"Unknown error";return a.json({message:c,code:"unknown",retryable:!1},500)}}),i.get("/__models",async a=>{try{let p=await tt();return a.json(p)}catch{return a.json([],200)}});let d=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"];i.get("/proxy/*",async a=>{let p=a.req.path.slice(7),c=p.lastIndexOf("https://");if(c===-1)return a.text("Invalid proxy URL",400);let f=p.slice(c),h;try{h=new URL(f)}catch{return a.text("Invalid URL",400)}if(h.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(h.hostname))return a.text("Host not allowed",403);try{let m=await fetch(f,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!m.ok)return a.text(`Upstream ${m.status}`,m.status);let w=new Headers,R=m.headers.get("Content-Type");R&&w.set("Content-Type",R);let P=m.headers.get("Cache-Control");return P&&w.set("Cache-Control",P),w.set("Access-Control-Allow-Origin","*"),w.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(m.body,{status:m.status,headers:w})}catch(m){return a.text(`Proxy fetch failed: ${m instanceof Error?m.message:m}`,502)}}),s&&i.get("/__reload",a=>Xe(a,async p=>{let c=()=>{p.writeSSE({event:"reload",data:""})};for(s.on("reload",c),p.onAbort(()=>{s.removeListener("reload",c)});;)await p.sleep(3e4)}));let u=Ye({fetch:i.fetch,port:r});return{port:r,close:()=>u.close()}}var Ee={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function Ze(n,e){let t=n??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 s;try{s=E(t)}catch{return`Unknown provider '${t}'.`}let o=Ee[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}var Qe="https://api.typebulb.com/api/models",et=1440*60*1e3,k=null;async function tt(){if(!k||Date.now()-k.fetchedAt>et){let n=await fetch(Qe);if(!n.ok)return k?xe(k.models):[];k={models:await n.json(),fetchedAt:Date.now()}}return xe(k.models)}function xe(n){let e=new Set(Object.entries(Ee).filter(([,t])=>!!process.env[t]).map(([t])=>t));return n.filter(t=>e.has(t.provider))}function Se(n,e){let t=_.resolve(e,n),r=_.normalize(e);if(!_.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function se(n){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(n,()=>{let s=r.address(),o=typeof s=="object"&&s?s.port:n;r.close(()=>t(o))}),r.on("error",()=>{t(se(n+1))})})}import rt from"open";async function _e(n){await rt(n)}import st from"chokidar";function ne(n){let{bulbPath:e,emitter:t}=n,r=st.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var ct=at(it),lt="0.1.3";function pt(n){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};for(let t=0;t<n.length;t++){let r=n[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==="--port"||r==="-p"){let s=n[++t],o=parseInt(s,10);isNaN(o)&&(console.error(`Invalid port: ${s}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function dt(){console.log(`
195
200
  typebulb - Local bulb runner for Typebulb
196
201
 
197
202
  Usage:
@@ -238,11 +243,11 @@ Examples:
238
243
  typebulb my-editor.bulb.md
239
244
  typebulb --no-watch --port 8080 my-editor.bulb.md
240
245
  typebulb .
241
- `)}async function ct(n){let t=(await v.readdir(n)).find(r=>r.endsWith(".bulb.md"));return t?y.join(n,t):null}function Ee(){ne([".env",".env.local"],process.cwd(),!0)}function ne(n,e,t=!1){for(let r of n){let s=y.resolve(e,r);try{let o=et(s,"utf-8");for(let i of o.split(`
242
- `)){let l=i.trim();if(!l||l.startsWith("#"))continue;let d=l.indexOf("=");if(d===-1)continue;let u=l.slice(0,d).trim(),a=l.slice(d+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),process.env[u]??=a}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}function lt(n){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(n);){let s=r[1];if(s.startsWith("node:"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}async function pt(n,e){let t=n.filter(s=>!Se(y.join(e,"node_modules",s)));if(t.length===0)return;let r=y.join(e,"package.json");Se(r)||await v.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await nt("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function _e(n,e){let t=ce(n);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=y.join(e,".typebulb");await v.mkdir(r,{recursive:!0});let s=lt(t.code);s.length>0&&await pt(s,r);let o=y.join(r,"server.mjs");return await v.writeFile(o,t.code,"utf-8"),await import(`${tt(o).href}?t=${Date.now()}`)}async function Pe(n,e){let t=await v.readFile(n,"utf-8"),r=W(t);if(!r)throw new Error("Invalid .bulb.md file format");let s=J(r),o=G(s.config),i=oe(s.data),l=ae(s.code,{jsxImportSource:o.jsxImportSource});l.error&&console.error("Compilation error:",l.error);let{importMap:d}=await me.buildImportMap(l.code,o.dependencies??{}),u=ge({name:s.name,code:l.code,css:s.css,html:s.html,data:i,insight:s.insight,importMap:d,watch:e}),a=y.dirname(n);o.env?.length&&ne(o.env,a);let p=null;return s.server&&(p=await _e(s.server,a)),{html:u,bulb:s,serverExports:p}}async function dt(n,e){Ee();let t=async()=>{let r=await v.readFile(n,"utf-8"),s=W(r);if(!s)throw new Error("Invalid .bulb.md file format");let o=J(s),i=G(o.config),l=y.dirname(n);i.env?.length&&ne(i.env,l),await _e(o.server,l)};if(console.log(`Running ${y.basename(n)}...`),await t(),e){console.log(`Watching for changes...
243
- `);let r=new se;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(s){console.error("Error:",s)}}),re({bulbPath:n,emitter:r})}}async function ut(){let n=it(process.argv.slice(2));n.version&&(console.log(`typebulb ${ot}`),process.exit(0)),n.help&&(at(),process.exit(0));let e;if(!n.file||n.file==="."){let h=await ct(process.cwd());h||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=h}else e=y.resolve(n.file);try{await v.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=await v.readFile(e,"utf-8"),r=W(t);if(r){let h=J(r);if(h.server&&(!h.code||n.server)){await dt(e,n.watch);return}}let s=process.cwd(),o=n.watch?new se:void 0;Ee(),console.log(`Loading ${y.basename(e)}...`);let{html:i,bulb:l,serverExports:d}=await Pe(e,n.watch),u=await te(n.port),a=await we({getHtml:()=>i,basePath:s,port:u,reloadEmitter:o,getServerExports:()=>d}),p=`http://localhost:${u}`;console.log(`
246
+ `)}async function ut(n){let t=(await v.readdir(n)).find(r=>r.endsWith(".bulb.md"));return t?y.join(n,t):null}function Ie(){ie([".env",".env.local"],process.cwd(),!0)}function ie(n,e,t=!1){for(let r of n){let s=y.resolve(e,r);try{let o=nt(s,"utf-8");for(let i of o.split(`
247
+ `)){let l=i.trim();if(!l||l.startsWith("#"))continue;let d=l.indexOf("=");if(d===-1)continue;let u=l.slice(0,d).trim(),a=l.slice(d+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),process.env[u]??=a}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}function ft(n){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(n);){let s=r[1];if(s.startsWith("node:"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}async function mt(n,e){let t=n.filter(s=>!Re(y.join(e,"node_modules",s)));if(t.length===0)return;let r=y.join(e,"package.json");Re(r)||await v.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await ct("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function ke(n,e){let t=pe(n);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=y.join(e,".typebulb");await v.mkdir(r,{recursive:!0});let s=ft(t.code);s.length>0&&await mt(s,r);let o=y.join(r,"server.mjs");return await v.writeFile(o,t.code,"utf-8"),await import(`${ot(o).href}?t=${Date.now()}`)}async function Ae(n,e){let t=await v.readFile(n,"utf-8"),r=H(t);if(!r)throw new Error("Invalid .bulb.md file format");let s=W(r),o=G(s.config),i=ae(s.data),l=le(s.code,{jsxImportSource:o.jsxImportSource});l.error&&console.error("Compilation error:",l.error);let{importMap:d}=await ge.buildImportMap(l.code,o.dependencies??{}),u=ve({name:s.name,code:l.code,css:s.css,html:s.html,data:i,insight:s.insight,importMap:d,watch:e}),a=y.dirname(n);o.env?.length&&ie(o.env,a);let p=null;return s.server&&(p=await ke(s.server,a)),{html:u,bulb:s,serverExports:p}}async function ht(n,e){Ie();let t=async()=>{let r=await v.readFile(n,"utf-8"),s=H(r);if(!s)throw new Error("Invalid .bulb.md file format");let o=W(s),i=G(o.config),l=y.dirname(n);i.env?.length&&ie(i.env,l),await ke(o.server,l)};if(console.log(`Running ${y.basename(n)}...`),await t(),e){console.log(`Watching for changes...
248
+ `);let r=new oe;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(s){console.error("Error:",s)}}),ne({bulbPath:n,emitter:r})}}async function gt(){let n=pt(process.argv.slice(2));n.version&&(console.log(`typebulb ${lt}`),process.exit(0)),n.help&&(dt(),process.exit(0));let e;if(!n.file||n.file==="."){let h=await ut(process.cwd());h||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=h}else e=y.resolve(n.file);try{await v.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=await v.readFile(e,"utf-8"),r=H(t);if(r){let h=W(r);if(h.server&&(!h.code||n.server)){await ht(e,n.watch);return}}let s=process.cwd(),o=n.watch?new oe:void 0;Ie(),console.log(`Loading ${y.basename(e)}...`);let{html:i,bulb:l,serverExports:d}=await Ae(e,n.watch),u=await se(n.port),a=await Pe({getHtml:()=>i,basePath:s,port:u,reloadEmitter:o,getServerExports:()=>d}),p=`http://localhost:${u}`;console.log(`
244
249
  ${l.name}`),console.log(` ${p}
245
250
  `),n.watch&&console.log(` Watching for changes...
246
- `);let c;if(n.watch&&o){let h=new se;h.on("reload",async()=>{try{console.log("Recompiling...");let m=await Pe(e,!0);i=m.html,d=m.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
247
- `)}catch(m){console.error("Compile error:",m)}}),c=re({bulbPath:e,emitter:h})}n.open&&await xe(p);let f=async()=>{console.log(`
248
- Shutting down...`),a.close(),c?.();let h=y.join(y.dirname(e),".typebulb","server.mjs");await v.rm(h,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",f),process.on("SIGTERM",f)}ut().catch(n=>{console.error("Error:",n.message),process.exit(1)});
251
+ `);let c;if(n.watch&&o){let h=new oe;h.on("reload",async()=>{try{console.log("Recompiling...");let m=await Ae(e,!0);i=m.html,d=m.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
252
+ `)}catch(m){console.error("Compile error:",m)}}),c=ne({bulbPath:e,emitter:h})}n.open&&await _e(p);let f=async()=>{console.log(`
253
+ Shutting down...`),a.close(),c?.();let h=y.join(y.dirname(e),".typebulb","server.mjs");await v.rm(h,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",f),process.on("SIGTERM",f)}gt().catch(n=>{console.error("Error:",n.message),process.exit(1)});
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "typebulb",
3
- "version": "0.4.1",
4
- "description": "Local bulb runner CLI for Typebulb",
5
- "license": "MIT",
6
- "engines": { "node": ">=18" },
7
- "type": "module",
8
- "bin": {
9
- "typebulb": "./dist/index.js"
10
- },
11
- "files": [
12
- "dist"
13
- ],
14
- "scripts": {
15
- "typecheck": "tsc --build",
16
- "build": "tsc --build && node esbuild.config.mjs",
17
- "clean": "rimraf dist .tsbuild",
18
- "dev": "tsc --build && node dist/index.js",
19
- "prepublishOnly": "rimraf dist && node esbuild.config.mjs"
20
- },
21
- "dependencies": {
22
- "@typebulb/shared-providers": "workspace:*",
23
- "@typebulb/shared-types": "workspace:*",
24
- "@hono/node-server": "^1.14.1",
25
- "chokidar": "^4.0.3",
26
- "es-module-lexer": "^1.7.0",
27
- "hono": "^4.7.5",
28
- "open": "^10.1.0",
29
- "semver": "^7.7.3",
30
- "sucrase": "^3.35.0"
31
- },
32
- "devDependencies": {
33
- "@types/node": "^22.15.21",
34
- "esbuild": "^0.27.3",
35
- "rimraf": "^6.0.1",
36
- "typebulb-resolver": "workspace:*"
37
- }
38
- }
1
+ {
2
+ "name": "typebulb",
3
+ "version": "0.4.2",
4
+ "description": "Local bulb runner CLI for Typebulb",
5
+ "license": "MIT",
6
+ "engines": { "node": ">=18" },
7
+ "type": "module",
8
+ "bin": {
9
+ "typebulb": "./dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "typecheck": "tsc --build",
16
+ "build": "tsc --build && node esbuild.config.mjs",
17
+ "clean": "rimraf dist .tsbuild",
18
+ "dev": "tsc --build && node dist/index.js",
19
+ "prepublishOnly": "rimraf dist && node esbuild.config.mjs"
20
+ },
21
+ "dependencies": {
22
+ "@typebulb/shared-providers": "workspace:*",
23
+ "@typebulb/shared-types": "workspace:*",
24
+ "@hono/node-server": "^1.14.1",
25
+ "chokidar": "^4.0.3",
26
+ "es-module-lexer": "^1.7.0",
27
+ "hono": "^4.7.5",
28
+ "open": "^10.1.0",
29
+ "semver": "^7.7.3",
30
+ "sucrase": "^3.35.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.15.21",
34
+ "esbuild": "^0.27.3",
35
+ "rimraf": "^6.0.1",
36
+ "typebulb-resolver": "workspace:*"
37
+ }
38
+ }