@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.
- package/README.md +427 -0
- package/dist/cli/formatters.d.ts +3 -0
- package/dist/cli/formatters.js +61 -0
- package/dist/cli/formatters.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +186 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/call-resolver.d.ts +8 -0
- package/dist/indexer/call-resolver.js +161 -0
- package/dist/indexer/call-resolver.js.map +1 -0
- package/dist/indexer/extractors/calls.d.ts +17 -0
- package/dist/indexer/extractors/calls.js +206 -0
- package/dist/indexer/extractors/calls.js.map +1 -0
- package/dist/indexer/extractors/classes.d.ts +35 -0
- package/dist/indexer/extractors/classes.js +209 -0
- package/dist/indexer/extractors/classes.js.map +1 -0
- package/dist/indexer/extractors/exports.d.ts +12 -0
- package/dist/indexer/extractors/exports.js +267 -0
- package/dist/indexer/extractors/exports.js.map +1 -0
- package/dist/indexer/extractors/functions.d.ts +12 -0
- package/dist/indexer/extractors/functions.js +169 -0
- package/dist/indexer/extractors/functions.js.map +1 -0
- package/dist/indexer/extractors/imports.d.ts +12 -0
- package/dist/indexer/extractors/imports.js +195 -0
- package/dist/indexer/extractors/imports.js.map +1 -0
- package/dist/indexer/extractors/index.d.ts +7 -0
- package/dist/indexer/extractors/index.js +24 -0
- package/dist/indexer/extractors/index.js.map +1 -0
- package/dist/indexer/extractors/types.d.ts +12 -0
- package/dist/indexer/extractors/types.js +138 -0
- package/dist/indexer/extractors/types.js.map +1 -0
- package/dist/indexer/extractors/variables.d.ts +10 -0
- package/dist/indexer/extractors/variables.js +134 -0
- package/dist/indexer/extractors/variables.js.map +1 -0
- package/dist/indexer/file-discovery.d.ts +7 -0
- package/dist/indexer/file-discovery.js +92 -0
- package/dist/indexer/file-discovery.js.map +1 -0
- package/dist/indexer/file-indexer.d.ts +2 -0
- package/dist/indexer/file-indexer.js +267 -0
- package/dist/indexer/file-indexer.js.map +1 -0
- package/dist/indexer/graph-contract.d.ts +25 -0
- package/dist/indexer/graph-contract.js +7 -0
- package/dist/indexer/graph-contract.js.map +1 -0
- package/dist/indexer/hasher.d.ts +1 -0
- package/dist/indexer/hasher.js +11 -0
- package/dist/indexer/hasher.js.map +1 -0
- package/dist/indexer/import-resolver.d.ts +11 -0
- package/dist/indexer/import-resolver.js +131 -0
- package/dist/indexer/import-resolver.js.map +1 -0
- package/dist/indexer/index.d.ts +11 -0
- package/dist/indexer/index.js +28 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/inheritance-resolver.d.ts +7 -0
- package/dist/indexer/inheritance-resolver.js +119 -0
- package/dist/indexer/inheritance-resolver.js.map +1 -0
- package/dist/indexer/parser.d.ts +5 -0
- package/dist/indexer/parser.js +48 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/path-utils.d.ts +3 -0
- package/dist/indexer/path-utils.js +20 -0
- package/dist/indexer/path-utils.js.map +1 -0
- package/dist/indexer/project-indexer.d.ts +14 -0
- package/dist/indexer/project-indexer.js +167 -0
- package/dist/indexer/project-indexer.js.map +1 -0
- package/dist/indexer/property-parsers.d.ts +20 -0
- package/dist/indexer/property-parsers.js +81 -0
- package/dist/indexer/property-parsers.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.js +20 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/response-formatter.d.ts +10 -0
- package/dist/mcp/response-formatter.js +47 -0
- package/dist/mcp/response-formatter.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +118 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools-list.d.ts +9 -0
- package/dist/mcp/tools-list.js +12 -0
- package/dist/mcp/tools-list.js.map +1 -0
- package/dist/mcp/tools.d.ts +13 -0
- package/dist/mcp/tools.js +163 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/query/analyze-impact.d.ts +18 -0
- package/dist/query/analyze-impact.js +58 -0
- package/dist/query/analyze-impact.js.map +1 -0
- package/dist/query/find-callees.d.ts +12 -0
- package/dist/query/find-callees.js +46 -0
- package/dist/query/find-callees.js.map +1 -0
- package/dist/query/find-callers.d.ts +12 -0
- package/dist/query/find-callers.js +46 -0
- package/dist/query/find-callers.js.map +1 -0
- package/dist/query/find-definition.d.ts +3 -0
- package/dist/query/find-definition.js +41 -0
- package/dist/query/find-definition.js.map +1 -0
- package/dist/query/find-dependency-path.d.ts +2 -0
- package/dist/query/find-dependency-path.js +39 -0
- package/dist/query/find-dependency-path.js.map +1 -0
- package/dist/query/find-implementations.d.ts +10 -0
- package/dist/query/find-implementations.js +34 -0
- package/dist/query/find-implementations.js.map +1 -0
- package/dist/query/get-exports.d.ts +3 -0
- package/dist/query/get-exports.js +82 -0
- package/dist/query/get-exports.js.map +1 -0
- package/dist/query/get-file-structure.d.ts +3 -0
- package/dist/query/get-file-structure.js +58 -0
- package/dist/query/get-file-structure.js.map +1 -0
- package/dist/query/get-graph-stats.d.ts +21 -0
- package/dist/query/get-graph-stats.js +42 -0
- package/dist/query/get-graph-stats.js.map +1 -0
- package/dist/query/index.d.ts +11 -0
- package/dist/query/index.js +28 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/search-symbols.d.ts +6 -0
- package/dist/query/search-symbols.js +75 -0
- package/dist/query/search-symbols.js.map +1 -0
- package/dist/query/types.d.ts +41 -0
- package/dist/query/types.js +36 -0
- package/dist/query/types.js.map +1 -0
- package/dist/storage/database.d.ts +13 -0
- package/dist/storage/database.js +49 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.js +24 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/migrations/001_initial.sql +59 -0
- package/dist/storage/migrations/002_add_name_index.sql +9 -0
- package/dist/storage/migrator.d.ts +9 -0
- package/dist/storage/migrator.js +86 -0
- package/dist/storage/migrator.js.map +1 -0
- package/dist/storage/paths.d.ts +5 -0
- package/dist/storage/paths.js +25 -0
- package/dist/storage/paths.js.map +1 -0
- package/dist/storage/reader.d.ts +10 -0
- package/dist/storage/reader.js +103 -0
- package/dist/storage/reader.js.map +1 -0
- package/dist/storage/schema.d.ts +14 -0
- package/dist/storage/schema.js +18 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/types.d.ts +42 -0
- package/dist/storage/types.js +3 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/writer.d.ts +13 -0
- package/dist/storage/writer.js +160 -0
- package/dist/storage/writer.js.map +1 -0
- 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,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 @@
|
|
|
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;
|