@ngcompass/planner
Advanced tools
+2
-2
@@ -1,2 +0,2 @@ | ||
| 'use strict';var $=require('fs/promises'),fs$1=require('fs'),k=require('path'),url=require('url'),cache=require('@ngcompass/cache'),common=require('@ngcompass/common'),minimatch=require('minimatch');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var $__namespace=/*#__PURE__*/_interopNamespace($);var k__namespace=/*#__PURE__*/_interopNamespace(k);var Fe=/templateUrl\s*:\s*['"`]([^'"`\n]+)['"`]/,be=/\bstyleUrl(?!s)\s*:\s*['"`]([^'"`\n]+)['"`]/,Se=/\bstyleUrls\s*:\s*\[([^\]]+)\]/,le=/['"`]([^'"`\n]+\.(?:css|scss|sass|less))['"`]/g,I=async(e,t,s)=>{try{let a=await $.readFile(e,"utf-8"),r=Fe.exec(a);if(!r)return;let l=k__namespace.default.resolve(t,r[1]);return s&&!s.has(l)?void 0:l}catch{return}},j=async(e,t,s)=>{try{let a=await $.readFile(e,"utf-8"),r=[],l=be.exec(a);if(l){let i=k__namespace.default.resolve(t,l[1]);(!s||s.has(i))&&r.push(i);}let n=Se.exec(a);if(n){let i;for(le.lastIndex=0;(i=le.exec(n[1]))!==null;){let o=k__namespace.default.resolve(t,i[1]);(!s||s.has(o))&&r.push(o);}}return r}catch{return []}};var N=class{graph=new Map;async build(t){this.graph.clear();let s=new Set(t),a=new Map;for(let r of t){let l=k__namespace.dirname(r),n=a.get(l);n?n.push(r):a.set(l,[r]);}for(let[r,l]of a){let n=new Set(l);for(let i of l.filter(o=>o.endsWith(".component.ts"))){let o=k__namespace.basename(i,".component.ts"),p=k__namespace.join(r,o),u=await Ce(i,r,p,n,s),c=await Ae(i,r,p,l,s),d=(function(m,y){return [`${m}.component.spec.ts`,`${m}.spec.ts`].find(f=>y.has(f))})(p,n);this.graph.set(i,{tsPath:i,templatePath:u,stylePaths:c,specPath:d,type:"component"});}}}getResources(t){return this.graph.get(t)}};async function Ce(e,t,s,a,r){return [`${s}.component.html`,`${s}.html`].find(n=>a.has(n))||I(e,t,r)}async function Ae(e,t,s,a,r){let l=a.filter(n=>{if(!n.startsWith(s))return false;let i=k__namespace.extname(n);return (n===`${s}.component${i}`||n===`${s}${i}`)&&/\.(css|scss|sass|less)$/.test(i)});return l.length>0?l:j(e,t,r)}var ie=/\@(Component|Directive|Pipe|Injectable|NgModule)\s*[\(\{]/,P=e=>{let t=k__namespace.default.basename(e),s=k__namespace.default.extname(e);return t.endsWith(".component.ts")?"component":t.endsWith(".directive.ts")?"directive":t.endsWith(".pipe.ts")?"pipe":t.endsWith(".service.ts")?"service":t.endsWith(".module.ts")?"module":t.endsWith(".guard.ts")?"guard":s===".html"?"template":s===".css"||s===".scss"||s===".sass"||s===".less"?"style":t.endsWith(".config.ts")||s===".json"?"config":t.endsWith(".spec.ts")||t.endsWith(".test.ts")?"spec":s===".ts"?"logic":"unknown"},Pe=e=>k__namespace.default.extname(e)===".ts",$e=e=>k__namespace.default.extname(e)===".html",Re=e=>{let t=k__namespace.default.extname(e);return t===".css"||t===".scss"||t===".sass"||t===".less"},Ee=e=>k__namespace.default.basename(e).endsWith(".spec.ts"),w=e=>k__namespace.default.basename(e).endsWith(".component.ts"),v=e=>{let t=k__namespace.default.basename(e);for(let s of [".component.ts",".directive.ts",".pipe.ts",".service.ts",".module.ts",".guard.ts",".spec.ts"])if(t.endsWith(s))return t.slice(0,-s.length);return k__namespace.default.basename(e,k__namespace.default.extname(e))};var pe=async(e,t,s)=>{for(let a=0;a<e.length;a+=500){let r=e.slice(a,a+500);await Promise.all(r.map(async l=>{if(!s.has(l))try{let n=await $__namespace.stat(l),i=await t.get(l);if(i&&i.mtime===n.mtimeMs&&i.size===n.size)return void s.set(l,i.hash);let o=await S(l);s.set(l,o),await t.set(l,{mtime:n.mtimeMs,size:n.size,hash:o});}catch{}}));}t.flush&&await t.flush();},S=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await $__namespace.readFile(e,"utf-8"),r=cache.computeHash(a);return t?.set(e,r),r}catch(a){let r=a instanceof Error?a.message:String(a);return common.debug("planner",`Failed to hash file: ${e}. Error: ${r}`),""}},ce=async(e,t)=>{if(e.length===0)return "";let s=await Promise.all(e.map(async a=>`${a}:${await S(a,t)}`));return s.sort(),cache.computeHash(s.join("|"))},Ie=async e=>{try{let t=await $__namespace.stat(e);return cache.computeHash(`${e}::${t.size}::${t.mtimeMs}`)}catch{return ""}},U=e=>cache.computeHash(common.stableSerialize(e.map(t=>({name:t.name,severity:t.severity,options:t.options})).sort((t,s)=>t.name<s.name?-1:+(t.name>s.name)))),D=(e,t)=>{let s=[];if(s.push(e.typescript.hash),e.template&&s.push(e.template.hash),e.styles){let a=e.styles.map(r=>r.hash).sort();s.push(...a);}return e.spec&&s.push(e.spec.hash),s.push(U(t)),cache.computeHash(s.join("::"))},je=async e=>{let t=[e.typescript.path];return e.template&&t.push(e.template.path),e.styles&&t.push(...e.styles.map(s=>s.path)),e.spec&&t.push(e.spec.path),ce(t)},ue=(e,t,s,a)=>{let r=[];return a&&(r.push(a.toolVersion),r.push(a.ruleRegistryHash)),r.push(e),r.push(t.typescript.path),r.push(t.typescript.hash),t.template&&r.push(t.template.hash),t.styles?.length&&r.push(t.styles.map(l=>l.hash).sort().join("::")),t.spec&&r.push(t.spec.hash),r.push(common.stableSerialize(s)),cache.computeHash(r.join("::"))},he=async(e,t,s,a)=>{let r=[];for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500),o=await Promise.all(i.map(async p=>`${p}:${s.get(p)??await S(p,s)}`));r.push(...o);}r.sort();let l=[];return l.push(...r),l.push(U(Array.from(t.values()))),a&&(l.push(`tool:${a.toolVersion}`),l.push(`parser:${a.parserVersion}`),l.push(`registry:${a.ruleRegistryHash}`),l.push(`platform:${a.platform}`)),cache.computeHash(l.join("||"))};var G=async(e,t,s={})=>{let a=performance.now();if(common.debug("incremental",`Filtering ${e.length} tasks by cache...`),s.forceRerun)return Me(e);if(e.length===0)return We();let r=await t.hasMany(e.map(p=>p.taskId));common.debug("incremental",`Found ${r.size}/${e.length} tasks in cache`);let{skippedTasks:l,tasks:n}=Le(e,r),i=await ze(t,l,s),o=_e(e.length,l.length,n.length);return Ue(a,o),{skippedTasks:l,tasks:n,cachedResults:i,stats:o}},Ne=async(e,t)=>e.length===0||(await t.hasMany(e.map(s=>s.taskId))).size===e.length,Oe=async(e,t)=>e.length===0?0:(await t.hasMany(e.map(s=>s.taskId))).size/e.length,Be=async(e,t,s={})=>{if(common.debug("incremental","Pruning stale cache entries..."),e.length===0)return common.debug("incremental","No tasks to prune"),0;let a=await t.getManyWithMetadata(e);if(a.size===0)return common.debug("incremental","Cache is empty, nothing to prune"),0;let{now:r,maxAgeMs:l,minHits:n}=De(s),i=Ge(a,r,l,n),o=await Ke(t,i);return common.debug("incremental",`Pruned ${o} stale entries`),o},Me=e=>(common.debug("incremental","Force rerun enabled - skipping cache check"),{skippedTasks:[],tasks:e,cachedResults:new Map,stats:{totalTasks:e.length,cachedTasks:0,pendingTasks:e.length,cacheHitRate:0,timeSavedEstimate:0}}),We=()=>({skippedTasks:[],tasks:[],cachedResults:new Map,stats:{totalTasks:0,cachedTasks:0,pendingTasks:0,cacheHitRate:0,timeSavedEstimate:0}}),Le=(e,t)=>{let s=[],a=[];for(let r of e)t.has(r.taskId)?s.push(r):a.push(r);return {skippedTasks:s,tasks:a}},ze=async(e,t,s)=>{if(!s.loadCachedResults||t.length===0)return new Map;common.debug("incremental",`Loading ${t.length} cached results...`);let a=await e.getMany(t.map(r=>r.taskId));return common.debug("incremental",`Loaded ${a.size} cached results`),a},_e=(e,t,s)=>{let a=e>0?t/e:0;return {totalTasks:e,cachedTasks:t,pendingTasks:s,cacheHitRate:a,timeSavedEstimate:100*a}},Ue=(e,t)=>{let s=performance.now()-e;common.debug("incremental",`Cache filtering completed in ${s.toFixed(2)}ms`),common.debug("incremental",`Cache hit rate: ${(100*t.cacheHitRate).toFixed(1)}%`),common.debug("incremental",`Skipping ${t.cachedTasks} tasks, executing ${t.pendingTasks} tasks`);},De=e=>({now:Date.now(),maxAgeMs:e.maxAge??6048e5,minHits:e.minHits??1}),Ge=(e,t,s,a)=>{let r=[];for(let[,l]of e)(t-l.metadata.timestamp>s||l.metadata.hits<a)&&r.push(l.metadata.taskId);return r},Ke=async(e,t)=>{let s=0;for(let a=0;a<t.length;a+=100){let r=t.slice(a,a+100);await Promise.all(r.map(l=>e.delete(l))),s+=r.length;}return s};function C(e,t){common.debug("planner","Generating execution indexes...");let s=K(e,"typescript"),a=K(e,"html"),r=K(e,"css"),l=Ve(e),n=t?tt(t):{},i=t?st(t):at(),o=Ye(e),p=Xe(e),u=Qe(e),c=et(e);return it(t,s,a,r,o),{filesNeedingTsAst:s,filesNeedingHtmlAst:a,filesNeedingCssAst:r,filesNeedingTypeChecker:l,tasksByFile:n,tasksBySeverityLevel:i,tasksByRule:o,filesByType:p,tasksBySeverity:u,stats:c}}var K=(e,t)=>{let s=new Set;for(let[a,r]of Object.entries(e))r.tasks.some(l=>qe(l,t))&&s.add(a);return Array.from(s).sort()},qe=(e,t)=>{switch(t){case "typescript":return !!e.inputs.typescript.needsAst;case "html":return !!e.inputs.template?.needsAst;case "css":return !!e.inputs.styles?.some(s=>s.needsAst)}},Ve=e=>{let t=new Set;for(let[s,a]of Object.entries(e))a.tasks.some(r=>r.needsTypeChecker===true||r.needsProjectContext===true)&&t.add(s);return Array.from(t).sort()},Ye=e=>{let t={};for(let[s,a]of Object.entries(e))for(let r of a.tasks)(t[r.ruleName]??=[]).push(s);for(let s of Object.keys(t))t[s].sort();return t},Xe=e=>{let t=Je();for(let[s,a]of Object.entries(e))t[a.file.type].push(s);for(let s of Object.keys(t))t[s].sort();return t},Je=()=>({component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]}),Qe=e=>{let t=Ze();for(let s of Object.values(e))for(let a of s.tasks)t[a.severity]++;return t},Ze=()=>({off:0,warn:0,error:0}),et=e=>{let t=Object.values(e),s=t.length,a=0,r=0,l=0,n=0;for(let i of t)a+=i.tasks.length,i.tasks.some(o=>!!o.inputs.template)&&r++,i.tasks.some(o=>!!o.inputs.styles?.length)&&l++,i.tasks.some(o=>!!o.inputs.spec)&&n++;return {totalFiles:s,totalTasks:a,avgTasksPerFile:s>0?a/s:0,filesWithTemplates:r,filesWithStyles:l,filesWithSpecs:n}},tt=e=>{let t={};for(let s of e)(t[s.filePath]??=[]).push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>a.ruleName.localeCompare(r.ruleName));return t},st=e=>{let t={off:[],warn:[],error:[]};for(let s of e)t[s.severity].push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>{let l=a.filePath.localeCompare(r.filePath);return l!==0?l:a.ruleName.localeCompare(r.ruleName)});return t},at=()=>({off:[],warn:[],error:[]}),rt=(e,t)=>{let s=new Set;for(let a of t){let r=e[a];if(r)for(let l of r)s.add(l);}return Array.from(s).sort()},lt=e=>e.stats.totalTasks,nt=(e,t)=>e.tasksBySeverity[t],it=(e,t,s,a,r)=>{common.debug("planner","Indexing complete:"),common.debug("planner",` - TypeScript AST needed: ${t.length} files`),common.debug("planner",` - HTML AST needed: ${s.length} files`),common.debug("planner",` - CSS AST needed: ${a.length} files`),common.debug("planner",` - Unique rules to run: ${Object.keys(r).length}`),e&&common.debug("planner",` - Total tasks: ${e.length}`);};var pt=(e,t)=>t.filter(s=>ct(e,Array.isArray(s.files)?s.files:[s.files])),me=(e,t,s)=>{let a=pt(e,s);if(a.length===0)return t;let r=new Map(t);for(let l of a)if(l.rules)for(let[n,i]of Object.entries(l.rules)){let o=r.get(n);if(!o)continue;let p=ut(i);p.severity==="off"?r.delete(n):r.set(n,{...o,severity:p.severity,options:{...o.options,...p.options}});}return r},ct=(e,t)=>t.some(s=>minimatch.minimatch(e.replace(/\\/g,"/"),s,{dot:true})),ut=e=>typeof e=="string"?{severity:e,options:{}}:e&&typeof e=="object"&&"severity"in e?{severity:e.severity,options:e.options??{}}:{severity:"off",options:{}};var V=2,de=e=>{let t=new R,s=new R,a=new R,r=new q,l=Object.values(e.plan).map(n=>ht(n,t,s,a,r));return {v:V,r:t.values(),o:r.values(),f:s.values(),h:a.values(),t:l}},fe=e=>{let{r:t,o:s,f:a,h:r,t:l}=e,n={},i=[];for(let p of l){let{filePath:u,fileType:c,fileHash:d,ruleTasks:m}=dt(p,t,a,r,s);for(let y of(n[u]={file:{path:u,type:c,hash:d},tasks:m},m))i.push(yt(u,y));}let o=C(n,i);return {tasks:i,plan:n,indexes:o,skippedTasks:[]}},ht=(e,t,s,a,r)=>{let l=s.id(e.file.path),n=a.idOrMinusOne(e.file.hash),i=e.tasks.map(o=>mt(o,t,s,a,r));return [l,e.file.type,n,i]},mt=(e,t,s,a,r)=>{let l=t.id(e.ruleName),n=r.id(e.options),i=a.idOrMinusOne(e.cacheKey),o=O(e.inputs.typescript,s,a),p=e.inputs.template?O(e.inputs.template,s,a):void 0,u=e.inputs.styles&&e.inputs.styles.length>0?e.inputs.styles.map(y=>O(y,s,a)):void 0,c=e.inputs.spec?O(e.inputs.spec,s,a):void 0,d=+!!e.needsTypeChecker,m=+!!e.needsProjectContext;return [l,e.severity,n,i,o,p,u,c,d,m]},O=(e,t,s)=>[t.id(e.path),s.idOrMinusOne(e.hash),+!!e.needsAst],dt=(e,t,s,a,r)=>{let[l,n,i,o]=e;return {filePath:s[l],fileType:n,fileHash:Y(i,a),ruleTasks:o.map(u=>ft(u,t,s,a,r))}},ft=(e,t,s,a,r)=>{let[l,n,i,o,p,u,c,d,m,y]=e,f=t[l],z=r[i],we=Y(o,a),H={typescript:B(p,s,a)};return u&&(H.template=B(u,s,a)),c&&(H.styles=c.map(ve=>B(ve,s,a))),d&&(H.spec=B(d,s,a)),{ruleName:f,severity:n,options:z,cacheKey:we,inputs:H,needsTypeChecker:m===1||void 0,needsProjectContext:y===1||void 0}},B=(e,t,s)=>({path:t[e[0]],hash:Y(e[1],s),needsAst:e[2]===1}),Y=(e,t)=>e>=0?t[e]:"",yt=(e,t)=>({taskId:t.cacheKey,filePath:e,ruleName:t.ruleName,severity:t.severity,options:t.options,inputs:t.inputs,needsTypeChecker:t.needsTypeChecker,needsProjectContext:t.needsProjectContext}),R=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}idOrMinusOne(t){return t?this.id(t):-1}values(){return this.list}},q=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}values(){return this.list}};var X=[".css",".scss",".sass",".less"],J=async(e,t,s,a,r,l)=>{let n=k__namespace.default.dirname(e),i=v(e),o=await E(n,l),p=A(e,t),u=Ct(n,i,o,s);if(!u){let m=await I(e,n);m&&(u=A(m,s));}let c=At(e,n,i,o,a);c.length===0&&w(e)&&(c=(await j(e,n)).map(m=>A(m,a)));let d=Pt(n,i,o,r);return {typescript:p,template:u,styles:c.length>0?c:void 0,spec:d}},Tt=async(e,t,s)=>{let a=v(e),r=await E(k__namespace.default.dirname(e),s);return t==="template"?Ft(a,r):t==="style"?!!w(e)&&bt(a,r):St(a,r)},xt=async(e,t)=>{if(!w(e))return [];let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t);return X.flatMap(l=>{let n=Z(a,l);return r.includes(n)?[k__namespace.default.join(s,n)]:[]})},wt=async(e,t)=>{if(!w(e))return null;let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t),l=Q(a);return r.includes(l)?k__namespace.default.join(s,l):null},vt=async(e,t)=>{let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t),l=ee(a);return r.includes(l)?k__namespace.default.join(s,l):null},E=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await $.readdir(e);return t?.set(e,a),a}catch(a){return common.debug("planner",`Failed to read directory: ${e}. Error: ${a instanceof Error?a.message:String(a)}`),[]}},A=(e,t)=>({path:e,needsAst:t,hash:""}),Q=e=>`${e}.component.html`,Z=(e,t)=>`${e}.component${t}`,ee=e=>`${e}.spec.ts`,Ft=(e,t)=>t.includes(Q(e)),bt=(e,t)=>X.some(s=>t.includes(Z(e,s))),St=(e,t)=>t.includes(ee(e)),Ct=(e,t,s,a)=>{let r=Q(t);return s.includes(r)?A(k__namespace.default.join(e,r),a):void 0},At=(e,t,s,a,r)=>{if(!w(e))return [];let l=[];for(let n of X){let i=Z(s,n);a.includes(i)&&l.push(A(k__namespace.default.join(t,i),r));}return l},Pt=(e,t,s,a)=>{let r=ee(t);return s.includes(r)?A(k__namespace.default.join(e,r),a):void 0};var ye=(e,t)=>{let{dependencyType:s}=e.metadata;return s==="standalone"||s==="imports"?Ht(t):s==="component"?t==="component"||t==="directive"||t==="angular-class":s==="styles"?t==="component":s==="spec"&&t==="spec"},Rt=(e,t)=>{let s=[];for(let a of e.values())a.metadata.requires[t]&&s.push(a);return s},Et=e=>{let t={standalone:[],component:[],styles:[],imports:[],spec:[]};for(let s of e.values())t[s.metadata.dependencyType].push(s);return t},ge=async(e,t,s,a)=>{let r=It(s,t);if(!r.apply)return common.debug("planner",` - Rule ${s.name} skipped: ${r.reason}`),null;let l=ke(s),n=await jt(e,s,a);return {taskId:ue(s.name,n,s.options,a?.cacheKeyCtx),ruleName:s.name,filePath:e,severity:s.severity,options:s.options,inputs:n,needsTypeChecker:l.needsTypeChecker,needsProjectContext:l.needsProjectContext||void 0}},te=async(e,t,s,a)=>{let r=[];for(let l of s.values()){let n=await ge(e,t,l,a);n&&r.push(n);}return r},Ht=e=>e!=="template"&&e!=="style"&&e!=="config"&&e!=="unknown",It=(e,t)=>ye(e,t)?e.severity==="off"?{apply:false,reason:"disabled ('off')"}:{apply:true,reason:"applicable"}:{apply:false,reason:`does not apply to ${t}`},ke=e=>{let t=e.metadata.requires;return {needsTsAst:!!t.tsAst,needsHtmlAst:!!t.htmlAst,needsCssAst:!!t.cssAst,needsSpecAst:!!t.specAst,needsTypeChecker:!!t.typeChecker,needsProjectContext:!!t.projectContext}},jt=async(e,t,s)=>{let a=ke(t),r=await Nt(e,s),l={typescript:await se(r.typescript.path,a.needsTsAst,s)},n=Ot(e,r,t,a,l,s);n&&(l.template=n);let i=await Bt(r,t,a,s);i&&(l.styles=i);let o=await Mt(r,a,s);return o&&(l.spec=o),l},Nt=async(e,t)=>{let s=t?.resourceCache?.get(e);if(s)return s;if(t?.componentGraph){let r=t.componentGraph.getResources(e);if(r){t.graphStats&&t.graphStats.hits++;let l={typescript:{path:e,hash:"",needsAst:false},styles:r.stylePaths.map(n=>({path:n,hash:"",needsAst:false}))};return r.templatePath&&(l.template={path:r.templatePath,hash:"",needsAst:false}),r.specPath&&(l.spec={path:r.specPath,hash:"",needsAst:false}),t.resourceCache?.set(e,l),l}t.graphStats&&t.graphStats.misses++;}t?.graphStats&&t.graphStats.fallbacks++;let a=await J(e,true,true,true,true,t?.directoryCache);return t?.resourceCache?.set(e,a),a},se=async(e,t,s)=>({path:e,hash:await S(e,s?.hashCache),needsAst:t}),Ot=(e,t,s,a,r,l)=>{let{dependencyType:n}=s.metadata,i=a.needsHtmlAst&&(n==="component"||n==="styles");return t.template?{path:t.template.path,hash:l?.hashCache?.get(t.template.path)??t.template.hash??"",needsAst:i}:n==="component"&&a.needsHtmlAst?{path:e,hash:r.typescript.hash,needsAst:true}:void 0},Bt=async(e,t,s,a)=>{if(!e.styles||e.styles.length===0)return;let r=s.needsCssAst&&t.metadata.dependencyType==="styles";return Promise.all(e.styles.map(l=>se(l.path,r,a)))},Mt=async(e,t,s)=>{if(e.spec)return se(e.spec.path,t.needsSpecAst,s)};var ae=e=>{let t=new Map;for(let s of e){let a=t.get(s.filePath);a?a.push(s):t.set(s.filePath,[s]);}return t};var qt=1e4,Vt=4,Yt=async e=>{let t="buildExecutionPlan";common.time(t);try{await cache.initHasher();let{files:s,rules:a}=e;common.debug("planner",`Building execution plan for ${s.length} files and ${a.size} rules`);let r=Jt(s,a);if(r)return common.Err(r);let l=Qt(e),n=new Map,i=new common.InfrastructureErrorCollector;await Zt(e,l);let o=await ts(e,l,i);if(o||await es(e,l),o&&o.precomputedAnalysis)return common.timeLog(t,"planner","Full analysis cached \u2014 returning precomputed result"),common.Ok(o);let p=o?(common.timeLog(t,"planner","Execution plan loaded from cache"),o.tasks):await ls(e,l,n),{tasks:u,skippedTasks:c,cachedResults:d,changedFiles:m,cachedFiles:y}=await ns(e,p);common.debug("planner","Converting tasks to file-centric plan...");let f=xe(u,a,n);common.debug("planner",`Building indexes for ${u.length} tasks...`);let z=C(f,u);return common.timeLog(t,"planner","Execution plan built"),common.Ok({tasks:u,plan:f,indexes:z,skippedTasks:c,cachedResults:d,globalHash:l.globalHash,changedFiles:m,cachedFiles:y})}catch(s){let a=s instanceof Error?s:Error(String(s));return common.debug("planner",`Error building plan: ${a.message}`),common.Err(Error(`Failed to build execution plan: ${a.message}`,{cause:a}))}},Xt=e=>{let{stats:t}=e.indexes;return `--- Execution Plan Summary --- | ||
| 'use strict';var R=require('fs/promises'),fs$1=require('fs'),k=require('path'),url=require('url'),cache=require('@ngcompass/cache'),common=require('@ngcompass/common'),minimatch=require('minimatch');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var R__namespace=/*#__PURE__*/_interopNamespace(R);var k__namespace=/*#__PURE__*/_interopNamespace(k);var Fe=/templateUrl\s*:\s*['"`]([^'"`\n]+)['"`]/,Se=/\bstyleUrl(?!s)\s*:\s*['"`]([^'"`\n]+)['"`]/,be=/\bstyleUrls\s*:\s*\[([^\]]+)\]/,le=/['"`]([^'"`\n]+\.(?:css|scss|sass|less))['"`]/g,I=async(e,t,s)=>{try{let a=await R.readFile(e,"utf-8"),r=Fe.exec(a);if(!r)return;let l=k__namespace.default.resolve(t,r[1]);return s&&!s.has(l)?void 0:l}catch{return}},j=async(e,t,s)=>{try{let a=await R.readFile(e,"utf-8"),r=[],l=Se.exec(a);if(l){let i=k__namespace.default.resolve(t,l[1]);(!s||s.has(i))&&r.push(i);}let n=be.exec(a);if(n){let i;for(le.lastIndex=0;(i=le.exec(n[1]))!==null;){let o=k__namespace.default.resolve(t,i[1]);(!s||s.has(o))&&r.push(o);}}return r}catch{return []}};var N=class{graph=new Map;async build(t){this.graph.clear();let s=new Set(t),a=new Map;for(let r of t){let l=k__namespace.dirname(r),n=a.get(l);n?n.push(r):a.set(l,[r]);}for(let[r,l]of a){let n=new Set(l);for(let i of l.filter(o=>o.endsWith(".component.ts"))){let o=k__namespace.basename(i,".component.ts"),p=k__namespace.join(r,o),u=await Ce(i,r,p,n,s),c=await Ae(i,r,p,l,s),d=(function(m,y){return [`${m}.component.spec.ts`,`${m}.spec.ts`].find(f=>y.has(f))})(p,n);this.graph.set(i,{tsPath:i,templatePath:u,stylePaths:c,specPath:d,type:"component"});}}}getResources(t){return this.graph.get(t)}};async function Ce(e,t,s,a,r){return [`${s}.component.html`,`${s}.html`].find(n=>a.has(n))||I(e,t,r)}async function Ae(e,t,s,a,r){let l=a.filter(n=>{if(!n.startsWith(s))return false;let i=k__namespace.extname(n);return (n===`${s}.component${i}`||n===`${s}${i}`)&&/\.(css|scss|sass|less)$/.test(i)});return l.length>0?l:j(e,t,r)}var ie=/\@(Component|Directive|Pipe|Injectable|NgModule)\s*[\(\{]/,P=e=>{let t=k__namespace.default.basename(e),s=k__namespace.default.extname(e);return t.endsWith(".component.ts")?"component":t.endsWith(".directive.ts")?"directive":t.endsWith(".pipe.ts")?"pipe":t.endsWith(".service.ts")?"service":t.endsWith(".module.ts")?"module":t.endsWith(".guard.ts")?"guard":s===".html"?"template":s===".css"||s===".scss"||s===".sass"||s===".less"?"style":t.endsWith(".config.ts")||s===".json"?"config":t.endsWith(".spec.ts")||t.endsWith(".test.ts")?"spec":s===".ts"?"logic":"unknown"},Pe=e=>k__namespace.default.extname(e)===".ts",Re=e=>k__namespace.default.extname(e)===".html",$e=e=>{let t=k__namespace.default.extname(e);return t===".css"||t===".scss"||t===".sass"||t===".less"},Ee=e=>k__namespace.default.basename(e).endsWith(".spec.ts"),w=e=>k__namespace.default.basename(e).endsWith(".component.ts"),v=e=>{let t=k__namespace.default.basename(e);for(let s of [".component.ts",".directive.ts",".pipe.ts",".service.ts",".module.ts",".guard.ts",".spec.ts"])if(t.endsWith(s))return t.slice(0,-s.length);return k__namespace.default.basename(e,k__namespace.default.extname(e))};var pe=async(e,t,s)=>{for(let a=0;a<e.length;a+=500){let r=e.slice(a,a+500);await Promise.all(r.map(async l=>{if(!s.has(l))try{let n=await R__namespace.stat(l),i=await t.get(l);if(i&&i.mtime===n.mtimeMs&&i.size===n.size)return void s.set(l,i.hash);let o=await b(l);s.set(l,o),await t.set(l,{mtime:n.mtimeMs,size:n.size,hash:o});}catch{}}));}t.flush&&await t.flush();},b=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await R__namespace.readFile(e,"utf-8"),r=cache.computeHash(a);return t?.set(e,r),r}catch(a){let r=a instanceof Error?a.message:String(a);return common.debug("planner",`Failed to hash file: ${e}. Error: ${r}`),""}},ce=async(e,t)=>{if(e.length===0)return "";let s=await Promise.all(e.map(async a=>`${a}:${await b(a,t)}`));return s.sort(),cache.computeHash(s.join("|"))},Ie=async e=>{try{let t=await R__namespace.stat(e);return cache.computeHash(`${e}::${t.size}::${t.mtimeMs}`)}catch{return ""}},U=e=>cache.computeHash(common.stableSerialize(e.map(t=>({name:t.name,severity:t.severity,options:t.options})).sort((t,s)=>t.name<s.name?-1:+(t.name>s.name)))),D=(e,t)=>{let s=[];if(s.push(e.typescript.hash),e.template&&s.push(e.template.hash),e.styles){let a=e.styles.map(r=>r.hash).sort();s.push(...a);}return e.spec&&s.push(e.spec.hash),s.push(U(t)),cache.computeHash(s.join("::"))},je=async e=>{let t=[e.typescript.path];return e.template&&t.push(e.template.path),e.styles&&t.push(...e.styles.map(s=>s.path)),e.spec&&t.push(e.spec.path),ce(t)},ue=(e,t,s,a)=>{let r=[];return a&&(r.push(a.toolVersion),r.push(a.ruleRegistryHash)),r.push(e),r.push(t.typescript.path),r.push(t.typescript.hash),t.template&&r.push(t.template.hash),t.styles?.length&&r.push(t.styles.map(l=>l.hash).sort().join("::")),t.spec&&r.push(t.spec.hash),r.push(common.stableSerialize(s)),cache.computeHash(r.join("::"))},he=async(e,t,s,a)=>{let r=[];for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500),o=await Promise.all(i.map(async p=>`${p}:${s.get(p)??await b(p,s)}`));r.push(...o);}r.sort();let l=[];return l.push(...r),l.push(U(Array.from(t.values()))),a&&(l.push(`tool:${a.toolVersion}`),l.push(`parser:${a.parserVersion}`),l.push(`registry:${a.ruleRegistryHash}`),l.push(`platform:${a.platform}`)),cache.computeHash(l.join("||"))};var G=async(e,t,s={})=>{let a=performance.now();if(common.debug("incremental",`Filtering ${e.length} tasks by cache...`),s.forceRerun)return Me(e);if(e.length===0)return We();let r=await t.hasMany(e.map(p=>p.taskId));common.debug("incremental",`Found ${r.size}/${e.length} tasks in cache`);let{skippedTasks:l,tasks:n}=Le(e,r),i=await ze(t,l,s),o=_e(e.length,l.length,n.length);return Ue(a,o),{skippedTasks:l,tasks:n,cachedResults:i,stats:o}},Ne=async(e,t)=>e.length===0||(await t.hasMany(e.map(s=>s.taskId))).size===e.length,Oe=async(e,t)=>e.length===0?0:(await t.hasMany(e.map(s=>s.taskId))).size/e.length,Be=async(e,t,s={})=>{if(common.debug("incremental","Pruning stale cache entries..."),e.length===0)return common.debug("incremental","No tasks to prune"),0;let a=await t.getManyWithMetadata(e);if(a.size===0)return common.debug("incremental","Cache is empty, nothing to prune"),0;let{now:r,maxAgeMs:l,minHits:n}=De(s),i=Ge(a,r,l,n),o=await Ke(t,i);return common.debug("incremental",`Pruned ${o} stale entries`),o},Me=e=>(common.debug("incremental","Force rerun enabled - skipping cache check"),{skippedTasks:[],tasks:e,cachedResults:new Map,stats:{totalTasks:e.length,cachedTasks:0,pendingTasks:e.length,cacheHitRate:0,timeSavedEstimate:0}}),We=()=>({skippedTasks:[],tasks:[],cachedResults:new Map,stats:{totalTasks:0,cachedTasks:0,pendingTasks:0,cacheHitRate:0,timeSavedEstimate:0}}),Le=(e,t)=>{let s=[],a=[];for(let r of e)t.has(r.taskId)?s.push(r):a.push(r);return {skippedTasks:s,tasks:a}},ze=async(e,t,s)=>{if(!s.loadCachedResults||t.length===0)return new Map;common.debug("incremental",`Loading ${t.length} cached results...`);let a=await e.getMany(t.map(r=>r.taskId));return common.debug("incremental",`Loaded ${a.size} cached results`),a},_e=(e,t,s)=>{let a=e>0?t/e:0;return {totalTasks:e,cachedTasks:t,pendingTasks:s,cacheHitRate:a,timeSavedEstimate:100*a}},Ue=(e,t)=>{let s=performance.now()-e;common.debug("incremental",`Cache filtering completed in ${s.toFixed(2)}ms`),common.debug("incremental",`Cache hit rate: ${(100*t.cacheHitRate).toFixed(1)}%`),common.debug("incremental",`Skipping ${t.cachedTasks} tasks, executing ${t.pendingTasks} tasks`);},De=e=>({now:Date.now(),maxAgeMs:e.maxAge??6048e5,minHits:e.minHits??1}),Ge=(e,t,s,a)=>{let r=[];for(let[,l]of e)(t-l.metadata.timestamp>s||l.metadata.hits<a)&&r.push(l.metadata.taskId);return r},Ke=async(e,t)=>{let s=0;for(let a=0;a<t.length;a+=100){let r=t.slice(a,a+100);await Promise.all(r.map(l=>e.delete(l))),s+=r.length;}return s};function C(e,t){common.debug("planner","Generating execution indexes...");let s=K(e,"typescript"),a=K(e,"html"),r=K(e,"css"),l=Ve(e),n=t?tt(t):{},i=t?st(t):at(),o=Ye(e),p=Xe(e),u=Qe(e),c=et(e);return it(t,s,a,r,o),{filesNeedingTsAst:s,filesNeedingHtmlAst:a,filesNeedingCssAst:r,filesNeedingTypeChecker:l,tasksByFile:n,tasksBySeverityLevel:i,tasksByRule:o,filesByType:p,tasksBySeverity:u,stats:c}}var K=(e,t)=>{let s=new Set;for(let[a,r]of Object.entries(e))r.tasks.some(l=>qe(l,t))&&s.add(a);return Array.from(s).sort()},qe=(e,t)=>{switch(t){case "typescript":return !!e.inputs.typescript.needsAst;case "html":return !!e.inputs.template?.needsAst;case "css":return !!e.inputs.styles?.some(s=>s.needsAst)}},Ve=e=>{let t=new Set;for(let[s,a]of Object.entries(e))a.tasks.some(r=>r.needsTypeChecker===true||r.needsProjectContext===true)&&t.add(s);return Array.from(t).sort()},Ye=e=>{let t={};for(let[s,a]of Object.entries(e))for(let r of a.tasks)(t[r.ruleName]??=[]).push(s);for(let s of Object.keys(t))t[s].sort();return t},Xe=e=>{let t=Je();for(let[s,a]of Object.entries(e))t[a.file.type].push(s);for(let s of Object.keys(t))t[s].sort();return t},Je=()=>({component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]}),Qe=e=>{let t=Ze();for(let s of Object.values(e))for(let a of s.tasks)t[a.severity]++;return t},Ze=()=>({off:0,warn:0,error:0}),et=e=>{let t=Object.values(e),s=t.length,a=0,r=0,l=0,n=0;for(let i of t)a+=i.tasks.length,i.tasks.some(o=>!!o.inputs.template)&&r++,i.tasks.some(o=>!!o.inputs.styles?.length)&&l++,i.tasks.some(o=>!!o.inputs.spec)&&n++;return {totalFiles:s,totalTasks:a,avgTasksPerFile:s>0?a/s:0,filesWithTemplates:r,filesWithStyles:l,filesWithSpecs:n}},tt=e=>{let t={};for(let s of e)(t[s.filePath]??=[]).push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>a.ruleName.localeCompare(r.ruleName));return t},st=e=>{let t={off:[],warn:[],error:[]};for(let s of e)t[s.severity].push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>{let l=a.filePath.localeCompare(r.filePath);return l!==0?l:a.ruleName.localeCompare(r.ruleName)});return t},at=()=>({off:[],warn:[],error:[]}),rt=(e,t)=>{let s=new Set;for(let a of t){let r=e[a];if(r)for(let l of r)s.add(l);}return Array.from(s).sort()},lt=e=>e.stats.totalTasks,nt=(e,t)=>e.tasksBySeverity[t],it=(e,t,s,a,r)=>{common.debug("planner","Indexing complete:"),common.debug("planner",` - TypeScript AST needed: ${t.length} files`),common.debug("planner",` - HTML AST needed: ${s.length} files`),common.debug("planner",` - CSS AST needed: ${a.length} files`),common.debug("planner",` - Unique rules to run: ${Object.keys(r).length}`),e&&common.debug("planner",` - Total tasks: ${e.length}`);};var pt=(e,t)=>t.filter(s=>ct(e,Array.isArray(s.files)?s.files:[s.files])),me=(e,t,s)=>{let a=pt(e,s);if(a.length===0)return t;let r=new Map(t);for(let l of a)if(l.rules)for(let[n,i]of Object.entries(l.rules)){let o=r.get(n);if(!o)continue;let p=ut(i);p.severity==="off"?r.delete(n):r.set(n,{...o,severity:p.severity,options:{...o.options,...p.options}});}return r},ct=(e,t)=>t.some(s=>minimatch.minimatch(e.replace(/\\/g,"/"),s,{dot:true})),ut=e=>typeof e=="string"?{severity:e,options:{}}:e&&typeof e=="object"&&"severity"in e?{severity:e.severity,options:e.options??{}}:{severity:"off",options:{}};var V=2,de=e=>{let t=new $,s=new $,a=new $,r=new q,l=Object.values(e.plan).map(n=>ht(n,t,s,a,r));return {v:V,r:t.values(),o:r.values(),f:s.values(),h:a.values(),t:l}},fe=e=>{let{r:t,o:s,f:a,h:r,t:l}=e,n={},i=[];for(let p of l){let{filePath:u,fileType:c,fileHash:d,ruleTasks:m}=dt(p,t,a,r,s);for(let y of(n[u]={file:{path:u,type:c,hash:d},tasks:m},m))i.push(yt(u,y));}let o=C(n,i);return {tasks:i,plan:n,indexes:o,skippedTasks:[]}},ht=(e,t,s,a,r)=>{let l=s.id(e.file.path),n=a.idOrMinusOne(e.file.hash),i=e.tasks.map(o=>mt(o,t,s,a,r));return [l,e.file.type,n,i]},mt=(e,t,s,a,r)=>{let l=t.id(e.ruleName),n=r.id(e.options),i=a.idOrMinusOne(e.cacheKey),o=O(e.inputs.typescript,s,a),p=e.inputs.template?O(e.inputs.template,s,a):void 0,u=e.inputs.styles&&e.inputs.styles.length>0?e.inputs.styles.map(y=>O(y,s,a)):void 0,c=e.inputs.spec?O(e.inputs.spec,s,a):void 0,d=+!!e.needsTypeChecker,m=+!!e.needsProjectContext;return [l,e.severity,n,i,o,p,u,c,d,m]},O=(e,t,s)=>[t.id(e.path),s.idOrMinusOne(e.hash),+!!e.needsAst],dt=(e,t,s,a,r)=>{let[l,n,i,o]=e;return {filePath:s[l],fileType:n,fileHash:Y(i,a),ruleTasks:o.map(u=>ft(u,t,s,a,r))}},ft=(e,t,s,a,r)=>{let[l,n,i,o,p,u,c,d,m,y]=e,f=t[l],z=r[i],we=Y(o,a),H={typescript:B(p,s,a)};return u&&(H.template=B(u,s,a)),c&&(H.styles=c.map(ve=>B(ve,s,a))),d&&(H.spec=B(d,s,a)),{ruleName:f,severity:n,options:z,cacheKey:we,inputs:H,needsTypeChecker:m===1||void 0,needsProjectContext:y===1||void 0}},B=(e,t,s)=>({path:t[e[0]],hash:Y(e[1],s),needsAst:e[2]===1}),Y=(e,t)=>e>=0?t[e]:"",yt=(e,t)=>({taskId:t.cacheKey,filePath:e,ruleName:t.ruleName,severity:t.severity,options:t.options,inputs:t.inputs,needsTypeChecker:t.needsTypeChecker,needsProjectContext:t.needsProjectContext}),$=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}idOrMinusOne(t){return t?this.id(t):-1}values(){return this.list}},q=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}values(){return this.list}};var X=[".css",".scss",".sass",".less"],J=async(e,t,s,a,r,l)=>{let n=k__namespace.default.dirname(e),i=v(e),o=await E(n,l),p=A(e,t),u=Ct(n,i,o,s);if(!u){let m=await I(e,n);m&&(u=A(m,s));}let c=At(e,n,i,o,a);c.length===0&&w(e)&&(c=(await j(e,n)).map(m=>A(m,a)));let d=Pt(n,i,o,r);return {typescript:p,template:u,styles:c.length>0?c:void 0,spec:d}},Tt=async(e,t,s)=>{let a=v(e),r=await E(k__namespace.default.dirname(e),s);return t==="template"?Ft(a,r):t==="style"?!!w(e)&&St(a,r):bt(a,r)},xt=async(e,t)=>{if(!w(e))return [];let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t);return X.flatMap(l=>{let n=Z(a,l);return r.includes(n)?[k__namespace.default.join(s,n)]:[]})},wt=async(e,t)=>{if(!w(e))return null;let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t),l=Q(a);return r.includes(l)?k__namespace.default.join(s,l):null},vt=async(e,t)=>{let s=k__namespace.default.dirname(e),a=v(e),r=await E(s,t),l=ee(a);return r.includes(l)?k__namespace.default.join(s,l):null},E=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await R.readdir(e);return t?.set(e,a),a}catch(a){return common.debug("planner",`Failed to read directory: ${e}. Error: ${a instanceof Error?a.message:String(a)}`),[]}},A=(e,t)=>({path:e,needsAst:t,hash:""}),Q=e=>`${e}.component.html`,Z=(e,t)=>`${e}.component${t}`,ee=e=>`${e}.spec.ts`,Ft=(e,t)=>t.includes(Q(e)),St=(e,t)=>X.some(s=>t.includes(Z(e,s))),bt=(e,t)=>t.includes(ee(e)),Ct=(e,t,s,a)=>{let r=Q(t);return s.includes(r)?A(k__namespace.default.join(e,r),a):void 0},At=(e,t,s,a,r)=>{if(!w(e))return [];let l=[];for(let n of X){let i=Z(s,n);a.includes(i)&&l.push(A(k__namespace.default.join(t,i),r));}return l},Pt=(e,t,s,a)=>{let r=ee(t);return s.includes(r)?A(k__namespace.default.join(e,r),a):void 0};var ye=(e,t)=>{let{dependencyType:s}=e.metadata;return s==="standalone"||s==="imports"?Et(t):s==="component"?t==="component"||t==="directive"||t==="angular-class":s==="styles"?t==="component":s==="spec"&&t==="spec"},Rt=(e,t)=>{let s=[];for(let a of e.values())a.metadata.requires[t]&&s.push(a);return s},$t=e=>{let t={standalone:[],component:[],styles:[],imports:[],spec:[]};for(let s of e.values())t[s.metadata.dependencyType].push(s);return t},ge=async(e,t,s,a)=>{if(!Ht(s,t))return null;let r=ke(s),l=await It(e,s,a);return {taskId:ue(s.name,l,s.options,a?.cacheKeyCtx),ruleName:s.name,filePath:e,severity:s.severity,options:s.options,inputs:l,needsTypeChecker:r.needsTypeChecker,needsProjectContext:r.needsProjectContext||void 0}},te=async(e,t,s,a)=>{let r=[];for(let l of s.values()){let n=await ge(e,t,l,a);n&&r.push(n);}return r},Et=e=>e!=="template"&&e!=="style"&&e!=="config"&&e!=="unknown",Ht=(e,t)=>!!ye(e,t)&&e.severity!=="off",ke=e=>{let t=e.metadata.requires;return {needsTsAst:!!t.tsAst,needsHtmlAst:!!t.htmlAst,needsCssAst:!!t.cssAst,needsSpecAst:!!t.specAst,needsTypeChecker:!!t.typeChecker,needsProjectContext:!!t.projectContext}},It=async(e,t,s)=>{let a=ke(t),r=await jt(e,s),l={typescript:await se(r.typescript.path,a.needsTsAst,s)},n=Nt(e,r,t,a,l,s);n&&(l.template=n);let i=await Ot(r,t,a,s);i&&(l.styles=i);let o=await Bt(r,a,s);return o&&(l.spec=o),l},jt=async(e,t)=>{let s=t?.resourceCache?.get(e);if(s)return s;if(t?.componentGraph){let r=t.componentGraph.getResources(e);if(r){t.graphStats&&t.graphStats.hits++;let l={typescript:{path:e,hash:"",needsAst:false},styles:r.stylePaths.map(n=>({path:n,hash:"",needsAst:false}))};return r.templatePath&&(l.template={path:r.templatePath,hash:"",needsAst:false}),r.specPath&&(l.spec={path:r.specPath,hash:"",needsAst:false}),t.resourceCache?.set(e,l),l}t.graphStats&&t.graphStats.misses++;}t?.graphStats&&t.graphStats.fallbacks++;let a=await J(e,true,true,true,true,t?.directoryCache);return t?.resourceCache?.set(e,a),a},se=async(e,t,s)=>({path:e,hash:await b(e,s?.hashCache),needsAst:t}),Nt=(e,t,s,a,r,l)=>{let{dependencyType:n}=s.metadata,i=a.needsHtmlAst&&(n==="component"||n==="styles");return t.template?{path:t.template.path,hash:l?.hashCache?.get(t.template.path)??t.template.hash??"",needsAst:i}:n==="component"&&a.needsHtmlAst?{path:e,hash:r.typescript.hash,needsAst:true}:void 0},Ot=async(e,t,s,a)=>{if(!e.styles||e.styles.length===0)return;let r=s.needsCssAst&&t.metadata.dependencyType==="styles";return Promise.all(e.styles.map(l=>se(l.path,r,a)))},Bt=async(e,t,s)=>{if(e.spec)return se(e.spec.path,t.needsSpecAst,s)};var ae=e=>{let t=new Map;for(let s of e){let a=t.get(s.filePath);a?a.push(s):t.set(s.filePath,[s]);}return t};var Kt=1e4,qt=4,Vt=async e=>{let t="buildExecutionPlan";common.time(t);try{await cache.initHasher();let{files:s,rules:a}=e;common.debug("planner",`Building execution plan for ${s.length} files and ${a.size} rules`);let r=Xt(s,a);if(r)return common.Err(r);let l=Jt(e),n=new Map,i=new common.InfrastructureErrorCollector;await Qt(e,l);let o=await es(e,l,i);if(o||await Zt(e,l),o&&o.precomputedAnalysis)return common.timeLog(t,"planner","Full analysis cached \u2014 returning precomputed result"),common.Ok(o);let p=o?(common.timeLog(t,"planner","Execution plan loaded from cache"),o.tasks):await rs(e,l,n),{tasks:u,skippedTasks:c,cachedResults:d,changedFiles:m,cachedFiles:y}=await ls(e,p);common.debug("planner","Converting tasks to file-centric plan...");let f=xe(u,a,n);common.debug("planner",`Building indexes for ${u.length} tasks...`);let z=C(f,u);return common.timeLog(t,"planner","Execution plan built"),common.Ok({tasks:u,plan:f,indexes:z,skippedTasks:c,cachedResults:d,globalHash:l.globalHash,changedFiles:m,cachedFiles:y})}catch(s){let a=s instanceof Error?s:Error(String(s));return common.debug("planner",`Error building plan: ${a.message}`),common.Err(Error(`Failed to build execution plan: ${a.message}`,{cause:a}))}},Yt=e=>{let{stats:t}=e.indexes;return `--- Execution Plan Summary --- | ||
| Total files: ${t.totalFiles} | ||
@@ -8,3 +8,3 @@ Total tasks: ${t.totalTasks} | ||
| Files with specs: ${t.filesWithSpecs} | ||
| `},Jt=(e,t)=>e.length===0?Error("No files to analyze"):t.size===0?Error("No rules configured"):null,Qt=e=>({hashCache:new Map,resourceCache:new Map,directoryCache:new Map,cacheKeyCtx:e?.cacheKeyCtx}),Zt=async(e,t)=>{if(!e.cache)return;common.debug("planner","Warming up hash cache from metadata index...");let s=performance.now();await pe(e.files,e.cache.metas,t.hashCache),common.debug("planner",`Metadata warmup took ${(performance.now()-s).toFixed(2)}ms`);},es=async(e,t)=>{let s=new N;await s.build(e.files),t.componentGraph=s,t.graphStats={hits:0,misses:0,fallbacks:0},common.debug("planner","Component dependency graph built");},ts=async(e,t,s)=>{let a;if(!e.cache)return null;let{files:r,rules:l}=e,n=await he(r,l,t.hashCache,e.cacheKeyCtx);if(t.globalHash=n,e.incremental?.forceRerun)return null;let i=await e.cache.analysis.get(n);if(i)return e.debug&&common.debug("planner","Analysis results cached (Short-circuit enabled)"),ss(n,i);let o=performance.now(),p=await e.cache.plans.get(n),u=performance.now();if(!p)return null;let c=performance.now();try{a=p.v===V?fe(p):p;}catch(m){common.debug("planner","Plan cache deserialization failed \u2014 deleting corrupted entry and rebuilding");try{await e.cache.plans.delete?.(n);}catch{}return s&&s.record(common.createInfrastructureError("CacheCorruption",{cause:m instanceof Error?m.message:String(m),phase:"planner",recoverable:true,details:{globalHash:n}})),null}let d=performance.now();return e.debug&&(common.debug("planner","Plan cache HIT"),common.debug("planner",` IO: ${(u-o).toFixed(2)}ms`),common.debug("planner",` Deser: ${(d-c).toFixed(2)}ms`)),{...a,globalHash:n}},ss=(e,t)=>({tasks:[],plan:{},indexes:as(),skippedTasks:[],globalHash:e,precomputedAnalysis:t}),as=()=>({filesNeedingTsAst:[],filesNeedingHtmlAst:[],filesNeedingCssAst:[],filesNeedingTypeChecker:[],tasksByFile:{},tasksByRule:{},tasksBySeverityLevel:{off:[],warn:[],error:[]},filesByType:{component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]},tasksBySeverity:{off:0,warn:0,error:0},stats:{totalFiles:0,totalTasks:0,avgTasksPerFile:0,filesWithTemplates:0,filesWithStyles:0,filesWithSpecs:0}}),rs=async(e,t,s)=>{if(!e.cache||!t.globalHash)return;let a=performance.now();common.debug("planner","Saving execution plan to cache...");let r=de(s);await e.cache.plans.set(t.globalHash,r),common.debug("planner",` Plan cache saved in ${(performance.now()-a).toFixed(2)}ms`);},ls=async(e,t,s)=>{common.debug("planner","Building tasks...");let a=await is(e.files,e.rules,t,s,e.parallelThreshold,e.workerCount,e.overrides);if(e.debug&&t.graphStats){let{hits:r,misses:l,fallbacks:n}=t.graphStats;common.debug("planner",`Graph stats \u2014 hits: ${r}, misses: ${l}, fallbacks: ${n}`);}if(e.cache&&t.globalHash){common.debug("planner","Converting all tasks to full plan for cache...");let r=xe(a,e.rules,s);C(r,a);await rs(e,t,{plan:r,globalHash:t.globalHash});}return a},ns=async(e,t)=>{if(!e.cache)return {tasks:t,skippedTasks:[]};common.debug("planner","Filtering cached tasks...");let s=await G(t,e.cache.results,e.incremental),a=[...new Set(s.tasks.map(l=>l.filePath))],r=[...new Set(s.skippedTasks.map(l=>l.filePath))].filter(l=>!a.includes(l));return {tasks:s.tasks,skippedTasks:s.skippedTasks,cachedResults:s.cachedResults,changedFiles:a,cachedFiles:r}},is=async(e,t,s,a,r=qt,l=Vt,n)=>{if(await os(e,a),e.length>=r){let i=await cs(e,t,a,l,n);if(i)return i}return ps(e,t,s,a,n)},os=async(e,t)=>{if(!t)return;let s=e.filter(l=>!t.has(l)&&P(l)==="logic");if(s.length===0)return;common.debug("planner",`Level-2 classification: scanning ${s.length} unclassified .ts files for Angular decorators`);let a=performance.now();for(let l=0;l<s.length;l+=256){let n=s.slice(l,l+256);await Promise.all(n.map(async i=>{try{let o=await $.readFile(i,"utf8");t.set(i,ie.test(o)?"angular-class":"logic");}catch{t.set(i,"logic");}}));}let r=[...t.values()].filter(l=>l==="angular-class").length;common.debug("planner",`Level-2 classification complete in ${(performance.now()-a).toFixed(1)}ms \u2014 upgraded ${r} files to 'angular-class'`);},ps=async(e,t,s,a,r)=>{let l=[];for(let n of e){let i=Te(n,a),o=r?.length?me(n,t,r):t,p=await te(n,i,o,s);l.push(...p);}return l},cs=async(e,t,s,a,r)=>{common.debug("planner",`Parallelizing task discovery across ${a} workers...`);try{let l=us();if(!l)return common.debug("planner","Worker script not found, falling back to sequential execution"),null;common.debug("planner",`Using worker: ${l}`);let n=hs(e,a);common.debug("planner",`Split ${e.length} files into ${n.length} chunks`);let i=await ms(n,l,t,s,r);return common.debug("planner",`Workers completed. Generated ${i.length} tasks.`),i}catch(l){return common.debug("planner",`Parallel execution failed, falling back to sequential: ${String(l)}`),null}},us=()=>{let e=k.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));return [k.join(e,"worker.js"),k.join(e,"worker.cjs"),k.join(e,"planner","worker.js"),k.join(e,"planner","worker.cjs")].find(t=>fs$1.existsSync(t))??null},hs=(e,t)=>{let s=Math.max(1,Math.ceil(e.length/t)),a=[];for(let r=0;r<e.length;r+=s)a.push(e.slice(r,r+s));return a},ms=async(e,t,s,a,r)=>{let{Worker:l}=await import('worker_threads'),n=Array.from(s.entries()),i=a?Array.from(a.entries()):void 0,o=r?.length?[...r]:void 0,p=e.map((u,c)=>new Promise((d,m)=>{let y=new l(t,{workerData:{files:u,rulesEntries:n,fileTypeCacheEntries:i,overridesData:o}});y.on("message",f=>d(f.tasks)),y.on("error",f=>{common.debug("planner",`Worker ${c} error: ${String(f)}`),m(f instanceof Error?f:Error(String(f)));}),y.on("exit",f=>{f!==0&&m(Error(`Worker ${c} stopped with exit code ${f}`));});}));return (await Promise.all(p)).flat()},Te=(e,t)=>{if(!t)return P(e);let s=t.get(e);if(s)return s;let a=P(e);return t.set(e,a),a},ds=(e,t)=>{let s=new Set(e.map(r=>r.ruleName)),a=[];for(let r of s){let l=t.get(r);l&&a.push(l);}return a},fs=(e,t)=>e.length===0?"":D(e[0].inputs,t),xe=(e,t,s)=>{let a=ae(e),r={};for(let[l,n]of a){let i=Te(l,s),o=ds(n,t),p=fs(n,o),u=n.map(c=>({ruleName:c.ruleName,severity:c.severity,options:c.options,cacheKey:c.taskId,inputs:c.inputs,needsTypeChecker:c.needsTypeChecker,needsProjectContext:c.needsProjectContext}));r[l]={file:{path:l,type:i,hash:p},tasks:u};}return r};var ys=(e,t)=>({files:e.files,rules:t.rules,rootDir:t.rootDir,cache:t.cache,debug:t.debug,incremental:t.incremental,cacheKeyCtx:t.cacheKeyCtx,parallelThreshold:t.parallelThreshold,workerCount:t.workerCount}),gs=e=>e.files.length>0,ks=e=>e.files.length;Object.defineProperty(exports,"Err",{enumerable:true,get:function(){return common.Err}});Object.defineProperty(exports,"Ok",{enumerable:true,get:function(){return common.Ok}});exports.areAllTasksCached=Ne;exports.buildExecutionPlan=Yt;exports.buildIndexes=C;exports.buildTask=ge;exports.buildTasksForFile=te;exports.calculateFileHash=D;exports.detectFileType=P;exports.discoverResources=J;exports.filterCachedTasks=G;exports.filterRulesByAstRequirement=Rt;exports.getBaseName=v;exports.getCacheHitRate=Oe;exports.getExecutionPlanSummary=Xt;exports.getFilesForRules=rt;exports.getScanFileCount=ks;exports.getSpecFile=vt;exports.getStyleFiles=xt;exports.getTasksCountBySeverity=nt;exports.getTemplateFile=wt;exports.getTotalTasks=lt;exports.groupRulesByDependencyType=Et;exports.groupTasksByFile=ae;exports.hasScanFiles=gs;exports.hashFile=S;exports.hashFileStats=Ie;exports.hashFiles=ce;exports.hashRules=U;exports.hashTaskInputs=je;exports.isComponentFile=w;exports.isSpecFile=Ee;exports.isStyleFile=Re;exports.isTemplateFile=$e;exports.isTypeScriptFile=Pe;exports.pruneStaleCache=Be;exports.resourceExists=Tt;exports.scanResultToPlanInput=ys;exports.shouldApplyRule=ye;//# sourceMappingURL=index.cjs.map | ||
| `},Xt=(e,t)=>e.length===0?Error("No files to analyze"):t.size===0?Error("No rules configured"):null,Jt=e=>({hashCache:new Map,resourceCache:new Map,directoryCache:new Map,cacheKeyCtx:e?.cacheKeyCtx}),Qt=async(e,t)=>{if(!e.cache)return;common.debug("planner","Warming up hash cache from metadata index...");let s=performance.now();await pe(e.files,e.cache.metas,t.hashCache),common.debug("planner",`Metadata warmup took ${(performance.now()-s).toFixed(2)}ms`);},Zt=async(e,t)=>{let s=new N;await s.build(e.files),t.componentGraph=s,t.graphStats={hits:0,misses:0,fallbacks:0},common.debug("planner","Component dependency graph built");},es=async(e,t,s)=>{let a;if(!e.cache)return null;let{files:r,rules:l}=e,n=await he(r,l,t.hashCache,e.cacheKeyCtx);if(t.globalHash=n,e.incremental?.forceRerun)return null;let i=await e.cache.analysis.get(n);if(i)return e.debug&&common.debug("planner","Analysis results cached (Short-circuit enabled)"),ts(n,i);let o=performance.now(),p=await e.cache.plans.get(n),u=performance.now();if(!p)return null;let c=performance.now();try{a=p.v===V?fe(p):p;}catch(m){common.debug("planner","Plan cache deserialization failed \u2014 deleting corrupted entry and rebuilding");try{await e.cache.plans.delete?.(n);}catch{}return s&&s.record(common.createInfrastructureError("CacheCorruption",{cause:m instanceof Error?m.message:String(m),phase:"planner",recoverable:true,details:{globalHash:n}})),null}let d=performance.now();return e.debug&&(common.debug("planner","Plan cache HIT"),common.debug("planner",` IO: ${(u-o).toFixed(2)}ms`),common.debug("planner",` Deser: ${(d-c).toFixed(2)}ms`)),{...a,globalHash:n}},ts=(e,t)=>({tasks:[],plan:{},indexes:ss(),skippedTasks:[],globalHash:e,precomputedAnalysis:t}),ss=()=>({filesNeedingTsAst:[],filesNeedingHtmlAst:[],filesNeedingCssAst:[],filesNeedingTypeChecker:[],tasksByFile:{},tasksByRule:{},tasksBySeverityLevel:{off:[],warn:[],error:[]},filesByType:{component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]},tasksBySeverity:{off:0,warn:0,error:0},stats:{totalFiles:0,totalTasks:0,avgTasksPerFile:0,filesWithTemplates:0,filesWithStyles:0,filesWithSpecs:0}}),as=async(e,t,s)=>{if(!e.cache||!t.globalHash)return;let a=performance.now();common.debug("planner","Saving execution plan to cache...");let r=de(s);await e.cache.plans.set(t.globalHash,r),common.debug("planner",` Plan cache saved in ${(performance.now()-a).toFixed(2)}ms`);},rs=async(e,t,s)=>{common.debug("planner","Building tasks...");let a=await ns(e.files,e.rules,t,s,e.parallelThreshold,e.workerCount,e.overrides);if(e.debug&&t.graphStats){let{hits:r,misses:l,fallbacks:n}=t.graphStats;common.debug("planner",`Graph stats \u2014 hits: ${r}, misses: ${l}, fallbacks: ${n}`);}if(e.cache&&t.globalHash){common.debug("planner","Converting all tasks to full plan for cache...");let r=xe(a,e.rules,s);C(r,a);await as(e,t,{plan:r,globalHash:t.globalHash});}return a},ls=async(e,t)=>{if(!e.cache)return {tasks:t,skippedTasks:[]};common.debug("planner","Filtering cached tasks...");let s=await G(t,e.cache.results,e.incremental),a=[...new Set(s.tasks.map(l=>l.filePath))],r=[...new Set(s.skippedTasks.map(l=>l.filePath))].filter(l=>!a.includes(l));return {tasks:s.tasks,skippedTasks:s.skippedTasks,cachedResults:s.cachedResults,changedFiles:a,cachedFiles:r}},ns=async(e,t,s,a,r=Kt,l=qt,n)=>{if(await is(e,a),e.length>=r){let i=await ps(e,t,a,l,n);if(i)return i}return os(e,t,s,a,n)},is=async(e,t)=>{if(!t)return;let s=e.filter(l=>!t.has(l)&&P(l)==="logic");if(s.length===0)return;common.debug("planner",`Level-2 classification: scanning ${s.length} unclassified .ts files for Angular decorators`);let a=performance.now();for(let l=0;l<s.length;l+=256){let n=s.slice(l,l+256);await Promise.all(n.map(async i=>{try{let o=await R.readFile(i,"utf8");t.set(i,ie.test(o)?"angular-class":"logic");}catch{t.set(i,"logic");}}));}let r=[...t.values()].filter(l=>l==="angular-class").length;common.debug("planner",`Level-2 classification complete in ${(performance.now()-a).toFixed(1)}ms \u2014 upgraded ${r} files to 'angular-class'`);},os=async(e,t,s,a,r)=>{let l=[];for(let n of e){let i=Te(n,a),o=r?.length?me(n,t,r):t,p=await te(n,i,o,s);l.push(...p);}return l},ps=async(e,t,s,a,r)=>{common.debug("planner",`Parallelizing task discovery across ${a} workers...`);try{let l=cs();if(!l)return common.debug("planner","Worker script not found, falling back to sequential execution"),null;common.debug("planner",`Using worker: ${l}`);let n=us(e,a);common.debug("planner",`Split ${e.length} files into ${n.length} chunks`);let i=await hs(n,l,t,s,r);return common.debug("planner",`Workers completed. Generated ${i.length} tasks.`),i}catch(l){return common.debug("planner",`Parallel execution failed, falling back to sequential: ${String(l)}`),null}},cs=()=>{let e=k.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));return [k.join(e,"worker.js"),k.join(e,"worker.cjs"),k.join(e,"planner","worker.js"),k.join(e,"planner","worker.cjs")].find(t=>fs$1.existsSync(t))??null},us=(e,t)=>{let s=Math.max(1,Math.ceil(e.length/t)),a=[];for(let r=0;r<e.length;r+=s)a.push(e.slice(r,r+s));return a},hs=async(e,t,s,a,r)=>{let{Worker:l}=await import('worker_threads'),n=Array.from(s.entries()),i=a?Array.from(a.entries()):void 0,o=r?.length?[...r]:void 0,p=e.map((u,c)=>new Promise((d,m)=>{let y=new l(t,{workerData:{files:u,rulesEntries:n,fileTypeCacheEntries:i,overridesData:o}});y.on("message",f=>d(f.tasks)),y.on("error",f=>{common.debug("planner",`Worker ${c} error: ${String(f)}`),m(f instanceof Error?f:Error(String(f)));}),y.on("exit",f=>{f!==0&&m(Error(`Worker ${c} stopped with exit code ${f}`));});}));return (await Promise.all(p)).flat()},Te=(e,t)=>{if(!t)return P(e);let s=t.get(e);if(s)return s;let a=P(e);return t.set(e,a),a},ms=(e,t)=>{let s=new Set(e.map(r=>r.ruleName)),a=[];for(let r of s){let l=t.get(r);l&&a.push(l);}return a},ds=(e,t)=>e.length===0?"":D(e[0].inputs,t),xe=(e,t,s)=>{let a=ae(e),r={};for(let[l,n]of a){let i=Te(l,s),o=ms(n,t),p=ds(n,o),u=n.map(c=>({ruleName:c.ruleName,severity:c.severity,options:c.options,cacheKey:c.taskId,inputs:c.inputs,needsTypeChecker:c.needsTypeChecker,needsProjectContext:c.needsProjectContext}));r[l]={file:{path:l,type:i,hash:p},tasks:u};}return r};var fs=(e,t)=>({files:e.files,rules:t.rules,rootDir:t.rootDir,cache:t.cache,debug:t.debug,incremental:t.incremental,cacheKeyCtx:t.cacheKeyCtx,parallelThreshold:t.parallelThreshold,workerCount:t.workerCount}),ys=e=>e.files.length>0,gs=e=>e.files.length;Object.defineProperty(exports,"Err",{enumerable:true,get:function(){return common.Err}});Object.defineProperty(exports,"Ok",{enumerable:true,get:function(){return common.Ok}});exports.areAllTasksCached=Ne;exports.buildExecutionPlan=Vt;exports.buildIndexes=C;exports.buildTask=ge;exports.buildTasksForFile=te;exports.calculateFileHash=D;exports.detectFileType=P;exports.discoverResources=J;exports.filterCachedTasks=G;exports.filterRulesByAstRequirement=Rt;exports.getBaseName=v;exports.getCacheHitRate=Oe;exports.getExecutionPlanSummary=Yt;exports.getFilesForRules=rt;exports.getScanFileCount=gs;exports.getSpecFile=vt;exports.getStyleFiles=xt;exports.getTasksCountBySeverity=nt;exports.getTemplateFile=wt;exports.getTotalTasks=lt;exports.groupRulesByDependencyType=$t;exports.groupTasksByFile=ae;exports.hasScanFiles=ys;exports.hashFile=b;exports.hashFileStats=Ie;exports.hashFiles=ce;exports.hashRules=U;exports.hashTaskInputs=je;exports.isComponentFile=w;exports.isSpecFile=Ee;exports.isStyleFile=$e;exports.isTemplateFile=Re;exports.isTypeScriptFile=Pe;exports.pruneStaleCache=Be;exports.resourceExists=Tt;exports.scanResultToPlanInput=fs;exports.shouldApplyRule=ye;//# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
+2
-2
@@ -1,2 +0,2 @@ | ||
| import*as $ from'fs/promises';import {readdir,readFile}from'fs/promises';import {existsSync}from'fs';import*as k from'path';import k__default,{dirname,join}from'path';import {fileURLToPath}from'url';import {computeHash,initHasher}from'@ngcompass/cache';import {debug,stableSerialize,time,Err,InfrastructureErrorCollector,timeLog,Ok,createInfrastructureError}from'@ngcompass/common';export{Err,Ok}from'@ngcompass/common';import {minimatch}from'minimatch';var Fe=/templateUrl\s*:\s*['"`]([^'"`\n]+)['"`]/,be=/\bstyleUrl(?!s)\s*:\s*['"`]([^'"`\n]+)['"`]/,Se=/\bstyleUrls\s*:\s*\[([^\]]+)\]/,le=/['"`]([^'"`\n]+\.(?:css|scss|sass|less))['"`]/g,I=async(e,t,s)=>{try{let a=await readFile(e,"utf-8"),r=Fe.exec(a);if(!r)return;let l=k__default.resolve(t,r[1]);return s&&!s.has(l)?void 0:l}catch{return}},j=async(e,t,s)=>{try{let a=await readFile(e,"utf-8"),r=[],l=be.exec(a);if(l){let i=k__default.resolve(t,l[1]);(!s||s.has(i))&&r.push(i);}let n=Se.exec(a);if(n){let i;for(le.lastIndex=0;(i=le.exec(n[1]))!==null;){let o=k__default.resolve(t,i[1]);(!s||s.has(o))&&r.push(o);}}return r}catch{return []}};var N=class{graph=new Map;async build(t){this.graph.clear();let s=new Set(t),a=new Map;for(let r of t){let l=k.dirname(r),n=a.get(l);n?n.push(r):a.set(l,[r]);}for(let[r,l]of a){let n=new Set(l);for(let i of l.filter(o=>o.endsWith(".component.ts"))){let o=k.basename(i,".component.ts"),p=k.join(r,o),u=await Ce(i,r,p,n,s),c=await Ae(i,r,p,l,s),d=(function(m,y){return [`${m}.component.spec.ts`,`${m}.spec.ts`].find(f=>y.has(f))})(p,n);this.graph.set(i,{tsPath:i,templatePath:u,stylePaths:c,specPath:d,type:"component"});}}}getResources(t){return this.graph.get(t)}};async function Ce(e,t,s,a,r){return [`${s}.component.html`,`${s}.html`].find(n=>a.has(n))||I(e,t,r)}async function Ae(e,t,s,a,r){let l=a.filter(n=>{if(!n.startsWith(s))return false;let i=k.extname(n);return (n===`${s}.component${i}`||n===`${s}${i}`)&&/\.(css|scss|sass|less)$/.test(i)});return l.length>0?l:j(e,t,r)}var ie=/\@(Component|Directive|Pipe|Injectable|NgModule)\s*[\(\{]/,P=e=>{let t=k__default.basename(e),s=k__default.extname(e);return t.endsWith(".component.ts")?"component":t.endsWith(".directive.ts")?"directive":t.endsWith(".pipe.ts")?"pipe":t.endsWith(".service.ts")?"service":t.endsWith(".module.ts")?"module":t.endsWith(".guard.ts")?"guard":s===".html"?"template":s===".css"||s===".scss"||s===".sass"||s===".less"?"style":t.endsWith(".config.ts")||s===".json"?"config":t.endsWith(".spec.ts")||t.endsWith(".test.ts")?"spec":s===".ts"?"logic":"unknown"},Pe=e=>k__default.extname(e)===".ts",$e=e=>k__default.extname(e)===".html",Re=e=>{let t=k__default.extname(e);return t===".css"||t===".scss"||t===".sass"||t===".less"},Ee=e=>k__default.basename(e).endsWith(".spec.ts"),w=e=>k__default.basename(e).endsWith(".component.ts"),v=e=>{let t=k__default.basename(e);for(let s of [".component.ts",".directive.ts",".pipe.ts",".service.ts",".module.ts",".guard.ts",".spec.ts"])if(t.endsWith(s))return t.slice(0,-s.length);return k__default.basename(e,k__default.extname(e))};var pe=async(e,t,s)=>{for(let a=0;a<e.length;a+=500){let r=e.slice(a,a+500);await Promise.all(r.map(async l=>{if(!s.has(l))try{let n=await $.stat(l),i=await t.get(l);if(i&&i.mtime===n.mtimeMs&&i.size===n.size)return void s.set(l,i.hash);let o=await S(l);s.set(l,o),await t.set(l,{mtime:n.mtimeMs,size:n.size,hash:o});}catch{}}));}t.flush&&await t.flush();},S=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await $.readFile(e,"utf-8"),r=computeHash(a);return t?.set(e,r),r}catch(a){let r=a instanceof Error?a.message:String(a);return debug("planner",`Failed to hash file: ${e}. Error: ${r}`),""}},ce=async(e,t)=>{if(e.length===0)return "";let s=await Promise.all(e.map(async a=>`${a}:${await S(a,t)}`));return s.sort(),computeHash(s.join("|"))},Ie=async e=>{try{let t=await $.stat(e);return computeHash(`${e}::${t.size}::${t.mtimeMs}`)}catch{return ""}},U=e=>computeHash(stableSerialize(e.map(t=>({name:t.name,severity:t.severity,options:t.options})).sort((t,s)=>t.name<s.name?-1:+(t.name>s.name)))),D=(e,t)=>{let s=[];if(s.push(e.typescript.hash),e.template&&s.push(e.template.hash),e.styles){let a=e.styles.map(r=>r.hash).sort();s.push(...a);}return e.spec&&s.push(e.spec.hash),s.push(U(t)),computeHash(s.join("::"))},je=async e=>{let t=[e.typescript.path];return e.template&&t.push(e.template.path),e.styles&&t.push(...e.styles.map(s=>s.path)),e.spec&&t.push(e.spec.path),ce(t)},ue=(e,t,s,a)=>{let r=[];return a&&(r.push(a.toolVersion),r.push(a.ruleRegistryHash)),r.push(e),r.push(t.typescript.path),r.push(t.typescript.hash),t.template&&r.push(t.template.hash),t.styles?.length&&r.push(t.styles.map(l=>l.hash).sort().join("::")),t.spec&&r.push(t.spec.hash),r.push(stableSerialize(s)),computeHash(r.join("::"))},he=async(e,t,s,a)=>{let r=[];for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500),o=await Promise.all(i.map(async p=>`${p}:${s.get(p)??await S(p,s)}`));r.push(...o);}r.sort();let l=[];return l.push(...r),l.push(U(Array.from(t.values()))),a&&(l.push(`tool:${a.toolVersion}`),l.push(`parser:${a.parserVersion}`),l.push(`registry:${a.ruleRegistryHash}`),l.push(`platform:${a.platform}`)),computeHash(l.join("||"))};var G=async(e,t,s={})=>{let a=performance.now();if(debug("incremental",`Filtering ${e.length} tasks by cache...`),s.forceRerun)return Me(e);if(e.length===0)return We();let r=await t.hasMany(e.map(p=>p.taskId));debug("incremental",`Found ${r.size}/${e.length} tasks in cache`);let{skippedTasks:l,tasks:n}=Le(e,r),i=await ze(t,l,s),o=_e(e.length,l.length,n.length);return Ue(a,o),{skippedTasks:l,tasks:n,cachedResults:i,stats:o}},Ne=async(e,t)=>e.length===0||(await t.hasMany(e.map(s=>s.taskId))).size===e.length,Oe=async(e,t)=>e.length===0?0:(await t.hasMany(e.map(s=>s.taskId))).size/e.length,Be=async(e,t,s={})=>{if(debug("incremental","Pruning stale cache entries..."),e.length===0)return debug("incremental","No tasks to prune"),0;let a=await t.getManyWithMetadata(e);if(a.size===0)return debug("incremental","Cache is empty, nothing to prune"),0;let{now:r,maxAgeMs:l,minHits:n}=De(s),i=Ge(a,r,l,n),o=await Ke(t,i);return debug("incremental",`Pruned ${o} stale entries`),o},Me=e=>(debug("incremental","Force rerun enabled - skipping cache check"),{skippedTasks:[],tasks:e,cachedResults:new Map,stats:{totalTasks:e.length,cachedTasks:0,pendingTasks:e.length,cacheHitRate:0,timeSavedEstimate:0}}),We=()=>({skippedTasks:[],tasks:[],cachedResults:new Map,stats:{totalTasks:0,cachedTasks:0,pendingTasks:0,cacheHitRate:0,timeSavedEstimate:0}}),Le=(e,t)=>{let s=[],a=[];for(let r of e)t.has(r.taskId)?s.push(r):a.push(r);return {skippedTasks:s,tasks:a}},ze=async(e,t,s)=>{if(!s.loadCachedResults||t.length===0)return new Map;debug("incremental",`Loading ${t.length} cached results...`);let a=await e.getMany(t.map(r=>r.taskId));return debug("incremental",`Loaded ${a.size} cached results`),a},_e=(e,t,s)=>{let a=e>0?t/e:0;return {totalTasks:e,cachedTasks:t,pendingTasks:s,cacheHitRate:a,timeSavedEstimate:100*a}},Ue=(e,t)=>{let s=performance.now()-e;debug("incremental",`Cache filtering completed in ${s.toFixed(2)}ms`),debug("incremental",`Cache hit rate: ${(100*t.cacheHitRate).toFixed(1)}%`),debug("incremental",`Skipping ${t.cachedTasks} tasks, executing ${t.pendingTasks} tasks`);},De=e=>({now:Date.now(),maxAgeMs:e.maxAge??6048e5,minHits:e.minHits??1}),Ge=(e,t,s,a)=>{let r=[];for(let[,l]of e)(t-l.metadata.timestamp>s||l.metadata.hits<a)&&r.push(l.metadata.taskId);return r},Ke=async(e,t)=>{let s=0;for(let a=0;a<t.length;a+=100){let r=t.slice(a,a+100);await Promise.all(r.map(l=>e.delete(l))),s+=r.length;}return s};function C(e,t){debug("planner","Generating execution indexes...");let s=K(e,"typescript"),a=K(e,"html"),r=K(e,"css"),l=Ve(e),n=t?tt(t):{},i=t?st(t):at(),o=Ye(e),p=Xe(e),u=Qe(e),c=et(e);return it(t,s,a,r,o),{filesNeedingTsAst:s,filesNeedingHtmlAst:a,filesNeedingCssAst:r,filesNeedingTypeChecker:l,tasksByFile:n,tasksBySeverityLevel:i,tasksByRule:o,filesByType:p,tasksBySeverity:u,stats:c}}var K=(e,t)=>{let s=new Set;for(let[a,r]of Object.entries(e))r.tasks.some(l=>qe(l,t))&&s.add(a);return Array.from(s).sort()},qe=(e,t)=>{switch(t){case "typescript":return !!e.inputs.typescript.needsAst;case "html":return !!e.inputs.template?.needsAst;case "css":return !!e.inputs.styles?.some(s=>s.needsAst)}},Ve=e=>{let t=new Set;for(let[s,a]of Object.entries(e))a.tasks.some(r=>r.needsTypeChecker===true||r.needsProjectContext===true)&&t.add(s);return Array.from(t).sort()},Ye=e=>{let t={};for(let[s,a]of Object.entries(e))for(let r of a.tasks)(t[r.ruleName]??=[]).push(s);for(let s of Object.keys(t))t[s].sort();return t},Xe=e=>{let t=Je();for(let[s,a]of Object.entries(e))t[a.file.type].push(s);for(let s of Object.keys(t))t[s].sort();return t},Je=()=>({component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]}),Qe=e=>{let t=Ze();for(let s of Object.values(e))for(let a of s.tasks)t[a.severity]++;return t},Ze=()=>({off:0,warn:0,error:0}),et=e=>{let t=Object.values(e),s=t.length,a=0,r=0,l=0,n=0;for(let i of t)a+=i.tasks.length,i.tasks.some(o=>!!o.inputs.template)&&r++,i.tasks.some(o=>!!o.inputs.styles?.length)&&l++,i.tasks.some(o=>!!o.inputs.spec)&&n++;return {totalFiles:s,totalTasks:a,avgTasksPerFile:s>0?a/s:0,filesWithTemplates:r,filesWithStyles:l,filesWithSpecs:n}},tt=e=>{let t={};for(let s of e)(t[s.filePath]??=[]).push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>a.ruleName.localeCompare(r.ruleName));return t},st=e=>{let t={off:[],warn:[],error:[]};for(let s of e)t[s.severity].push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>{let l=a.filePath.localeCompare(r.filePath);return l!==0?l:a.ruleName.localeCompare(r.ruleName)});return t},at=()=>({off:[],warn:[],error:[]}),rt=(e,t)=>{let s=new Set;for(let a of t){let r=e[a];if(r)for(let l of r)s.add(l);}return Array.from(s).sort()},lt=e=>e.stats.totalTasks,nt=(e,t)=>e.tasksBySeverity[t],it=(e,t,s,a,r)=>{debug("planner","Indexing complete:"),debug("planner",` - TypeScript AST needed: ${t.length} files`),debug("planner",` - HTML AST needed: ${s.length} files`),debug("planner",` - CSS AST needed: ${a.length} files`),debug("planner",` - Unique rules to run: ${Object.keys(r).length}`),e&&debug("planner",` - Total tasks: ${e.length}`);};var pt=(e,t)=>t.filter(s=>ct(e,Array.isArray(s.files)?s.files:[s.files])),me=(e,t,s)=>{let a=pt(e,s);if(a.length===0)return t;let r=new Map(t);for(let l of a)if(l.rules)for(let[n,i]of Object.entries(l.rules)){let o=r.get(n);if(!o)continue;let p=ut(i);p.severity==="off"?r.delete(n):r.set(n,{...o,severity:p.severity,options:{...o.options,...p.options}});}return r},ct=(e,t)=>t.some(s=>minimatch(e.replace(/\\/g,"/"),s,{dot:true})),ut=e=>typeof e=="string"?{severity:e,options:{}}:e&&typeof e=="object"&&"severity"in e?{severity:e.severity,options:e.options??{}}:{severity:"off",options:{}};var V=2,de=e=>{let t=new R,s=new R,a=new R,r=new q,l=Object.values(e.plan).map(n=>ht(n,t,s,a,r));return {v:V,r:t.values(),o:r.values(),f:s.values(),h:a.values(),t:l}},fe=e=>{let{r:t,o:s,f:a,h:r,t:l}=e,n={},i=[];for(let p of l){let{filePath:u,fileType:c,fileHash:d,ruleTasks:m}=dt(p,t,a,r,s);for(let y of(n[u]={file:{path:u,type:c,hash:d},tasks:m},m))i.push(yt(u,y));}let o=C(n,i);return {tasks:i,plan:n,indexes:o,skippedTasks:[]}},ht=(e,t,s,a,r)=>{let l=s.id(e.file.path),n=a.idOrMinusOne(e.file.hash),i=e.tasks.map(o=>mt(o,t,s,a,r));return [l,e.file.type,n,i]},mt=(e,t,s,a,r)=>{let l=t.id(e.ruleName),n=r.id(e.options),i=a.idOrMinusOne(e.cacheKey),o=O(e.inputs.typescript,s,a),p=e.inputs.template?O(e.inputs.template,s,a):void 0,u=e.inputs.styles&&e.inputs.styles.length>0?e.inputs.styles.map(y=>O(y,s,a)):void 0,c=e.inputs.spec?O(e.inputs.spec,s,a):void 0,d=+!!e.needsTypeChecker,m=+!!e.needsProjectContext;return [l,e.severity,n,i,o,p,u,c,d,m]},O=(e,t,s)=>[t.id(e.path),s.idOrMinusOne(e.hash),+!!e.needsAst],dt=(e,t,s,a,r)=>{let[l,n,i,o]=e;return {filePath:s[l],fileType:n,fileHash:Y(i,a),ruleTasks:o.map(u=>ft(u,t,s,a,r))}},ft=(e,t,s,a,r)=>{let[l,n,i,o,p,u,c,d,m,y]=e,f=t[l],z=r[i],we=Y(o,a),H={typescript:B(p,s,a)};return u&&(H.template=B(u,s,a)),c&&(H.styles=c.map(ve=>B(ve,s,a))),d&&(H.spec=B(d,s,a)),{ruleName:f,severity:n,options:z,cacheKey:we,inputs:H,needsTypeChecker:m===1||void 0,needsProjectContext:y===1||void 0}},B=(e,t,s)=>({path:t[e[0]],hash:Y(e[1],s),needsAst:e[2]===1}),Y=(e,t)=>e>=0?t[e]:"",yt=(e,t)=>({taskId:t.cacheKey,filePath:e,ruleName:t.ruleName,severity:t.severity,options:t.options,inputs:t.inputs,needsTypeChecker:t.needsTypeChecker,needsProjectContext:t.needsProjectContext}),R=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}idOrMinusOne(t){return t?this.id(t):-1}values(){return this.list}},q=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}values(){return this.list}};var X=[".css",".scss",".sass",".less"],J=async(e,t,s,a,r,l)=>{let n=k__default.dirname(e),i=v(e),o=await E(n,l),p=A(e,t),u=Ct(n,i,o,s);if(!u){let m=await I(e,n);m&&(u=A(m,s));}let c=At(e,n,i,o,a);c.length===0&&w(e)&&(c=(await j(e,n)).map(m=>A(m,a)));let d=Pt(n,i,o,r);return {typescript:p,template:u,styles:c.length>0?c:void 0,spec:d}},Tt=async(e,t,s)=>{let a=v(e),r=await E(k__default.dirname(e),s);return t==="template"?Ft(a,r):t==="style"?!!w(e)&&bt(a,r):St(a,r)},xt=async(e,t)=>{if(!w(e))return [];let s=k__default.dirname(e),a=v(e),r=await E(s,t);return X.flatMap(l=>{let n=Z(a,l);return r.includes(n)?[k__default.join(s,n)]:[]})},wt=async(e,t)=>{if(!w(e))return null;let s=k__default.dirname(e),a=v(e),r=await E(s,t),l=Q(a);return r.includes(l)?k__default.join(s,l):null},vt=async(e,t)=>{let s=k__default.dirname(e),a=v(e),r=await E(s,t),l=ee(a);return r.includes(l)?k__default.join(s,l):null},E=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await readdir(e);return t?.set(e,a),a}catch(a){return debug("planner",`Failed to read directory: ${e}. Error: ${a instanceof Error?a.message:String(a)}`),[]}},A=(e,t)=>({path:e,needsAst:t,hash:""}),Q=e=>`${e}.component.html`,Z=(e,t)=>`${e}.component${t}`,ee=e=>`${e}.spec.ts`,Ft=(e,t)=>t.includes(Q(e)),bt=(e,t)=>X.some(s=>t.includes(Z(e,s))),St=(e,t)=>t.includes(ee(e)),Ct=(e,t,s,a)=>{let r=Q(t);return s.includes(r)?A(k__default.join(e,r),a):void 0},At=(e,t,s,a,r)=>{if(!w(e))return [];let l=[];for(let n of X){let i=Z(s,n);a.includes(i)&&l.push(A(k__default.join(t,i),r));}return l},Pt=(e,t,s,a)=>{let r=ee(t);return s.includes(r)?A(k__default.join(e,r),a):void 0};var ye=(e,t)=>{let{dependencyType:s}=e.metadata;return s==="standalone"||s==="imports"?Ht(t):s==="component"?t==="component"||t==="directive"||t==="angular-class":s==="styles"?t==="component":s==="spec"&&t==="spec"},Rt=(e,t)=>{let s=[];for(let a of e.values())a.metadata.requires[t]&&s.push(a);return s},Et=e=>{let t={standalone:[],component:[],styles:[],imports:[],spec:[]};for(let s of e.values())t[s.metadata.dependencyType].push(s);return t},ge=async(e,t,s,a)=>{let r=It(s,t);if(!r.apply)return debug("planner",` - Rule ${s.name} skipped: ${r.reason}`),null;let l=ke(s),n=await jt(e,s,a);return {taskId:ue(s.name,n,s.options,a?.cacheKeyCtx),ruleName:s.name,filePath:e,severity:s.severity,options:s.options,inputs:n,needsTypeChecker:l.needsTypeChecker,needsProjectContext:l.needsProjectContext||void 0}},te=async(e,t,s,a)=>{let r=[];for(let l of s.values()){let n=await ge(e,t,l,a);n&&r.push(n);}return r},Ht=e=>e!=="template"&&e!=="style"&&e!=="config"&&e!=="unknown",It=(e,t)=>ye(e,t)?e.severity==="off"?{apply:false,reason:"disabled ('off')"}:{apply:true,reason:"applicable"}:{apply:false,reason:`does not apply to ${t}`},ke=e=>{let t=e.metadata.requires;return {needsTsAst:!!t.tsAst,needsHtmlAst:!!t.htmlAst,needsCssAst:!!t.cssAst,needsSpecAst:!!t.specAst,needsTypeChecker:!!t.typeChecker,needsProjectContext:!!t.projectContext}},jt=async(e,t,s)=>{let a=ke(t),r=await Nt(e,s),l={typescript:await se(r.typescript.path,a.needsTsAst,s)},n=Ot(e,r,t,a,l,s);n&&(l.template=n);let i=await Bt(r,t,a,s);i&&(l.styles=i);let o=await Mt(r,a,s);return o&&(l.spec=o),l},Nt=async(e,t)=>{let s=t?.resourceCache?.get(e);if(s)return s;if(t?.componentGraph){let r=t.componentGraph.getResources(e);if(r){t.graphStats&&t.graphStats.hits++;let l={typescript:{path:e,hash:"",needsAst:false},styles:r.stylePaths.map(n=>({path:n,hash:"",needsAst:false}))};return r.templatePath&&(l.template={path:r.templatePath,hash:"",needsAst:false}),r.specPath&&(l.spec={path:r.specPath,hash:"",needsAst:false}),t.resourceCache?.set(e,l),l}t.graphStats&&t.graphStats.misses++;}t?.graphStats&&t.graphStats.fallbacks++;let a=await J(e,true,true,true,true,t?.directoryCache);return t?.resourceCache?.set(e,a),a},se=async(e,t,s)=>({path:e,hash:await S(e,s?.hashCache),needsAst:t}),Ot=(e,t,s,a,r,l)=>{let{dependencyType:n}=s.metadata,i=a.needsHtmlAst&&(n==="component"||n==="styles");return t.template?{path:t.template.path,hash:l?.hashCache?.get(t.template.path)??t.template.hash??"",needsAst:i}:n==="component"&&a.needsHtmlAst?{path:e,hash:r.typescript.hash,needsAst:true}:void 0},Bt=async(e,t,s,a)=>{if(!e.styles||e.styles.length===0)return;let r=s.needsCssAst&&t.metadata.dependencyType==="styles";return Promise.all(e.styles.map(l=>se(l.path,r,a)))},Mt=async(e,t,s)=>{if(e.spec)return se(e.spec.path,t.needsSpecAst,s)};var ae=e=>{let t=new Map;for(let s of e){let a=t.get(s.filePath);a?a.push(s):t.set(s.filePath,[s]);}return t};var qt=1e4,Vt=4,Yt=async e=>{let t="buildExecutionPlan";time(t);try{await initHasher();let{files:s,rules:a}=e;debug("planner",`Building execution plan for ${s.length} files and ${a.size} rules`);let r=Jt(s,a);if(r)return Err(r);let l=Qt(e),n=new Map,i=new InfrastructureErrorCollector;await Zt(e,l);let o=await ts(e,l,i);if(o||await es(e,l),o&&o.precomputedAnalysis)return timeLog(t,"planner","Full analysis cached \u2014 returning precomputed result"),Ok(o);let p=o?(timeLog(t,"planner","Execution plan loaded from cache"),o.tasks):await ls(e,l,n),{tasks:u,skippedTasks:c,cachedResults:d,changedFiles:m,cachedFiles:y}=await ns(e,p);debug("planner","Converting tasks to file-centric plan...");let f=xe(u,a,n);debug("planner",`Building indexes for ${u.length} tasks...`);let z=C(f,u);return timeLog(t,"planner","Execution plan built"),Ok({tasks:u,plan:f,indexes:z,skippedTasks:c,cachedResults:d,globalHash:l.globalHash,changedFiles:m,cachedFiles:y})}catch(s){let a=s instanceof Error?s:Error(String(s));return debug("planner",`Error building plan: ${a.message}`),Err(Error(`Failed to build execution plan: ${a.message}`,{cause:a}))}},Xt=e=>{let{stats:t}=e.indexes;return `--- Execution Plan Summary --- | ||
| import*as R from'fs/promises';import {readdir,readFile}from'fs/promises';import {existsSync}from'fs';import*as k from'path';import k__default,{dirname,join}from'path';import {fileURLToPath}from'url';import {computeHash,initHasher}from'@ngcompass/cache';import {debug,stableSerialize,time,Err,InfrastructureErrorCollector,timeLog,Ok,createInfrastructureError}from'@ngcompass/common';export{Err,Ok}from'@ngcompass/common';import {minimatch}from'minimatch';var Fe=/templateUrl\s*:\s*['"`]([^'"`\n]+)['"`]/,Se=/\bstyleUrl(?!s)\s*:\s*['"`]([^'"`\n]+)['"`]/,be=/\bstyleUrls\s*:\s*\[([^\]]+)\]/,le=/['"`]([^'"`\n]+\.(?:css|scss|sass|less))['"`]/g,I=async(e,t,s)=>{try{let a=await readFile(e,"utf-8"),r=Fe.exec(a);if(!r)return;let l=k__default.resolve(t,r[1]);return s&&!s.has(l)?void 0:l}catch{return}},j=async(e,t,s)=>{try{let a=await readFile(e,"utf-8"),r=[],l=Se.exec(a);if(l){let i=k__default.resolve(t,l[1]);(!s||s.has(i))&&r.push(i);}let n=be.exec(a);if(n){let i;for(le.lastIndex=0;(i=le.exec(n[1]))!==null;){let o=k__default.resolve(t,i[1]);(!s||s.has(o))&&r.push(o);}}return r}catch{return []}};var N=class{graph=new Map;async build(t){this.graph.clear();let s=new Set(t),a=new Map;for(let r of t){let l=k.dirname(r),n=a.get(l);n?n.push(r):a.set(l,[r]);}for(let[r,l]of a){let n=new Set(l);for(let i of l.filter(o=>o.endsWith(".component.ts"))){let o=k.basename(i,".component.ts"),p=k.join(r,o),u=await Ce(i,r,p,n,s),c=await Ae(i,r,p,l,s),d=(function(m,y){return [`${m}.component.spec.ts`,`${m}.spec.ts`].find(f=>y.has(f))})(p,n);this.graph.set(i,{tsPath:i,templatePath:u,stylePaths:c,specPath:d,type:"component"});}}}getResources(t){return this.graph.get(t)}};async function Ce(e,t,s,a,r){return [`${s}.component.html`,`${s}.html`].find(n=>a.has(n))||I(e,t,r)}async function Ae(e,t,s,a,r){let l=a.filter(n=>{if(!n.startsWith(s))return false;let i=k.extname(n);return (n===`${s}.component${i}`||n===`${s}${i}`)&&/\.(css|scss|sass|less)$/.test(i)});return l.length>0?l:j(e,t,r)}var ie=/\@(Component|Directive|Pipe|Injectable|NgModule)\s*[\(\{]/,P=e=>{let t=k__default.basename(e),s=k__default.extname(e);return t.endsWith(".component.ts")?"component":t.endsWith(".directive.ts")?"directive":t.endsWith(".pipe.ts")?"pipe":t.endsWith(".service.ts")?"service":t.endsWith(".module.ts")?"module":t.endsWith(".guard.ts")?"guard":s===".html"?"template":s===".css"||s===".scss"||s===".sass"||s===".less"?"style":t.endsWith(".config.ts")||s===".json"?"config":t.endsWith(".spec.ts")||t.endsWith(".test.ts")?"spec":s===".ts"?"logic":"unknown"},Pe=e=>k__default.extname(e)===".ts",Re=e=>k__default.extname(e)===".html",$e=e=>{let t=k__default.extname(e);return t===".css"||t===".scss"||t===".sass"||t===".less"},Ee=e=>k__default.basename(e).endsWith(".spec.ts"),w=e=>k__default.basename(e).endsWith(".component.ts"),v=e=>{let t=k__default.basename(e);for(let s of [".component.ts",".directive.ts",".pipe.ts",".service.ts",".module.ts",".guard.ts",".spec.ts"])if(t.endsWith(s))return t.slice(0,-s.length);return k__default.basename(e,k__default.extname(e))};var pe=async(e,t,s)=>{for(let a=0;a<e.length;a+=500){let r=e.slice(a,a+500);await Promise.all(r.map(async l=>{if(!s.has(l))try{let n=await R.stat(l),i=await t.get(l);if(i&&i.mtime===n.mtimeMs&&i.size===n.size)return void s.set(l,i.hash);let o=await b(l);s.set(l,o),await t.set(l,{mtime:n.mtimeMs,size:n.size,hash:o});}catch{}}));}t.flush&&await t.flush();},b=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await R.readFile(e,"utf-8"),r=computeHash(a);return t?.set(e,r),r}catch(a){let r=a instanceof Error?a.message:String(a);return debug("planner",`Failed to hash file: ${e}. Error: ${r}`),""}},ce=async(e,t)=>{if(e.length===0)return "";let s=await Promise.all(e.map(async a=>`${a}:${await b(a,t)}`));return s.sort(),computeHash(s.join("|"))},Ie=async e=>{try{let t=await R.stat(e);return computeHash(`${e}::${t.size}::${t.mtimeMs}`)}catch{return ""}},U=e=>computeHash(stableSerialize(e.map(t=>({name:t.name,severity:t.severity,options:t.options})).sort((t,s)=>t.name<s.name?-1:+(t.name>s.name)))),D=(e,t)=>{let s=[];if(s.push(e.typescript.hash),e.template&&s.push(e.template.hash),e.styles){let a=e.styles.map(r=>r.hash).sort();s.push(...a);}return e.spec&&s.push(e.spec.hash),s.push(U(t)),computeHash(s.join("::"))},je=async e=>{let t=[e.typescript.path];return e.template&&t.push(e.template.path),e.styles&&t.push(...e.styles.map(s=>s.path)),e.spec&&t.push(e.spec.path),ce(t)},ue=(e,t,s,a)=>{let r=[];return a&&(r.push(a.toolVersion),r.push(a.ruleRegistryHash)),r.push(e),r.push(t.typescript.path),r.push(t.typescript.hash),t.template&&r.push(t.template.hash),t.styles?.length&&r.push(t.styles.map(l=>l.hash).sort().join("::")),t.spec&&r.push(t.spec.hash),r.push(stableSerialize(s)),computeHash(r.join("::"))},he=async(e,t,s,a)=>{let r=[];for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500),o=await Promise.all(i.map(async p=>`${p}:${s.get(p)??await b(p,s)}`));r.push(...o);}r.sort();let l=[];return l.push(...r),l.push(U(Array.from(t.values()))),a&&(l.push(`tool:${a.toolVersion}`),l.push(`parser:${a.parserVersion}`),l.push(`registry:${a.ruleRegistryHash}`),l.push(`platform:${a.platform}`)),computeHash(l.join("||"))};var G=async(e,t,s={})=>{let a=performance.now();if(debug("incremental",`Filtering ${e.length} tasks by cache...`),s.forceRerun)return Me(e);if(e.length===0)return We();let r=await t.hasMany(e.map(p=>p.taskId));debug("incremental",`Found ${r.size}/${e.length} tasks in cache`);let{skippedTasks:l,tasks:n}=Le(e,r),i=await ze(t,l,s),o=_e(e.length,l.length,n.length);return Ue(a,o),{skippedTasks:l,tasks:n,cachedResults:i,stats:o}},Ne=async(e,t)=>e.length===0||(await t.hasMany(e.map(s=>s.taskId))).size===e.length,Oe=async(e,t)=>e.length===0?0:(await t.hasMany(e.map(s=>s.taskId))).size/e.length,Be=async(e,t,s={})=>{if(debug("incremental","Pruning stale cache entries..."),e.length===0)return debug("incremental","No tasks to prune"),0;let a=await t.getManyWithMetadata(e);if(a.size===0)return debug("incremental","Cache is empty, nothing to prune"),0;let{now:r,maxAgeMs:l,minHits:n}=De(s),i=Ge(a,r,l,n),o=await Ke(t,i);return debug("incremental",`Pruned ${o} stale entries`),o},Me=e=>(debug("incremental","Force rerun enabled - skipping cache check"),{skippedTasks:[],tasks:e,cachedResults:new Map,stats:{totalTasks:e.length,cachedTasks:0,pendingTasks:e.length,cacheHitRate:0,timeSavedEstimate:0}}),We=()=>({skippedTasks:[],tasks:[],cachedResults:new Map,stats:{totalTasks:0,cachedTasks:0,pendingTasks:0,cacheHitRate:0,timeSavedEstimate:0}}),Le=(e,t)=>{let s=[],a=[];for(let r of e)t.has(r.taskId)?s.push(r):a.push(r);return {skippedTasks:s,tasks:a}},ze=async(e,t,s)=>{if(!s.loadCachedResults||t.length===0)return new Map;debug("incremental",`Loading ${t.length} cached results...`);let a=await e.getMany(t.map(r=>r.taskId));return debug("incremental",`Loaded ${a.size} cached results`),a},_e=(e,t,s)=>{let a=e>0?t/e:0;return {totalTasks:e,cachedTasks:t,pendingTasks:s,cacheHitRate:a,timeSavedEstimate:100*a}},Ue=(e,t)=>{let s=performance.now()-e;debug("incremental",`Cache filtering completed in ${s.toFixed(2)}ms`),debug("incremental",`Cache hit rate: ${(100*t.cacheHitRate).toFixed(1)}%`),debug("incremental",`Skipping ${t.cachedTasks} tasks, executing ${t.pendingTasks} tasks`);},De=e=>({now:Date.now(),maxAgeMs:e.maxAge??6048e5,minHits:e.minHits??1}),Ge=(e,t,s,a)=>{let r=[];for(let[,l]of e)(t-l.metadata.timestamp>s||l.metadata.hits<a)&&r.push(l.metadata.taskId);return r},Ke=async(e,t)=>{let s=0;for(let a=0;a<t.length;a+=100){let r=t.slice(a,a+100);await Promise.all(r.map(l=>e.delete(l))),s+=r.length;}return s};function C(e,t){debug("planner","Generating execution indexes...");let s=K(e,"typescript"),a=K(e,"html"),r=K(e,"css"),l=Ve(e),n=t?tt(t):{},i=t?st(t):at(),o=Ye(e),p=Xe(e),u=Qe(e),c=et(e);return it(t,s,a,r,o),{filesNeedingTsAst:s,filesNeedingHtmlAst:a,filesNeedingCssAst:r,filesNeedingTypeChecker:l,tasksByFile:n,tasksBySeverityLevel:i,tasksByRule:o,filesByType:p,tasksBySeverity:u,stats:c}}var K=(e,t)=>{let s=new Set;for(let[a,r]of Object.entries(e))r.tasks.some(l=>qe(l,t))&&s.add(a);return Array.from(s).sort()},qe=(e,t)=>{switch(t){case "typescript":return !!e.inputs.typescript.needsAst;case "html":return !!e.inputs.template?.needsAst;case "css":return !!e.inputs.styles?.some(s=>s.needsAst)}},Ve=e=>{let t=new Set;for(let[s,a]of Object.entries(e))a.tasks.some(r=>r.needsTypeChecker===true||r.needsProjectContext===true)&&t.add(s);return Array.from(t).sort()},Ye=e=>{let t={};for(let[s,a]of Object.entries(e))for(let r of a.tasks)(t[r.ruleName]??=[]).push(s);for(let s of Object.keys(t))t[s].sort();return t},Xe=e=>{let t=Je();for(let[s,a]of Object.entries(e))t[a.file.type].push(s);for(let s of Object.keys(t))t[s].sort();return t},Je=()=>({component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]}),Qe=e=>{let t=Ze();for(let s of Object.values(e))for(let a of s.tasks)t[a.severity]++;return t},Ze=()=>({off:0,warn:0,error:0}),et=e=>{let t=Object.values(e),s=t.length,a=0,r=0,l=0,n=0;for(let i of t)a+=i.tasks.length,i.tasks.some(o=>!!o.inputs.template)&&r++,i.tasks.some(o=>!!o.inputs.styles?.length)&&l++,i.tasks.some(o=>!!o.inputs.spec)&&n++;return {totalFiles:s,totalTasks:a,avgTasksPerFile:s>0?a/s:0,filesWithTemplates:r,filesWithStyles:l,filesWithSpecs:n}},tt=e=>{let t={};for(let s of e)(t[s.filePath]??=[]).push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>a.ruleName.localeCompare(r.ruleName));return t},st=e=>{let t={off:[],warn:[],error:[]};for(let s of e)t[s.severity].push(s);for(let s of Object.keys(t))t[s].sort((a,r)=>{let l=a.filePath.localeCompare(r.filePath);return l!==0?l:a.ruleName.localeCompare(r.ruleName)});return t},at=()=>({off:[],warn:[],error:[]}),rt=(e,t)=>{let s=new Set;for(let a of t){let r=e[a];if(r)for(let l of r)s.add(l);}return Array.from(s).sort()},lt=e=>e.stats.totalTasks,nt=(e,t)=>e.tasksBySeverity[t],it=(e,t,s,a,r)=>{debug("planner","Indexing complete:"),debug("planner",` - TypeScript AST needed: ${t.length} files`),debug("planner",` - HTML AST needed: ${s.length} files`),debug("planner",` - CSS AST needed: ${a.length} files`),debug("planner",` - Unique rules to run: ${Object.keys(r).length}`),e&&debug("planner",` - Total tasks: ${e.length}`);};var pt=(e,t)=>t.filter(s=>ct(e,Array.isArray(s.files)?s.files:[s.files])),me=(e,t,s)=>{let a=pt(e,s);if(a.length===0)return t;let r=new Map(t);for(let l of a)if(l.rules)for(let[n,i]of Object.entries(l.rules)){let o=r.get(n);if(!o)continue;let p=ut(i);p.severity==="off"?r.delete(n):r.set(n,{...o,severity:p.severity,options:{...o.options,...p.options}});}return r},ct=(e,t)=>t.some(s=>minimatch(e.replace(/\\/g,"/"),s,{dot:true})),ut=e=>typeof e=="string"?{severity:e,options:{}}:e&&typeof e=="object"&&"severity"in e?{severity:e.severity,options:e.options??{}}:{severity:"off",options:{}};var V=2,de=e=>{let t=new $,s=new $,a=new $,r=new q,l=Object.values(e.plan).map(n=>ht(n,t,s,a,r));return {v:V,r:t.values(),o:r.values(),f:s.values(),h:a.values(),t:l}},fe=e=>{let{r:t,o:s,f:a,h:r,t:l}=e,n={},i=[];for(let p of l){let{filePath:u,fileType:c,fileHash:d,ruleTasks:m}=dt(p,t,a,r,s);for(let y of(n[u]={file:{path:u,type:c,hash:d},tasks:m},m))i.push(yt(u,y));}let o=C(n,i);return {tasks:i,plan:n,indexes:o,skippedTasks:[]}},ht=(e,t,s,a,r)=>{let l=s.id(e.file.path),n=a.idOrMinusOne(e.file.hash),i=e.tasks.map(o=>mt(o,t,s,a,r));return [l,e.file.type,n,i]},mt=(e,t,s,a,r)=>{let l=t.id(e.ruleName),n=r.id(e.options),i=a.idOrMinusOne(e.cacheKey),o=O(e.inputs.typescript,s,a),p=e.inputs.template?O(e.inputs.template,s,a):void 0,u=e.inputs.styles&&e.inputs.styles.length>0?e.inputs.styles.map(y=>O(y,s,a)):void 0,c=e.inputs.spec?O(e.inputs.spec,s,a):void 0,d=+!!e.needsTypeChecker,m=+!!e.needsProjectContext;return [l,e.severity,n,i,o,p,u,c,d,m]},O=(e,t,s)=>[t.id(e.path),s.idOrMinusOne(e.hash),+!!e.needsAst],dt=(e,t,s,a,r)=>{let[l,n,i,o]=e;return {filePath:s[l],fileType:n,fileHash:Y(i,a),ruleTasks:o.map(u=>ft(u,t,s,a,r))}},ft=(e,t,s,a,r)=>{let[l,n,i,o,p,u,c,d,m,y]=e,f=t[l],z=r[i],we=Y(o,a),H={typescript:B(p,s,a)};return u&&(H.template=B(u,s,a)),c&&(H.styles=c.map(ve=>B(ve,s,a))),d&&(H.spec=B(d,s,a)),{ruleName:f,severity:n,options:z,cacheKey:we,inputs:H,needsTypeChecker:m===1||void 0,needsProjectContext:y===1||void 0}},B=(e,t,s)=>({path:t[e[0]],hash:Y(e[1],s),needsAst:e[2]===1}),Y=(e,t)=>e>=0?t[e]:"",yt=(e,t)=>({taskId:t.cacheKey,filePath:e,ruleName:t.ruleName,severity:t.severity,options:t.options,inputs:t.inputs,needsTypeChecker:t.needsTypeChecker,needsProjectContext:t.needsProjectContext}),$=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}idOrMinusOne(t){return t?this.id(t):-1}values(){return this.list}},q=class{map=new Map;list=[];id(t){let s=this.map.get(t);if(s!==void 0)return s;let a=this.list.length;return this.map.set(t,a),this.list.push(t),a}values(){return this.list}};var X=[".css",".scss",".sass",".less"],J=async(e,t,s,a,r,l)=>{let n=k__default.dirname(e),i=v(e),o=await E(n,l),p=A(e,t),u=Ct(n,i,o,s);if(!u){let m=await I(e,n);m&&(u=A(m,s));}let c=At(e,n,i,o,a);c.length===0&&w(e)&&(c=(await j(e,n)).map(m=>A(m,a)));let d=Pt(n,i,o,r);return {typescript:p,template:u,styles:c.length>0?c:void 0,spec:d}},Tt=async(e,t,s)=>{let a=v(e),r=await E(k__default.dirname(e),s);return t==="template"?Ft(a,r):t==="style"?!!w(e)&&St(a,r):bt(a,r)},xt=async(e,t)=>{if(!w(e))return [];let s=k__default.dirname(e),a=v(e),r=await E(s,t);return X.flatMap(l=>{let n=Z(a,l);return r.includes(n)?[k__default.join(s,n)]:[]})},wt=async(e,t)=>{if(!w(e))return null;let s=k__default.dirname(e),a=v(e),r=await E(s,t),l=Q(a);return r.includes(l)?k__default.join(s,l):null},vt=async(e,t)=>{let s=k__default.dirname(e),a=v(e),r=await E(s,t),l=ee(a);return r.includes(l)?k__default.join(s,l):null},E=async(e,t)=>{let s=t?.get(e);if(s)return s;try{let a=await readdir(e);return t?.set(e,a),a}catch(a){return debug("planner",`Failed to read directory: ${e}. Error: ${a instanceof Error?a.message:String(a)}`),[]}},A=(e,t)=>({path:e,needsAst:t,hash:""}),Q=e=>`${e}.component.html`,Z=(e,t)=>`${e}.component${t}`,ee=e=>`${e}.spec.ts`,Ft=(e,t)=>t.includes(Q(e)),St=(e,t)=>X.some(s=>t.includes(Z(e,s))),bt=(e,t)=>t.includes(ee(e)),Ct=(e,t,s,a)=>{let r=Q(t);return s.includes(r)?A(k__default.join(e,r),a):void 0},At=(e,t,s,a,r)=>{if(!w(e))return [];let l=[];for(let n of X){let i=Z(s,n);a.includes(i)&&l.push(A(k__default.join(t,i),r));}return l},Pt=(e,t,s,a)=>{let r=ee(t);return s.includes(r)?A(k__default.join(e,r),a):void 0};var ye=(e,t)=>{let{dependencyType:s}=e.metadata;return s==="standalone"||s==="imports"?Et(t):s==="component"?t==="component"||t==="directive"||t==="angular-class":s==="styles"?t==="component":s==="spec"&&t==="spec"},Rt=(e,t)=>{let s=[];for(let a of e.values())a.metadata.requires[t]&&s.push(a);return s},$t=e=>{let t={standalone:[],component:[],styles:[],imports:[],spec:[]};for(let s of e.values())t[s.metadata.dependencyType].push(s);return t},ge=async(e,t,s,a)=>{if(!Ht(s,t))return null;let r=ke(s),l=await It(e,s,a);return {taskId:ue(s.name,l,s.options,a?.cacheKeyCtx),ruleName:s.name,filePath:e,severity:s.severity,options:s.options,inputs:l,needsTypeChecker:r.needsTypeChecker,needsProjectContext:r.needsProjectContext||void 0}},te=async(e,t,s,a)=>{let r=[];for(let l of s.values()){let n=await ge(e,t,l,a);n&&r.push(n);}return r},Et=e=>e!=="template"&&e!=="style"&&e!=="config"&&e!=="unknown",Ht=(e,t)=>!!ye(e,t)&&e.severity!=="off",ke=e=>{let t=e.metadata.requires;return {needsTsAst:!!t.tsAst,needsHtmlAst:!!t.htmlAst,needsCssAst:!!t.cssAst,needsSpecAst:!!t.specAst,needsTypeChecker:!!t.typeChecker,needsProjectContext:!!t.projectContext}},It=async(e,t,s)=>{let a=ke(t),r=await jt(e,s),l={typescript:await se(r.typescript.path,a.needsTsAst,s)},n=Nt(e,r,t,a,l,s);n&&(l.template=n);let i=await Ot(r,t,a,s);i&&(l.styles=i);let o=await Bt(r,a,s);return o&&(l.spec=o),l},jt=async(e,t)=>{let s=t?.resourceCache?.get(e);if(s)return s;if(t?.componentGraph){let r=t.componentGraph.getResources(e);if(r){t.graphStats&&t.graphStats.hits++;let l={typescript:{path:e,hash:"",needsAst:false},styles:r.stylePaths.map(n=>({path:n,hash:"",needsAst:false}))};return r.templatePath&&(l.template={path:r.templatePath,hash:"",needsAst:false}),r.specPath&&(l.spec={path:r.specPath,hash:"",needsAst:false}),t.resourceCache?.set(e,l),l}t.graphStats&&t.graphStats.misses++;}t?.graphStats&&t.graphStats.fallbacks++;let a=await J(e,true,true,true,true,t?.directoryCache);return t?.resourceCache?.set(e,a),a},se=async(e,t,s)=>({path:e,hash:await b(e,s?.hashCache),needsAst:t}),Nt=(e,t,s,a,r,l)=>{let{dependencyType:n}=s.metadata,i=a.needsHtmlAst&&(n==="component"||n==="styles");return t.template?{path:t.template.path,hash:l?.hashCache?.get(t.template.path)??t.template.hash??"",needsAst:i}:n==="component"&&a.needsHtmlAst?{path:e,hash:r.typescript.hash,needsAst:true}:void 0},Ot=async(e,t,s,a)=>{if(!e.styles||e.styles.length===0)return;let r=s.needsCssAst&&t.metadata.dependencyType==="styles";return Promise.all(e.styles.map(l=>se(l.path,r,a)))},Bt=async(e,t,s)=>{if(e.spec)return se(e.spec.path,t.needsSpecAst,s)};var ae=e=>{let t=new Map;for(let s of e){let a=t.get(s.filePath);a?a.push(s):t.set(s.filePath,[s]);}return t};var Kt=1e4,qt=4,Vt=async e=>{let t="buildExecutionPlan";time(t);try{await initHasher();let{files:s,rules:a}=e;debug("planner",`Building execution plan for ${s.length} files and ${a.size} rules`);let r=Xt(s,a);if(r)return Err(r);let l=Jt(e),n=new Map,i=new InfrastructureErrorCollector;await Qt(e,l);let o=await es(e,l,i);if(o||await Zt(e,l),o&&o.precomputedAnalysis)return timeLog(t,"planner","Full analysis cached \u2014 returning precomputed result"),Ok(o);let p=o?(timeLog(t,"planner","Execution plan loaded from cache"),o.tasks):await rs(e,l,n),{tasks:u,skippedTasks:c,cachedResults:d,changedFiles:m,cachedFiles:y}=await ls(e,p);debug("planner","Converting tasks to file-centric plan...");let f=xe(u,a,n);debug("planner",`Building indexes for ${u.length} tasks...`);let z=C(f,u);return timeLog(t,"planner","Execution plan built"),Ok({tasks:u,plan:f,indexes:z,skippedTasks:c,cachedResults:d,globalHash:l.globalHash,changedFiles:m,cachedFiles:y})}catch(s){let a=s instanceof Error?s:Error(String(s));return debug("planner",`Error building plan: ${a.message}`),Err(Error(`Failed to build execution plan: ${a.message}`,{cause:a}))}},Yt=e=>{let{stats:t}=e.indexes;return `--- Execution Plan Summary --- | ||
| Total files: ${t.totalFiles} | ||
@@ -8,3 +8,3 @@ Total tasks: ${t.totalTasks} | ||
| Files with specs: ${t.filesWithSpecs} | ||
| `},Jt=(e,t)=>e.length===0?Error("No files to analyze"):t.size===0?Error("No rules configured"):null,Qt=e=>({hashCache:new Map,resourceCache:new Map,directoryCache:new Map,cacheKeyCtx:e?.cacheKeyCtx}),Zt=async(e,t)=>{if(!e.cache)return;debug("planner","Warming up hash cache from metadata index...");let s=performance.now();await pe(e.files,e.cache.metas,t.hashCache),debug("planner",`Metadata warmup took ${(performance.now()-s).toFixed(2)}ms`);},es=async(e,t)=>{let s=new N;await s.build(e.files),t.componentGraph=s,t.graphStats={hits:0,misses:0,fallbacks:0},debug("planner","Component dependency graph built");},ts=async(e,t,s)=>{let a;if(!e.cache)return null;let{files:r,rules:l}=e,n=await he(r,l,t.hashCache,e.cacheKeyCtx);if(t.globalHash=n,e.incremental?.forceRerun)return null;let i=await e.cache.analysis.get(n);if(i)return e.debug&&debug("planner","Analysis results cached (Short-circuit enabled)"),ss(n,i);let o=performance.now(),p=await e.cache.plans.get(n),u=performance.now();if(!p)return null;let c=performance.now();try{a=p.v===V?fe(p):p;}catch(m){debug("planner","Plan cache deserialization failed \u2014 deleting corrupted entry and rebuilding");try{await e.cache.plans.delete?.(n);}catch{}return s&&s.record(createInfrastructureError("CacheCorruption",{cause:m instanceof Error?m.message:String(m),phase:"planner",recoverable:true,details:{globalHash:n}})),null}let d=performance.now();return e.debug&&(debug("planner","Plan cache HIT"),debug("planner",` IO: ${(u-o).toFixed(2)}ms`),debug("planner",` Deser: ${(d-c).toFixed(2)}ms`)),{...a,globalHash:n}},ss=(e,t)=>({tasks:[],plan:{},indexes:as(),skippedTasks:[],globalHash:e,precomputedAnalysis:t}),as=()=>({filesNeedingTsAst:[],filesNeedingHtmlAst:[],filesNeedingCssAst:[],filesNeedingTypeChecker:[],tasksByFile:{},tasksByRule:{},tasksBySeverityLevel:{off:[],warn:[],error:[]},filesByType:{component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]},tasksBySeverity:{off:0,warn:0,error:0},stats:{totalFiles:0,totalTasks:0,avgTasksPerFile:0,filesWithTemplates:0,filesWithStyles:0,filesWithSpecs:0}}),rs=async(e,t,s)=>{if(!e.cache||!t.globalHash)return;let a=performance.now();debug("planner","Saving execution plan to cache...");let r=de(s);await e.cache.plans.set(t.globalHash,r),debug("planner",` Plan cache saved in ${(performance.now()-a).toFixed(2)}ms`);},ls=async(e,t,s)=>{debug("planner","Building tasks...");let a=await is(e.files,e.rules,t,s,e.parallelThreshold,e.workerCount,e.overrides);if(e.debug&&t.graphStats){let{hits:r,misses:l,fallbacks:n}=t.graphStats;debug("planner",`Graph stats \u2014 hits: ${r}, misses: ${l}, fallbacks: ${n}`);}if(e.cache&&t.globalHash){debug("planner","Converting all tasks to full plan for cache...");let r=xe(a,e.rules,s);C(r,a);await rs(e,t,{plan:r,globalHash:t.globalHash});}return a},ns=async(e,t)=>{if(!e.cache)return {tasks:t,skippedTasks:[]};debug("planner","Filtering cached tasks...");let s=await G(t,e.cache.results,e.incremental),a=[...new Set(s.tasks.map(l=>l.filePath))],r=[...new Set(s.skippedTasks.map(l=>l.filePath))].filter(l=>!a.includes(l));return {tasks:s.tasks,skippedTasks:s.skippedTasks,cachedResults:s.cachedResults,changedFiles:a,cachedFiles:r}},is=async(e,t,s,a,r=qt,l=Vt,n)=>{if(await os(e,a),e.length>=r){let i=await cs(e,t,a,l,n);if(i)return i}return ps(e,t,s,a,n)},os=async(e,t)=>{if(!t)return;let s=e.filter(l=>!t.has(l)&&P(l)==="logic");if(s.length===0)return;debug("planner",`Level-2 classification: scanning ${s.length} unclassified .ts files for Angular decorators`);let a=performance.now();for(let l=0;l<s.length;l+=256){let n=s.slice(l,l+256);await Promise.all(n.map(async i=>{try{let o=await readFile(i,"utf8");t.set(i,ie.test(o)?"angular-class":"logic");}catch{t.set(i,"logic");}}));}let r=[...t.values()].filter(l=>l==="angular-class").length;debug("planner",`Level-2 classification complete in ${(performance.now()-a).toFixed(1)}ms \u2014 upgraded ${r} files to 'angular-class'`);},ps=async(e,t,s,a,r)=>{let l=[];for(let n of e){let i=Te(n,a),o=r?.length?me(n,t,r):t,p=await te(n,i,o,s);l.push(...p);}return l},cs=async(e,t,s,a,r)=>{debug("planner",`Parallelizing task discovery across ${a} workers...`);try{let l=us();if(!l)return debug("planner","Worker script not found, falling back to sequential execution"),null;debug("planner",`Using worker: ${l}`);let n=hs(e,a);debug("planner",`Split ${e.length} files into ${n.length} chunks`);let i=await ms(n,l,t,s,r);return debug("planner",`Workers completed. Generated ${i.length} tasks.`),i}catch(l){return debug("planner",`Parallel execution failed, falling back to sequential: ${String(l)}`),null}},us=()=>{let e=dirname(fileURLToPath(import.meta.url));return [join(e,"worker.js"),join(e,"worker.cjs"),join(e,"planner","worker.js"),join(e,"planner","worker.cjs")].find(t=>existsSync(t))??null},hs=(e,t)=>{let s=Math.max(1,Math.ceil(e.length/t)),a=[];for(let r=0;r<e.length;r+=s)a.push(e.slice(r,r+s));return a},ms=async(e,t,s,a,r)=>{let{Worker:l}=await import('worker_threads'),n=Array.from(s.entries()),i=a?Array.from(a.entries()):void 0,o=r?.length?[...r]:void 0,p=e.map((u,c)=>new Promise((d,m)=>{let y=new l(t,{workerData:{files:u,rulesEntries:n,fileTypeCacheEntries:i,overridesData:o}});y.on("message",f=>d(f.tasks)),y.on("error",f=>{debug("planner",`Worker ${c} error: ${String(f)}`),m(f instanceof Error?f:Error(String(f)));}),y.on("exit",f=>{f!==0&&m(Error(`Worker ${c} stopped with exit code ${f}`));});}));return (await Promise.all(p)).flat()},Te=(e,t)=>{if(!t)return P(e);let s=t.get(e);if(s)return s;let a=P(e);return t.set(e,a),a},ds=(e,t)=>{let s=new Set(e.map(r=>r.ruleName)),a=[];for(let r of s){let l=t.get(r);l&&a.push(l);}return a},fs=(e,t)=>e.length===0?"":D(e[0].inputs,t),xe=(e,t,s)=>{let a=ae(e),r={};for(let[l,n]of a){let i=Te(l,s),o=ds(n,t),p=fs(n,o),u=n.map(c=>({ruleName:c.ruleName,severity:c.severity,options:c.options,cacheKey:c.taskId,inputs:c.inputs,needsTypeChecker:c.needsTypeChecker,needsProjectContext:c.needsProjectContext}));r[l]={file:{path:l,type:i,hash:p},tasks:u};}return r};var ys=(e,t)=>({files:e.files,rules:t.rules,rootDir:t.rootDir,cache:t.cache,debug:t.debug,incremental:t.incremental,cacheKeyCtx:t.cacheKeyCtx,parallelThreshold:t.parallelThreshold,workerCount:t.workerCount}),gs=e=>e.files.length>0,ks=e=>e.files.length;export{Ne as areAllTasksCached,Yt as buildExecutionPlan,C as buildIndexes,ge as buildTask,te as buildTasksForFile,D as calculateFileHash,P as detectFileType,J as discoverResources,G as filterCachedTasks,Rt as filterRulesByAstRequirement,v as getBaseName,Oe as getCacheHitRate,Xt as getExecutionPlanSummary,rt as getFilesForRules,ks as getScanFileCount,vt as getSpecFile,xt as getStyleFiles,nt as getTasksCountBySeverity,wt as getTemplateFile,lt as getTotalTasks,Et as groupRulesByDependencyType,ae as groupTasksByFile,gs as hasScanFiles,S as hashFile,Ie as hashFileStats,ce as hashFiles,U as hashRules,je as hashTaskInputs,w as isComponentFile,Ee as isSpecFile,Re as isStyleFile,$e as isTemplateFile,Pe as isTypeScriptFile,Be as pruneStaleCache,Tt as resourceExists,ys as scanResultToPlanInput,ye as shouldApplyRule};//# sourceMappingURL=index.js.map | ||
| `},Xt=(e,t)=>e.length===0?Error("No files to analyze"):t.size===0?Error("No rules configured"):null,Jt=e=>({hashCache:new Map,resourceCache:new Map,directoryCache:new Map,cacheKeyCtx:e?.cacheKeyCtx}),Qt=async(e,t)=>{if(!e.cache)return;debug("planner","Warming up hash cache from metadata index...");let s=performance.now();await pe(e.files,e.cache.metas,t.hashCache),debug("planner",`Metadata warmup took ${(performance.now()-s).toFixed(2)}ms`);},Zt=async(e,t)=>{let s=new N;await s.build(e.files),t.componentGraph=s,t.graphStats={hits:0,misses:0,fallbacks:0},debug("planner","Component dependency graph built");},es=async(e,t,s)=>{let a;if(!e.cache)return null;let{files:r,rules:l}=e,n=await he(r,l,t.hashCache,e.cacheKeyCtx);if(t.globalHash=n,e.incremental?.forceRerun)return null;let i=await e.cache.analysis.get(n);if(i)return e.debug&&debug("planner","Analysis results cached (Short-circuit enabled)"),ts(n,i);let o=performance.now(),p=await e.cache.plans.get(n),u=performance.now();if(!p)return null;let c=performance.now();try{a=p.v===V?fe(p):p;}catch(m){debug("planner","Plan cache deserialization failed \u2014 deleting corrupted entry and rebuilding");try{await e.cache.plans.delete?.(n);}catch{}return s&&s.record(createInfrastructureError("CacheCorruption",{cause:m instanceof Error?m.message:String(m),phase:"planner",recoverable:true,details:{globalHash:n}})),null}let d=performance.now();return e.debug&&(debug("planner","Plan cache HIT"),debug("planner",` IO: ${(u-o).toFixed(2)}ms`),debug("planner",` Deser: ${(d-c).toFixed(2)}ms`)),{...a,globalHash:n}},ts=(e,t)=>({tasks:[],plan:{},indexes:ss(),skippedTasks:[],globalHash:e,precomputedAnalysis:t}),ss=()=>({filesNeedingTsAst:[],filesNeedingHtmlAst:[],filesNeedingCssAst:[],filesNeedingTypeChecker:[],tasksByFile:{},tasksByRule:{},tasksBySeverityLevel:{off:[],warn:[],error:[]},filesByType:{component:[],directive:[],pipe:[],service:[],module:[],guard:[],logic:[],"angular-class":[],spec:[],template:[],style:[],config:[],unknown:[]},tasksBySeverity:{off:0,warn:0,error:0},stats:{totalFiles:0,totalTasks:0,avgTasksPerFile:0,filesWithTemplates:0,filesWithStyles:0,filesWithSpecs:0}}),as=async(e,t,s)=>{if(!e.cache||!t.globalHash)return;let a=performance.now();debug("planner","Saving execution plan to cache...");let r=de(s);await e.cache.plans.set(t.globalHash,r),debug("planner",` Plan cache saved in ${(performance.now()-a).toFixed(2)}ms`);},rs=async(e,t,s)=>{debug("planner","Building tasks...");let a=await ns(e.files,e.rules,t,s,e.parallelThreshold,e.workerCount,e.overrides);if(e.debug&&t.graphStats){let{hits:r,misses:l,fallbacks:n}=t.graphStats;debug("planner",`Graph stats \u2014 hits: ${r}, misses: ${l}, fallbacks: ${n}`);}if(e.cache&&t.globalHash){debug("planner","Converting all tasks to full plan for cache...");let r=xe(a,e.rules,s);C(r,a);await as(e,t,{plan:r,globalHash:t.globalHash});}return a},ls=async(e,t)=>{if(!e.cache)return {tasks:t,skippedTasks:[]};debug("planner","Filtering cached tasks...");let s=await G(t,e.cache.results,e.incremental),a=[...new Set(s.tasks.map(l=>l.filePath))],r=[...new Set(s.skippedTasks.map(l=>l.filePath))].filter(l=>!a.includes(l));return {tasks:s.tasks,skippedTasks:s.skippedTasks,cachedResults:s.cachedResults,changedFiles:a,cachedFiles:r}},ns=async(e,t,s,a,r=Kt,l=qt,n)=>{if(await is(e,a),e.length>=r){let i=await ps(e,t,a,l,n);if(i)return i}return os(e,t,s,a,n)},is=async(e,t)=>{if(!t)return;let s=e.filter(l=>!t.has(l)&&P(l)==="logic");if(s.length===0)return;debug("planner",`Level-2 classification: scanning ${s.length} unclassified .ts files for Angular decorators`);let a=performance.now();for(let l=0;l<s.length;l+=256){let n=s.slice(l,l+256);await Promise.all(n.map(async i=>{try{let o=await readFile(i,"utf8");t.set(i,ie.test(o)?"angular-class":"logic");}catch{t.set(i,"logic");}}));}let r=[...t.values()].filter(l=>l==="angular-class").length;debug("planner",`Level-2 classification complete in ${(performance.now()-a).toFixed(1)}ms \u2014 upgraded ${r} files to 'angular-class'`);},os=async(e,t,s,a,r)=>{let l=[];for(let n of e){let i=Te(n,a),o=r?.length?me(n,t,r):t,p=await te(n,i,o,s);l.push(...p);}return l},ps=async(e,t,s,a,r)=>{debug("planner",`Parallelizing task discovery across ${a} workers...`);try{let l=cs();if(!l)return debug("planner","Worker script not found, falling back to sequential execution"),null;debug("planner",`Using worker: ${l}`);let n=us(e,a);debug("planner",`Split ${e.length} files into ${n.length} chunks`);let i=await hs(n,l,t,s,r);return debug("planner",`Workers completed. Generated ${i.length} tasks.`),i}catch(l){return debug("planner",`Parallel execution failed, falling back to sequential: ${String(l)}`),null}},cs=()=>{let e=dirname(fileURLToPath(import.meta.url));return [join(e,"worker.js"),join(e,"worker.cjs"),join(e,"planner","worker.js"),join(e,"planner","worker.cjs")].find(t=>existsSync(t))??null},us=(e,t)=>{let s=Math.max(1,Math.ceil(e.length/t)),a=[];for(let r=0;r<e.length;r+=s)a.push(e.slice(r,r+s));return a},hs=async(e,t,s,a,r)=>{let{Worker:l}=await import('worker_threads'),n=Array.from(s.entries()),i=a?Array.from(a.entries()):void 0,o=r?.length?[...r]:void 0,p=e.map((u,c)=>new Promise((d,m)=>{let y=new l(t,{workerData:{files:u,rulesEntries:n,fileTypeCacheEntries:i,overridesData:o}});y.on("message",f=>d(f.tasks)),y.on("error",f=>{debug("planner",`Worker ${c} error: ${String(f)}`),m(f instanceof Error?f:Error(String(f)));}),y.on("exit",f=>{f!==0&&m(Error(`Worker ${c} stopped with exit code ${f}`));});}));return (await Promise.all(p)).flat()},Te=(e,t)=>{if(!t)return P(e);let s=t.get(e);if(s)return s;let a=P(e);return t.set(e,a),a},ms=(e,t)=>{let s=new Set(e.map(r=>r.ruleName)),a=[];for(let r of s){let l=t.get(r);l&&a.push(l);}return a},ds=(e,t)=>e.length===0?"":D(e[0].inputs,t),xe=(e,t,s)=>{let a=ae(e),r={};for(let[l,n]of a){let i=Te(l,s),o=ms(n,t),p=ds(n,o),u=n.map(c=>({ruleName:c.ruleName,severity:c.severity,options:c.options,cacheKey:c.taskId,inputs:c.inputs,needsTypeChecker:c.needsTypeChecker,needsProjectContext:c.needsProjectContext}));r[l]={file:{path:l,type:i,hash:p},tasks:u};}return r};var fs=(e,t)=>({files:e.files,rules:t.rules,rootDir:t.rootDir,cache:t.cache,debug:t.debug,incremental:t.incremental,cacheKeyCtx:t.cacheKeyCtx,parallelThreshold:t.parallelThreshold,workerCount:t.workerCount}),ys=e=>e.files.length>0,gs=e=>e.files.length;export{Ne as areAllTasksCached,Vt as buildExecutionPlan,C as buildIndexes,ge as buildTask,te as buildTasksForFile,D as calculateFileHash,P as detectFileType,J as discoverResources,G as filterCachedTasks,Rt as filterRulesByAstRequirement,v as getBaseName,Oe as getCacheHitRate,Yt as getExecutionPlanSummary,rt as getFilesForRules,gs as getScanFileCount,vt as getSpecFile,xt as getStyleFiles,nt as getTasksCountBySeverity,wt as getTemplateFile,lt as getTotalTasks,$t as groupRulesByDependencyType,ae as groupTasksByFile,ys as hasScanFiles,b as hashFile,Ie as hashFileStats,ce as hashFiles,U as hashRules,je as hashTaskInputs,w as isComponentFile,Ee as isSpecFile,$e as isStyleFile,Re as isTemplateFile,Pe as isTypeScriptFile,Be as pruneStaleCache,Tt as resourceExists,fs as scanResultToPlanInput,ye as shouldApplyRule};//# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+4
-4
| { | ||
| "name": "@ngcompass/planner", | ||
| "version": "0.1.9-beta", | ||
| "version": "0.2.0-beta", | ||
| "description": "Execution planning and incremental analysis for ngcompass", | ||
@@ -25,5 +25,5 @@ "sideEffects": false, | ||
| "minimatch": "^10.2.4", | ||
| "@ngcompass/cache": "0.1.9-beta", | ||
| "@ngcompass/common": "0.1.9-beta", | ||
| "@ngcompass/scanner": "0.1.9-beta" | ||
| "@ngcompass/common": "0.2.0-beta", | ||
| "@ngcompass/scanner": "0.2.0-beta", | ||
| "@ngcompass/cache": "0.2.0-beta" | ||
| }, | ||
@@ -30,0 +30,0 @@ "peerDependencies": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
296059
-0.48%408
-0.24%1
Infinity%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
Updated
Updated