@szabadkai/graphite 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +427 -0
  2. package/dist/cli/formatters.d.ts +3 -0
  3. package/dist/cli/formatters.js +61 -0
  4. package/dist/cli/formatters.js.map +1 -0
  5. package/dist/cli/index.d.ts +2 -0
  6. package/dist/cli/index.js +186 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/index.d.ts +6 -0
  9. package/dist/index.js +23 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/indexer/call-resolver.d.ts +8 -0
  12. package/dist/indexer/call-resolver.js +161 -0
  13. package/dist/indexer/call-resolver.js.map +1 -0
  14. package/dist/indexer/extractors/calls.d.ts +17 -0
  15. package/dist/indexer/extractors/calls.js +206 -0
  16. package/dist/indexer/extractors/calls.js.map +1 -0
  17. package/dist/indexer/extractors/classes.d.ts +35 -0
  18. package/dist/indexer/extractors/classes.js +209 -0
  19. package/dist/indexer/extractors/classes.js.map +1 -0
  20. package/dist/indexer/extractors/exports.d.ts +12 -0
  21. package/dist/indexer/extractors/exports.js +267 -0
  22. package/dist/indexer/extractors/exports.js.map +1 -0
  23. package/dist/indexer/extractors/functions.d.ts +12 -0
  24. package/dist/indexer/extractors/functions.js +169 -0
  25. package/dist/indexer/extractors/functions.js.map +1 -0
  26. package/dist/indexer/extractors/imports.d.ts +12 -0
  27. package/dist/indexer/extractors/imports.js +195 -0
  28. package/dist/indexer/extractors/imports.js.map +1 -0
  29. package/dist/indexer/extractors/index.d.ts +7 -0
  30. package/dist/indexer/extractors/index.js +24 -0
  31. package/dist/indexer/extractors/index.js.map +1 -0
  32. package/dist/indexer/extractors/types.d.ts +12 -0
  33. package/dist/indexer/extractors/types.js +138 -0
  34. package/dist/indexer/extractors/types.js.map +1 -0
  35. package/dist/indexer/extractors/variables.d.ts +10 -0
  36. package/dist/indexer/extractors/variables.js +134 -0
  37. package/dist/indexer/extractors/variables.js.map +1 -0
  38. package/dist/indexer/file-discovery.d.ts +7 -0
  39. package/dist/indexer/file-discovery.js +92 -0
  40. package/dist/indexer/file-discovery.js.map +1 -0
  41. package/dist/indexer/file-indexer.d.ts +2 -0
  42. package/dist/indexer/file-indexer.js +267 -0
  43. package/dist/indexer/file-indexer.js.map +1 -0
  44. package/dist/indexer/graph-contract.d.ts +25 -0
  45. package/dist/indexer/graph-contract.js +7 -0
  46. package/dist/indexer/graph-contract.js.map +1 -0
  47. package/dist/indexer/hasher.d.ts +1 -0
  48. package/dist/indexer/hasher.js +11 -0
  49. package/dist/indexer/hasher.js.map +1 -0
  50. package/dist/indexer/import-resolver.d.ts +11 -0
  51. package/dist/indexer/import-resolver.js +131 -0
  52. package/dist/indexer/import-resolver.js.map +1 -0
  53. package/dist/indexer/index.d.ts +11 -0
  54. package/dist/indexer/index.js +28 -0
  55. package/dist/indexer/index.js.map +1 -0
  56. package/dist/indexer/inheritance-resolver.d.ts +7 -0
  57. package/dist/indexer/inheritance-resolver.js +119 -0
  58. package/dist/indexer/inheritance-resolver.js.map +1 -0
  59. package/dist/indexer/parser.d.ts +5 -0
  60. package/dist/indexer/parser.js +48 -0
  61. package/dist/indexer/parser.js.map +1 -0
  62. package/dist/indexer/path-utils.d.ts +3 -0
  63. package/dist/indexer/path-utils.js +20 -0
  64. package/dist/indexer/path-utils.js.map +1 -0
  65. package/dist/indexer/project-indexer.d.ts +14 -0
  66. package/dist/indexer/project-indexer.js +167 -0
  67. package/dist/indexer/project-indexer.js.map +1 -0
  68. package/dist/indexer/property-parsers.d.ts +20 -0
  69. package/dist/indexer/property-parsers.js +81 -0
  70. package/dist/indexer/property-parsers.js.map +1 -0
  71. package/dist/mcp/index.d.ts +3 -0
  72. package/dist/mcp/index.js +20 -0
  73. package/dist/mcp/index.js.map +1 -0
  74. package/dist/mcp/response-formatter.d.ts +10 -0
  75. package/dist/mcp/response-formatter.js +47 -0
  76. package/dist/mcp/response-formatter.js.map +1 -0
  77. package/dist/mcp/server.d.ts +10 -0
  78. package/dist/mcp/server.js +118 -0
  79. package/dist/mcp/server.js.map +1 -0
  80. package/dist/mcp/tools-list.d.ts +9 -0
  81. package/dist/mcp/tools-list.js +12 -0
  82. package/dist/mcp/tools-list.js.map +1 -0
  83. package/dist/mcp/tools.d.ts +13 -0
  84. package/dist/mcp/tools.js +163 -0
  85. package/dist/mcp/tools.js.map +1 -0
  86. package/dist/query/analyze-impact.d.ts +18 -0
  87. package/dist/query/analyze-impact.js +58 -0
  88. package/dist/query/analyze-impact.js.map +1 -0
  89. package/dist/query/find-callees.d.ts +12 -0
  90. package/dist/query/find-callees.js +46 -0
  91. package/dist/query/find-callees.js.map +1 -0
  92. package/dist/query/find-callers.d.ts +12 -0
  93. package/dist/query/find-callers.js +46 -0
  94. package/dist/query/find-callers.js.map +1 -0
  95. package/dist/query/find-definition.d.ts +3 -0
  96. package/dist/query/find-definition.js +41 -0
  97. package/dist/query/find-definition.js.map +1 -0
  98. package/dist/query/find-dependency-path.d.ts +2 -0
  99. package/dist/query/find-dependency-path.js +39 -0
  100. package/dist/query/find-dependency-path.js.map +1 -0
  101. package/dist/query/find-implementations.d.ts +10 -0
  102. package/dist/query/find-implementations.js +34 -0
  103. package/dist/query/find-implementations.js.map +1 -0
  104. package/dist/query/get-exports.d.ts +3 -0
  105. package/dist/query/get-exports.js +82 -0
  106. package/dist/query/get-exports.js.map +1 -0
  107. package/dist/query/get-file-structure.d.ts +3 -0
  108. package/dist/query/get-file-structure.js +58 -0
  109. package/dist/query/get-file-structure.js.map +1 -0
  110. package/dist/query/get-graph-stats.d.ts +21 -0
  111. package/dist/query/get-graph-stats.js +42 -0
  112. package/dist/query/get-graph-stats.js.map +1 -0
  113. package/dist/query/index.d.ts +11 -0
  114. package/dist/query/index.js +28 -0
  115. package/dist/query/index.js.map +1 -0
  116. package/dist/query/search-symbols.d.ts +6 -0
  117. package/dist/query/search-symbols.js +75 -0
  118. package/dist/query/search-symbols.js.map +1 -0
  119. package/dist/query/types.d.ts +41 -0
  120. package/dist/query/types.js +36 -0
  121. package/dist/query/types.js.map +1 -0
  122. package/dist/storage/database.d.ts +13 -0
  123. package/dist/storage/database.js +49 -0
  124. package/dist/storage/database.js.map +1 -0
  125. package/dist/storage/index.d.ts +7 -0
  126. package/dist/storage/index.js +24 -0
  127. package/dist/storage/index.js.map +1 -0
  128. package/dist/storage/migrations/001_initial.sql +59 -0
  129. package/dist/storage/migrations/002_add_name_index.sql +9 -0
  130. package/dist/storage/migrator.d.ts +9 -0
  131. package/dist/storage/migrator.js +86 -0
  132. package/dist/storage/migrator.js.map +1 -0
  133. package/dist/storage/paths.d.ts +5 -0
  134. package/dist/storage/paths.js +25 -0
  135. package/dist/storage/paths.js.map +1 -0
  136. package/dist/storage/reader.d.ts +10 -0
  137. package/dist/storage/reader.js +103 -0
  138. package/dist/storage/reader.js.map +1 -0
  139. package/dist/storage/schema.d.ts +14 -0
  140. package/dist/storage/schema.js +18 -0
  141. package/dist/storage/schema.js.map +1 -0
  142. package/dist/storage/types.d.ts +42 -0
  143. package/dist/storage/types.js +3 -0
  144. package/dist/storage/types.js.map +1 -0
  145. package/dist/storage/writer.d.ts +13 -0
  146. package/dist/storage/writer.js +160 -0
  147. package/dist/storage/writer.js.map +1 -0
  148. package/package.json +47 -0
