@zipbul/gildash 0.5.0 → 0.5.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/README.ko.md +10 -1
- package/README.md +10 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +10 -9
- package/dist/src/constants.d.ts +4 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -33,6 +33,7 @@ gildash는 TypeScript 코드베이스를 로컬 SQLite 데이터베이스에 인
|
|
|
33
33
|
- **멀티 프로세스 안전** — owner/reader 역할 분리로 단일 writer 보장
|
|
34
34
|
- **스캔 전용 모드** — `watchMode: false`로 파일 워처 없이 1회성 인덱싱
|
|
35
35
|
- **외부 패키지 인덱싱** — `node_modules`의 `.d.ts` 타입 선언 인덱싱
|
|
36
|
+
- **tsconfig.json JSONC** — `tsconfig.json`의 주석(`//`, `/* */`)과 트레일링 콤마를 지원하는 경로 별칭 파싱
|
|
36
37
|
|
|
37
38
|
<br>
|
|
38
39
|
|
|
@@ -374,7 +375,7 @@ interface GildashError {
|
|
|
374
375
|
Gildash (파사드)
|
|
375
376
|
├── Parser — oxc-parser 기반 TypeScript AST 파싱
|
|
376
377
|
├── Extractor — 심볼/관계 추출 (imports, re-exports, type-refs, calls, heritage)
|
|
377
|
-
├── Store — bun:sqlite + drizzle-orm (files · symbols · relations · FTS5)
|
|
378
|
+
├── Store — bun:sqlite + drizzle-orm (files · symbols · relations · FTS5), `.gildash/gildash.db`에 저장
|
|
378
379
|
├── Indexer — 파일 변경 → 파싱 → 추출 → 저장 파이프라인, 심볼 레벨 diff
|
|
379
380
|
├── Search — FTS + regex + decorator 검색, 관계 쿼리, 의존성 그래프, ast-grep
|
|
380
381
|
└── Watcher — @parcel/watcher + owner/reader 역할 관리
|
|
@@ -389,6 +390,14 @@ Gildash (파사드)
|
|
|
389
390
|
|
|
390
391
|
<br>
|
|
391
392
|
|
|
393
|
+
## ⬆️ 0.5.0에서 업그레이드
|
|
394
|
+
|
|
395
|
+
데이터베이스 디렉토리가 `.zipbul/`에서 `.gildash/`로 변경되었습니다. 데이터베이스는 `<projectRoot>/.gildash/gildash.db`에 저장됩니다.
|
|
396
|
+
|
|
397
|
+
기존 `.zipbul/` 데이터는 자동으로 이전되지 않습니다. 최초 실행 시 `.gildash/gildash.db`에 새 데이터베이스가 생성됩니다. 업그레이드 후 `.zipbul/`을 수동으로 삭제하세요.
|
|
398
|
+
|
|
399
|
+
<br>
|
|
400
|
+
|
|
392
401
|
## 📄 라이선스
|
|
393
402
|
|
|
394
403
|
[MIT](./LICENSE) © [zipbul](https://github.com/zipbul)
|
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ gildash indexes your TypeScript codebase into a local SQLite database, then lets
|
|
|
33
33
|
- **Multi-process safe** — Owner/reader role separation guarantees a single writer per database
|
|
34
34
|
- **Scan-only mode** — `watchMode: false` for one-shot indexing without file watcher overhead
|
|
35
35
|
- **External package indexing** — Index `.d.ts` type declarations from `node_modules`
|
|
36
|
+
- **tsconfig.json JSONC** — Path alias resolution parses comments and trailing commas in `tsconfig.json`
|
|
36
37
|
|
|
37
38
|
<br>
|
|
38
39
|
|
|
@@ -482,7 +483,7 @@ interface GildashError {
|
|
|
482
483
|
Gildash (Facade)
|
|
483
484
|
├── Parser — oxc-parser-based TypeScript AST parsing
|
|
484
485
|
├── Extractor — Symbol & relation extraction (imports, re-exports, type-refs, calls, heritage)
|
|
485
|
-
├── Store — bun:sqlite + drizzle-orm (files · symbols · relations · FTS5)
|
|
486
|
+
├── Store — bun:sqlite + drizzle-orm (files · symbols · relations · FTS5) at `.gildash/gildash.db`
|
|
486
487
|
├── Indexer — File change → parse → extract → store pipeline, symbol-level diff
|
|
487
488
|
├── Search — FTS + regex + decorator search, relation queries, dependency graph, ast-grep
|
|
488
489
|
└── Watcher — @parcel/watcher + owner/reader role management
|
|
@@ -497,6 +498,14 @@ When multiple processes share the same SQLite database, gildash enforces a singl
|
|
|
497
498
|
|
|
498
499
|
<br>
|
|
499
500
|
|
|
501
|
+
## ⬆️ Upgrading from 0.5.0
|
|
502
|
+
|
|
503
|
+
The database directory was renamed from `.zipbul/` to `.gildash/`. The database is now stored at `<projectRoot>/.gildash/gildash.db`.
|
|
504
|
+
|
|
505
|
+
Existing `.zipbul/` data is **not** migrated automatically. On first run, a fresh database is created at `.gildash/gildash.db`. Delete `.zipbul/` manually after upgrading.
|
|
506
|
+
|
|
507
|
+
<br>
|
|
508
|
+
|
|
500
509
|
## 📄 License
|
|
501
510
|
|
|
502
511
|
[MIT](./LICENSE) © [zipbul](https://github.com/zipbul)
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
3
|
-
`)t.push(i+1);return t}function hn(n,t){let i=0,e=n.length-1;while(i<e){let r=i+e+1>>1;if(n[r]<=t)i=r;else e=r-1}return{line:i+1,column:t-n[i]}}import{err as bt}from"@zipbul/result";import{parse as Ot}from"comment-parser";function Pn(n){try{let t=n.trim();if(t.startsWith("/**"))t=t.slice(3);if(t.endsWith("*/"))t=t.slice(0,-2);let e=Ot(`/** ${t} */`)[0]??{description:"",tags:[]};return{description:(e.description??"").trim(),tags:(e.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 bt(y("parse","Failed to parse JSDoc comment",t))}}import{isErr as Nt}from"@zipbul/result";function ln(n){let{program:t,sourceText:i,comments:e}=n,r=Vn(i);function s(c,g){return{start:hn(r,c),end:hn(r,g)}}function m(c){let g=null;for(let o of e){if(o.type!=="Block")continue;if(o.end>c)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 l=o.start??0;if(l===c)continue;if(l>g.end&&l<c)return}return g.value}function u(c){if(!c)return;let g=c.typeAnnotation??c;return i.slice(g.start,g.end)}function a(c){if(!c||c.length===0)return[];return c.map((g)=>{let o=g.expression;if(!o)return{name:"unknown"};if(o.type==="CallExpression"){let l=o.callee?.name??o.callee?.property?.name??"unknown",d=(o.arguments??[]).map((b)=>i.slice(b.start,b.end));return{name:l,arguments:d.length>0?d:void 0}}if(o.type==="Identifier")return{name:o.name??"unknown"};return{name:i.slice(o.start,o.end)}})}function p(c){let g=c.type==="TSParameterProperty"?c.parameter:c;if(g?.type==="RestElement"){let h=`...${g.argument?.name??"unknown"}`,I=g.typeAnnotation,R=I?u(I):void 0,T={name:h,isOptional:!1};if(R)T.type=R;return T}if(g?.type==="AssignmentPattern"){let{left:k,right:h}=g,I=k?.name??"unknown",R=k?.typeAnnotation,T=R?u(R):void 0,z=i.slice(h.start,h.end),rn=a(k?.decorators??[]),Y={name:I,isOptional:!0,defaultValue:z};if(T)Y.type=T;if(rn.length>0)Y.decorators=rn;return Y}let o=g?.name??g?.pattern?.name??"unknown",l=!!g?.optional,d=g?.typeAnnotation,b=d?u(d):void 0,D=a(g?.decorators??[]),M={name:o,isOptional:l};if(b)M.type=b;if(D.length>0)M.decorators=D;return M}function f(c,g){let o=[];if(g?.async)o.push("async");if(c.static)o.push("static");if(c.abstract)o.push("abstract");if(c.readonly)o.push("readonly");if(c.override)o.push("override");if(c.declare)o.push("declare");if(c.const)o.push("const");let l=c.accessibility;if(l==="private")o.push("private");else if(l==="protected")o.push("protected");else if(l==="public")o.push("public");return o}function x(c){let g=[];if(c.superClass){let l=i.slice(c.superClass.start,c.superClass.end);g.push({kind:"extends",name:l})}let o=c.implements??[];for(let l of o){let d=l.expression??l,b=i.slice(d.start,d.end);g.push({kind:"implements",name:b})}return g}function S(c){let g=[];for(let o of c.extends??[]){let l=o.expression??o,d=i.slice(l.start,l.end);g.push({kind:"extends",name:d})}return g}function N(c){let g=[];for(let o of c)if(o.type==="MethodDefinition"){let l=o.key?.name??"unknown",d=o.value,b=o.kind??"method",D=b==="constructor"?"constructor":b==="get"?"getter":b==="set"?"setter":"method",M=f(o,d),k=(d?.params??[]).map(p),h=u(d?.returnType),I={kind:"method",name:l,span:s(o.start,o.end),isExported:!1,methodKind:D,modifiers:M,parameters:k.length>0?k:void 0,returnType:h};g.push(I)}else if(o.type==="PropertyDefinition"){let l=o.key?.name??"unknown",d=f(o),b={kind:"property",name:l,span:s(o.start,o.end),isExported:!1,modifiers:d};g.push(b)}return g}function J(c){let g=[];for(let o of c)if(o.type==="TSMethodSignature"){let l=o.key?.name??"unknown",d=(o.params??[]).map(p),b=u(o.returnType);g.push({kind:"method",name:l,span:s(o.start,o.end),isExported:!1,modifiers:[],methodKind:"method",parameters:d.length>0?d:void 0,returnType:b})}else if(o.type==="TSPropertySignature"){let l=o.key?.name??"unknown",d=u(o.typeAnnotation),b={kind:"property",name:l,span:s(o.start,o.end),isExported:!1,modifiers:o.readonly?["readonly"]:[],returnType:d};g.push(b)}return g}function A(c,g){let o=c.type??"";if(o==="FunctionDeclaration"){let l=c.id?.name??"default",d=(c.params??[]).map(p),b=u(c.returnType),D=f(c,c),M=a(c.decorators??[]),k=c.typeParameters?.params?.map((I)=>I.name?.name).filter(Boolean)||void 0,h={kind:"function",name:l,span:s(c.start,c.end),isExported:g,modifiers:D,parameters:d.length>0?d:void 0,returnType:b,decorators:M.length>0?M:void 0};if(k&&k.length>0)h.typeParameters=k;return h}if(o==="ClassDeclaration"||o==="ClassExpression"){let l=c.id?.name??"default",d=x(c),b=N(c.body?.body??[]),D=a(c.decorators??[]),M=f(c,c),k=c.typeParameters?.params?.map((I)=>I.name?.name).filter(Boolean)||void 0,h={kind:"class",name:l,span:s(c.start,c.end),isExported:g,modifiers:M,heritage:d.length>0?d:void 0,members:b.length>0?b:void 0,decorators:D.length>0?D:void 0};if(k&&k.length>0)h.typeParameters=k;return h}if(o==="VariableDeclaration"){let l=[];for(let d of c.declarations??[]){let{id:b,init:D}=d;if(b?.type==="ObjectPattern"){for(let T of b.properties??[]){let z=T.value?.name??T.key?.name??"unknown";l.push({kind:"variable",name:z,span:s(T.start??d.start,T.end??d.end),isExported:g,modifiers:[]})}continue}if(b?.type==="ArrayPattern"){for(let T of b.elements??[]){if(!T||T.type!=="Identifier")continue;let z=T.name??"unknown";l.push({kind:"variable",name:z,span:s(T.start??d.start,T.end??d.end),isExported:g,modifiers:[]})}continue}let M=b?.name??"unknown",k="variable",h,I;if(D?.type==="FunctionExpression"||D?.type==="ArrowFunctionExpression")k="function",h=(D.params??[]).map(p),I=u(D.returnType);let R=[];l.push({kind:k,name:M,span:s(d.start,d.end),isExported:g,modifiers:R,parameters:h,returnType:I})}if(l.length===0)return null;if(l.length===1)return l[0];return l}if(o==="TSTypeAliasDeclaration")return{kind:"type",name:c.id?.name??"unknown",span:s(c.start,c.end),isExported:g,modifiers:[]};if(o==="TSInterfaceDeclaration"){let l=c.id?.name??"unknown",d=S(c),b=J(c.body?.body??[]),D=c.typeParameters?.params?.map((k)=>k.name?.name).filter(Boolean)||void 0,M={kind:"interface",name:l,span:s(c.start,c.end),isExported:g,modifiers:[],heritage:d.length>0?d:void 0,members:b.length>0?b:void 0};if(D&&D.length>0)M.typeParameters=D;return M}if(o==="TSEnumDeclaration"){let l=c.id?.name??"unknown",d=f(c),D=(c.body?.members??[]).map((M)=>({kind:"property",name:M.id?.name??M.id?.value??"unknown",span:s(M.start,M.end),isExported:!1,modifiers:[]}));return{kind:"enum",name:l,span:s(c.start,c.end),isExported:g,modifiers:d,members:D.length>0?D:void 0}}return null}let F=[];for(let c of t.body){let g=null,o=c,l=typeof o.type==="string"?o.type:"";if(l==="ExportNamedDeclaration"){let b=c;if(b.declaration){if(g=A(b.declaration,!0),g&&!Array.isArray(g))g.span=s(b.start,b.end);else if(Array.isArray(g))for(let D of g)D.span=s(b.start,b.end)}}else if(l==="ExportDefaultDeclaration"){let b=c,D=b.declaration;if(D){if(g=A(D,!0),g&&!Array.isArray(g))g.name=D.id?.name??"default",g.isExported=!0,g.span=s(b.start,b.end)}}else g=A(c,!1);let d=Array.isArray(g)?g:g?[g]:[];for(let b of d){let D=c.start??0,M=m(D);if(M){let k=Pn(M);if(!Nt(k))b.jsDoc=k}F.push(b)}}return F}import{resolve as Dn,dirname as At,extname as ht}from"path";function kn(n,t,i){let e=(r)=>{let s=ht(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(At(n),t);return e(r)}if(i)for(let[r,s]of i.paths){if(s.length===0)continue;let m=r.indexOf("*");if(m===-1){if(t===r){let u=[];for(let a of s)u.push(...e(Dn(i.baseUrl,a)));return u}}else{let u=r.slice(0,m),a=r.slice(m+1);if(t.startsWith(u)&&(a===""||t.endsWith(a))){let p=t.slice(u.length,a===""?void 0:t.length-a.length),f=[];for(let x of s)f.push(...e(Dn(i.baseUrl,x.replace("*",p))));return f}}}return[]}function Qn(n,t,i,e=kn){let r=new Map,s=n.body??[];for(let m of s){if(m.type!=="ImportDeclaration")continue;let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],f=m.specifiers??[];for(let x of f)switch(x.type){case"ImportSpecifier":r.set(x.local.name,{path:p,importedName:x.imported.name});break;case"ImportDefaultSpecifier":r.set(x.local.name,{path:p,importedName:"default"});break;case"ImportNamespaceSpecifier":r.set(x.local.name,{path:p,importedName:"*"});break}}return r}var Dt=new Set(["loc","start","end","scope"]);function sn(n,t){if(!n||typeof n!=="object")return;if(Array.isArray(n)){for(let e of n)sn(e,t);return}let i=n;t(i);for(let e of Object.keys(i)){if(Dt.has(e))continue;let r=i[e];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 i=t.name;return{root:i,parts:[],full:i}}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 i=[],e=t;while(e.type==="MemberExpression"){let m=e.property;if(!m||typeof m.name!=="string")return null;i.unshift(m.name),e=e.object}let r;if(e.type==="Identifier")r=e.name;else if(e.type==="ThisExpression")r="this";else if(e.type==="Super")r="super";else return null;let s=[r,...i].join(".");return{root:r,parts:i,full:s}}return null}function Zn(n,t,i,e=kn){let r=[],s=n.body??[];for(let m of s){if(m.type==="ImportDeclaration"){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],f=m.importKind==="type",x=m.specifiers??[];if(x.length===0){let S={};if(f)S.isType=!0;r.push({type:f?"type-references":"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,...Object.keys(S).length>0?{metaJson:JSON.stringify(S)}:{}})}else for(let S of x){let N=S.type,J=f||S.importKind==="type",A={};if(J)A.isType=!0;let F,c;if(N==="ImportDefaultSpecifier")F="default",c=S.local.name;else if(N==="ImportNamespaceSpecifier")F="*",c=S.local.name,A.importKind="namespace";else F=S.imported.name,c=S.local.name;r.push({type:J?"type-references":"imports",srcFilePath:t,srcSymbolName:c,dstFilePath:p,dstSymbolName:F,...Object.keys(A).length>0?{metaJson:JSON.stringify(A)}:{}})}continue}if(m.type==="ExportAllDeclaration"&&m.source){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],f=m.exportKind==="type",x={isReExport:!0};if(f)x.isType=!0;r.push({type:f?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify(x)});continue}if(m.type==="ExportNamedDeclaration"&&m.source){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],f=m.exportKind==="type",N={isReExport:!0,specifiers:(m.specifiers??[]).map((J)=>({local:J.local.name,exported:J.exported.name}))};if(f)N.isType=!0;r.push({type:f?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify(N)})}}return sn(n,(m)=>{if(m.type!=="ImportExpression")return;let u=Yn(m.source);if(!u)return;let a=e(t,u,i);if(a.length===0)return;let p=a[0];r.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify({isDynamic:!0})})}),r}function vn(n,t,i){let e=[],r=[],s=[];function m(){if(r.length>0)return r[r.length-1]??null;return null}function u(p){if(!p)return null;let f=i.get(p.root);if(p.parts.length===0){if(f)return{dstFilePath:f.path,dstSymbolName:f.importedName,resolution:"import"};return{dstFilePath:t,dstSymbolName:p.root,resolution:"local"}}else{if(f&&f.importedName==="*"){let x=p.parts[p.parts.length-1];return{dstFilePath:f.path,dstSymbolName:x,resolution:"namespace"}}return{dstFilePath:t,dstSymbolName:p.full,resolution:"local-member"}}}function a(p){if(!p||typeof p!=="object")return;if(Array.isArray(p)){for(let S of p)a(S);return}let f=p,x=typeof f.type==="string"?f.type:"";if(x==="ClassDeclaration"||x==="ClassExpression"){let S=f,N=S.id?.name??"AnonymousClass";s.push(N),a(S.body),s.pop();return}if(x==="FunctionDeclaration"){let S=f,N=S.id?.name??"anonymous";r.push(N),a(S.body),r.pop();return}if(x==="VariableDeclarator"&&f.init&&(f.init?.type==="FunctionExpression"||f.init?.type==="ArrowFunctionExpression")){let S=f,N=S.id?.name??"anonymous";r.push(N),a(S.init?.body??S.init),r.pop();return}if(x==="MethodDefinition"&&f.value){let S=f,N=s[s.length-1]??"",J=S.key?.name??"anonymous",A=N?`${N}.${J}`:J;r.push(A),a(S.value?.body),r.pop();return}if(x==="FunctionExpression"||x==="ArrowFunctionExpression"){let S=m(),N=S?`${S}.<anonymous>`:"<anonymous>";r.push(N),a(f.body),r.pop();return}if(x==="CallExpression"){let S=f,N=q(S.callee),J=u(N);if(J){let A=m(),F={};if(A===null)F.scope="module";e.push({type:"calls",srcFilePath:t,srcSymbolName:A,dstFilePath:J.dstFilePath,dstSymbolName:J.dstSymbolName,...Object.keys(F).length>0?{metaJson:JSON.stringify(F)}:{}})}a(S.callee);for(let A of S.arguments??[])a(A);return}if(x==="NewExpression"){let S=f,N=q(S.callee),J=u(N);if(J){let A=m(),F={isNew:!0};if(A===null)F.scope="module";e.push({type:"calls",srcFilePath:t,srcSymbolName:A,dstFilePath:J.dstFilePath,dstSymbolName:J.dstSymbolName,metaJson:JSON.stringify(F)})}for(let A of S.arguments??[])a(A);return}for(let S of Object.keys(f)){if(S==="loc"||S==="start"||S==="end"||S==="scope")continue;let N=f[S];if(N&&typeof N==="object")a(N)}}return a(n),e}function Xn(n,t,i){let e=[];return sn(n,(r)=>{if(r.type==="TSInterfaceDeclaration"){let u=r.id?.name??"AnonymousInterface",a=r.extends??[];for(let p of a){let f=p.expression??p,x=q(f);if(!x)continue;let S=Fn(x,t,i);e.push({type:"extends",srcFilePath:t,srcSymbolName:u,...S})}return}if(r.type!=="ClassDeclaration"&&r.type!=="ClassExpression")return;let s=r.id?.name??"AnonymousClass";if(r.superClass){let u=q(r.superClass);if(u){let a=Fn(u,t,i);e.push({type:"extends",srcFilePath:t,srcSymbolName:s,...a})}}let m=r.implements??[];for(let u of m){let a=u.expression??u,p=q(a);if(!p)continue;let f=Fn(p,t,i);e.push({type:"implements",srcFilePath:t,srcSymbolName:s,...f})}}),e}function Fn(n,t,i){let e=i.get(n.root);if(e){if(e.importedName==="*"){let r=n.parts[n.parts.length-1]??n.root;return{dstFilePath:e.path,dstSymbolName:r,metaJson:JSON.stringify({isNamespaceImport:!0})}}return{dstFilePath:e.path,dstSymbolName:n.parts.length>0?n.full:e.importedName}}return{dstFilePath:t,dstSymbolName:n.full,metaJson:JSON.stringify({isLocal:!0})}}function fn(n,t,i){let e=Qn(n,t,i),r=Zn(n,t,i),s=vn(n,t,e),m=Xn(n,t,e);return[...r,...s,...m]}import{err as En,isErr as It}from"@zipbul/result";import{Database as Rt}from"bun:sqlite";import{mkdirSync as Tt,unlinkSync as jn,existsSync as qn}from"fs";import{dirname as Lt,join as nt}from"path";import{drizzle as $t}from"drizzle-orm/bun-sqlite";import{migrate as Ct}from"drizzle-orm/bun-sqlite/migrator";var Jn={};yt(Jn,{watcherOwner:()=>Mt,symbols:()=>_,relations:()=>w,files:()=>K});import{sql as kt}from"drizzle-orm";import{sqliteTable as pn,text as C,integer as H,real as Ft,index as nn,primaryKey as _t,foreignKey as _n,check as Jt}from"drizzle-orm/sqlite-core";var K=pn("files",{project:C("project").notNull(),filePath:C("file_path").notNull(),mtimeMs:Ft("mtime_ms").notNull(),size:H("size").notNull(),contentHash:C("content_hash").notNull(),updatedAt:C("updated_at").notNull(),lineCount:H("line_count")},(n)=>[_t({columns:[n.project,n.filePath]})]),_=pn("symbols",{id:H("id").primaryKey({autoIncrement:!0}),project:C("project").notNull(),filePath:C("file_path").notNull(),kind:C("kind").notNull(),name:C("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:C("signature"),fingerprint:C("fingerprint"),detailJson:C("detail_json"),contentHash:C("content_hash").notNull(),indexedAt:C("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:[K.project,K.filePath]}).onDelete("cascade")]),w=pn("relations",{id:H("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)=>[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:[K.project,K.filePath]}).onDelete("cascade"),_n({columns:[n.project,n.dstFilePath],foreignColumns:[K.project,K.filePath]}).onDelete("cascade")]),Mt=pn("watcher_owner",{id:H("id").primaryKey(),pid:H("pid").notNull(),startedAt:C("started_at").notNull(),heartbeatAt:C("heartbeat_at").notNull()},(n)=>[Jt("watcher_owner_singleton",kt`${n.id} = 1`)]);class Mn{client=null;drizzle=null;dbPath;txDepth=0;constructor(n){this.dbPath=nt(n.projectRoot,".zipbul","gildash.db")}get drizzleDb(){if(!this.drizzle)throw Error("Database is not open. Call open() first.");return this.drizzle}open(){try{Tt(Lt(this.dbPath),{recursive:!0}),this.client=new Rt(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=$t(this.client,{schema:Jn}),Ct(this.drizzle,{migrationsFolder:nt(import.meta.dirname,"migrations")});let n=this.client;if(typeof n.function==="function")n.function.call(this.client,"regexp",(t,i)=>{try{return new RegExp(t).test(i)?1:0}catch{return 0}})}catch(n){if(this.isCorruptionError(n)&&qn(this.dbPath)){this.closeClient(),jn(this.dbPath);for(let i of["-wal","-shm"]){let e=this.dbPath+i;if(qn(e))jn(e)}let t=this.open();if(It(t))return En(y("store",`Failed to recover database at ${this.dbPath}`,t.data));return t}return En(y("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 i=`sp_${this.txDepth++}`;t.run(`SAVEPOINT "${i}"`);try{let e=n(this);return t.run(`RELEASE SAVEPOINT "${i}"`),e}catch(e){throw t.run(`ROLLBACK TO SAVEPOINT "${i}"`),t.run(`RELEASE SAVEPOINT "${i}"`),e}finally{this.txDepth--}}immediateTransaction(n){let t=this.requireClient();this.txDepth++,t.run("BEGIN IMMEDIATE");try{let i=n();return t.run("COMMIT"),i}catch(i){throw t.run("ROLLBACK"),i}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 tt}from"drizzle-orm";class In{db;constructor(n){this.db=n}getFile(n,t){return this.db.drizzleDb.select().from(K).where(tt(un(K.project,n),un(K.filePath,t))).get()??null}upsertFile(n){this.db.drizzleDb.insert(K).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:[K.project,K.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(K).where(un(K.project,n)).all()}getFilesMap(n){let t=this.getAllFiles(n),i=new Map;for(let e of t)i.set(e.filePath,e);return i}deleteFile(n,t){this.db.drizzleDb.delete(K).where(tt(un(K.project,n),un(K.filePath,t))).run()}}import{eq as G,and as tn,sql as dn,count as Kt}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 Rn{db;constructor(n){this.db=n}replaceFileSymbols(n,t,i,e){if(this.db.drizzleDb.delete(_).where(tn(G(_.project,n),G(_.filePath,t))).run(),!e.length)return;let r=new Date().toISOString();for(let s of e)this.db.drizzleDb.insert(_).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:i,indexedAt:s.indexedAt??r}).run()}getFileSymbols(n,t){return this.db.drizzleDb.select().from(_).where(tn(G(_.project,n),G(_.filePath,t))).all()}searchByName(n,t,i={}){let e=i.limit??50,r=gn(t);if(!r)return[];return this.db.drizzleDb.select().from(_).where(tn(dn`${_.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${r})`,G(_.project,n),i.kind?G(_.kind,i.kind):void 0)).orderBy(_.name).limit(e).all()}searchByKind(n,t){return this.db.drizzleDb.select().from(_).where(tn(G(_.project,n),G(_.kind,t))).orderBy(_.name).all()}getStats(n){let t=this.db.drizzleDb.select({symbolCount:Kt(),fileCount:dn`COUNT(DISTINCT ${_.filePath})`}).from(_).where(G(_.project,n)).get();return{symbolCount:t?.symbolCount??0,fileCount:t?.fileCount??0}}getByFingerprint(n,t){return this.db.drizzleDb.select().from(_).where(tn(G(_.project,n),G(_.fingerprint,t))).all()}deleteFileSymbols(n,t){this.db.drizzleDb.delete(_).where(tn(G(_.project,n),G(_.filePath,t))).run()}searchByQuery(n){let t=this.db.drizzleDb.select().from(_).where(tn(n.ftsQuery?dn`${_.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${n.ftsQuery})`:void 0,n.exactName?G(_.name,n.exactName):void 0,n.project!==void 0?G(_.project,n.project):void 0,n.kind?G(_.kind,n.kind):void 0,n.filePath!==void 0?G(_.filePath,n.filePath):void 0,n.isExported!==void 0?G(_.isExported,n.isExported?1:0):void 0,n.decorator?dn`${_.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(_.name).limit(n.regex?Math.max(n.limit*50,5000):n.limit).all();if(!n.regex)return t;try{let i=new RegExp(n.regex);return t.filter((e)=>i.test(e.name)).slice(0,n.limit)}catch{return[]}}}import{eq as $,and as P,isNull as it,or as zt}from"drizzle-orm";class Tn{db;constructor(n){this.db=n}replaceFileRelations(n,t,i){if(this.db.drizzleDb.delete(w).where(P($(w.project,n),$(w.srcFilePath,t))).run(),!i.length)return;for(let e of i)this.db.drizzleDb.insert(w).values({project:n,type:e.type??"unknown",srcFilePath:e.srcFilePath??t,srcSymbolName:e.srcSymbolName??null,dstFilePath:e.dstFilePath??"",dstSymbolName:e.dstSymbolName??null,metaJson:e.metaJson??null}).run()}getOutgoing(n,t,i){if(i!==void 0)return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(P($(w.project,n),$(w.srcFilePath,t),zt($(w.srcSymbolName,i),it(w.srcSymbolName)))).all();return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(P($(w.project,n),$(w.srcFilePath,t))).all()}getIncoming(n,t){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(P($(w.project,n),$(w.dstFilePath,t))).all()}getByType(n,t){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(P($(w.project,n),$(w.type,t))).all()}deleteFileRelations(n,t){this.db.drizzleDb.delete(w).where(P($(w.project,n),$(w.srcFilePath,t))).run()}searchRelations(n){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(P(n.project!==void 0?$(w.project,n.project):void 0,n.srcFilePath!==void 0?$(w.srcFilePath,n.srcFilePath):void 0,n.srcSymbolName!==void 0?$(w.srcSymbolName,n.srcSymbolName):void 0,n.dstFilePath!==void 0?$(w.dstFilePath,n.dstFilePath):void 0,n.dstSymbolName!==void 0?$(w.dstSymbolName,n.dstSymbolName):void 0,n.type!==void 0?$(w.type,n.type):void 0)).limit(n.limit).all()}retargetRelations(n,t,i,e,r){let s=i===null?P($(w.project,n),$(w.dstFilePath,t),it(w.dstSymbolName)):P($(w.project,n),$(w.dstFilePath,t),$(w.dstSymbolName,i));this.db.drizzleDb.update(w).set({dstFilePath:e,dstSymbolName:r}).where(s).run()}}import{err as et}from"@zipbul/result";import{subscribe as Gt}from"@parcel/watcher";import Ln from"path";var Bt=["**/.git/**","**/.zipbul/**","**/dist/**","**/node_modules/**"],Wt=new Set(["package.json","tsconfig.json"]);function Ht(n){return n.replaceAll("\\","/")}function Ut(n){if(n==="update")return"change";if(n==="create")return"create";return"delete"}class xn{#t;#n;#e;#r;#s;#i;constructor(n,t=Gt,i=console){this.#n=n.projectRoot,this.#e=[...Bt,...n.ignorePatterns??[]],this.#r=new Set((n.extensions??[".ts",".mts",".cts"]).map((e)=>e.toLowerCase())),this.#s=t,this.#i=i}async start(n){try{this.#t=await this.#s(this.#n,(t,i)=>{if(t){this.#i.error(y("watcher","Callback error",t));return}try{for(let e of i){let r=Ht(Ln.relative(this.#n,e.path));if(r.startsWith(".."))continue;let s=Ln.basename(r),m=Ln.extname(r).toLowerCase();if(!Wt.has(s)&&!this.#r.has(m))continue;if(r.endsWith(".d.ts"))continue;n({eventType:Ut(e.type),filePath:r})}}catch(e){this.#i.error(y("watcher","Callback error",e))}},{ignore:this.#e})}catch(t){return et(y("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(y("watcher","Failed to close watcher",n))}}}import $n from"path";import{promises as Vt}from"fs";var Pt=["**/node_modules/**","**/.git/**","**/.zipbul/**","**/dist/**"];async function yn(n){let t=[];for await(let i of Vt.glob("**/package.json",{cwd:n,exclude:Pt})){let e=$n.dirname(i).replaceAll("\\","/"),r=$n.join(n,i),s=await Bun.file(r).json(),m=typeof s?.name==="string"&&s.name.length>0?s.name:$n.basename(e==="."?n:e);t.push({dir:e,project:m})}return t.sort((i,e)=>e.dir.length-i.dir.length),t}function Q(n,t,i="default"){let e=n.replaceAll("\\","/");for(let r of t){if(r.dir===".")return r.project;if(e===r.dir||e.startsWith(`${r.dir}/`))return r.project}return i}import rt from"path";var v=new Map;async function Qt(n){let t=Bun.file(n);if(!await t.exists())return null;let i=await t.json();return typeof i==="object"&&i!==null?i:null}async function mn(n){if(v.has(n))return v.get(n)??null;let t=rt.join(n,"tsconfig.json"),i=await Qt(t);if(!i)return v.set(n,null),null;let e=typeof i.compilerOptions==="object"&&i.compilerOptions!==null?i.compilerOptions:null;if(!e)return v.set(n,null),null;let r=typeof e.baseUrl==="string"?e.baseUrl:null,s=typeof e.paths==="object"&&e.paths!==null?e.paths:null;if(!r&&!s)return v.set(n,null),null;let m=r?rt.resolve(n,r):n,u=new Map;if(s)for(let[p,f]of Object.entries(s)){if(!Array.isArray(f))continue;let x=f.filter((S)=>typeof S==="string");u.set(p,x)}let a={baseUrl:m,paths:u};return v.set(n,a),a}function wn(n){if(n){v.delete(n);return}v.clear()}import st from"path";function Cn(n,t){return st.relative(n,t).replaceAll("\\","/")}function an(n,t){return st.resolve(n,t)}function X(n){let t=Bun.hash.xxHash64(n);return BigInt.asUintN(64,BigInt(t)).toString(16).padStart(16,"0")}import{isErr as ut}from"@zipbul/result";import{promises as Yt}from"fs";import{join as Zt}from"path";async function at(n){let{projectRoot:t,extensions:i,ignorePatterns:e,fileRepo:r}=n,s=r.getFilesMap(),m=new Set,u=[],a=[],p=e.map((x)=>new Bun.Glob(x));for await(let x of Yt.glob("**/*",{cwd:t})){if(!i.some((o)=>x.endsWith(o)))continue;if(p.some((o)=>o.match(x)))continue;m.add(x);let S=Zt(t,x),N=Bun.file(S),{size:J,lastModified:A}=N,F=s.get(x);if(!F){let o=await N.text(),l=X(o);u.push({filePath:x,contentHash:l,mtimeMs:A,size:J});continue}if(F.mtimeMs===A&&F.size===J){a.push({filePath:x,contentHash:F.contentHash,mtimeMs:A,size:J});continue}let c=await N.text(),g=X(c);if(g===F.contentHash)a.push({filePath:x,contentHash:g,mtimeMs:A,size:J});else u.push({filePath:x,contentHash:g,mtimeMs:A,size:J})}let f=[];for(let x of s.keys())if(!m.has(x))f.push(x);return{changed:u,unchanged:a,deleted:f}}function vt(n){if(n.kind==="function"||n.kind==="method"){let t=n.parameters?.length??0,i=n.modifiers.includes("async")?1:0;return`params:${t}|async:${i}`}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((i)=>{let e=i.modifiers.find((r)=>r==="private"||r==="protected"||r==="public");return{name:i.name,kind:i.methodKind??i.kind,type:i.returnType,visibility:e,isStatic:i.modifiers.includes("static")||void 0,isReadonly:i.modifiers.includes("readonly")||void 0}});return Object.keys(t).length>0?JSON.stringify(t):null}function ot(n,t,i,e,r){let s=vt(n),m=X(`${t}|${n.kind}|${s??""}`);return{project:i,filePath:e,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:m,detailJson:Xt(n),contentHash:r,indexedAt:new Date().toISOString()}}function Kn(n){let{parsed:t,project:i,filePath:e,contentHash:r,symbolRepo:s}=n,m=ln(t),u=[];for(let a of m){u.push(ot(a,a.name,i,e,r));for(let p of a.members??[])u.push(ot(p,`${a.name}.${p.name}`,i,e,r))}s.replaceFileSymbols(i,e,r,u)}function zn(n){let{ast:t,project:i,filePath:e,relationRepo:r,projectRoot:s,tsconfigPaths:m}=n,u=an(s,e),a=fn(t,u,m),p=[];for(let f of a){let x=Cn(s,f.dstFilePath);if(x.startsWith(".."))continue;let S=Cn(s,f.srcFilePath);p.push({project:i,type:f.type,srcFilePath:S,srcSymbolName:f.srcSymbolName??null,dstFilePath:x,dstSymbolName:f.dstSymbolName??null,metaJson:f.metaJson??null})}return r.replaceFileRelations(i,e,p),p.length}var Et=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")){wn(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((i)=>{this.opts.boundaries=i})}if(this.pendingEvents.push(n),this.debounceTimer===null)this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.flushPending()},Et)}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((e,r)=>{this.pendingFullIndexWaiters.push({resolve:e,reject:r})});return this.currentIndexing}this.indexingLock=!0;let i=this.doIndex(n,t).then((e)=>{return this.fireCallbacks(e),e}).finally(()=>{if(this.indexingLock=!1,this.currentIndexing=null,this.pendingFullIndex){this.pendingFullIndex=!1;let e=this.pendingFullIndexWaiters.splice(0);this.startIndex(void 0,!0).then((r)=>{for(let s of e)s.resolve(r)}).catch((r)=>{for(let s of e)s.reject(r)})}else if(this.pendingEvents.length>0){let e=this.pendingEvents.splice(0);this.startIndex(e,!1).catch((r)=>this.logger.error("[IndexCoordinator] incremental drain error",r))}});return this.currentIndexing=i,i}async doIndex(n,t){let i=Date.now(),{fileRepo:e,symbolRepo:r,relationRepo:s,dbConnection:m}=this.opts;if(this.boundariesRefresh)await this.boundariesRefresh,this.boundariesRefresh=null;let u,a;if(n!==void 0)u=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 d of this.opts.boundaries)for(let[b,D]of e.getFilesMap(d.project))o.set(b,D);let l=await at({projectRoot:this.opts.projectRoot,extensions:this.opts.extensions,ignorePatterns:this.opts.ignorePatterns,fileRepo:{getFilesMap:()=>o}});u=l.changed,a=l.deleted}let p=await this.tsconfigPathsRaw??void 0,f=new Map;for(let o of a){let l=Q(o,this.opts.boundaries),d=r.getFileSymbols(l,o);f.set(o,d)}let x=new Map,S=new Map;if(t)for(let o of this.opts.boundaries)for(let l of e.getAllFiles(o.project))for(let d of r.getFileSymbols(o.project,l.filePath))x.set(`${d.filePath}::${d.name}`,{name:d.name,filePath:d.filePath,kind:d.kind,fingerprint:d.fingerprint});else{for(let o of u){let l=Q(o.filePath,this.opts.boundaries);for(let d of r.getFileSymbols(l,o.filePath))x.set(`${d.filePath}::${d.name}`,{name:d.name,filePath:d.filePath,kind:d.kind,fingerprint:d.fingerprint})}for(let[,o]of f)for(let l of o)x.set(`${l.filePath}::${l.name}`,{name:l.name,filePath:l.filePath,kind:l.kind,fingerprint:l.fingerprint})}let N=()=>{for(let o of a){let l=Q(o,this.opts.boundaries);r.deleteFileSymbols(l,o),s.deleteFileRelations(l,o),e.deleteFile(l,o)}},J=async()=>{let o=0,l=0,d=[];for(let b of u)try{let D=await this.processFile(b.filePath,b.contentHash||void 0,p);o+=D.symbolCount,l+=D.relCount}catch(D){this.logger.error(`[IndexCoordinator] Failed to index ${b.filePath}:`,D),d.push(b.filePath)}return{symbols:o,relations:l,failedFiles:d}},A=0,F=0,c=[];if(t){let{projectRoot:o,boundaries:l}=this.opts,{parseCache:d}=this.opts,b=await Promise.allSettled(u.map(async(k)=>{let h=an(o,k.filePath),I=Bun.file(h),R=await I.text(),T=k.contentHash||X(R);return{filePath:k.filePath,text:R,contentHash:T,mtimeMs:I.lastModified,size:I.size}})),D=b.filter((k)=>k.status==="fulfilled").map((k)=>k.value);for(let k of b)if(k.status==="rejected")this.logger.error("[IndexCoordinator] Failed to pre-read file:",k.reason);let M=[];m.transaction(()=>{for(let h of l){let I=e.getAllFiles(h.project);for(let R of I)e.deleteFile(R.project,R.filePath)}for(let h of D){let I=Q(h.filePath,l);e.upsertFile({project:I,filePath:h.filePath,mtimeMs:h.mtimeMs,size:h.size,contentHash:h.contentHash,updatedAt:new Date().toISOString(),lineCount:h.text.split(`
|
|
4
|
-
`).length})}let k=this.opts.parseSourceFn??
|
|
5
|
-
`).length}),Kn({parsed:F,project:N,filePath:n,contentHash:S,symbolRepo:m});let c=zn({ast:F.program,project:N,filePath:n,relationRepo:u,projectRoot:e,tsconfigPaths:i});return{symbolCount:m.getFileSymbols(N,n).length,relCount:c}}fireCallbacks(n){for(let t of this.callbacks)try{t(n)}catch(i){this.logger.error("[IndexCoordinator] onIndexed callback threw:",i)}}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 jt(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 qt(n){let t=new Date(n).getTime();return Number.isNaN(t)?0:t}function mt(n,t,i={}){let e=i.now??Date.now,r=i.isAlive??jt,s=i.staleAfterSeconds??90;return n.immediateTransaction(()=>{let m=n.selectOwner();if(!m)return n.insertOwner(t),"owner";let u=Math.floor((e()-qt(m.heartbeat_at))/1000);if(r(m.pid)&&u<s)return"reader";return n.replaceOwner(t),"owner"})}function ct(n,t){n.deleteOwner(t)}function lt(n,t){n.touchOwner(t)}function Gn(n){let{symbolRepo:t,project:i,query:e}=n,r=e.project??i,s=e.limit??100,m={kind:e.kind,filePath:e.filePath,isExported:e.isExported,project:r,limit:s};if(e.text)if(e.exact)m.exactName=e.text;else{let a=gn(e.text);if(a)m.ftsQuery=a}if(e.decorator)m.decorator=e.decorator;if(e.regex)m.regex=e.regex;return t.searchByQuery(m).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 Bn(n){let{relationRepo:t,project:i,query:e}=n,r=e.project??i,s=e.limit??500;return t.searchRelations({srcFilePath:e.srcFilePath,srcSymbolName:e.srcSymbolName,dstFilePath:e.dstFilePath,dstSymbolName:e.dstSymbolName,type:e.type,project:r,limit:s}).map((u)=>{let a;if(u.metaJson)try{a=JSON.parse(u.metaJson)}catch{console.error("[relationSearch] malformed metaJson:",u.metaJson)}return{type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson??void 0,meta:a}})}class Sn{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:i,dstFilePath:e}=t;if(!this.adjacencyList.has(i))this.adjacencyList.set(i,new Set);if(this.adjacencyList.get(i).add(e),!this.adjacencyList.has(e))this.adjacencyList.set(e,new Set);if(!this.reverseAdjacencyList.has(e))this.reverseAdjacencyList.set(e,new Set);this.reverseAdjacencyList.get(e).add(i)}}getDependencies(n){return Array.from(this.adjacencyList.get(n)??[])}getDependents(n){return Array.from(this.reverseAdjacencyList.get(n)??[])}getTransitiveDependents(n){let t=new Set,i=[n];while(i.length>0){let e=i.shift();for(let r of this.reverseAdjacencyList.get(e)??[])if(!t.has(r))t.add(r),i.push(r)}return Array.from(t)}hasCycle(){let n=new Set,t=new Set;for(let i of this.adjacencyList.keys()){if(n.has(i))continue;let e=[{node:i,entered:!1}];while(e.length>0){let r=e.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),e.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))e.push({node:s,entered:!1})}}}return!1}getAffectedByChange(n){let t=new Set;for(let i of n)for(let e of this.getTransitiveDependents(i))t.add(e);return Array.from(t)}getAdjacencyList(){let n=new Map;for(let[t,i]of this.adjacencyList)n.set(t,Array.from(i));return n}getTransitiveDependencies(n){let t=new Set,i=[n];while(i.length>0){let e=i.shift();for(let r of this.adjacencyList.get(e)??[])if(!t.has(r))t.add(r),i.push(r)}return Array.from(t)}getCyclePaths(n){let t=n?.maxCycles??1/0;if(t<=0)return[];let i=new Map;for(let[e,r]of this.adjacencyList)i.set(e,Array.from(r));return ri(i,t)}}var ni=(n,t)=>n.localeCompare(t);function ti(n){let t=n.length>1&&n[0]===n[n.length-1]?n.slice(0,-1):[...n];if(t.length===0)return[];let i=t;for(let e=1;e<t.length;e++){let r=t.slice(e).concat(t.slice(0,e));if(r.join("::")<i.join("::"))i=r}return[...i]}function Wn(n,t,i){let e=ti(i);if(e.length===0)return!1;let r=e.join("->");if(n.has(r))return!1;return n.add(r),t.push(e),!0}function ii(n){let t=0,i=[],e=new Set,r=new Map,s=new Map,m=[],u=(a)=>{r.set(a,t),s.set(a,t),t+=1,i.push(a),e.add(a);for(let p of n.get(a)??[])if(!r.has(p))u(p),s.set(a,Math.min(s.get(a)??0,s.get(p)??0));else if(e.has(p))s.set(a,Math.min(s.get(a)??0,r.get(p)??0));if(s.get(a)===r.get(a)){let p=[],f="";do f=i.pop()??"",e.delete(f),p.push(f);while(f!==a&&i.length>0);m.push(p)}};for(let a of n.keys())if(!r.has(a))u(a);return{components:m}}function ei(n,t,i){let e=[],r=new Set,s=[...n].sort(ni),m=(u,a,p)=>{a.delete(u);let f=p.get(u);if(!f)return;for(let x of f)if(a.has(x))m(x,a,p);f.clear()};for(let u=0;u<s.length&&e.length<i;u++){let a=s[u]??"",p=new Set(s.slice(u)),f=new Set,x=new Map,S=[],N=(A)=>(t.get(A)??[]).filter((F)=>p.has(F)),J=(A)=>{if(e.length>=i)return!0;let F=!1;S.push(A),f.add(A);for(let c of N(A)){if(e.length>=i)break;if(c===a)Wn(r,e,S.concat(a)),F=!0;else if(!f.has(c)){if(J(c))F=!0}}if(F)m(A,f,x);else for(let c of N(A)){let g=x.get(c)??new Set;g.add(A),x.set(c,g)}return S.pop(),F};J(a)}return e}function ri(n,t){let{components:i}=ii(n),e=[],r=new Set;for(let s of i){if(e.length>=t)break;if(s.length===0)continue;if(s.length===1){let a=s[0]??"";if((n.get(a)??[]).includes(a))Wn(r,e,[a,a]);continue}let m=t-e.length,u=ei(s,n,m);for(let a of u){if(e.length>=t)break;Wn(r,e,a)}}return e}import{findInFiles as si,Lang as ai}from"@ast-grep/napi";async function Hn(n){if(n.filePaths.length===0)return[];let t=[];return await si(ai.TypeScript,{paths:n.filePaths,matcher:{rule:{pattern:n.pattern}}},(i,e)=>{if(i)return;for(let r of e){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 ft=30000,pt=60000,ui=10;class Un{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:i=[".ts",".mts",".cts"],ignorePatterns:e=[],parseCacheCapacity:r=500,logger:s=console,existsSyncFn:m=oi,dbConnectionFactory:u,watcherFactory:a,coordinatorFactory:p,repositoryFactory:f,acquireWatcherRoleFn:x=mt,releaseWatcherRoleFn:S=ct,updateHeartbeatFn:N=lt,discoverProjectsFn:J=yn,parseSourceFn:A=on,extractSymbolsFn:F=ln,extractRelationsFn:c=fn,symbolSearchFn:g=Gn,relationSearchFn:o=Bn,patternSearchFn:l=Hn,loadTsconfigPathsFn:d=mn,makeExternalCoordinatorFn:b,readFileFn:D=async(R)=>Bun.file(R).text(),unlinkFn:M=async(R)=>{await Bun.file(R).unlink()},watchMode:k}=n;if(!bn.isAbsolute(t))return O(y("validation",`Gildash: projectRoot must be an absolute path, got: "${t}"`));if(!m(t))return O(y("validation",`Gildash: projectRoot does not exist: "${t}"`));let h=u?u():new Mn({projectRoot:t}),I=h.open();if(en(I))return I;try{let R=await J(t),T=R[0]?.project??bn.basename(t),z=f?f():(()=>{let B=h;return{fileRepo:new In(B),symbolRepo:new Rn(B),relationRepo:new Tn(B),parseCache:new An(r)}})(),rn=k??!0,Y;if(rn)Y=await Promise.resolve(x(h,process.pid,{}));else Y="owner";let gt=null,dt=null,L=new Un({projectRoot:t,db:h,symbolRepo:z.symbolRepo,relationRepo:z.relationRepo,fileRepo:z.fileRepo,parseCache:z.parseCache,coordinator:gt,watcher:dt,releaseWatcherRoleFn:S,parseSourceFn:A,extractSymbolsFn:F,extractRelationsFn:c,symbolSearchFn:g,relationSearchFn:o,patternSearchFn:l,readFileFn:D,unlinkFn:M,existsSyncFn:m,makeExternalCoordinatorFn:b,logger:s,defaultProject:T,role:Y});if(wn(t),L.tsconfigPaths=await d(t),L.boundaries=R,Y==="owner"){let B=p?p():new cn({projectRoot:t,boundaries:R,extensions:i,ignorePatterns:e,dbConnection:h,parseCache:z.parseCache,fileRepo:z.fileRepo,symbolRepo:z.symbolRepo,relationRepo:z.relationRepo,logger:s});if(L.coordinator=B,B.onIndexed(()=>L.invalidateGraphCache()),rn){let U=a?a():new xn({projectRoot:t,ignorePatterns:e,extensions:i},void 0,s);L.watcher=U,await U.start((V)=>B.handleWatcherEvent?.(V)).then((V)=>{if(en(V))throw V.data});let E=setInterval(()=>{N(h,process.pid)},ft);L.timer=E}await B.fullIndex()}else{let B=0,U=async()=>{try{let V=await Promise.resolve(x(h,process.pid,{}));if(B=0,V==="owner"){clearInterval(L.timer),L.timer=null;let j=null,Z=null;try{j=a?a():new xn({projectRoot:t,ignorePatterns:e,extensions:i},void 0,s),Z=p?p():new cn({projectRoot:t,boundaries:R,extensions:i,ignorePatterns:e,dbConnection:h,parseCache:z.parseCache,fileRepo:z.fileRepo,symbolRepo:z.symbolRepo,relationRepo:z.relationRepo,logger:s});for(let W of L.onIndexedCallbacks)Z.onIndexed(W);Z.onIndexed(()=>L.invalidateGraphCache()),await j.start((W)=>Z?.handleWatcherEvent?.(W)).then((W)=>{if(en(W))throw W.data});let On=setInterval(()=>{N(h,process.pid)},ft);L.timer=On,L.coordinator=Z,L.watcher=j,await Z.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);L.watcher=null}if(Z)await Z.shutdown().catch((W)=>s.error("[Gildash] coordinator shutdown error during promotion rollback",W)),L.coordinator=null;if(L.timer===null)L.timer=setInterval(U,pt)}}}catch(V){if(B++,s.error("[Gildash] healthcheck error",V),B>=ui)s.error("[Gildash] healthcheck failed too many times, shutting down"),clearInterval(L.timer),L.timer=null,L.close().catch((j)=>s.error("[Gildash] close error during healthcheck shutdown",j))}},E=setInterval(U,pt);L.timer=E}if(rn){let B=["SIGTERM","SIGINT","beforeExit"];for(let U of B){let E=()=>{L.close().catch((V)=>s.error("[Gildash] close error during signal",U,V))};if(U==="beforeExit")process.on("beforeExit",E);else process.on(U,E);L.signalHandlers.push([U,E])}}return L}catch(R){return h.close(),O(y("store","Gildash: initialization failed",R))}}async close(n){if(this.closed)return;this.closed=!0;let t=[];for(let[i,e]of this.signalHandlers)if(i==="beforeExit")process.off("beforeExit",e);else process.off(i,e);if(this.signalHandlers=[],this.coordinator)try{await this.coordinator.shutdown()}catch(i){t.push(i instanceof Error?i:Error(String(i)))}if(this.watcher){let i=await this.watcher.close();if(en(i))t.push(i.data)}if(this.timer!==null)clearInterval(this.timer),this.timer=null;try{this.releaseWatcherRoleFn(this.db,process.pid)}catch(i){t.push(i instanceof Error?i:Error(String(i)))}try{this.db.close()}catch(i){t.push(i instanceof Error?i:Error(String(i)))}if(n?.cleanup)for(let i of["","-wal","-shm"])try{await this.unlinkFn(bn.join(this.projectRoot,".zipbul","gildash.db"+i))}catch{}if(t.length>0)return O(y("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,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));let e=this.parseSourceFn(n,t,i);if(en(e))return e;return this.parseCache.set(n,e),e}extractSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));return this.extractSymbolsFn(n)}extractRelations(n){if(this.closed)return O(y("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 i=new Sn({relationRepo:this.relationRepo,project:n??this.defaultProject});return i.build(),this.graphCache=i,this.graphCacheKey=t,i}async reindex(){if(this.closed)return O(y("closed","Gildash: instance is closed"));if(!this.coordinator)return O(y("closed","Gildash: reindex() is not available for readers"));try{let n=await this.coordinator.fullIndex();return this.invalidateGraphCache(),n}catch(n){return O(y("index","Gildash: reindex failed",n))}}get projects(){return[...this.boundaries]}getStats(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolRepo.getStats(n??this.defaultProject)}catch(t){return O(y("store","Gildash: getStats failed",t))}}searchSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:this.defaultProject,query:n})}catch(t){return O(y("search","Gildash: searchSymbols failed",t))}}searchRelations(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:this.defaultProject,query:n})}catch(t){return O(y("search","Gildash: searchRelations failed",t))}}searchAllSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:void 0,query:n})}catch(t){return O(y("search","Gildash: searchAllSymbols failed",t))}}searchAllRelations(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:void 0,query:n})}catch(t){return O(y("search","Gildash: searchAllRelations failed",t))}}listIndexedFiles(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.fileRepo.getAllFiles(n??this.defaultProject)}catch(t){return O(y("store","Gildash: listIndexedFiles failed",t))}}getInternalRelations(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{srcFilePath:n,dstFilePath:n,limit:1e4}})}catch(i){return O(y("search","Gildash: getInternalRelations failed",i))}}diffSymbols(n,t){let i=new Map(n.map((u)=>[`${u.name}::${u.filePath}`,u])),e=new Map(t.map((u)=>[`${u.name}::${u.filePath}`,u])),r=[],s=[],m=[];for(let[u,a]of e){let p=i.get(u);if(!p)r.push(a);else if(p.fingerprint!==a.fingerprint)m.push({before:p,after:a})}for(let[u,a]of i)if(!e.has(u))s.push(a);return{added:r,removed:s,modified:m}}getDependencies(n,t,i=1e4){if(this.closed)return O(y("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:i}}).map((e)=>e.dstFilePath)}catch(e){return O(y("search","Gildash: getDependencies failed",e))}}getDependents(n,t,i=1e4){if(this.closed)return O(y("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:i}}).map((e)=>e.srcFilePath)}catch(e){return O(y("search","Gildash: getDependents failed",e))}}async getAffected(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getAffectedByChange(n)}catch(i){return O(y("search","Gildash: getAffected failed",i))}}async hasCycle(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).hasCycle()}catch(t){return O(y("search","Gildash: hasCycle failed",t))}}async getImportGraph(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getAdjacencyList()}catch(t){return O(y("search","Gildash: getImportGraph failed",t))}}async getTransitiveDependencies(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getTransitiveDependencies(n)}catch(i){return O(y("search","Gildash: getTransitiveDependencies failed",i))}}async getCyclePaths(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getCyclePaths(t)}catch(i){return O(y("search","Gildash: getCyclePaths failed",i))}}getFullSymbol(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=i??this.defaultProject,r=this.symbolSearchFn({symbolRepo:this.symbolRepo,project:e,query:{text:n,exact:!0,filePath:t,limit:1}});if(r.length===0)return O(y("search",`Gildash: symbol '${n}' not found in '${t}'`));let s=r[0],m=s.detail;return{...s,members:Array.isArray(m.members)?m.members:void 0,jsDoc:typeof m.jsDoc==="string"?m.jsDoc:void 0,parameters:typeof m.parameters==="string"?m.parameters:void 0,returnType:typeof m.returnType==="string"?m.returnType:void 0,heritage:Array.isArray(m.heritage)?m.heritage:void 0,decorators:Array.isArray(m.decorators)?m.decorators:void 0,typeParameters:typeof m.typeParameters==="string"?m.typeParameters:void 0}}catch(e){return O(y("search","Gildash: getFullSymbol failed",e))}}getFileStats(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=t??this.defaultProject,e=this.fileRepo.getFile(i,n);if(!e)return O(y("search",`Gildash: file '${n}' is not in the index`));let r=this.symbolRepo.getFileSymbols(i,n),s=this.relationRepo.getOutgoing(i,n);return{filePath:e.filePath,lineCount:e.lineCount??0,size:e.size,symbolCount:r.length,exportedSymbolCount:r.filter((m)=>m.isExported).length,relationCount:s.length}}catch(i){return O(y("store","Gildash: getFileStats failed",i))}}async getFanMetrics(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=this.getOrBuildGraph(t);return{filePath:n,fanIn:i.getDependents(n).length,fanOut:i.getDependencies(n).length}}catch(i){return O(y("search","Gildash: getFanMetrics failed",i))}}resolveSymbol(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));let e=i??this.defaultProject,r=new Set,s=[],m=n,u=t;for(;;){let a=`${u}::${m}`;if(r.has(a))return O(y("search","Gildash: resolveSymbol detected circular re-export chain"));r.add(a);let p=this.relationSearchFn({relationRepo:this.relationRepo,project:e,query:{type:"re-exports",srcFilePath:u,limit:500}}),f,x;for(let S of p){let N;if(S.metaJson)try{let A=JSON.parse(S.metaJson);if(Array.isArray(A.specifiers))N=A.specifiers}catch{}if(!N)continue;let J=N.find((A)=>A.exported===m);if(!J)continue;f=S.dstFilePath,x=J.local;break}if(!f||!x)return{originalName:m,originalFilePath:u,reExportChain:s};s.push({filePath:u,exportedAs:m}),u=f,m=x}}async findPattern(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=t?.project??this.defaultProject,e=t?.filePaths?t.filePaths:this.fileRepo.getAllFiles(i).map((r)=>r.filePath);return await this.patternSearchFn({pattern:n,filePaths:e})}catch(i){return O(y("search","Gildash: findPattern failed",i))}}async indexExternalPackages(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));if(this.role!=="owner")return O(y("closed","Gildash: indexExternalPackages() is not available for readers"));try{let i=[];for(let e of n){let r=bn.resolve(this.projectRoot,"node_modules",e);if(!this.existsSyncFn(r))return O(y("validation",`Gildash: package not found in node_modules: ${e}`));let s=`@external/${e}`,u=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();i.push(u)}return i}catch(i){return O(y("store","Gildash: indexExternalPackages failed",i))}}async batchParse(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));let i=new Map;return await Promise.all(n.map(async(e)=>{try{let r=await this.readFileFn(e),s=this.parseSourceFn(e,r,t);if(!en(s))i.set(e,s)}catch{}})),i}getModuleInterface(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=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:e}}catch(i){return O(y("search","Gildash: getModuleInterface failed",i))}}async getHeritageChain(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=i??this.defaultProject,r=new Set,s=(m,u,a)=>{let p=`${m}::${u}`;if(r.has(p))return{symbolName:m,filePath:u,kind:a,children:[]};r.add(p);let S=this.relationSearchFn({relationRepo:this.relationRepo,project:e,query:{srcFilePath:u,srcSymbolName:m,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:m,filePath:u,kind:a,children:S}};return s(n,t)}catch(e){return O(y("search","Gildash: getHeritageChain failed",e))}}getParsedAst(n){if(this.closed)return;return this.parseCache.get(n)}getFileInfo(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.fileRepo.getFile(t??this.defaultProject,n)}catch(i){return O(y("store","Gildash: getFileInfo failed",i))}}getSymbolsByFile(n,t){return this.searchSymbols({filePath:n,project:t??void 0,limit:1e4})}}export{Gn as symbolSearch,Bn as relationSearch,Hn as patternSearch,y as gildashError,Un as Gildash,Sn as DependencyGraph};
|
|
2
|
+
var wt=Object.defineProperty;var St=(n,t)=>{for(var i in t)wt(n,i,{get:t[i],enumerable:!0,configurable:!0,set:(e)=>t[i]=()=>e})};import{err as O,isErr as rn}from"@zipbul/result";import Nn from"path";import{existsSync as mi}from"fs";import{err as bt}from"@zipbul/result";import{parseSync as Ot}from"oxc-parser";function y(n,t,i){return i!==void 0?{type:n,message:t,cause:i}:{type:n,message:t}}function un(n,t,i,e=Ot){try{let{program:r,errors:s,comments:m}=e(n,t,i);return{filePath:n,program:r,errors:s,comments:m,sourceText:t}}catch(r){return bt(y("parse",`Failed to parse file: ${n}`,r))}}class An{#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 i=this.#n.keys().next().value;if(i!==void 0)this.#n.delete(i)}}delete(n){return this.#n.delete(n)}clear(){this.#n.clear()}}class Dn{lru;constructor(n=500){this.lru=new An(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 Yn(n){let t=[0];for(let i=0;i<n.length;i++)if(n[i]===`
|
|
3
|
+
`)t.push(i+1);return t}function kn(n,t){let i=0,e=n.length-1;while(i<e){let r=i+e+1>>1;if(n[r]<=t)i=r;else e=r-1}return{line:i+1,column:t-n[i]}}import{err as Nt}from"@zipbul/result";import{parse as ht}from"comment-parser";function Zn(n){try{let t=n.trim();if(t.startsWith("/**"))t=t.slice(3);if(t.endsWith("*/"))t=t.slice(0,-2);let e=ht(`/** ${t} */`)[0]??{description:"",tags:[]};return{description:(e.description??"").trim(),tags:(e.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 Nt(y("parse","Failed to parse JSDoc comment",t))}}import{isErr as At}from"@zipbul/result";function ln(n){let{program:t,sourceText:i,comments:e}=n,r=Yn(i);function s(c,g){return{start:kn(r,c),end:kn(r,g)}}function m(c){let g=null;for(let o of e){if(o.type!=="Block")continue;if(o.end>c)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 f=o.start??0;if(f===c)continue;if(f>g.end&&f<c)return}return g.value}function u(c){if(!c)return;let g=c.typeAnnotation??c;return i.slice(g.start,g.end)}function a(c){if(!c||c.length===0)return[];return c.map((g)=>{let o=g.expression;if(!o)return{name:"unknown"};if(o.type==="CallExpression"){let f=o.callee?.name??o.callee?.property?.name??"unknown",x=(o.arguments??[]).map((b)=>i.slice(b.start,b.end));return{name:f,arguments:x.length>0?x:void 0}}if(o.type==="Identifier")return{name:o.name??"unknown"};return{name:i.slice(o.start,o.end)}})}function p(c){let g=c.type==="TSParameterProperty"?c.parameter:c;if(g?.type==="RestElement"){let h=`...${g.argument?.name??"unknown"}`,M=g.typeAnnotation,C=M?u(M):void 0,I={name:h,isOptional:!1};if(C)I.type=C;return I}if(g?.type==="AssignmentPattern"){let{left:k,right:h}=g,M=k?.name??"unknown",C=k?.typeAnnotation,I=C?u(C):void 0,L=i.slice(h.start,h.end),sn=a(k?.decorators??[]),Z={name:M,isOptional:!0,defaultValue:L};if(I)Z.type=I;if(sn.length>0)Z.decorators=sn;return Z}let o=g?.name??g?.pattern?.name??"unknown",f=!!g?.optional,x=g?.typeAnnotation,b=x?u(x):void 0,D=a(g?.decorators??[]),$={name:o,isOptional:f};if(b)$.type=b;if(D.length>0)$.decorators=D;return $}function l(c,g){let o=[];if(g?.async)o.push("async");if(c.static)o.push("static");if(c.abstract)o.push("abstract");if(c.readonly)o.push("readonly");if(c.override)o.push("override");if(c.declare)o.push("declare");if(c.const)o.push("const");let f=c.accessibility;if(f==="private")o.push("private");else if(f==="protected")o.push("protected");else if(f==="public")o.push("public");return o}function d(c){let g=[];if(c.superClass){let f=i.slice(c.superClass.start,c.superClass.end);g.push({kind:"extends",name:f})}let o=c.implements??[];for(let f of o){let x=f.expression??f,b=i.slice(x.start,x.end);g.push({kind:"implements",name:b})}return g}function S(c){let g=[];for(let o of c.extends??[]){let f=o.expression??o,x=i.slice(f.start,f.end);g.push({kind:"extends",name:x})}return g}function N(c){let g=[];for(let o of c)if(o.type==="MethodDefinition"){let f=o.key?.name??"unknown",x=o.value,b=o.kind??"method",D=b==="constructor"?"constructor":b==="get"?"getter":b==="set"?"setter":"method",$=l(o,x),k=(x?.params??[]).map(p),h=u(x?.returnType),M={kind:"method",name:f,span:s(o.start,o.end),isExported:!1,methodKind:D,modifiers:$,parameters:k.length>0?k:void 0,returnType:h};g.push(M)}else if(o.type==="PropertyDefinition"){let f=o.key?.name??"unknown",x=l(o),b={kind:"property",name:f,span:s(o.start,o.end),isExported:!1,modifiers:x};g.push(b)}return g}function J(c){let g=[];for(let o of c)if(o.type==="TSMethodSignature"){let f=o.key?.name??"unknown",x=(o.params??[]).map(p),b=u(o.returnType);g.push({kind:"method",name:f,span:s(o.start,o.end),isExported:!1,modifiers:[],methodKind:"method",parameters:x.length>0?x:void 0,returnType:b})}else if(o.type==="TSPropertySignature"){let f=o.key?.name??"unknown",x=u(o.typeAnnotation),b={kind:"property",name:f,span:s(o.start,o.end),isExported:!1,modifiers:o.readonly?["readonly"]:[],returnType:x};g.push(b)}return g}function A(c,g){let o=c.type??"";if(o==="FunctionDeclaration"){let f=c.id?.name??"default",x=(c.params??[]).map(p),b=u(c.returnType),D=l(c,c),$=a(c.decorators??[]),k=c.typeParameters?.params?.map((M)=>M.name?.name).filter(Boolean)||void 0,h={kind:"function",name:f,span:s(c.start,c.end),isExported:g,modifiers:D,parameters:x.length>0?x:void 0,returnType:b,decorators:$.length>0?$:void 0};if(k&&k.length>0)h.typeParameters=k;return h}if(o==="ClassDeclaration"||o==="ClassExpression"){let f=c.id?.name??"default",x=d(c),b=N(c.body?.body??[]),D=a(c.decorators??[]),$=l(c,c),k=c.typeParameters?.params?.map((M)=>M.name?.name).filter(Boolean)||void 0,h={kind:"class",name:f,span:s(c.start,c.end),isExported:g,modifiers:$,heritage:x.length>0?x:void 0,members:b.length>0?b:void 0,decorators:D.length>0?D:void 0};if(k&&k.length>0)h.typeParameters=k;return h}if(o==="VariableDeclaration"){let f=[];for(let x of c.declarations??[]){let{id:b,init:D}=x;if(b?.type==="ObjectPattern"){for(let I of b.properties??[]){let L=I.value?.name??I.key?.name??"unknown";f.push({kind:"variable",name:L,span:s(I.start??x.start,I.end??x.end),isExported:g,modifiers:[]})}continue}if(b?.type==="ArrayPattern"){for(let I of b.elements??[]){if(!I||I.type!=="Identifier")continue;let L=I.name??"unknown";f.push({kind:"variable",name:L,span:s(I.start??x.start,I.end??x.end),isExported:g,modifiers:[]})}continue}let $=b?.name??"unknown",k="variable",h,M;if(D?.type==="FunctionExpression"||D?.type==="ArrowFunctionExpression")k="function",h=(D.params??[]).map(p),M=u(D.returnType);let C=[];f.push({kind:k,name:$,span:s(x.start,x.end),isExported:g,modifiers:C,parameters:h,returnType:M})}if(f.length===0)return null;if(f.length===1)return f[0];return f}if(o==="TSTypeAliasDeclaration")return{kind:"type",name:c.id?.name??"unknown",span:s(c.start,c.end),isExported:g,modifiers:[]};if(o==="TSInterfaceDeclaration"){let f=c.id?.name??"unknown",x=S(c),b=J(c.body?.body??[]),D=c.typeParameters?.params?.map((k)=>k.name?.name).filter(Boolean)||void 0,$={kind:"interface",name:f,span:s(c.start,c.end),isExported:g,modifiers:[],heritage:x.length>0?x:void 0,members:b.length>0?b:void 0};if(D&&D.length>0)$.typeParameters=D;return $}if(o==="TSEnumDeclaration"){let f=c.id?.name??"unknown",x=l(c),D=(c.body?.members??[]).map(($)=>({kind:"property",name:$.id?.name??$.id?.value??"unknown",span:s($.start,$.end),isExported:!1,modifiers:[]}));return{kind:"enum",name:f,span:s(c.start,c.end),isExported:g,modifiers:x,members:D.length>0?D:void 0}}return null}let F=[];for(let c of t.body){let g=null,o=c,f=typeof o.type==="string"?o.type:"";if(f==="ExportNamedDeclaration"){let b=c;if(b.declaration){if(g=A(b.declaration,!0),g&&!Array.isArray(g))g.span=s(b.start,b.end);else if(Array.isArray(g))for(let D of g)D.span=s(b.start,b.end)}}else if(f==="ExportDefaultDeclaration"){let b=c,D=b.declaration;if(D){if(g=A(D,!0),g&&!Array.isArray(g))g.name=D.id?.name??"default",g.isExported=!0,g.span=s(b.start,b.end)}}else g=A(c,!1);let x=Array.isArray(g)?g:g?[g]:[];for(let b of x){let D=c.start??0,$=m(D);if($){let k=Zn($);if(!At(k))b.jsDoc=k}F.push(b)}}return F}import{resolve as Fn,dirname as Dt,extname as kt}from"path";function _n(n,t,i){let e=(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=Fn(Dt(n),t);return e(r)}if(i)for(let[r,s]of i.paths){if(s.length===0)continue;let m=r.indexOf("*");if(m===-1){if(t===r){let u=[];for(let a of s)u.push(...e(Fn(i.baseUrl,a)));return u}}else{let u=r.slice(0,m),a=r.slice(m+1);if(t.startsWith(u)&&(a===""||t.endsWith(a))){let p=t.slice(u.length,a===""?void 0:t.length-a.length),l=[];for(let d of s)l.push(...e(Fn(i.baseUrl,d.replace("*",p))));return l}}}return[]}function vn(n,t,i,e=_n){let r=new Map,s=n.body??[];for(let m of s){if(m.type!=="ImportDeclaration")continue;let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],l=m.specifiers??[];for(let d of l)switch(d.type){case"ImportSpecifier":r.set(d.local.name,{path:p,importedName:d.imported.name});break;case"ImportDefaultSpecifier":r.set(d.local.name,{path:p,importedName:"default"});break;case"ImportNamespaceSpecifier":r.set(d.local.name,{path:p,importedName:"*"});break}}return r}var Ft=new Set(["loc","start","end","scope"]);function an(n,t){if(!n||typeof n!=="object")return;if(Array.isArray(n)){for(let e of n)an(e,t);return}let i=n;t(i);for(let e of Object.keys(i)){if(Ft.has(e))continue;let r=i[e];if(r&&typeof r==="object")an(r,t)}}function Xn(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 nn(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n;if(t.type==="Identifier"){let i=t.name;return{root:i,parts:[],full:i}}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 i=[],e=t;while(e.type==="MemberExpression"){let m=e.property;if(!m||typeof m.name!=="string")return null;i.unshift(m.name),e=e.object}let r;if(e.type==="Identifier")r=e.name;else if(e.type==="ThisExpression")r="this";else if(e.type==="Super")r="super";else return null;let s=[r,...i].join(".");return{root:r,parts:i,full:s}}return null}function Pn(n,t,i,e=_n){let r=[],s=n.body??[];for(let m of s){if(m.type==="ImportDeclaration"){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],l=m.importKind==="type",d=m.specifiers??[];if(d.length===0){let S={};if(l)S.isType=!0;r.push({type:l?"type-references":"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,...Object.keys(S).length>0?{metaJson:JSON.stringify(S)}:{}})}else for(let S of d){let N=S.type,J=l||S.importKind==="type",A={};if(J)A.isType=!0;let F,c;if(N==="ImportDefaultSpecifier")F="default",c=S.local.name;else if(N==="ImportNamespaceSpecifier")F="*",c=S.local.name,A.importKind="namespace";else F=S.imported.name,c=S.local.name;r.push({type:J?"type-references":"imports",srcFilePath:t,srcSymbolName:c,dstFilePath:p,dstSymbolName:F,...Object.keys(A).length>0?{metaJson:JSON.stringify(A)}:{}})}continue}if(m.type==="ExportAllDeclaration"&&m.source){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],l=m.exportKind==="type",d={isReExport:!0};if(l)d.isType=!0;r.push({type:l?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify(d)});continue}if(m.type==="ExportNamedDeclaration"&&m.source){let u=m.source?.value??"",a=e(t,u,i);if(a.length===0)continue;let p=a[0],l=m.exportKind==="type",N={isReExport:!0,specifiers:(m.specifiers??[]).map((J)=>({local:J.local.name,exported:J.exported.name}))};if(l)N.isType=!0;r.push({type:l?"type-references":"re-exports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify(N)})}}return an(n,(m)=>{if(m.type!=="ImportExpression")return;let u=Xn(m.source);if(!u)return;let a=e(t,u,i);if(a.length===0)return;let p=a[0];r.push({type:"imports",srcFilePath:t,srcSymbolName:null,dstFilePath:p,dstSymbolName:null,metaJson:JSON.stringify({isDynamic:!0})})}),r}function En(n,t,i){let e=[],r=[],s=[];function m(){if(r.length>0)return r[r.length-1]??null;return null}function u(p){if(!p)return null;let l=i.get(p.root);if(p.parts.length===0){if(l)return{dstFilePath:l.path,dstSymbolName:l.importedName,resolution:"import"};return{dstFilePath:t,dstSymbolName:p.root,resolution:"local"}}else{if(l&&l.importedName==="*"){let d=p.parts[p.parts.length-1];return{dstFilePath:l.path,dstSymbolName:d,resolution:"namespace"}}return{dstFilePath:t,dstSymbolName:p.full,resolution:"local-member"}}}function a(p){if(!p||typeof p!=="object")return;if(Array.isArray(p)){for(let S of p)a(S);return}let l=p,d=typeof l.type==="string"?l.type:"";if(d==="ClassDeclaration"||d==="ClassExpression"){let S=l,N=S.id?.name??"AnonymousClass";s.push(N),a(S.body),s.pop();return}if(d==="FunctionDeclaration"){let S=l,N=S.id?.name??"anonymous";r.push(N),a(S.body),r.pop();return}if(d==="VariableDeclarator"&&l.init&&(l.init?.type==="FunctionExpression"||l.init?.type==="ArrowFunctionExpression")){let S=l,N=S.id?.name??"anonymous";r.push(N),a(S.init?.body??S.init),r.pop();return}if(d==="MethodDefinition"&&l.value){let S=l,N=s[s.length-1]??"",J=S.key?.name??"anonymous",A=N?`${N}.${J}`:J;r.push(A),a(S.value?.body),r.pop();return}if(d==="FunctionExpression"||d==="ArrowFunctionExpression"){let S=m(),N=S?`${S}.<anonymous>`:"<anonymous>";r.push(N),a(l.body),r.pop();return}if(d==="CallExpression"){let S=l,N=nn(S.callee),J=u(N);if(J){let A=m(),F={};if(A===null)F.scope="module";e.push({type:"calls",srcFilePath:t,srcSymbolName:A,dstFilePath:J.dstFilePath,dstSymbolName:J.dstSymbolName,...Object.keys(F).length>0?{metaJson:JSON.stringify(F)}:{}})}a(S.callee);for(let A of S.arguments??[])a(A);return}if(d==="NewExpression"){let S=l,N=nn(S.callee),J=u(N);if(J){let A=m(),F={isNew:!0};if(A===null)F.scope="module";e.push({type:"calls",srcFilePath:t,srcSymbolName:A,dstFilePath:J.dstFilePath,dstSymbolName:J.dstSymbolName,metaJson:JSON.stringify(F)})}for(let A of S.arguments??[])a(A);return}for(let S of Object.keys(l)){if(S==="loc"||S==="start"||S==="end"||S==="scope")continue;let N=l[S];if(N&&typeof N==="object")a(N)}}return a(n),e}function jn(n,t,i){let e=[];return an(n,(r)=>{if(r.type==="TSInterfaceDeclaration"){let u=r.id?.name??"AnonymousInterface",a=r.extends??[];for(let p of a){let l=p.expression??p,d=nn(l);if(!d)continue;let S=Jn(d,t,i);e.push({type:"extends",srcFilePath:t,srcSymbolName:u,...S})}return}if(r.type!=="ClassDeclaration"&&r.type!=="ClassExpression")return;let s=r.id?.name??"AnonymousClass";if(r.superClass){let u=nn(r.superClass);if(u){let a=Jn(u,t,i);e.push({type:"extends",srcFilePath:t,srcSymbolName:s,...a})}}let m=r.implements??[];for(let u of m){let a=u.expression??u,p=nn(a);if(!p)continue;let l=Jn(p,t,i);e.push({type:"implements",srcFilePath:t,srcSymbolName:s,...l})}}),e}function Jn(n,t,i){let e=i.get(n.root);if(e){if(e.importedName==="*"){let r=n.parts[n.parts.length-1]??n.root;return{dstFilePath:e.path,dstSymbolName:r,metaJson:JSON.stringify({isNamespaceImport:!0})}}return{dstFilePath:e.path,dstSymbolName:n.parts.length>0?n.full:e.importedName}}return{dstFilePath:t,dstSymbolName:n.full,metaJson:JSON.stringify({isLocal:!0})}}function pn(n,t,i){let e=vn(n,t,i),r=Pn(n,t,i),s=En(n,t,e),m=jn(n,t,e);return[...r,...s,...m]}import{err as qn,isErr as It}from"@zipbul/result";import{Database as Kt}from"bun:sqlite";import{mkdirSync as Rt,unlinkSync as nt,existsSync as tt}from"fs";import{dirname as Tt,join as it}from"path";import{drizzle as zt}from"drizzle-orm/bun-sqlite";import{migrate as Lt}from"drizzle-orm/bun-sqlite/migrator";var X=".gildash",gn="gildash.db";var $n={};St($n,{watcherOwner:()=>Ct,symbols:()=>_,relations:()=>w,files:()=>z});import{sql as _t}from"drizzle-orm";import{sqliteTable as xn,text as T,integer as H,real as Jt,index as tn,primaryKey as Mt,foreignKey as Mn,check as $t}from"drizzle-orm/sqlite-core";var z=xn("files",{project:T("project").notNull(),filePath:T("file_path").notNull(),mtimeMs:Jt("mtime_ms").notNull(),size:H("size").notNull(),contentHash:T("content_hash").notNull(),updatedAt:T("updated_at").notNull(),lineCount:H("line_count")},(n)=>[Mt({columns:[n.project,n.filePath]})]),_=xn("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)=>[tn("idx_symbols_project_file").on(n.project,n.filePath),tn("idx_symbols_project_kind").on(n.project,n.kind),tn("idx_symbols_project_name").on(n.project,n.name),tn("idx_symbols_fingerprint").on(n.project,n.fingerprint),Mn({columns:[n.project,n.filePath],foreignColumns:[z.project,z.filePath]}).onDelete("cascade")]),w=xn("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)=>[tn("idx_relations_src").on(n.project,n.srcFilePath),tn("idx_relations_dst").on(n.project,n.dstFilePath),tn("idx_relations_type").on(n.project,n.type),Mn({columns:[n.project,n.srcFilePath],foreignColumns:[z.project,z.filePath]}).onDelete("cascade"),Mn({columns:[n.project,n.dstFilePath],foreignColumns:[z.project,z.filePath]}).onDelete("cascade")]),Ct=xn("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",_t`${n.id} = 1`)]);class Cn{client=null;drizzle=null;dbPath;txDepth=0;constructor(n){this.dbPath=it(n.projectRoot,X,gn)}get drizzleDb(){if(!this.drizzle)throw Error("Database is not open. Call open() first.");return this.drizzle}open(){try{Rt(Tt(this.dbPath),{recursive:!0}),this.client=new Kt(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=zt(this.client,{schema:$n}),Lt(this.drizzle,{migrationsFolder:it(import.meta.dirname,"migrations")});let n=this.client;if(typeof n.function==="function")n.function.call(this.client,"regexp",(t,i)=>{try{return new RegExp(t).test(i)?1:0}catch{return 0}})}catch(n){if(this.isCorruptionError(n)&&tt(this.dbPath)){this.closeClient(),nt(this.dbPath);for(let i of["-wal","-shm"]){let e=this.dbPath+i;if(tt(e))nt(e)}let t=this.open();if(It(t))return qn(y("store",`Failed to recover database at ${this.dbPath}`,t.data));return t}return qn(y("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 i=`sp_${this.txDepth++}`;t.run(`SAVEPOINT "${i}"`);try{let e=n(this);return t.run(`RELEASE SAVEPOINT "${i}"`),e}catch(e){throw t.run(`ROLLBACK TO SAVEPOINT "${i}"`),t.run(`RELEASE SAVEPOINT "${i}"`),e}finally{this.txDepth--}}immediateTransaction(n){let t=this.requireClient();this.txDepth++,t.run("BEGIN IMMEDIATE");try{let i=n();return t.run("COMMIT"),i}catch(i){throw t.run("ROLLBACK"),i}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 mn,and as et}from"drizzle-orm";class In{db;constructor(n){this.db=n}getFile(n,t){return this.db.drizzleDb.select().from(z).where(et(mn(z.project,n),mn(z.filePath,t))).get()??null}upsertFile(n){this.db.drizzleDb.insert(z).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:[z.project,z.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(z).where(mn(z.project,n)).all()}getFilesMap(n){let t=this.getAllFiles(n),i=new Map;for(let e of t)i.set(e.filePath,e);return i}deleteFile(n,t){this.db.drizzleDb.delete(z).where(et(mn(z.project,n),mn(z.filePath,t))).run()}}import{eq as G,and as en,sql as yn,count as Gt}from"drizzle-orm";function dn(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,i,e){if(this.db.drizzleDb.delete(_).where(en(G(_.project,n),G(_.filePath,t))).run(),!e.length)return;let r=new Date().toISOString();for(let s of e)this.db.drizzleDb.insert(_).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:i,indexedAt:s.indexedAt??r}).run()}getFileSymbols(n,t){return this.db.drizzleDb.select().from(_).where(en(G(_.project,n),G(_.filePath,t))).all()}searchByName(n,t,i={}){let e=i.limit??50,r=dn(t);if(!r)return[];return this.db.drizzleDb.select().from(_).where(en(yn`${_.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${r})`,G(_.project,n),i.kind?G(_.kind,i.kind):void 0)).orderBy(_.name).limit(e).all()}searchByKind(n,t){return this.db.drizzleDb.select().from(_).where(en(G(_.project,n),G(_.kind,t))).orderBy(_.name).all()}getStats(n){let t=this.db.drizzleDb.select({symbolCount:Gt(),fileCount:yn`COUNT(DISTINCT ${_.filePath})`}).from(_).where(G(_.project,n)).get();return{symbolCount:t?.symbolCount??0,fileCount:t?.fileCount??0}}getByFingerprint(n,t){return this.db.drizzleDb.select().from(_).where(en(G(_.project,n),G(_.fingerprint,t))).all()}deleteFileSymbols(n,t){this.db.drizzleDb.delete(_).where(en(G(_.project,n),G(_.filePath,t))).run()}searchByQuery(n){let t=this.db.drizzleDb.select().from(_).where(en(n.ftsQuery?yn`${_.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${n.ftsQuery})`:void 0,n.exactName?G(_.name,n.exactName):void 0,n.project!==void 0?G(_.project,n.project):void 0,n.kind?G(_.kind,n.kind):void 0,n.filePath!==void 0?G(_.filePath,n.filePath):void 0,n.isExported!==void 0?G(_.isExported,n.isExported?1:0):void 0,n.decorator?yn`${_.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(_.name).limit(n.regex?Math.max(n.limit*50,5000):n.limit).all();if(!n.regex)return t;try{let i=new RegExp(n.regex);return t.filter((e)=>i.test(e.name)).slice(0,n.limit)}catch{return[]}}}import{eq as R,and as Y,isNull as rt,or as Bt}from"drizzle-orm";class Rn{db;constructor(n){this.db=n}replaceFileRelations(n,t,i){if(this.db.drizzleDb.delete(w).where(Y(R(w.project,n),R(w.srcFilePath,t))).run(),!i.length)return;for(let e of i)this.db.drizzleDb.insert(w).values({project:n,type:e.type??"unknown",srcFilePath:e.srcFilePath??t,srcSymbolName:e.srcSymbolName??null,dstFilePath:e.dstFilePath??"",dstSymbolName:e.dstSymbolName??null,metaJson:e.metaJson??null}).run()}getOutgoing(n,t,i){if(i!==void 0)return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(Y(R(w.project,n),R(w.srcFilePath,t),Bt(R(w.srcSymbolName,i),rt(w.srcSymbolName)))).all();return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(Y(R(w.project,n),R(w.srcFilePath,t))).all()}getIncoming(n,t){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(Y(R(w.project,n),R(w.dstFilePath,t))).all()}getByType(n,t){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(Y(R(w.project,n),R(w.type,t))).all()}deleteFileRelations(n,t){this.db.drizzleDb.delete(w).where(Y(R(w.project,n),R(w.srcFilePath,t))).run()}searchRelations(n){return this.db.drizzleDb.select({project:w.project,type:w.type,srcFilePath:w.srcFilePath,srcSymbolName:w.srcSymbolName,dstFilePath:w.dstFilePath,dstSymbolName:w.dstSymbolName,metaJson:w.metaJson}).from(w).where(Y(n.project!==void 0?R(w.project,n.project):void 0,n.srcFilePath!==void 0?R(w.srcFilePath,n.srcFilePath):void 0,n.srcSymbolName!==void 0?R(w.srcSymbolName,n.srcSymbolName):void 0,n.dstFilePath!==void 0?R(w.dstFilePath,n.dstFilePath):void 0,n.dstSymbolName!==void 0?R(w.dstSymbolName,n.dstSymbolName):void 0,n.type!==void 0?R(w.type,n.type):void 0)).limit(n.limit).all()}retargetRelations(n,t,i,e,r){let s=i===null?Y(R(w.project,n),R(w.dstFilePath,t),rt(w.dstSymbolName)):Y(R(w.project,n),R(w.dstFilePath,t),R(w.dstSymbolName,i));this.db.drizzleDb.update(w).set({dstFilePath:e,dstSymbolName:r}).where(s).run()}}import{err as st}from"@zipbul/result";import{subscribe as Wt}from"@parcel/watcher";import Tn from"path";var Ht=["**/.git/**",`**/${X}/**`,"**/dist/**","**/node_modules/**"],Ut=new Set(["package.json","tsconfig.json"]);function Vt(n){return n.replaceAll("\\","/")}function Qt(n){if(n==="update")return"change";if(n==="create")return"create";return"delete"}class wn{#t;#n;#e;#r;#s;#i;constructor(n,t=Wt,i=console){this.#n=n.projectRoot,this.#e=[...Ht,...n.ignorePatterns??[]],this.#r=new Set((n.extensions??[".ts",".mts",".cts"]).map((e)=>e.toLowerCase())),this.#s=t,this.#i=i}async start(n){try{this.#t=await this.#s(this.#n,(t,i)=>{if(t){this.#i.error(y("watcher","Callback error",t));return}try{for(let e of i){let r=Vt(Tn.relative(this.#n,e.path));if(r.startsWith(".."))continue;let s=Tn.basename(r),m=Tn.extname(r).toLowerCase();if(!Ut.has(s)&&!this.#r.has(m))continue;if(r.endsWith(".d.ts"))continue;n({eventType:Qt(e.type),filePath:r})}}catch(e){this.#i.error(y("watcher","Callback error",e))}},{ignore:this.#e})}catch(t){return st(y("watcher","Failed to subscribe watcher",t))}}async close(){if(!this.#t)return;try{await this.#t.unsubscribe(),this.#t=void 0}catch(n){return st(y("watcher","Failed to close watcher",n))}}}import zn from"path";import{promises as Yt}from"fs";var Zt=["**/node_modules/**","**/.git/**",`**/${X}/**`,"**/dist/**"];async function Sn(n){let t=[];for await(let i of Yt.glob("**/package.json",{cwd:n,exclude:Zt})){let e=zn.dirname(i).replaceAll("\\","/"),r=zn.join(n,i),s=await Bun.file(r).json(),m=typeof s?.name==="string"&&s.name.length>0?s.name:zn.basename(e==="."?n:e);t.push({dir:e,project:m})}return t.sort((i,e)=>e.dir.length-i.dir.length),t}function U(n,t,i="default"){let e=n.replaceAll("\\","/");for(let r of t){if(r.dir===".")return r.project;if(e===r.dir||e.startsWith(`${r.dir}/`))return r.project}return i}import at from"path";var P=new Map;async function vt(n){let t=Bun.file(n);if(!await t.exists())return null;try{let i=await t.text(),e=Bun.JSONC.parse(i);return typeof e==="object"&&e!==null?e:null}catch{return null}}async function cn(n){if(P.has(n))return P.get(n)??null;let t=at.join(n,"tsconfig.json"),i=await vt(t);if(!i)return P.set(n,null),null;let e=typeof i.compilerOptions==="object"&&i.compilerOptions!==null?i.compilerOptions:null;if(!e)return P.set(n,null),null;let r=typeof e.baseUrl==="string"?e.baseUrl:null,s=typeof e.paths==="object"&&e.paths!==null?e.paths:null;if(!r&&!s)return P.set(n,null),null;let m=r?at.resolve(n,r):n,u=new Map;if(s)for(let[p,l]of Object.entries(s)){if(!Array.isArray(l))continue;let d=l.filter((S)=>typeof S==="string");u.set(p,d)}let a={baseUrl:m,paths:u};return P.set(n,a),a}function bn(n){if(n){P.delete(n);return}P.clear()}import ot from"path";function Ln(n,t){return ot.relative(n,t).replaceAll("\\","/")}function on(n,t){return ot.resolve(n,t)}function E(n){let t=Bun.hash.xxHash64(n);return BigInt.asUintN(64,BigInt(t)).toString(16).padStart(16,"0")}import{isErr as ct}from"@zipbul/result";import{promises as Xt}from"fs";import{join as Pt}from"path";async function ut(n){let{projectRoot:t,extensions:i,ignorePatterns:e,fileRepo:r}=n,s=r.getFilesMap(),m=new Set,u=[],a=[],p=e.map((d)=>new Bun.Glob(d));for await(let d of Xt.glob("**/*",{cwd:t})){if(!i.some((o)=>d.endsWith(o)))continue;if(p.some((o)=>o.match(d)))continue;m.add(d);let S=Pt(t,d),N=Bun.file(S),{size:J,lastModified:A}=N,F=s.get(d);if(!F){let o=await N.text(),f=E(o);u.push({filePath:d,contentHash:f,mtimeMs:A,size:J});continue}if(F.mtimeMs===A&&F.size===J){a.push({filePath:d,contentHash:F.contentHash,mtimeMs:A,size:J});continue}let c=await N.text(),g=E(c);if(g===F.contentHash)a.push({filePath:d,contentHash:g,mtimeMs:A,size:J});else u.push({filePath:d,contentHash:g,mtimeMs:A,size:J})}let l=[];for(let d of s.keys())if(!m.has(d))l.push(d);return{changed:u,unchanged:a,deleted:l}}function Et(n){if(n.kind==="function"||n.kind==="method"){let t=n.parameters?.length??0,i=n.modifiers.includes("async")?1:0;return`params:${t}|async:${i}`}return null}function jt(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((i)=>{let e=i.modifiers.find((r)=>r==="private"||r==="protected"||r==="public");return{name:i.name,kind:i.methodKind??i.kind,type:i.returnType,visibility:e,isStatic:i.modifiers.includes("static")||void 0,isReadonly:i.modifiers.includes("readonly")||void 0}});return Object.keys(t).length>0?JSON.stringify(t):null}function mt(n,t,i,e,r){let s=Et(n),m=E(`${t}|${n.kind}|${s??""}`);return{project:i,filePath:e,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:m,detailJson:jt(n),contentHash:r,indexedAt:new Date().toISOString()}}function Gn(n){let{parsed:t,project:i,filePath:e,contentHash:r,symbolRepo:s}=n,m=ln(t),u=[];for(let a of m){u.push(mt(a,a.name,i,e,r));for(let p of a.members??[])u.push(mt(p,`${a.name}.${p.name}`,i,e,r))}s.replaceFileSymbols(i,e,r,u)}function Bn(n){let{ast:t,project:i,filePath:e,relationRepo:r,projectRoot:s,tsconfigPaths:m}=n,u=on(s,e),a=pn(t,u,m),p=[];for(let l of a){let d=Ln(s,l.dstFilePath);if(d.startsWith(".."))continue;let S=Ln(s,l.srcFilePath);p.push({project:i,type:l.type,srcFilePath:S,srcSymbolName:l.srcSymbolName??null,dstFilePath:d,dstSymbolName:l.dstSymbolName??null,metaJson:l.metaJson??null})}return r.replaceFileRelations(i,e,p),p.length}var qt=100;class fn{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=cn(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=cn(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??Sn;this.boundariesRefresh=t(this.opts.projectRoot).then((i)=>{this.opts.boundaries=i})}if(this.pendingEvents.push(n),this.debounceTimer===null)this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.flushPending()},qt)}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((e,r)=>{this.pendingFullIndexWaiters.push({resolve:e,reject:r})});return this.currentIndexing}this.indexingLock=!0;let i=this.doIndex(n,t).then((e)=>{return this.fireCallbacks(e),e}).finally(()=>{if(this.indexingLock=!1,this.currentIndexing=null,this.pendingFullIndex){this.pendingFullIndex=!1;let e=this.pendingFullIndexWaiters.splice(0);this.startIndex(void 0,!0).then((r)=>{for(let s of e)s.resolve(r)}).catch((r)=>{for(let s of e)s.reject(r)})}else if(this.pendingEvents.length>0){let e=this.pendingEvents.splice(0);this.startIndex(e,!1).catch((r)=>this.logger.error("[IndexCoordinator] incremental drain error",r))}});return this.currentIndexing=i,i}async doIndex(n,t){let i=Date.now(),{fileRepo:e,symbolRepo:r,relationRepo:s,dbConnection:m}=this.opts;if(this.boundariesRefresh)await this.boundariesRefresh,this.boundariesRefresh=null;let u,a;if(n!==void 0)u=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 x of this.opts.boundaries)for(let[b,D]of e.getFilesMap(x.project))o.set(b,D);let f=await ut({projectRoot:this.opts.projectRoot,extensions:this.opts.extensions,ignorePatterns:this.opts.ignorePatterns,fileRepo:{getFilesMap:()=>o}});u=f.changed,a=f.deleted}let p=await this.tsconfigPathsRaw??void 0,l=new Map;for(let o of a){let f=U(o,this.opts.boundaries),x=r.getFileSymbols(f,o);l.set(o,x)}let d=new Map,S=new Map;if(t)for(let o of this.opts.boundaries)for(let f of e.getAllFiles(o.project))for(let x of r.getFileSymbols(o.project,f.filePath))d.set(`${x.filePath}::${x.name}`,{name:x.name,filePath:x.filePath,kind:x.kind,fingerprint:x.fingerprint});else{for(let o of u){let f=U(o.filePath,this.opts.boundaries);for(let x of r.getFileSymbols(f,o.filePath))d.set(`${x.filePath}::${x.name}`,{name:x.name,filePath:x.filePath,kind:x.kind,fingerprint:x.fingerprint})}for(let[,o]of l)for(let f of o)d.set(`${f.filePath}::${f.name}`,{name:f.name,filePath:f.filePath,kind:f.kind,fingerprint:f.fingerprint})}let N=()=>{for(let o of a){let f=U(o,this.opts.boundaries);r.deleteFileSymbols(f,o),s.deleteFileRelations(f,o),e.deleteFile(f,o)}},J=async()=>{let o=0,f=0,x=[];for(let b of u)try{let D=await this.processFile(b.filePath,b.contentHash||void 0,p);o+=D.symbolCount,f+=D.relCount}catch(D){this.logger.error(`[IndexCoordinator] Failed to index ${b.filePath}:`,D),x.push(b.filePath)}return{symbols:o,relations:f,failedFiles:x}},A=0,F=0,c=[];if(t){let{projectRoot:o,boundaries:f}=this.opts,{parseCache:x}=this.opts,b=await Promise.allSettled(u.map(async(k)=>{let h=on(o,k.filePath),M=Bun.file(h),C=await M.text(),I=k.contentHash||E(C);return{filePath:k.filePath,text:C,contentHash:I,mtimeMs:M.lastModified,size:M.size}})),D=b.filter((k)=>k.status==="fulfilled").map((k)=>k.value);for(let k of b)if(k.status==="rejected")this.logger.error("[IndexCoordinator] Failed to pre-read file:",k.reason);let $=[];m.transaction(()=>{for(let h of D){let M=U(h.filePath,f);e.deleteFile(M,h.filePath)}for(let h of a){let M=U(h,f);r.deleteFileSymbols(M,h),s.deleteFileRelations(M,h),e.deleteFile(M,h)}for(let h of D){let M=U(h.filePath,f);e.upsertFile({project:M,filePath:h.filePath,mtimeMs:h.mtimeMs,size:h.size,contentHash:h.contentHash,updatedAt:new Date().toISOString(),lineCount:h.text.split(`
|
|
4
|
+
`).length})}let k=this.opts.parseSourceFn??un;for(let h of D){let M=U(h.filePath,f),C=k(on(o,h.filePath),h.text);if(ct(C))throw C.data;let I=C;$.push({filePath:h.filePath,parsed:I}),Gn({parsed:I,project:M,filePath:h.filePath,contentHash:h.contentHash,symbolRepo:r}),F+=Bn({ast:I.program,project:M,filePath:h.filePath,relationRepo:s,projectRoot:o,tsconfigPaths:p}),A+=r.getFileSymbols(M,h.filePath).length}});for(let k of $)x.set(k.filePath,k.parsed)}else{N();let o=await J();A=o.symbols,F=o.relations,c=o.failedFiles}for(let o of u){let f=U(o.filePath,this.opts.boundaries);for(let x of r.getFileSymbols(f,o.filePath))S.set(`${x.filePath}::${x.name}`,{name:x.name,filePath:x.filePath,kind:x.kind,fingerprint:x.fingerprint})}let g={added:[],modified:[],removed:[]};for(let[o,f]of S){let x=d.get(o);if(!x)g.added.push({name:f.name,filePath:f.filePath,kind:f.kind});else if(x.fingerprint!==f.fingerprint)g.modified.push({name:f.name,filePath:f.filePath,kind:f.kind})}for(let[o,f]of d)if(!S.has(o))g.removed.push({name:f.name,filePath:f.filePath,kind:f.kind});if(!t)for(let[o,f]of l)for(let x of f){if(!x.fingerprint)continue;let b=U(o,this.opts.boundaries),D=r.getByFingerprint(b,x.fingerprint);if(D.length===1){let $=D[0];s.retargetRelations(b,o,x.name,$.filePath,$.name)}}return{indexedFiles:u.length,removedFiles:a.length,totalSymbols:A,totalRelations:F,durationMs:Date.now()-i,changedFiles:u.map((o)=>o.filePath),deletedFiles:[...a],failedFiles:c,changedSymbols:g}}async processFile(n,t,i){let{projectRoot:e,boundaries:r}=this.opts,{fileRepo:s,symbolRepo:m,relationRepo:u,parseCache:a}=this.opts,p=on(e,n),l=Bun.file(p),d=await l.text(),S=t||E(d),N=U(n,r),A=(this.opts.parseSourceFn??un)(p,d);if(ct(A))throw A.data;let F=A;a.set(n,F),s.upsertFile({project:N,filePath:n,mtimeMs:l.lastModified,size:l.size,contentHash:S,updatedAt:new Date().toISOString(),lineCount:d.split(`
|
|
5
|
+
`).length}),Gn({parsed:F,project:N,filePath:n,contentHash:S,symbolRepo:m});let c=Bn({ast:F.program,project:N,filePath:n,relationRepo:u,projectRoot:e,tsconfigPaths:i});return{symbolCount:m.getFileSymbols(N,n).length,relCount:c}}fireCallbacks(n){for(let t of this.callbacks)try{t(n)}catch(i){this.logger.error("[IndexCoordinator] onIndexed callback threw:",i)}}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 ni(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 ti(n){let t=new Date(n).getTime();return Number.isNaN(t)?0:t}function ft(n,t,i={}){let e=i.now??Date.now,r=i.isAlive??ni,s=i.staleAfterSeconds??90;return n.immediateTransaction(()=>{let m=n.selectOwner();if(!m)return n.insertOwner(t),"owner";let u=Math.floor((e()-ti(m.heartbeat_at))/1000);if(r(m.pid)&&u<s)return"reader";return n.replaceOwner(t),"owner"})}function lt(n,t){n.deleteOwner(t)}function pt(n,t){n.touchOwner(t)}function Wn(n){let{symbolRepo:t,project:i,query:e}=n,r=e.project??i,s=e.limit??100,m={kind:e.kind,filePath:e.filePath,isExported:e.isExported,project:r,limit:s};if(e.text)if(e.exact)m.exactName=e.text;else{let a=dn(e.text);if(a)m.ftsQuery=a}if(e.decorator)m.decorator=e.decorator;if(e.regex)m.regex=e.regex;return t.searchByQuery(m).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 Hn(n){let{relationRepo:t,project:i,query:e}=n,r=e.project??i,s=e.limit??500;return t.searchRelations({srcFilePath:e.srcFilePath,srcSymbolName:e.srcSymbolName,dstFilePath:e.dstFilePath,dstSymbolName:e.dstSymbolName,type:e.type,project:r,limit:s}).map((u)=>{let a;if(u.metaJson)try{a=JSON.parse(u.metaJson)}catch{console.error("[relationSearch] malformed metaJson:",u.metaJson)}return{type:u.type,srcFilePath:u.srcFilePath,srcSymbolName:u.srcSymbolName,dstFilePath:u.dstFilePath,dstSymbolName:u.dstSymbolName,metaJson:u.metaJson??void 0,meta:a}})}class On{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:i,dstFilePath:e}=t;if(!this.adjacencyList.has(i))this.adjacencyList.set(i,new Set);if(this.adjacencyList.get(i).add(e),!this.adjacencyList.has(e))this.adjacencyList.set(e,new Set);if(!this.reverseAdjacencyList.has(e))this.reverseAdjacencyList.set(e,new Set);this.reverseAdjacencyList.get(e).add(i)}}getDependencies(n){return Array.from(this.adjacencyList.get(n)??[])}getDependents(n){return Array.from(this.reverseAdjacencyList.get(n)??[])}getTransitiveDependents(n){let t=new Set,i=[n];while(i.length>0){let e=i.shift();for(let r of this.reverseAdjacencyList.get(e)??[])if(!t.has(r))t.add(r),i.push(r)}return Array.from(t)}hasCycle(){let n=new Set,t=new Set;for(let i of this.adjacencyList.keys()){if(n.has(i))continue;let e=[{node:i,entered:!1}];while(e.length>0){let r=e.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),e.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))e.push({node:s,entered:!1})}}}return!1}getAffectedByChange(n){let t=new Set;for(let i of n)for(let e of this.getTransitiveDependents(i))t.add(e);return Array.from(t)}getAdjacencyList(){let n=new Map;for(let[t,i]of this.adjacencyList)n.set(t,Array.from(i));return n}getTransitiveDependencies(n){let t=new Set,i=[n];while(i.length>0){let e=i.shift();for(let r of this.adjacencyList.get(e)??[])if(!t.has(r))t.add(r),i.push(r)}return Array.from(t)}getCyclePaths(n){let t=n?.maxCycles??1/0;if(t<=0)return[];let i=new Map;for(let[e,r]of this.adjacencyList)i.set(e,Array.from(r));return ai(i,t)}}var ii=(n,t)=>n.localeCompare(t);function ei(n){let t=n.length>1&&n[0]===n[n.length-1]?n.slice(0,-1):[...n];if(t.length===0)return[];let i=t;for(let e=1;e<t.length;e++){let r=t.slice(e).concat(t.slice(0,e));if(r.join("::")<i.join("::"))i=r}return[...i]}function Un(n,t,i){let e=ei(i);if(e.length===0)return!1;let r=e.join("->");if(n.has(r))return!1;return n.add(r),t.push(e),!0}function ri(n){let t=0,i=[],e=new Set,r=new Map,s=new Map,m=[],u=(a)=>{r.set(a,t),s.set(a,t),t+=1,i.push(a),e.add(a);for(let p of n.get(a)??[])if(!r.has(p))u(p),s.set(a,Math.min(s.get(a)??0,s.get(p)??0));else if(e.has(p))s.set(a,Math.min(s.get(a)??0,r.get(p)??0));if(s.get(a)===r.get(a)){let p=[],l="";do l=i.pop()??"",e.delete(l),p.push(l);while(l!==a&&i.length>0);m.push(p)}};for(let a of n.keys())if(!r.has(a))u(a);return{components:m}}function si(n,t,i){let e=[],r=new Set,s=[...n].sort(ii),m=(u,a,p)=>{a.delete(u);let l=p.get(u);if(!l)return;for(let d of l)if(a.has(d))m(d,a,p);l.clear()};for(let u=0;u<s.length&&e.length<i;u++){let a=s[u]??"",p=new Set(s.slice(u)),l=new Set,d=new Map,S=[],N=(A)=>(t.get(A)??[]).filter((F)=>p.has(F)),J=(A)=>{if(e.length>=i)return!0;let F=!1;S.push(A),l.add(A);for(let c of N(A)){if(e.length>=i)break;if(c===a)Un(r,e,S.concat(a)),F=!0;else if(!l.has(c)){if(J(c))F=!0}}if(F)m(A,l,d);else for(let c of N(A)){let g=d.get(c)??new Set;g.add(A),d.set(c,g)}return S.pop(),F};J(a)}return e}function ai(n,t){let{components:i}=ri(n),e=[],r=new Set;for(let s of i){if(e.length>=t)break;if(s.length===0)continue;if(s.length===1){let a=s[0]??"";if((n.get(a)??[]).includes(a))Un(r,e,[a,a]);continue}let m=t-e.length,u=si(s,n,m);for(let a of u){if(e.length>=t)break;Un(r,e,a)}}return e}import{findInFiles as oi,Lang as ui}from"@ast-grep/napi";async function Vn(n){if(n.filePaths.length===0)return[];let t=[];return await oi(ui.TypeScript,{paths:n.filePaths,matcher:{rule:{pattern:n.pattern}}},(i,e)=>{if(i)return;for(let r of e){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 gt=30000,xt=60000,ci=10;class Qn{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:i=[".ts",".mts",".cts"],ignorePatterns:e=[],parseCacheCapacity:r=500,logger:s=console,existsSyncFn:m=mi,dbConnectionFactory:u,watcherFactory:a,coordinatorFactory:p,repositoryFactory:l,acquireWatcherRoleFn:d=ft,releaseWatcherRoleFn:S=lt,updateHeartbeatFn:N=pt,discoverProjectsFn:J=Sn,parseSourceFn:A=un,extractSymbolsFn:F=ln,extractRelationsFn:c=pn,symbolSearchFn:g=Wn,relationSearchFn:o=Hn,patternSearchFn:f=Vn,loadTsconfigPathsFn:x=cn,makeExternalCoordinatorFn:b,readFileFn:D=async(C)=>Bun.file(C).text(),unlinkFn:$=async(C)=>{await Bun.file(C).unlink()},watchMode:k}=n;if(!Nn.isAbsolute(t))return O(y("validation",`Gildash: projectRoot must be an absolute path, got: "${t}"`));if(!m(t))return O(y("validation",`Gildash: projectRoot does not exist: "${t}"`));let h=u?u():new Cn({projectRoot:t}),M=h.open();if(rn(M))return M;try{let C=await J(t),I=C[0]?.project??Nn.basename(t),L=l?l():(()=>{let B=h;return{fileRepo:new In(B),symbolRepo:new Kn(B),relationRepo:new Rn(B),parseCache:new Dn(r)}})(),sn=k??!0,Z;if(sn)Z=await Promise.resolve(d(h,process.pid,{}));else Z="owner";let dt=null,yt=null,K=new Qn({projectRoot:t,db:h,symbolRepo:L.symbolRepo,relationRepo:L.relationRepo,fileRepo:L.fileRepo,parseCache:L.parseCache,coordinator:dt,watcher:yt,releaseWatcherRoleFn:S,parseSourceFn:A,extractSymbolsFn:F,extractRelationsFn:c,symbolSearchFn:g,relationSearchFn:o,patternSearchFn:f,readFileFn:D,unlinkFn:$,existsSyncFn:m,makeExternalCoordinatorFn:b,logger:s,defaultProject:I,role:Z});if(bn(t),K.tsconfigPaths=await x(t),K.boundaries=C,Z==="owner"){let B=p?p():new fn({projectRoot:t,boundaries:C,extensions:i,ignorePatterns:e,dbConnection:h,parseCache:L.parseCache,fileRepo:L.fileRepo,symbolRepo:L.symbolRepo,relationRepo:L.relationRepo,logger:s});if(K.coordinator=B,B.onIndexed(()=>K.invalidateGraphCache()),sn){let V=a?a():new wn({projectRoot:t,ignorePatterns:e,extensions:i},void 0,s);K.watcher=V,await V.start((Q)=>B.handleWatcherEvent?.(Q)).then((Q)=>{if(rn(Q))throw Q.data});let j=setInterval(()=>{N(h,process.pid)},gt);K.timer=j}await B.fullIndex()}else{let B=0,V=async()=>{try{let Q=await Promise.resolve(d(h,process.pid,{}));if(B=0,Q==="owner"){clearInterval(K.timer),K.timer=null;let q=null,v=null;try{q=a?a():new wn({projectRoot:t,ignorePatterns:e,extensions:i},void 0,s),v=p?p():new fn({projectRoot:t,boundaries:C,extensions:i,ignorePatterns:e,dbConnection:h,parseCache:L.parseCache,fileRepo:L.fileRepo,symbolRepo:L.symbolRepo,relationRepo:L.relationRepo,logger:s});for(let W of K.onIndexedCallbacks)v.onIndexed(W);v.onIndexed(()=>K.invalidateGraphCache()),await q.start((W)=>v?.handleWatcherEvent?.(W)).then((W)=>{if(rn(W))throw W.data});let hn=setInterval(()=>{N(h,process.pid)},gt);K.timer=hn,K.coordinator=v,K.watcher=q,await v.fullIndex()}catch(hn){if(s.error("[Gildash] owner promotion failed, reverting to reader",hn),q){let W=await q.close();if(rn(W))s.error("[Gildash] watcher close error during promotion rollback",W.data);K.watcher=null}if(v)await v.shutdown().catch((W)=>s.error("[Gildash] coordinator shutdown error during promotion rollback",W)),K.coordinator=null;if(K.timer===null)K.timer=setInterval(V,xt)}}}catch(Q){if(B++,s.error("[Gildash] healthcheck error",Q),B>=ci)s.error("[Gildash] healthcheck failed too many times, shutting down"),clearInterval(K.timer),K.timer=null,K.close().catch((q)=>s.error("[Gildash] close error during healthcheck shutdown",q))}},j=setInterval(V,xt);K.timer=j}if(sn){let B=["SIGTERM","SIGINT","beforeExit"];for(let V of B){let j=()=>{K.close().catch((Q)=>s.error("[Gildash] close error during signal",V,Q))};if(V==="beforeExit")process.on("beforeExit",j);else process.on(V,j);K.signalHandlers.push([V,j])}}return K}catch(C){return h.close(),O(y("store","Gildash: initialization failed",C))}}async close(n){if(this.closed)return;this.closed=!0;let t=[];for(let[i,e]of this.signalHandlers)if(i==="beforeExit")process.off("beforeExit",e);else process.off(i,e);if(this.signalHandlers=[],this.coordinator)try{await this.coordinator.shutdown()}catch(i){t.push(i instanceof Error?i:Error(String(i)))}if(this.watcher){let i=await this.watcher.close();if(rn(i))t.push(i.data)}if(this.timer!==null)clearInterval(this.timer),this.timer=null;try{this.releaseWatcherRoleFn(this.db,process.pid)}catch(i){t.push(i instanceof Error?i:Error(String(i)))}try{this.db.close()}catch(i){t.push(i instanceof Error?i:Error(String(i)))}if(n?.cleanup)for(let i of["","-wal","-shm"])try{await this.unlinkFn(Nn.join(this.projectRoot,X,gn+i))}catch{}if(t.length>0)return O(y("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,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));let e=this.parseSourceFn(n,t,i);if(rn(e))return e;return this.parseCache.set(n,e),e}extractSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));return this.extractSymbolsFn(n)}extractRelations(n){if(this.closed)return O(y("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 i=new On({relationRepo:this.relationRepo,project:n??this.defaultProject});return i.build(),this.graphCache=i,this.graphCacheKey=t,i}async reindex(){if(this.closed)return O(y("closed","Gildash: instance is closed"));if(!this.coordinator)return O(y("closed","Gildash: reindex() is not available for readers"));try{let n=await this.coordinator.fullIndex();return this.invalidateGraphCache(),n}catch(n){return O(y("index","Gildash: reindex failed",n))}}get projects(){return[...this.boundaries]}getStats(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolRepo.getStats(n??this.defaultProject)}catch(t){return O(y("store","Gildash: getStats failed",t))}}searchSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:this.defaultProject,query:n})}catch(t){return O(y("search","Gildash: searchSymbols failed",t))}}searchRelations(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:this.defaultProject,query:n})}catch(t){return O(y("search","Gildash: searchRelations failed",t))}}searchAllSymbols(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.symbolSearchFn({symbolRepo:this.symbolRepo,project:void 0,query:n})}catch(t){return O(y("search","Gildash: searchAllSymbols failed",t))}}searchAllRelations(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:void 0,query:n})}catch(t){return O(y("search","Gildash: searchAllRelations failed",t))}}listIndexedFiles(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.fileRepo.getAllFiles(n??this.defaultProject)}catch(t){return O(y("store","Gildash: listIndexedFiles failed",t))}}getInternalRelations(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.relationSearchFn({relationRepo:this.relationRepo,project:t??this.defaultProject,query:{srcFilePath:n,dstFilePath:n,limit:1e4}})}catch(i){return O(y("search","Gildash: getInternalRelations failed",i))}}diffSymbols(n,t){let i=new Map(n.map((u)=>[`${u.name}::${u.filePath}`,u])),e=new Map(t.map((u)=>[`${u.name}::${u.filePath}`,u])),r=[],s=[],m=[];for(let[u,a]of e){let p=i.get(u);if(!p)r.push(a);else if(p.fingerprint!==a.fingerprint)m.push({before:p,after:a})}for(let[u,a]of i)if(!e.has(u))s.push(a);return{added:r,removed:s,modified:m}}getDependencies(n,t,i=1e4){if(this.closed)return O(y("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:i}}).map((e)=>e.dstFilePath)}catch(e){return O(y("search","Gildash: getDependencies failed",e))}}getDependents(n,t,i=1e4){if(this.closed)return O(y("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:i}}).map((e)=>e.srcFilePath)}catch(e){return O(y("search","Gildash: getDependents failed",e))}}async getAffected(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getAffectedByChange(n)}catch(i){return O(y("search","Gildash: getAffected failed",i))}}async hasCycle(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).hasCycle()}catch(t){return O(y("search","Gildash: hasCycle failed",t))}}async getImportGraph(n){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getAdjacencyList()}catch(t){return O(y("search","Gildash: getImportGraph failed",t))}}async getTransitiveDependencies(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(t).getTransitiveDependencies(n)}catch(i){return O(y("search","Gildash: getTransitiveDependencies failed",i))}}async getCyclePaths(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.getOrBuildGraph(n).getCyclePaths(t)}catch(i){return O(y("search","Gildash: getCyclePaths failed",i))}}getFullSymbol(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=i??this.defaultProject,r=this.symbolSearchFn({symbolRepo:this.symbolRepo,project:e,query:{text:n,exact:!0,filePath:t,limit:1}});if(r.length===0)return O(y("search",`Gildash: symbol '${n}' not found in '${t}'`));let s=r[0],m=s.detail;return{...s,members:Array.isArray(m.members)?m.members:void 0,jsDoc:typeof m.jsDoc==="string"?m.jsDoc:void 0,parameters:typeof m.parameters==="string"?m.parameters:void 0,returnType:typeof m.returnType==="string"?m.returnType:void 0,heritage:Array.isArray(m.heritage)?m.heritage:void 0,decorators:Array.isArray(m.decorators)?m.decorators:void 0,typeParameters:typeof m.typeParameters==="string"?m.typeParameters:void 0}}catch(e){return O(y("search","Gildash: getFullSymbol failed",e))}}getFileStats(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=t??this.defaultProject,e=this.fileRepo.getFile(i,n);if(!e)return O(y("search",`Gildash: file '${n}' is not in the index`));let r=this.symbolRepo.getFileSymbols(i,n),s=this.relationRepo.getOutgoing(i,n);return{filePath:e.filePath,lineCount:e.lineCount??0,size:e.size,symbolCount:r.length,exportedSymbolCount:r.filter((m)=>m.isExported).length,relationCount:s.length}}catch(i){return O(y("store","Gildash: getFileStats failed",i))}}async getFanMetrics(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=this.getOrBuildGraph(t);return{filePath:n,fanIn:i.getDependents(n).length,fanOut:i.getDependencies(n).length}}catch(i){return O(y("search","Gildash: getFanMetrics failed",i))}}resolveSymbol(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));let e=i??this.defaultProject,r=new Set,s=[],m=n,u=t;for(;;){let a=`${u}::${m}`;if(r.has(a))return O(y("search","Gildash: resolveSymbol detected circular re-export chain"));r.add(a);let p=this.relationSearchFn({relationRepo:this.relationRepo,project:e,query:{type:"re-exports",srcFilePath:u,limit:500}}),l,d;for(let S of p){let N;if(S.metaJson)try{let A=JSON.parse(S.metaJson);if(Array.isArray(A.specifiers))N=A.specifiers}catch{}if(!N)continue;let J=N.find((A)=>A.exported===m);if(!J)continue;l=S.dstFilePath,d=J.local;break}if(!l||!d)return{originalName:m,originalFilePath:u,reExportChain:s};s.push({filePath:u,exportedAs:m}),u=l,m=d}}async findPattern(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let i=t?.project??this.defaultProject,e=t?.filePaths?t.filePaths:this.fileRepo.getAllFiles(i).map((r)=>r.filePath);return await this.patternSearchFn({pattern:n,filePaths:e})}catch(i){return O(y("search","Gildash: findPattern failed",i))}}async indexExternalPackages(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));if(this.role!=="owner")return O(y("closed","Gildash: indexExternalPackages() is not available for readers"));try{let i=[];for(let e of n){let r=Nn.resolve(this.projectRoot,"node_modules",e);if(!this.existsSyncFn(r))return O(y("validation",`Gildash: package not found in node_modules: ${e}`));let s=`@external/${e}`,u=await(this.makeExternalCoordinatorFn?this.makeExternalCoordinatorFn(r,s):new fn({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();i.push(u)}return i}catch(i){return O(y("store","Gildash: indexExternalPackages failed",i))}}async batchParse(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));let i=new Map;return await Promise.all(n.map(async(e)=>{try{let r=await this.readFileFn(e),s=this.parseSourceFn(e,r,t);if(!rn(s))i.set(e,s)}catch{}})),i}getModuleInterface(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=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:e}}catch(i){return O(y("search","Gildash: getModuleInterface failed",i))}}async getHeritageChain(n,t,i){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{let e=i??this.defaultProject,r=new Set,s=(m,u,a)=>{let p=`${m}::${u}`;if(r.has(p))return{symbolName:m,filePath:u,kind:a,children:[]};r.add(p);let S=this.relationSearchFn({relationRepo:this.relationRepo,project:e,query:{srcFilePath:u,srcSymbolName:m,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:m,filePath:u,kind:a,children:S}};return s(n,t)}catch(e){return O(y("search","Gildash: getHeritageChain failed",e))}}getParsedAst(n){if(this.closed)return;return this.parseCache.get(n)}getFileInfo(n,t){if(this.closed)return O(y("closed","Gildash: instance is closed"));try{return this.fileRepo.getFile(t??this.defaultProject,n)}catch(i){return O(y("store","Gildash: getFileInfo failed",i))}}getSymbolsByFile(n,t){return this.searchSymbols({filePath:n,project:t??void 0,limit:1e4})}}export{Wn as symbolSearch,Hn as relationSearch,Vn as patternSearch,y as gildashError,Qn as Gildash,On as DependencyGraph};
|
|
6
6
|
|
|
7
|
-
//# debugId=
|
|
7
|
+
//# debugId=17EE0521DDE8D3DB64756E2164756E21
|
|
8
8
|
//# sourceMappingURL=index.js.map
|