import esbuildWasm from"https://cdn.jsdelivr.net/npm/esbuild-wasm@0.24.2/+esm";import pako from"https://cdn.jsdelivr.net/npm/pako@2.1.0/+esm";export default class npmBundler{constructor(e={}){this.esbuild=null,this.processedFiles=new Set,this.outputFiles=[],this.dependencyGraph=new Map,this.options={rewriteBareImports:!1,minify:!0,...e}}async initEsbuild(){this.esbuild=window.TvrMT?.mod?.MThtml?.esbuild,this.esbuild||(this.esbuild=esbuildWasm,window.TvrMT.mod.MThtml.esbuild=this.esbuild,await this.esbuild.initialize({wasmURL:"https://cdn.jsdelivr.net/npm/esbuild-wasm@0.24.2/esbuild.wasm"}))}async minifyContent(e){if(!this.options.minify)return e;return(await this.esbuild.transform(e,{minify:!0,format:"esm",loader:"js"})).code}escapeRegex(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async processFile(e,t,s,i,a,n=null){if(this.processedFiles.has(e))return;this.processedFiles.add(e),n&&(this.dependencyGraph.has(n)||this.dependencyGraph.set(n,new Set),this.dependencyGraph.get(n).add(e));const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch ${e}`);const o=await r.text();let l,p;if(e.match(/\+esm$/)){let s=this.extractPackageName(e);a=t,t=s.packageName,i=s.packageName,l=t+".js",p=t}else l=this.createLocalPath(e,t),p=s?l.split(".")[0]:t;this.calculatePathDepth(l);const c=this.findRelativeImports(o);let h,d={},m=!1;for(const e of c)if(e.startsWith("/")){let t="./"+this.extractPackageName(e).packageName+".js";d[this.escapeRegex(e)]=t,m=!0}if(m){const e=new RegExp(Object.keys(d).join("|"),"g");h=o.replace(e,(e=>d[this.escapeRegex(e)]))}else h=o;const u=await this.minifyContent(h);let f=parseFloat(this.getSizeInKB(u));this.totalSize+=f,this.outputFiles.push({isAddon:s,rootName:a,addonName:i,install:1,local:l,content:u,cdn:e.split("/npm/").reverse()[0],size:f,package:p});for(const s of c){let n;if(s.startsWith("/")){n=`${new URL(e).origin}${s}`}else n=new URL(s,e).href;await this.processFile(n,t,1,i,a,e)}}getSizeInKB(e){return`${(new Blob([e],{type:"text/javascript"}).size/1024).toFixed(2)}`}findRelativeImports(e){const t=[],s=/from\s*["']((\.\.?\/)?[^"']+\.(js|mjs)|\/npm\/[^"']+\+esm|https?:\/\/[^"']+\.(js|mjs)(\?[^"']*)?)["']/g;let i;for(;null!==(i=s.exec(e));)t.push(i[1]);return t}extractPackageName(e){const t=e.match(/npm\/(@?[^@]+)@/),s=t?t[1]:"unknown-package";return{packageName:s,addonName:e.split("/").pop().replace(".js",""),rootName:this.createLocalPath(e,s)}}createLocalPath(e,t){return`${t}/${e.replace(/^https:\/\/cdn\.jsdelivr\.net\/npm\/[^/]+@[^/]+\//,"")}`}calculatePathDepth(e){return(e.match(/\//g)||[]).length-1}rewriteImports(e,t,s){return e.replace(/from\s+["']([^"']+)["']/g,((e,i)=>{if(i.startsWith("."))return e;if(i===s){return`from "${"../".repeat(t)+`${s}.js`}"`}return e}))}printDependencyTree(e,t=""){const s=this.dependencyGraph.get(e)||new Set;for(const e of s)this.printDependencyTree(e,t+"  ")}async bundle(e,t={}){this.options={...this.options,...t},this.totalSize=0,await this.initEsbuild();const{packageName:s,addonName:i,rootName:a}=this.extractPackageName(e);return await this.processFile(e,s,this.options.isAddon,i,a),this.printDependencyTree(e),{outputFiles:this.outputFiles,totalSize:this.totalSize}}}