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