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