@zipbul/gildash 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,26 +1,8 @@
1
1
  // @bun
2
- var lt=Object.defineProperty;var ut=(n,t)=>{for(var e in t)lt(n,e,{get:t[e],enumerable:!0,configurable:!0,set:(r)=>t[e]=()=>r})};import{err as T,isErr as tn}from"@zipbul/result";import at from"path";import{existsSync as Qt}from"fs";import{err as pt}from"@zipbul/result";import{parseSync as dt}from"oxc-parser";function k(n,t,e){return e!==void 0?{type:n,message:t,cause:e}:{type:n,message:t}}function rn(n,t,e=dt){try{let{program:r,errors:i,comments:s}=e(n,t);return{filePath:n,program:r,errors:i,comments:s,sourceText:t}}catch(r){return pt(k("parse",`Failed to parse file: ${n}`,r))}}class hn{#t;#n=new Map;constructor(n){this.#t=Math.max(1,n)}get size(){return this.#n.size}has(n){return this.#n.has(n)}get(n){if(!this.#n.has(n))return;let t=this.#n.get(n);return this.#n.delete(n),this.#n.set(n,t),t}set(n,t){if(this.#n.has(n))this.#n.delete(n);if(this.#n.set(n,t),this.#n.size>this.#t){let e=this.#n.keys().next().value;if(e!==void 0)this.#n.delete(e)}}delete(n){return this.#n.delete(n)}clear(){this.#n.clear()}}class bn{lru;constructor(n=500){this.lru=new hn(n)}get(n){return this.lru.get(n)}set(n,t){this.lru.set(n,t)}invalidate(n){this.lru.delete(n)}invalidateAll(){this.lru.clear()}size(){return this.lru.size}}function zn(n){let t=[0];for(let e=0;e<n.length;e++)if(n[e]===`
3
- `)t.push(e+1);return t}function xn(n,t){let e=0,r=n.length-1;while(e<r){let i=e+r+1>>1;if(n[i]<=t)e=i;else r=i-1}return{line:e+1,column:t-n[e]}}import{err as ft}from"@zipbul/result";import{parse as gt}from"comment-parser";function Gn(n){try{let t=n.trim();if(t.startsWith("/**"))t=t.slice(3);if(t.endsWith("*/"))t=t.slice(0,-2);let r=gt(`/** ${t} */`)[0]??{description:"",tags:[]};return{description:(r.description??"").trim(),tags:(r.tags??[]).map((i)=>({tag:i.tag??"",name:i.name??"",type:i.type??"",description:i.description??"",optional:i.optional??!1,...i.default!==void 0?{default:i.default}:{}}))}}catch(t){return ft(k("parse","Failed to parse JSDoc comment",t))}}import{isErr as yt}from"@zipbul/result";function cn(n){let{program:t,sourceText:e,comments:r}=n,i=zn(e);function s(o,m){return{start:xn(i,o),end:xn(i,m)}}function p(o){let m=null;for(let a of r){if(a.type!=="Block")continue;if(a.end>o)continue;if(!a.value.startsWith("*"))continue;if(!m||a.end>m.end)m={value:`/*${a.value}*/`,end:a.end}}if(!m)return;for(let a of t.body){let g=a.start??0;if(g===o)continue;if(g>m.end&&g<o)return}return m.value}function l(o){if(!o)return;let m=o.typeAnnotation??o;return e.slice(m.start,m.end)}function c(o){if(!o||o.length===0)return[];return o.map((m)=>{let a=m.expression;if(!a)return{name:"unknown"};if(a.type==="CallExpression"){let g=a.callee?.name??a.callee?.property?.name??"unknown",h=(a.arguments??[]).map((d)=>e.slice(d.start,d.end));return{name:g,arguments:h.length>0?h:void 0}}if(a.type==="Identifier")return{name:a.name??"unknown"};return{name:e.slice(a.start,a.end)}})}function y(o){let m=o.type==="TSParameterProperty"?o.parameter:o;if(m?.type==="RestElement"){let R=`...${m.argument?.name??"unknown"}`,L=m.typeAnnotation,B=L?l(L):void 0,O={name:R,isOptional:!1};if(B)O.type=B;return O}if(m?.type==="AssignmentPattern"){let{left:N,right:R}=m,L=N?.name??"unknown",B=N?.typeAnnotation,O=B?l(B):void 0,W=e.slice(R.start,R.end),v=c(N?.decorators??[]),J={name:L,isOptional:!0,defaultValue:W};if(O)J.type=O;if(v.length>0)J.decorators=v;return J}let a=m?.name??m?.pattern?.name??"unknown",g=!!m?.optional,h=m?.typeAnnotation,d=h?l(h):void 0,S=c(m?.decorators??[]),P={name:a,isOptional:g};if(d)P.type=d;if(S.length>0)P.decorators=S;return P}function f(o,m){let a=[];if(m?.async)a.push("async");if(o.static)a.push("static");if(o.abstract)a.push("abstract");if(o.readonly)a.push("readonly");if(o.override)a.push("override");if(o.declare)a.push("declare");if(o.const)a.push("const");let g=o.accessibility;if(g==="private")a.push("private");else if(g==="protected")a.push("protected");else if(g==="public")a.push("public");return a}function x(o){let m=[];if(o.superClass){let g=e.slice(o.superClass.start,o.superClass.end);m.push({kind:"extends",name:g})}let a=o.implements??[];for(let g of a){let h=g.expression??g,d=e.slice(h.start,h.end);m.push({kind:"implements",name:d})}return m}function w(o){let m=[];for(let a of o.extends??[]){let g=a.expression??a,h=e.slice(g.start,g.end);m.push({kind:"extends",name:h})}return m}function A(o){let m=[];for(let a of o)if(a.type==="MethodDefinition"){let g=a.key?.name??"unknown",h=a.value,d=a.kind??"method",S=d==="constructor"?"constructor":d==="get"?"getter":d==="set"?"setter":"method",P=f(a,h),N=(h?.params??[]).map(y),R=l(h?.returnType),L={kind:"method",name:g,span:s(a.start,a.end),isExported:!1,methodKind:S,modifiers:P,parameters:N.length>0?N:void 0,returnType:R};m.push(L)}else if(a.type==="PropertyDefinition"){let g=a.key?.name??"unknown",h=f(a),d={kind:"property",name:g,span:s(a.start,a.end),isExported:!1,modifiers:h};m.push(d)}return m}function F(o){let m=[];for(let a of o)if(a.type==="TSMethodSignature"){let g=a.key?.name??"unknown",h=(a.params??[]).map(y),d=l(a.returnType);m.push({kind:"method",name:g,span:s(a.start,a.end),isExported:!1,modifiers:[],methodKind:"method",parameters:h.length>0?h:void 0,returnType:d})}else if(a.type==="TSPropertySignature"){let g=a.key?.name??"unknown",h=l(a.typeAnnotation),d={kind:"property",name:g,span:s(a.start,a.end),isExported:!1,modifiers:a.readonly?["readonly"]:[],returnType:h};m.push(d)}return m}function E(o,m){let a=o.type??"";if(a==="FunctionDeclaration"){let g=o.id?.name??"default",h=(o.params??[]).map(y),d=l(o.returnType),S=f(o,o),P=c(o.decorators??[]),N=o.typeParameters?.params?.map((L)=>L.name?.name).filter(Boolean)||void 0,R={kind:"function",name:g,span:s(o.start,o.end),isExported:m,modifiers:S,parameters:h.length>0?h:void 0,returnType:d,decorators:P.length>0?P:void 0};if(N&&N.length>0)R.typeParameters=N;return R}if(a==="ClassDeclaration"||a==="ClassExpression"){let g=o.id?.name??"default",h=x(o),d=A(o.body?.body??[]),S=c(o.decorators??[]),P=f(o,o),N=o.typeParameters?.params?.map((L)=>L.name?.name).filter(Boolean)||void 0,R={kind:"class",name:g,span:s(o.start,o.end),isExported:m,modifiers:P,heritage:h.length>0?h:void 0,members:d.length>0?d:void 0,decorators:S.length>0?S:void 0};if(N&&N.length>0)R.typeParameters=N;return R}if(a==="VariableDeclaration"){let g=[];for(let h of o.declarations??[]){let{id:d,init:S}=h;if(d?.type==="ObjectPattern"){for(let O of d.properties??[]){let W=O.value?.name??O.key?.name??"unknown";g.push({kind:"variable",name:W,span:s(O.start??h.start,O.end??h.end),isExported:m,modifiers:[]})}continue}if(d?.type==="ArrayPattern"){for(let O of d.elements??[]){if(!O||O.type!=="Identifier")continue;let W=O.name??"unknown";g.push({kind:"variable",name:W,span:s(O.start??h.start,O.end??h.end),isExported:m,modifiers:[]})}continue}let P=d?.name??"unknown",N="variable",R,L;if(S?.type==="FunctionExpression"||S?.type==="ArrowFunctionExpression")N="function",R=(S.params??[]).map(y),L=l(S.returnType);let B=[];g.push({kind:N,name:P,span:s(h.start,h.end),isExported:m,modifiers:B,parameters:R,returnType:L})}if(g.length===0)return null;if(g.length===1)return g[0];return g}if(a==="TSTypeAliasDeclaration")return{kind:"type",name:o.id?.name??"unknown",span:s(o.start,o.end),isExported:m,modifiers:[]};if(a==="TSInterfaceDeclaration"){let g=o.id?.name??"unknown",h=w(o),d=F(o.body?.body??[]),S=o.typeParameters?.params?.map((N)=>N.name?.name).filter(Boolean)||void 0,P={kind:"interface",name:g,span:s(o.start,o.end),isExported:m,modifiers:[],heritage:h.length>0?h:void 0,members:d.length>0?d:void 0};if(S&&S.length>0)P.typeParameters=S;return P}if(a==="TSEnumDeclaration"){let g=o.id?.name??"unknown",h=f(o),S=(o.body?.members??[]).map((P)=>({kind:"property",name:P.id?.name??P.id?.value??"unknown",span:s(P.start,P.end),isExported:!1,modifiers:[]}));return{kind:"enum",name:g,span:s(o.start,o.end),isExported:m,modifiers:h,members:S.length>0?S:void 0}}return null}let b=[];for(let o of t.body){let m=null,a=o,g=typeof a.type==="string"?a.type:"";if(g==="ExportNamedDeclaration"){let d=o;if(d.declaration){if(m=E(d.declaration,!0),m&&!Array.isArray(m))m.span=s(d.start,d.end);else if(Array.isArray(m))for(let S of m)S.span=s(d.start,d.end)}}else if(g==="ExportDefaultDeclaration"){let d=o,S=d.declaration;if(S){if(m=E(S,!0),m&&!Array.isArray(m))m.name=S.id?.name??"default",m.isExported=!0,m.span=s(d.start,d.end)}}else m=E(o,!1);let h=Array.isArray(m)?m:m?[m]:[];for(let d of h){let S=o.start??0,P=p(S);if(P){let N=Gn(P);if(!yt(N))d.jsDoc=N}b.push(d)}}return b}import{resolve as Sn,dirname as ht,extname as bt}from"path";function wn(n,t,e){let r=(i)=>{let s=bt(i);if(s==="")return[i+".ts",i+"/index.ts",i+".mts",i+"/index.mts",i+".cts",i+"/index.cts"];if(s===".js")return[i.slice(0,-3)+".ts"];if(s===".mjs")return[i.slice(0,-4)+".mts"];if(s===".cjs")return[i.slice(0,-4)+".cts"];return[i]};if(t.startsWith(".")){let i=Sn(ht(n),t);return r(i)}if(e)for(let[i,s]of e.paths){if(s.length===0)continue;let p=i.indexOf("*");if(p===-1){if(t===i){let l=[];for(let c of s)l.push(...r(Sn(e.baseUrl,c)));return l}}else{let l=i.slice(0,p),c=i.slice(p+1);if(t.startsWith(l)&&(c===""||t.endsWith(c))){let y=t.slice(l.length,c===""?void 0:t.length-c.length),f=[];for(let x of s)f.push(...r(Sn(e.baseUrl,x.replace("*",y))));return f}}}return[]}function Bn(n,t,e,r=wn){let i=new Map,s=n.body??[];for(let p of s){if(p.type!=="ImportDeclaration")continue;let l=p.source?.value??"",c=r(t,l,e);if(c.length===0)continue;let y=c[0],f=p.specifiers??[];for(let x of f)switch(x.type){case"ImportSpecifier":i.set(x.local.name,{path:y,importedName:x.imported.name});break;case"ImportDefaultSpecifier":i.set(x.local.name,{path:y,importedName:"default"});break;case"ImportNamespaceSpecifier":i.set(x.local.name,{path:y,importedName:"*"});break}}return i}var xt=new Set(["loc","start","end","scope"]);function j(n,t){if(!n||typeof n!=="object")return;if(Array.isArray(n)){for(let r of n)j(r,t);return}let e=n;t(e);for(let r of Object.keys(e)){if(xt.has(r))continue;let i=e[r];if(i&&typeof i==="object")j(i,t)}}function Kn(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n;if((t.type==="StringLiteral"||t.type==="Literal")&&typeof t.value==="string")return t.value;return null}function X(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n;if(t.type==="Identifier"){let e=t.name;return{root:e,parts:[],full:e}}if(t.type==="ThisExpression")return{root:"this",parts:[],full:"this"};if(t.type==="Super")return{root:"super",parts:[],full:"super"};if(t.type==="MemberExpression"){let e=[],r=t;while(r.type==="MemberExpression"){let p=r.property;if(!p||typeof p.name!=="string")return null;e.unshift(p.name),r=r.object}let i;if(r.type==="Identifier")i=r.name;else if(r.type==="ThisExpression")i="this";else if(r.type==="Super")i="super";else return null;let s=[i,...e].join(".");return{root:i,parts:e,full:s}}return null}function $n(n,t,e,r=wn){let i=[],s=n.body??[];for(let p of s){if(p.type==="ImportDeclaration"){let l=p.source?.value??"",c=r(t,l,e);if(c.length===0)continue;let y=c[0],f=p.importKind==="type";i.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:y,dstSymbolName:null,...f?{metaJson:JSON.stringify({isType:!0})}:{}});continue}if(p.type==="ExportAllDeclaration"&&p.source){let l=p.source?.value??"",c=r(t,l,e);if(c.length===0)continue;let y=c[0],f=p.exportKind==="type",x={isReExport:!0};if(f)x.isType=!0;i.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:y,dstSymbolName:null,metaJson:JSON.stringify(x)});continue}if(p.type==="ExportNamedDeclaration"&&p.source){let l=p.source?.value??"",c=r(t,l,e);if(c.length===0)continue;let y=c[0];i.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:y,dstSymbolName:null,metaJson:JSON.stringify({isReExport:!0})})}}return j(n,(p)=>{if(p.type!=="ImportExpression")return;let l=Kn(p.source);if(!l)return;let c=r(t,l,e);if(c.length===0)return;let y=c[0];i.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:y,dstSymbolName:null,metaJson:JSON.stringify({isDynamic:!0})})}),i}function Un(n,t,e){let r=[],i=[],s=[];function p(){if(i.length>0)return i[i.length-1]??null;return null}function l(y){if(!y)return null;let f=e.get(y.root);if(y.parts.length===0){if(f)return{dstFilePath:f.path,dstSymbolName:f.importedName,resolution:"import"};return{dstFilePath:t,dstSymbolName:y.root,resolution:"local"}}else{if(f&&f.importedName==="*"){let x=y.parts[y.parts.length-1];return{dstFilePath:f.path,dstSymbolName:x,resolution:"namespace"}}return{dstFilePath:t,dstSymbolName:y.full,resolution:"local-member"}}}function c(y){if(!y||typeof y!=="object")return;if(Array.isArray(y)){for(let w of y)c(w);return}let f=y,x=typeof f.type==="string"?f.type:"";if(x==="ClassDeclaration"||x==="ClassExpression"){let w=f,A=w.id?.name??"AnonymousClass";s.push(A),c(w.body),s.pop();return}if(x==="FunctionDeclaration"){let w=f,A=w.id?.name??"anonymous";i.push(A),c(w.body),i.pop();return}if(x==="VariableDeclarator"&&f.init&&(f.init?.type==="FunctionExpression"||f.init?.type==="ArrowFunctionExpression")){let w=f,A=w.id?.name??"anonymous";i.push(A),c(w.init?.body??w.init),i.pop();return}if(x==="MethodDefinition"&&f.value){let w=f,A=s[s.length-1]??"",F=w.key?.name??"anonymous",E=A?`${A}.${F}`:F;i.push(E),c(w.value?.body),i.pop();return}if(x==="FunctionExpression"||x==="ArrowFunctionExpression"){let w=p(),A=w?`${w}.<anonymous>`:"<anonymous>";i.push(A),c(f.body),i.pop();return}if(x==="CallExpression"){let w=f,A=X(w.callee),F=l(A);if(F){let E=p(),b={};if(E===null)b.scope="module";r.push({type:"calls",srcFilePath:t,srcSymbolName:E,dstFilePath:F.dstFilePath,dstSymbolName:F.dstSymbolName,...Object.keys(b).length>0?{metaJson:JSON.stringify(b)}:{}})}c(w.callee);for(let E of w.arguments??[])c(E);return}if(x==="NewExpression"){let w=f,A=X(w.callee),F=l(A);if(F){let E=p(),b={isNew:!0};if(E===null)b.scope="module";r.push({type:"calls",srcFilePath:t,srcSymbolName:E,dstFilePath:F.dstFilePath,dstSymbolName:F.dstSymbolName,metaJson:JSON.stringify(b)})}for(let E of w.arguments??[])c(E);return}for(let w of Object.keys(f)){if(w==="loc"||w==="start"||w==="end"||w==="scope")continue;let A=f[w];if(A&&typeof A==="object")c(A)}}return c(n),r}function Vn(n,t,e){let r=[];return j(n,(i)=>{if(i.type==="TSInterfaceDeclaration"){let l=i.id?.name??"AnonymousInterface",c=i.extends??[];for(let y of c){let f=y.expression??y,x=X(f);if(!x)continue;let w=Nn(x,t,e);r.push({type:"extends",srcFilePath:t,srcSymbolName:l,...w})}return}if(i.type!=="ClassDeclaration"&&i.type!=="ClassExpression")return;let s=i.id?.name??"AnonymousClass";if(i.superClass){let l=X(i.superClass);if(l){let c=Nn(l,t,e);r.push({type:"extends",srcFilePath:t,srcSymbolName:s,...c})}}let p=i.implements??[];for(let l of p){let c=l.expression??l,y=X(c);if(!y)continue;let f=Nn(y,t,e);r.push({type:"implements",srcFilePath:t,srcSymbolName:s,...f})}}),r}function Nn(n,t,e){let r=e.get(n.root);if(r){if(r.importedName==="*"){let i=n.parts[n.parts.length-1]??n.root;return{dstFilePath:r.path,dstSymbolName:i,metaJson:JSON.stringify({isNamespaceImport:!0})}}return{dstFilePath:r.path,dstSymbolName:n.parts.length>0?n.full:r.importedName}}return{dstFilePath:t,dstSymbolName:n.full,metaJson:JSON.stringify({isLocal:!0})}}function mn(n,t,e){let r=Bn(n,t,e),i=$n(n,t,e),s=Un(n,t,r),p=Vn(n,t,r);return[...i,...s,...p]}import{err as Wn,isErr as At}from"@zipbul/result";import{Database as Pt}from"bun:sqlite";import{mkdirSync as Dt,unlinkSync as Hn,existsSync as Qn}from"fs";import{dirname as Et,join as Xn}from"path";import{drizzle as Tt}from"drizzle-orm/bun-sqlite";import{migrate as Ft}from"drizzle-orm/bun-sqlite/migrator";var An={};ut(An,{watcherOwner:()=>kt,symbols:()=>D,relations:()=>u,files:()=>I,FTS_SETUP_SQL:()=>kn});import{sql as St}from"drizzle-orm";import{sqliteTable as ln,text as C,integer as G,real as wt,index as Y,primaryKey as Nt,foreignKey as On,check as Ot}from"drizzle-orm/sqlite-core";var I=ln("files",{project:C("project").notNull(),filePath:C("file_path").notNull(),mtimeMs:wt("mtime_ms").notNull(),size:G("size").notNull(),contentHash:C("content_hash").notNull(),updatedAt:C("updated_at").notNull()},(n)=>[Nt({columns:[n.project,n.filePath]})]),D=ln("symbols",{id:G("id").primaryKey({autoIncrement:!0}),project:C("project").notNull(),filePath:C("file_path").notNull(),kind:C("kind").notNull(),name:C("name").notNull(),startLine:G("start_line").notNull(),startColumn:G("start_column").notNull(),endLine:G("end_line").notNull(),endColumn:G("end_column").notNull(),isExported:G("is_exported").notNull().default(0),signature:C("signature"),fingerprint:C("fingerprint"),detailJson:C("detail_json"),contentHash:C("content_hash").notNull(),indexedAt:C("indexed_at").notNull()},(n)=>[Y("idx_symbols_project_file").on(n.project,n.filePath),Y("idx_symbols_project_kind").on(n.project,n.kind),Y("idx_symbols_project_name").on(n.project,n.name),Y("idx_symbols_fingerprint").on(n.project,n.fingerprint),On({columns:[n.project,n.filePath],foreignColumns:[I.project,I.filePath]}).onDelete("cascade")]),u=ln("relations",{id:G("id").primaryKey({autoIncrement:!0}),project:C("project").notNull(),type:C("type").notNull(),srcFilePath:C("src_file_path").notNull(),srcSymbolName:C("src_symbol_name"),dstFilePath:C("dst_file_path").notNull(),dstSymbolName:C("dst_symbol_name"),metaJson:C("meta_json")},(n)=>[Y("idx_relations_src").on(n.project,n.srcFilePath),Y("idx_relations_dst").on(n.project,n.dstFilePath),Y("idx_relations_type").on(n.project,n.type),On({columns:[n.project,n.srcFilePath],foreignColumns:[I.project,I.filePath]}).onDelete("cascade"),On({columns:[n.project,n.dstFilePath],foreignColumns:[I.project,I.filePath]}).onDelete("cascade")]),kt=ln("watcher_owner",{id:G("id").primaryKey(),pid:G("pid").notNull(),startedAt:C("started_at").notNull(),heartbeatAt:C("heartbeat_at").notNull()},(n)=>[Ot("watcher_owner_singleton",St`${n.id} = 1`)]),kn=[`CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(
4
- name,
5
- file_path,
6
- kind,
7
- content=symbols,
8
- content_rowid=id
9
- )`,`CREATE TRIGGER IF NOT EXISTS symbols_ai
10
- AFTER INSERT ON symbols BEGIN
11
- INSERT INTO symbols_fts(rowid, name, file_path, kind)
12
- VALUES (new.id, new.name, new.file_path, new.kind);
13
- END`,`CREATE TRIGGER IF NOT EXISTS symbols_ad
14
- AFTER DELETE ON symbols BEGIN
15
- INSERT INTO symbols_fts(symbols_fts, rowid, name, file_path, kind)
16
- VALUES ('delete', old.id, old.name, old.file_path, old.kind);
17
- END`,`CREATE TRIGGER IF NOT EXISTS symbols_au
18
- AFTER UPDATE ON symbols BEGIN
19
- INSERT INTO symbols_fts(symbols_fts, rowid, name, file_path, kind)
20
- VALUES ('delete', old.id, old.name, old.file_path, old.kind);
21
- INSERT INTO symbols_fts(rowid, name, file_path, kind)
22
- VALUES (new.id, new.name, new.file_path, new.kind);
23
- END`];class Pn{client=null;drizzle=null;dbPath;txDepth=0;constructor(n){this.dbPath=Xn(n.projectRoot,".zipbul","gildash.db")}get drizzleDb(){if(!this.drizzle)throw Error("Database is not open. Call open() first.");return this.drizzle}open(){try{Dt(Et(this.dbPath),{recursive:!0}),this.client=new Pt(this.dbPath),this.client.run("PRAGMA journal_mode = WAL"),this.client.run("PRAGMA foreign_keys = ON"),this.client.run("PRAGMA busy_timeout = 5000"),this.drizzle=Tt(this.client,{schema:An}),Ft(this.drizzle,{migrationsFolder:Xn(import.meta.dirname,"migrations")});for(let n of kn)this.client.run(n)}catch(n){if(this.isCorruptionError(n)&&Qn(this.dbPath)){this.closeClient(),Hn(this.dbPath);for(let e of["-wal","-shm"]){let r=this.dbPath+e;if(Qn(r))Hn(r)}let t=this.open();if(At(t))return Wn(k("store",`Failed to recover database at ${this.dbPath}`,t.data));return t}return Wn(k("store",`Failed to open database at ${this.dbPath}`,n))}}close(){this.closeClient(),this.drizzle=null}transaction(n){let t=this.requireClient();if(this.txDepth===0){this.txDepth++;try{return t.transaction(()=>n(this))()}finally{this.txDepth--}}let e=`sp_${this.txDepth++}`;t.run(`SAVEPOINT "${e}"`);try{let r=n(this);return t.run(`RELEASE SAVEPOINT "${e}"`),r}catch(r){throw t.run(`ROLLBACK TO SAVEPOINT "${e}"`),t.run(`RELEASE SAVEPOINT "${e}"`),r}finally{this.txDepth--}}immediateTransaction(n){let t=this.requireClient();this.txDepth++,t.run("BEGIN IMMEDIATE");try{let e=n();return t.run("COMMIT"),e}catch(e){throw t.run("ROLLBACK"),e}finally{this.txDepth--}}query(n){let t=this.requireClient().prepare(n).get();if(!t)return null;return Object.values(t)[0]}getTableNames(){return this.requireClient().query("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((t)=>t.name)}selectOwner(){return this.requireClient().prepare("SELECT pid, heartbeat_at FROM watcher_owner WHERE id = 1").get()??void 0}insertOwner(n){let t=new Date().toISOString();this.requireClient().prepare("INSERT INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)").run(n,t,t)}replaceOwner(n){let t=new Date().toISOString();this.requireClient().prepare("INSERT OR REPLACE INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)").run(n,t,t)}touchOwner(n){let t=new Date().toISOString();this.requireClient().prepare("UPDATE watcher_owner SET heartbeat_at = ? WHERE id = 1 AND pid = ?").run(t,n)}deleteOwner(n){this.requireClient().prepare("DELETE FROM watcher_owner WHERE id = 1 AND pid = ?").run(n)}requireClient(){if(!this.client)throw Error("Database is not open. Call open() first.");return this.client}closeClient(){if(this.client)this.client.close(),this.client=null}isCorruptionError(n){if(!(n instanceof Error))return!1;let t=n.message.toLowerCase();return t.includes("malformed")||t.includes("corrupt")||t.includes("not a database")||t.includes("disk i/o error")||t.includes("sqlite_corrupt")}}import{eq as sn,and as Yn}from"drizzle-orm";class Dn{db;constructor(n){this.db=n}getFile(n,t){return this.db.drizzleDb.select().from(I).where(Yn(sn(I.project,n),sn(I.filePath,t))).get()??null}upsertFile(n){this.db.drizzleDb.insert(I).values({project:n.project,filePath:n.filePath,mtimeMs:n.mtimeMs,size:n.size,contentHash:n.contentHash,updatedAt:n.updatedAt}).onConflictDoUpdate({target:[I.project,I.filePath],set:{mtimeMs:n.mtimeMs,size:n.size,contentHash:n.contentHash,updatedAt:n.updatedAt}}).run()}getAllFiles(n){return this.db.drizzleDb.select().from(I).where(sn(I.project,n)).all()}getFilesMap(n){let t=this.getAllFiles(n),e=new Map;for(let r of t)e.set(r.filePath,r);return e}deleteFile(n,t){this.db.drizzleDb.delete(I).where(Yn(sn(I.project,n),sn(I.filePath,t))).run()}}import{eq as M,and as Z,sql as En,count as Rt}from"drizzle-orm";function un(n){return n.trim().split(/\s+/).map((t)=>t.trim()).filter((t)=>t.length>0).map((t)=>`"${t.replaceAll('"','""')}"*`).join(" ")}class Tn{db;constructor(n){this.db=n}replaceFileSymbols(n,t,e,r){if(this.db.drizzleDb.delete(D).where(Z(M(D.project,n),M(D.filePath,t))).run(),!r.length)return;let i=new Date().toISOString();for(let s of r)this.db.drizzleDb.insert(D).values({project:n,filePath:t,kind:s.kind??"unknown",name:s.name??"",startLine:s.startLine??0,startColumn:s.startColumn??0,endLine:s.endLine??0,endColumn:s.endColumn??0,isExported:s.isExported??0,signature:s.signature??null,fingerprint:s.fingerprint??null,detailJson:s.detailJson??null,contentHash:e,indexedAt:s.indexedAt??i}).run()}getFileSymbols(n,t){return this.db.drizzleDb.select().from(D).where(Z(M(D.project,n),M(D.filePath,t))).all()}searchByName(n,t,e={}){let r=e.limit??50,i=un(t);if(!i)return[];return this.db.drizzleDb.select().from(D).where(Z(En`${D.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${i})`,M(D.project,n),e.kind?M(D.kind,e.kind):void 0)).orderBy(D.name).limit(r).all()}searchByKind(n,t){return this.db.drizzleDb.select().from(D).where(Z(M(D.project,n),M(D.kind,t))).orderBy(D.name).all()}getStats(n){let t=this.db.drizzleDb.select({symbolCount:Rt(),fileCount:En`COUNT(DISTINCT ${D.filePath})`}).from(D).where(M(D.project,n)).get();return{symbolCount:t?.symbolCount??0,fileCount:t?.fileCount??0}}getByFingerprint(n,t){return this.db.drizzleDb.select().from(D).where(Z(M(D.project,n),M(D.fingerprint,t))).all()}deleteFileSymbols(n,t){this.db.drizzleDb.delete(D).where(Z(M(D.project,n),M(D.filePath,t))).run()}searchByQuery(n){return this.db.drizzleDb.select().from(D).where(Z(n.ftsQuery?En`${D.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${n.ftsQuery})`:void 0,n.exactName?M(D.name,n.exactName):void 0,n.project!==void 0?M(D.project,n.project):void 0,n.kind?M(D.kind,n.kind):void 0,n.filePath!==void 0?M(D.filePath,n.filePath):void 0,n.isExported!==void 0?M(D.isExported,n.isExported?1:0):void 0)).orderBy(D.name).limit(n.limit).all()}}import{eq as _,and as K,isNull as Zn,or as _t}from"drizzle-orm";class Fn{db;constructor(n){this.db=n}replaceFileRelations(n,t,e){if(this.db.drizzleDb.delete(u).where(K(_(u.project,n),_(u.srcFilePath,t))).run(),!e.length)return;for(let r of e)this.db.drizzleDb.insert(u).values({project:n,type:r.type??"unknown",srcFilePath:r.srcFilePath??t,srcSymbolName:r.srcSymbolName??null,dstFilePath:r.dstFilePath??"",dstSymbolName:r.dstSymbolName??null,metaJson:r.metaJson??null}).run()}getOutgoing(n,t,e){if(e!==void 0)return this.db.drizzleDb.select({project:u.project,type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson}).from(u).where(K(_(u.project,n),_(u.srcFilePath,t),_t(_(u.srcSymbolName,e),Zn(u.srcSymbolName)))).all();return this.db.drizzleDb.select({project:u.project,type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson}).from(u).where(K(_(u.project,n),_(u.srcFilePath,t))).all()}getIncoming(n,t){return this.db.drizzleDb.select({project:u.project,type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson}).from(u).where(K(_(u.project,n),_(u.dstFilePath,t))).all()}getByType(n,t){return this.db.drizzleDb.select({project:u.project,type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson}).from(u).where(K(_(u.project,n),_(u.type,t))).all()}deleteFileRelations(n,t){this.db.drizzleDb.delete(u).where(K(_(u.project,n),_(u.srcFilePath,t))).run()}searchRelations(n){return this.db.drizzleDb.select({project:u.project,type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson}).from(u).where(K(n.project!==void 0?_(u.project,n.project):void 0,n.srcFilePath!==void 0?_(u.srcFilePath,n.srcFilePath):void 0,n.srcSymbolName!==void 0?_(u.srcSymbolName,n.srcSymbolName):void 0,n.dstFilePath!==void 0?_(u.dstFilePath,n.dstFilePath):void 0,n.dstSymbolName!==void 0?_(u.dstSymbolName,n.dstSymbolName):void 0,n.type!==void 0?_(u.type,n.type):void 0)).limit(n.limit).all()}retargetRelations(n,t,e,r,i){let s=e===null?K(_(u.project,n),_(u.dstFilePath,t),Zn(u.dstSymbolName)):K(_(u.project,n),_(u.dstFilePath,t),_(u.dstSymbolName,e));this.db.drizzleDb.update(u).set({dstFilePath:r,dstSymbolName:i}).where(s).run()}}import{err as jn}from"@zipbul/result";import{subscribe as Ct}from"@parcel/watcher";import Rn from"path";var It=["**/.git/**","**/.zipbul/**","**/dist/**","**/node_modules/**"],vt=new Set(["package.json","tsconfig.json"]);function Mt(n){return n.replaceAll("\\","/")}function Lt(n){if(n==="update")return"change";if(n==="create")return"create";return"delete"}class pn{#t;#n;#r;#i;#s;#e;constructor(n,t=Ct,e=console){this.#n=n.projectRoot,this.#r=[...It,...n.ignorePatterns??[]],this.#i=new Set((n.extensions??[".ts",".mts",".cts"]).map((r)=>r.toLowerCase())),this.#s=t,this.#e=e}async start(n){try{this.#t=await this.#s(this.#n,(t,e)=>{if(t){this.#e.error(k("watcher","Callback error",t));return}try{for(let r of e){let i=Mt(Rn.relative(this.#n,r.path));if(i.startsWith(".."))continue;let s=Rn.basename(i),p=Rn.extname(i).toLowerCase();if(!vt.has(s)&&!this.#i.has(p))continue;if(i.endsWith(".d.ts"))continue;n({eventType:Lt(r.type),filePath:i})}}catch(r){this.#e.error(k("watcher","Callback error",r))}},{ignore:this.#r})}catch(t){return jn(k("watcher","Failed to subscribe watcher",t))}}async close(){if(!this.#t)return;try{await this.#t.unsubscribe(),this.#t=void 0}catch(n){return jn(k("watcher","Failed to close watcher",n))}}}import _n from"path";import{promises as Jt}from"fs";var zt=["**/node_modules/**","**/.git/**","**/.zipbul/**","**/dist/**"];async function dn(n){let t=[];for await(let e of Jt.glob("**/package.json",{cwd:n,exclude:zt})){let r=_n.dirname(e).replaceAll("\\","/"),i=_n.join(n,e),s=await Bun.file(i).json(),p=typeof s?.name==="string"&&s.name.length>0?s.name:_n.basename(r==="."?n:r);t.push({dir:r,project:p})}return t.sort((e,r)=>r.dir.length-e.dir.length),t}function q(n,t,e="default"){let r=n.replaceAll("\\","/");for(let i of t){if(i.dir===".")return i.project;if(r===i.dir||r.startsWith(`${i.dir}/`))return i.project}return e}import qn from"path";var U=new Map;async function Gt(n){let t=Bun.file(n);if(!await t.exists())return null;let e=await t.json();return typeof e==="object"&&e!==null?e:null}async function on(n){if(U.has(n))return U.get(n)??null;let t=qn.join(n,"tsconfig.json"),e=await Gt(t);if(!e)return U.set(n,null),null;let r=typeof e.compilerOptions==="object"&&e.compilerOptions!==null?e.compilerOptions:null;if(!r)return U.set(n,null),null;let i=typeof r.baseUrl==="string"?r.baseUrl:null,s=typeof r.paths==="object"&&r.paths!==null?r.paths:null;if(!i&&!s)return U.set(n,null),null;let p=i?qn.resolve(n,i):n,l=new Map;if(s)for(let[y,f]of Object.entries(s)){if(!Array.isArray(f))continue;let x=f.filter((w)=>typeof w==="string");l.set(y,x)}let c={baseUrl:p,paths:l};return U.set(n,c),c}function fn(n){if(n){U.delete(n);return}U.clear()}import nt from"path";function Cn(n,t){return nt.relative(n,t).replaceAll("\\","/")}function nn(n,t){return nt.resolve(n,t)}function V(n){let t=Bun.hash.xxHash64(n);return BigInt.asUintN(64,BigInt(t)).toString(16).padStart(16,"0")}import{isErr as rt}from"@zipbul/result";import{promises as Bt}from"fs";import{join as Kt}from"path";async function tt(n){let{projectRoot:t,extensions:e,ignorePatterns:r,fileRepo:i}=n,s=i.getFilesMap(),p=new Set,l=[],c=[],y=r.map((x)=>new Bun.Glob(x));for await(let x of Bt.glob("**/*",{cwd:t})){if(!e.some((a)=>x.endsWith(a)))continue;if(y.some((a)=>a.match(x)))continue;p.add(x);let w=Kt(t,x),A=Bun.file(w),{size:F,lastModified:E}=A,b=s.get(x);if(!b){let a=await A.text(),g=V(a);l.push({filePath:x,contentHash:g,mtimeMs:E,size:F});continue}if(b.mtimeMs===E&&b.size===F){c.push({filePath:x,contentHash:b.contentHash,mtimeMs:E,size:F});continue}let o=await A.text(),m=V(o);if(m===b.contentHash)c.push({filePath:x,contentHash:m,mtimeMs:E,size:F});else l.push({filePath:x,contentHash:m,mtimeMs:E,size:F})}let f=[];for(let x of s.keys())if(!p.has(x))f.push(x);return{changed:l,unchanged:c,deleted:f}}function $t(n){if(n.kind==="function"||n.kind==="method"){let t=n.parameters?.length??0,e=n.modifiers.includes("async")?1:0;return`params:${t}|async:${e}`}return null}function Ut(n){let t={};if(n.jsDoc)t.jsDoc=n.jsDoc;if(n.kind==="function"||n.kind==="method"){if(n.parameters!==void 0)t.parameters=n.parameters;if(n.returnType!==void 0)t.returnType=n.returnType}if(n.heritage?.length)t.heritage=n.heritage;if(n.decorators?.length)t.decorators=n.decorators;if(n.typeParameters?.length)t.typeParameters=n.typeParameters;if(n.modifiers?.length)t.modifiers=n.modifiers;if(n.members?.length)t.members=n.members.map((e)=>e.name);return Object.keys(t).length>0?JSON.stringify(t):null}function et(n,t,e,r,i){let s=$t(n),p=V(`${t}|${n.kind}|${s??""}`);return{project:e,filePath:r,kind:n.kind,name:t,startLine:n.span.start.line,startColumn:n.span.start.column,endLine:n.span.end.line,endColumn:n.span.end.column,isExported:n.isExported?1:0,signature:s,fingerprint:p,detailJson:Ut(n),contentHash:i,indexedAt:new Date().toISOString()}}function In(n){let{parsed:t,project:e,filePath:r,contentHash:i,symbolRepo:s}=n,p=cn(t),l=[];for(let c of p){l.push(et(c,c.name,e,r,i));for(let y of c.members??[])l.push(et(y,`${c.name}.${y.name}`,e,r,i))}s.replaceFileSymbols(e,r,i,l)}function vn(n){let{ast:t,project:e,filePath:r,relationRepo:i,projectRoot:s,tsconfigPaths:p}=n,l=nn(s,r),c=mn(t,l,p),y=[];for(let f of c){let x=Cn(s,f.dstFilePath);if(x.startsWith(".."))continue;let w=Cn(s,f.srcFilePath);y.push({project:e,type:f.type,srcFilePath:w,srcSymbolName:f.srcSymbolName??null,dstFilePath:x,dstSymbolName:f.dstSymbolName??null,metaJson:f.metaJson??null})}return i.replaceFileRelations(e,r,y),y.length}var Vt=100;class gn{opts;logger;callbacks=new Set;indexingLock=!1;pendingEvents=[];debounceTimer=null;currentIndexing=null;pendingFullIndex=!1;pendingFullIndexWaiters=[];tsconfigPathsRaw;boundariesRefresh=null;constructor(n){this.opts=n,this.logger=n.logger??console,this.tsconfigPathsRaw=on(n.projectRoot)}get tsconfigPaths(){return this.tsconfigPathsRaw}fullIndex(){return this.startIndex(void 0,!0)}incrementalIndex(n){return this.startIndex(n,!1)}onIndexed(n){return this.callbacks.add(n),()=>this.callbacks.delete(n)}handleWatcherEvent(n){if(n.filePath.endsWith("tsconfig.json")){fn(this.opts.projectRoot),this.tsconfigPathsRaw=on(this.opts.projectRoot),this.fullIndex().catch((t)=>{this.logger.error("[IndexCoordinator] fullIndex failed after tsconfig change:",t)});return}if(n.filePath.endsWith("package.json")){let t=this.opts.discoverProjectsFn??dn;this.boundariesRefresh=t(this.opts.projectRoot).then((e)=>{this.opts.boundaries=e})}if(this.pendingEvents.push(n),this.debounceTimer===null)this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.flushPending()},Vt)}async shutdown(){if(this.debounceTimer!==null)clearTimeout(this.debounceTimer),this.debounceTimer=null;if(this.currentIndexing)await this.currentIndexing}startIndex(n,t){if(this.indexingLock){if(t)return this.pendingFullIndex=!0,new Promise((r,i)=>{this.pendingFullIndexWaiters.push({resolve:r,reject:i})});return this.currentIndexing}this.indexingLock=!0;let e=this.doIndex(n,t).then((r)=>{return this.fireCallbacks(r),r}).finally(()=>{if(this.indexingLock=!1,this.currentIndexing=null,this.pendingFullIndex){this.pendingFullIndex=!1;let r=this.pendingFullIndexWaiters.splice(0);this.startIndex(void 0,!0).then((i)=>{for(let s of r)s.resolve(i)}).catch((i)=>{for(let s of r)s.reject(i)})}else if(this.pendingEvents.length>0){let r=this.pendingEvents.splice(0);this.startIndex(r,!1).catch((i)=>this.logger.error("[IndexCoordinator] incremental drain error",i))}});return this.currentIndexing=e,e}async doIndex(n,t){let e=Date.now(),{fileRepo:r,symbolRepo:i,relationRepo:s,dbConnection:p}=this.opts;if(this.boundariesRefresh)await this.boundariesRefresh,this.boundariesRefresh=null;let l,c;if(n!==void 0)l=n.filter((b)=>b.eventType==="create"||b.eventType==="change").map((b)=>({filePath:b.filePath,contentHash:"",mtimeMs:0,size:0})),c=n.filter((b)=>b.eventType==="delete").map((b)=>b.filePath);else{let b=new Map;for(let m of this.opts.boundaries)for(let[a,g]of r.getFilesMap(m.project))b.set(a,g);let o=await tt({projectRoot:this.opts.projectRoot,extensions:this.opts.extensions,ignorePatterns:this.opts.ignorePatterns,fileRepo:{getFilesMap:()=>b}});l=o.changed,c=o.deleted}let y=await this.tsconfigPathsRaw??void 0,f=new Map;for(let b of c){let o=q(b,this.opts.boundaries),m=i.getFileSymbols(o,b);f.set(b,m)}let x=()=>{for(let b of c){let o=q(b,this.opts.boundaries);i.deleteFileSymbols(o,b),s.deleteFileRelations(o,b),r.deleteFile(o,b)}},w=async()=>{let b=0,o=0,m=[];for(let a of l)try{let g=await this.processFile(a.filePath,a.contentHash||void 0,y);b+=g.symbolCount,o+=g.relCount}catch(g){this.logger.error(`[IndexCoordinator] Failed to index ${a.filePath}:`,g),m.push(a.filePath)}return{symbols:b,relations:o,failedFiles:m}},A=0,F=0,E=[];if(t){let{projectRoot:b,boundaries:o}=this.opts,{parseCache:m}=this.opts,a=await Promise.allSettled(l.map(async(d)=>{let S=nn(b,d.filePath),P=Bun.file(S),N=await P.text(),R=d.contentHash||V(N);return{filePath:d.filePath,text:N,contentHash:R,mtimeMs:P.lastModified,size:P.size}})),g=a.filter((d)=>d.status==="fulfilled").map((d)=>d.value);for(let d of a)if(d.status==="rejected")this.logger.error("[IndexCoordinator] Failed to pre-read file:",d.reason);let h=[];p.transaction(()=>{for(let S of o){let P=r.getAllFiles(S.project);for(let N of P)r.deleteFile(N.project,N.filePath)}let d=this.opts.parseSourceFn??rn;for(let S of g){let P=q(S.filePath,o),N=d(nn(b,S.filePath),S.text);if(rt(N))throw N.data;let R=N;h.push({filePath:S.filePath,parsed:R}),r.upsertFile({project:P,filePath:S.filePath,mtimeMs:S.mtimeMs,size:S.size,contentHash:S.contentHash,updatedAt:new Date().toISOString()}),In({parsed:R,project:P,filePath:S.filePath,contentHash:S.contentHash,symbolRepo:i}),F+=vn({ast:R.program,project:P,filePath:S.filePath,relationRepo:s,projectRoot:b,tsconfigPaths:y}),A+=i.getFileSymbols(P,S.filePath).length}});for(let d of h)m.set(d.filePath,d.parsed)}else{x();let b=await w();A=b.symbols,F=b.relations,E=b.failedFiles}if(!t)for(let[b,o]of f)for(let m of o){if(!m.fingerprint)continue;let a=q(b,this.opts.boundaries),g=i.getByFingerprint(a,m.fingerprint);if(g.length===1){let h=g[0];s.retargetRelations(a,b,m.name,h.filePath,h.name)}}return{indexedFiles:l.length,removedFiles:c.length,totalSymbols:A,totalRelations:F,durationMs:Date.now()-e,changedFiles:l.map((b)=>b.filePath),deletedFiles:[...c],failedFiles:E}}async processFile(n,t,e){let{projectRoot:r,boundaries:i}=this.opts,{fileRepo:s,symbolRepo:p,relationRepo:l,parseCache:c}=this.opts,y=nn(r,n),f=Bun.file(y),x=await f.text(),w=t||V(x),A=q(n,i),E=(this.opts.parseSourceFn??rn)(y,x);if(rt(E))throw E.data;let b=E;c.set(n,b),s.upsertFile({project:A,filePath:n,mtimeMs:f.lastModified,size:f.size,contentHash:w,updatedAt:new Date().toISOString()}),In({parsed:b,project:A,filePath:n,contentHash:w,symbolRepo:p});let o=vn({ast:b.program,project:A,filePath:n,relationRepo:l,projectRoot:r,tsconfigPaths:e});return{symbolCount:p.getFileSymbols(A,n).length,relCount:o}}fireCallbacks(n){for(let t of this.callbacks)try{t(n)}catch(e){this.logger.error("[IndexCoordinator] onIndexed callback threw:",e)}}flushPending(){if(this.indexingLock)return;if(this.pendingEvents.length>0){let n=this.pendingEvents.splice(0);this.startIndex(n,!1).catch((t)=>this.logger.error("[IndexCoordinator] flushPending startIndex error:",t))}}}function Wt(n){try{return process.kill(n,0),!0}catch(t){if(typeof t==="object"&&t&&"code"in t)return t.code!=="ESRCH";return!0}}function Ht(n){let t=new Date(n).getTime();return Number.isNaN(t)?0:t}function it(n,t,e={}){let r=e.now??Date.now,i=e.isAlive??Wt,s=e.staleAfterSeconds??90;return n.immediateTransaction(()=>{let p=n.selectOwner();if(!p)return n.insertOwner(t),"owner";let l=Math.floor((r()-Ht(p.heartbeat_at))/1000);if(i(p.pid)&&l<s)return"reader";return n.replaceOwner(t),"owner"})}function st(n,t){n.deleteOwner(t)}function ot(n,t){n.touchOwner(t)}function Mn(n){let{symbolRepo:t,project:e,query:r}=n,i=r.project??e,s=r.limit??100,p={kind:r.kind,filePath:r.filePath,isExported:r.isExported,project:i,limit:s};if(r.text)if(r.exact)p.exactName=r.text;else{let c=un(r.text);if(c)p.ftsQuery=c}return t.searchByQuery(p).map((c)=>({id:c.id,filePath:c.filePath,kind:c.kind,name:c.name,span:{start:{line:c.startLine,column:c.startColumn},end:{line:c.endLine,column:c.endColumn}},isExported:c.isExported===1,signature:c.signature,fingerprint:c.fingerprint,detail:c.detailJson?(()=>{try{return JSON.parse(c.detailJson)}catch{return{}}})():{}}))}function Ln(n){let{relationRepo:t,project:e,query:r}=n,i=r.project??e,s=r.limit??500;return t.searchRelations({srcFilePath:r.srcFilePath,srcSymbolName:r.srcSymbolName,dstFilePath:r.dstFilePath,dstSymbolName:r.dstSymbolName,type:r.type,project:i,limit:s}).map((l)=>({type:l.type,srcFilePath:l.srcFilePath,srcSymbolName:l.srcSymbolName,dstFilePath:l.dstFilePath,dstSymbolName:l.dstSymbolName,metaJson:l.metaJson??void 0}))}class an{options;adjacencyList=new Map;reverseAdjacencyList=new Map;constructor(n){this.options=n}build(){this.adjacencyList=new Map,this.reverseAdjacencyList=new Map;let n=this.options.relationRepo.getByType(this.options.project,"imports");for(let t of n){let{srcFilePath:e,dstFilePath:r}=t;if(!this.adjacencyList.has(e))this.adjacencyList.set(e,new Set);if(this.adjacencyList.get(e).add(r),!this.reverseAdjacencyList.has(r))this.reverseAdjacencyList.set(r,new Set);this.reverseAdjacencyList.get(r).add(e)}}getDependencies(n){return Array.from(this.adjacencyList.get(n)??[])}getDependents(n){return Array.from(this.reverseAdjacencyList.get(n)??[])}getTransitiveDependents(n){let t=new Set,e=[n];while(e.length>0){let r=e.shift();for(let i of this.reverseAdjacencyList.get(r)??[])if(!t.has(i))t.add(i),e.push(i)}return Array.from(t)}hasCycle(){let n=new Set,t=new Set;for(let e of this.adjacencyList.keys()){if(n.has(e))continue;let r=[{node:e,entered:!1}];while(r.length>0){let i=r.pop();if(i.entered){t.delete(i.node);continue}if(t.has(i.node))return!0;if(n.has(i.node))continue;n.add(i.node),t.add(i.node),r.push({node:i.node,entered:!0});for(let s of this.adjacencyList.get(i.node)??[]){if(t.has(s))return!0;if(!n.has(s))r.push({node:s,entered:!1})}}}return!1}getAffectedByChange(n){let t=new Set;for(let e of n)for(let r of this.getTransitiveDependents(e))t.add(r);return Array.from(t)}}var ct=30000,mt=60000,Xt=10;class Jn{projectRoot;db;symbolRepo;relationRepo;fileRepo;parseCache;coordinator;watcher;releaseWatcherRoleFn;parseSourceFn;extractSymbolsFn;extractRelationsFn;symbolSearchFn;relationSearchFn;logger;defaultProject;role;timer=null;signalHandlers=[];closed=!1;tsconfigPaths=null;boundaries=[];onIndexedCallbacks=new Set;constructor(n){this.projectRoot=n.projectRoot,this.db=n.db,this.symbolRepo=n.symbolRepo,this.relationRepo=n.relationRepo,this.fileRepo=n.fileRepo,this.parseCache=n.parseCache,this.coordinator=n.coordinator,this.watcher=n.watcher,this.releaseWatcherRoleFn=n.releaseWatcherRoleFn,this.parseSourceFn=n.parseSourceFn,this.extractSymbolsFn=n.extractSymbolsFn,this.extractRelationsFn=n.extractRelationsFn,this.symbolSearchFn=n.symbolSearchFn,this.relationSearchFn=n.relationSearchFn,this.logger=n.logger,this.defaultProject=n.defaultProject,this.role=n.role}static async open(n){let{projectRoot:t,extensions:e=[".ts",".mts",".cts"],ignorePatterns:r=[],parseCacheCapacity:i=500,logger:s=console,existsSyncFn:p=Qt,dbConnectionFactory:l,watcherFactory:c,coordinatorFactory:y,repositoryFactory:f,acquireWatcherRoleFn:x=it,releaseWatcherRoleFn:w=st,updateHeartbeatFn:A=ot,discoverProjectsFn:F=dn,parseSourceFn:E=rn,extractSymbolsFn:b=cn,extractRelationsFn:o=mn,symbolSearchFn:m=Mn,relationSearchFn:a=Ln,loadTsconfigPathsFn:g=on}=n;if(!at.isAbsolute(t))return T(k("validation",`Gildash: projectRoot must be an absolute path, got: "${t}"`));if(!p(t))return T(k("validation",`Gildash: projectRoot does not exist: "${t}"`));let h=l?l():new Pn({projectRoot:t}),d=h.open();if(tn(d))return d;try{let S=await F(t),P=S[0]?.project??at.basename(t),N=f?f():(()=>{let v=h;return{fileRepo:new Dn(v),symbolRepo:new Tn(v),relationRepo:new Fn(v),parseCache:new bn(i)}})(),R=await Promise.resolve(x(h,process.pid,{})),L=null,B=null,O=new Jn({projectRoot:t,db:h,symbolRepo:N.symbolRepo,relationRepo:N.relationRepo,fileRepo:N.fileRepo,parseCache:N.parseCache,coordinator:L,watcher:B,releaseWatcherRoleFn:w,parseSourceFn:E,extractSymbolsFn:b,extractRelationsFn:o,symbolSearchFn:m,relationSearchFn:a,logger:s,defaultProject:P,role:R});if(fn(t),O.tsconfigPaths=await g(t),O.boundaries=S,R==="owner"){let v=c?c():new pn({projectRoot:t,ignorePatterns:r,extensions:e},void 0,s),J=y?y():new gn({projectRoot:t,boundaries:S,extensions:e,ignorePatterns:r,dbConnection:h,parseCache:N.parseCache,fileRepo:N.fileRepo,symbolRepo:N.symbolRepo,relationRepo:N.relationRepo,logger:s});O.coordinator=J,O.watcher=v,await v.start(($)=>J.handleWatcherEvent?.($)).then(($)=>{if(tn($))throw $.data});let en=setInterval(()=>{A(h,process.pid)},ct);O.timer=en,await J.fullIndex()}else{let v=0,J=async()=>{try{let $=await Promise.resolve(x(h,process.pid,{}));if(v=0,$==="owner"){clearInterval(O.timer),O.timer=null;let H=null,Q=null;try{H=c?c():new pn({projectRoot:t,ignorePatterns:r,extensions:e},void 0,s),Q=y?y():new gn({projectRoot:t,boundaries:S,extensions:e,ignorePatterns:r,dbConnection:h,parseCache:N.parseCache,fileRepo:N.fileRepo,symbolRepo:N.symbolRepo,relationRepo:N.relationRepo,logger:s});for(let z of O.onIndexedCallbacks)Q.onIndexed(z);await H.start((z)=>Q?.handleWatcherEvent?.(z)).then((z)=>{if(tn(z))throw z.data});let yn=setInterval(()=>{A(h,process.pid)},ct);O.timer=yn,O.coordinator=Q,O.watcher=H,await Q.fullIndex()}catch(yn){if(s.error("[Gildash] owner promotion failed, reverting to reader",yn),H){let z=await H.close();if(tn(z))s.error("[Gildash] watcher close error during promotion rollback",z.data);O.watcher=null}if(Q)await Q.shutdown().catch((z)=>s.error("[Gildash] coordinator shutdown error during promotion rollback",z)),O.coordinator=null;if(O.timer===null)O.timer=setInterval(J,mt)}}}catch($){if(v++,s.error("[Gildash] healthcheck error",$),v>=Xt)s.error("[Gildash] healthcheck failed too many times, shutting down"),clearInterval(O.timer),O.timer=null,O.close().catch((H)=>s.error("[Gildash] close error during healthcheck shutdown",H))}},en=setInterval(J,mt);O.timer=en}let W=["SIGTERM","SIGINT","beforeExit"];for(let v of W){let J=()=>{O.close().catch((en)=>s.error("[Gildash] close error during signal",v,en))};if(v==="beforeExit")process.on("beforeExit",J);else process.on(v,J);O.signalHandlers.push([v,J])}return O}catch(S){return h.close(),T(k("store","Gildash: initialization failed",S))}}async close(){if(this.closed)return;this.closed=!0;let n=[];for(let[t,e]of this.signalHandlers)if(t==="beforeExit")process.off("beforeExit",e);else process.off(t,e);if(this.signalHandlers=[],this.coordinator)try{await this.coordinator.shutdown()}catch(t){n.push(t instanceof Error?t:Error(String(t)))}if(this.watcher){let t=await this.watcher.close();if(tn(t))n.push(t.data)}if(this.timer!==null)clearInterval(this.timer),this.timer=null;try{this.releaseWatcherRoleFn(this.db,process.pid)}catch(t){n.push(t instanceof Error?t:Error(String(t)))}try{this.db.close()}catch(t){n.push(t instanceof Error?t:Error(String(t)))}if(n.length>0)return T(k("close","Gildash: one or more errors occurred during close()",n))}onIndexed(n){if(this.onIndexedCallbacks.add(n),!this.coordinator)return()=>{this.onIndexedCallbacks.delete(n)};let t=this.coordinator.onIndexed(n);return()=>{this.onIndexedCallbacks.delete(n),t()}}parseSource(n,t){if(this.closed)return T(k("closed","Gildash: instance is closed"));let e=this.parseSourceFn(n,t);if(tn(e))return e;return this.parseCache.set(n,e),e}extractSymbols(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));return this.extractSymbolsFn(n)}extractRelations(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));return this.extractRelationsFn(n.program,n.filePath,this.tsconfigPaths??void 0)}async reindex(){if(this.closed)return T(k("closed","Gildash: instance is closed"));if(!this.coordinator)return T(k("closed","Gildash: reindex() is not available for readers"));try{return await this.coordinator.fullIndex()}catch(n){return T(k("index","Gildash: reindex failed",n))}}get projects(){return[...this.boundaries]}getStats(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.symbolRepo.getStats(n??this.defaultProject)}catch(t){return T(k("store","Gildash: getStats failed",t))}}searchSymbols(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:this.defaultProject,query:n})}catch(t){return T(k("search","Gildash: searchSymbols failed",t))}}searchRelations(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:this.defaultProject,query:n})}catch(t){return T(k("search","Gildash: searchRelations failed",t))}}getDependencies(n,t,e=1e4){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{srcFilePath:n,type:"imports",project:t??this.defaultProject,limit:e}}).map((r)=>r.dstFilePath)}catch(r){return T(k("search","Gildash: getDependencies failed",r))}}getDependents(n,t,e=1e4){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{dstFilePath:n,type:"imports",project:t??this.defaultProject,limit:e}}).map((r)=>r.srcFilePath)}catch(r){return T(k("search","Gildash: getDependents failed",r))}}async getAffected(n,t){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{let e=new an({relationRepo:this.relationRepo,project:t??this.defaultProject});return await e.build(),e.getAffectedByChange(n)}catch(e){return T(k("search","Gildash: getAffected failed",e))}}async hasCycle(n){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{let t=new an({relationRepo:this.relationRepo,project:n??this.defaultProject});return await t.build(),t.hasCycle()}catch(t){return T(k("search","Gildash: hasCycle failed",t))}}getParsedAst(n){if(this.closed)return;return this.parseCache.get(n)}getFileInfo(n,t){if(this.closed)return T(k("closed","Gildash: instance is closed"));try{return this.fileRepo.getFile(t??this.defaultProject,n)}catch(e){return T(k("store","Gildash: getFileInfo failed",e))}}getSymbolsByFile(n,t){return this.searchSymbols({filePath:n,project:t??void 0,limit:1e4})}}export{Mn as symbolSearch,Ln as relationSearch,k as gildashError,Jn as Gildash,an as DependencyGraph};
2
+ var dt=Object.defineProperty;var xt=(n,t)=>{for(var e in t)dt(n,e,{get:t[e],enumerable:!0,configurable:!0,set:(i)=>t[e]=()=>i})};import{err as S,isErr as en}from"@zipbul/result";import Sn from"path";import{existsSync as te}from"fs";import{err as yt}from"@zipbul/result";import{parseSync as bt}from"oxc-parser";function d(n,t,e){return e!==void 0?{type:n,message:t,cause:e}:{type:n,message:t}}function an(n,t,e=bt){try{let{program:i,errors:r,comments:s}=e(n,t);return{filePath:n,program:i,errors:r,comments:s,sourceText:t}}catch(i){return yt(d("parse",`Failed to parse file: ${n}`,i))}}class Nn{#t;#n=new Map;constructor(n){this.#t=Math.max(1,n)}get size(){return this.#n.size}has(n){return this.#n.has(n)}get(n){if(!this.#n.has(n))return;let t=this.#n.get(n);return this.#n.delete(n),this.#n.set(n,t),t}set(n,t){if(this.#n.has(n))this.#n.delete(n);if(this.#n.set(n,t),this.#n.size>this.#t){let e=this.#n.keys().next().value;if(e!==void 0)this.#n.delete(e)}}delete(n){return this.#n.delete(n)}clear(){this.#n.clear()}}class kn{lru;constructor(n=500){this.lru=new Nn(n)}get(n){return this.lru.get(n)}set(n,t){this.lru.set(n,t)}invalidate(n){this.lru.delete(n)}invalidateAll(){this.lru.clear()}size(){return this.lru.size}}function Un(n){let t=[0];for(let e=0;e<n.length;e++)if(n[e]===`
3
+ `)t.push(e+1);return t}function An(n,t){let e=0,i=n.length-1;while(e<i){let r=e+i+1>>1;if(n[r]<=t)e=r;else i=r-1}return{line:e+1,column:t-n[e]}}import{err as wt}from"@zipbul/result";import{parse as St}from"comment-parser";function Qn(n){try{let t=n.trim();if(t.startsWith("/**"))t=t.slice(3);if(t.endsWith("*/"))t=t.slice(0,-2);let i=St(`/** ${t} */`)[0]??{description:"",tags:[]};return{description:(i.description??"").trim(),tags:(i.tags??[]).map((r)=>({tag:r.tag??"",name:r.name??"",type:r.type??"",description:r.description??"",optional:r.optional??!1,...r.default!==void 0?{default:r.default}:{}}))}}catch(t){return wt(d("parse","Failed to parse JSDoc comment",t))}}import{isErr as Ot}from"@zipbul/result";function ln(n){let{program:t,sourceText:e,comments:i}=n,r=Un(e);function s(l,g){return{start:An(r,l),end:An(r,g)}}function u(l){let g=null;for(let o of i){if(o.type!=="Block")continue;if(o.end>l)continue;if(!o.value.startsWith("*"))continue;if(!g||o.end>g.end)g={value:`/*${o.value}*/`,end:o.end}}if(!g)return;for(let o of t.body){let c=o.start??0;if(c===l)continue;if(c>g.end&&c<l)return}return g.value}function m(l){if(!l)return;let g=l.typeAnnotation??l;return e.slice(g.start,g.end)}function a(l){if(!l||l.length===0)return[];return l.map((g)=>{let o=g.expression;if(!o)return{name:"unknown"};if(o.type==="CallExpression"){let c=o.callee?.name??o.callee?.property?.name??"unknown",f=(o.arguments??[]).map((O)=>e.slice(O.start,O.end));return{name:c,arguments:f.length>0?f:void 0}}if(o.type==="Identifier")return{name:o.name??"unknown"};return{name:e.slice(o.start,o.end)}})}function x(l){let g=l.type==="TSParameterProperty"?l.parameter:l;if(g?.type==="RestElement"){let k=`...${g.argument?.name??"unknown"}`,J=g.typeAnnotation,K=J?m(J):void 0,I={name:k,isOptional:!1};if(K)I.type=K;return I}if(g?.type==="AssignmentPattern"){let{left:h,right:k}=g,J=h?.name??"unknown",K=h?.typeAnnotation,I=K?m(K):void 0,$=e.slice(k.start,k.end),rn=a(h?.decorators??[]),Z={name:J,isOptional:!0,defaultValue:$};if(I)Z.type=I;if(rn.length>0)Z.decorators=rn;return Z}let o=g?.name??g?.pattern?.name??"unknown",c=!!g?.optional,f=g?.typeAnnotation,O=f?m(f):void 0,A=a(g?.decorators??[]),C={name:o,isOptional:c};if(O)C.type=O;if(A.length>0)C.decorators=A;return C}function p(l,g){let o=[];if(g?.async)o.push("async");if(l.static)o.push("static");if(l.abstract)o.push("abstract");if(l.readonly)o.push("readonly");if(l.override)o.push("override");if(l.declare)o.push("declare");if(l.const)o.push("const");let c=l.accessibility;if(c==="private")o.push("private");else if(c==="protected")o.push("protected");else if(c==="public")o.push("public");return o}function y(l){let g=[];if(l.superClass){let c=e.slice(l.superClass.start,l.superClass.end);g.push({kind:"extends",name:c})}let o=l.implements??[];for(let c of o){let f=c.expression??c,O=e.slice(f.start,f.end);g.push({kind:"implements",name:O})}return g}function w(l){let g=[];for(let o of l.extends??[]){let c=o.expression??o,f=e.slice(c.start,c.end);g.push({kind:"extends",name:f})}return g}function N(l){let g=[];for(let o of l)if(o.type==="MethodDefinition"){let c=o.key?.name??"unknown",f=o.value,O=o.kind??"method",A=O==="constructor"?"constructor":O==="get"?"getter":O==="set"?"setter":"method",C=p(o,f),h=(f?.params??[]).map(x),k=m(f?.returnType),J={kind:"method",name:c,span:s(o.start,o.end),isExported:!1,methodKind:A,modifiers:C,parameters:h.length>0?h:void 0,returnType:k};g.push(J)}else if(o.type==="PropertyDefinition"){let c=o.key?.name??"unknown",f=p(o),O={kind:"property",name:c,span:s(o.start,o.end),isExported:!1,modifiers:f};g.push(O)}return g}function _(l){let g=[];for(let o of l)if(o.type==="TSMethodSignature"){let c=o.key?.name??"unknown",f=(o.params??[]).map(x),O=m(o.returnType);g.push({kind:"method",name:c,span:s(o.start,o.end),isExported:!1,modifiers:[],methodKind:"method",parameters:f.length>0?f:void 0,returnType:O})}else if(o.type==="TSPropertySignature"){let c=o.key?.name??"unknown",f=m(o.typeAnnotation),O={kind:"property",name:c,span:s(o.start,o.end),isExported:!1,modifiers:o.readonly?["readonly"]:[],returnType:f};g.push(O)}return g}function D(l,g){let o=l.type??"";if(o==="FunctionDeclaration"){let c=l.id?.name??"default",f=(l.params??[]).map(x),O=m(l.returnType),A=p(l,l),C=a(l.decorators??[]),h=l.typeParameters?.params?.map((J)=>J.name?.name).filter(Boolean)||void 0,k={kind:"function",name:c,span:s(l.start,l.end),isExported:g,modifiers:A,parameters:f.length>0?f:void 0,returnType:O,decorators:C.length>0?C:void 0};if(h&&h.length>0)k.typeParameters=h;return k}if(o==="ClassDeclaration"||o==="ClassExpression"){let c=l.id?.name??"default",f=y(l),O=N(l.body?.body??[]),A=a(l.decorators??[]),C=p(l,l),h=l.typeParameters?.params?.map((J)=>J.name?.name).filter(Boolean)||void 0,k={kind:"class",name:c,span:s(l.start,l.end),isExported:g,modifiers:C,heritage:f.length>0?f:void 0,members:O.length>0?O:void 0,decorators:A.length>0?A:void 0};if(h&&h.length>0)k.typeParameters=h;return k}if(o==="VariableDeclaration"){let c=[];for(let f of l.declarations??[]){let{id:O,init:A}=f;if(O?.type==="ObjectPattern"){for(let I of O.properties??[]){let $=I.value?.name??I.key?.name??"unknown";c.push({kind:"variable",name:$,span:s(I.start??f.start,I.end??f.end),isExported:g,modifiers:[]})}continue}if(O?.type==="ArrayPattern"){for(let I of O.elements??[]){if(!I||I.type!=="Identifier")continue;let $=I.name??"unknown";c.push({kind:"variable",name:$,span:s(I.start??f.start,I.end??f.end),isExported:g,modifiers:[]})}continue}let C=O?.name??"unknown",h="variable",k,J;if(A?.type==="FunctionExpression"||A?.type==="ArrowFunctionExpression")h="function",k=(A.params??[]).map(x),J=m(A.returnType);let K=[];c.push({kind:h,name:C,span:s(f.start,f.end),isExported:g,modifiers:K,parameters:k,returnType:J})}if(c.length===0)return null;if(c.length===1)return c[0];return c}if(o==="TSTypeAliasDeclaration")return{kind:"type",name:l.id?.name??"unknown",span:s(l.start,l.end),isExported:g,modifiers:[]};if(o==="TSInterfaceDeclaration"){let c=l.id?.name??"unknown",f=w(l),O=_(l.body?.body??[]),A=l.typeParameters?.params?.map((h)=>h.name?.name).filter(Boolean)||void 0,C={kind:"interface",name:c,span:s(l.start,l.end),isExported:g,modifiers:[],heritage:f.length>0?f:void 0,members:O.length>0?O:void 0};if(A&&A.length>0)C.typeParameters=A;return C}if(o==="TSEnumDeclaration"){let c=l.id?.name??"unknown",f=p(l),A=(l.body?.members??[]).map((C)=>({kind:"property",name:C.id?.name??C.id?.value??"unknown",span:s(C.start,C.end),isExported:!1,modifiers:[]}));return{kind:"enum",name:c,span:s(l.start,l.end),isExported:g,modifiers:f,members:A.length>0?A:void 0}}return null}let M=[];for(let l of t.body){let g=null,o=l,c=typeof o.type==="string"?o.type:"";if(c==="ExportNamedDeclaration"){let O=l;if(O.declaration){if(g=D(O.declaration,!0),g&&!Array.isArray(g))g.span=s(O.start,O.end);else if(Array.isArray(g))for(let A of g)A.span=s(O.start,O.end)}}else if(c==="ExportDefaultDeclaration"){let O=l,A=O.declaration;if(A){if(g=D(A,!0),g&&!Array.isArray(g))g.name=A.id?.name??"default",g.isExported=!0,g.span=s(O.start,O.end)}}else g=D(l,!1);let f=Array.isArray(g)?g:g?[g]:[];for(let O of f){let A=l.start??0,C=u(A);if(C){let h=Qn(C);if(!Ot(h))O.jsDoc=h}M.push(O)}}return M}import{resolve as Dn,dirname as Nt,extname as kt}from"path";function hn(n,t,e){let i=(r)=>{let s=kt(r);if(s==="")return[r+".ts",r+"/index.ts",r+".mts",r+"/index.mts",r+".cts",r+"/index.cts"];if(s===".js")return[r.slice(0,-3)+".ts"];if(s===".mjs")return[r.slice(0,-4)+".mts"];if(s===".cjs")return[r.slice(0,-4)+".cts"];return[r]};if(t.startsWith(".")){let r=Dn(Nt(n),t);return i(r)}if(e)for(let[r,s]of e.paths){if(s.length===0)continue;let u=r.indexOf("*");if(u===-1){if(t===r){let m=[];for(let a of s)m.push(...i(Dn(e.baseUrl,a)));return m}}else{let m=r.slice(0,u),a=r.slice(u+1);if(t.startsWith(m)&&(a===""||t.endsWith(a))){let x=t.slice(m.length,a===""?void 0:t.length-a.length),p=[];for(let y of s)p.push(...i(Dn(e.baseUrl,y.replace("*",x))));return p}}}return[]}function Vn(n,t,e,i=hn){let r=new Map,s=n.body??[];for(let u of s){if(u.type!=="ImportDeclaration")continue;let m=u.source?.value??"",a=i(t,m,e);if(a.length===0)continue;let x=a[0],p=u.specifiers??[];for(let y of p)switch(y.type){case"ImportSpecifier":r.set(y.local.name,{path:x,importedName:y.imported.name});break;case"ImportDefaultSpecifier":r.set(y.local.name,{path:x,importedName:"default"});break;case"ImportNamespaceSpecifier":r.set(y.local.name,{path:x,importedName:"*"});break}}return r}var At=new Set(["loc","start","end","scope"]);function sn(n,t){if(!n||typeof n!=="object")return;if(Array.isArray(n)){for(let i of n)sn(i,t);return}let e=n;t(e);for(let i of Object.keys(e)){if(At.has(i))continue;let r=e[i];if(r&&typeof r==="object")sn(r,t)}}function Yn(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n;if((t.type==="StringLiteral"||t.type==="Literal")&&typeof t.value==="string")return t.value;return null}function q(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n;if(t.type==="Identifier"){let e=t.name;return{root:e,parts:[],full:e}}if(t.type==="ThisExpression")return{root:"this",parts:[],full:"this"};if(t.type==="Super")return{root:"super",parts:[],full:"super"};if(t.type==="MemberExpression"){let e=[],i=t;while(i.type==="MemberExpression"){let u=i.property;if(!u||typeof u.name!=="string")return null;e.unshift(u.name),i=i.object}let r;if(i.type==="Identifier")r=i.name;else if(i.type==="ThisExpression")r="this";else if(i.type==="Super")r="super";else return null;let s=[r,...e].join(".");return{root:r,parts:e,full:s}}return null}function Zn(n,t,e,i=hn){let r=[],s=n.body??[];for(let u of s){if(u.type==="ImportDeclaration"){let m=u.source?.value??"",a=i(t,m,e);if(a.length===0)continue;let x=a[0],p=u.importKind==="type",y=u.specifiers??[];if(y.length===0){let w={};if(p)w.isType=!0;r.push({type:p?"type-references":"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:x,dstSymbolName:null,...Object.keys(w).length>0?{metaJson:JSON.stringify(w)}:{}})}else for(let w of y){let N=w.type,_=p||w.importKind==="type",D={};if(_)D.isType=!0;let M,l;if(N==="ImportDefaultSpecifier")M="default",l=w.local.name;else if(N==="ImportNamespaceSpecifier")M="*",l=w.local.name,D.importKind="namespace";else M=w.imported.name,l=w.local.name;r.push({type:_?"type-references":"imports",srcFilePath:t,srcSymbolName:l,dstFilePath:x,dstSymbolName:M,...Object.keys(D).length>0?{metaJson:JSON.stringify(D)}:{}})}continue}if(u.type==="ExportAllDeclaration"&&u.source){let m=u.source?.value??"",a=i(t,m,e);if(a.length===0)continue;let x=a[0],p=u.exportKind==="type",y={isReExport:!0};if(p)y.isType=!0;r.push({type:p?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:x,dstSymbolName:null,metaJson:JSON.stringify(y)});continue}if(u.type==="ExportNamedDeclaration"&&u.source){let m=u.source?.value??"",a=i(t,m,e);if(a.length===0)continue;let x=a[0],p=u.exportKind==="type",N={isReExport:!0,specifiers:(u.specifiers??[]).map((_)=>({local:_.local.name,exported:_.exported.name}))};if(p)N.isType=!0;r.push({type:p?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:x,dstSymbolName:null,metaJson:JSON.stringify(N)})}}return sn(n,(u)=>{if(u.type!=="ImportExpression")return;let m=Yn(u.source);if(!m)return;let a=i(t,m,e);if(a.length===0)return;let x=a[0];r.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:x,dstSymbolName:null,metaJson:JSON.stringify({isDynamic:!0})})}),r}function vn(n,t,e){let i=[],r=[],s=[];function u(){if(r.length>0)return r[r.length-1]??null;return null}function m(x){if(!x)return null;let p=e.get(x.root);if(x.parts.length===0){if(p)return{dstFilePath:p.path,dstSymbolName:p.importedName,resolution:"import"};return{dstFilePath:t,dstSymbolName:x.root,resolution:"local"}}else{if(p&&p.importedName==="*"){let y=x.parts[x.parts.length-1];return{dstFilePath:p.path,dstSymbolName:y,resolution:"namespace"}}return{dstFilePath:t,dstSymbolName:x.full,resolution:"local-member"}}}function a(x){if(!x||typeof x!=="object")return;if(Array.isArray(x)){for(let w of x)a(w);return}let p=x,y=typeof p.type==="string"?p.type:"";if(y==="ClassDeclaration"||y==="ClassExpression"){let w=p,N=w.id?.name??"AnonymousClass";s.push(N),a(w.body),s.pop();return}if(y==="FunctionDeclaration"){let w=p,N=w.id?.name??"anonymous";r.push(N),a(w.body),r.pop();return}if(y==="VariableDeclarator"&&p.init&&(p.init?.type==="FunctionExpression"||p.init?.type==="ArrowFunctionExpression")){let w=p,N=w.id?.name??"anonymous";r.push(N),a(w.init?.body??w.init),r.pop();return}if(y==="MethodDefinition"&&p.value){let w=p,N=s[s.length-1]??"",_=w.key?.name??"anonymous",D=N?`${N}.${_}`:_;r.push(D),a(w.value?.body),r.pop();return}if(y==="FunctionExpression"||y==="ArrowFunctionExpression"){let w=u(),N=w?`${w}.<anonymous>`:"<anonymous>";r.push(N),a(p.body),r.pop();return}if(y==="CallExpression"){let w=p,N=q(w.callee),_=m(N);if(_){let D=u(),M={};if(D===null)M.scope="module";i.push({type:"calls",srcFilePath:t,srcSymbolName:D,dstFilePath:_.dstFilePath,dstSymbolName:_.dstSymbolName,...Object.keys(M).length>0?{metaJson:JSON.stringify(M)}:{}})}a(w.callee);for(let D of w.arguments??[])a(D);return}if(y==="NewExpression"){let w=p,N=q(w.callee),_=m(N);if(_){let D=u(),M={isNew:!0};if(D===null)M.scope="module";i.push({type:"calls",srcFilePath:t,srcSymbolName:D,dstFilePath:_.dstFilePath,dstSymbolName:_.dstSymbolName,metaJson:JSON.stringify(M)})}for(let D of w.arguments??[])a(D);return}for(let w of Object.keys(p)){if(w==="loc"||w==="start"||w==="end"||w==="scope")continue;let N=p[w];if(N&&typeof N==="object")a(N)}}return a(n),i}function Xn(n,t,e){let i=[];return sn(n,(r)=>{if(r.type==="TSInterfaceDeclaration"){let m=r.id?.name??"AnonymousInterface",a=r.extends??[];for(let x of a){let p=x.expression??x,y=q(p);if(!y)continue;let w=Fn(y,t,e);i.push({type:"extends",srcFilePath:t,srcSymbolName:m,...w})}return}if(r.type!=="ClassDeclaration"&&r.type!=="ClassExpression")return;let s=r.id?.name??"AnonymousClass";if(r.superClass){let m=q(r.superClass);if(m){let a=Fn(m,t,e);i.push({type:"extends",srcFilePath:t,srcSymbolName:s,...a})}}let u=r.implements??[];for(let m of u){let a=m.expression??m,x=q(a);if(!x)continue;let p=Fn(x,t,e);i.push({type:"implements",srcFilePath:t,srcSymbolName:s,...p})}}),i}function Fn(n,t,e){let i=e.get(n.root);if(i){if(i.importedName==="*"){let r=n.parts[n.parts.length-1]??n.root;return{dstFilePath:i.path,dstSymbolName:r,metaJson:JSON.stringify({isNamespaceImport:!0})}}return{dstFilePath:i.path,dstSymbolName:n.parts.length>0?n.full:i.importedName}}return{dstFilePath:t,dstSymbolName:n.full,metaJson:JSON.stringify({isLocal:!0})}}function pn(n,t,e){let i=Vn(n,t,e),r=Zn(n,t,e),s=vn(n,t,i),u=Xn(n,t,i);return[...r,...s,...u]}import{err as Pn,isErr as Mt}from"@zipbul/result";import{Database as Jt}from"bun:sqlite";import{mkdirSync as Kt,unlinkSync as En,existsSync as jn}from"fs";import{dirname as It,join as qn}from"path";import{drizzle as Rt}from"drizzle-orm/bun-sqlite";import{migrate as zt}from"drizzle-orm/bun-sqlite/migrator";var Cn={};xt(Cn,{watcherOwner:()=>Ct,symbols:()=>F,relations:()=>b,files:()=>L});import{sql as Dt}from"drizzle-orm";import{sqliteTable as fn,text as T,integer as H,real as ht,index as nn,primaryKey as Ft,foreignKey as _n,check as _t}from"drizzle-orm/sqlite-core";var L=fn("files",{project:T("project").notNull(),filePath:T("file_path").notNull(),mtimeMs:ht("mtime_ms").notNull(),size:H("size").notNull(),contentHash:T("content_hash").notNull(),updatedAt:T("updated_at").notNull(),lineCount:H("line_count")},(n)=>[Ft({columns:[n.project,n.filePath]})]),F=fn("symbols",{id:H("id").primaryKey({autoIncrement:!0}),project:T("project").notNull(),filePath:T("file_path").notNull(),kind:T("kind").notNull(),name:T("name").notNull(),startLine:H("start_line").notNull(),startColumn:H("start_column").notNull(),endLine:H("end_line").notNull(),endColumn:H("end_column").notNull(),isExported:H("is_exported").notNull().default(0),signature:T("signature"),fingerprint:T("fingerprint"),detailJson:T("detail_json"),contentHash:T("content_hash").notNull(),indexedAt:T("indexed_at").notNull()},(n)=>[nn("idx_symbols_project_file").on(n.project,n.filePath),nn("idx_symbols_project_kind").on(n.project,n.kind),nn("idx_symbols_project_name").on(n.project,n.name),nn("idx_symbols_fingerprint").on(n.project,n.fingerprint),_n({columns:[n.project,n.filePath],foreignColumns:[L.project,L.filePath]}).onDelete("cascade")]),b=fn("relations",{id:H("id").primaryKey({autoIncrement:!0}),project:T("project").notNull(),type:T("type").notNull(),srcFilePath:T("src_file_path").notNull(),srcSymbolName:T("src_symbol_name"),dstFilePath:T("dst_file_path").notNull(),dstSymbolName:T("dst_symbol_name"),metaJson:T("meta_json")},(n)=>[nn("idx_relations_src").on(n.project,n.srcFilePath),nn("idx_relations_dst").on(n.project,n.dstFilePath),nn("idx_relations_type").on(n.project,n.type),_n({columns:[n.project,n.srcFilePath],foreignColumns:[L.project,L.filePath]}).onDelete("cascade"),_n({columns:[n.project,n.dstFilePath],foreignColumns:[L.project,L.filePath]}).onDelete("cascade")]),Ct=fn("watcher_owner",{id:H("id").primaryKey(),pid:H("pid").notNull(),startedAt:T("started_at").notNull(),heartbeatAt:T("heartbeat_at").notNull()},(n)=>[_t("watcher_owner_singleton",Dt`${n.id} = 1`)]);class Mn{client=null;drizzle=null;dbPath;txDepth=0;constructor(n){this.dbPath=qn(n.projectRoot,".zipbul","gildash.db")}get drizzleDb(){if(!this.drizzle)throw Error("Database is not open. Call open() first.");return this.drizzle}open(){try{Kt(It(this.dbPath),{recursive:!0}),this.client=new Jt(this.dbPath),this.client.run("PRAGMA journal_mode = WAL"),this.client.run("PRAGMA foreign_keys = ON"),this.client.run("PRAGMA busy_timeout = 5000"),this.drizzle=Rt(this.client,{schema:Cn}),zt(this.drizzle,{migrationsFolder:qn(import.meta.dirname,"migrations")});let n=this.client;if(typeof n.function==="function")n.function.call(this.client,"regexp",(t,e)=>{try{return new RegExp(t).test(e)?1:0}catch{return 0}})}catch(n){if(this.isCorruptionError(n)&&jn(this.dbPath)){this.closeClient(),En(this.dbPath);for(let e of["-wal","-shm"]){let i=this.dbPath+e;if(jn(i))En(i)}let t=this.open();if(Mt(t))return Pn(d("store",`Failed to recover database at ${this.dbPath}`,t.data));return t}return Pn(d("store",`Failed to open database at ${this.dbPath}`,n))}}close(){this.closeClient(),this.drizzle=null}transaction(n){let t=this.requireClient();if(this.txDepth===0){this.txDepth++;try{return t.transaction(()=>n(this))()}finally{this.txDepth--}}let e=`sp_${this.txDepth++}`;t.run(`SAVEPOINT "${e}"`);try{let i=n(this);return t.run(`RELEASE SAVEPOINT "${e}"`),i}catch(i){throw t.run(`ROLLBACK TO SAVEPOINT "${e}"`),t.run(`RELEASE SAVEPOINT "${e}"`),i}finally{this.txDepth--}}immediateTransaction(n){let t=this.requireClient();this.txDepth++,t.run("BEGIN IMMEDIATE");try{let e=n();return t.run("COMMIT"),e}catch(e){throw t.run("ROLLBACK"),e}finally{this.txDepth--}}query(n){let t=this.requireClient().prepare(n).get();if(!t)return null;return Object.values(t)[0]}getTableNames(){return this.requireClient().query("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((t)=>t.name)}selectOwner(){return this.requireClient().prepare("SELECT pid, heartbeat_at FROM watcher_owner WHERE id = 1").get()??void 0}insertOwner(n){let t=new Date().toISOString();this.requireClient().prepare("INSERT INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)").run(n,t,t)}replaceOwner(n){let t=new Date().toISOString();this.requireClient().prepare("INSERT OR REPLACE INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)").run(n,t,t)}touchOwner(n){let t=new Date().toISOString();this.requireClient().prepare("UPDATE watcher_owner SET heartbeat_at = ? WHERE id = 1 AND pid = ?").run(t,n)}deleteOwner(n){this.requireClient().prepare("DELETE FROM watcher_owner WHERE id = 1 AND pid = ?").run(n)}requireClient(){if(!this.client)throw Error("Database is not open. Call open() first.");return this.client}closeClient(){if(this.client)this.client.close(),this.client=null}isCorruptionError(n){if(!(n instanceof Error))return!1;let t=n.message.toLowerCase();return t.includes("malformed")||t.includes("corrupt")||t.includes("not a database")||t.includes("disk i/o error")||t.includes("sqlite_corrupt")}}import{eq as un,and as nt}from"drizzle-orm";class Jn{db;constructor(n){this.db=n}getFile(n,t){return this.db.drizzleDb.select().from(L).where(nt(un(L.project,n),un(L.filePath,t))).get()??null}upsertFile(n){this.db.drizzleDb.insert(L).values({project:n.project,filePath:n.filePath,mtimeMs:n.mtimeMs,size:n.size,contentHash:n.contentHash,updatedAt:n.updatedAt,lineCount:n.lineCount??null}).onConflictDoUpdate({target:[L.project,L.filePath],set:{mtimeMs:n.mtimeMs,size:n.size,contentHash:n.contentHash,updatedAt:n.updatedAt,lineCount:n.lineCount??null}}).run()}getAllFiles(n){return this.db.drizzleDb.select().from(L).where(un(L.project,n)).all()}getFilesMap(n){let t=this.getAllFiles(n),e=new Map;for(let i of t)e.set(i.filePath,i);return e}deleteFile(n,t){this.db.drizzleDb.delete(L).where(nt(un(L.project,n),un(L.filePath,t))).run()}}import{eq as B,and as tn,sql as dn,count as Tt}from"drizzle-orm";function gn(n){return n.trim().split(/\s+/).map((t)=>t.trim()).filter((t)=>t.length>0).map((t)=>`"${t.replaceAll('"','""')}"*`).join(" ")}class Kn{db;constructor(n){this.db=n}replaceFileSymbols(n,t,e,i){if(this.db.drizzleDb.delete(F).where(tn(B(F.project,n),B(F.filePath,t))).run(),!i.length)return;let r=new Date().toISOString();for(let s of i)this.db.drizzleDb.insert(F).values({project:n,filePath:t,kind:s.kind??"unknown",name:s.name??"",startLine:s.startLine??0,startColumn:s.startColumn??0,endLine:s.endLine??0,endColumn:s.endColumn??0,isExported:s.isExported??0,signature:s.signature??null,fingerprint:s.fingerprint??null,detailJson:s.detailJson??null,contentHash:e,indexedAt:s.indexedAt??r}).run()}getFileSymbols(n,t){return this.db.drizzleDb.select().from(F).where(tn(B(F.project,n),B(F.filePath,t))).all()}searchByName(n,t,e={}){let i=e.limit??50,r=gn(t);if(!r)return[];return this.db.drizzleDb.select().from(F).where(tn(dn`${F.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${r})`,B(F.project,n),e.kind?B(F.kind,e.kind):void 0)).orderBy(F.name).limit(i).all()}searchByKind(n,t){return this.db.drizzleDb.select().from(F).where(tn(B(F.project,n),B(F.kind,t))).orderBy(F.name).all()}getStats(n){let t=this.db.drizzleDb.select({symbolCount:Tt(),fileCount:dn`COUNT(DISTINCT ${F.filePath})`}).from(F).where(B(F.project,n)).get();return{symbolCount:t?.symbolCount??0,fileCount:t?.fileCount??0}}getByFingerprint(n,t){return this.db.drizzleDb.select().from(F).where(tn(B(F.project,n),B(F.fingerprint,t))).all()}deleteFileSymbols(n,t){this.db.drizzleDb.delete(F).where(tn(B(F.project,n),B(F.filePath,t))).run()}searchByQuery(n){let t=this.db.drizzleDb.select().from(F).where(tn(n.ftsQuery?dn`${F.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${n.ftsQuery})`:void 0,n.exactName?B(F.name,n.exactName):void 0,n.project!==void 0?B(F.project,n.project):void 0,n.kind?B(F.kind,n.kind):void 0,n.filePath!==void 0?B(F.filePath,n.filePath):void 0,n.isExported!==void 0?B(F.isExported,n.isExported?1:0):void 0,n.decorator?dn`${F.id} IN (SELECT s.id FROM symbols s, json_each(s.detail_json, '$.decorators') je WHERE json_extract(je.value, '$.name') = ${n.decorator})`:void 0)).orderBy(F.name).limit(n.regex?Math.max(n.limit*50,5000):n.limit).all();if(!n.regex)return t;try{let e=new RegExp(n.regex);return t.filter((i)=>e.test(i.name)).slice(0,n.limit)}catch{return[]}}}import{eq as z,and as V,isNull as tt,or as Lt}from"drizzle-orm";class In{db;constructor(n){this.db=n}replaceFileRelations(n,t,e){if(this.db.drizzleDb.delete(b).where(V(z(b.project,n),z(b.srcFilePath,t))).run(),!e.length)return;for(let i of e)this.db.drizzleDb.insert(b).values({project:n,type:i.type??"unknown",srcFilePath:i.srcFilePath??t,srcSymbolName:i.srcSymbolName??null,dstFilePath:i.dstFilePath??"",dstSymbolName:i.dstSymbolName??null,metaJson:i.metaJson??null}).run()}getOutgoing(n,t,e){if(e!==void 0)return this.db.drizzleDb.select({project:b.project,type:b.type,srcFilePath:b.srcFilePath,srcSymbolName:b.srcSymbolName,dstFilePath:b.dstFilePath,dstSymbolName:b.dstSymbolName,metaJson:b.metaJson}).from(b).where(V(z(b.project,n),z(b.srcFilePath,t),Lt(z(b.srcSymbolName,e),tt(b.srcSymbolName)))).all();return this.db.drizzleDb.select({project:b.project,type:b.type,srcFilePath:b.srcFilePath,srcSymbolName:b.srcSymbolName,dstFilePath:b.dstFilePath,dstSymbolName:b.dstSymbolName,metaJson:b.metaJson}).from(b).where(V(z(b.project,n),z(b.srcFilePath,t))).all()}getIncoming(n,t){return this.db.drizzleDb.select({project:b.project,type:b.type,srcFilePath:b.srcFilePath,srcSymbolName:b.srcSymbolName,dstFilePath:b.dstFilePath,dstSymbolName:b.dstSymbolName,metaJson:b.metaJson}).from(b).where(V(z(b.project,n),z(b.dstFilePath,t))).all()}getByType(n,t){return this.db.drizzleDb.select({project:b.project,type:b.type,srcFilePath:b.srcFilePath,srcSymbolName:b.srcSymbolName,dstFilePath:b.dstFilePath,dstSymbolName:b.dstSymbolName,metaJson:b.metaJson}).from(b).where(V(z(b.project,n),z(b.type,t))).all()}deleteFileRelations(n,t){this.db.drizzleDb.delete(b).where(V(z(b.project,n),z(b.srcFilePath,t))).run()}searchRelations(n){return this.db.drizzleDb.select({project:b.project,type:b.type,srcFilePath:b.srcFilePath,srcSymbolName:b.srcSymbolName,dstFilePath:b.dstFilePath,dstSymbolName:b.dstSymbolName,metaJson:b.metaJson}).from(b).where(V(n.project!==void 0?z(b.project,n.project):void 0,n.srcFilePath!==void 0?z(b.srcFilePath,n.srcFilePath):void 0,n.srcSymbolName!==void 0?z(b.srcSymbolName,n.srcSymbolName):void 0,n.dstFilePath!==void 0?z(b.dstFilePath,n.dstFilePath):void 0,n.dstSymbolName!==void 0?z(b.dstSymbolName,n.dstSymbolName):void 0,n.type!==void 0?z(b.type,n.type):void 0)).limit(n.limit).all()}retargetRelations(n,t,e,i,r){let s=e===null?V(z(b.project,n),z(b.dstFilePath,t),tt(b.dstSymbolName)):V(z(b.project,n),z(b.dstFilePath,t),z(b.dstSymbolName,e));this.db.drizzleDb.update(b).set({dstFilePath:i,dstSymbolName:r}).where(s).run()}}import{err as et}from"@zipbul/result";import{subscribe as $t}from"@parcel/watcher";import Rn from"path";var Bt=["**/.git/**","**/.zipbul/**","**/dist/**","**/node_modules/**"],Gt=new Set(["package.json","tsconfig.json"]);function Wt(n){return n.replaceAll("\\","/")}function Ht(n){if(n==="update")return"change";if(n==="create")return"create";return"delete"}class xn{#t;#n;#i;#r;#s;#e;constructor(n,t=$t,e=console){this.#n=n.projectRoot,this.#i=[...Bt,...n.ignorePatterns??[]],this.#r=new Set((n.extensions??[".ts",".mts",".cts"]).map((i)=>i.toLowerCase())),this.#s=t,this.#e=e}async start(n){try{this.#t=await this.#s(this.#n,(t,e)=>{if(t){this.#e.error(d("watcher","Callback error",t));return}try{for(let i of e){let r=Wt(Rn.relative(this.#n,i.path));if(r.startsWith(".."))continue;let s=Rn.basename(r),u=Rn.extname(r).toLowerCase();if(!Gt.has(s)&&!this.#r.has(u))continue;if(r.endsWith(".d.ts"))continue;n({eventType:Ht(i.type),filePath:r})}}catch(i){this.#e.error(d("watcher","Callback error",i))}},{ignore:this.#i})}catch(t){return et(d("watcher","Failed to subscribe watcher",t))}}async close(){if(!this.#t)return;try{await this.#t.unsubscribe(),this.#t=void 0}catch(n){return et(d("watcher","Failed to close watcher",n))}}}import zn from"path";import{promises as Ut}from"fs";var Qt=["**/node_modules/**","**/.git/**","**/.zipbul/**","**/dist/**"];async function yn(n){let t=[];for await(let e of Ut.glob("**/package.json",{cwd:n,exclude:Qt})){let i=zn.dirname(e).replaceAll("\\","/"),r=zn.join(n,e),s=await Bun.file(r).json(),u=typeof s?.name==="string"&&s.name.length>0?s.name:zn.basename(i==="."?n:i);t.push({dir:i,project:u})}return t.sort((e,i)=>i.dir.length-e.dir.length),t}function Y(n,t,e="default"){let i=n.replaceAll("\\","/");for(let r of t){if(r.dir===".")return r.project;if(i===r.dir||i.startsWith(`${r.dir}/`))return r.project}return e}import it from"path";var X=new Map;async function Vt(n){let t=Bun.file(n);if(!await t.exists())return null;let e=await t.json();return typeof e==="object"&&e!==null?e:null}async function mn(n){if(X.has(n))return X.get(n)??null;let t=it.join(n,"tsconfig.json"),e=await Vt(t);if(!e)return X.set(n,null),null;let i=typeof e.compilerOptions==="object"&&e.compilerOptions!==null?e.compilerOptions:null;if(!i)return X.set(n,null),null;let r=typeof i.baseUrl==="string"?i.baseUrl:null,s=typeof i.paths==="object"&&i.paths!==null?i.paths:null;if(!r&&!s)return X.set(n,null),null;let u=r?it.resolve(n,r):n,m=new Map;if(s)for(let[x,p]of Object.entries(s)){if(!Array.isArray(p))continue;let y=p.filter((w)=>typeof w==="string");m.set(x,y)}let a={baseUrl:u,paths:m};return X.set(n,a),a}function bn(n){if(n){X.delete(n);return}X.clear()}import rt from"path";function Tn(n,t){return rt.relative(n,t).replaceAll("\\","/")}function on(n,t){return rt.resolve(n,t)}function P(n){let t=Bun.hash.xxHash64(n);return BigInt.asUintN(64,BigInt(t)).toString(16).padStart(16,"0")}import{isErr as at}from"@zipbul/result";import{promises as Yt}from"fs";import{join as Zt}from"path";async function st(n){let{projectRoot:t,extensions:e,ignorePatterns:i,fileRepo:r}=n,s=r.getFilesMap(),u=new Set,m=[],a=[],x=i.map((y)=>new Bun.Glob(y));for await(let y of Yt.glob("**/*",{cwd:t})){if(!e.some((o)=>y.endsWith(o)))continue;if(x.some((o)=>o.match(y)))continue;u.add(y);let w=Zt(t,y),N=Bun.file(w),{size:_,lastModified:D}=N,M=s.get(y);if(!M){let o=await N.text(),c=P(o);m.push({filePath:y,contentHash:c,mtimeMs:D,size:_});continue}if(M.mtimeMs===D&&M.size===_){a.push({filePath:y,contentHash:M.contentHash,mtimeMs:D,size:_});continue}let l=await N.text(),g=P(l);if(g===M.contentHash)a.push({filePath:y,contentHash:g,mtimeMs:D,size:_});else m.push({filePath:y,contentHash:g,mtimeMs:D,size:_})}let p=[];for(let y of s.keys())if(!u.has(y))p.push(y);return{changed:m,unchanged:a,deleted:p}}function vt(n){if(n.kind==="function"||n.kind==="method"){let t=n.parameters?.length??0,e=n.modifiers.includes("async")?1:0;return`params:${t}|async:${e}`}return null}function Xt(n){let t={};if(n.jsDoc)t.jsDoc=n.jsDoc;if(n.kind==="function"||n.kind==="method"){if(n.parameters!==void 0)t.parameters=n.parameters;if(n.returnType!==void 0)t.returnType=n.returnType}if(n.heritage?.length)t.heritage=n.heritage;if(n.decorators?.length)t.decorators=n.decorators;if(n.typeParameters?.length)t.typeParameters=n.typeParameters;if(n.modifiers?.length)t.modifiers=n.modifiers;if(n.members?.length)t.members=n.members.map((e)=>{let i=e.modifiers.find((r)=>r==="private"||r==="protected"||r==="public");return{name:e.name,kind:e.methodKind??e.kind,type:e.returnType,visibility:i,isStatic:e.modifiers.includes("static")||void 0,isReadonly:e.modifiers.includes("readonly")||void 0}});return Object.keys(t).length>0?JSON.stringify(t):null}function ot(n,t,e,i,r){let s=vt(n),u=P(`${t}|${n.kind}|${s??""}`);return{project:e,filePath:i,kind:n.kind,name:t,startLine:n.span.start.line,startColumn:n.span.start.column,endLine:n.span.end.line,endColumn:n.span.end.column,isExported:n.isExported?1:0,signature:s,fingerprint:u,detailJson:Xt(n),contentHash:r,indexedAt:new Date().toISOString()}}function Ln(n){let{parsed:t,project:e,filePath:i,contentHash:r,symbolRepo:s}=n,u=ln(t),m=[];for(let a of u){m.push(ot(a,a.name,e,i,r));for(let x of a.members??[])m.push(ot(x,`${a.name}.${x.name}`,e,i,r))}s.replaceFileSymbols(e,i,r,m)}function $n(n){let{ast:t,project:e,filePath:i,relationRepo:r,projectRoot:s,tsconfigPaths:u}=n,m=on(s,i),a=pn(t,m,u),x=[];for(let p of a){let y=Tn(s,p.dstFilePath);if(y.startsWith(".."))continue;let w=Tn(s,p.srcFilePath);x.push({project:e,type:p.type,srcFilePath:w,srcSymbolName:p.srcSymbolName??null,dstFilePath:y,dstSymbolName:p.dstSymbolName??null,metaJson:p.metaJson??null})}return r.replaceFileRelations(e,i,x),x.length}var Pt=100;class cn{opts;logger;callbacks=new Set;indexingLock=!1;pendingEvents=[];debounceTimer=null;currentIndexing=null;pendingFullIndex=!1;pendingFullIndexWaiters=[];tsconfigPathsRaw;boundariesRefresh=null;constructor(n){this.opts=n,this.logger=n.logger??console,this.tsconfigPathsRaw=mn(n.projectRoot)}get tsconfigPaths(){return this.tsconfigPathsRaw}fullIndex(){return this.startIndex(void 0,!0)}incrementalIndex(n){return this.startIndex(n,!1)}onIndexed(n){return this.callbacks.add(n),()=>this.callbacks.delete(n)}handleWatcherEvent(n){if(n.filePath.endsWith("tsconfig.json")){bn(this.opts.projectRoot),this.tsconfigPathsRaw=mn(this.opts.projectRoot),this.fullIndex().catch((t)=>{this.logger.error("[IndexCoordinator] fullIndex failed after tsconfig change:",t)});return}if(n.filePath.endsWith("package.json")){let t=this.opts.discoverProjectsFn??yn;this.boundariesRefresh=t(this.opts.projectRoot).then((e)=>{this.opts.boundaries=e})}if(this.pendingEvents.push(n),this.debounceTimer===null)this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.flushPending()},Pt)}async shutdown(){if(this.debounceTimer!==null)clearTimeout(this.debounceTimer),this.debounceTimer=null;if(this.currentIndexing)await this.currentIndexing}startIndex(n,t){if(this.indexingLock){if(t)return this.pendingFullIndex=!0,new Promise((i,r)=>{this.pendingFullIndexWaiters.push({resolve:i,reject:r})});return this.currentIndexing}this.indexingLock=!0;let e=this.doIndex(n,t).then((i)=>{return this.fireCallbacks(i),i}).finally(()=>{if(this.indexingLock=!1,this.currentIndexing=null,this.pendingFullIndex){this.pendingFullIndex=!1;let i=this.pendingFullIndexWaiters.splice(0);this.startIndex(void 0,!0).then((r)=>{for(let s of i)s.resolve(r)}).catch((r)=>{for(let s of i)s.reject(r)})}else if(this.pendingEvents.length>0){let i=this.pendingEvents.splice(0);this.startIndex(i,!1).catch((r)=>this.logger.error("[IndexCoordinator] incremental drain error",r))}});return this.currentIndexing=e,e}async doIndex(n,t){let e=Date.now(),{fileRepo:i,symbolRepo:r,relationRepo:s,dbConnection:u}=this.opts;if(this.boundariesRefresh)await this.boundariesRefresh,this.boundariesRefresh=null;let m,a;if(n!==void 0)m=n.filter((o)=>o.eventType==="create"||o.eventType==="change").map((o)=>({filePath:o.filePath,contentHash:"",mtimeMs:0,size:0})),a=n.filter((o)=>o.eventType==="delete").map((o)=>o.filePath);else{let o=new Map;for(let f of this.opts.boundaries)for(let[O,A]of i.getFilesMap(f.project))o.set(O,A);let c=await st({projectRoot:this.opts.projectRoot,extensions:this.opts.extensions,ignorePatterns:this.opts.ignorePatterns,fileRepo:{getFilesMap:()=>o}});m=c.changed,a=c.deleted}let x=await this.tsconfigPathsRaw??void 0,p=new Map;for(let o of a){let c=Y(o,this.opts.boundaries),f=r.getFileSymbols(c,o);p.set(o,f)}let y=new Map,w=new Map;if(t)for(let o of this.opts.boundaries)for(let c of i.getAllFiles(o.project))for(let f of r.getFileSymbols(o.project,c.filePath))y.set(`${f.filePath}::${f.name}`,{name:f.name,filePath:f.filePath,kind:f.kind,fingerprint:f.fingerprint});else{for(let o of m){let c=Y(o.filePath,this.opts.boundaries);for(let f of r.getFileSymbols(c,o.filePath))y.set(`${f.filePath}::${f.name}`,{name:f.name,filePath:f.filePath,kind:f.kind,fingerprint:f.fingerprint})}for(let[,o]of p)for(let c of o)y.set(`${c.filePath}::${c.name}`,{name:c.name,filePath:c.filePath,kind:c.kind,fingerprint:c.fingerprint})}let N=()=>{for(let o of a){let c=Y(o,this.opts.boundaries);r.deleteFileSymbols(c,o),s.deleteFileRelations(c,o),i.deleteFile(c,o)}},_=async()=>{let o=0,c=0,f=[];for(let O of m)try{let A=await this.processFile(O.filePath,O.contentHash||void 0,x);o+=A.symbolCount,c+=A.relCount}catch(A){this.logger.error(`[IndexCoordinator] Failed to index ${O.filePath}:`,A),f.push(O.filePath)}return{symbols:o,relations:c,failedFiles:f}},D=0,M=0,l=[];if(t){let{projectRoot:o,boundaries:c}=this.opts,{parseCache:f}=this.opts,O=await Promise.allSettled(m.map(async(h)=>{let k=on(o,h.filePath),J=Bun.file(k),K=await J.text(),I=h.contentHash||P(K);return{filePath:h.filePath,text:K,contentHash:I,mtimeMs:J.lastModified,size:J.size}})),A=O.filter((h)=>h.status==="fulfilled").map((h)=>h.value);for(let h of O)if(h.status==="rejected")this.logger.error("[IndexCoordinator] Failed to pre-read file:",h.reason);let C=[];u.transaction(()=>{for(let k of c){let J=i.getAllFiles(k.project);for(let K of J)i.deleteFile(K.project,K.filePath)}for(let k of A){let J=Y(k.filePath,c);i.upsertFile({project:J,filePath:k.filePath,mtimeMs:k.mtimeMs,size:k.size,contentHash:k.contentHash,updatedAt:new Date().toISOString(),lineCount:k.text.split(`
4
+ `).length})}let h=this.opts.parseSourceFn??an;for(let k of A){let J=Y(k.filePath,c),K=h(on(o,k.filePath),k.text);if(at(K))throw K.data;let I=K;C.push({filePath:k.filePath,parsed:I}),Ln({parsed:I,project:J,filePath:k.filePath,contentHash:k.contentHash,symbolRepo:r}),M+=$n({ast:I.program,project:J,filePath:k.filePath,relationRepo:s,projectRoot:o,tsconfigPaths:x}),D+=r.getFileSymbols(J,k.filePath).length}});for(let h of C)f.set(h.filePath,h.parsed)}else{N();let o=await _();D=o.symbols,M=o.relations,l=o.failedFiles}for(let o of m){let c=Y(o.filePath,this.opts.boundaries);for(let f of r.getFileSymbols(c,o.filePath))w.set(`${f.filePath}::${f.name}`,{name:f.name,filePath:f.filePath,kind:f.kind,fingerprint:f.fingerprint})}let g={added:[],modified:[],removed:[]};for(let[o,c]of w){let f=y.get(o);if(!f)g.added.push({name:c.name,filePath:c.filePath,kind:c.kind});else if(f.fingerprint!==c.fingerprint)g.modified.push({name:c.name,filePath:c.filePath,kind:c.kind})}for(let[o,c]of y)if(!w.has(o))g.removed.push({name:c.name,filePath:c.filePath,kind:c.kind});if(!t)for(let[o,c]of p)for(let f of c){if(!f.fingerprint)continue;let O=Y(o,this.opts.boundaries),A=r.getByFingerprint(O,f.fingerprint);if(A.length===1){let C=A[0];s.retargetRelations(O,o,f.name,C.filePath,C.name)}}return{indexedFiles:m.length,removedFiles:a.length,totalSymbols:D,totalRelations:M,durationMs:Date.now()-e,changedFiles:m.map((o)=>o.filePath),deletedFiles:[...a],failedFiles:l,changedSymbols:g}}async processFile(n,t,e){let{projectRoot:i,boundaries:r}=this.opts,{fileRepo:s,symbolRepo:u,relationRepo:m,parseCache:a}=this.opts,x=on(i,n),p=Bun.file(x),y=await p.text(),w=t||P(y),N=Y(n,r),D=(this.opts.parseSourceFn??an)(x,y);if(at(D))throw D.data;let M=D;a.set(n,M),s.upsertFile({project:N,filePath:n,mtimeMs:p.lastModified,size:p.size,contentHash:w,updatedAt:new Date().toISOString(),lineCount:y.split(`
5
+ `).length}),Ln({parsed:M,project:N,filePath:n,contentHash:w,symbolRepo:u});let l=$n({ast:M.program,project:N,filePath:n,relationRepo:m,projectRoot:i,tsconfigPaths:e});return{symbolCount:u.getFileSymbols(N,n).length,relCount:l}}fireCallbacks(n){for(let t of this.callbacks)try{t(n)}catch(e){this.logger.error("[IndexCoordinator] onIndexed callback threw:",e)}}flushPending(){if(this.indexingLock)return;if(this.pendingEvents.length>0){let n=this.pendingEvents.splice(0);this.startIndex(n,!1).catch((t)=>this.logger.error("[IndexCoordinator] flushPending startIndex error:",t))}}}function Et(n){try{return process.kill(n,0),!0}catch(t){if(typeof t==="object"&&t&&"code"in t)return t.code!=="ESRCH";return!0}}function jt(n){let t=new Date(n).getTime();return Number.isNaN(t)?0:t}function ut(n,t,e={}){let i=e.now??Date.now,r=e.isAlive??Et,s=e.staleAfterSeconds??90;return n.immediateTransaction(()=>{let u=n.selectOwner();if(!u)return n.insertOwner(t),"owner";let m=Math.floor((i()-jt(u.heartbeat_at))/1000);if(r(u.pid)&&m<s)return"reader";return n.replaceOwner(t),"owner"})}function mt(n,t){n.deleteOwner(t)}function ct(n,t){n.touchOwner(t)}function Bn(n){let{symbolRepo:t,project:e,query:i}=n,r=i.project??e,s=i.limit??100,u={kind:i.kind,filePath:i.filePath,isExported:i.isExported,project:r,limit:s};if(i.text)if(i.exact)u.exactName=i.text;else{let a=gn(i.text);if(a)u.ftsQuery=a}if(i.decorator)u.decorator=i.decorator;if(i.regex)u.regex=i.regex;return t.searchByQuery(u).map((a)=>({id:a.id,filePath:a.filePath,kind:a.kind,name:a.name,span:{start:{line:a.startLine,column:a.startColumn},end:{line:a.endLine,column:a.endColumn}},isExported:a.isExported===1,signature:a.signature,fingerprint:a.fingerprint,detail:a.detailJson?(()=>{try{return JSON.parse(a.detailJson)}catch{return{}}})():{}}))}function Gn(n){let{relationRepo:t,project:e,query:i}=n,r=i.project??e,s=i.limit??500;return t.searchRelations({srcFilePath:i.srcFilePath,srcSymbolName:i.srcSymbolName,dstFilePath:i.dstFilePath,dstSymbolName:i.dstSymbolName,type:i.type,project:r,limit:s}).map((m)=>{let a;if(m.metaJson)try{a=JSON.parse(m.metaJson)}catch{console.error("[relationSearch] malformed metaJson:",m.metaJson)}return{type:m.type,srcFilePath:m.srcFilePath,srcSymbolName:m.srcSymbolName,dstFilePath:m.dstFilePath,dstSymbolName:m.dstSymbolName,metaJson:m.metaJson??void 0,meta:a}})}class wn{options;adjacencyList=new Map;reverseAdjacencyList=new Map;constructor(n){this.options=n}build(){this.adjacencyList=new Map,this.reverseAdjacencyList=new Map;let n=[...this.options.relationRepo.getByType(this.options.project,"imports"),...this.options.relationRepo.getByType(this.options.project,"type-references"),...this.options.relationRepo.getByType(this.options.project,"re-exports")];for(let t of n){let{srcFilePath:e,dstFilePath:i}=t;if(!this.adjacencyList.has(e))this.adjacencyList.set(e,new Set);if(this.adjacencyList.get(e).add(i),!this.adjacencyList.has(i))this.adjacencyList.set(i,new Set);if(!this.reverseAdjacencyList.has(i))this.reverseAdjacencyList.set(i,new Set);this.reverseAdjacencyList.get(i).add(e)}}getDependencies(n){return Array.from(this.adjacencyList.get(n)??[])}getDependents(n){return Array.from(this.reverseAdjacencyList.get(n)??[])}getTransitiveDependents(n){let t=new Set,e=[n];while(e.length>0){let i=e.shift();for(let r of this.reverseAdjacencyList.get(i)??[])if(!t.has(r))t.add(r),e.push(r)}return Array.from(t)}hasCycle(){let n=new Set,t=new Set;for(let e of this.adjacencyList.keys()){if(n.has(e))continue;let i=[{node:e,entered:!1}];while(i.length>0){let r=i.pop();if(r.entered){t.delete(r.node);continue}if(t.has(r.node))return!0;if(n.has(r.node))continue;n.add(r.node),t.add(r.node),i.push({node:r.node,entered:!0});for(let s of this.adjacencyList.get(r.node)??[]){if(t.has(s))return!0;if(!n.has(s))i.push({node:s,entered:!1})}}}return!1}getAffectedByChange(n){let t=new Set;for(let e of n)for(let i of this.getTransitiveDependents(e))t.add(i);return Array.from(t)}getAdjacencyList(){let n=new Map;for(let[t,e]of this.adjacencyList)n.set(t,Array.from(e));return n}getTransitiveDependencies(n){let t=new Set,e=[n];while(e.length>0){let i=e.shift();for(let r of this.adjacencyList.get(i)??[])if(!t.has(r))t.add(r),e.push(r)}return Array.from(t)}getCyclePaths(){let n=new Set,t=[],e=new Set,i=new Map,r=[],s=(u)=>{if(e.has(u))return;if(i.has(u)){let m=i.get(u),a=r.slice(m),x=a.reduce((N,_)=>N<=_?N:_),p=a.indexOf(x),y=[...a.slice(p),...a.slice(0,p)],w=y.join("\x00");if(!n.has(w))n.add(w),t.push(y);return}i.set(u,r.length),r.push(u);for(let m of this.adjacencyList.get(u)??[])s(m);r.pop(),i.delete(u),e.add(u)};for(let u of this.adjacencyList.keys())s(u);return t}}import{findInFiles as qt,Lang as ne}from"@ast-grep/napi";async function Wn(n){if(n.filePaths.length===0)return[];let t=[];return await qt(ne.TypeScript,{paths:n.filePaths,matcher:{rule:{pattern:n.pattern}}},(e,i)=>{if(e)return;for(let r of i){let s=r.range();t.push({filePath:r.getRoot().filename(),startLine:s.start.line+1,endLine:s.end.line+1,matchedText:r.text()})}}),t}var lt=30000,pt=60000,ee=10;class Hn{projectRoot;db;symbolRepo;relationRepo;fileRepo;parseCache;coordinator;watcher;releaseWatcherRoleFn;parseSourceFn;extractSymbolsFn;extractRelationsFn;symbolSearchFn;relationSearchFn;patternSearchFn;readFileFn;unlinkFn;existsSyncFn;makeExternalCoordinatorFn;logger;defaultProject;role;timer=null;signalHandlers=[];closed=!1;tsconfigPaths=null;boundaries=[];onIndexedCallbacks=new Set;graphCache=null;graphCacheKey=null;constructor(n){this.projectRoot=n.projectRoot,this.db=n.db,this.symbolRepo=n.symbolRepo,this.relationRepo=n.relationRepo,this.fileRepo=n.fileRepo,this.parseCache=n.parseCache,this.coordinator=n.coordinator,this.watcher=n.watcher,this.releaseWatcherRoleFn=n.releaseWatcherRoleFn,this.parseSourceFn=n.parseSourceFn,this.extractSymbolsFn=n.extractSymbolsFn,this.extractRelationsFn=n.extractRelationsFn,this.symbolSearchFn=n.symbolSearchFn,this.relationSearchFn=n.relationSearchFn,this.patternSearchFn=n.patternSearchFn,this.readFileFn=n.readFileFn,this.unlinkFn=n.unlinkFn,this.existsSyncFn=n.existsSyncFn,this.makeExternalCoordinatorFn=n.makeExternalCoordinatorFn,this.logger=n.logger,this.defaultProject=n.defaultProject,this.role=n.role}static async open(n){let{projectRoot:t,extensions:e=[".ts",".mts",".cts"],ignorePatterns:i=[],parseCacheCapacity:r=500,logger:s=console,existsSyncFn:u=te,dbConnectionFactory:m,watcherFactory:a,coordinatorFactory:x,repositoryFactory:p,acquireWatcherRoleFn:y=ut,releaseWatcherRoleFn:w=mt,updateHeartbeatFn:N=ct,discoverProjectsFn:_=yn,parseSourceFn:D=an,extractSymbolsFn:M=ln,extractRelationsFn:l=pn,symbolSearchFn:g=Bn,relationSearchFn:o=Gn,patternSearchFn:c=Wn,loadTsconfigPathsFn:f=mn,makeExternalCoordinatorFn:O,readFileFn:A=async(K)=>Bun.file(K).text(),unlinkFn:C=async(K)=>{await Bun.file(K).unlink()},watchMode:h}=n;if(!Sn.isAbsolute(t))return S(d("validation",`Gildash: projectRoot must be an absolute path, got: "${t}"`));if(!u(t))return S(d("validation",`Gildash: projectRoot does not exist: "${t}"`));let k=m?m():new Mn({projectRoot:t}),J=k.open();if(en(J))return J;try{let K=await _(t),I=K[0]?.project??Sn.basename(t),$=p?p():(()=>{let G=k;return{fileRepo:new Jn(G),symbolRepo:new Kn(G),relationRepo:new In(G),parseCache:new kn(r)}})(),rn=h??!0,Z;if(rn)Z=await Promise.resolve(y(k,process.pid,{}));else Z="owner";let ft=null,gt=null,R=new Hn({projectRoot:t,db:k,symbolRepo:$.symbolRepo,relationRepo:$.relationRepo,fileRepo:$.fileRepo,parseCache:$.parseCache,coordinator:ft,watcher:gt,releaseWatcherRoleFn:w,parseSourceFn:D,extractSymbolsFn:M,extractRelationsFn:l,symbolSearchFn:g,relationSearchFn:o,patternSearchFn:c,readFileFn:A,unlinkFn:C,existsSyncFn:u,makeExternalCoordinatorFn:O,logger:s,defaultProject:I,role:Z});if(bn(t),R.tsconfigPaths=await f(t),R.boundaries=K,Z==="owner"){let G=x?x():new cn({projectRoot:t,boundaries:K,extensions:e,ignorePatterns:i,dbConnection:k,parseCache:$.parseCache,fileRepo:$.fileRepo,symbolRepo:$.symbolRepo,relationRepo:$.relationRepo,logger:s});if(R.coordinator=G,G.onIndexed(()=>R.invalidateGraphCache()),rn){let U=a?a():new xn({projectRoot:t,ignorePatterns:i,extensions:e},void 0,s);R.watcher=U,await U.start((Q)=>G.handleWatcherEvent?.(Q)).then((Q)=>{if(en(Q))throw Q.data});let E=setInterval(()=>{N(k,process.pid)},lt);R.timer=E}await G.fullIndex()}else{let G=0,U=async()=>{try{let Q=await Promise.resolve(y(k,process.pid,{}));if(G=0,Q==="owner"){clearInterval(R.timer),R.timer=null;let j=null,v=null;try{j=a?a():new xn({projectRoot:t,ignorePatterns:i,extensions:e},void 0,s),v=x?x():new cn({projectRoot:t,boundaries:K,extensions:e,ignorePatterns:i,dbConnection:k,parseCache:$.parseCache,fileRepo:$.fileRepo,symbolRepo:$.symbolRepo,relationRepo:$.relationRepo,logger:s});for(let W of R.onIndexedCallbacks)v.onIndexed(W);v.onIndexed(()=>R.invalidateGraphCache()),await j.start((W)=>v?.handleWatcherEvent?.(W)).then((W)=>{if(en(W))throw W.data});let On=setInterval(()=>{N(k,process.pid)},lt);R.timer=On,R.coordinator=v,R.watcher=j,await v.fullIndex()}catch(On){if(s.error("[Gildash] owner promotion failed, reverting to reader",On),j){let W=await j.close();if(en(W))s.error("[Gildash] watcher close error during promotion rollback",W.data);R.watcher=null}if(v)await v.shutdown().catch((W)=>s.error("[Gildash] coordinator shutdown error during promotion rollback",W)),R.coordinator=null;if(R.timer===null)R.timer=setInterval(U,pt)}}}catch(Q){if(G++,s.error("[Gildash] healthcheck error",Q),G>=ee)s.error("[Gildash] healthcheck failed too many times, shutting down"),clearInterval(R.timer),R.timer=null,R.close().catch((j)=>s.error("[Gildash] close error during healthcheck shutdown",j))}},E=setInterval(U,pt);R.timer=E}if(rn){let G=["SIGTERM","SIGINT","beforeExit"];for(let U of G){let E=()=>{R.close().catch((Q)=>s.error("[Gildash] close error during signal",U,Q))};if(U==="beforeExit")process.on("beforeExit",E);else process.on(U,E);R.signalHandlers.push([U,E])}}return R}catch(K){return k.close(),S(d("store","Gildash: initialization failed",K))}}async close(n){if(this.closed)return;this.closed=!0;let t=[];for(let[e,i]of this.signalHandlers)if(e==="beforeExit")process.off("beforeExit",i);else process.off(e,i);if(this.signalHandlers=[],this.coordinator)try{await this.coordinator.shutdown()}catch(e){t.push(e instanceof Error?e:Error(String(e)))}if(this.watcher){let e=await this.watcher.close();if(en(e))t.push(e.data)}if(this.timer!==null)clearInterval(this.timer),this.timer=null;try{this.releaseWatcherRoleFn(this.db,process.pid)}catch(e){t.push(e instanceof Error?e:Error(String(e)))}try{this.db.close()}catch(e){t.push(e instanceof Error?e:Error(String(e)))}if(n?.cleanup)for(let e of["","-wal","-shm"])try{await this.unlinkFn(Sn.join(this.projectRoot,".zipbul","gildash.db"+e))}catch{}if(t.length>0)return S(d("close","Gildash: one or more errors occurred during close()",t))}onIndexed(n){if(this.onIndexedCallbacks.add(n),!this.coordinator)return()=>{this.onIndexedCallbacks.delete(n)};let t=this.coordinator.onIndexed(n);return()=>{this.onIndexedCallbacks.delete(n),t()}}parseSource(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));let e=this.parseSourceFn(n,t);if(en(e))return e;return this.parseCache.set(n,e),e}extractSymbols(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));return this.extractSymbolsFn(n)}extractRelations(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));return this.extractRelationsFn(n.program,n.filePath,this.tsconfigPaths??void 0)}invalidateGraphCache(){this.graphCache=null,this.graphCacheKey=null}getOrBuildGraph(n){let t=n??"__cross__";if(this.graphCache&&this.graphCacheKey===t)return this.graphCache;let e=new wn({relationRepo:this.relationRepo,project:n??this.defaultProject});return e.build(),this.graphCache=e,this.graphCacheKey=t,e}async reindex(){if(this.closed)return S(d("closed","Gildash: instance is closed"));if(!this.coordinator)return S(d("closed","Gildash: reindex() is not available for readers"));try{let n=await this.coordinator.fullIndex();return this.invalidateGraphCache(),n}catch(n){return S(d("index","Gildash: reindex failed",n))}}get projects(){return[...this.boundaries]}getStats(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.symbolRepo.getStats(n??this.defaultProject)}catch(t){return S(d("store","Gildash: getStats failed",t))}}searchSymbols(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:this.defaultProject,query:n})}catch(t){return S(d("search","Gildash: searchSymbols failed",t))}}searchRelations(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:this.defaultProject,query:n})}catch(t){return S(d("search","Gildash: searchRelations failed",t))}}searchAllSymbols(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:void 0,query:n})}catch(t){return S(d("search","Gildash: searchAllSymbols failed",t))}}searchAllRelations(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:void 0,query:n})}catch(t){return S(d("search","Gildash: searchAllRelations failed",t))}}listIndexedFiles(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.fileRepo.getAllFiles(n??this.defaultProject)}catch(t){return S(d("store","Gildash: listIndexedFiles failed",t))}}getInternalRelations(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{srcFilePath:n,dstFilePath:n,limit:1e4}})}catch(e){return S(d("search","Gildash: getInternalRelations failed",e))}}diffSymbols(n,t){let e=new Map(n.map((m)=>[`${m.name}::${m.filePath}`,m])),i=new Map(t.map((m)=>[`${m.name}::${m.filePath}`,m])),r=[],s=[],u=[];for(let[m,a]of i){let x=e.get(m);if(!x)r.push(a);else if(x.fingerprint!==a.fingerprint)u.push({before:x,after:a})}for(let[m,a]of e)if(!i.has(m))s.push(a);return{added:r,removed:s,modified:u}}getDependencies(n,t,e=1e4){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{srcFilePath:n,type:"imports",project:t??this.defaultProject,limit:e}}).map((i)=>i.dstFilePath)}catch(i){return S(d("search","Gildash: getDependencies failed",i))}}getDependents(n,t,e=1e4){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{dstFilePath:n,type:"imports",project:t??this.defaultProject,limit:e}}).map((i)=>i.srcFilePath)}catch(i){return S(d("search","Gildash: getDependents failed",i))}}async getAffected(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getAffectedByChange(n)}catch(e){return S(d("search","Gildash: getAffected failed",e))}}async hasCycle(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).hasCycle()}catch(t){return S(d("search","Gildash: hasCycle failed",t))}}async getImportGraph(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getAdjacencyList()}catch(t){return S(d("search","Gildash: getImportGraph failed",t))}}async getTransitiveDependencies(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getTransitiveDependencies(n)}catch(e){return S(d("search","Gildash: getTransitiveDependencies failed",e))}}async getCyclePaths(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getCyclePaths()}catch(t){return S(d("search","Gildash: getCyclePaths failed",t))}}getDeadExports(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let e=n??this.defaultProject,i=this.symbolRepo.searchByQuery({project:e,isExported:!0,limit:1e5}),r=new Set;for(let a of["imports","re-exports"]){let x=this.relationRepo.getByType(e,a);for(let p of x)if(p.dstSymbolName!=null)r.add(`${p.dstFilePath}::${p.dstSymbolName}`)}let s=t?.entryPoints,u=["index.ts","index.mts","main.ts"];return i.filter((a)=>{if(r.has(`${a.filePath}::${a.name}`))return!1;if(s!==void 0)return!s.includes(a.filePath);let x=a.filePath.split("/").pop()??a.filePath;return!u.includes(x)}).map((a)=>({symbolName:a.name,filePath:a.filePath}))}catch(e){return S(d("store","Gildash: getDeadExports failed",e))}}getFullSymbol(n,t,e){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let i=e??this.defaultProject,r=this.symbolSearchFn({symbolRepo:this.symbolRepo,project:i,query:{text:n,exact:!0,filePath:t,limit:1}});if(r.length===0)return S(d("search",`Gildash: symbol '${n}' not found in '${t}'`));let s=r[0],u=s.detail;return{...s,members:Array.isArray(u.members)?u.members:void 0,jsDoc:typeof u.jsDoc==="string"?u.jsDoc:void 0,parameters:typeof u.parameters==="string"?u.parameters:void 0,returnType:typeof u.returnType==="string"?u.returnType:void 0,heritage:Array.isArray(u.heritage)?u.heritage:void 0,decorators:Array.isArray(u.decorators)?u.decorators:void 0,typeParameters:typeof u.typeParameters==="string"?u.typeParameters:void 0}}catch(i){return S(d("search","Gildash: getFullSymbol failed",i))}}getFileStats(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let e=t??this.defaultProject,i=this.fileRepo.getFile(e,n);if(!i)return S(d("search",`Gildash: file '${n}' is not in the index`));let r=this.symbolRepo.getFileSymbols(e,n),s=this.relationRepo.getOutgoing(e,n);return{filePath:i.filePath,lineCount:i.lineCount??0,size:i.size,symbolCount:r.length,exportedSymbolCount:r.filter((u)=>u.isExported).length,relationCount:s.length}}catch(e){return S(d("store","Gildash: getFileStats failed",e))}}async getFanMetrics(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let e=this.getOrBuildGraph(t);return{filePath:n,fanIn:e.getDependents(n).length,fanOut:e.getDependencies(n).length}}catch(e){return S(d("search","Gildash: getFanMetrics failed",e))}}resolveSymbol(n,t,e){if(this.closed)return S(d("closed","Gildash: instance is closed"));let i=e??this.defaultProject,r=new Set,s=[],u=n,m=t;for(;;){let a=`${m}::${u}`;if(r.has(a))return S(d("search","Gildash: resolveSymbol detected circular re-export chain"));r.add(a);let x=this.relationSearchFn({relationRepo:this.relationRepo,project:i,query:{type:"re-exports",srcFilePath:m,limit:500}}),p,y;for(let w of x){let N;if(w.metaJson)try{let D=JSON.parse(w.metaJson);if(Array.isArray(D.specifiers))N=D.specifiers}catch{}if(!N)continue;let _=N.find((D)=>D.exported===u);if(!_)continue;p=w.dstFilePath,y=_.local;break}if(!p||!y)return{originalName:u,originalFilePath:m,reExportChain:s};s.push({filePath:m,exportedAs:u}),m=p,u=y}}async findPattern(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let e=t?.project??this.defaultProject,i=t?.filePaths?t.filePaths:this.fileRepo.getAllFiles(e).map((r)=>r.filePath);return await this.patternSearchFn({pattern:n,filePaths:i})}catch(e){return S(d("search","Gildash: findPattern failed",e))}}async indexExternalPackages(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));if(this.role!=="owner")return S(d("closed","Gildash: indexExternalPackages() is not available for readers"));try{let e=[];for(let i of n){let r=Sn.resolve(this.projectRoot,"node_modules",i);if(!this.existsSyncFn(r))return S(d("validation",`Gildash: package not found in node_modules: ${i}`));let s=`@external/${i}`,m=await(this.makeExternalCoordinatorFn?this.makeExternalCoordinatorFn(r,s):new cn({projectRoot:r,boundaries:[{dir:".",project:s}],extensions:[".d.ts"],ignorePatterns:[],dbConnection:this.db,parseCache:this.parseCache,fileRepo:this.fileRepo,symbolRepo:this.symbolRepo,relationRepo:this.relationRepo,logger:this.logger})).fullIndex();e.push(m)}return e}catch(e){return S(d("store","Gildash: indexExternalPackages failed",e))}}async batchParse(n){if(this.closed)return S(d("closed","Gildash: instance is closed"));let t=new Map;return await Promise.all(n.map(async(e)=>{try{let i=await this.readFileFn(e),r=this.parseSourceFn(e,i);if(!en(r))t.set(e,r)}catch{}})),t}getModuleInterface(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let i=this.symbolSearchFn({symbolRepo:this.symbolRepo,project:t??this.defaultProject,query:{filePath:n,isExported:!0}}).map((r)=>({name:r.name,kind:r.kind,parameters:r.detail.parameters??void 0,returnType:r.detail.returnType??void 0,jsDoc:r.detail.jsDoc??void 0}));return{filePath:n,exports:i}}catch(e){return S(d("search","Gildash: getModuleInterface failed",e))}}async getHeritageChain(n,t,e){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{let i=e??this.defaultProject,r=new Set,s=(u,m,a)=>{let x=`${u}::${m}`;if(r.has(x))return{symbolName:u,filePath:m,kind:a,children:[]};r.add(x);let w=this.relationSearchFn({relationRepo:this.relationRepo,project:i,query:{srcFilePath:m,srcSymbolName:u,limit:1000}}).filter((N)=>N.type==="extends"||N.type==="implements").filter((N)=>N.dstSymbolName!=null).map((N)=>s(N.dstSymbolName,N.dstFilePath,N.type));return{symbolName:u,filePath:m,kind:a,children:w}};return s(n,t)}catch(i){return S(d("search","Gildash: getHeritageChain failed",i))}}getParsedAst(n){if(this.closed)return;return this.parseCache.get(n)}getFileInfo(n,t){if(this.closed)return S(d("closed","Gildash: instance is closed"));try{return this.fileRepo.getFile(t??this.defaultProject,n)}catch(e){return S(d("store","Gildash: getFileInfo failed",e))}}getSymbolsByFile(n,t){return this.searchSymbols({filePath:n,project:t??void 0,limit:1e4})}}export{Bn as symbolSearch,Gn as relationSearch,Wn as patternSearch,d as gildashError,Hn as Gildash,wn as DependencyGraph};
24
6
 
25
- //# debugId=FFD967C0260E6D8A64756E2164756E21
7
+ //# debugId=2A1CE56202A9E9A664756E2164756E21
26
8
  //# sourceMappingURL=index.js.map