leangraph 1.1.1 → 1.1.3

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 (40) hide show
  1. package/dist/db.d.ts.map +1 -1
  2. package/dist/db.js +42 -3
  3. package/dist/db.js.map +1 -1
  4. package/dist/engine/hybrid-executor.d.ts +118 -0
  5. package/dist/engine/hybrid-executor.d.ts.map +1 -0
  6. package/dist/engine/hybrid-executor.js +205 -0
  7. package/dist/engine/hybrid-executor.js.map +1 -0
  8. package/dist/engine/index.d.ts +36 -0
  9. package/dist/engine/index.d.ts.map +1 -0
  10. package/dist/engine/index.js +34 -0
  11. package/dist/engine/index.js.map +1 -0
  12. package/dist/engine/memory-graph.d.ts +68 -0
  13. package/dist/engine/memory-graph.d.ts.map +1 -0
  14. package/dist/engine/memory-graph.js +176 -0
  15. package/dist/engine/memory-graph.js.map +1 -0
  16. package/dist/engine/query-planner.d.ts +62 -0
  17. package/dist/engine/query-planner.d.ts.map +1 -0
  18. package/dist/engine/query-planner.js +481 -0
  19. package/dist/engine/query-planner.js.map +1 -0
  20. package/dist/engine/subgraph-loader.d.ts +41 -0
  21. package/dist/engine/subgraph-loader.d.ts.map +1 -0
  22. package/dist/engine/subgraph-loader.js +172 -0
  23. package/dist/engine/subgraph-loader.js.map +1 -0
  24. package/dist/executor.d.ts +17 -0
  25. package/dist/executor.d.ts.map +1 -1
  26. package/dist/executor.js +286 -100
  27. package/dist/executor.js.map +1 -1
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +2 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/parser.d.ts +47 -3
  33. package/dist/parser.d.ts.map +1 -1
  34. package/dist/parser.js +228 -41
  35. package/dist/parser.js.map +1 -1
  36. package/dist/translator.d.ts +53 -0
  37. package/dist/translator.d.ts.map +1 -1
  38. package/dist/translator.js +1548 -183
  39. package/dist/translator.js.map +1 -1
  40. package/package.json +9 -3
