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