@zipbul/gildash 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ko.md +386 -0
- package/README.md +445 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2736 -0
- package/dist/index.js.map +42 -0
- package/dist/migrations/0000_soft_revanche.sql +56 -0
- package/dist/migrations/meta/0000_snapshot.json +408 -0
- package/dist/migrations/meta/_journal.json +13 -0
- package/dist/migrations/migrations/0000_soft_revanche.sql +56 -0
- package/dist/migrations/migrations/meta/0000_snapshot.json +408 -0
- package/dist/migrations/migrations/meta/_journal.json +13 -0
- package/dist/src/codeledger.d.ts +103 -0
- package/dist/src/common/hasher.d.ts +2 -0
- package/dist/src/common/index.d.ts +5 -0
- package/dist/src/common/lru-cache.d.ts +10 -0
- package/dist/src/common/path-utils.d.ts +2 -0
- package/dist/src/common/project-discovery.d.ts +6 -0
- package/dist/src/common/tsconfig-resolver.d.ts +6 -0
- package/dist/src/errors.d.ts +42 -0
- package/dist/src/extractor/calls-extractor.d.ts +3 -0
- package/dist/src/extractor/extractor-utils.d.ts +5 -0
- package/dist/src/extractor/heritage-extractor.d.ts +3 -0
- package/dist/src/extractor/imports-extractor.d.ts +4 -0
- package/dist/src/extractor/index.d.ts +7 -0
- package/dist/src/extractor/relation-extractor.d.ts +4 -0
- package/dist/src/extractor/symbol-extractor.d.ts +3 -0
- package/dist/src/extractor/types.d.ts +162 -0
- package/dist/src/gildash.d.ts +284 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/indexer/file-indexer.d.ts +27 -0
- package/dist/src/indexer/index-coordinator.d.ts +80 -0
- package/dist/src/indexer/index.d.ts +8 -0
- package/dist/src/indexer/relation-indexer.d.ts +24 -0
- package/dist/src/indexer/symbol-indexer.d.ts +29 -0
- package/dist/src/parser/ast-utils.d.ts +10 -0
- package/dist/src/parser/index.d.ts +6 -0
- package/dist/src/parser/jsdoc-parser.d.ts +2 -0
- package/dist/src/parser/parse-cache.d.ts +10 -0
- package/dist/src/parser/parse-source.d.ts +3 -0
- package/dist/src/parser/source-position.d.ts +3 -0
- package/dist/src/parser/types.d.ts +16 -0
- package/dist/src/search/dependency-graph.d.ts +71 -0
- package/dist/src/search/index.d.ts +6 -0
- package/dist/src/search/relation-search.d.ts +45 -0
- package/dist/src/search/symbol-search.d.ts +76 -0
- package/dist/src/store/connection.d.ts +30 -0
- package/dist/src/store/index.d.ts +10 -0
- package/dist/src/store/repositories/file.repository.d.ts +18 -0
- package/dist/src/store/repositories/fts-utils.d.ts +1 -0
- package/dist/src/store/repositories/relation.repository.d.ts +29 -0
- package/dist/src/store/repositories/symbol.repository.d.ts +46 -0
- package/dist/src/store/schema.d.ts +634 -0
- package/dist/src/watcher/index.d.ts +3 -0
- package/dist/src/watcher/ownership.d.ts +22 -0
- package/dist/src/watcher/project-watcher.d.ts +13 -0
- package/dist/src/watcher/types.d.ts +11 -0
- package/package.json +58 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/gildash.ts", "../src/parser/parse-source.ts", "../src/errors.ts", "../src/common/lru-cache.ts", "../src/parser/parse-cache.ts", "../src/parser/source-position.ts", "../src/parser/jsdoc-parser.ts", "../src/extractor/symbol-extractor.ts", "../src/extractor/extractor-utils.ts", "../src/parser/ast-utils.ts", "../src/extractor/imports-extractor.ts", "../src/extractor/calls-extractor.ts", "../src/extractor/heritage-extractor.ts", "../src/extractor/relation-extractor.ts", "../src/store/connection.ts", "../src/store/schema.ts", "../src/store/repositories/file.repository.ts", "../src/store/repositories/symbol.repository.ts", "../src/store/repositories/fts-utils.ts", "../src/store/repositories/relation.repository.ts", "../src/watcher/project-watcher.ts", "../src/common/project-discovery.ts", "../src/common/tsconfig-resolver.ts", "../src/common/path-utils.ts", "../src/common/hasher.ts", "../src/indexer/file-indexer.ts", "../src/indexer/symbol-indexer.ts", "../src/indexer/relation-indexer.ts", "../src/indexer/index-coordinator.ts", "../src/watcher/ownership.ts", "../src/search/symbol-search.ts", "../src/search/relation-search.ts", "../src/search/dependency-graph.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport type { ParsedFile } from './parser/types';\nimport { parseSource as defaultParseSource } from './parser/parse-source';\nimport { ParseCache } from './parser/parse-cache';\nimport type { ExtractedSymbol } from './extractor/types';\nimport { extractSymbols as defaultExtractSymbols } from './extractor/symbol-extractor';\nimport { extractRelations as defaultExtractRelations } from './extractor/relation-extractor';\nimport type { CodeRelation } from './extractor/types';\nimport { DbConnection } from './store/connection';\nimport { FileRepository } from './store/repositories/file.repository';\nimport { SymbolRepository } from './store/repositories/symbol.repository';\nimport { RelationRepository } from './store/repositories/relation.repository';\nimport { ProjectWatcher } from './watcher/project-watcher';\nimport { IndexCoordinator } from './indexer/index-coordinator';\nimport type { IndexResult } from './indexer/index-coordinator';\nimport type { IndexCoordinatorOptions } from './indexer/index-coordinator';\nimport type { FileChangeEvent } from './watcher/types';\nimport { acquireWatcherRole, releaseWatcherRole, updateHeartbeat } from './watcher/ownership';\nimport type { WatcherOwnerStore } from './watcher/ownership';\nimport { discoverProjects } from './common/project-discovery';\nimport type { ProjectBoundary } from './common/project-discovery';\nimport { loadTsconfigPaths, clearTsconfigPathsCache } from './common/tsconfig-resolver';\nimport type { TsconfigPaths } from './common/tsconfig-resolver';\nimport { symbolSearch as defaultSymbolSearch } from './search/symbol-search';\nimport type { SymbolSearchQuery, SymbolSearchResult } from './search/symbol-search';\nimport { relationSearch as defaultRelationSearch } from './search/relation-search';\nimport type { RelationSearchQuery } from './search/relation-search';\nimport type { SymbolStats } from './store/repositories/symbol.repository';\nimport { DependencyGraph } from './search/dependency-graph';\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst HEALTHCHECK_INTERVAL_MS = 60_000;\nconst MAX_HEALTHCHECK_RETRIES = 10;\n\n/**\n * Minimal logger interface accepted by {@link Gildash}.\n *\n * Any object with an `error` method (including `console`) satisfies this interface.\n */\nexport interface Logger {\n /** Log one or more error-level messages. */\n error(...args: unknown[]): void;\n}\n\n/**\n * Options for creating a {@link Gildash} instance via {@link Gildash.open}.\n *\n * @example\n * ```ts\n * const ledger = await Gildash.open({\n * projectRoot: '/absolute/path/to/project',\n * extensions: ['.ts', '.tsx'],\n * ignorePatterns: ['vendor'],\n * });\n * ```\n */\nexport interface GildashOptions {\n /** Absolute path to the project root directory. */\n projectRoot: string;\n /** File extensions to index. Defaults to `['.ts', '.mts', '.cts']`. */\n extensions?: string[];\n /** Glob patterns to ignore during indexing. */\n ignorePatterns?: string[];\n /** Maximum number of parsed ASTs to keep in the LRU cache. Defaults to `500`. */\n parseCacheCapacity?: number;\n /** Logger for error output. Defaults to `console`. */\n logger?: Logger;\n}\n\ninterface GildashInternalOptions {\n existsSyncFn?: (p: string) => boolean;\n dbConnectionFactory?: () => Pick<DbConnection, 'open' | 'close' | 'transaction'> & WatcherOwnerStore;\n watcherFactory?: () => Pick<ProjectWatcher, 'start' | 'close'>;\n coordinatorFactory?: () => Pick<IndexCoordinator, 'fullIndex' | 'shutdown' | 'onIndexed'> & {\n tsconfigPaths?: Promise<TsconfigPaths | null>;\n handleWatcherEvent?(event: FileChangeEvent): void;\n };\n repositoryFactory?: () => {\n fileRepo: Pick<FileRepository, 'upsertFile' | 'getAllFiles' | 'getFilesMap' | 'deleteFile'>;\n symbolRepo: SymbolRepository;\n relationRepo: RelationRepository;\n parseCache: Pick<ParseCache, 'set' | 'get' | 'invalidate'>;\n };\n acquireWatcherRoleFn?: typeof acquireWatcherRole;\n releaseWatcherRoleFn?: typeof releaseWatcherRole;\n updateHeartbeatFn?: typeof updateHeartbeat;\n discoverProjectsFn?: typeof discoverProjects;\n parseSourceFn?: typeof defaultParseSource;\n extractSymbolsFn?: typeof defaultExtractSymbols;\n extractRelationsFn?: typeof defaultExtractRelations;\n symbolSearchFn?: typeof defaultSymbolSearch;\n relationSearchFn?: typeof defaultRelationSearch;\n loadTsconfigPathsFn?: typeof loadTsconfigPaths;\n}\n\n/**\n * Main entry point for gildash.\n *\n * `Gildash` indexes TypeScript source code into a local SQLite database,\n * watches for file changes, and provides search / dependency-graph queries.\n *\n * Create an instance with the static {@link Gildash.open} factory.\n * Always call {@link Gildash.close} when done to release resources.\n *\n * @example\n * ```ts\n * import { Gildash } from '@zipbul/gildash';\n *\n * const ledger = await Gildash.open({ projectRoot: '/my/project' });\n * const symbols = ledger.searchSymbols({ text: 'handle', kind: 'function' });\n * await ledger.close();\n * ```\n */\nexport class Gildash {\n /** Absolute path to the indexed project root. */\n readonly projectRoot: string;\n\n private readonly db: Pick<DbConnection, 'open' | 'close' | 'transaction'> & WatcherOwnerStore;\n private readonly symbolRepo: SymbolRepository;\n private readonly relationRepo: RelationRepository;\n private readonly parseCache: Pick<ParseCache, 'set' | 'get' | 'invalidate'>;\n private coordinator: (Pick<IndexCoordinator, 'fullIndex' | 'shutdown' | 'onIndexed'> & {\n tsconfigPaths?: Promise<TsconfigPaths | null>;\n handleWatcherEvent?(event: FileChangeEvent): void;\n }) | null;\n private watcher: Pick<ProjectWatcher, 'start' | 'close'> | null;\n private readonly releaseWatcherRoleFn: typeof releaseWatcherRole;\n private readonly parseSourceFn: typeof defaultParseSource;\n private readonly extractSymbolsFn: typeof defaultExtractSymbols;\n private readonly extractRelationsFn: typeof defaultExtractRelations;\n private readonly symbolSearchFn: typeof defaultSymbolSearch;\n private readonly relationSearchFn: typeof defaultRelationSearch;\n private readonly logger: Logger;\n private readonly defaultProject: string;\n private readonly role: 'owner' | 'reader';\n private timer: ReturnType<typeof setInterval> | null = null;\n private signalHandlers: Array<[string, () => void]> = [];\n private closed = false;\n private tsconfigPaths: TsconfigPaths | null = null;\n private boundaries: ProjectBoundary[] = [];\n private readonly onIndexedCallbacks = new Set<(result: IndexResult) => void>();\n\n private constructor(opts: {\n projectRoot: string;\n db: Pick<DbConnection, 'open' | 'close' | 'transaction'> & WatcherOwnerStore;\n symbolRepo: SymbolRepository;\n relationRepo: RelationRepository;\n parseCache: Pick<ParseCache, 'set' | 'get' | 'invalidate'>;\n coordinator: (Pick<IndexCoordinator, 'fullIndex' | 'shutdown' | 'onIndexed'> & {\n tsconfigPaths?: Promise<TsconfigPaths | null>;\n handleWatcherEvent?(event: FileChangeEvent): void;\n }) | null;\n watcher: Pick<ProjectWatcher, 'start' | 'close'> | null;\n releaseWatcherRoleFn: typeof releaseWatcherRole;\n parseSourceFn: typeof defaultParseSource;\n extractSymbolsFn: typeof defaultExtractSymbols;\n extractRelationsFn: typeof defaultExtractRelations;\n symbolSearchFn: typeof defaultSymbolSearch;\n relationSearchFn: typeof defaultRelationSearch;\n logger: Logger;\n defaultProject: string;\n role: 'owner' | 'reader';\n }) {\n this.projectRoot = opts.projectRoot;\n this.db = opts.db;\n this.symbolRepo = opts.symbolRepo;\n this.relationRepo = opts.relationRepo;\n this.parseCache = opts.parseCache;\n this.coordinator = opts.coordinator;\n this.watcher = opts.watcher;\n this.releaseWatcherRoleFn = opts.releaseWatcherRoleFn;\n this.parseSourceFn = opts.parseSourceFn;\n this.extractSymbolsFn = opts.extractSymbolsFn;\n this.extractRelationsFn = opts.extractRelationsFn;\n this.symbolSearchFn = opts.symbolSearchFn;\n this.relationSearchFn = opts.relationSearchFn;\n this.logger = opts.logger;\n this.defaultProject = opts.defaultProject;\n this.role = opts.role;\n }\n\n /**\n * Create and initialise a new `Gildash` instance.\n *\n * Opens (or creates) a SQLite database alongside the project root,\n * discovers sub-projects, acquires a watcher role, performs initial indexing,\n * and begins watching for file changes.\n *\n * @param options - Configuration for the instance.\n * @returns A fully-initialised `Gildash` ready for queries.\n * @throws {Error} If `projectRoot` is not absolute or does not exist.\n *\n * @example\n * ```ts\n * const ledger = await Gildash.open({\n * projectRoot: '/home/user/my-app',\n * extensions: ['.ts', '.tsx'],\n * });\n * ```\n */\n static async open(options: GildashOptions & GildashInternalOptions): Promise<Gildash> {\n const {\n projectRoot,\n extensions = ['.ts', '.mts', '.cts'],\n ignorePatterns = [],\n parseCacheCapacity = 500,\n logger = console,\n existsSyncFn = existsSync,\n dbConnectionFactory,\n watcherFactory,\n coordinatorFactory,\n repositoryFactory,\n acquireWatcherRoleFn = acquireWatcherRole,\n releaseWatcherRoleFn = releaseWatcherRole,\n updateHeartbeatFn = updateHeartbeat,\n discoverProjectsFn = discoverProjects,\n parseSourceFn = defaultParseSource,\n extractSymbolsFn = defaultExtractSymbols,\n extractRelationsFn = defaultExtractRelations,\n symbolSearchFn = defaultSymbolSearch,\n relationSearchFn = defaultRelationSearch,\n loadTsconfigPathsFn = loadTsconfigPaths,\n } = options;\n\n if (!path.isAbsolute(projectRoot)) {\n throw new Error(`Gildash: projectRoot must be an absolute path, got: \"${projectRoot}\"`);\n }\n if (!existsSyncFn(projectRoot)) {\n throw new Error(`Gildash: projectRoot does not exist: \"${projectRoot}\"`);\n }\n\n const db = dbConnectionFactory\n ? dbConnectionFactory()\n : new DbConnection({ projectRoot });\n db.open();\n try {\n\n const boundaries: ProjectBoundary[] = await discoverProjectsFn(projectRoot);\n const defaultProject = boundaries[0]?.project ?? path.basename(projectRoot);\n\n const repos = repositoryFactory\n ? repositoryFactory()\n : (() => {\n const connection = db as DbConnection;\n return {\n fileRepo: new FileRepository(connection),\n symbolRepo: new SymbolRepository(connection),\n relationRepo: new RelationRepository(connection),\n parseCache: new ParseCache(parseCacheCapacity),\n };\n })();\n\n const role = await Promise.resolve(\n acquireWatcherRoleFn(db, process.pid, {}),\n );\n\n let coordinator: (Pick<IndexCoordinator, 'fullIndex' | 'shutdown' | 'onIndexed'> & {\n tsconfigPaths?: Promise<TsconfigPaths | null>;\n handleWatcherEvent?(event: FileChangeEvent): void;\n }) | null = null;\n let watcher: Pick<ProjectWatcher, 'start' | 'close'> | null = null;\n\n const instance = new Gildash({\n projectRoot,\n db,\n symbolRepo: repos.symbolRepo,\n relationRepo: repos.relationRepo,\n parseCache: repos.parseCache,\n coordinator,\n watcher,\n releaseWatcherRoleFn: releaseWatcherRoleFn,\n parseSourceFn: parseSourceFn,\n extractSymbolsFn: extractSymbolsFn,\n extractRelationsFn: extractRelationsFn,\n symbolSearchFn: symbolSearchFn,\n relationSearchFn: relationSearchFn,\n logger,\n defaultProject,\n role,\n });\n clearTsconfigPathsCache(projectRoot);\n instance.tsconfigPaths = await loadTsconfigPathsFn(projectRoot);\n instance.boundaries = boundaries;\n if (role === 'owner') {\n const w = watcherFactory\n ? watcherFactory()\n : new ProjectWatcher({ projectRoot, ignorePatterns, extensions }, undefined, logger);\n\n const c = coordinatorFactory\n ? coordinatorFactory()\n : new IndexCoordinator({\n projectRoot,\n boundaries,\n extensions,\n ignorePatterns,\n dbConnection: db,\n parseCache: repos.parseCache,\n fileRepo: repos.fileRepo,\n symbolRepo: repos.symbolRepo,\n relationRepo: repos.relationRepo,\n logger,\n });\n\n instance.coordinator = c;\n instance.watcher = w;\n\n await w.start((event) => c.handleWatcherEvent?.(event));\n\n const timer = setInterval(() => {\n updateHeartbeatFn(db, process.pid);\n }, HEARTBEAT_INTERVAL_MS);\n instance.timer = timer;\n\n await c.fullIndex();\n } else {\n let retryCount = 0;\n const healthcheck = async () => {\n try {\n const newRole = await Promise.resolve(\n acquireWatcherRoleFn(db, process.pid, {}),\n );\n retryCount = 0;\n if (newRole === 'owner') {\n clearInterval(instance.timer!);\n instance.timer = null;\n let promotedWatcher: Pick<ProjectWatcher, 'start' | 'close'> | null = null;\n let promotedCoordinator: (Pick<IndexCoordinator, 'fullIndex' | 'shutdown' | 'onIndexed'> & {\n tsconfigPaths?: Promise<TsconfigPaths | null>;\n handleWatcherEvent?(event: FileChangeEvent): void;\n }) | null = null;\n try {\n promotedWatcher = watcherFactory\n ? watcherFactory()\n : new ProjectWatcher({ projectRoot, ignorePatterns, extensions }, undefined, logger);\n promotedCoordinator = coordinatorFactory\n ? coordinatorFactory()\n : new IndexCoordinator({\n projectRoot,\n boundaries,\n extensions,\n ignorePatterns,\n dbConnection: db,\n parseCache: repos.parseCache,\n fileRepo: repos.fileRepo,\n symbolRepo: repos.symbolRepo,\n relationRepo: repos.relationRepo,\n logger,\n });\n for (const cb of instance.onIndexedCallbacks) {\n promotedCoordinator.onIndexed(cb);\n }\n await promotedWatcher.start((event) => promotedCoordinator?.handleWatcherEvent?.(event));\n const hbTimer = setInterval(() => {\n updateHeartbeatFn(db, process.pid);\n }, HEARTBEAT_INTERVAL_MS);\n instance.timer = hbTimer;\n instance.coordinator = promotedCoordinator;\n instance.watcher = promotedWatcher;\n await promotedCoordinator.fullIndex();\n } catch (setupErr) {\n logger.error('[Gildash] owner promotion failed, reverting to reader', setupErr);\n if (promotedWatcher) {\n await promotedWatcher.close().catch((e) =>\n logger.error('[Gildash] watcher close error during promotion rollback', e),\n );\n instance.watcher = null;\n }\n if (promotedCoordinator) {\n await promotedCoordinator.shutdown().catch((e) =>\n logger.error('[Gildash] coordinator shutdown error during promotion rollback', e),\n );\n instance.coordinator = null;\n }\n if (instance.timer === null) {\n instance.timer = setInterval(healthcheck, HEALTHCHECK_INTERVAL_MS);\n }\n }\n }\n } catch (err) {\n retryCount++;\n logger.error('[Gildash] healthcheck error', err);\n if (retryCount >= MAX_HEALTHCHECK_RETRIES) {\n logger.error('[Gildash] healthcheck failed too many times, shutting down');\n clearInterval(instance.timer!);\n instance.timer = null;\n instance.close().catch((closeErr) =>\n logger.error('[Gildash] close error during healthcheck shutdown', closeErr),\n );\n }\n }\n };\n const timer = setInterval(healthcheck, HEALTHCHECK_INTERVAL_MS);\n instance.timer = timer;\n }\n\n const signals: Array<NodeJS.Signals | 'beforeExit'> = ['SIGTERM', 'SIGINT', 'beforeExit'];\n for (const sig of signals) {\n const handler = () => { instance.close().catch(err => logger.error('[Gildash] close error during signal', sig, err)); };\n if (sig === 'beforeExit') {\n process.on('beforeExit', handler);\n } else {\n process.on(sig, handler);\n }\n instance.signalHandlers.push([sig, handler]);\n }\n\n return instance;\n } catch (err) {\n db.close();\n throw err;\n }\n }\n\n /**\n * Shut down the instance and release all resources.\n *\n * Stops the file watcher, shuts down the index coordinator,\n * releases the watcher ownership role, and closes the database.\n * Calling `close()` more than once is safe (subsequent calls are no-ops).\n *\n * @throws {AggregateError} If one or more sub-systems fail during shutdown.\n */\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n\n const closeErrors: Error[] = [];\n\n for (const [sig, handler] of this.signalHandlers) {\n if (sig === 'beforeExit') {\n process.off('beforeExit', handler);\n } else {\n process.off(sig as NodeJS.Signals, handler);\n }\n }\n this.signalHandlers = [];\n\n if (this.coordinator) {\n try {\n await this.coordinator.shutdown();\n } catch (err) {\n closeErrors.push(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n if (this.watcher) {\n try {\n await this.watcher.close();\n } catch (err) {\n closeErrors.push(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n\n try {\n this.releaseWatcherRoleFn(this.db, process.pid);\n } catch (err) {\n closeErrors.push(err instanceof Error ? err : new Error(String(err)));\n }\n\n try {\n this.db.close();\n } catch (err) {\n closeErrors.push(err instanceof Error ? err : new Error(String(err)));\n }\n\n if (closeErrors.length > 0) {\n throw new AggregateError(closeErrors, 'Gildash: one or more errors occurred during close()');\n }\n }\n\n /**\n * Register a callback that fires after each indexing run completes.\n *\n * @param callback - Receives the {@link IndexResult} for the completed run.\n * @returns An unsubscribe function. Call it to remove the listener.\n *\n * @example\n * ```ts\n * const off = ledger.onIndexed(result => {\n * console.log(`Indexed ${result.filesProcessed} files`);\n * });\n * // later…\n * off();\n * ```\n */\n onIndexed(callback: (result: IndexResult) => void): () => void {\n this.onIndexedCallbacks.add(callback);\n if (!this.coordinator) {\n return () => { this.onIndexedCallbacks.delete(callback); };\n }\n const unsubscribe = this.coordinator.onIndexed(callback);\n return () => {\n this.onIndexedCallbacks.delete(callback);\n unsubscribe();\n };\n }\n\n /**\n * Parse a TypeScript source string into an AST and cache the result.\n *\n * @param filePath - File path used as the cache key and for diagnostics.\n * @param sourceText - Raw TypeScript source code.\n * @returns The parsed file representation.\n * @throws {Error} If the instance is closed.\n */\n parseSource(filePath: string, sourceText: string): ParsedFile {\n if (this.closed) throw new Error('Gildash: instance is closed');\n const parsed = this.parseSourceFn(filePath, sourceText);\n this.parseCache.set(filePath, parsed);\n return parsed;\n }\n\n /**\n * Extract all symbol declarations from a previously parsed file.\n *\n * @param parsed - A {@link ParsedFile} obtained from {@link parseSource}.\n * @returns An array of {@link ExtractedSymbol} entries.\n * @throws {Error} If the instance is closed.\n */\n extractSymbols(parsed: ParsedFile): ExtractedSymbol[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.extractSymbolsFn(parsed);\n }\n\n /**\n * Extract inter-file relationships (imports, calls, extends, implements)\n * from a previously parsed file.\n *\n * @param parsed - A {@link ParsedFile} obtained from {@link parseSource}.\n * @returns An array of {@link CodeRelation} entries.\n * @throws {Error} If the instance is closed.\n */\n extractRelations(parsed: ParsedFile): CodeRelation[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.extractRelationsFn(\n parsed.program,\n parsed.filePath,\n this.tsconfigPaths ?? undefined,\n );\n }\n\n /**\n * Trigger a full re-index of all tracked files.\n *\n * Only available to the instance that holds the *owner* role.\n *\n * @returns The indexing result summary.\n * @throws {Error} If the instance is closed or is a reader.\n */\n async reindex(): Promise<IndexResult> {\n if (this.closed) throw new Error('Gildash: instance is closed');\n if (!this.coordinator) {\n throw new Error('Gildash: reindex() is not available for readers');\n }\n return this.coordinator.fullIndex();\n }\n\n /**\n * Discovered project boundaries within the project root.\n *\n * Each entry contains a project name and its root directory.\n */\n get projects(): ProjectBoundary[] {\n return [...this.boundaries];\n }\n\n /**\n * Return aggregate symbol statistics for the given project.\n *\n * @param project - Project name. Defaults to the auto-discovered primary project.\n * @returns Counts grouped by symbol kind.\n * @throws {Error} If the instance is closed.\n */\n getStats(project?: string): SymbolStats {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.symbolRepo.getStats(project ?? this.defaultProject);\n }\n\n /**\n * Search indexed symbols by name, kind, file path, or export status.\n *\n * @param query - Search filters. All fields are optional; omitted fields match everything.\n * @returns Matching {@link SymbolSearchResult} entries.\n * @throws {Error} If the instance is closed.\n *\n * @example\n * ```ts\n * const fns = ledger.searchSymbols({ kind: 'function', isExported: true });\n * ```\n */\n searchSymbols(query: SymbolSearchQuery): SymbolSearchResult[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.symbolSearchFn({ symbolRepo: this.symbolRepo, project: this.defaultProject, query });\n }\n\n /**\n * Search indexed code relationships (imports, calls, extends, implements).\n *\n * @param query - Search filters. All fields are optional.\n * @returns Matching {@link CodeRelation} entries.\n * @throws {Error} If the instance is closed.\n */\n searchRelations(query: RelationSearchQuery): CodeRelation[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.relationSearchFn({ relationRepo: this.relationRepo, project: this.defaultProject, query });\n }\n\n /**\n * List the files that a given file directly imports.\n *\n * @param filePath - Absolute path of the source file.\n * @param project - Project name. Defaults to the primary project.\n * @param limit - Maximum results. Defaults to `10_000`.\n * @returns Absolute paths of imported files.\n * @throws {Error} If the instance is closed.\n */\n getDependencies(filePath: string, project?: string, limit = 10_000): string[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.relationSearchFn({\n relationRepo: this.relationRepo,\n project: project ?? this.defaultProject,\n query: { srcFilePath: filePath, type: 'imports', project: project ?? this.defaultProject, limit },\n }).map(r => r.dstFilePath);\n }\n\n /**\n * List the files that directly import a given file.\n *\n * @param filePath - Absolute path of the target file.\n * @param project - Project name. Defaults to the primary project.\n * @param limit - Maximum results. Defaults to `10_000`.\n * @returns Absolute paths of files that import the target.\n * @throws {Error} If the instance is closed.\n */\n getDependents(filePath: string, project?: string, limit = 10_000): string[] {\n if (this.closed) throw new Error('Gildash: instance is closed');\n return this.relationSearchFn({\n relationRepo: this.relationRepo,\n project: project ?? this.defaultProject,\n query: { dstFilePath: filePath, type: 'imports', project: project ?? this.defaultProject, limit },\n }).map(r => r.srcFilePath);\n }\n\n /**\n * Compute the full set of files transitively affected by changes.\n *\n * Builds a dependency graph and walks all reverse edges from each changed file.\n *\n * @param changedFiles - Absolute paths of files that changed.\n * @param project - Project name. Defaults to the primary project.\n * @returns Paths of all transitively-dependent files (excludes the changed files themselves).\n * @throws {Error} If the instance is closed.\n */\n async getAffected(changedFiles: string[], project?: string): Promise<string[]> {\n if (this.closed) throw new Error('Gildash: instance is closed');\n const g = new DependencyGraph({\n relationRepo: this.relationRepo,\n project: project ?? this.defaultProject,\n });\n await g.build();\n return g.getAffectedByChange(changedFiles);\n }\n\n /**\n * Check whether the import graph contains a circular dependency.\n *\n * @param project - Project name. Defaults to the primary project.\n * @returns `true` if at least one cycle exists.\n * @throws {Error} If the instance is closed.\n */\n async hasCycle(project?: string): Promise<boolean> {\n if (this.closed) throw new Error('Gildash: instance is closed');\n const g = new DependencyGraph({\n relationRepo: this.relationRepo,\n project: project ?? this.defaultProject,\n });\n await g.build();\n return g.hasCycle();\n }\n}\n",
|
|
6
|
+
"import { parseSync as defaultParseSync } from 'oxc-parser';\nimport type { ParsedFile } from './types';\nimport { ParseError } from '../errors';\n\nexport function parseSource(\n filePath: string,\n sourceText: string,\n parseSyncFn: typeof defaultParseSync = defaultParseSync,\n): ParsedFile {\n try {\n const { program, errors, comments } = parseSyncFn(filePath, sourceText);\n return { filePath, program: program as ParsedFile['program'], errors, comments, sourceText };\n } catch (err) {\n throw new ParseError(`Failed to parse file: ${filePath}`, { cause: err });\n }\n}\n",
|
|
7
|
+
"/**\n * Base error class for all Gildash errors.\n * Every error thrown by this library is an instance of `GildashError`.\n *\n * @example\n * ```ts\n * try {\n * await Gildash.open({ projectRoot: '/path' });\n * } catch (err) {\n * if (err instanceof GildashError) {\n * console.error('Gildash error:', err.message);\n * }\n * }\n * ```\n */\nexport class GildashError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"GildashError\";\n }\n}\n\n/** Thrown when the file watcher fails to start or stop. */\nexport class WatcherError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"WatcherError\";\n }\n}\n\n/** Thrown when AST parsing of a TypeScript file fails. */\nexport class ParseError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ParseError\";\n }\n}\n\n/** Thrown when symbol or relation extraction from a parsed AST fails. */\nexport class ExtractError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ExtractError\";\n }\n}\n\n/** Thrown when the indexing pipeline encounters an unrecoverable error. */\nexport class IndexError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"IndexError\";\n }\n}\n\n/** Thrown when a database (SQLite) operation fails. */\nexport class StoreError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"StoreError\";\n }\n}\n\n/** Thrown when a search query (symbol search, relation search) fails. */\nexport class SearchError extends GildashError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SearchError\";\n }\n}\n",
|
|
8
|
+
"export class LruCache<K, V> {\n #capacity: number;\n #map = new Map<K, V>();\n\n constructor(capacity: number) {\n this.#capacity = Math.max(1, capacity);\n }\n\n get size(): number {\n return this.#map.size;\n }\n\n has(key: K): boolean {\n return this.#map.has(key);\n }\n\n get(key: K): V | undefined {\n if (!this.#map.has(key)) {\n return undefined;\n }\n const value = this.#map.get(key)!;\n this.#map.delete(key);\n this.#map.set(key, value);\n return value;\n }\n\n set(key: K, value: V): void {\n if (this.#map.has(key)) {\n this.#map.delete(key);\n }\n\n this.#map.set(key, value);\n\n if (this.#map.size > this.#capacity) {\n const oldestKey = this.#map.keys().next().value as K | undefined;\n if (oldestKey !== undefined) {\n this.#map.delete(oldestKey);\n }\n }\n }\n\n delete(key: K): boolean {\n return this.#map.delete(key);\n }\n\n clear(): void {\n this.#map.clear();\n }\n}\n",
|
|
9
|
+
"import type { ParsedFile } from './types';\nimport { LruCache } from '../common/lru-cache';\n\nexport class ParseCache {\n private readonly lru: LruCache<string, ParsedFile>;\n\n constructor(capacity: number = 500) {\n this.lru = new LruCache<string, ParsedFile>(capacity);\n }\n\n get(filePath: string): ParsedFile | undefined {\n return this.lru.get(filePath);\n }\n\n set(filePath: string, parsed: ParsedFile): void {\n this.lru.set(filePath, parsed);\n }\n\n invalidate(filePath: string): void {\n this.lru.delete(filePath);\n }\n\n invalidateAll(): void {\n this.lru.clear();\n }\n\n size(): number {\n return this.lru.size;\n }\n}\n",
|
|
10
|
+
"import type { SourcePosition } from './types';\n\nexport function buildLineOffsets(sourceText: string): number[] {\n const offsets: number[] = [0];\n for (let i = 0; i < sourceText.length; i++) {\n if (sourceText[i] === '\\n') {\n offsets.push(i + 1);\n }\n }\n return offsets;\n}\n\nexport function getLineColumn(offsets: number[], offset: number): SourcePosition {\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (offsets[mid]! <= offset) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return { line: lo + 1, column: offset - offsets[lo]! };\n}\n",
|
|
11
|
+
"import { parse } from 'comment-parser';\nimport type { JsDocBlock } from '../extractor/types';\nimport { ParseError } from '../errors';\n\nexport function parseJsDoc(commentText: string): JsDocBlock {\n try {\n let stripped = commentText.trim();\n if (stripped.startsWith('/**')) stripped = stripped.slice(3);\n if (stripped.endsWith('*/')) stripped = stripped.slice(0, -2);\n\n const blocks = parse(`/** ${stripped} */`);\n const block = blocks[0] ?? { description: '', tags: [] };\n\n return {\n description: (block.description ?? '').trim(),\n tags: (block.tags ?? []).map((t) => ({\n tag: t.tag ?? '',\n name: t.name ?? '',\n type: t.type ?? '',\n description: t.description ?? '',\n optional: t.optional ?? false,\n ...(t.default !== undefined ? { default: t.default } : {}),\n })),\n };\n } catch (err) {\n throw new ParseError(`Failed to parse JSDoc comment`, { cause: err });\n }\n}\n",
|
|
12
|
+
"import type { ParsedFile } from '../parser/types';\nimport type { SourceSpan } from '../parser/types';\nimport type {\n ExtractedSymbol,\n SymbolKind,\n Modifier,\n Heritage,\n Parameter,\n Decorator,\n} from './types';\nimport { buildLineOffsets, getLineColumn } from '../parser/source-position';\nimport { parseJsDoc } from '../parser/jsdoc-parser';\n\ntype OxcSpan = { start: number; end: number };\n\ntype OxcTypeAnn = OxcSpan & { typeAnnotation?: OxcSpan };\n\ntype OxcDeco = OxcSpan & {\n expression?: OxcSpan & {\n type?: string;\n callee?: { name?: string; property?: { name?: string } };\n arguments?: OxcSpan[];\n name?: string;\n };\n};\n\ntype OxcParam = OxcSpan & {\n type?: string;\n name?: string;\n optional?: boolean;\n typeAnnotation?: OxcTypeAnn;\n decorators?: OxcDeco[];\n parameter?: OxcParam;\n argument?: OxcParam & { name?: string };\n left?: OxcParam;\n right?: OxcSpan;\n pattern?: { name?: string };\n};\n\ntype OxcModNode = {\n static?: boolean;\n abstract?: boolean;\n readonly?: boolean;\n override?: boolean;\n declare?: boolean;\n const?: boolean;\n accessibility?: string;\n async?: boolean;\n};\n\ntype OxcMember = OxcSpan & OxcModNode & {\n type?: string;\n key?: { name?: string };\n value?: OxcSpan & OxcModNode & { params?: OxcParam[]; returnType?: OxcTypeAnn };\n kind?: string;\n params?: OxcParam[];\n returnType?: OxcTypeAnn;\n typeAnnotation?: OxcTypeAnn;\n};\n\ntype OxcNode = OxcSpan & OxcModNode & {\n type?: string;\n name?: string;\n id?: { name?: string };\n params?: OxcParam[];\n returnType?: OxcTypeAnn;\n typeAnnotation?: OxcTypeAnn;\n body?: {\n body?: OxcMember[];\n members?: Array<OxcSpan & { id?: { name?: string; value?: string } }>;\n };\n decorators?: OxcDeco[];\n typeParameters?: { params?: Array<{ name?: { name?: string } }> };\n superClass?: OxcSpan;\n implements?: Array<OxcSpan & { expression?: OxcSpan }>;\n extends?: Array<OxcSpan & { expression?: OxcSpan }>;\n declarations?: Array<OxcSpan & {\n id?: OxcNode & {\n properties?: Array<OxcSpan & { value?: { name?: string }; key?: { name?: string } }>;\n elements?: Array<(OxcSpan & { type?: string; name?: string }) | null>;\n };\n init?: OxcNode;\n }>;\n};\n\nexport function extractSymbols(parsed: ParsedFile): ExtractedSymbol[] {\n const { program, sourceText, comments } = parsed;\n const lineOffsets = buildLineOffsets(sourceText);\n\n function span(start: number, end: number): SourceSpan {\n return {\n start: getLineColumn(lineOffsets, start),\n end: getLineColumn(lineOffsets, end),\n };\n }\n\n function findJsDocComment(nodeStart: number): string | undefined {\n let best: { value: string; end: number } | null = null;\n for (const c of comments) {\n if (c.type !== 'Block') continue;\n if (c.end > nodeStart) continue;\n if (!c.value.startsWith('*')) continue;\n if (!best || c.end > best.end) {\n best = { value: `/*${c.value}*/`, end: c.end };\n }\n }\n if (!best) return undefined;\n\n for (const stmt of program.body) {\n const stmtStart = (stmt as { start?: number }).start ?? 0;\n if (stmtStart === nodeStart) continue;\n if (stmtStart > best.end && stmtStart < nodeStart) {\n return undefined;\n }\n }\n\n return best.value;\n }\n\n function typeText(typeAnnotation: OxcTypeAnn | null | undefined): string | undefined {\n if (!typeAnnotation) return undefined;\n const inner = typeAnnotation.typeAnnotation ?? typeAnnotation;\n return sourceText.slice(inner.start, inner.end);\n }\n\n function extractDecorators(decorators: OxcDeco[]): Decorator[] {\n if (!decorators || decorators.length === 0) return [];\n return decorators.map((d) => {\n const expr = d.expression;\n if (!expr) return { name: 'unknown' };\n if (expr.type === 'CallExpression') {\n const name = expr.callee?.name ?? expr.callee?.property?.name ?? 'unknown';\n const args = (expr.arguments ?? []).map((a: OxcSpan) => sourceText.slice(a.start, a.end));\n return { name, arguments: args.length > 0 ? args : undefined };\n }\n if (expr.type === 'Identifier') return { name: expr.name ?? 'unknown' };\n return { name: sourceText.slice(expr.start, expr.end) };\n });\n }\n\n function extractParam(p: OxcParam): Parameter {\n const inner = p.type === 'TSParameterProperty' ? p.parameter : p;\n\n if (inner?.type === 'RestElement') {\n const argName: string = inner.argument?.name ?? 'unknown';\n const name = `...${argName}`;\n const typeAnn = inner.typeAnnotation;\n const type = typeAnn ? typeText(typeAnn) : undefined;\n const param: Parameter = { name, isOptional: false };\n if (type) param.type = type;\n return param;\n }\n\n if (inner?.type === 'AssignmentPattern') {\n const left = inner.left;\n const right = inner.right;\n const name: string = left?.name ?? 'unknown';\n const typeAnn = left?.typeAnnotation;\n const type = typeAnn ? typeText(typeAnn) : undefined;\n const defaultValue: string = sourceText.slice(right!.start, right!.end);\n const decos = extractDecorators(left?.decorators ?? []);\n const param: Parameter = { name, isOptional: true, defaultValue };\n if (type) param.type = type;\n if (decos.length > 0) param.decorators = decos;\n return param;\n }\n\n const name: string = inner?.name ?? inner?.pattern?.name ?? 'unknown';\n const optional: boolean = !!(inner?.optional);\n const typeAnn = inner?.typeAnnotation;\n const type = typeAnn ? typeText(typeAnn) : undefined;\n const decos = extractDecorators(inner?.decorators ?? []);\n const param: Parameter = { name, isOptional: optional };\n if (type) param.type = type;\n if (decos.length > 0) param.decorators = decos;\n return param;\n }\n\n function extractModifiers(node: OxcModNode, fn?: OxcModNode): Modifier[] {\n const mods: Modifier[] = [];\n if (fn?.async) mods.push('async');\n if (node.static) mods.push('static');\n if (node.abstract) mods.push('abstract');\n if (node.readonly) mods.push('readonly');\n if (node.override) mods.push('override');\n if (node.declare) mods.push('declare');\n if (node.const) mods.push('const');\n const acc = node.accessibility;\n if (acc === 'private') mods.push('private');\n else if (acc === 'protected') mods.push('protected');\n else if (acc === 'public') mods.push('public');\n return mods;\n }\n\n function classHeritage(node: OxcNode): Heritage[] {\n const heritage: Heritage[] = [];\n if (node.superClass) {\n const name = sourceText.slice(node.superClass.start, node.superClass.end);\n heritage.push({ kind: 'extends', name });\n }\n const impls = node.implements ?? [];\n for (const impl of impls) {\n const expr = impl.expression ?? impl;\n const name = sourceText.slice(expr.start, expr.end);\n heritage.push({ kind: 'implements', name });\n }\n return heritage;\n }\n\n function interfaceHeritage(node: OxcNode): Heritage[] {\n const heritage: Heritage[] = [];\n for (const ext of (node.extends ?? [])) {\n const expr = ext.expression ?? ext;\n const name = sourceText.slice(expr.start, expr.end);\n heritage.push({ kind: 'extends', name });\n }\n return heritage;\n }\n\n function extractClassMembers(bodyNodes: OxcMember[]): ExtractedSymbol[] {\n const members: ExtractedSymbol[] = [];\n for (const m of bodyNodes) {\n if (m.type === 'MethodDefinition') {\n const name: string = m.key?.name ?? 'unknown';\n const fnValue = m.value;\n const rawKind: string = m.kind ?? 'method';\n const methodKind =\n rawKind === 'constructor'\n ? 'constructor'\n : rawKind === 'get'\n ? 'getter'\n : rawKind === 'set'\n ? 'setter'\n : 'method';\n const mods = extractModifiers(m, fnValue);\n const params = (fnValue?.params ?? []).map(extractParam);\n const returnType = typeText(fnValue?.returnType);\n const s: ExtractedSymbol = {\n kind: 'method',\n name,\n span: span(m.start, m.end),\n isExported: false,\n methodKind,\n modifiers: mods,\n parameters: params.length > 0 ? params : undefined,\n returnType,\n };\n members.push(s);\n } else if (m.type === 'PropertyDefinition') {\n const name: string = m.key?.name ?? 'unknown';\n const mods = extractModifiers(m);\n const s: ExtractedSymbol = {\n kind: 'property',\n name,\n span: span(m.start, m.end),\n isExported: false,\n modifiers: mods,\n };\n members.push(s);\n }\n }\n return members;\n }\n\n function extractInterfaceMembers(bodyNodes: OxcMember[]): ExtractedSymbol[] {\n const members: ExtractedSymbol[] = [];\n for (const m of bodyNodes) {\n if (m.type === 'TSMethodSignature') {\n const name: string = m.key?.name ?? 'unknown';\n const params = (m.params ?? []).map(extractParam);\n const returnType = typeText(m.returnType);\n members.push({\n kind: 'method',\n name,\n span: span(m.start, m.end),\n isExported: false,\n modifiers: [],\n methodKind: 'method',\n parameters: params.length > 0 ? params : undefined,\n returnType,\n });\n } else if (m.type === 'TSPropertySignature') {\n const name: string = m.key?.name ?? 'unknown';\n const typeAnn = typeText(m.typeAnnotation);\n const s: ExtractedSymbol = {\n kind: 'property',\n name,\n span: span(m.start, m.end),\n isExported: false,\n modifiers: m.readonly ? ['readonly'] : [],\n returnType: typeAnn,\n };\n members.push(s);\n }\n }\n return members;\n }\n\n function buildSymbol(node: OxcNode, isExported: boolean): ExtractedSymbol | ExtractedSymbol[] | null {\n const type: string = node.type ?? '';\n\n if (type === 'FunctionDeclaration') {\n const name: string = node.id?.name ?? 'default';\n const params = (node.params ?? []).map(extractParam);\n const returnType = typeText(node.returnType);\n const mods = extractModifiers(node, node);\n const decos = extractDecorators(node.decorators ?? []);\n const typeParameters: string[] | undefined =\n node.typeParameters?.params?.map((p: { name?: { name?: string } }) => p.name?.name as string).filter(Boolean) || undefined;\n const sym: ExtractedSymbol = {\n kind: 'function',\n name,\n span: span(node.start, node.end),\n isExported,\n modifiers: mods,\n parameters: params.length > 0 ? params : undefined,\n returnType,\n decorators: decos.length > 0 ? decos : undefined,\n };\n if (typeParameters && typeParameters.length > 0) sym.typeParameters = typeParameters;\n return sym;\n }\n\n if (type === 'ClassDeclaration' || type === 'ClassExpression') {\n const name: string = node.id?.name ?? 'default';\n const heritage = classHeritage(node);\n const members = extractClassMembers(node.body?.body ?? []);\n const decos = extractDecorators(node.decorators ?? []);\n const mods = extractModifiers(node, node);\n const typeParameters: string[] | undefined =\n node.typeParameters?.params?.map((p: { name?: { name?: string } }) => p.name?.name as string).filter(Boolean) || undefined;\n const sym: ExtractedSymbol = {\n kind: 'class',\n name,\n span: span(node.start, node.end),\n isExported,\n modifiers: mods,\n heritage: heritage.length > 0 ? heritage : undefined,\n members: members.length > 0 ? members : undefined,\n decorators: decos.length > 0 ? decos : undefined,\n };\n if (typeParameters && typeParameters.length > 0) sym.typeParameters = typeParameters;\n return sym;\n }\n\n if (type === 'VariableDeclaration') {\n const symbols: ExtractedSymbol[] = [];\n for (const decl of node.declarations ?? []) {\n const id = decl.id;\n const init = decl.init;\n\n if (id?.type === 'ObjectPattern') {\n for (const prop of id.properties ?? []) {\n const propName: string = prop.value?.name ?? prop.key?.name ?? 'unknown';\n symbols.push({\n kind: 'variable' as SymbolKind,\n name: propName,\n span: span(prop.start ?? decl.start, prop.end ?? decl.end),\n isExported,\n modifiers: [],\n });\n }\n continue;\n }\n\n if (id?.type === 'ArrayPattern') {\n for (const elem of id.elements ?? []) {\n if (!elem || elem.type !== 'Identifier') continue;\n const elemName: string = elem.name ?? 'unknown';\n symbols.push({\n kind: 'variable' as SymbolKind,\n name: elemName,\n span: span(elem.start ?? decl.start, elem.end ?? decl.end),\n isExported,\n modifiers: [],\n });\n }\n continue;\n }\n\n const name: string = id?.name ?? 'unknown';\n let kind: SymbolKind = 'variable';\n let params: Parameter[] | undefined;\n let returnType: string | undefined;\n\n if (\n init?.type === 'FunctionExpression' ||\n init?.type === 'ArrowFunctionExpression'\n ) {\n kind = 'function';\n const rawParams = init.params ?? [];\n params = rawParams.map(extractParam);\n returnType = typeText(init.returnType);\n }\n const mods: Modifier[] = [];\n symbols.push({\n kind,\n name,\n span: span(decl.start, decl.end),\n isExported,\n modifiers: mods,\n parameters: params,\n returnType,\n });\n }\n if (symbols.length === 0) return null;\n if (symbols.length === 1) return symbols[0]!;\n return symbols;\n }\n\n if (type === 'TSTypeAliasDeclaration') {\n const name: string = node.id?.name ?? 'unknown';\n return {\n kind: 'type',\n name,\n span: span(node.start, node.end),\n isExported,\n modifiers: [],\n };\n }\n\n if (type === 'TSInterfaceDeclaration') {\n const name: string = node.id?.name ?? 'unknown';\n const heritage = interfaceHeritage(node);\n const members = extractInterfaceMembers(node.body?.body ?? []);\n const typeParameters: string[] | undefined =\n node.typeParameters?.params?.map((p: { name?: { name?: string } }) => p.name?.name as string).filter(Boolean) || undefined;\n const sym: ExtractedSymbol = {\n kind: 'interface',\n name,\n span: span(node.start, node.end),\n isExported,\n modifiers: [],\n heritage: heritage.length > 0 ? heritage : undefined,\n members: members.length > 0 ? members : undefined,\n };\n if (typeParameters && typeParameters.length > 0) sym.typeParameters = typeParameters;\n return sym;\n }\n\n if (type === 'TSEnumDeclaration') {\n const name: string = node.id?.name ?? 'unknown';\n const mods = extractModifiers(node);\n const rawMembers: Array<OxcSpan & { id?: { name?: string; value?: string } }> = node.body?.members ?? [];\n const members: ExtractedSymbol[] = rawMembers.map((m) => ({\n kind: 'property' as SymbolKind,\n name: m.id?.name ?? m.id?.value ?? 'unknown',\n span: span(m.start, m.end),\n isExported: false,\n modifiers: [],\n }));\n return {\n kind: 'enum',\n name,\n span: span(node.start, node.end),\n isExported,\n modifiers: mods,\n members: members.length > 0 ? members : undefined,\n };\n }\n\n return null;\n }\n\n const result: ExtractedSymbol[] = [];\n\n for (const node of program.body) {\n let sym: ExtractedSymbol | ExtractedSymbol[] | null = null;\n const record = node as unknown as Record<string, unknown>;\n const type: string = typeof record.type === 'string' ? record.type : '';\n\n if (type === 'ExportNamedDeclaration') {\n const n = node as unknown as {\n declaration?: unknown;\n start: number;\n end: number;\n };\n if (n.declaration) {\n sym = buildSymbol(n.declaration as OxcNode, true);\n if (sym && !Array.isArray(sym)) {\n sym.span = span(n.start, n.end);\n } else if (Array.isArray(sym)) {\n for (const s of sym) s.span = span(n.start, n.end);\n }\n }\n } else if (type === 'ExportDefaultDeclaration') {\n const n = node as unknown as {\n declaration?: { id?: { name?: string } } & Record<string, unknown>;\n start: number;\n end: number;\n };\n const decl = n.declaration;\n if (decl) {\n sym = buildSymbol(decl as unknown as OxcNode, true);\n if (sym && !Array.isArray(sym)) {\n sym.name = decl.id?.name ?? 'default';\n sym.isExported = true;\n sym.span = span(n.start, n.end);\n }\n }\n } else {\n sym = buildSymbol(node as unknown as OxcNode, false);\n }\n\n const syms: ExtractedSymbol[] = Array.isArray(sym) ? sym : sym ? [sym] : [];\n for (const s of syms) {\n const nodeStart = (node as { start?: number }).start ?? 0;\n const jsdocText = findJsDocComment(nodeStart);\n if (jsdocText) {\n s.jsDoc = parseJsDoc(jsdocText);\n }\n result.push(s);\n }\n }\n\n return result;\n}\n",
|
|
13
|
+
"import { resolve, dirname, extname } from 'node:path';\nimport type { Program } from 'oxc-parser';\nimport type { TsconfigPaths } from '../common/tsconfig-resolver';\nimport type { ImportReference } from './types';\n\nexport function resolveImport(\n currentFilePath: string,\n importPath: string,\n tsconfigPaths?: TsconfigPaths,\n): string[] {\n const withTypeScriptCandidates = (resolved: string): string[] => {\n const extension = extname(resolved);\n if (extension === '') {\n return [\n resolved + '.ts',\n resolved + '/index.ts',\n resolved + '.mts',\n resolved + '/index.mts',\n resolved + '.cts',\n resolved + '/index.cts',\n ];\n }\n if (extension === '.js') return [resolved.slice(0, -3) + '.ts'];\n if (extension === '.mjs') return [resolved.slice(0, -4) + '.mts'];\n if (extension === '.cjs') return [resolved.slice(0, -4) + '.cts'];\n return [resolved];\n };\n\n if (importPath.startsWith('.')) {\n const resolved = resolve(dirname(currentFilePath), importPath);\n return withTypeScriptCandidates(resolved);\n }\n\n if (tsconfigPaths) {\n for (const [pattern, targets] of tsconfigPaths.paths) {\n if (targets.length === 0) continue;\n\n const starIdx = pattern.indexOf('*');\n\n if (starIdx === -1) {\n if (importPath === pattern) {\n const candidates: string[] = [];\n for (const t of targets) {\n candidates.push(...withTypeScriptCandidates(resolve(tsconfigPaths.baseUrl, t)));\n }\n return candidates;\n }\n } else {\n const prefix = pattern.slice(0, starIdx);\n const suffix = pattern.slice(starIdx + 1);\n if (\n importPath.startsWith(prefix) &&\n (suffix === '' || importPath.endsWith(suffix))\n ) {\n const captured = importPath.slice(\n prefix.length,\n suffix === '' ? undefined : importPath.length - suffix.length,\n );\n const candidates: string[] = [];\n for (const t of targets) {\n candidates.push(...withTypeScriptCandidates(resolve(tsconfigPaths.baseUrl, t.replace('*', captured))));\n }\n return candidates;\n }\n }\n }\n }\n\n return [];\n}\n\nexport function buildImportMap(\n ast: Program,\n currentFilePath: string,\n tsconfigPaths?: TsconfigPaths,\n resolveImportFn: (\n currentFilePath: string,\n importPath: string,\n tsconfigPaths?: TsconfigPaths,\n ) => string[] = resolveImport,\n): Map<string, ImportReference> {\n const map = new Map<string, ImportReference>();\n const body = (ast as unknown as { body?: Array<Record<string, unknown>> }).body ?? [];\n\n for (const node of body) {\n if (node.type !== 'ImportDeclaration') continue;\n\n const sourcePath: string = ((node.source as { value?: string } | undefined)?.value) ?? '';\n const candidates = resolveImportFn(currentFilePath, sourcePath, tsconfigPaths);\n if (candidates.length === 0) continue;\n const resolved = candidates[0];\n\n const specifiers = (node.specifiers as Array<Record<string, unknown>> | undefined) ?? [];\n for (const spec of specifiers) {\n switch (spec.type) {\n case 'ImportSpecifier':\n map.set((spec.local as { name: string }).name, {\n path: resolved!,\n importedName: (spec.imported as { name: string }).name,\n });\n break;\n case 'ImportDefaultSpecifier':\n map.set((spec.local as { name: string }).name, {\n path: resolved!,\n importedName: 'default',\n });\n break;\n case 'ImportNamespaceSpecifier':\n map.set((spec.local as { name: string }).name, {\n path: resolved!,\n importedName: '*',\n });\n break;\n }\n }\n }\n\n return map;\n}\n",
|
|
14
|
+
"import type { QualifiedName } from '../extractor/types';\n\nconst SKIP_KEYS = new Set(['loc', 'start', 'end', 'scope']);\n\nexport function isNode(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function isNodeArray(value: unknown): value is ReadonlyArray<unknown> {\n return Array.isArray(value);\n}\n\nexport function visit(\n node: unknown,\n callback: (node: Record<string, unknown>) => void,\n): void {\n if (!node || typeof node !== 'object') return;\n\n if (Array.isArray(node)) {\n for (const item of node) visit(item, callback);\n return;\n }\n\n const record = node as Record<string, unknown>;\n callback(record);\n\n for (const key of Object.keys(record)) {\n if (SKIP_KEYS.has(key)) continue;\n const child = record[key];\n if (child && typeof child === 'object') {\n visit(child, callback);\n }\n }\n}\n\nexport function collectNodes(\n root: unknown,\n predicate: (node: Record<string, unknown>) => boolean,\n): Record<string, unknown>[] {\n const results: Record<string, unknown>[] = [];\n visit(root, (node) => {\n if (predicate(node)) results.push(node);\n });\n return results;\n}\n\nexport function getNodeHeader(\n node: Record<string, unknown>,\n parent?: Record<string, unknown> | null,\n): string {\n const id = node.id as Record<string, unknown> | undefined;\n if (id && typeof id.name === 'string') return id.name;\n\n const key = node.key as Record<string, unknown> | undefined;\n if (key) {\n if (typeof key.name === 'string') return key.name;\n if (\n (key.type === 'StringLiteral' || key.type === 'Literal') &&\n typeof key.value === 'string'\n ) {\n return key.value;\n }\n }\n\n if (parent) {\n if (parent.type === 'VariableDeclarator') {\n const pid = parent.id as Record<string, unknown> | undefined;\n if (pid && typeof pid.name === 'string') return pid.name;\n }\n if (\n parent.type === 'MethodDefinition' ||\n parent.type === 'PropertyDefinition' ||\n parent.type === 'Property'\n ) {\n const pkey = parent.key as Record<string, unknown> | undefined;\n if (pkey) {\n if (typeof pkey.name === 'string') return pkey.name;\n if (typeof pkey.value === 'string') return pkey.value;\n }\n }\n }\n\n return 'anonymous';\n}\n\nexport function isFunctionNode(node: Record<string, unknown>): boolean {\n return (\n node.type === 'FunctionDeclaration' ||\n node.type === 'FunctionExpression' ||\n node.type === 'ArrowFunctionExpression'\n );\n}\n\nexport function getNodeName(node: unknown): string | null {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return null;\n const record = node as Record<string, unknown>;\n return typeof record.name === 'string' ? record.name : null;\n}\n\nexport function getStringLiteralValue(node: unknown): string | null {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return null;\n const record = node as Record<string, unknown>;\n if (\n (record.type === 'StringLiteral' || record.type === 'Literal') &&\n typeof record.value === 'string'\n ) {\n return record.value;\n }\n return null;\n}\n\nexport function getQualifiedName(expr: unknown): QualifiedName | null {\n if (!expr || typeof expr !== 'object' || Array.isArray(expr)) return null;\n const node = expr as Record<string, unknown>;\n\n if (node.type === 'Identifier') {\n const name = node.name as string;\n return { root: name, parts: [], full: name };\n }\n\n if (node.type === 'ThisExpression') {\n return { root: 'this', parts: [], full: 'this' };\n }\n\n if (node.type === 'Super') {\n return { root: 'super', parts: [], full: 'super' };\n }\n\n if (node.type === 'MemberExpression') {\n const parts: string[] = [];\n let current: Record<string, unknown> = node;\n\n while (current.type === 'MemberExpression') {\n const prop = current.property as Record<string, unknown> | undefined;\n if (!prop || typeof prop.name !== 'string') return null;\n parts.unshift(prop.name);\n current = current.object as Record<string, unknown>;\n }\n\n let root: string;\n if (current.type === 'Identifier') {\n root = current.name as string;\n } else if (current.type === 'ThisExpression') {\n root = 'this';\n } else if (current.type === 'Super') {\n root = 'super';\n } else {\n return null;\n }\n\n const full = [root, ...parts].join('.');\n return { root, parts, full };\n }\n\n return null;\n}\n",
|
|
15
|
+
"import type { Program } from 'oxc-parser';\nimport type { TsconfigPaths } from '../common/tsconfig-resolver';\nimport type { CodeRelation } from './types';\nimport { resolveImport } from './extractor-utils';\nimport { visit, getStringLiteralValue } from '../parser/ast-utils';\n\nexport function extractImports(\n ast: Program,\n filePath: string,\n tsconfigPaths?: TsconfigPaths,\n resolveImportFn: (\n currentFilePath: string,\n importPath: string,\n tsconfigPaths?: TsconfigPaths,\n ) => string[] = resolveImport,\n): CodeRelation[] {\n const relations: CodeRelation[] = [];\n const body = (ast as unknown as { body?: Array<Record<string, unknown>> }).body ?? [];\n\n for (const node of body) {\n if (node.type === 'ImportDeclaration') {\n const sourcePath: string = ((node.source as { value?: string } | undefined)?.value) ?? '';\n const candidates = resolveImportFn(filePath, sourcePath, tsconfigPaths);\n if (candidates.length === 0) continue;\n const resolved = candidates[0]!;\n\n const isType = node.importKind === 'type';\n relations.push({\n type: 'imports',\n srcFilePath: filePath,\n srcSymbolName: null,\n dstFilePath: resolved,\n dstSymbolName: null,\n ...(isType ? { metaJson: JSON.stringify({ isType: true }) } : {}),\n });\n continue;\n }\n\n if (node.type === 'ExportAllDeclaration' && node.source) {\n const sourcePath: string = ((node.source as { value?: string } | undefined)?.value) ?? '';\n const candidates = resolveImportFn(filePath, sourcePath, tsconfigPaths);\n if (candidates.length === 0) continue;\n const resolved = candidates[0]!;\n\n const isType = node.exportKind === 'type';\n const meta: Record<string, unknown> = { isReExport: true };\n if (isType) meta.isType = true;\n relations.push({\n type: 'imports',\n srcFilePath: filePath,\n srcSymbolName: null,\n dstFilePath: resolved,\n dstSymbolName: null,\n metaJson: JSON.stringify(meta),\n });\n continue;\n }\n\n if (node.type === 'ExportNamedDeclaration' && node.source) {\n const sourcePath: string = ((node.source as { value?: string } | undefined)?.value) ?? '';\n const candidates = resolveImportFn(filePath, sourcePath, tsconfigPaths);\n if (candidates.length === 0) continue;\n const resolved = candidates[0]!;\n\n relations.push({\n type: 'imports',\n srcFilePath: filePath,\n srcSymbolName: null,\n dstFilePath: resolved,\n dstSymbolName: null,\n metaJson: JSON.stringify({ isReExport: true }),\n });\n }\n }\n\n visit(ast, (node) => {\n if (node.type !== 'ImportExpression') return;\n const sourceValue = getStringLiteralValue(node.source);\n if (!sourceValue) return;\n const candidates = resolveImportFn(filePath, sourceValue, tsconfigPaths);\n if (candidates.length === 0) return;\n const resolved = candidates[0]!;\n\n relations.push({\n type: 'imports',\n srcFilePath: filePath,\n srcSymbolName: null,\n dstFilePath: resolved,\n dstSymbolName: null,\n metaJson: JSON.stringify({ isDynamic: true }),\n });\n });\n\n return relations;\n}\n",
|
|
16
|
+
"import type { Program } from 'oxc-parser';\nimport type { ImportReference, CodeRelation } from './types';\nimport { getQualifiedName } from '../parser/ast-utils';\n\nexport function extractCalls(\n ast: Program,\n filePath: string,\n importMap: Map<string, ImportReference>,\n): CodeRelation[] {\n const relations: CodeRelation[] = [];\n const functionStack: string[] = [];\n const classStack: string[] = [];\n\n function currentCaller(): string | null {\n if (functionStack.length > 0) return functionStack[functionStack.length - 1] ?? null;\n return null;\n }\n\n function resolveCallee(\n qn: { root: string; parts: string[]; full: string } | null,\n ): { dstFilePath: string; dstSymbolName: string; resolution: string } | null {\n if (!qn) return null;\n\n const ref = importMap.get(qn.root);\n\n if (qn.parts.length === 0) {\n if (ref) {\n return { dstFilePath: ref.path, dstSymbolName: ref.importedName, resolution: 'import' };\n }\n return { dstFilePath: filePath, dstSymbolName: qn.root, resolution: 'local' };\n } else {\n if (ref && ref.importedName === '*') {\n const dstSymbolName = qn.parts[qn.parts.length - 1]!;\n return { dstFilePath: ref.path, dstSymbolName, resolution: 'namespace' };\n }\n return { dstFilePath: filePath, dstSymbolName: qn.full, resolution: 'local-member' };\n }\n }\n\n function walk(node: unknown): void {\n if (!node || typeof node !== 'object') return;\n\n if (Array.isArray(node)) {\n for (const item of node) walk(item);\n return;\n }\n\n const record = node as Record<string, unknown>;\n const type: string = typeof record.type === 'string' ? record.type : '';\n\n if (type === 'ClassDeclaration' || type === 'ClassExpression') {\n const classNode = record as { id?: { name?: string }; body?: unknown };\n const className: string = classNode.id?.name ?? 'AnonymousClass';\n classStack.push(className);\n walk(classNode.body);\n classStack.pop();\n return;\n }\n\n if (type === 'FunctionDeclaration') {\n const functionNode = record as { id?: { name?: string }; body?: unknown };\n const name: string = functionNode.id?.name ?? 'anonymous';\n functionStack.push(name);\n walk(functionNode.body);\n functionStack.pop();\n return;\n }\n\n if (type === 'VariableDeclarator' && (record as { init?: { type?: string } }).init && (\n (record as { init?: { type?: string } }).init?.type === 'FunctionExpression' ||\n (record as { init?: { type?: string } }).init?.type === 'ArrowFunctionExpression'\n )) {\n const declarator = record as { id?: { name?: string }; init?: { body?: unknown } };\n const name: string = declarator.id?.name ?? 'anonymous';\n functionStack.push(name);\n walk(declarator.init?.body ?? declarator.init);\n functionStack.pop();\n return;\n }\n\n if (type === 'MethodDefinition' && (record as { value?: unknown }).value) {\n const method = record as { key?: { name?: string }; value?: { body?: unknown } };\n const className = classStack[classStack.length - 1] ?? '';\n const methodName: string = method.key?.name ?? 'anonymous';\n const fullName = className ? `${className}.${methodName}` : methodName;\n functionStack.push(fullName);\n walk(method.value?.body);\n functionStack.pop();\n return;\n }\n\n if (type === 'FunctionExpression' || type === 'ArrowFunctionExpression') {\n const parentCaller = currentCaller();\n const anonymousName = parentCaller ? `${parentCaller}.<anonymous>` : '<anonymous>';\n functionStack.push(anonymousName);\n walk((record as { body?: unknown }).body);\n functionStack.pop();\n return;\n }\n\n if (type === 'CallExpression') {\n const call = record as { callee?: unknown; arguments?: unknown[] };\n const qn = getQualifiedName(call.callee);\n const dst = resolveCallee(qn);\n if (dst) {\n const srcSymbolName = currentCaller();\n const meta: Record<string, unknown> = {};\n if (srcSymbolName === null) meta.scope = 'module';\n\n relations.push({\n type: 'calls',\n srcFilePath: filePath,\n srcSymbolName,\n dstFilePath: dst.dstFilePath,\n dstSymbolName: dst.dstSymbolName,\n ...(Object.keys(meta).length > 0 ? { metaJson: JSON.stringify(meta) } : {}),\n });\n }\n walk(call.callee);\n for (const arg of call.arguments ?? []) walk(arg);\n return;\n }\n\n if (type === 'NewExpression') {\n const ctorCall = record as { callee?: unknown; arguments?: unknown[] };\n const qn = getQualifiedName(ctorCall.callee);\n const dst = resolveCallee(qn);\n if (dst) {\n const srcSymbolName = currentCaller();\n const meta: Record<string, unknown> = { isNew: true };\n if (srcSymbolName === null) meta.scope = 'module';\n\n relations.push({\n type: 'calls',\n srcFilePath: filePath,\n srcSymbolName,\n dstFilePath: dst.dstFilePath,\n dstSymbolName: dst.dstSymbolName,\n metaJson: JSON.stringify(meta),\n });\n }\n for (const arg of ctorCall.arguments ?? []) walk(arg);\n return;\n }\n\n for (const key of Object.keys(record)) {\n if (key === 'loc' || key === 'start' || key === 'end' || key === 'scope') continue;\n const child = record[key];\n if (child && typeof child === 'object') {\n walk(child);\n }\n }\n }\n\n walk(ast);\n return relations;\n}\n",
|
|
17
|
+
"import type { Program } from 'oxc-parser';\nimport type { ImportReference, CodeRelation } from './types';\nimport { visit, getQualifiedName } from '../parser/ast-utils';\n\nexport function extractHeritage(\n ast: Program,\n filePath: string,\n importMap: Map<string, ImportReference>,\n): CodeRelation[] {\n const relations: CodeRelation[] = [];\n\n visit(ast, (node) => {\n if (node.type === 'TSInterfaceDeclaration') {\n const interfaceName: string = ((node.id as { name?: string } | undefined)?.name) ?? 'AnonymousInterface';\n const interfaces = (node.extends as unknown[] | undefined) ?? [];\n for (const item of interfaces) {\n const expr = (item as { expression?: unknown }).expression ?? item;\n const qn = getQualifiedName(expr);\n if (!qn) continue;\n const rel = resolveHeritageDst(qn, filePath, importMap);\n relations.push({\n type: 'extends',\n srcFilePath: filePath,\n srcSymbolName: interfaceName,\n ...rel,\n });\n }\n return;\n }\n\n if (node.type !== 'ClassDeclaration' && node.type !== 'ClassExpression') return;\n\n const className: string =\n ((node.id as { name?: string } | undefined)?.name) ?? 'AnonymousClass';\n\n if (node.superClass) {\n const qn = getQualifiedName(node.superClass);\n if (qn) {\n const rel = resolveHeritageDst(qn, filePath, importMap);\n relations.push({\n type: 'extends',\n srcFilePath: filePath,\n srcSymbolName: className,\n ...rel,\n });\n }\n }\n\n const impls = (node.implements as unknown[] | undefined) ?? [];\n for (const impl of impls) {\n const expr = (impl as { expression?: unknown }).expression ?? impl;\n const qn = getQualifiedName(expr);\n if (!qn) continue;\n const rel = resolveHeritageDst(qn, filePath, importMap);\n relations.push({\n type: 'implements',\n srcFilePath: filePath,\n srcSymbolName: className,\n ...rel,\n });\n }\n });\n\n return relations;\n}\n\nfunction resolveHeritageDst(\n qn: { root: string; parts: string[]; full: string },\n currentFilePath: string,\n importMap: Map<string, ImportReference>,\n): { dstFilePath: string; dstSymbolName: string; metaJson?: string } {\n const ref = importMap.get(qn.root);\n\n if (ref) {\n if (ref.importedName === '*') {\n const dstSymbolName = qn.parts[qn.parts.length - 1] ?? qn.root;\n return {\n dstFilePath: ref.path,\n dstSymbolName,\n metaJson: JSON.stringify({ isNamespaceImport: true }),\n };\n }\n return {\n dstFilePath: ref.path,\n dstSymbolName: qn.parts.length > 0 ? qn.full : ref.importedName,\n };\n }\n\n return {\n dstFilePath: currentFilePath,\n dstSymbolName: qn.full,\n metaJson: JSON.stringify({ isLocal: true }),\n };\n}\n",
|
|
18
|
+
"import type { Program } from 'oxc-parser';\nimport type { TsconfigPaths } from '../common/tsconfig-resolver';\nimport type { CodeRelation } from './types';\nimport { buildImportMap } from './extractor-utils';\nimport { extractImports } from './imports-extractor';\nimport { extractCalls } from './calls-extractor';\nimport { extractHeritage } from './heritage-extractor';\n\nexport function extractRelations(\n ast: Program,\n filePath: string,\n tsconfigPaths?: TsconfigPaths,\n): CodeRelation[] {\n const importMap = buildImportMap(ast, filePath, tsconfigPaths);\n\n const imports = extractImports(ast, filePath, tsconfigPaths);\n const calls = extractCalls(ast, filePath, importMap);\n const heritage = extractHeritage(ast, filePath, importMap);\n\n return [...imports, ...calls, ...heritage];\n}\n",
|
|
19
|
+
"import { Database } from 'bun:sqlite';\nimport { mkdirSync, unlinkSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { drizzle, type BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite';\nimport { migrate } from 'drizzle-orm/bun-sqlite/migrator';\nimport { StoreError } from '../errors';\nimport * as schema from './schema';\nimport { FTS_SETUP_SQL } from './schema';\n\nexport interface DbConnectionOptions {\n projectRoot: string;\n}\n\nexport class DbConnection {\n private client: Database | null = null;\n private drizzle: BunSQLiteDatabase<typeof schema> | null = null;\n private readonly dbPath: string;\n private txDepth = 0;\n\n constructor(opts: DbConnectionOptions) {\n this.dbPath = join(opts.projectRoot, '.zipbul', 'gildash.db');\n }\n\n get drizzleDb(): BunSQLiteDatabase<typeof schema> {\n if (!this.drizzle) throw new StoreError('Database is not open. Call open() first.');\n return this.drizzle;\n }\n\n open(): void {\n try {\n mkdirSync(dirname(this.dbPath), { recursive: true });\n this.client = new Database(this.dbPath);\n\n this.client.run('PRAGMA journal_mode = WAL');\n this.client.run('PRAGMA foreign_keys = ON');\n this.client.run('PRAGMA busy_timeout = 5000');\n\n this.drizzle = drizzle(this.client, { schema });\n\n migrate(this.drizzle, {\n migrationsFolder: join(import.meta.dirname, 'migrations'),\n });\n\n for (const sql of FTS_SETUP_SQL) {\n this.client.run(sql);\n }\n } catch (err) {\n if (this.isCorruptionError(err) && existsSync(this.dbPath)) {\n this.closeClient();\n unlinkSync(this.dbPath);\n for (const ext of ['-wal', '-shm']) {\n const p = this.dbPath + ext;\n if (existsSync(p)) unlinkSync(p);\n }\n try {\n this.open();\n return;\n } catch (retryErr) {\n throw new StoreError(`Failed to recover database at ${this.dbPath}`, { cause: retryErr });\n }\n }\n if (err instanceof StoreError) throw err;\n throw new StoreError(`Failed to open database at ${this.dbPath}`, { cause: err });\n }\n }\n\n close(): void {\n this.closeClient();\n this.drizzle = null;\n }\n\n transaction<T>(fn: (tx: DbConnection) => T): T {\n const db = this.requireClient();\n\n if (this.txDepth === 0) {\n this.txDepth++;\n try {\n return db.transaction(() => fn(this))();\n } finally {\n this.txDepth--;\n }\n }\n\n const sp = `sp_${this.txDepth++}`;\n db.run(`SAVEPOINT \"${sp}\"`);\n try {\n const result = fn(this);\n db.run(`RELEASE SAVEPOINT \"${sp}\"`);\n return result;\n } catch (err) {\n db.run(`ROLLBACK TO SAVEPOINT \"${sp}\"`);\n db.run(`RELEASE SAVEPOINT \"${sp}\"`);\n throw err;\n } finally {\n this.txDepth--;\n }\n }\n\n immediateTransaction<T>(fn: () => T): T {\n const db = this.requireClient();\n this.txDepth++;\n db.run('BEGIN IMMEDIATE');\n try {\n const result = fn();\n db.run('COMMIT');\n return result;\n } catch (err) {\n db.run('ROLLBACK');\n throw err;\n } finally {\n this.txDepth--;\n }\n }\n\n query(sql: string): unknown {\n const row = this.requireClient().prepare(sql).get() as Record<string, unknown> | null;\n if (!row) return null;\n return Object.values(row)[0];\n }\n\n getTableNames(): string[] {\n const rows = this.requireClient()\n .query(\"SELECT name FROM sqlite_master WHERE type = 'table'\")\n .all() as Array<{ name: string }>;\n return rows.map((r) => r.name);\n }\n\n selectOwner(): { pid: number; heartbeat_at: string } | undefined {\n const row = this.requireClient()\n .prepare('SELECT pid, heartbeat_at FROM watcher_owner WHERE id = 1')\n .get() as { pid: number; heartbeat_at: string } | null;\n return row ?? undefined;\n }\n\n insertOwner(pid: number): void {\n const now = new Date().toISOString();\n this.requireClient()\n .prepare('INSERT INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)')\n .run(pid, now, now);\n }\n\n replaceOwner(pid: number): void {\n const now = new Date().toISOString();\n this.requireClient()\n .prepare('INSERT OR REPLACE INTO watcher_owner (id, pid, started_at, heartbeat_at) VALUES (1, ?, ?, ?)')\n .run(pid, now, now);\n }\n\n touchOwner(pid: number): void {\n const now = new Date().toISOString();\n this.requireClient()\n .prepare('UPDATE watcher_owner SET heartbeat_at = ? WHERE id = 1 AND pid = ?')\n .run(now, pid);\n }\n\n deleteOwner(pid: number): void {\n this.requireClient()\n .prepare('DELETE FROM watcher_owner WHERE id = 1 AND pid = ?')\n .run(pid);\n }\n\n private requireClient(): Database {\n if (!this.client) throw new StoreError('Database is not open. Call open() first.');\n return this.client;\n }\n\n private closeClient(): void {\n if (this.client) {\n this.client.close();\n this.client = null;\n }\n }\n\n private isCorruptionError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n return (\n msg.includes('malformed') ||\n msg.includes('corrupt') ||\n msg.includes('not a database') ||\n msg.includes('disk i/o error') ||\n msg.includes('sqlite_corrupt')\n );\n }\n}\n",
|
|
20
|
+
"import { sql } from 'drizzle-orm';\nimport {\n sqliteTable,\n text,\n integer,\n real,\n index,\n primaryKey,\n foreignKey,\n check,\n} from 'drizzle-orm/sqlite-core';\n\nexport const files = sqliteTable(\n 'files',\n {\n project: text('project').notNull(),\n filePath: text('file_path').notNull(),\n mtimeMs: real('mtime_ms').notNull(),\n size: integer('size').notNull(),\n contentHash: text('content_hash').notNull(),\n updatedAt: text('updated_at').notNull(),\n },\n (table) => [primaryKey({ columns: [table.project, table.filePath] })],\n);\n\nexport const symbols = sqliteTable(\n 'symbols',\n {\n id: integer('id').primaryKey({ autoIncrement: true }),\n project: text('project').notNull(),\n filePath: text('file_path').notNull(),\n kind: text('kind').notNull(),\n name: text('name').notNull(),\n startLine: integer('start_line').notNull(),\n startColumn: integer('start_column').notNull(),\n endLine: integer('end_line').notNull(),\n endColumn: integer('end_column').notNull(),\n isExported: integer('is_exported').notNull().default(0),\n signature: text('signature'),\n fingerprint: text('fingerprint'),\n detailJson: text('detail_json'),\n contentHash: text('content_hash').notNull(),\n indexedAt: text('indexed_at').notNull(),\n },\n (table) => [\n index('idx_symbols_project_file').on(table.project, table.filePath),\n index('idx_symbols_project_kind').on(table.project, table.kind),\n index('idx_symbols_project_name').on(table.project, table.name),\n index('idx_symbols_fingerprint').on(table.project, table.fingerprint),\n foreignKey({\n columns: [table.project, table.filePath],\n foreignColumns: [files.project, files.filePath],\n }).onDelete('cascade'),\n ],\n);\n\nexport const relations = sqliteTable(\n 'relations',\n {\n id: integer('id').primaryKey({ autoIncrement: true }),\n project: text('project').notNull(),\n type: text('type').notNull(),\n srcFilePath: text('src_file_path').notNull(),\n srcSymbolName: text('src_symbol_name'),\n dstFilePath: text('dst_file_path').notNull(),\n dstSymbolName: text('dst_symbol_name'),\n metaJson: text('meta_json'),\n },\n (table) => [\n index('idx_relations_src').on(table.project, table.srcFilePath),\n index('idx_relations_dst').on(table.project, table.dstFilePath),\n index('idx_relations_type').on(table.project, table.type),\n foreignKey({\n columns: [table.project, table.srcFilePath],\n foreignColumns: [files.project, files.filePath],\n }).onDelete('cascade'),\n foreignKey({\n columns: [table.project, table.dstFilePath],\n foreignColumns: [files.project, files.filePath],\n }).onDelete('cascade'),\n ],\n);\n\nexport const watcherOwner = sqliteTable(\n 'watcher_owner',\n {\n id: integer('id').primaryKey(),\n pid: integer('pid').notNull(),\n startedAt: text('started_at').notNull(),\n heartbeatAt: text('heartbeat_at').notNull(),\n },\n (table) => [check('watcher_owner_singleton', sql`${table.id} = 1`)],\n);\n\nexport const FTS_SETUP_SQL: readonly string[] = [\n `CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(\n name,\n file_path,\n kind,\n content=symbols,\n content_rowid=id\n )`,\n\n `CREATE TRIGGER IF NOT EXISTS symbols_ai\n AFTER INSERT ON symbols BEGIN\n INSERT INTO symbols_fts(rowid, name, file_path, kind)\n VALUES (new.id, new.name, new.file_path, new.kind);\n END`,\n\n `CREATE TRIGGER IF NOT EXISTS symbols_ad\n AFTER DELETE ON symbols BEGIN\n INSERT INTO symbols_fts(symbols_fts, rowid, name, file_path, kind)\n VALUES ('delete', old.id, old.name, old.file_path, old.kind);\n END`,\n\n `CREATE TRIGGER IF NOT EXISTS symbols_au\n AFTER UPDATE ON symbols BEGIN\n INSERT INTO symbols_fts(symbols_fts, rowid, name, file_path, kind)\n VALUES ('delete', old.id, old.name, old.file_path, old.kind);\n INSERT INTO symbols_fts(rowid, name, file_path, kind)\n VALUES (new.id, new.name, new.file_path, new.kind);\n END`,\n];\n",
|
|
21
|
+
"import { eq, and } from 'drizzle-orm';\nimport { files } from '../schema';\nimport type { DbConnection } from '../connection';\n\nexport interface FileRecord {\n project: string;\n filePath: string;\n mtimeMs: number;\n size: number;\n contentHash: string;\n updatedAt: string;\n}\n\nexport class FileRepository {\n constructor(private readonly db: DbConnection) {}\n\n getFile(project: string, filePath: string): FileRecord | null {\n return this.db.drizzleDb\n .select()\n .from(files)\n .where(and(eq(files.project, project), eq(files.filePath, filePath)))\n .get() ?? null;\n }\n\n upsertFile(record: FileRecord): void {\n this.db.drizzleDb\n .insert(files)\n .values({\n project: record.project,\n filePath: record.filePath,\n mtimeMs: record.mtimeMs,\n size: record.size,\n contentHash: record.contentHash,\n updatedAt: record.updatedAt,\n })\n .onConflictDoUpdate({\n target: [files.project, files.filePath],\n set: {\n mtimeMs: record.mtimeMs,\n size: record.size,\n contentHash: record.contentHash,\n updatedAt: record.updatedAt,\n },\n })\n .run();\n }\n\n getAllFiles(project: string): FileRecord[] {\n return this.db.drizzleDb\n .select()\n .from(files)\n .where(eq(files.project, project))\n .all();\n }\n\n getFilesMap(project: string): Map<string, FileRecord> {\n const rows = this.getAllFiles(project);\n const map = new Map<string, FileRecord>();\n for (const r of rows) map.set(r.filePath, r);\n return map;\n }\n\n deleteFile(project: string, filePath: string): void {\n this.db.drizzleDb\n .delete(files)\n .where(and(eq(files.project, project), eq(files.filePath, filePath)))\n .run();\n }\n}\n",
|
|
22
|
+
"import { eq, and, sql, count } from 'drizzle-orm';\nimport { symbols } from '../schema';\nimport type { DbConnection } from '../connection';\nimport { toFtsPrefixQuery } from './fts-utils';\n\nexport interface SymbolRecord {\n project: string;\n filePath: string;\n kind: string;\n name: string;\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n isExported: number;\n signature: string | null;\n fingerprint: string | null;\n detailJson: string | null;\n contentHash: string;\n indexedAt: string;\n}\n\nexport interface SearchOptions {\n kind?: string;\n limit?: number;\n}\n\nexport interface SymbolStats {\n symbolCount: number;\n fileCount: number;\n}\n\nexport class SymbolRepository {\n constructor(private readonly db: DbConnection) {}\n\n replaceFileSymbols(\n project: string,\n filePath: string,\n contentHash: string,\n syms: ReadonlyArray<Partial<SymbolRecord>>,\n ): void {\n this.db.drizzleDb\n .delete(symbols)\n .where(and(eq(symbols.project, project), eq(symbols.filePath, filePath)))\n .run();\n\n if (!syms.length) return;\n\n const now = new Date().toISOString();\n for (const sym of syms) {\n this.db.drizzleDb.insert(symbols).values({\n project,\n filePath,\n kind: sym.kind ?? 'unknown',\n name: sym.name ?? '',\n startLine: sym.startLine ?? 0,\n startColumn: sym.startColumn ?? 0,\n endLine: sym.endLine ?? 0,\n endColumn: sym.endColumn ?? 0,\n isExported: sym.isExported ?? 0,\n signature: sym.signature ?? null,\n fingerprint: sym.fingerprint ?? null,\n detailJson: sym.detailJson ?? null,\n contentHash,\n indexedAt: sym.indexedAt ?? now,\n }).run();\n }\n }\n\n getFileSymbols(project: string, filePath: string): SymbolRecord[] {\n return this.db.drizzleDb\n .select()\n .from(symbols)\n .where(and(eq(symbols.project, project), eq(symbols.filePath, filePath)))\n .all();\n }\n\n searchByName(project: string, query: string, opts: SearchOptions = {}): SymbolRecord[] {\n const limit = opts.limit ?? 50;\n const ftsQuery = toFtsPrefixQuery(query);\n\n if (!ftsQuery) return [];\n\n let builder = this.db.drizzleDb\n .select()\n .from(symbols)\n .where(\n and(\n sql`${symbols.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${ftsQuery})`,\n eq(symbols.project, project),\n opts.kind ? eq(symbols.kind, opts.kind) : undefined,\n ),\n )\n .orderBy(symbols.name)\n .limit(limit);\n\n return builder.all();\n }\n\n searchByKind(project: string, kind: string): SymbolRecord[] {\n return this.db.drizzleDb\n .select()\n .from(symbols)\n .where(and(eq(symbols.project, project), eq(symbols.kind, kind)))\n .orderBy(symbols.name)\n .all();\n }\n\n getStats(project: string): SymbolStats {\n const row = this.db.drizzleDb\n .select({\n symbolCount: count(),\n fileCount: sql<number>`COUNT(DISTINCT ${symbols.filePath})`,\n })\n .from(symbols)\n .where(eq(symbols.project, project))\n .get();\n return {\n symbolCount: row?.symbolCount ?? 0,\n fileCount: row?.fileCount ?? 0,\n };\n }\n\n getByFingerprint(project: string, fingerprint: string): SymbolRecord[] {\n return this.db.drizzleDb\n .select()\n .from(symbols)\n .where(and(eq(symbols.project, project), eq(symbols.fingerprint, fingerprint)))\n .all();\n }\n\n deleteFileSymbols(project: string, filePath: string): void {\n this.db.drizzleDb\n .delete(symbols)\n .where(and(eq(symbols.project, project), eq(symbols.filePath, filePath)))\n .run();\n }\n\n searchByQuery(opts: {\n ftsQuery?: string;\n kind?: string;\n filePath?: string;\n isExported?: boolean;\n project?: string;\n limit: number;\n }): (SymbolRecord & { id: number })[] {\n return this.db.drizzleDb\n .select()\n .from(symbols)\n .where(\n and(\n opts.ftsQuery\n ? sql`${symbols.id} IN (SELECT rowid FROM symbols_fts WHERE symbols_fts MATCH ${opts.ftsQuery})`\n : undefined,\n opts.project !== undefined ? eq(symbols.project, opts.project) : undefined,\n opts.kind ? eq(symbols.kind, opts.kind) : undefined,\n opts.filePath !== undefined ? eq(symbols.filePath, opts.filePath) : undefined,\n opts.isExported !== undefined\n ? eq(symbols.isExported, opts.isExported ? 1 : 0)\n : undefined,\n ),\n )\n .orderBy(symbols.name)\n .limit(opts.limit)\n .all() as (SymbolRecord & { id: number })[];\n }\n}\n",
|
|
23
|
+
"export function toFtsPrefixQuery(text: string): string {\n return text\n .trim()\n .split(/\\s+/)\n .map((token) => token.trim())\n .filter((token) => token.length > 0)\n .map((token) => `\"${token.replaceAll('\"', '\"\"')}\"*`)\n .join(' ');\n}\n",
|
|
24
|
+
"import { eq, and, isNull, or, sql } from 'drizzle-orm';\nimport { relations as relationsTable } from '../schema';\nimport type { DbConnection } from '../connection';\n\nexport interface RelationRecord {\n project: string;\n type: string;\n srcFilePath: string;\n srcSymbolName: string | null;\n dstFilePath: string;\n dstSymbolName: string | null;\n metaJson: string | null;\n}\n\nexport class RelationRepository {\n constructor(private readonly db: DbConnection) {}\n\n replaceFileRelations(\n project: string,\n srcFilePath: string,\n rels: ReadonlyArray<Partial<RelationRecord>>,\n ): void {\n this.db.drizzleDb\n .delete(relationsTable)\n .where(and(eq(relationsTable.project, project), eq(relationsTable.srcFilePath, srcFilePath)))\n .run();\n\n if (!rels.length) return;\n\n for (const rel of rels) {\n this.db.drizzleDb.insert(relationsTable).values({\n project,\n type: rel.type ?? 'unknown',\n srcFilePath: rel.srcFilePath ?? srcFilePath,\n srcSymbolName: rel.srcSymbolName ?? null,\n dstFilePath: rel.dstFilePath ?? '',\n dstSymbolName: rel.dstSymbolName ?? null,\n metaJson: rel.metaJson ?? null,\n }).run();\n }\n }\n\n getOutgoing(project: string, srcFilePath: string, srcSymbolName?: string): RelationRecord[] {\n if (srcSymbolName !== undefined) {\n return this.db.drizzleDb\n .select({\n project: relationsTable.project,\n type: relationsTable.type,\n srcFilePath: relationsTable.srcFilePath,\n srcSymbolName: relationsTable.srcSymbolName,\n dstFilePath: relationsTable.dstFilePath,\n dstSymbolName: relationsTable.dstSymbolName,\n metaJson: relationsTable.metaJson,\n })\n .from(relationsTable)\n .where(\n and(\n eq(relationsTable.project, project),\n eq(relationsTable.srcFilePath, srcFilePath),\n or(\n eq(relationsTable.srcSymbolName, srcSymbolName),\n isNull(relationsTable.srcSymbolName),\n ),\n ),\n )\n .all();\n }\n\n return this.db.drizzleDb\n .select({\n project: relationsTable.project,\n type: relationsTable.type,\n srcFilePath: relationsTable.srcFilePath,\n srcSymbolName: relationsTable.srcSymbolName,\n dstFilePath: relationsTable.dstFilePath,\n dstSymbolName: relationsTable.dstSymbolName,\n metaJson: relationsTable.metaJson,\n })\n .from(relationsTable)\n .where(\n and(\n eq(relationsTable.project, project),\n eq(relationsTable.srcFilePath, srcFilePath),\n ),\n )\n .all();\n }\n\n getIncoming(project: string, dstFilePath: string): RelationRecord[] {\n return this.db.drizzleDb\n .select({\n project: relationsTable.project,\n type: relationsTable.type,\n srcFilePath: relationsTable.srcFilePath,\n srcSymbolName: relationsTable.srcSymbolName,\n dstFilePath: relationsTable.dstFilePath,\n dstSymbolName: relationsTable.dstSymbolName,\n metaJson: relationsTable.metaJson,\n })\n .from(relationsTable)\n .where(\n and(\n eq(relationsTable.project, project),\n eq(relationsTable.dstFilePath, dstFilePath),\n ),\n )\n .all();\n }\n\n getByType(project: string, type: string): RelationRecord[] {\n return this.db.drizzleDb\n .select({\n project: relationsTable.project,\n type: relationsTable.type,\n srcFilePath: relationsTable.srcFilePath,\n srcSymbolName: relationsTable.srcSymbolName,\n dstFilePath: relationsTable.dstFilePath,\n dstSymbolName: relationsTable.dstSymbolName,\n metaJson: relationsTable.metaJson,\n })\n .from(relationsTable)\n .where(\n and(\n eq(relationsTable.project, project),\n eq(relationsTable.type, type),\n ),\n )\n .all();\n }\n\n deleteFileRelations(project: string, srcFilePath: string): void {\n this.db.drizzleDb\n .delete(relationsTable)\n .where(and(eq(relationsTable.project, project), eq(relationsTable.srcFilePath, srcFilePath)))\n .run();\n }\n\n searchRelations(opts: {\n srcFilePath?: string;\n srcSymbolName?: string;\n dstFilePath?: string;\n dstSymbolName?: string;\n type?: string;\n project?: string;\n limit: number;\n }): RelationRecord[] {\n return this.db.drizzleDb\n .select({\n project: relationsTable.project,\n type: relationsTable.type,\n srcFilePath: relationsTable.srcFilePath,\n srcSymbolName: relationsTable.srcSymbolName,\n dstFilePath: relationsTable.dstFilePath,\n dstSymbolName: relationsTable.dstSymbolName,\n metaJson: relationsTable.metaJson,\n })\n .from(relationsTable)\n .where(\n and(\n opts.project !== undefined ? eq(relationsTable.project, opts.project) : undefined,\n opts.srcFilePath !== undefined\n ? eq(relationsTable.srcFilePath, opts.srcFilePath)\n : undefined,\n opts.srcSymbolName !== undefined\n ? eq(relationsTable.srcSymbolName, opts.srcSymbolName)\n : undefined,\n opts.dstFilePath !== undefined\n ? eq(relationsTable.dstFilePath, opts.dstFilePath)\n : undefined,\n opts.dstSymbolName !== undefined\n ? eq(relationsTable.dstSymbolName, opts.dstSymbolName)\n : undefined,\n opts.type !== undefined ? eq(relationsTable.type, opts.type) : undefined,\n ),\n )\n .limit(opts.limit)\n .all();\n }\n\n retargetRelations(\n project: string,\n oldFile: string,\n oldSymbol: string | null,\n newFile: string,\n newSymbol: string | null,\n ): void {\n const condition = oldSymbol === null\n ? and(\n eq(relationsTable.project, project),\n eq(relationsTable.dstFilePath, oldFile),\n isNull(relationsTable.dstSymbolName),\n )\n : and(\n eq(relationsTable.project, project),\n eq(relationsTable.dstFilePath, oldFile),\n eq(relationsTable.dstSymbolName, oldSymbol),\n );\n\n this.db.drizzleDb\n .update(relationsTable)\n .set({ dstFilePath: newFile, dstSymbolName: newSymbol })\n .where(condition)\n .run();\n }\n}\n",
|
|
25
|
+
"import type {\n AsyncSubscription,\n SubscribeCallback,\n} from \"@parcel/watcher\";\nimport { subscribe as parcelSubscribe } from \"@parcel/watcher\";\n\ntype FileEvent = Parameters<SubscribeCallback>[1][number];\ntype SubscribeOptions = NonNullable<Parameters<typeof parcelSubscribe>[2]>;\nimport path from \"node:path\";\nimport { WatcherError } from \"../errors\";\nimport type { FileChangeEvent, FileChangeEventType, WatcherOptions } from \"./types\";\nimport type { Logger } from \"../gildash\";\n\ntype SubscribeFn = (\n directoryPath: string,\n callback: SubscribeCallback,\n options?: SubscribeOptions,\n) => Promise<AsyncSubscription>;\n\nconst WATCHER_IGNORE_GLOBS: readonly string[] = [\n \"**/.git/**\",\n \"**/.zipbul/**\",\n \"**/dist/**\",\n \"**/node_modules/**\",\n];\n\nconst CONFIG_FILE_NAMES = new Set([\"package.json\", \"tsconfig.json\"]);\n\nfunction normalizePath(value: string): string {\n return value.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction mapEventType(type: FileEvent[\"type\"]): FileChangeEventType {\n if (type === \"update\") {\n return \"change\";\n }\n\n if (type === \"create\") {\n return \"create\";\n }\n\n return \"delete\";\n}\n\nexport class ProjectWatcher {\n #subscription: AsyncSubscription | undefined;\n #rootPath: string;\n #ignoreGlobs: string[];\n #extensions: Set<string>;\n #subscribe: SubscribeFn;\n #logger: Logger;\n\n constructor(options: WatcherOptions, subscribeFn: SubscribeFn = parcelSubscribe, logger: Logger = console) {\n this.#rootPath = options.projectRoot;\n this.#ignoreGlobs = [...WATCHER_IGNORE_GLOBS, ...(options.ignorePatterns ?? [])];\n this.#extensions = new Set(\n (options.extensions ?? [\".ts\", \".mts\", \".cts\"]).map((ext) =>\n ext.toLowerCase(),\n ),\n );\n this.#subscribe = subscribeFn;\n this.#logger = logger;\n }\n\n async start(onChange: (event: FileChangeEvent) => void): Promise<void> {\n try {\n this.#subscription = await this.#subscribe(\n this.#rootPath,\n (error, events) => {\n if (error) {\n this.#logger.error(new WatcherError(\"Callback error\", { cause: error }));\n return;\n }\n\n try {\n for (const rawEvent of events) {\n const relativePath = normalizePath(path.relative(this.#rootPath, rawEvent.path));\n\n if (relativePath.startsWith(\"..\")) {\n continue;\n }\n\n const baseName = path.basename(relativePath);\n const extension = path.extname(relativePath).toLowerCase();\n const isConfigFile = CONFIG_FILE_NAMES.has(baseName);\n\n if (!isConfigFile && !this.#extensions.has(extension)) {\n continue;\n }\n\n if (relativePath.endsWith(\".d.ts\")) {\n continue;\n }\n\n onChange({\n eventType: mapEventType(rawEvent.type),\n filePath: relativePath,\n });\n }\n } catch (callbackError) {\n this.#logger.error(new WatcherError(\"Callback error\", { cause: callbackError }));\n }\n },\n {\n ignore: this.#ignoreGlobs,\n },\n );\n } catch (error) {\n throw new WatcherError(\"Failed to subscribe watcher\", { cause: error });\n }\n }\n\n async close(): Promise<void> {\n if (!this.#subscription) {\n return;\n }\n\n try {\n await this.#subscription.unsubscribe();\n this.#subscription = undefined;\n } catch (error) {\n throw new WatcherError(\"Failed to close watcher\", { cause: error });\n }\n }\n}\n",
|
|
26
|
+
"import path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\n\nexport interface ProjectBoundary {\n dir: string;\n project: string;\n}\n\nconst DISCOVERY_EXCLUDE = [\"**/node_modules/**\", \"**/.git/**\", \"**/.zipbul/**\", \"**/dist/**\"];\n\nexport async function discoverProjects(projectRoot: string): Promise<ProjectBoundary[]> {\n const boundaries: ProjectBoundary[] = [];\n\n for await (const relativePackageJson of fs.glob(\"**/package.json\", {\n cwd: projectRoot,\n exclude: DISCOVERY_EXCLUDE,\n })) {\n const packageDir = path.dirname(relativePackageJson).replaceAll(\"\\\\\", \"/\");\n const packagePath = path.join(projectRoot, relativePackageJson);\n const content = await Bun.file(packagePath).json();\n\n const packageName =\n typeof content?.name === \"string\" && content.name.length > 0\n ? content.name\n : path.basename(packageDir === \".\" ? projectRoot : packageDir);\n\n boundaries.push({\n dir: packageDir,\n project: packageName,\n });\n }\n\n boundaries.sort((left, right) => right.dir.length - left.dir.length);\n return boundaries;\n}\n\nexport function resolveFileProject(\n filePath: string,\n boundaries: ProjectBoundary[],\n rootProject = \"default\",\n): string {\n const normalizedFilePath = filePath.replaceAll(\"\\\\\", \"/\");\n for (const boundary of boundaries) {\n if (boundary.dir === \".\") {\n return boundary.project;\n }\n\n if (\n normalizedFilePath === boundary.dir ||\n normalizedFilePath.startsWith(`${boundary.dir}/`)\n ) {\n return boundary.project;\n }\n }\n\n return rootProject;\n}\n",
|
|
27
|
+
"import path from \"node:path\";\n\nexport interface TsconfigPaths {\n baseUrl: string;\n paths: Map<string, string[]>;\n}\n\nconst cache = new Map<string, TsconfigPaths | null>();\n\nasync function readConfig(configPath: string): Promise<Record<string, unknown> | null> {\n const file = Bun.file(configPath);\n if (!(await file.exists())) {\n return null;\n }\n\n const parsed = await file.json();\n return typeof parsed === \"object\" && parsed !== null ? (parsed as Record<string, unknown>) : null;\n}\n\nexport async function loadTsconfigPaths(projectRoot: string): Promise<TsconfigPaths | null> {\n if (cache.has(projectRoot)) {\n return cache.get(projectRoot) ?? null;\n }\n\n const tsconfigPath = path.join(projectRoot, \"tsconfig.json\");\n\n const config = await readConfig(tsconfigPath);\n if (!config) {\n cache.set(projectRoot, null);\n return null;\n }\n\n const compilerOptions =\n typeof config.compilerOptions === \"object\" && config.compilerOptions !== null\n ? (config.compilerOptions as Record<string, unknown>)\n : null;\n\n if (!compilerOptions) {\n cache.set(projectRoot, null);\n return null;\n }\n\n const rawBaseUrl = typeof compilerOptions.baseUrl === \"string\" ? compilerOptions.baseUrl : null;\n const rawPaths =\n typeof compilerOptions.paths === \"object\" && compilerOptions.paths !== null\n ? (compilerOptions.paths as Record<string, unknown>)\n : null;\n\n if (!rawBaseUrl && !rawPaths) {\n cache.set(projectRoot, null);\n return null;\n }\n\n const resolvedBaseUrl = rawBaseUrl ? path.resolve(projectRoot, rawBaseUrl) : projectRoot;\n const paths = new Map<string, string[]>();\n\n if (rawPaths) {\n for (const [pattern, targets] of Object.entries(rawPaths)) {\n if (!Array.isArray(targets)) {\n continue;\n }\n\n const normalizedTargets = targets.filter((value): value is string => typeof value === \"string\");\n paths.set(pattern, normalizedTargets);\n }\n }\n\n const result: TsconfigPaths = {\n baseUrl: resolvedBaseUrl,\n paths,\n };\n\n cache.set(projectRoot, result);\n return result;\n}\n\nexport function clearTsconfigPathsCache(projectRoot?: string): void {\n if (projectRoot) {\n cache.delete(projectRoot);\n return;\n }\n\n cache.clear();\n}\n",
|
|
28
|
+
"import path from \"node:path\";\n\nexport function toRelativePath(projectRoot: string, absolutePath: string): string {\n return path.relative(projectRoot, absolutePath).replaceAll(\"\\\\\", \"/\");\n}\n\nexport function toAbsolutePath(projectRoot: string, relativePath: string): string {\n return path.resolve(projectRoot, relativePath);\n}\n",
|
|
29
|
+
"export function hashString(input: string): string {\n const raw = Bun.hash.xxHash64(input);\n const unsigned = BigInt.asUintN(64, BigInt(raw));\n return unsigned.toString(16).padStart(16, \"0\");\n}\n\nexport async function hashFile(filePath: string): Promise<string> {\n const text = await Bun.file(filePath).text();\n return hashString(text);\n}\n",
|
|
30
|
+
"import { promises as fsPromises } from 'node:fs';\nimport { join } from 'node:path';\nimport { hashString } from '../common/hasher';\n\nexport interface FileChangeRecord {\n filePath: string;\n contentHash: string;\n mtimeMs: number;\n size: number;\n}\n\nexport interface DetectChangesResult {\n changed: FileChangeRecord[];\n unchanged: FileChangeRecord[];\n deleted: string[];\n}\n\ninterface FileRepoPart {\n getFilesMap(): Map<string, { filePath: string; mtimeMs: number; size: number; contentHash: string }>;\n}\n\nexport interface DetectChangesOptions {\n projectRoot: string;\n extensions: string[];\n ignorePatterns: string[];\n fileRepo: FileRepoPart;\n}\n\nexport async function detectChanges(opts: DetectChangesOptions): Promise<DetectChangesResult> {\n const { projectRoot, extensions, ignorePatterns, fileRepo } = opts;\n\n const existingMap = fileRepo.getFilesMap();\n const seenPaths = new Set<string>();\n const changed: FileChangeRecord[] = [];\n const unchanged: FileChangeRecord[] = [];\n\n const ignoreGlobs = ignorePatterns.map((p) => new Bun.Glob(p));\n\n for await (const relativePath of fsPromises.glob('**/*', { cwd: projectRoot })) {\n if (!extensions.some((ext) => relativePath.endsWith(ext))) continue;\n\n if (ignoreGlobs.some((g) => g.match(relativePath))) continue;\n\n seenPaths.add(relativePath);\n\n const absPath = join(projectRoot, relativePath);\n const bunFile = Bun.file(absPath);\n const { size, lastModified: mtimeMs } = bunFile;\n\n const existing = existingMap.get(relativePath);\n\n if (!existing) {\n const text = await bunFile.text();\n const contentHash = hashString(text);\n changed.push({ filePath: relativePath, contentHash, mtimeMs, size });\n continue;\n }\n\n if (existing.mtimeMs === mtimeMs && existing.size === size) {\n unchanged.push({ filePath: relativePath, contentHash: existing.contentHash, mtimeMs, size });\n continue;\n }\n\n const text = await bunFile.text();\n const contentHash = hashString(text);\n if (contentHash === existing.contentHash) {\n unchanged.push({ filePath: relativePath, contentHash, mtimeMs, size });\n } else {\n changed.push({ filePath: relativePath, contentHash, mtimeMs, size });\n }\n }\n\n const deleted: string[] = [];\n for (const filePath of existingMap.keys()) {\n if (!seenPaths.has(filePath)) {\n deleted.push(filePath);\n }\n }\n\n return { changed, unchanged, deleted };\n}\n",
|
|
31
|
+
"import type { ParsedFile } from '../parser/types';\nimport type { ExtractedSymbol } from '../extractor/types';\nimport { extractSymbols } from '../extractor/symbol-extractor';\nimport { hashString } from '../common/hasher';\n\nexport interface SymbolDbRow {\n project: string;\n filePath: string;\n kind: string;\n name: string;\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n isExported: number;\n signature: string | null;\n fingerprint: string | null;\n detailJson: string | null;\n contentHash: string;\n indexedAt: string;\n}\n\ninterface SymbolRepoPart {\n replaceFileSymbols(\n project: string,\n filePath: string,\n contentHash: string,\n symbols: SymbolDbRow[],\n ): void;\n}\n\nexport interface IndexFileSymbolsOptions {\n parsed: ParsedFile;\n project: string;\n filePath: string;\n contentHash: string;\n symbolRepo: SymbolRepoPart;\n}\n\nfunction buildSignature(sym: ExtractedSymbol): string | null {\n if (sym.kind === 'function' || sym.kind === 'method') {\n const paramCount = sym.parameters?.length ?? 0;\n const isAsync = sym.modifiers.includes('async') ? 1 : 0;\n return `params:${paramCount}|async:${isAsync}`;\n }\n return null;\n}\n\nfunction buildDetailJson(sym: ExtractedSymbol): string | null {\n const detail: Record<string, unknown> = {};\n\n if (sym.jsDoc) detail.jsDoc = sym.jsDoc;\n\n if (sym.kind === 'function' || sym.kind === 'method') {\n if (sym.parameters !== undefined) detail.parameters = sym.parameters;\n if (sym.returnType !== undefined) detail.returnType = sym.returnType;\n }\n\n if (sym.heritage?.length) detail.heritage = sym.heritage;\n if (sym.decorators?.length) detail.decorators = sym.decorators;\n if (sym.typeParameters?.length) detail.typeParameters = sym.typeParameters;\n if (sym.modifiers?.length) detail.modifiers = sym.modifiers;\n if (sym.members?.length) detail.members = sym.members.map((m) => m.name);\n\n return Object.keys(detail).length > 0 ? JSON.stringify(detail) : null;\n}\n\nfunction buildRow(\n sym: ExtractedSymbol,\n name: string,\n project: string,\n filePath: string,\n contentHash: string,\n): SymbolDbRow {\n const signature = buildSignature(sym);\n const fingerprint = hashString(`${name}|${sym.kind}|${signature ?? ''}`);\n\n return {\n project,\n filePath,\n kind: sym.kind,\n name,\n startLine: sym.span.start.line,\n startColumn: sym.span.start.column,\n endLine: sym.span.end.line,\n endColumn: sym.span.end.column,\n isExported: sym.isExported ? 1 : 0,\n signature,\n fingerprint,\n detailJson: buildDetailJson(sym),\n contentHash,\n indexedAt: new Date().toISOString(),\n };\n}\n\nexport function indexFileSymbols(opts: IndexFileSymbolsOptions): void {\n const { parsed, project, filePath, contentHash, symbolRepo } = opts;\n\n const extracted = extractSymbols(parsed);\n const rows: SymbolDbRow[] = [];\n\n for (const sym of extracted) {\n rows.push(buildRow(sym, sym.name, project, filePath, contentHash));\n\n for (const member of sym.members ?? []) {\n rows.push(buildRow(member, `${sym.name}.${member.name}`, project, filePath, contentHash));\n }\n }\n\n symbolRepo.replaceFileSymbols(project, filePath, contentHash, rows);\n}\n",
|
|
32
|
+
"import type { Program } from 'oxc-parser';\nimport { extractRelations } from '../extractor/relation-extractor';\nimport { toAbsolutePath, toRelativePath } from '../common/path-utils';\nimport type { TsconfigPaths } from '../common/tsconfig-resolver';\n\nexport interface RelationDbRow {\n project: string;\n type: string;\n srcFilePath: string;\n srcSymbolName: string | null;\n dstFilePath: string;\n dstSymbolName: string | null;\n metaJson: string | null;\n}\n\ninterface RelationRepoPart {\n replaceFileRelations(\n project: string,\n filePath: string,\n relations: RelationDbRow[],\n ): void;\n}\n\nexport interface IndexFileRelationsOptions {\n ast: Program;\n project: string;\n filePath: string;\n relationRepo: RelationRepoPart;\n projectRoot: string;\n tsconfigPaths?: TsconfigPaths;\n}\n\nexport function indexFileRelations(opts: IndexFileRelationsOptions): number {\n const { ast, project, filePath, relationRepo, projectRoot, tsconfigPaths } = opts;\n\n const absFilePath = toAbsolutePath(projectRoot, filePath);\n const rawRelations = extractRelations(ast, absFilePath, tsconfigPaths);\n\n const rows: RelationDbRow[] = [];\n\n for (const rel of rawRelations) {\n const relDst = toRelativePath(projectRoot, rel.dstFilePath);\n\n if (relDst.startsWith('..')) continue;\n\n const relSrc = toRelativePath(projectRoot, rel.srcFilePath);\n\n rows.push({\n project,\n type: rel.type,\n srcFilePath: relSrc,\n srcSymbolName: rel.srcSymbolName ?? null,\n dstFilePath: relDst,\n dstSymbolName: rel.dstSymbolName ?? null,\n metaJson: rel.metaJson ?? null,\n });\n }\n\n relationRepo.replaceFileRelations(project, filePath, rows);\n return rows.length;\n}\n",
|
|
33
|
+
"import type { FileChangeEvent } from '../watcher/types';\nimport type { ProjectBoundary } from '../common/project-discovery';\nimport { resolveFileProject, discoverProjects } from '../common/project-discovery';\nimport { loadTsconfigPaths, clearTsconfigPathsCache } from '../common/tsconfig-resolver';\nimport type { TsconfigPaths } from '../common/tsconfig-resolver';\nimport { toAbsolutePath } from '../common/path-utils';\nimport { hashString } from '../common/hasher';\nimport { parseSource } from '../parser/parse-source';\nimport { detectChanges } from './file-indexer';\nimport { indexFileSymbols } from './symbol-indexer';\nimport { indexFileRelations } from './relation-indexer';\nimport type { DbConnection } from '../store/connection';\nimport type { FileRecord } from '../store/repositories/file.repository';\nimport type { SymbolRecord } from '../store/repositories/symbol.repository';\nimport type { RelationRecord } from '../store/repositories/relation.repository';\nimport type { Logger } from '../gildash';\n\nexport const WATCHER_DEBOUNCE_MS = 100;\n\nexport interface IndexResult {\n indexedFiles: number;\n removedFiles: number;\n totalSymbols: number;\n totalRelations: number;\n durationMs: number;\n changedFiles: string[];\n deletedFiles: string[];\n failedFiles: string[];\n}\n\nexport interface IndexCoordinatorOptions {\n projectRoot: string;\n boundaries: ProjectBoundary[];\n extensions: string[];\n ignorePatterns: string[];\n dbConnection: { transaction<T>(fn: (tx: DbConnection) => T): T };\n parseCache: {\n set(key: string, value: unknown): void;\n get(key: string): unknown;\n invalidate(key: string): void;\n };\n fileRepo: {\n getFilesMap(project: string): Map<string, FileRecord>;\n getAllFiles(project: string): FileRecord[];\n upsertFile(record: FileRecord): void;\n deleteFile(project: string, filePath: string): void;\n };\n symbolRepo: {\n replaceFileSymbols(project: string, filePath: string, contentHash: string, symbols: ReadonlyArray<Partial<SymbolRecord>>): void;\n getFileSymbols(project: string, filePath: string): SymbolRecord[];\n getByFingerprint(project: string, fingerprint: string): SymbolRecord[];\n deleteFileSymbols(project: string, filePath: string): void;\n };\n relationRepo: {\n replaceFileRelations(project: string, filePath: string, relations: ReadonlyArray<Partial<RelationRecord>>): void;\n retargetRelations(project: string, oldFile: string, oldSymbol: string | null, newFile: string, newSymbol: string | null): void;\n deleteFileRelations(project: string, filePath: string): void;\n };\n parseSourceFn?: typeof parseSource;\n discoverProjectsFn?: typeof discoverProjects;\n logger?: Logger;\n}\n\nexport class IndexCoordinator {\n private readonly opts: IndexCoordinatorOptions;\n private readonly logger: Logger;\n\n private readonly callbacks = new Set<(result: IndexResult) => void>();\n\n private indexingLock = false;\n\n private pendingEvents: FileChangeEvent[] = [];\n\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n private currentIndexing: Promise<IndexResult> | null = null;\n\n private pendingFullIndex = false;\n\n private pendingFullIndexWaiters: Array<{ resolve: (r: IndexResult) => void; reject: (e: unknown) => void }> = [];\n\n private tsconfigPathsRaw: Promise<TsconfigPaths | null>;\n\n private boundariesRefresh: Promise<void> | null = null;\n\n constructor(opts: IndexCoordinatorOptions) {\n this.opts = opts;\n this.logger = opts.logger ?? console;\n this.tsconfigPathsRaw = loadTsconfigPaths(opts.projectRoot);\n }\n\n get tsconfigPaths(): Promise<TsconfigPaths | null> {\n return this.tsconfigPathsRaw;\n }\n\n fullIndex(): Promise<IndexResult> {\n return this.startIndex(undefined, true);\n }\n\n incrementalIndex(events?: FileChangeEvent[]): Promise<IndexResult> {\n return this.startIndex(events, false);\n }\n\n onIndexed(cb: (result: IndexResult) => void): () => void {\n this.callbacks.add(cb);\n return () => this.callbacks.delete(cb);\n }\n\n handleWatcherEvent(event: FileChangeEvent): void {\n if (event.filePath.endsWith('tsconfig.json')) {\n clearTsconfigPathsCache(this.opts.projectRoot);\n this.tsconfigPathsRaw = loadTsconfigPaths(this.opts.projectRoot);\n this.fullIndex().catch((err) => {\n this.logger.error('[IndexCoordinator] fullIndex failed after tsconfig change:', err);\n });\n return;\n }\n\n if (event.filePath.endsWith('package.json')) {\n const discover = this.opts.discoverProjectsFn ?? discoverProjects;\n this.boundariesRefresh = discover(this.opts.projectRoot).then((b) => {\n this.opts.boundaries = b;\n });\n }\n\n this.pendingEvents.push(event);\n\n if (this.debounceTimer === null) {\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.flushPending();\n }, WATCHER_DEBOUNCE_MS);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.currentIndexing) {\n await this.currentIndexing;\n }\n }\n\n private startIndex(events: FileChangeEvent[] | undefined, useTransaction: boolean): Promise<IndexResult> {\n if (this.indexingLock) {\n if (useTransaction) {\n this.pendingFullIndex = true;\n return new Promise<IndexResult>((resolve, reject) => {\n this.pendingFullIndexWaiters.push({ resolve, reject });\n });\n }\n return this.currentIndexing!;\n }\n this.indexingLock = true;\n\n const work = this.doIndex(events, useTransaction)\n .then((result) => {\n this.fireCallbacks(result);\n return result;\n })\n .finally(() => {\n this.indexingLock = false;\n this.currentIndexing = null;\n if (this.pendingFullIndex) {\n this.pendingFullIndex = false;\n const waiters = this.pendingFullIndexWaiters.splice(0);\n this.startIndex(undefined, true)\n .then((result) => {\n for (const waiter of waiters) waiter.resolve(result);\n })\n .catch((error) => {\n for (const waiter of waiters) waiter.reject(error);\n });\n } else if (this.pendingEvents.length > 0) {\n const drained = this.pendingEvents.splice(0);\n this.startIndex(drained, false).catch((err) =>\n this.logger.error('[IndexCoordinator] incremental drain error', err),\n );\n }\n });\n\n this.currentIndexing = work;\n return work;\n }\n\n private async doIndex(events: FileChangeEvent[] | undefined, useTransaction: boolean): Promise<IndexResult> {\n const start = Date.now();\n const { fileRepo, symbolRepo, relationRepo, dbConnection } = this.opts;\n\n if (this.boundariesRefresh) {\n await this.boundariesRefresh;\n this.boundariesRefresh = null;\n }\n\n let changed: Array<{ filePath: string; contentHash: string; mtimeMs: number; size: number }>;\n let deleted: string[];\n\n if (events !== undefined) {\n changed = events\n .filter((e) => e.eventType === 'create' || e.eventType === 'change')\n .map((e) => ({\n filePath: e.filePath,\n contentHash: '',\n mtimeMs: 0,\n size: 0,\n }));\n deleted = events.filter((e) => e.eventType === 'delete').map((e) => e.filePath);\n } else {\n const existingMap = new Map<string, FileRecord>();\n for (const boundary of this.opts.boundaries) {\n for (const [key, val] of fileRepo.getFilesMap(boundary.project)) {\n existingMap.set(key, val);\n }\n }\n const result = await detectChanges({\n projectRoot: this.opts.projectRoot,\n extensions: this.opts.extensions,\n ignorePatterns: this.opts.ignorePatterns,\n fileRepo: { getFilesMap: () => existingMap },\n });\n changed = result.changed;\n deleted = result.deleted;\n }\n\n const tsconfigPaths = (await this.tsconfigPathsRaw) ?? undefined;\n\n const deletedSymbols = new Map<string, SymbolRecord[]>();\n for (const filePath of deleted) {\n const project = resolveFileProject(filePath, this.opts.boundaries);\n const syms = symbolRepo.getFileSymbols(project, filePath);\n deletedSymbols.set(filePath, syms);\n }\n\n const processDeleted = () => {\n for (const filePath of deleted) {\n const project = resolveFileProject(filePath, this.opts.boundaries);\n symbolRepo.deleteFileSymbols(project, filePath);\n relationRepo.deleteFileRelations(project, filePath);\n fileRepo.deleteFile(project, filePath);\n }\n };\n\n const processChanged = async (): Promise<{ symbols: number; relations: number; failedFiles: string[] }> => {\n let symbols = 0;\n let relations = 0;\n const failedFiles: string[] = [];\n for (const file of changed) {\n try {\n const r = await this.processFile(file.filePath, file.contentHash || undefined, tsconfigPaths);\n symbols += r.symbolCount;\n relations += r.relCount;\n } catch (err) {\n this.logger.error(`[IndexCoordinator] Failed to index ${file.filePath}:`, err);\n failedFiles.push(file.filePath);\n }\n }\n return { symbols, relations, failedFiles };\n };\n\n let totalSymbols = 0;\n let totalRelations = 0;\n let allFailedFiles: string[] = [];\n\n if (useTransaction) {\n const { projectRoot, boundaries } = this.opts;\n const { parseCache } = this.opts;\n const prereadResults = await Promise.allSettled(\n changed.map(async (file) => {\n const absPath = toAbsolutePath(projectRoot, file.filePath);\n const bunFile = Bun.file(absPath);\n const text = await bunFile.text();\n const contentHash = file.contentHash || hashString(text);\n return { filePath: file.filePath, text, contentHash, mtimeMs: bunFile.lastModified, size: bunFile.size };\n }),\n );\n const preread = prereadResults\n .filter((r): r is PromiseFulfilledResult<{ filePath: string; text: string; contentHash: string; mtimeMs: number; size: number }> => r.status === 'fulfilled')\n .map((r) => r.value);\n for (const r of prereadResults) {\n if (r.status === 'rejected') {\n this.logger.error('[IndexCoordinator] Failed to pre-read file:', r.reason);\n }\n }\n\n const parsedCacheEntries: Array<{ filePath: string; parsed: unknown }> = [];\n\n dbConnection.transaction(() => {\n for (const boundary of boundaries) {\n const projectFiles = fileRepo.getAllFiles(boundary.project);\n for (const f of projectFiles) {\n fileRepo.deleteFile(f.project, f.filePath);\n }\n }\n const parseFn = this.opts.parseSourceFn ?? parseSource;\n for (const fd of preread) {\n const project = resolveFileProject(fd.filePath, boundaries);\n const parsed = parseFn(toAbsolutePath(projectRoot, fd.filePath), fd.text);\n parsedCacheEntries.push({ filePath: fd.filePath, parsed });\n fileRepo.upsertFile({\n project,\n filePath: fd.filePath,\n mtimeMs: fd.mtimeMs,\n size: fd.size,\n contentHash: fd.contentHash,\n updatedAt: new Date().toISOString(),\n });\n indexFileSymbols({ parsed, project, filePath: fd.filePath, contentHash: fd.contentHash, symbolRepo });\n totalRelations += indexFileRelations({\n ast: parsed.program,\n project,\n filePath: fd.filePath,\n relationRepo,\n projectRoot,\n tsconfigPaths,\n });\n totalSymbols += symbolRepo.getFileSymbols(project, fd.filePath).length;\n }\n });\n\n for (const entry of parsedCacheEntries) {\n parseCache.set(entry.filePath, entry.parsed);\n }\n } else {\n processDeleted();\n const counts = await processChanged();\n totalSymbols = counts.symbols;\n totalRelations = counts.relations;\n allFailedFiles = counts.failedFiles;\n }\n\n if (!useTransaction) {\n for (const [oldFile, syms] of deletedSymbols) {\n for (const sym of syms) {\n if (!sym.fingerprint) continue;\n const oldProject = resolveFileProject(oldFile, this.opts.boundaries);\n const matches = symbolRepo.getByFingerprint(oldProject, sym.fingerprint);\n if (matches.length === 1) {\n const newSym = matches[0]!;\n relationRepo.retargetRelations(\n oldProject,\n oldFile,\n sym.name,\n newSym.filePath,\n newSym.name,\n );\n }\n }\n }\n }\n\n return {\n indexedFiles: changed.length,\n removedFiles: deleted.length,\n totalSymbols,\n totalRelations,\n durationMs: Date.now() - start,\n changedFiles: changed.map((f) => f.filePath),\n deletedFiles: [...deleted],\n failedFiles: allFailedFiles,\n };\n }\n\n private async processFile(\n filePath: string,\n knownHash: string | undefined,\n tsconfigPaths: TsconfigPaths | undefined,\n ): Promise<{ symbolCount: number; relCount: number }> {\n const { projectRoot, boundaries } = this.opts;\n const { fileRepo, symbolRepo, relationRepo, parseCache } = this.opts;\n\n const absPath = toAbsolutePath(projectRoot, filePath);\n const bunFile = Bun.file(absPath);\n const text = await bunFile.text();\n const contentHash = knownHash || hashString(text);\n\n const project = resolveFileProject(filePath, boundaries);\n\n const parseFn = this.opts.parseSourceFn ?? parseSource;\n const parsed = parseFn(absPath, text);\n parseCache.set(filePath, parsed);\n\n fileRepo.upsertFile({\n project,\n filePath,\n mtimeMs: bunFile.lastModified,\n size: bunFile.size,\n contentHash,\n updatedAt: new Date().toISOString(),\n });\n\n indexFileSymbols({ parsed, project, filePath, contentHash, symbolRepo });\n\n const relCount = indexFileRelations({\n ast: parsed.program,\n project,\n filePath,\n relationRepo,\n projectRoot,\n tsconfigPaths,\n });\n\n const symbolCount = symbolRepo.getFileSymbols(project, filePath).length;\n return { symbolCount, relCount };\n }\n\n private fireCallbacks(result: IndexResult): void {\n for (const cb of this.callbacks) {\n try {\n cb(result);\n } catch (err) {\n this.logger.error('[IndexCoordinator] onIndexed callback threw:', err);\n }\n }\n }\n\n private flushPending(): void {\n if (this.indexingLock) {\n return;\n }\n if (this.pendingEvents.length > 0) {\n const events = this.pendingEvents.splice(0);\n this.startIndex(events, false).catch((err) =>\n this.logger.error('[IndexCoordinator] flushPending startIndex error:', err),\n );\n }\n }\n}\n",
|
|
34
|
+
"import type { WatcherRole } from \"./types\";\n\ninterface WatcherOwnerRow {\n pid: number;\n heartbeat_at: string;\n}\n\nexport interface WatcherOwnerStore {\n immediateTransaction<T>(fn: () => T): T;\n selectOwner(): WatcherOwnerRow | undefined;\n insertOwner(pid: number): void;\n replaceOwner(pid: number): void;\n touchOwner(pid: number): void;\n deleteOwner(pid: number): void;\n}\n\ninterface AcquireOptions {\n now?: () => number;\n isAlive?: (pid: number) => boolean;\n staleAfterSeconds?: number;\n}\n\nfunction defaultIsAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (typeof error === \"object\" && error && \"code\" in error) {\n return (error as { code?: string }).code !== \"ESRCH\";\n }\n\n return true;\n }\n}\n\nfunction toEpochMs(value: string): number {\n const ms = new Date(value).getTime();\n return Number.isNaN(ms) ? 0 : ms;\n}\n\nexport function acquireWatcherRole(\n db: WatcherOwnerStore,\n pid: number,\n options: AcquireOptions = {},\n): WatcherRole {\n const now = options.now ?? Date.now;\n const isAlive = options.isAlive ?? defaultIsAlive;\n const staleAfterSeconds = options.staleAfterSeconds ?? 90;\n\n return db.immediateTransaction(() => {\n const owner = db.selectOwner();\n if (!owner) {\n db.insertOwner(pid);\n return \"owner\";\n }\n\n const heartbeatAgeSeconds = Math.floor((now() - toEpochMs(owner.heartbeat_at)) / 1000);\n if (isAlive(owner.pid) && heartbeatAgeSeconds < staleAfterSeconds) {\n return \"reader\";\n }\n\n db.replaceOwner(pid);\n return \"owner\";\n });\n}\n\nexport function releaseWatcherRole(db: WatcherOwnerStore, pid: number): void {\n db.deleteOwner(pid);\n}\n\nexport function updateHeartbeat(db: WatcherOwnerStore, pid: number): void {\n db.touchOwner(pid);\n}\n",
|
|
35
|
+
"import type { SymbolKind } from '../extractor/types';\nimport type { SymbolRecord } from '../store/repositories/symbol.repository';\nimport { toFtsPrefixQuery } from '../store/repositories/fts-utils';\n\n/**\n * Filters for {@link symbolSearch}.\n *\n * All fields are optional. Omitted fields impose no constraint.\n */\nexport interface SymbolSearchQuery {\n /** Full-text search on symbol names (prefix matching). */\n text?: string;\n /** Restrict to a specific {@link SymbolKind}. */\n kind?: SymbolKind;\n /** Restrict to symbols declared in this file path. */\n filePath?: string;\n /** `true` for exported symbols only, `false` for non-exported only. */\n isExported?: boolean;\n /** Limit results to this project. Defaults to the primary project. */\n project?: string;\n /** Maximum number of results. Defaults to `100`. */\n limit?: number;\n}\n\n/**\n * A single result returned by {@link symbolSearch}.\n */\nexport interface SymbolSearchResult {\n /** Database row id. */\n id: number;\n /** Absolute file path containing the symbol. */\n filePath: string;\n /** Kind of the symbol (function, class, variable, etc.). */\n kind: SymbolKind;\n /** Symbol name. */\n name: string;\n /** Source location span (start/end line and column). */\n span: { start: { line: number; column: number }; end: { line: number; column: number } };\n /** Whether the symbol is exported from its module. */\n isExported: boolean;\n /** Human-readable signature text, if available. */\n signature: string | null;\n /** Content-hash fingerprint for change detection. */\n fingerprint: string | null;\n /** Arbitrary detail fields stored as JSON. */\n detail: Record<string, unknown>;\n}\n\nexport interface ISymbolRepo {\n searchByQuery(opts: {\n ftsQuery?: string;\n kind?: string;\n filePath?: string;\n isExported?: boolean;\n project?: string;\n limit: number;\n }): (SymbolRecord & { id: number })[];\n}\n\n/**\n * Search the symbol index using the given query filters.\n *\n * @param options - Symbol repository, default project, and search query.\n * @returns An array of {@link SymbolSearchResult} entries matching the query.\n */\nexport function symbolSearch(options: {\n symbolRepo: ISymbolRepo;\n project?: string;\n query: SymbolSearchQuery;\n}): SymbolSearchResult[] {\n const { symbolRepo, project, query } = options;\n const effectiveProject = query.project ?? project;\n const limit = query.limit ?? 100;\n\n const opts: Parameters<ISymbolRepo['searchByQuery']>[0] = {\n kind: query.kind,\n filePath: query.filePath,\n isExported: query.isExported,\n project: effectiveProject,\n limit,\n };\n\n if (query.text) {\n const ftsQuery = toFtsPrefixQuery(query.text);\n if (ftsQuery) opts.ftsQuery = ftsQuery;\n }\n\n const records = symbolRepo.searchByQuery(opts);\n\n return records.map(r => ({\n id: r.id,\n filePath: r.filePath,\n kind: r.kind as SymbolKind,\n name: r.name,\n span: {\n start: { line: r.startLine, column: r.startColumn },\n end: { line: r.endLine, column: r.endColumn },\n },\n isExported: r.isExported === 1,\n signature: r.signature,\n fingerprint: r.fingerprint,\n detail: r.detailJson ? (() => {\n try { return JSON.parse(r.detailJson!) as Record<string, unknown>; }\n catch { return {}; }\n })() : {},\n }));\n}\n",
|
|
36
|
+
"import type { CodeRelation } from '../extractor/types';\nimport type { RelationRecord } from '../store/repositories/relation.repository';\n\n/**\n * Filters for {@link relationSearch}.\n *\n * All fields are optional. Omitted fields impose no constraint.\n */\nexport interface RelationSearchQuery {\n /** Source file path. */\n srcFilePath?: string;\n /** Source symbol name. */\n srcSymbolName?: string;\n /** Destination file path. */\n dstFilePath?: string;\n /** Destination symbol name. */\n dstSymbolName?: string;\n /** Relationship type: `'imports'`, `'calls'`, `'extends'`, or `'implements'`. */\n type?: CodeRelation['type'];\n /** Limit results to this project. */\n project?: string;\n /** Maximum number of results. Defaults to `500`. */\n limit?: number;\n}\n\nexport interface IRelationRepo {\n searchRelations(opts: {\n srcFilePath?: string;\n srcSymbolName?: string;\n dstFilePath?: string;\n dstSymbolName?: string;\n type?: string;\n project?: string;\n limit: number;\n }): RelationRecord[];\n}\n\n/**\n * Search the relation index using the given query filters.\n *\n * @param options - Relation repository, default project, and search query.\n * @returns An array of {@link CodeRelation} entries matching the query.\n */\nexport function relationSearch(options: {\n relationRepo: IRelationRepo;\n project?: string;\n query: RelationSearchQuery;\n}): CodeRelation[] {\n const { relationRepo, project, query } = options;\n const effectiveProject = query.project ?? project;\n const limit = query.limit ?? 500;\n\n const records = relationRepo.searchRelations({\n srcFilePath: query.srcFilePath,\n srcSymbolName: query.srcSymbolName,\n dstFilePath: query.dstFilePath,\n dstSymbolName: query.dstSymbolName,\n type: query.type,\n project: effectiveProject,\n limit,\n });\n\n return records.map(r => ({\n type: r.type as CodeRelation['type'],\n srcFilePath: r.srcFilePath,\n srcSymbolName: r.srcSymbolName,\n dstFilePath: r.dstFilePath,\n dstSymbolName: r.dstSymbolName,\n metaJson: r.metaJson ?? undefined,\n }));\n}\n",
|
|
37
|
+
"import type { RelationRecord } from '../store/repositories/relation.repository';\n\nexport interface IDependencyGraphRepo {\n getByType(project: string, type: string): RelationRecord[];\n}\n\n/**\n * Directed import graph for dependency analysis.\n *\n * Build the graph once with {@link DependencyGraph.build}, then query\n * dependencies, dependents, cycles, and change-impact.\n *\n * @example\n * ```ts\n * const graph = new DependencyGraph({ relationRepo, project: 'my-app' });\n * graph.build();\n * graph.getDependencies('/src/a.ts'); // files that a.ts imports\n * graph.getDependents('/src/a.ts'); // files that import a.ts\n * graph.hasCycle(); // true if a circular import exists\n * ```\n */\nexport class DependencyGraph {\n private adjacencyList = new Map<string, Set<string>>();\n private reverseAdjacencyList = new Map<string, Set<string>>();\n\n constructor(\n private readonly options: {\n relationRepo: IDependencyGraphRepo;\n project: string;\n },\n ) {}\n\n /**\n * Populate the graph by reading all `imports` relations from the store.\n *\n * Must be called before any query method.\n */\n build(): void {\n this.adjacencyList = new Map();\n this.reverseAdjacencyList = new Map();\n\n const relations = this.options.relationRepo.getByType(\n this.options.project,\n 'imports',\n );\n\n for (const rel of relations) {\n const { srcFilePath, dstFilePath } = rel;\n\n if (!this.adjacencyList.has(srcFilePath)) {\n this.adjacencyList.set(srcFilePath, new Set());\n }\n this.adjacencyList.get(srcFilePath)!.add(dstFilePath);\n\n if (!this.reverseAdjacencyList.has(dstFilePath)) {\n this.reverseAdjacencyList.set(dstFilePath, new Set());\n }\n this.reverseAdjacencyList.get(dstFilePath)!.add(srcFilePath);\n }\n }\n\n /**\n * Return the files that `filePath` directly imports.\n *\n * @param filePath - Absolute file path.\n */\n getDependencies(filePath: string): string[] {\n return Array.from(this.adjacencyList.get(filePath) ?? []);\n }\n\n /**\n * Return the files that directly import `filePath`.\n *\n * @param filePath - Absolute file path.\n */\n getDependents(filePath: string): string[] {\n return Array.from(this.reverseAdjacencyList.get(filePath) ?? []);\n }\n\n /**\n * Return all files that transitively depend on `filePath`\n * (breadth-first reverse walk).\n *\n * @param filePath - Absolute file path.\n */\n getTransitiveDependents(filePath: string): string[] {\n const visited = new Set<string>();\n const queue: string[] = [filePath];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const dependent of this.reverseAdjacencyList.get(current) ?? []) {\n if (!visited.has(dependent)) {\n visited.add(dependent);\n queue.push(dependent);\n }\n }\n }\n\n return Array.from(visited);\n }\n\n /**\n * Detect whether the import graph contains at least one cycle.\n *\n * Uses iterative DFS with a path-tracking set.\n *\n * @returns `true` if a circular dependency exists.\n */\n hasCycle(): boolean {\n const visited = new Set<string>();\n const inPath = new Set<string>();\n\n for (const startNode of this.adjacencyList.keys()) {\n if (visited.has(startNode)) continue;\n\n const stack: Array<{ node: string; entered: boolean }> = [{ node: startNode, entered: false }];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n\n if (current.entered) {\n inPath.delete(current.node);\n continue;\n }\n\n if (inPath.has(current.node)) {\n return true;\n }\n\n if (visited.has(current.node)) {\n continue;\n }\n\n visited.add(current.node);\n inPath.add(current.node);\n stack.push({ node: current.node, entered: true });\n\n for (const neighbor of this.adjacencyList.get(current.node) ?? []) {\n if (inPath.has(neighbor)) {\n return true;\n }\n if (!visited.has(neighbor)) {\n stack.push({ node: neighbor, entered: false });\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Compute all files transitively affected by a set of changed files.\n *\n * Combines {@link getTransitiveDependents} for every changed file\n * and de-duplicates the result.\n *\n * @param changedFiles - Absolute paths of files that changed.\n * @returns Paths of all transitively-dependent files.\n */\n getAffectedByChange(changedFiles: string[]): string[] {\n const allAffected = new Set<string>();\n\n for (const file of changedFiles) {\n for (const dep of this.getTransitiveDependents(file)) {\n allAffected.add(dep);\n }\n }\n\n return Array.from(allAffected);\n }\n}\n"
|
|
38
|
+
],
|
|
39
|
+
"mappings": "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",
|
|
40
|
+
"debugId": "C2664325F1F8637F64756E2164756E21",
|
|
41
|
+
"names": []
|
|
42
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
CREATE TABLE `files` (
|
|
2
|
+
`project` text NOT NULL,
|
|
3
|
+
`file_path` text NOT NULL,
|
|
4
|
+
`mtime_ms` real NOT NULL,
|
|
5
|
+
`size` integer NOT NULL,
|
|
6
|
+
`content_hash` text NOT NULL,
|
|
7
|
+
`updated_at` text NOT NULL,
|
|
8
|
+
PRIMARY KEY(`project`, `file_path`)
|
|
9
|
+
);
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
CREATE TABLE `relations` (
|
|
12
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
13
|
+
`project` text NOT NULL,
|
|
14
|
+
`type` text NOT NULL,
|
|
15
|
+
`src_file_path` text NOT NULL,
|
|
16
|
+
`src_symbol_name` text,
|
|
17
|
+
`dst_file_path` text NOT NULL,
|
|
18
|
+
`dst_symbol_name` text,
|
|
19
|
+
`meta_json` text,
|
|
20
|
+
FOREIGN KEY (`project`,`src_file_path`) REFERENCES `files`(`project`,`file_path`) ON UPDATE no action ON DELETE cascade,
|
|
21
|
+
FOREIGN KEY (`project`,`dst_file_path`) REFERENCES `files`(`project`,`file_path`) ON UPDATE no action ON DELETE cascade
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
CREATE INDEX `idx_relations_src` ON `relations` (`project`,`src_file_path`);--> statement-breakpoint
|
|
25
|
+
CREATE INDEX `idx_relations_dst` ON `relations` (`project`,`dst_file_path`);--> statement-breakpoint
|
|
26
|
+
CREATE INDEX `idx_relations_type` ON `relations` (`project`,`type`);--> statement-breakpoint
|
|
27
|
+
CREATE TABLE `symbols` (
|
|
28
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
29
|
+
`project` text NOT NULL,
|
|
30
|
+
`file_path` text NOT NULL,
|
|
31
|
+
`kind` text NOT NULL,
|
|
32
|
+
`name` text NOT NULL,
|
|
33
|
+
`start_line` integer NOT NULL,
|
|
34
|
+
`start_column` integer NOT NULL,
|
|
35
|
+
`end_line` integer NOT NULL,
|
|
36
|
+
`end_column` integer NOT NULL,
|
|
37
|
+
`is_exported` integer DEFAULT 0 NOT NULL,
|
|
38
|
+
`signature` text,
|
|
39
|
+
`fingerprint` text,
|
|
40
|
+
`detail_json` text,
|
|
41
|
+
`content_hash` text NOT NULL,
|
|
42
|
+
`indexed_at` text NOT NULL,
|
|
43
|
+
FOREIGN KEY (`project`,`file_path`) REFERENCES `files`(`project`,`file_path`) ON UPDATE no action ON DELETE cascade
|
|
44
|
+
);
|
|
45
|
+
--> statement-breakpoint
|
|
46
|
+
CREATE INDEX `idx_symbols_project_file` ON `symbols` (`project`,`file_path`);--> statement-breakpoint
|
|
47
|
+
CREATE INDEX `idx_symbols_project_kind` ON `symbols` (`project`,`kind`);--> statement-breakpoint
|
|
48
|
+
CREATE INDEX `idx_symbols_project_name` ON `symbols` (`project`,`name`);--> statement-breakpoint
|
|
49
|
+
CREATE INDEX `idx_symbols_fingerprint` ON `symbols` (`project`,`fingerprint`);--> statement-breakpoint
|
|
50
|
+
CREATE TABLE `watcher_owner` (
|
|
51
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
52
|
+
`pid` integer NOT NULL,
|
|
53
|
+
`started_at` text NOT NULL,
|
|
54
|
+
`heartbeat_at` text NOT NULL,
|
|
55
|
+
CONSTRAINT "watcher_owner_singleton" CHECK("watcher_owner"."id" = 1)
|
|
56
|
+
);
|