@@ -0,0 +1,68 @@
1
+ /**
2
+ * In-memory graph structure for hybrid query execution.
3
+ * Optimized for traversal operations with O(1) node lookups
4
+ * and adjacency list access.
5
+ */
6
+ export interface MemoryNode {
7
+ id: string;
8
+ labels: string[];
9
+ properties: Record<string, unknown>;
10
+ }
11
+ export interface MemoryEdge {
12
+ id: string;
13
+ type: string;
14
+ sourceId: string;
15
+ targetId: string;
16
+ properties: Record<string, unknown>;
17
+ }
18
+ export interface Path {
19
+ nodes: MemoryNode[];
20
+ edges: MemoryEdge[];
21
+ }
22
+ export type Direction = "out" | "in" | "both";
23
+ /** Row format from SQLite nodes table */
24
+ export interface NodeRow {
25
+ id: string;
26
+ label: string;
27
+ properties: string;
28
+ }
29
+ /** Row format from SQLite edges table */
30
+ export interface EdgeRow {
31
+ id: string;
32
+ type: string;
33
+ source_id: string;
34
+ target_id: string;
35
+ properties: string;
36
+ }
37
+ export declare class MemoryGraph {
38
+ private nodes;
39
+ private outEdges;
40
+ private inEdges;
41
+ /**
42
+ * Build a MemoryGraph from SQLite row data.
43
+ */
44
+ static fromRows(nodeRows: NodeRow[], edgeRows: EdgeRow[]): MemoryGraph;
45
+ /**
46
+ * Get a node by ID. O(1) lookup.
47
+ */
48
+ getNode(id: string): MemoryNode | undefined;
49
+ /**
50
+ * Get outgoing edges from a node, optionally filtered by type.
51
+ */
52
+ getOutEdges(nodeId: string, type?: string): MemoryEdge[];
53
+ /**
54
+ * Get incoming edges to a node, optionally filtered by type.
55
+ */
56
+ getInEdges(nodeId: string, type?: string): MemoryEdge[];
57
+ /**
58
+ * Get neighboring nodes in a given direction, optionally filtered by edge type.
59
+ */
60
+ neighbors(nodeId: string, direction: Direction, type?: string): MemoryNode[];
61
+ /**
62
+ * Traverse variable-length paths from a starting node.
63
+ * Yields paths lazily using a generator for memory efficiency.
64
+ * Handles cycle detection to prevent infinite loops.
65
+ */
66
+ traversePaths(startId: string, edgeType: string | null, minDepth: number, maxDepth: number, direction: Direction): Generator<Path>;
67
+ }
68
+ //# sourceMappingURL=memory-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-graph.d.ts","sourceRoot":"","sources":["../../src/engine/memory-graph.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C,yCAAyC;AACzC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,OAAO,CAAwC;IAEvD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,WAAW;IA0CtE;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI3C;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAQxD;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAQvD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IA2B5E;;;;OAIG;IACF,aAAa,CACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACnB,SAAS,CAAC,IAAI,CAAC;CA2FnB"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * In-memory graph structure for hybrid query execution.
3
+ * Optimized for traversal operations with O(1) node lookups
4
+ * and adjacency list access.
5
+ */
6
+ export class MemoryGraph {
7
+ nodes = new Map();
8
+ outEdges = new Map();
9
+ inEdges = new Map();
10
+ /**
11
+ * Build a MemoryGraph from SQLite row data.
12
+ */
13
+ static fromRows(nodeRows, edgeRows) {
14
+ const graph = new MemoryGraph();
15
+ // Parse and index nodes
16
+ for (const row of nodeRows) {
17
+ const node = {
18
+ id: row.id,
19
+ labels: JSON.parse(row.label),
20
+ properties: JSON.parse(row.properties),
21
+ };
22
+ graph.nodes.set(node.id, node);
23
+ // Initialize adjacency lists
24
+ graph.outEdges.set(node.id, []);
25
+ graph.inEdges.set(node.id, []);
26
+ }
27
+ // Parse and index edges
28
+ for (const row of edgeRows) {
29
+ const edge = {
30
+ id: row.id,
31
+ type: row.type,
32
+ sourceId: row.source_id,
33
+ targetId: row.target_id,
34
+ properties: JSON.parse(row.properties),
35
+ };
36
+ // Add to outgoing edges of source
37
+ const outList = graph.outEdges.get(edge.sourceId);
38
+ if (outList) {
39
+ outList.push(edge);
40
+ }
41
+ // Add to incoming edges of target
42
+ const inList = graph.inEdges.get(edge.targetId);
43
+ if (inList) {
44
+ inList.push(edge);
45
+ }
46
+ }
47
+ return graph;
48
+ }
49
+ /**
50
+ * Get a node by ID. O(1) lookup.
51
+ */
52
+ getNode(id) {
53
+ return this.nodes.get(id);
54
+ }
55
+ /**
56
+ * Get outgoing edges from a node, optionally filtered by type.
57
+ */
58
+ getOutEdges(nodeId, type) {
59
+ const edges = this.outEdges.get(nodeId) ?? [];
60
+ if (type === undefined) {
61
+ return edges;
62
+ }
63
+ return edges.filter((e) => e.type === type);
64
+ }
65
+ /**
66
+ * Get incoming edges to a node, optionally filtered by type.
67
+ */
68
+ getInEdges(nodeId, type) {
69
+ const edges = this.inEdges.get(nodeId) ?? [];
70
+ if (type === undefined) {
71
+ return edges;
72
+ }
73
+ return edges.filter((e) => e.type === type);
74
+ }
75
+ /**
76
+ * Get neighboring nodes in a given direction, optionally filtered by edge type.
77
+ */
78
+ neighbors(nodeId, direction, type) {
79
+ const result = [];
80
+ const seen = new Set();
81
+ if (direction === "out" || direction === "both") {
82
+ for (const edge of this.getOutEdges(nodeId, type)) {
83
+ const node = this.nodes.get(edge.targetId);
84
+ if (node && !seen.has(node.id)) {
85
+ seen.add(node.id);
86
+ result.push(node);
87
+ }
88
+ }
89
+ }
90
+ if (direction === "in" || direction === "both") {
91
+ for (const edge of this.getInEdges(nodeId, type)) {
92
+ const node = this.nodes.get(edge.sourceId);
93
+ if (node && !seen.has(node.id)) {
94
+ seen.add(node.id);
95
+ result.push(node);
96
+ }
97
+ }
98
+ }
99
+ return result;
100
+ }
101
+ /**
102
+ * Traverse variable-length paths from a starting node.
103
+ * Yields paths lazily using a generator for memory efficiency.
104
+ * Handles cycle detection to prevent infinite loops.
105
+ */
106
+ *traversePaths(startId, edgeType, minDepth, maxDepth, direction) {
107
+ const startNode = this.nodes.get(startId);
108
+ if (!startNode) {
109
+ return;
110
+ }
111
+ // Handle minDepth = 0 case (include start node as a path)
112
+ if (minDepth === 0) {
113
+ yield { nodes: [startNode], edges: [] };
114
+ }
115
+ const initialEntry = {
116
+ nodeId: startId,
117
+ nodes: [startNode],
118
+ edges: [],
119
+ visitedEdges: new Set(),
120
+ };
121
+ const stack = [initialEntry];
122
+ while (stack.length > 0) {
123
+ const current = stack.pop();
124
+ const depth = current.edges.length;
125
+ // Get edges to traverse
126
+ const edgesToTraverse = [];
127
+ if (direction === "out" || direction === "both") {
128
+ const outEdges = this.getOutEdges(current.nodeId, edgeType ?? undefined);
129
+ edgesToTraverse.push(...outEdges);
130
+ }
131
+ if (direction === "in" || direction === "both") {
132
+ const inEdges = this.getInEdges(current.nodeId, edgeType ?? undefined);
133
+ edgesToTraverse.push(...inEdges);
134
+ }
135
+ // Explore each edge
136
+ for (const edge of edgesToTraverse) {
137
+ // Skip if edge already used in this path (cycle prevention)
138
+ if (current.visitedEdges.has(edge.id)) {
139
+ continue;
140
+ }
141
+ // Determine the target node based on direction
142
+ let targetId;
143
+ if (edge.sourceId === current.nodeId) {
144
+ targetId = edge.targetId;
145
+ }
146
+ else {
147
+ targetId = edge.sourceId;
148
+ }
149
+ const targetNode = this.nodes.get(targetId);
150
+ if (!targetNode) {
151
+ continue;
152
+ }
153
+ // Build new path
154
+ const newNodes = [...current.nodes, targetNode];
155
+ const newEdges = [...current.edges, edge];
156
+ const newVisited = new Set(current.visitedEdges);
157
+ newVisited.add(edge.id);
158
+ const newDepth = newEdges.length;
159
+ // Yield if within depth range
160
+ if (newDepth >= minDepth && newDepth <= maxDepth) {
161
+ yield { nodes: newNodes, edges: newEdges };
162
+ }
163
+ // Continue exploring if we haven't reached max depth
164
+ if (newDepth < maxDepth) {
165
+ stack.push({
166
+ nodeId: targetId,
167
+ nodes: newNodes,
168
+ edges: newEdges,
169
+ visitedEdges: newVisited,
170
+ });
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ //# sourceMappingURL=memory-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-graph.js","sourceRoot":"","sources":["../../src/engine/memory-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Query Planner - Analyzes Cypher AST to determine if a query
3
+ * can use the hybrid execution engine.
4
+ *
5
+ * Supports generalized pattern chains with:
6
+ * - N nodes (arbitrary chain length)
7
+ * - Multiple variable-length edges
8
+ * - Var-length edges at any position
9
+ */
10
+ import { Query, WhereCondition, NodePattern } from "../parser.js";
11
+ import { PatternChainParams } from "./hybrid-executor.js";
12
+ import { MemoryNode } from "./memory-graph.js";
13
+ export interface HybridAnalysisResult {
14
+ /** Whether the query is suitable for hybrid execution */
15
+ suitable: boolean;
16
+ /** Extracted parameters for HybridExecutor (if suitable) */
17
+ params?: PatternChainParams;
18
+ /** Reason why the query is not suitable (for debugging) */
19
+ reason?: string;
20
+ }
21
+ /**
22
+ * Analyze a parsed query to determine if it can use the hybrid executor.
23
+ * Returns extracted parameters if suitable, or a reason if not.
24
+ *
25
+ * Supports generalized pattern chains:
26
+ * (a)-[*]->(b)-[:R1]->(c)-[:R2]->(d) -- N nodes
27
+ * (a)-[*]->(b)-[*]->(c) -- multiple var-length
28
+ */
29
+ export declare function analyzeForHybrid(query: Query, params: Record<string, unknown>): HybridAnalysisResult;
30
+ /**
31
+ * Check if a query's structure matches a hybrid-compatible pattern.
32
+ *
33
+ * Supported patterns:
34
+ * (a:Label)-[*min..max]->(b:Label)-[:TYPE]->(c:Label) -- original
35
+ * (a)-[*]->(b)-[:R1]->(c)-[:R2]->(d) -- longer chains
36
+ * (a)-[*]->(b)-[*]->(c) -- multiple var-length
37
+ * (a)-[:R1]->(b)-[*]->(c) -- var-length anywhere
38
+ *
39
+ * Requirements:
40
+ * - No mutations (CREATE, SET, DELETE, MERGE)
41
+ * - Has RETURN clause
42
+ * - Exactly one MATCH clause
43
+ * - At least 1 relationship pattern
44
+ * - At least one variable-length edge
45
+ * - No relationship property predicates (not supported in hybrid)
46
+ * - All nodes must have labels (checked in analyzeForHybrid)
47
+ */
48
+ export declare function isHybridCompatiblePattern(query: Query): boolean;
49
+ /**
50
+ * Extract node information (label, properties) from a NodePattern.
51
+ */
52
+ export declare function extractNodeInfo(node: NodePattern, params: Record<string, unknown>): {
53
+ label: string;
54
+ properties: Record<string, unknown>;
55
+ } | null;
56
+ /**
57
+ * Convert a WHERE condition to a filter function for the middle node.
58
+ * Returns null if the condition references nodes other than the middle node,
59
+ * or if it contains unsupported expressions.
60
+ */
61
+ export declare function convertWhereToFilter(where: WhereCondition | undefined, middleVar: string, params: Record<string, unknown>): ((node: MemoryNode) => boolean) | null;
62
+ //# sourceMappingURL=query-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-planner.d.ts","sourceRoot":"","sources":["../../src/engine/query-planner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,KAAK,EAGL,cAAc,EACd,WAAW,EAIZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAuB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAa,MAAM,mBAAmB,CAAC;AAK1D,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,oBAAoB,CA8HtB;AAyHD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAuF/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAsB/D;AAuBD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,GAAG,SAAS,EACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,CAAC,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,GAAG,IAAI,CAOxC"}