UNPKG

@stacksjs/dtsx

Version:

A modern, fast .d.ts generation tool, powered by Bun.

5 lines (4 loc) 4.69 kB
// @bun import{xf as D}from"./chunk-pwwfmfhh.js";import{createHash as T}from"crypto";import{mkdir as b,readFile as w,stat as Z,writeFile as x}from"fs/promises";import{dirname as M,join as W}from"path";var X="1.0.0",V=".dtsx-cache",U="manifest.json";class j{config;manifest=null;dirty=!1;stats={totalEntries:0,hits:0,misses:0,hitRatio:0,sizeBytes:0,timeSavedMs:0};constructor(q={}){this.config={enabled:q.enabled??!0,cacheDir:q.cacheDir??V,format:q.format??"json",maxAge:q.maxAge??86400000,force:q.force??!1,validateCache:q.validateCache??!0}}async init(){if(!this.config.enabled)return;try{await b(this.config.cacheDir,{recursive:!0}),await this.loadManifest()}catch{this.manifest={version:X,entries:{},createdAt:Date.now(),updatedAt:Date.now()}}}async loadManifest(){let q=W(this.config.cacheDir,U);try{let z=await w(q,"utf-8");if(this.manifest=JSON.parse(z),this.manifest.version!==X){await this.clear();return}this.stats.totalEntries=Object.keys(this.manifest.entries).length}catch{this.manifest={version:X,entries:{},createdAt:Date.now(),updatedAt:Date.now()}}}async save(){if(!this.config.enabled||!this.manifest||!this.dirty)return;let q=W(this.config.cacheDir,U);this.manifest.updatedAt=Date.now(),await x(q,JSON.stringify(this.manifest,null,2)),this.dirty=!1}async get(q,z){if(!this.config.enabled||!this.manifest||this.config.force)return this.stats.misses++,null;let B=this.manifest.entries[q];if(!B)return this.stats.misses++,null;if(B.configHash!==z)return this.stats.misses++,null;if(Date.now()-B.cachedAt>this.config.maxAge)return this.stats.misses++,delete this.manifest.entries[q],this.dirty=!0,null;if(this.config.validateCache)try{let K=(await Z(q)).mtimeMs;if(K!==B.mtime){let G=await w(q,"utf-8");if(this.hashContent(G)!==B.hash)return this.stats.misses++,null;B.mtime=K,this.dirty=!0}}catch{return this.stats.misses++,delete this.manifest.entries[q],this.dirty=!0,null}if(B.dependencies.length>0){if((await Promise.all(B.dependencies.map(async(K)=>{let G=this.manifest.entries[K];if(!G)return!0;try{return(await Z(K)).mtimeMs===G.mtime}catch{return!1}}))).some((K)=>!K))return this.stats.misses++,null}return this.stats.hits++,this.stats.timeSavedMs+=50,this.updateHitRatio(),B}async set(q,z,B,Q,K,G){if(!this.config.enabled||!this.manifest)return;let J=Date.now();try{J=(await Z(q)).mtimeMs}catch{}let Y={filePath:q,hash:this.hashContent(z),mtime:J,declarations:B,dtsContent:Q,dependencies:K,cachedAt:Date.now(),configHash:G};if(!(q in this.manifest.entries))this.stats.totalEntries++;this.manifest.entries[q]=Y,this.dirty=!0}invalidate(q){if(!this.manifest)return;delete this.manifest.entries[q],this.dirty=!0;for(let[z,B]of Object.entries(this.manifest.entries))if(B.dependencies.includes(q))delete this.manifest.entries[z]}async clear(){this.manifest={version:X,entries:{},createdAt:Date.now(),updatedAt:Date.now()},this.stats={totalEntries:0,hits:0,misses:0,hitRatio:0,sizeBytes:0,timeSavedMs:0},this.dirty=!0,await this.save()}getStats(){return{...this.stats}}hashContent(q){return String(D(q))}updateHitRatio(){let q=this.stats.hits+this.stats.misses;this.stats.hitRatio=q>0?this.stats.hits/q:0}static hashConfig(q){let z={outdir:q.outdir,clean:q.clean,tsconfigPath:q.tsconfigPath};return T("sha256").update(JSON.stringify(z)).digest("hex").slice(0,16)}}function S(q,z){let B=[],Q=[],K=[];return{async needsRebuild(G){return await q.get(G,z)===null},async getCachedDeclarations(G){let J=await q.get(G,z);if(J)return Q.push(G),J.declarations;return null},async getCachedDts(G){let J=await q.get(G,z);if(J)return J.dtsContent;return null},async cacheResult(G,J,Y,$,L=[]){await q.set(G,J,Y,$,L,z),B.push(G)},skip(G){K.push(G)},getResult(){return{rebuilt:B,cached:Q,skipped:K,stats:q.getStats()}},async save(){await q.save()}}}async function v(q,z=604800000){let B=q.getStats();if(B.totalEntries>1000)return await q.clear(),B.totalEntries;return 0}function F(q){let z=[];return z.push("Incremental Build Results:"),z.push(` Rebuilt: ${q.rebuilt.length} files`),z.push(` From cache: ${q.cached.length} files`),z.push(` Skipped: ${q.skipped.length} files`),z.push(""),z.push("Cache Statistics:"),z.push(` Total entries: ${q.stats.totalEntries}`),z.push(` Hit ratio: ${(q.stats.hitRatio*100).toFixed(1)}%`),z.push(` Time saved: ~${q.stats.timeSavedMs}ms`),z.join(` `)}function _(q,z){let B=[],Q=/import\s+(?:type\s+)?(?:.+(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])from\s+)?['"]([^'"]+)['"]/g,K;while((K=Q.exec(q))!==null){let G=K[1];if(G.startsWith(".")){let J=W(M(z),G);B.push(J),B.push(`${J}.ts`),B.push(`${J}.tsx`),B.push(W(J,"index.ts")),B.push(W(J,"index.tsx"))}}return B} export{j as sf,S as tf,v as uf,F as vf,_ as wf};