@@ -0,0 +1,41 @@
1
+ export interface DefinitionResult {
2
+ id: string;
3
+ name: string;
4
+ type: string;
5
+ filePath: string;
6
+ startLine: number;
7
+ endLine: number;
8
+ startCol: number | null;
9
+ endCol: number | null;
10
+ exported: boolean;
11
+ signature: string | null;
12
+ }
13
+ export interface SearchSymbolResult extends DefinitionResult {
14
+ rank: number;
15
+ }
16
+ export interface FileStructureResult {
17
+ filePath: string;
18
+ functions: DefinitionResult[];
19
+ classes: Array<DefinitionResult & {
20
+ members: DefinitionResult[];
21
+ }>;
22
+ interfaces: DefinitionResult[];
23
+ types: DefinitionResult[];
24
+ enums: DefinitionResult[];
25
+ variables: DefinitionResult[];
26
+ }
27
+ export interface ExportResult {
28
+ exportedName: string;
29
+ localName: string | null;
30
+ type: string | null;
31
+ filePath: string | null;
32
+ startLine: number | null;
33
+ endLine: number | null;
34
+ startCol: number | null;
35
+ endCol: number | null;
36
+ signature: string | null;
37
+ reExport: boolean;
38
+ sourcePath: string | null;
39
+ }
40
+ export declare function normalizeNodeTypeFilter(type: string | undefined): string | undefined;
41
+ export declare function safeParseProperties(properties: string | null): Record<string, unknown>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeNodeTypeFilter = normalizeNodeTypeFilter;
4
+ exports.safeParseProperties = safeParseProperties;
5
+ function normalizeNodeTypeFilter(type) {
6
+ if (!type) {
7
+ return undefined;
8
+ }
9
+ const normalized = type.trim().toLowerCase();
10
+ const mapping = {
11
+ file: "File",
12
+ module: "Module",
13
+ function: "Function",
14
+ class: "Class",
15
+ method: "Method",
16
+ property: "Property",
17
+ interface: "Interface",
18
+ type: "TypeAlias",
19
+ typealias: "TypeAlias",
20
+ enum: "Enum",
21
+ variable: "Variable"
22
+ };
23
+ return mapping[normalized] ?? type;
24
+ }
25
+ function safeParseProperties(properties) {
26
+ if (!properties) {
27
+ return {};
28
+ }
29
+ try {
30
+ return JSON.parse(properties);
31
+ }
32
+ catch {
33
+ return {};
34
+ }
35
+ }
36
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/query/types.ts"],"names":[],"mappings":";;AAyCA,0DAqBC;AAED,kDAUC;AAjCD,SAAgB,uBAAuB,CAAC,IAAwB;IAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,OAAO,GAA2B;QACtC,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,SAAS,EAAE,WAAW;QACtB,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,WAAW;QACtB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,UAAU;KACrB,CAAC;IAEF,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,SAAgB,mBAAmB,CAAC,UAAyB;IAC3D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAA4B,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import Database from "better-sqlite3";
2
+ export interface DatabaseOptions {
3
+ projectRoot?: string;
4
+ migrationsDir?: string;
5
+ autoMigrate?: boolean;
6
+ }
7
+ export interface DatabaseManager {
8
+ db: Database.Database;
9
+ dbPath: string;
10
+ close: () => void;
11
+ destroy: () => void;
12
+ }
13
+ export declare function connectDatabase(options?: DatabaseOptions): DatabaseManager;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.connectDatabase = connectDatabase;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
10
+ const paths_1 = require("./paths");
11
+ const migrator_1 = require("./migrator");
12
+ function connectDatabase(options = {}) {
13
+ const dbPath = (0, paths_1.resolveDatabasePath)(options.projectRoot);
14
+ const dbExisted = node_fs_1.default.existsSync(dbPath);
15
+ (0, paths_1.ensureDatabaseDirectory)(dbPath);
16
+ const db = new better_sqlite3_1.default(dbPath);
17
+ let isClosed = false;
18
+ const safeClose = () => {
19
+ if (isClosed) {
20
+ return;
21
+ }
22
+ db.close();
23
+ isClosed = true;
24
+ };
25
+ db.pragma("foreign_keys = ON");
26
+ db.pragma("journal_mode = WAL");
27
+ db.pragma("busy_timeout = 5000");
28
+ db.pragma("cache_size = -16000"); // 16MB cache
29
+ const migrationsDir = options.migrationsDir ?? node_path_1.default.join(__dirname, "migrations");
30
+ if (options.autoMigrate !== false) {
31
+ const appliedCount = (0, migrator_1.runMigrations)(db, migrationsDir);
32
+ if (!dbExisted && appliedCount === 0) {
33
+ safeClose();
34
+ throw new Error(`No migrations were applied for a new database at '${dbPath}'. Check migrations in '${migrationsDir}'.`);
35
+ }
36
+ }
37
+ return {
38
+ db,
39
+ dbPath,
40
+ close: () => safeClose(),
41
+ destroy: () => {
42
+ safeClose();
43
+ node_fs_1.default.rmSync(dbPath, { force: true });
44
+ node_fs_1.default.rmSync(`${dbPath}-wal`, { force: true });
45
+ node_fs_1.default.rmSync(`${dbPath}-shm`, { force: true });
46
+ }
47
+ };
48
+ }
49
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":";;;;;AAmBA,0CA8CC;AAjED,0DAA6B;AAC7B,sDAAyB;AACzB,oEAAsC;AACtC,mCAAuE;AACvE,yCAA2C;AAe3C,SAAgB,eAAe,CAAC,UAA2B,EAAE;IAC3D,MAAM,MAAM,GAAG,IAAA,2BAAmB,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACxC,IAAA,+BAAuB,EAAC,MAAM,CAAC,CAAC;IAEhC,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;IAEF,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,aAAa;IAE/C,MAAM,aAAa,GACjB,OAAO,CAAC,aAAa,IAAI,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAE9D,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,IAAA,wBAAa,EAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;YACrC,SAAS,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,qDAAqD,MAAM,2BAA2B,aAAa,IAAI,CACxG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE;QACF,MAAM;QACN,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE;QACxB,OAAO,EAAE,GAAG,EAAE;YACZ,SAAS,EAAE,CAAC;YACZ,iBAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,iBAAE,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,iBAAE,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./database";
2
+ export * from "./migrator";
3
+ export * from "./paths";
4
+ export * from "./schema";
5
+ export * from "./types";
6
+ export * from "./writer";
7
+ export * from "./reader";
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./database"), exports);
18
+ __exportStar(require("./migrator"), exports);
19
+ __exportStar(require("./paths"), exports);
20
+ __exportStar(require("./schema"), exports);
21
+ __exportStar(require("./types"), exports);
22
+ __exportStar(require("./writer"), exports);
23
+ __exportStar(require("./reader"), exports);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,2CAAyB;AACzB,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB"}
@@ -0,0 +1,59 @@
1
+ CREATE TABLE IF NOT EXISTS files (
2
+ path TEXT PRIMARY KEY,
3
+ content_hash TEXT NOT NULL,
4
+ language TEXT NOT NULL,
5
+ indexed_at INTEGER NOT NULL
6
+ );
7
+
8
+ CREATE TABLE IF NOT EXISTS nodes (
9
+ id TEXT PRIMARY KEY,
10
+ type TEXT NOT NULL,
11
+ name TEXT NOT NULL,
12
+ file_path TEXT NOT NULL REFERENCES files(path),
13
+ start_line INTEGER NOT NULL,
14
+ end_line INTEGER NOT NULL,
15
+ start_col INTEGER,
16
+ end_col INTEGER,
17
+ properties TEXT,
18
+ UNIQUE(file_path, type, name, start_line)
19
+ );
20
+
21
+ CREATE TABLE IF NOT EXISTS edges (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ source_id TEXT NOT NULL REFERENCES nodes(id),
24
+ target_id TEXT NOT NULL REFERENCES nodes(id),
25
+ type TEXT NOT NULL,
26
+ properties TEXT,
27
+ UNIQUE(source_id, target_id, type)
28
+ );
29
+
30
+ CREATE INDEX IF NOT EXISTS idx_nodes_type_name ON nodes(type, name);
31
+ CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
32
+ CREATE INDEX IF NOT EXISTS idx_nodes_file ON nodes(file_path);
33
+ CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(type, source_id);
34
+ CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(type, target_id);
35
+ CREATE INDEX IF NOT EXISTS idx_edges_source_id ON edges(source_id);
36
+ CREATE INDEX IF NOT EXISTS idx_edges_target_id ON edges(target_id);
37
+ -- L1: Standalone idx_edges_type removed — covered by composite indexes idx_edges_source and idx_edges_target
38
+
39
+ CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
40
+ node_id UNINDEXED,
41
+ name,
42
+ type,
43
+ file_path
44
+ );
45
+
46
+ CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN
47
+ INSERT INTO nodes_fts(node_id, name, type, file_path)
48
+ VALUES (new.id, new.name, new.type, new.file_path);
49
+ END;
50
+
51
+ CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN
52
+ DELETE FROM nodes_fts WHERE node_id = old.id;
53
+ END;
54
+
55
+ CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN
56
+ DELETE FROM nodes_fts WHERE node_id = old.id;
57
+ INSERT INTO nodes_fts(node_id, name, type, file_path)
58
+ VALUES (new.id, new.name, new.type, new.file_path);
59
+ END;
@@ -0,0 +1,9 @@
1
+ -- Add standalone index on nodes(name) for name-only lookups.
2
+ -- The existing idx_nodes_type_name on (type, name) cannot be used when
3
+ -- queries filter by name alone without specifying type.
4
+ CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
5
+
6
+ -- Add standalone indexes on edges(source_id) and edges(target_id) for
7
+ -- non-type-filtered lookups and deletion operations.
8
+ CREATE INDEX IF NOT EXISTS idx_edges_source_id ON edges(source_id);
9
+ CREATE INDEX IF NOT EXISTS idx_edges_target_id ON edges(target_id);
@@ -0,0 +1,9 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface Migration {
3
+ version: number;
4
+ fileName: string;
5
+ sql: string;
6
+ }
7
+ export declare function ensureMigrationsTable(db: Database.Database): void;
8
+ export declare function loadMigrations(migrationsDir: string): Migration[];
9
+ export declare function runMigrations(db: Database.Database, migrationsDir: string): number;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ensureMigrationsTable = ensureMigrationsTable;
7
+ exports.loadMigrations = loadMigrations;
8
+ exports.runMigrations = runMigrations;
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const MIGRATION_FILE_PATTERN = /^(\d+)_(.+)\.sql$/;
12
+ function ensureMigrationsTable(db) {
13
+ db.exec(`
14
+ CREATE TABLE IF NOT EXISTS migrations (
15
+ version INTEGER PRIMARY KEY,
16
+ file_name TEXT NOT NULL,
17
+ applied_at INTEGER NOT NULL
18
+ );
19
+ `);
20
+ }
21
+ function loadMigrations(migrationsDir) {
22
+ if (!node_fs_1.default.existsSync(migrationsDir)) {
23
+ return [];
24
+ }
25
+ const migrations = node_fs_1.default
26
+ .readdirSync(migrationsDir)
27
+ .filter((fileName) => fileName.endsWith(".sql"))
28
+ .map((fileName) => {
29
+ const match = MIGRATION_FILE_PATTERN.exec(fileName);
30
+ if (!match) {
31
+ throw new Error(`Invalid migration filename '${fileName}'. Expected '<number>_<name>.sql'.`);
32
+ }
33
+ return {
34
+ version: Number.parseInt(match[1], 10),
35
+ fileName,
36
+ sql: node_fs_1.default.readFileSync(node_path_1.default.join(migrationsDir, fileName), "utf8")
37
+ };
38
+ })
39
+ .sort((a, b) => a.version - b.version);
40
+ const seenVersions = new Set();
41
+ for (const migration of migrations) {
42
+ if (seenVersions.has(migration.version)) {
43
+ throw new Error(`Duplicate migration version ${migration.version} found at '${migration.fileName}'.`);
44
+ }
45
+ seenVersions.add(migration.version);
46
+ }
47
+ return migrations;
48
+ }
49
+ function runMigrations(db, migrationsDir) {
50
+ ensureMigrationsTable(db);
51
+ const migrations = loadMigrations(migrationsDir);
52
+ const migrationVersions = migrations.map((migration) => migration.version);
53
+ const availableVersionSet = new Set(migrationVersions);
54
+ const appliedVersionList = db
55
+ .prepare("SELECT version FROM migrations ORDER BY version ASC")
56
+ .all()
57
+ .map((row) => row.version);
58
+ const appliedVersions = new Set(appliedVersionList);
59
+ for (const version of appliedVersions) {
60
+ if (!availableVersionSet.has(version)) {
61
+ throw new Error(`Applied migration version ${version} is missing from '${migrationsDir}'.`);
62
+ }
63
+ }
64
+ const highestApplied = appliedVersionList.at(-1);
65
+ if (highestApplied !== undefined) {
66
+ for (const version of migrationVersions) {
67
+ if (version < highestApplied && !appliedVersions.has(version)) {
68
+ throw new Error(`Migration history is inconsistent: version ${version} is missing but version ${highestApplied} is already applied.`);
69
+ }
70
+ }
71
+ }
72
+ let appliedCount = 0;
73
+ for (const migration of migrations) {
74
+ if (appliedVersions.has(migration.version)) {
75
+ continue;
76
+ }
77
+ const tx = db.transaction(() => {
78
+ db.exec(migration.sql);
79
+ db.prepare("INSERT INTO migrations (version, file_name, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.fileName, Date.now());
80
+ });
81
+ tx();
82
+ appliedCount += 1;
83
+ }
84
+ return appliedCount;
85
+ }
86
+ //# sourceMappingURL=migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../../src/storage/migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const DEFAULT_DB_DIRECTORY = ".graphite";
2
+ export declare const DEFAULT_DB_FILE_NAME = "index.db";
3
+ export declare function resolveProjectRoot(projectRoot?: string): string;
4
+ export declare function resolveDatabasePath(projectRoot?: string): string;
5
+ export declare function ensureDatabaseDirectory(databasePath: string): void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_DB_FILE_NAME = exports.DEFAULT_DB_DIRECTORY = void 0;
7
+ exports.resolveProjectRoot = resolveProjectRoot;
8
+ exports.resolveDatabasePath = resolveDatabasePath;
9
+ exports.ensureDatabaseDirectory = ensureDatabaseDirectory;
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ exports.DEFAULT_DB_DIRECTORY = ".graphite";
13
+ exports.DEFAULT_DB_FILE_NAME = "index.db";
14
+ function resolveProjectRoot(projectRoot = process.cwd()) {
15
+ return node_path_1.default.resolve(projectRoot);
16
+ }
17
+ function resolveDatabasePath(projectRoot) {
18
+ const root = resolveProjectRoot(projectRoot);
19
+ return node_path_1.default.join(root, exports.DEFAULT_DB_DIRECTORY, exports.DEFAULT_DB_FILE_NAME);
20
+ }
21
+ function ensureDatabaseDirectory(databasePath) {
22
+ const dbDirectory = node_path_1.default.dirname(databasePath);
23
+ node_fs_1.default.mkdirSync(dbDirectory, { recursive: true });
24
+ }
25
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/storage/paths.ts"],"names":[],"mappings":";;;;;;AAMA,gDAEC;AAED,kDAGC;AAED,0DAGC;AAlBD,sDAAyB;AACzB,0DAA6B;AAEhB,QAAA,oBAAoB,GAAG,WAAW,CAAC;AACnC,QAAA,oBAAoB,GAAG,UAAU,CAAC;AAE/C,SAAgB,kBAAkB,CAAC,cAAsB,OAAO,CAAC,GAAG,EAAE;IACpE,OAAO,mBAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,mBAAmB,CAAC,WAAoB;IACtD,MAAM,IAAI,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC7C,OAAO,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,4BAAoB,EAAE,4BAAoB,CAAC,CAAC;AACrE,CAAC;AAED,SAAgB,uBAAuB,CAAC,YAAoB;IAC1D,MAAM,WAAW,GAAG,mBAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,iBAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { IndexedFileState, NodeRecord, StorageStats } from "./types";
3
+ export interface StorageReader {
4
+ findNodeByName: (name: string, type?: string) => NodeRecord[];
5
+ getFileNodes: (filePath: string) => NodeRecord[];
6
+ getNodeById: (id: string) => NodeRecord | null;
7
+ getIndexedFiles: () => IndexedFileState[];
8
+ getStats: () => StorageStats;
9
+ }
10
+ export declare function createStorageReader(db: Database.Database): StorageReader;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStorageReader = createStorageReader;
4
+ const NODE_SELECT_COLUMNS = "id, type, name, file_path, start_line, end_line, start_col, end_col, properties";
5
+ function mapNodeRow(row) {
6
+ return {
7
+ id: row.id,
8
+ type: row.type,
9
+ name: row.name,
10
+ filePath: row.file_path,
11
+ startLine: row.start_line,
12
+ endLine: row.end_line,
13
+ startCol: row.start_col,
14
+ endCol: row.end_col,
15
+ properties: row.properties
16
+ };
17
+ }
18
+ function createStorageReader(db) {
19
+ const findNodeByNameAnyTypeStatement = db.prepare(`
20
+ SELECT ${NODE_SELECT_COLUMNS}
21
+ FROM nodes
22
+ WHERE name = ?
23
+ ORDER BY file_path ASC, start_line ASC
24
+ `);
25
+ const findNodeByNameWithTypeStatement = db.prepare(`
26
+ SELECT ${NODE_SELECT_COLUMNS}
27
+ FROM nodes
28
+ WHERE name = ? AND type = ?
29
+ ORDER BY file_path ASC, start_line ASC
30
+ `);
31
+ const getFileNodesStatement = db.prepare(`
32
+ SELECT ${NODE_SELECT_COLUMNS}
33
+ FROM nodes
34
+ WHERE file_path = ?
35
+ ORDER BY start_line ASC, name ASC
36
+ `);
37
+ const getNodeByIdStatement = db.prepare(`
38
+ SELECT ${NODE_SELECT_COLUMNS}
39
+ FROM nodes
40
+ WHERE id = ?
41
+ LIMIT 1
42
+ `);
43
+ const countFilesStatement = db.prepare("SELECT COUNT(*) as count FROM files");
44
+ const countNodesStatement = db.prepare("SELECT COUNT(*) as count FROM nodes");
45
+ const countEdgesStatement = db.prepare("SELECT COUNT(*) as count FROM edges");
46
+ const countNodesByTypeStatement = db.prepare(`
47
+ SELECT type, COUNT(*) as count
48
+ FROM nodes
49
+ GROUP BY type
50
+ ORDER BY count DESC, type ASC
51
+ `);
52
+ const countEdgesByTypeStatement = db.prepare(`
53
+ SELECT type, COUNT(*) as count
54
+ FROM edges
55
+ GROUP BY type
56
+ ORDER BY count DESC, type ASC
57
+ `);
58
+ const getIndexedFilesStatement = db.prepare(`
59
+ SELECT path, content_hash, language, indexed_at
60
+ FROM files
61
+ ORDER BY path ASC
62
+ `);
63
+ return {
64
+ findNodeByName: (name, type) => {
65
+ const rows = (type
66
+ ? findNodeByNameWithTypeStatement.all(name, type)
67
+ : findNodeByNameAnyTypeStatement.all(name));
68
+ return rows.map(mapNodeRow);
69
+ },
70
+ getFileNodes: (filePath) => {
71
+ const rows = getFileNodesStatement.all(filePath);
72
+ return rows.map(mapNodeRow);
73
+ },
74
+ getNodeById: (id) => {
75
+ const row = getNodeByIdStatement.get(id);
76
+ return row ? mapNodeRow(row) : null;
77
+ },
78
+ getIndexedFiles: () => {
79
+ const rows = getIndexedFilesStatement.all();
80
+ return rows.map((row) => ({
81
+ path: row.path,
82
+ contentHash: row.content_hash,
83
+ language: row.language,
84
+ indexedAt: row.indexed_at
85
+ }));
86
+ },
87
+ getStats: () => {
88
+ const fileCount = countFilesStatement.get().count;
89
+ const nodeCount = countNodesStatement.get().count;
90
+ const edgeCount = countEdgesStatement.get().count;
91
+ const nodesByType = countNodesByTypeStatement.all();
92
+ const edgesByType = countEdgesByTypeStatement.all();
93
+ return {
94
+ fileCount,
95
+ nodeCount,
96
+ edgeCount,
97
+ nodesByType,
98
+ edgesByType
99
+ };
100
+ }
101
+ };
102
+ }
103
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/storage/reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare const TABLES: {
2
+ readonly files: "files";
3
+ readonly nodes: "nodes";
4
+ readonly edges: "edges";
5
+ readonly migrations: "migrations";
6
+ readonly nodesFts: "nodes_fts";
7
+ };
8
+ export declare const INDEXES: {
9
+ readonly nodesTypeName: "idx_nodes_type_name";
10
+ readonly nodesFile: "idx_nodes_file";
11
+ readonly edgesSource: "idx_edges_source";
12
+ readonly edgesTarget: "idx_edges_target";
13
+ readonly edgesType: "idx_edges_type";
14
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INDEXES = exports.TABLES = void 0;
4
+ exports.TABLES = {
5
+ files: "files",
6
+ nodes: "nodes",
7
+ edges: "edges",
8
+ migrations: "migrations",
9
+ nodesFts: "nodes_fts"
10
+ };
11
+ exports.INDEXES = {
12
+ nodesTypeName: "idx_nodes_type_name",
13
+ nodesFile: "idx_nodes_file",
14
+ edgesSource: "idx_edges_source",
15
+ edgesTarget: "idx_edges_target",
16
+ edgesType: "idx_edges_type"
17
+ };
18
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,WAAW;CACb,CAAC;AAEE,QAAA,OAAO,GAAG;IACrB,aAAa,EAAE,qBAAqB;IACpC,SAAS,EAAE,gBAAgB;IAC3B,WAAW,EAAE,kBAAkB;IAC/B,WAAW,EAAE,kBAAkB;IAC/B,SAAS,EAAE,gBAAgB;CACnB,CAAC"}
@@ -0,0 +1,42 @@
1
+ export interface FileRecord {
2
+ path: string;
3
+ contentHash: string;
4
+ language: string;
5
+ indexedAt: number;
6
+ }
7
+ export interface NodeRecord {
8
+ id: string;
9
+ type: string;
10
+ name: string;
11
+ filePath: string;
12
+ startLine: number;
13
+ endLine: number;
14
+ startCol?: number | null;
15
+ endCol?: number | null;
16
+ properties?: string | null;
17
+ }
18
+ export interface EdgeRecord {
19
+ sourceId: string;
20
+ targetId: string;
21
+ type: string;
22
+ properties?: string | null;
23
+ }
24
+ export interface StorageStats {
25
+ fileCount: number;
26
+ nodeCount: number;
27
+ edgeCount: number;
28
+ nodesByType: Array<{
29
+ type: string;
30
+ count: number;
31
+ }>;
32
+ edgesByType: Array<{
33
+ type: string;
34
+ count: number;
35
+ }>;
36
+ }
37
+ export interface IndexedFileState {
38
+ path: string;
39
+ contentHash: string;
40
+ language: string;
41
+ indexedAt: number;
42
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { EdgeRecord, FileRecord, NodeRecord } from "./types";
3
+ export interface StorageWriter {
4
+ upsertFile: (file: FileRecord) => void;
5
+ upsertNode: (node: NodeRecord) => void;
6
+ upsertEdge: (edge: EdgeRecord) => void;
7
+ deleteEdgesByType: (type: string) => number;
8
+ deleteFileEdges: (filePath: string) => number;
9
+ deleteFileNodes: (filePath: string) => number;
10
+ deleteFileGraph: (filePath: string) => void;
11
+ replaceFileGraph: (file: FileRecord, nodes: NodeRecord[], edges: EdgeRecord[]) => void;
12
+ }
13
+ export declare function createStorageWriter(db: Database.Database): StorageWriter;