ralph-hero-knowledge-index 0.1.14 → 0.1.16
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/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/dist/db.d.ts +23 -3
- package/dist/db.js +64 -13
- package/dist/db.js.map +1 -1
- package/dist/format.d.ts +39 -0
- package/dist/format.js +40 -0
- package/dist/format.js.map +1 -0
- package/dist/graph-builder.d.ts +17 -0
- package/dist/graph-builder.js +36 -0
- package/dist/graph-builder.js.map +1 -0
- package/dist/graph-tools.d.ts +3 -0
- package/dist/graph-tools.js +474 -0
- package/dist/graph-tools.js.map +1 -0
- package/dist/hybrid-search.js +2 -1
- package/dist/hybrid-search.js.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts +13 -0
- package/dist/parser.js +36 -1
- package/dist/parser.js.map +1 -1
- package/dist/reindex.js +59 -11
- package/dist/reindex.js.map +1 -1
- package/dist/traverse.d.ts +1 -0
- package/dist/traverse.js +8 -4
- package/dist/traverse.js.map +1 -1
- package/dist/vector-search.d.ts +1 -0
- package/dist/vector-search.js +6 -0
- package/dist/vector-search.js.map +1 -1
- package/package.json +10 -1
- package/src/__tests__/db.test.ts +213 -1
- package/src/__tests__/format.test.ts +235 -0
- package/src/__tests__/graph-builder.test.ts +174 -0
- package/src/__tests__/graph-tools.test.ts +1015 -0
- package/src/__tests__/parser.test.ts +115 -1
- package/src/__tests__/reindex.test.ts +171 -3
- package/src/__tests__/traverse.test.ts +78 -0
- package/src/db.ts +83 -15
- package/src/format.ts +75 -0
- package/src/graph-builder.ts +69 -0
- package/src/graph-tools.ts +650 -0
- package/src/hybrid-search.ts +3 -2
- package/src/index.ts +12 -4
- package/src/parser.ts +53 -1
- package/src/reindex.ts +70 -12
- package/src/traverse.ts +11 -4
- package/src/vector-search.ts +7 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralph-knowledge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Knowledge graph for ralph-hero: semantic search, relationship traversal, and document indexing across thoughts/ documents. Optional companion to ralph-hero.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Chad Dubiel",
|
package/.mcp.json
CHANGED
package/dist/db.d.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import type { Database as DatabaseType } from "better-sqlite3";
|
|
2
2
|
export interface DocumentRow {
|
|
3
3
|
id: string;
|
|
4
|
-
path: string;
|
|
4
|
+
path: string | null;
|
|
5
5
|
title: string;
|
|
6
6
|
date: string | null;
|
|
7
7
|
type: string | null;
|
|
8
8
|
status: string | null;
|
|
9
9
|
githubIssue: number | null;
|
|
10
10
|
content: string;
|
|
11
|
+
isStub: number;
|
|
11
12
|
}
|
|
12
13
|
export interface RelationshipRow {
|
|
13
14
|
sourceId: string;
|
|
14
15
|
targetId: string;
|
|
15
16
|
type: string;
|
|
17
|
+
context: string | null;
|
|
16
18
|
}
|
|
17
19
|
export interface OutcomeEventInput {
|
|
18
20
|
eventType: string;
|
|
@@ -44,6 +46,11 @@ export interface OutcomeEventRow {
|
|
|
44
46
|
iterationCount: number | null;
|
|
45
47
|
payload: string;
|
|
46
48
|
}
|
|
49
|
+
export interface SyncRecord {
|
|
50
|
+
path: string;
|
|
51
|
+
mtime: number;
|
|
52
|
+
indexed_at: number;
|
|
53
|
+
}
|
|
47
54
|
export interface OutcomeQueryParams {
|
|
48
55
|
issueNumber?: number;
|
|
49
56
|
eventType?: string;
|
|
@@ -76,11 +83,18 @@ export declare class KnowledgeDB {
|
|
|
76
83
|
readonly db: DatabaseType;
|
|
77
84
|
constructor(dbPath: string);
|
|
78
85
|
private createSchema;
|
|
79
|
-
upsertDocument(doc: DocumentRow
|
|
86
|
+
upsertDocument(doc: Omit<DocumentRow, "isStub"> & {
|
|
87
|
+
isStub?: number;
|
|
88
|
+
}): void;
|
|
89
|
+
/**
|
|
90
|
+
* Creates a stub document for an unresolved wikilink target.
|
|
91
|
+
* Uses INSERT OR IGNORE so it never overwrites a real document.
|
|
92
|
+
*/
|
|
93
|
+
upsertStubDocument(id: string): void;
|
|
80
94
|
getDocument(id: string): DocumentRow | undefined;
|
|
81
95
|
setTags(docId: string, tags: string[]): void;
|
|
82
96
|
getTags(docId: string): string[];
|
|
83
|
-
addRelationship(sourceId: string, targetId: string, type: string): void;
|
|
97
|
+
addRelationship(sourceId: string, targetId: string, type: string, context?: string): void;
|
|
84
98
|
getRelationshipsFrom(sourceId: string): RelationshipRow[];
|
|
85
99
|
getRelationshipsTo(targetId: string): RelationshipRow[];
|
|
86
100
|
insertOutcomeEvent(input: OutcomeEventInput): {
|
|
@@ -92,6 +106,12 @@ export declare class KnowledgeDB {
|
|
|
92
106
|
queryOutcomeEvents(params?: OutcomeQueryParams): OutcomeEventRow[];
|
|
93
107
|
aggregateOutcomeEvents(params?: OutcomeQueryParams): OutcomeAggregate;
|
|
94
108
|
getOutcomeSummary(issueNumber: number): OutcomeSummary | null;
|
|
109
|
+
getSyncRecord(path: string): SyncRecord | undefined;
|
|
110
|
+
upsertSyncRecord(path: string, mtime: number): void;
|
|
111
|
+
deleteSyncRecord(path: string): void;
|
|
112
|
+
getAllSyncPaths(): string[];
|
|
113
|
+
documentExists(id: string): boolean;
|
|
114
|
+
deleteDocument(id: string): void;
|
|
95
115
|
clearAll(): void;
|
|
96
116
|
close(): void;
|
|
97
117
|
}
|
package/dist/db.js
CHANGED
|
@@ -14,13 +14,14 @@ export class KnowledgeDB {
|
|
|
14
14
|
this.db.exec(`
|
|
15
15
|
CREATE TABLE IF NOT EXISTS documents (
|
|
16
16
|
id TEXT PRIMARY KEY,
|
|
17
|
-
path TEXT
|
|
17
|
+
path TEXT,
|
|
18
18
|
title TEXT,
|
|
19
19
|
date TEXT,
|
|
20
20
|
type TEXT,
|
|
21
21
|
status TEXT,
|
|
22
22
|
github_issue INTEGER,
|
|
23
|
-
content TEXT
|
|
23
|
+
content TEXT,
|
|
24
|
+
is_stub INTEGER DEFAULT 0
|
|
24
25
|
);
|
|
25
26
|
CREATE TABLE IF NOT EXISTS tags (
|
|
26
27
|
doc_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
@@ -29,8 +30,9 @@ export class KnowledgeDB {
|
|
|
29
30
|
);
|
|
30
31
|
CREATE TABLE IF NOT EXISTS relationships (
|
|
31
32
|
source_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
32
|
-
target_id TEXT,
|
|
33
|
-
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by')),
|
|
33
|
+
target_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
34
|
+
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by', 'post_mortem', 'untyped')),
|
|
35
|
+
context TEXT,
|
|
34
36
|
PRIMARY KEY (source_id, target_id, type)
|
|
35
37
|
);
|
|
36
38
|
CREATE INDEX IF NOT EXISTS idx_rel_target ON relationships(target_id, type);
|
|
@@ -58,19 +60,44 @@ export class KnowledgeDB {
|
|
|
58
60
|
CREATE INDEX IF NOT EXISTS idx_oe_timestamp ON outcome_events(timestamp);
|
|
59
61
|
CREATE INDEX IF NOT EXISTS idx_oe_session ON outcome_events(session_id);
|
|
60
62
|
CREATE INDEX IF NOT EXISTS idx_oe_type_component ON outcome_events(event_type, component_area);
|
|
63
|
+
|
|
64
|
+
CREATE TABLE IF NOT EXISTS sync (
|
|
65
|
+
path TEXT PRIMARY KEY,
|
|
66
|
+
mtime INTEGER NOT NULL,
|
|
67
|
+
indexed_at INTEGER NOT NULL
|
|
68
|
+
);
|
|
61
69
|
`);
|
|
70
|
+
// Migration: add is_stub column for databases created before it existed.
|
|
71
|
+
// SQLite has no IF NOT EXISTS for ALTER TABLE ADD COLUMN, so we catch the
|
|
72
|
+
// "duplicate column" error and ignore it.
|
|
73
|
+
try {
|
|
74
|
+
this.db.exec("ALTER TABLE documents ADD COLUMN is_stub INTEGER DEFAULT 0");
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Column already exists — expected for new databases
|
|
78
|
+
}
|
|
62
79
|
}
|
|
63
80
|
upsertDocument(doc) {
|
|
64
81
|
this.db.prepare(`
|
|
65
|
-
INSERT INTO documents (id, path, title, date, type, status, github_issue, content)
|
|
66
|
-
VALUES (@id, @path, @title, @date, @type, @status, @githubIssue, @content)
|
|
82
|
+
INSERT INTO documents (id, path, title, date, type, status, github_issue, content, is_stub)
|
|
83
|
+
VALUES (@id, @path, @title, @date, @type, @status, @githubIssue, @content, 0)
|
|
67
84
|
ON CONFLICT(id) DO UPDATE SET
|
|
68
85
|
path = @path, title = @title, date = @date, type = @type,
|
|
69
|
-
status = @status, github_issue = @githubIssue, content = @content
|
|
86
|
+
status = @status, github_issue = @githubIssue, content = @content, is_stub = 0
|
|
70
87
|
`).run(doc);
|
|
71
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Creates a stub document for an unresolved wikilink target.
|
|
91
|
+
* Uses INSERT OR IGNORE so it never overwrites a real document.
|
|
92
|
+
*/
|
|
93
|
+
upsertStubDocument(id) {
|
|
94
|
+
this.db.prepare(`
|
|
95
|
+
INSERT OR IGNORE INTO documents (id, path, title, date, type, status, github_issue, content, is_stub)
|
|
96
|
+
VALUES (?, NULL, ?, NULL, NULL, NULL, NULL, '', 1)
|
|
97
|
+
`).run(id, id);
|
|
98
|
+
}
|
|
72
99
|
getDocument(id) {
|
|
73
|
-
return this.db.prepare(`SELECT id, path, title, date, type, status, github_issue AS githubIssue, content FROM documents WHERE id = ?`).get(id);
|
|
100
|
+
return this.db.prepare(`SELECT id, path, title, date, type, status, github_issue AS githubIssue, content, is_stub AS isStub FROM documents WHERE id = ?`).get(id);
|
|
74
101
|
}
|
|
75
102
|
setTags(docId, tags) {
|
|
76
103
|
this.db.prepare("DELETE FROM tags WHERE doc_id = ?").run(docId);
|
|
@@ -81,14 +108,14 @@ export class KnowledgeDB {
|
|
|
81
108
|
getTags(docId) {
|
|
82
109
|
return this.db.prepare("SELECT tag FROM tags WHERE doc_id = ? ORDER BY tag").all(docId).map(r => r.tag);
|
|
83
110
|
}
|
|
84
|
-
addRelationship(sourceId, targetId, type) {
|
|
85
|
-
this.db.prepare("INSERT OR IGNORE INTO relationships (source_id, target_id, type) VALUES (?, ?, ?)").run(sourceId, targetId, type);
|
|
111
|
+
addRelationship(sourceId, targetId, type, context) {
|
|
112
|
+
this.db.prepare("INSERT OR IGNORE INTO relationships (source_id, target_id, type, context) VALUES (?, ?, ?, ?)").run(sourceId, targetId, type, context ?? null);
|
|
86
113
|
}
|
|
87
114
|
getRelationshipsFrom(sourceId) {
|
|
88
|
-
return this.db.prepare("SELECT source_id AS sourceId, target_id AS targetId, type FROM relationships WHERE source_id = ?").all(sourceId);
|
|
115
|
+
return this.db.prepare("SELECT source_id AS sourceId, target_id AS targetId, type, context FROM relationships WHERE source_id = ?").all(sourceId);
|
|
89
116
|
}
|
|
90
117
|
getRelationshipsTo(targetId) {
|
|
91
|
-
return this.db.prepare("SELECT source_id AS sourceId, target_id AS targetId, type FROM relationships WHERE target_id = ?").all(targetId);
|
|
118
|
+
return this.db.prepare("SELECT source_id AS sourceId, target_id AS targetId, type, context FROM relationships WHERE target_id = ?").all(targetId);
|
|
92
119
|
}
|
|
93
120
|
insertOutcomeEvent(input) {
|
|
94
121
|
const id = randomUUID();
|
|
@@ -216,9 +243,33 @@ export class KnowledgeDB {
|
|
|
216
243
|
eventsByType,
|
|
217
244
|
};
|
|
218
245
|
}
|
|
246
|
+
getSyncRecord(path) {
|
|
247
|
+
return this.db.prepare("SELECT path, mtime, indexed_at AS indexed_at FROM sync WHERE path = ?").get(path);
|
|
248
|
+
}
|
|
249
|
+
upsertSyncRecord(path, mtime) {
|
|
250
|
+
const indexedAt = Date.now();
|
|
251
|
+
this.db.prepare(`
|
|
252
|
+
INSERT INTO sync (path, mtime, indexed_at)
|
|
253
|
+
VALUES (?, ?, ?)
|
|
254
|
+
ON CONFLICT(path) DO UPDATE SET mtime = ?, indexed_at = ?
|
|
255
|
+
`).run(path, mtime, indexedAt, mtime, indexedAt);
|
|
256
|
+
}
|
|
257
|
+
deleteSyncRecord(path) {
|
|
258
|
+
this.db.prepare("DELETE FROM sync WHERE path = ?").run(path);
|
|
259
|
+
}
|
|
260
|
+
getAllSyncPaths() {
|
|
261
|
+
return this.db.prepare("SELECT path FROM sync").all().map(r => r.path);
|
|
262
|
+
}
|
|
263
|
+
documentExists(id) {
|
|
264
|
+
const row = this.db.prepare("SELECT 1 FROM documents WHERE id = ?").get(id);
|
|
265
|
+
return row !== undefined;
|
|
266
|
+
}
|
|
267
|
+
deleteDocument(id) {
|
|
268
|
+
this.db.prepare("DELETE FROM documents WHERE id = ?").run(id);
|
|
269
|
+
}
|
|
219
270
|
clearAll() {
|
|
220
271
|
// outcome_events is intentionally NOT cleared — outcome data is preserved across rebuilds
|
|
221
|
-
this.db.exec("DELETE FROM relationships; DELETE FROM tags; DELETE FROM documents;");
|
|
272
|
+
this.db.exec("DELETE FROM relationships; DELETE FROM tags; DELETE FROM documents; DELETE FROM sync;");
|
|
222
273
|
}
|
|
223
274
|
close() {
|
|
224
275
|
this.db.close();
|
package/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { SearchResult } from "./search.js";
|
|
2
|
+
import type { TraverseResult } from "./traverse.js";
|
|
3
|
+
export interface EnrichedSearchResult extends SearchResult {
|
|
4
|
+
tags: string[];
|
|
5
|
+
outcomes_summary?: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface BriefSearchResult {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
type: string | null;
|
|
11
|
+
date: string | null;
|
|
12
|
+
tags: string[];
|
|
13
|
+
score: number;
|
|
14
|
+
}
|
|
15
|
+
export interface BriefTraverseResult {
|
|
16
|
+
sourceId: string;
|
|
17
|
+
targetId: string;
|
|
18
|
+
type: string;
|
|
19
|
+
depth: number;
|
|
20
|
+
doc: {
|
|
21
|
+
title: string;
|
|
22
|
+
} | null;
|
|
23
|
+
tags: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Format search results for return to the caller.
|
|
27
|
+
*
|
|
28
|
+
* brief=false (default): Returns the full enriched result objects unchanged.
|
|
29
|
+
* brief=true: Returns lightweight objects with id, title, type, date, tags, score only.
|
|
30
|
+
* Strips snippet, path, status, and outcomes_summary.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatSearchResults(results: EnrichedSearchResult[], brief: boolean): EnrichedSearchResult[] | BriefSearchResult[];
|
|
33
|
+
/**
|
|
34
|
+
* Format traverse results for return to the caller.
|
|
35
|
+
*
|
|
36
|
+
* brief=false (default): Returns the original TraverseResult objects unchanged (no tags added).
|
|
37
|
+
* brief=true: Strips doc to { title } only and adds tags array per hop target.
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatTraverseResults(results: TraverseResult[], getTagsFn: (id: string) => string[], brief: boolean): TraverseResult[] | BriefTraverseResult[];
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format search results for return to the caller.
|
|
3
|
+
*
|
|
4
|
+
* brief=false (default): Returns the full enriched result objects unchanged.
|
|
5
|
+
* brief=true: Returns lightweight objects with id, title, type, date, tags, score only.
|
|
6
|
+
* Strips snippet, path, status, and outcomes_summary.
|
|
7
|
+
*/
|
|
8
|
+
export function formatSearchResults(results, brief) {
|
|
9
|
+
if (!brief) {
|
|
10
|
+
return results;
|
|
11
|
+
}
|
|
12
|
+
return results.map((r) => ({
|
|
13
|
+
id: r.id,
|
|
14
|
+
title: r.title,
|
|
15
|
+
type: r.type,
|
|
16
|
+
date: r.date,
|
|
17
|
+
tags: r.tags,
|
|
18
|
+
score: r.score,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Format traverse results for return to the caller.
|
|
23
|
+
*
|
|
24
|
+
* brief=false (default): Returns the original TraverseResult objects unchanged (no tags added).
|
|
25
|
+
* brief=true: Strips doc to { title } only and adds tags array per hop target.
|
|
26
|
+
*/
|
|
27
|
+
export function formatTraverseResults(results, getTagsFn, brief) {
|
|
28
|
+
if (!brief) {
|
|
29
|
+
return results;
|
|
30
|
+
}
|
|
31
|
+
return results.map((r) => ({
|
|
32
|
+
sourceId: r.sourceId,
|
|
33
|
+
targetId: r.targetId,
|
|
34
|
+
type: r.type,
|
|
35
|
+
depth: r.depth,
|
|
36
|
+
doc: r.doc != null ? { title: r.doc.title } : null,
|
|
37
|
+
tags: getTagsFn(r.targetId),
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AA0BA;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAA+B,EAC/B,KAAc;IAEd,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC;QAC5C,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAyB,EACzB,SAAmC,EACnC,KAAc;IAEd,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC;QAC9C,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI;QAClD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC5B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MultiDirectedGraph as MultiDirectedGraphType } from "graphology";
|
|
2
|
+
import type { KnowledgeDB } from "./db.js";
|
|
3
|
+
export interface NodeAttributes {
|
|
4
|
+
title: string;
|
|
5
|
+
type: string | null;
|
|
6
|
+
date: string | null;
|
|
7
|
+
status: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface EdgeAttributes {
|
|
10
|
+
type: string;
|
|
11
|
+
}
|
|
12
|
+
export type KnowledgeGraph = MultiDirectedGraphType<NodeAttributes, EdgeAttributes>;
|
|
13
|
+
export declare class GraphBuilder {
|
|
14
|
+
private readonly db;
|
|
15
|
+
constructor(db: KnowledgeDB);
|
|
16
|
+
buildGraph(): KnowledgeGraph;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import graphology from "graphology";
|
|
2
|
+
const { MultiDirectedGraph } = graphology;
|
|
3
|
+
export class GraphBuilder {
|
|
4
|
+
db;
|
|
5
|
+
constructor(db) {
|
|
6
|
+
this.db = db;
|
|
7
|
+
}
|
|
8
|
+
buildGraph() {
|
|
9
|
+
const graph = new MultiDirectedGraph();
|
|
10
|
+
// Load all documents and add as nodes
|
|
11
|
+
const docs = this.db.db
|
|
12
|
+
.prepare("SELECT id, title, date, type, status FROM documents WHERE is_stub = 0 OR is_stub IS NULL")
|
|
13
|
+
.all();
|
|
14
|
+
for (const doc of docs) {
|
|
15
|
+
graph.addNode(doc.id, {
|
|
16
|
+
title: doc.title,
|
|
17
|
+
type: doc.type,
|
|
18
|
+
date: doc.date,
|
|
19
|
+
status: doc.status,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
// Load all relationships and add as directed edges
|
|
23
|
+
const rels = this.db.db
|
|
24
|
+
.prepare("SELECT source_id, target_id, type FROM relationships")
|
|
25
|
+
.all();
|
|
26
|
+
for (const rel of rels) {
|
|
27
|
+
// Defensively skip edges where source or target node does not exist
|
|
28
|
+
if (!graph.hasNode(rel.source_id) || !graph.hasNode(rel.target_id)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
graph.addDirectedEdge(rel.source_id, rel.target_id, { type: rel.type });
|
|
32
|
+
}
|
|
33
|
+
return graph;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=graph-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-builder.js","sourceRoot":"","sources":["../src/graph-builder.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAIpC,MAAM,EAAE,kBAAkB,EAAE,GAAG,UAAU,CAAC;AAe1C,MAAM,OAAO,YAAY;IACN,EAAE,CAAc;IAEjC,YAAY,EAAe;QACzB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,UAAU;QACR,MAAM,KAAK,GAAmB,IAAI,kBAAkB,EAAkC,CAAC;QAEvF,sCAAsC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE;aACpB,OAAO,CAAC,0FAA0F,CAAC;aACnG,GAAG,EAMJ,CAAC;QAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE;gBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,CAAC,CAAC;QACL,CAAC;QAED,mDAAmD;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE;aACpB,OAAO,CAAC,sDAAsD,CAAC;aAC/D,GAAG,EAIJ,CAAC;QAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,oEAAoE;YACpE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|