@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
package/README.md
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
# @zipbul/gildash
|
|
2
|
+
|
|
3
|
+
**English** | [한국어](./README.ko.md)
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@zipbul/gildash)
|
|
6
|
+
[](https://github.com/zipbul/gildash/actions/workflows/ci.yml)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
|
|
9
|
+
A **Bun-native** TypeScript code indexer. Extracts symbols, tracks cross-file relationships, and builds a full dependency graph — all stored in a local SQLite database.
|
|
10
|
+
|
|
11
|
+
<br>
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Symbol extraction** — Functions, classes, variables, types, interfaces, enums, and properties extracted via [oxc-parser](https://oxc.rs) AST
|
|
16
|
+
- **Relation tracking** — `import`, `calls`, `extends`, `implements` relationships across files
|
|
17
|
+
- **Full-text search** — SQLite FTS5-powered symbol name search
|
|
18
|
+
- **Dependency graph** — Directed import graph with cycle detection and transitive impact analysis
|
|
19
|
+
- **Incremental indexing** — `@parcel/watcher`-based file change detection; only re-indexes modified files
|
|
20
|
+
- **Multi-process safe** — Owner/reader role separation guarantees a single writer per database
|
|
21
|
+
|
|
22
|
+
<br>
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
- **Bun** v1.3 or higher
|
|
27
|
+
- TypeScript source files: `.ts`, `.mts`, `.cts`
|
|
28
|
+
|
|
29
|
+
<br>
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add @zipbul/gildash
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
<br>
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { Gildash } from '@zipbul/gildash';
|
|
43
|
+
|
|
44
|
+
const ledger = await Gildash.open({
|
|
45
|
+
projectRoot: '/absolute/path/to/project',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Search for exported classes by name
|
|
49
|
+
const hits = ledger.searchSymbols({
|
|
50
|
+
text: 'UserService',
|
|
51
|
+
kind: 'class',
|
|
52
|
+
isExported: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Find what a file imports
|
|
56
|
+
const deps = ledger.getDependencies('src/app.ts');
|
|
57
|
+
|
|
58
|
+
// Find everything affected by a change
|
|
59
|
+
const affected = await ledger.getAffected(['src/utils.ts']);
|
|
60
|
+
|
|
61
|
+
// Detect circular dependencies
|
|
62
|
+
if (await ledger.hasCycle()) {
|
|
63
|
+
console.warn('Circular dependency detected');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Subscribe to index-complete events
|
|
67
|
+
const unsubscribe = ledger.onIndexed((result) => {
|
|
68
|
+
console.log(`Indexed ${result.indexedFiles} files in ${result.durationMs}ms`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await ledger.close();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Error handling
|
|
75
|
+
|
|
76
|
+
All errors extend `GildashError`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { Gildash, GildashError, ParseError } from '@zipbul/gildash';
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const ledger = await Gildash.open({ projectRoot: '/path' });
|
|
83
|
+
} catch (err) {
|
|
84
|
+
if (err instanceof ParseError) {
|
|
85
|
+
// AST parsing failure
|
|
86
|
+
} else if (err instanceof GildashError) {
|
|
87
|
+
// Any gildash error
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<br>
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
### `Gildash.open(options)`
|
|
97
|
+
|
|
98
|
+
Creates and returns a `Gildash` instance. Performs a full index on first run, then watches for file changes.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const ledger = await Gildash.open({
|
|
102
|
+
projectRoot: '/absolute/path',
|
|
103
|
+
extensions: ['.ts', '.mts', '.cts'],
|
|
104
|
+
ignorePatterns: ['dist', 'vendor'],
|
|
105
|
+
parseCacheCapacity: 500,
|
|
106
|
+
logger: console,
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### options
|
|
111
|
+
|
|
112
|
+
| Option | Type | Default | Description |
|
|
113
|
+
|--------|------|---------|-------------|
|
|
114
|
+
| `projectRoot` | `string` | — | Absolute path to project root **(required)** |
|
|
115
|
+
| `extensions` | `string[]` | `['.ts', '.mts', '.cts']` | File extensions to index |
|
|
116
|
+
| `ignorePatterns` | `string[]` | `[]` | Glob patterns to exclude |
|
|
117
|
+
| `parseCacheCapacity` | `number` | `500` | LRU parse-cache capacity |
|
|
118
|
+
| `logger` | `Logger` | `console` | Custom logger (`{ error(...args): void }`) |
|
|
119
|
+
|
|
120
|
+
Returns `Promise<Gildash>`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### `ledger.searchSymbols(query)`
|
|
125
|
+
|
|
126
|
+
Search symbols by name (FTS5 full-text), kind, file path, and/or export status.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
// Full-text search
|
|
130
|
+
const results = ledger.searchSymbols({ text: 'handleClick' });
|
|
131
|
+
|
|
132
|
+
// Filter by kind + export status
|
|
133
|
+
const classes = ledger.searchSymbols({
|
|
134
|
+
kind: 'class',
|
|
135
|
+
isExported: true,
|
|
136
|
+
limit: 50,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Scope to a specific file
|
|
140
|
+
const inFile = ledger.searchSymbols({
|
|
141
|
+
filePath: 'src/services/user.ts',
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### SymbolSearchQuery
|
|
146
|
+
|
|
147
|
+
| Field | Type | Description |
|
|
148
|
+
|-------|------|-------------|
|
|
149
|
+
| `text` | `string?` | FTS5 full-text search query |
|
|
150
|
+
| `kind` | `SymbolKind?` | `'function'` \| `'method'` \| `'class'` \| `'variable'` \| `'type'` \| `'interface'` \| `'enum'` \| `'property'` |
|
|
151
|
+
| `filePath` | `string?` | Filter by file path |
|
|
152
|
+
| `isExported` | `boolean?` | Filter by export status |
|
|
153
|
+
| `project` | `string?` | Project name (monorepo) |
|
|
154
|
+
| `limit` | `number?` | Max results (default: `100`) |
|
|
155
|
+
|
|
156
|
+
Returns `SymbolSearchResult[]`
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
interface SymbolSearchResult {
|
|
160
|
+
id: number;
|
|
161
|
+
filePath: string;
|
|
162
|
+
kind: SymbolKind;
|
|
163
|
+
name: string;
|
|
164
|
+
span: {
|
|
165
|
+
start: { line: number; column: number };
|
|
166
|
+
end: { line: number; column: number };
|
|
167
|
+
};
|
|
168
|
+
isExported: boolean;
|
|
169
|
+
signature: string | null;
|
|
170
|
+
fingerprint: string | null;
|
|
171
|
+
detail: Record<string, unknown>;
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### `ledger.searchRelations(query)`
|
|
178
|
+
|
|
179
|
+
Search cross-file relationships by source/destination file, symbol name, or relation type.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// All imports from a file
|
|
183
|
+
const imports = ledger.searchRelations({
|
|
184
|
+
srcFilePath: 'src/app.ts',
|
|
185
|
+
type: 'imports',
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Find callers of a specific function
|
|
189
|
+
const callers = ledger.searchRelations({
|
|
190
|
+
dstSymbolName: 'processOrder',
|
|
191
|
+
type: 'calls',
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### RelationSearchQuery
|
|
196
|
+
|
|
197
|
+
| Field | Type | Description |
|
|
198
|
+
|-------|------|-------------|
|
|
199
|
+
| `srcFilePath` | `string?` | Source file path |
|
|
200
|
+
| `srcSymbolName` | `string?` | Source symbol name |
|
|
201
|
+
| `dstFilePath` | `string?` | Destination file path |
|
|
202
|
+
| `dstSymbolName` | `string?` | Destination symbol name |
|
|
203
|
+
| `type` | `'imports'` \| `'calls'` \| `'extends'` \| `'implements'`? | Relation type |
|
|
204
|
+
| `project` | `string?` | Project name |
|
|
205
|
+
| `limit` | `number?` | Max results (default: `500`) |
|
|
206
|
+
|
|
207
|
+
Returns `CodeRelation[]`
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
interface CodeRelation {
|
|
211
|
+
type: 'imports' | 'calls' | 'extends' | 'implements';
|
|
212
|
+
srcFilePath: string;
|
|
213
|
+
srcSymbolName: string | null; // null = module-level
|
|
214
|
+
dstFilePath: string;
|
|
215
|
+
dstSymbolName: string | null;
|
|
216
|
+
metaJson?: string;
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### `ledger.getDependencies(filePath, project?)`
|
|
223
|
+
|
|
224
|
+
Returns files that the given file imports.
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
const deps = ledger.getDependencies('src/app.ts');
|
|
228
|
+
// → ['src/utils.ts', 'src/config.ts', ...]
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Returns `string[]`
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### `ledger.getDependents(filePath, project?)`
|
|
236
|
+
|
|
237
|
+
Returns files that import the given file.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
const dependents = ledger.getDependents('src/utils.ts');
|
|
241
|
+
// → ['src/app.ts', 'src/services/user.ts', ...]
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Returns `string[]`
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### `ledger.getAffected(changedFiles, project?)`
|
|
249
|
+
|
|
250
|
+
Computes the full transitive set of files affected by file changes.
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
const affected = await ledger.getAffected(['src/utils.ts']);
|
|
254
|
+
// → ['src/app.ts', 'src/services/user.ts', 'src/main.ts', ...]
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Returns `Promise<string[]>`
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### `ledger.hasCycle(project?)`
|
|
262
|
+
|
|
263
|
+
Detects circular dependencies in the import graph.
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
if (await ledger.hasCycle()) {
|
|
267
|
+
console.warn('Circular dependency detected');
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Returns `Promise<boolean>`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### `ledger.reindex()`
|
|
276
|
+
|
|
277
|
+
Forces a full re-index. Only available when the instance holds the owner role.
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
const result = await ledger.reindex();
|
|
281
|
+
console.log(`Indexed ${result.indexedFiles} files in ${result.durationMs}ms`);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Returns `Promise<IndexResult>`
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
interface IndexResult {
|
|
288
|
+
indexedFiles: number;
|
|
289
|
+
removedFiles: number;
|
|
290
|
+
totalSymbols: number;
|
|
291
|
+
totalRelations: number;
|
|
292
|
+
durationMs: number;
|
|
293
|
+
changedFiles: string[];
|
|
294
|
+
deletedFiles: string[];
|
|
295
|
+
failedFiles: string[];
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### `ledger.onIndexed(callback)`
|
|
302
|
+
|
|
303
|
+
Subscribes to index-complete events. Returns an unsubscribe function.
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
const unsubscribe = ledger.onIndexed((result) => {
|
|
307
|
+
console.log(`Indexed ${result.indexedFiles} files`);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Later
|
|
311
|
+
unsubscribe();
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Returns `() => void`
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
### `ledger.projects`
|
|
319
|
+
|
|
320
|
+
Detected project boundaries. In a monorepo, multiple projects are discovered automatically from `package.json` files.
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
const boundaries = ledger.projects;
|
|
324
|
+
// → [{ dir: '.', project: 'my-app' }, { dir: 'packages/core', project: '@my/core' }]
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Type: `ProjectBoundary[]`
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
interface ProjectBoundary {
|
|
331
|
+
dir: string;
|
|
332
|
+
project: string;
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
### `ledger.getStats(project?)`
|
|
339
|
+
|
|
340
|
+
Returns symbol count statistics.
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
const stats = ledger.getStats();
|
|
344
|
+
// → { symbolCount: 1234, fileCount: 56 }
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Returns `SymbolStats`
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
interface SymbolStats {
|
|
351
|
+
symbolCount: number;
|
|
352
|
+
fileCount: number;
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
### `ledger.parseSource(filePath, sourceText)`
|
|
359
|
+
|
|
360
|
+
Parses a TypeScript file and caches the AST internally.
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
const parsed = ledger.parseSource('src/foo.ts', sourceCode);
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Returns `ParsedFile`
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### `ledger.extractSymbols(parsed)`
|
|
371
|
+
|
|
372
|
+
Extracts symbols from a parsed file.
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
const symbols = ledger.extractSymbols(parsed);
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Returns `ExtractedSymbol[]`
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### `ledger.extractRelations(parsed)`
|
|
383
|
+
|
|
384
|
+
Extracts cross-file relations from a parsed file.
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
const relations = ledger.extractRelations(parsed);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Returns `CodeRelation[]`
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
### `ledger.close()`
|
|
395
|
+
|
|
396
|
+
Graceful shutdown. Stops the watcher, releases the database, and removes signal handlers.
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
await ledger.close();
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Returns `Promise<void>`
|
|
403
|
+
|
|
404
|
+
<br>
|
|
405
|
+
|
|
406
|
+
## Errors
|
|
407
|
+
|
|
408
|
+
All errors extend `GildashError`, which extends `Error`.
|
|
409
|
+
|
|
410
|
+
| Class | When |
|
|
411
|
+
|-------|------|
|
|
412
|
+
| `GildashError` | Base class for all errors |
|
|
413
|
+
| `WatcherError` | File watcher start/stop failure |
|
|
414
|
+
| `ParseError` | AST parsing failure |
|
|
415
|
+
| `ExtractError` | Symbol/relation extraction failure |
|
|
416
|
+
| `IndexError` | Indexing pipeline failure |
|
|
417
|
+
| `StoreError` | Database operation failure |
|
|
418
|
+
| `SearchError` | Search query failure |
|
|
419
|
+
|
|
420
|
+
<br>
|
|
421
|
+
|
|
422
|
+
## Architecture
|
|
423
|
+
|
|
424
|
+
```
|
|
425
|
+
Gildash (Facade)
|
|
426
|
+
├── Parser — oxc-parser-based TypeScript AST parser
|
|
427
|
+
├── Extractor — Symbol & relation extraction (imports, calls, heritage)
|
|
428
|
+
├── Store — bun:sqlite + drizzle-orm (files, symbols, relations, FTS5)
|
|
429
|
+
├── Indexer — Change detection → parse → extract → store pipeline
|
|
430
|
+
├── Search — Symbol search, relation search, dependency graph
|
|
431
|
+
└── Watcher — @parcel/watcher + owner/reader role management
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Owner / Reader Pattern
|
|
435
|
+
|
|
436
|
+
When multiple processes share the same SQLite database, a single-writer guarantee is enforced.
|
|
437
|
+
|
|
438
|
+
- **Owner** — Runs the file watcher, performs indexing, sends a heartbeat every 30 s
|
|
439
|
+
- **Reader** — Read-only access; polls owner status every 60 s and self-promotes if the owner goes stale
|
|
440
|
+
|
|
441
|
+
<br>
|
|
442
|
+
|
|
443
|
+
## License
|
|
444
|
+
|
|
445
|
+
[MIT](./LICENSE) © [zipbul](https://github.com/zipbul)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|