typebulb 0.2.5 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +7 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import*as v from"fs/promises";import{readFileSync as Fe,existsSync as ce}from"fs";import*as w from"path";import{pathToFileURL as Ae}from"url";import{execFile as Be}from"child_process";import{promisify as Ve}from"util";import{EventEmitter as J}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 k(s){try{let e=s.split(`
3
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=ge(r);if(!n)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:n,files:o}}catch{return null}}function ge(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(n){case"format":e.format=o;break;case"name":e.name=we(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function we(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function D(s){let e=t=>s.files.get(me[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 ve(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 z(s){let e=s.trim();return e?ve(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function A(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as G}from"sucrase";function be(s,e){try{let{code:t}=G(s,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function K(s,e={}){return be(s,e)}function Y(s){try{let{code:e}=G(s,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var R="https://esm.sh",I="https://cdn.jsdelivr.net/npm/",B="https://data.jsdelivr.com/v1/package/npm/";function Z(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var m=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=S(t??n.version),this.subpath=S(r??n.subpath)}static parse(e){let t=Z(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[o,i]=X(t[1]??""),l=S(t.slice(2).join("/"));return new s({name:`${n}/${o}`,version:i,subpath:l})}else{let[n,o]=X(t[0]),i=S(t.slice(1).join("/"));return new s({name:n,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL(R).host,n=new URL(I).host;if(t.host===r){let o=Z(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return s.parse(i)}if(t.host===n){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return s.parse(i)}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:S(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://")}},S=s=>s&&s.length?s:void 0,X=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),S(s.slice(e+1))]};async function b(s){try{return await s()}catch{return}}var $=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=R,this.jsDelivrBase=I,this.jsDelivrMeta=B,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 m(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:o}=t,i=new URLSearchParams({target:r});return n&&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}),n=await b(()=>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 b(()=>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 b(()=>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=m.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 n=this.packageJson(new m(`${e}@${t}`)),o=await b(()=>this.http.getJson(n));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 Q=s=>s.startsWith("@types/"),j=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!Q(e)),V=s=>Object.keys(s?.dependencies||{}).filter(e=>!Q(e)),ye=s=>j(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),C=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(n);return{allRoots:n,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])),n=[];for(let o of e)for(let i of ye(o.meta))!r.has(i)&&!n.some(l=>l.name===i)&&n.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of n)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:n.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>j(o.meta))),r=new Map;for(let o of e)for(let i of V(o.meta))r.set(i,(r.get(i)||0)+1);let n=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:j(o.meta).length>0,isSharedDep:n.has(o.name)}]))}};var M=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 n=await b(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let i=this.selectVersionFromIndex(n.versions,t,n.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 m(e),n=r.root(),o=t[n],i=o?await b(()=>this.cache.getPinnedExact(n,o))??await b(()=>this.resolveExactForRoot(n,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:n,range:o,pinned:i}}};import{init as xe,parse as Se}from"es-module-lexer";var E=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))m.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{m.isBare(n)&&t.add(n)};try{await xe;let[n]=Se(e);n.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),n=[...new Set(r.map(m.rootOf))],o=await Promise.all(n.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],n=await this.version.resolveExactForRoot(e,r);if(!n){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.`);n=m.versionFromUrl(i),n&&r&&await b(()=>this.cache.setPinnedExact(e,r,n))}if(!n)throw new Error(`Cannot resolve version for ${e}`);return n}buildEntries(e,t,r,n){let o=new Map(t.map(c=>[c.name,c])),i=c=>{let f=o.get(m.rootOf(c));return new m(c).withPreferredVersion(f.version,n[f.name]).format()},l=new Set([...r.entries()].filter(([,c])=>c.isPeerRoot||c.isSharedDep).map(([c])=>c)),d=new Set(e.filter(c=>c!==m.rootOf(c)).map(m.rootOf)),u=[],a=new Set,p=new Set(e.filter(c=>c===m.rootOf(c)));for(let c of e){let f=m.rootOf(c),g=o.get(f),{isPeerRoot:h,hasPeers:y,isSharedDep:T}=r.get(f),O=d.has(f),ue=c!==f,fe=!(h||T)&&(O||!y),F=this.singletonDepsOf(g,l),he=ue&&p.has(f)?[...F,f]:F.length?F:void 0;u.push([c,this.cdn.buildEsmUrl(i(c),{bundle:fe,external:he})]),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([...j(e.meta),...V(e.meta)])].filter(r=>t.has(r))}};E.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as ee,satisfies as Ee,maxSatisfying as W,major as Pe,prerelease as Re,rsort as Ie,valid as $e}from"semver";var _=class{cmp(e,t){return e===t?0:ee(e,t)?1:ee(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Ee(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=W(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Ie(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(n){let l=W(e,r,{includePrerelease:!1});if(l)return l}return W(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Pe(e)}isPrerelease(e){return Re(e)!==null}isExactVersion(e){return $e(e)!==null}},U=new _;function te(s,e){let t=new $(s,e),r=new C(t),n=new M(s,t,U);return{packageService:new E(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}var N=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,n,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:n,peerDependenciesMeta:o,updatedAt:Date.now()})}},je={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}}},Ce=new N,{packageService:re,versionResolver:kt,cdnClient:Dt,peerResolver:_t}=te(Ce,je);var se=`
4
+ `))}else t++}return{frontmatter:n,files:o}}catch{return null}}function ge(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(n){case"format":e.format=o;break;case"name":e.name=we(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function we(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function D(s){let e=t=>s.files.get(me[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 ve(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 z(s){let e=s.trim();return e?ve(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function A(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as G}from"sucrase";function be(s,e){try{let{code:t}=G(s,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function K(s,e={}){return be(s,e)}function Y(s){try{let{code:e}=G(s,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var R="https://esm.sh",I="https://cdn.jsdelivr.net/npm/",B="https://data.jsdelivr.com/v1/package/npm/";function Z(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var m=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=S(t??n.version),this.subpath=S(r??n.subpath)}static parse(e){let t=Z(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[o,i]=X(t[1]??""),l=S(t.slice(2).join("/"));return new s({name:`${n}/${o}`,version:i,subpath:l})}else{let[n,o]=X(t[0]),i=S(t.slice(1).join("/"));return new s({name:n,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL(R).host,n=new URL(I).host;if(t.host===r){let o=Z(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return s.parse(i)}if(t.host===n){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return s.parse(i)}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:S(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://")}},S=s=>s&&s.length?s:void 0,X=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),S(s.slice(e+1))]};async function b(s){try{return await s()}catch{return}}var $=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=R,this.jsDelivrBase=I,this.jsDelivrMeta=B,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 m(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:o}=t,i=new URLSearchParams({target:r});return n&&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}),n=await b(()=>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 b(()=>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 b(()=>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=m.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 n=this.packageJson(new m(`${e}@${t}`)),o=await b(()=>this.http.getJson(n));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 Q=s=>s.startsWith("@types/"),j=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!Q(e)),V=s=>Object.keys(s?.dependencies||{}).filter(e=>!Q(e)),ye=s=>j(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),C=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(n);return{allRoots:n,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])),n=[];for(let o of e)for(let i of ye(o.meta))!r.has(i)&&!n.some(l=>l.name===i)&&n.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of n)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:n.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>j(o.meta))),r=new Map;for(let o of e)for(let i of V(o.meta))r.set(i,(r.get(i)||0)+1);let n=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:j(o.meta).length>0,isSharedDep:n.has(o.name)}]))}};var M=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 n=await b(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let i=this.selectVersionFromIndex(n.versions,t,n.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 m(e),n=r.root(),o=t[n],i=o?await b(()=>this.cache.getPinnedExact(n,o))??await b(()=>this.resolveExactForRoot(n,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:n,range:o,pinned:i}}};import{init as xe,parse as Se}from"es-module-lexer";var E=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))m.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{m.isBare(n)&&t.add(n)};try{await xe;let[n]=Se(e);n.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),n=[...new Set(r.map(m.rootOf))],o=await Promise.all(n.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],n=await this.version.resolveExactForRoot(e,r);if(!n){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.`);n=m.versionFromUrl(i),n&&r&&await b(()=>this.cache.setPinnedExact(e,r,n))}if(!n)throw new Error(`Cannot resolve version for ${e}`);return n}buildEntries(e,t,r,n){let o=new Map(t.map(c=>[c.name,c])),i=c=>{let f=o.get(m.rootOf(c));return new m(c).withPreferredVersion(f.version,n[f.name]).format()},l=new Set([...r.entries()].filter(([,c])=>c.isPeerRoot||c.isSharedDep).map(([c])=>c)),d=new Set(e.filter(c=>c!==m.rootOf(c)).map(m.rootOf)),u=[],a=new Set,p=new Set(e.filter(c=>c===m.rootOf(c)));for(let c of e){let f=m.rootOf(c),g=o.get(f),{isPeerRoot:h,hasPeers:y,isSharedDep:T}=r.get(f),O=d.has(f),ue=c!==f,fe=!(h||T)&&(O||!y),F=this.singletonDepsOf(g,l),he=ue&&p.has(f)?[...F,f]:F.length?F:void 0;u.push([c,this.cdn.buildEsmUrl(i(c),{bundle:fe,external:he})]),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([...j(e.meta),...V(e.meta)])].filter(r=>t.has(r))}};E.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as ee,satisfies as Ee,maxSatisfying as U,major as Pe,prerelease as Re,rsort as Ie,valid as $e}from"semver";var _=class{cmp(e,t){return e===t?0:ee(e,t)?1:ee(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Ee(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=U(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Ie(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(n){let l=U(e,r,{includePrerelease:!1});if(l)return l}return U(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Pe(e)}isPrerelease(e){return Re(e)!==null}isExactVersion(e){return $e(e)!==null}},W=new _;function te(s,e){let t=new $(s,e),r=new C(t),n=new M(s,t,W);return{packageService:new E(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}var N=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,n,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:n,peerDependenciesMeta:o,updatedAt:Date.now()})}},je={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}}},Ce=new N,{packageService:re,versionResolver:kt,cdnClient:Dt,peerResolver:_t}=te(Ce,je);var se=`
5
5
  (() => {
6
6
  // JSON parser (handles jsonish - unquoted keys)
7
7
  const parseJson = (str) => {
@@ -76,6 +76,9 @@ import*as v from"fs/promises";import{readFileSync as Fe,existsSync as ce}from"fs
76
76
  // Clipboard
77
77
  copy,
78
78
 
79
+ // URL
80
+ url: () => Promise.resolve(location.href),
81
+
79
82
  // Proxy: rewrite CDN URLs to local server for same-origin Worker/WASM loading
80
83
  proxy: (url) => {
81
84
  if (!url) return url;
@@ -152,7 +155,7 @@ ${se}
152
155
  ${a(t)}
153
156
  </script>
154
157
  </body>
155
- </html>`}function Me(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}import{Hono as Te}from"hono";import{serve as Oe}from"@hono/node-server";import{streamSSE as ke}from"hono/streaming";import*as P from"fs/promises";import*as x from"path";async function ie(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:o}=s,i=new Te;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=oe(p,t),f=await P.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=oe(p,t);return await P.mkdir(x.dirname(f),{recursive:!0}),await P.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:g}=await a.req.json(),h=await f(...g||[]);return a.json({result:h})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},500)}});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),g;try{g=new URL(f)}catch{return a.text("Invalid URL",400)}if(g.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(g.hostname))return a.text("Host not allowed",403);try{let h=await fetch(f,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!h.ok)return a.text(`Upstream ${h.status}`,h.status);let y=new Headers,T=h.headers.get("Content-Type");T&&y.set("Content-Type",T);let O=h.headers.get("Cache-Control");return O&&y.set("Cache-Control",O),y.set("Access-Control-Allow-Origin","*"),y.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(h.body,{status:h.status,headers:y})}catch(h){return a.text(`Proxy fetch failed: ${h instanceof Error?h.message:h}`,502)}}),n&&i.get("/__reload",a=>ke(a,async p=>{let c=()=>{p.writeSSE({event:"reload",data:""})};for(n.on("reload",c),p.onAbort(()=>{n.removeListener("reload",c)});;)await p.sleep(3e4)}));let u=Oe({fetch:i.fetch,port:r});return{port:r,close:()=>u.close()}}function oe(s,e){let t=x.resolve(e,s),r=x.normalize(e);if(!x.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function L(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,()=>{let n=r.address(),o=typeof n=="object"&&n?n.port:s;r.close(()=>t(o))}),r.on("error",()=>{t(L(s+1))})})}import De from"open";async function ae(s){await De(s)}import _e from"chokidar";function H(s){let{bulbPath:e,emitter:t}=s,r=_e.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var We=Ve(Be),Ue="0.1.3";function Ne(s){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!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==="--port"||r==="-p"){let n=s[++t],o=parseInt(n,10);isNaN(o)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function Le(){console.log(`
158
+ </html>`}function Me(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}import{Hono as Te}from"hono";import{serve as Oe}from"@hono/node-server";import{streamSSE as ke}from"hono/streaming";import*as P from"fs/promises";import*as x from"path";async function ie(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:o}=s,i=new Te;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=oe(p,t),f=await P.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=oe(p,t);return await P.mkdir(x.dirname(f),{recursive:!0}),await P.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:g}=await a.req.json(),h=await f(...g||[]);return a.json({result:h})}catch(p){let c=p instanceof Error?p.message:"Unknown error";return a.json({error:c},500)}});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),g;try{g=new URL(f)}catch{return a.text("Invalid URL",400)}if(g.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(g.hostname))return a.text("Host not allowed",403);try{let h=await fetch(f,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!h.ok)return a.text(`Upstream ${h.status}`,h.status);let y=new Headers,T=h.headers.get("Content-Type");T&&y.set("Content-Type",T);let O=h.headers.get("Cache-Control");return O&&y.set("Cache-Control",O),y.set("Access-Control-Allow-Origin","*"),y.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(h.body,{status:h.status,headers:y})}catch(h){return a.text(`Proxy fetch failed: ${h instanceof Error?h.message:h}`,502)}}),n&&i.get("/__reload",a=>ke(a,async p=>{let c=()=>{p.writeSSE({event:"reload",data:""})};for(n.on("reload",c),p.onAbort(()=>{n.removeListener("reload",c)});;)await p.sleep(3e4)}));let u=Oe({fetch:i.fetch,port:r});return{port:r,close:()=>u.close()}}function oe(s,e){let t=x.resolve(e,s),r=x.normalize(e);if(!x.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function L(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,()=>{let n=r.address(),o=typeof n=="object"&&n?n.port:s;r.close(()=>t(o))}),r.on("error",()=>{t(L(s+1))})})}import De from"open";async function ae(s){await De(s)}import _e from"chokidar";function H(s){let{bulbPath:e,emitter:t}=s,r=_e.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var Ue=Ve(Be),We="0.1.3";function Ne(s){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!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==="--port"||r==="-p"){let n=s[++t],o=parseInt(n,10);isNaN(o)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function Le(){console.log(`
156
159
  typebulb - Local bulb runner for Typebulb
157
160
 
158
161
  Usage:
@@ -184,8 +187,8 @@ Examples:
184
187
  typebulb --no-watch --port 8080 my-editor.bulb.md
185
188
  typebulb .
186
189
  `)}async function He(s){let t=(await v.readdir(s)).find(r=>r.endsWith(".bulb.md"));return t?w.join(s,t):null}function pe(){q([".env",".env.local"],process.cwd(),!0)}function q(s,e,t=!1){for(let r of s){let n=w.resolve(e,r);try{let o=Fe(n,"utf-8");for(let i of o.split(`
187
- `)){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 Je(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 o=n.startsWith("@")?n.split("/").slice(0,2).join("/"):n.split("/")[0];e.add(o)}return[...e]}async function qe(s,e){let t=s.filter(n=>!ce(w.join(e,"node_modules",n)));if(t.length===0)return;let r=w.join(e,"package.json");ce(r)||await v.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await We("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function de(s,e){let t=Y(s);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=w.join(e,".typebulb");await v.mkdir(r,{recursive:!0});let n=Je(t.code);n.length>0&&await qe(n,r);let o=w.join(r,"server.mjs");return await v.writeFile(o,t.code,"utf-8"),await import(`${Ae(o).href}?t=${Date.now()}`)}async function le(s,e){let t=await v.readFile(s,"utf-8"),r=k(t);if(!r)throw new Error("Invalid .bulb.md file format");let n=D(r),o=A(n.config),i=z(n.data),l=K(n.code,{jsxImportSource:o.jsxImportSource});l.error&&console.error("Compilation error:",l.error);let{importMap:d}=await re.buildImportMap(l.code,o.dependencies??{}),u=ne({name:n.name,code:l.code,css:n.css,html:n.html,data:i,insight:n.insight,importMap:d,watch:e}),a=w.dirname(s);o.env?.length&&q(o.env,a);let p=null;return n.server&&(p=await de(n.server,a)),{html:u,bulb:n,serverExports:p}}async function ze(s,e){pe();let t=async()=>{let r=await v.readFile(s,"utf-8"),n=k(r);if(!n)throw new Error("Invalid .bulb.md file format");let o=D(n),i=A(o.config),l=w.dirname(s);i.env?.length&&q(i.env,l),await de(o.server,l)};if(console.log(`Running ${w.basename(s)}...`),await t(),e){console.log(`Watching for changes...
188
- `);let r=new J;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),H({bulbPath:s,emitter:r})}}async function Ge(){let s=Ne(process.argv.slice(2));s.version&&(console.log(`typebulb ${Ue}`),process.exit(0)),s.help&&(Le(),process.exit(0));let e;if(!s.file||s.file==="."){let g=await He(process.cwd());g||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=g}else e=w.resolve(s.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=k(t);if(r){let g=D(r);if(g.server&&(!g.code||s.server)){await ze(e,s.watch);return}}let n=process.cwd(),o=s.watch?new J:void 0;pe(),console.log(`Loading ${w.basename(e)}...`);let{html:i,bulb:l,serverExports:d}=await le(e,s.watch),u=await L(s.port),a=await ie({getHtml:()=>i,basePath:n,port:u,reloadEmitter:o,getServerExports:()=>d}),p=`http://localhost:${u}`;console.log(`
190
+ `)){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 Je(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 o=n.startsWith("@")?n.split("/").slice(0,2).join("/"):n.split("/")[0];e.add(o)}return[...e]}async function qe(s,e){let t=s.filter(n=>!ce(w.join(e,"node_modules",n)));if(t.length===0)return;let r=w.join(e,"package.json");ce(r)||await v.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await Ue("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function de(s,e){let t=Y(s);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=w.join(e,".typebulb");await v.mkdir(r,{recursive:!0});let n=Je(t.code);n.length>0&&await qe(n,r);let o=w.join(r,"server.mjs");return await v.writeFile(o,t.code,"utf-8"),await import(`${Ae(o).href}?t=${Date.now()}`)}async function le(s,e){let t=await v.readFile(s,"utf-8"),r=k(t);if(!r)throw new Error("Invalid .bulb.md file format");let n=D(r),o=A(n.config),i=z(n.data),l=K(n.code,{jsxImportSource:o.jsxImportSource});l.error&&console.error("Compilation error:",l.error);let{importMap:d}=await re.buildImportMap(l.code,o.dependencies??{}),u=ne({name:n.name,code:l.code,css:n.css,html:n.html,data:i,insight:n.insight,importMap:d,watch:e}),a=w.dirname(s);o.env?.length&&q(o.env,a);let p=null;return n.server&&(p=await de(n.server,a)),{html:u,bulb:n,serverExports:p}}async function ze(s,e){pe();let t=async()=>{let r=await v.readFile(s,"utf-8"),n=k(r);if(!n)throw new Error("Invalid .bulb.md file format");let o=D(n),i=A(o.config),l=w.dirname(s);i.env?.length&&q(i.env,l),await de(o.server,l)};if(console.log(`Running ${w.basename(s)}...`),await t(),e){console.log(`Watching for changes...
191
+ `);let r=new J;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),H({bulbPath:s,emitter:r})}}async function Ge(){let s=Ne(process.argv.slice(2));s.version&&(console.log(`typebulb ${We}`),process.exit(0)),s.help&&(Le(),process.exit(0));let e;if(!s.file||s.file==="."){let g=await He(process.cwd());g||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=g}else e=w.resolve(s.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=k(t);if(r){let g=D(r);if(g.server&&(!g.code||s.server)){await ze(e,s.watch);return}}let n=process.cwd(),o=s.watch?new J:void 0;pe(),console.log(`Loading ${w.basename(e)}...`);let{html:i,bulb:l,serverExports:d}=await le(e,s.watch),u=await L(s.port),a=await ie({getHtml:()=>i,basePath:n,port:u,reloadEmitter:o,getServerExports:()=>d}),p=`http://localhost:${u}`;console.log(`
189
192
  ${l.name}`),console.log(` ${p}
190
193
  `),s.watch&&console.log(` Watching for changes...
191
194
  `);let c;if(s.watch&&o){let g=new J;g.on("reload",async()=>{try{console.log("Recompiling...");let h=await le(e,!0);i=h.html,d=h.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "Local bulb runner CLI for Typebulb",
5
5
  "license": "MIT",
6
6
  "engines": { "node": ">=18" },