gcyphrq 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/engine/cypher-engine.d.ts +39 -0
- package/dist/engine/cypher-engine.d.ts.map +1 -0
- package/dist/engine/cypher-parser.d.ts +3 -0
- package/dist/engine/cypher-parser.d.ts.map +1 -0
- package/dist/graph.d.ts +24 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/index.js +5816 -0
- package/dist/indexes.d.ts +38 -0
- package/dist/indexes.d.ts.map +1 -0
- package/dist/lib.d.ts +189 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +1455 -0
- package/dist/types/cypher.d.ts +139 -0
- package/dist/types/cypher.d.ts.map +1 -0
- package/docs/404.md +11 -0
- package/docs/_config.yml +42 -0
- package/docs/_includes/footer.html +6 -0
- package/docs/_includes/head.html +13 -0
- package/docs/_includes/nav.html +23 -0
- package/docs/_layouts/default.html +20 -0
- package/docs/assets/cypher-highlight.js +171 -0
- package/docs/assets/favicon.svg +4 -0
- package/docs/assets/main.css +416 -0
- package/docs/cli.md +115 -0
- package/docs/examples.md +223 -0
- package/docs/getting-started.md +158 -0
- package/docs/index.md +89 -0
- package/docs/library-api.md +618 -0
- package/docs/query-guide.md +302 -0
- package/docs/skill.md +219 -0
- package/examples/README.md +187 -0
- package/examples/cloud-infra.json +199 -0
- package/examples/social-graph.json +11 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pascal Le Levier
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# gcyphrq
|
|
2
|
+
|
|
3
|
+
A Cypher graph query engine for in-memory graphs built on [Graphology](https://graphology.github.io/).
|
|
4
|
+
|
|
5
|
+
Available as a **CLI tool** and as a **library** for Node.js / TypeScript projects.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Cypher query engine** — supports `MATCH`, `OPTIONAL MATCH`, `WITH`, `RETURN`, `CREATE`, `SET`, `DELETE`
|
|
10
|
+
- **Variable-length paths** — e.g. `-[r:FRIEND*1..3]->`
|
|
11
|
+
- **Aggregations** — `count()`, `sum()`, `avg()`, `min()`, `max()` with implicit grouping via `WITH`
|
|
12
|
+
- **Directional filtering** — `->`, `<-`, `-`
|
|
13
|
+
- **Library or CLI** — use as a dependency in your project or run from the terminal
|
|
14
|
+
- **TypeScript support** — full type declarations shipped with the package
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Install dependencies
|
|
20
|
+
npm install
|
|
21
|
+
|
|
22
|
+
# Build the project
|
|
23
|
+
npm run build
|
|
24
|
+
|
|
25
|
+
# Link globally so `gcyphrq` is available everywhere
|
|
26
|
+
npm link
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Load a graph from a JSON file
|
|
33
|
+
gcyphrq -g examples/social-graph.json -e 'MATCH (u:User) RETURN u'
|
|
34
|
+
|
|
35
|
+
# Pipe a graph from stdin
|
|
36
|
+
cat my-graph.json | gcyphrq -g - -e 'MATCH (u:User) RETURN u'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Usage: gcyphrq [options]
|
|
43
|
+
|
|
44
|
+
Options:
|
|
45
|
+
-e, --expr <query> Cypher query expression (required)
|
|
46
|
+
-g, --graph <file> Path to a JSON graph file (or "-" to read from stdin)
|
|
47
|
+
-h, --help Show this help message
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Graph File Format
|
|
51
|
+
|
|
52
|
+
Graphs are described as JSON files with two arrays:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"nodes": [
|
|
57
|
+
{ "id": "alice", "label": "User", "name": "Alice" }
|
|
58
|
+
],
|
|
59
|
+
"edges": [
|
|
60
|
+
{ "source": "alice", "target": "bob", "type": "FRIEND" }
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This format follows the [Graphology](https://graphology.github.io/) project's JSON representation for graphs.
|
|
66
|
+
|
|
67
|
+
See the [`examples/`](examples/) directory for sample graphs.
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
📖 **[Full documentation](https://plelevier.github.io/gcyphrq/)** — Getting Started, CLI Reference, Query Guide, Library API, and Examples
|
|
72
|
+
|
|
73
|
+
Local docs (source):
|
|
74
|
+
- **[Library API](docs/library-api.md)** — how to use gcyphrq as a library (Node.js / TypeScript)
|
|
75
|
+
- **[Query Guide](docs/query-guide.md)** — full Cypher syntax reference, supported features, and query examples
|
|
76
|
+
- **[Example Graphs](examples/README.md)** — graph file format and available examples
|
|
77
|
+
|
|
78
|
+
## Using as a Library
|
|
79
|
+
|
|
80
|
+
Install gcyphrq as a dependency:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm install gcyphrq
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### One-shot query
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { executeQuery } from 'gcyphrq';
|
|
90
|
+
|
|
91
|
+
const results = executeQuery(graphData, 'MATCH (u:User) RETURN u.name');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Multiple queries on the same graph
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { createGraph, GraphEngine, parseCypher } from 'gcyphrq';
|
|
98
|
+
|
|
99
|
+
const graph = createGraph(graphData);
|
|
100
|
+
const engine = new GraphEngine(graph);
|
|
101
|
+
|
|
102
|
+
const users = engine.execute(parseCypher('MATCH (u:User) RETURN u.name'));
|
|
103
|
+
const counts = engine.execute(parseCypher('MATCH (u:User) RETURN count(u)'));
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Building a graph programmatically
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { Graph, GraphEngine, parseCypher } from 'gcyphrq';
|
|
110
|
+
|
|
111
|
+
const graph = new Graph();
|
|
112
|
+
graph.addNode('alice', { label: 'User', name: 'Alice' });
|
|
113
|
+
graph.addNode('bob', { label: 'User', name: 'Bob' });
|
|
114
|
+
graph.addEdge('alice', 'bob', { type: 'FRIEND' });
|
|
115
|
+
|
|
116
|
+
const engine = new GraphEngine(graph);
|
|
117
|
+
const results = engine.execute(parseCypher('MATCH (u:User) RETURN u.name'));
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
See the [Library API documentation](https://plelevier.github.io/gcyphrq/library-api/) for the full reference.
|
|
121
|
+
|
|
122
|
+
## Running without installing
|
|
123
|
+
|
|
124
|
+
You can also run the tool directly from the source without a global install:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npx tsx src/index.ts -g examples/social-graph.json -e 'MATCH (u:User) RETURN u'
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Testing
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm test
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Benchmarking
|
|
137
|
+
|
|
138
|
+
The `bench.ts` script measures query performance with and without pre-computed indexes:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Default: 5 queries against examples/cloud-infra.json
|
|
142
|
+
npx tsx bench.ts
|
|
143
|
+
|
|
144
|
+
# Different graph
|
|
145
|
+
npx tsx bench.ts -g examples/social-graph.json
|
|
146
|
+
|
|
147
|
+
# Custom queries
|
|
148
|
+
npx tsx bench.ts -q 'MATCH (s:Service) RETURN s' 'MATCH (n) RETURN count(n) AS total'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
See the [Benchmark documentation](docs/benchmark.md) for details on output format and interpretation.
|
|
152
|
+
|
|
153
|
+
## AI Agent Skill
|
|
154
|
+
|
|
155
|
+
This project includes a [skill](skills/gcyphrq/SKILL.md) that teaches AI agents how to use `gcyphrq` — supported Cypher features, query patterns, limitations, and ready-made examples against the bundled `cloud-infra.json` graph.
|
|
156
|
+
|
|
157
|
+
Install the skill so your AI agent knows how to query your graphs without you having to explain the syntax every time.
|
|
158
|
+
|
|
159
|
+
### pi
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
ln -s $(pwd)/skills/gcyphrq ~/.pi/agent/skills/gcyphrq
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The skill is auto-discovered on next invocation.
|
|
166
|
+
|
|
167
|
+
### Claude Code
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
ln -s $(pwd)/skills/gcyphrq ~/.claude/skills/gcyphrq
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The skill is auto-discovered on next invocation.
|
|
174
|
+
|
|
175
|
+
### OpenCode
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
ln -s $(pwd)/skills/gcyphrq ~/.opencode/skills/gcyphrq
|
|
179
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AdvancedCypherAST, ResultRow, GraphIndexes } from '../types/cypher';
|
|
2
|
+
import type { GraphInstance } from '../graph';
|
|
3
|
+
export declare class AdvancedCypherGraphologyEngine {
|
|
4
|
+
private graph;
|
|
5
|
+
private indexes;
|
|
6
|
+
constructor(graph: GraphInstance, indexes?: GraphIndexes);
|
|
7
|
+
/**
|
|
8
|
+
* MAIN ENTRY POINT
|
|
9
|
+
* Sequentially executes query stages and formats the return projection.
|
|
10
|
+
*/
|
|
11
|
+
execute(ast: AdvancedCypherAST): ResultRow[];
|
|
12
|
+
/**
|
|
13
|
+
* Resolve node IDs matching a pattern using indexes when available.
|
|
14
|
+
* Falls back to full-graph scan when indexes are absent.
|
|
15
|
+
*/
|
|
16
|
+
private getMatchingNodeIds;
|
|
17
|
+
private executeMatch;
|
|
18
|
+
/**
|
|
19
|
+
* Build a neighbor iterator using the edge-type adjacency index when available.
|
|
20
|
+
* Falls back to graph iteration for untyped edges or missing indexes.
|
|
21
|
+
*/
|
|
22
|
+
private buildNeighborGetter;
|
|
23
|
+
private executeWith;
|
|
24
|
+
private computeAggregations;
|
|
25
|
+
private executeWrite;
|
|
26
|
+
private executeReturn;
|
|
27
|
+
private evaluateExpression;
|
|
28
|
+
private evaluateWhere;
|
|
29
|
+
private applyOrderByToContexts;
|
|
30
|
+
/**
|
|
31
|
+
* Compare two values for sorting. Handles nulls, numbers, strings, booleans.
|
|
32
|
+
* null < boolean < number < string < object
|
|
33
|
+
* Mixed-type coercion differs from Neo4j (which throws). Here we stringify
|
|
34
|
+
* for pragmatic compatibility in exploratory queries.
|
|
35
|
+
*/
|
|
36
|
+
private compareValues;
|
|
37
|
+
private matchNodeCriteria;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=cypher-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cypher-engine.d.ts","sourceRoot":"","sources":["../../src/engine/cypher-engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAcjB,SAAS,EACT,YAAY,EAEb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0D9C,qBAAa,8BAA8B;IACzC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAA2B;gBAE9B,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,YAAY;IAKxD;;;OAGG;IACI,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,SAAS,EAAE;IAsBnD;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAwE1B,OAAO,CAAC,YAAY;IA6IpB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAqE3B,OAAO,CAAC,WAAW;IAyDnB,OAAO,CAAC,mBAAmB;IAoE3B,OAAO,CAAC,YAAY;IAoEpB,OAAO,CAAC,aAAa;IA8DrB,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,sBAAsB;IAsB9B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,iBAAiB;CAQ1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cypher-parser.d.ts","sourceRoot":"","sources":["../../src/engine/cypher-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAalB,MAAM,iBAAiB,CAAC;AAozBzB,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAuD5D"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface GraphInstance {
|
|
2
|
+
addNode(id: string, attrs?: Record<string, unknown>): void;
|
|
3
|
+
addEdge(a: string, b: string, attrs?: Record<string, unknown>): void;
|
|
4
|
+
getNodeAttributes(id: string): Record<string, unknown>;
|
|
5
|
+
getEdgeAttributes(id: string): Record<string, unknown>;
|
|
6
|
+
filterNodes(fn: (id: string, attrs: Record<string, unknown>) => boolean): string[];
|
|
7
|
+
forEachOutboundEdge(id: string, cb: (e: string, a: Record<string, unknown>, s: string, t: string) => void): void;
|
|
8
|
+
forEachInboundEdge(id: string, cb: (e: string, a: Record<string, unknown>, s: string, t: string) => void): void;
|
|
9
|
+
/**
|
|
10
|
+
* Iterate edges incident to a specific node, or all edges when no node ID is given.
|
|
11
|
+
* (Wraps Graphology's `forEachEdge` which accepts an optional node parameter.)
|
|
12
|
+
*/
|
|
13
|
+
forEachEdge(id: string, cb: (e: string, a: Record<string, unknown>, s: string, t: string) => void): void;
|
|
14
|
+
forEachEdge(cb: (e: string, a: Record<string, unknown>, s: string, t: string) => void): void;
|
|
15
|
+
setNodeAttribute(id: string, attr: string, value: unknown): void;
|
|
16
|
+
hasNode(id: string): boolean;
|
|
17
|
+
dropNode(id: string): void;
|
|
18
|
+
order: number;
|
|
19
|
+
}
|
|
20
|
+
declare const Graph: {
|
|
21
|
+
new (): GraphInstance;
|
|
22
|
+
};
|
|
23
|
+
export { Graph };
|
|
24
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,WAAW,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,MAAM,EAAE,CAAC;IACnF,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACjH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAChH;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7F,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACjE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,QAAA,MAAM,KAAK,EAA6B;IAAE,QAAQ,aAAa,CAAA;CAAE,CAAC;AAkClE,OAAO,EAAE,KAAK,EAAE,CAAC"}
|