grafio-mongo 1.0.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 (38) hide show
  1. package/.gitattributes +2 -0
  2. package/LICENSE +674 -0
  3. package/README.md +220 -0
  4. package/dist/MongoGraphFactory.d.ts +13 -0
  5. package/dist/MongoGraphFactory.d.ts.map +1 -0
  6. package/dist/MongoGraphFactory.js +33 -0
  7. package/dist/MongoGraphFactory.js.map +1 -0
  8. package/dist/MongoStorageProvider.d.ts +48 -0
  9. package/dist/MongoStorageProvider.d.ts.map +1 -0
  10. package/dist/MongoStorageProvider.js +417 -0
  11. package/dist/MongoStorageProvider.js.map +1 -0
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +7 -0
  15. package/dist/index.js.map +1 -0
  16. package/jest.config.js +27 -0
  17. package/package.json +41 -0
  18. package/src/MongoGraphFactory.ts +93 -0
  19. package/src/MongoStorageProvider.ts +719 -0
  20. package/src/index.ts +4 -0
  21. package/tests/EducationGraph.mongo.test.ts +33 -0
  22. package/tests/SocialGraph.mongo.test.ts +30 -0
  23. package/tests/graph/Graph.clear.mongo.test.ts +24 -0
  24. package/tests/graph/Graph.edge.mongo.test.ts +24 -0
  25. package/tests/graph/Graph.fromJSON.mongo.test.ts +24 -0
  26. package/tests/graph/Graph.index.mongo.test.ts +24 -0
  27. package/tests/graph/Graph.isDAG.mongo.test.ts +24 -0
  28. package/tests/graph/Graph.node.mongo.test.ts +24 -0
  29. package/tests/graph/Graph.properties.mongo.test.ts +24 -0
  30. package/tests/graph/Graph.serialization.mongo.test.ts +24 -0
  31. package/tests/graph/Graph.topologicalSort.mongo.test.ts +24 -0
  32. package/tests/graph/Graph.transaction.mongo.test.ts +24 -0
  33. package/tests/graph/Graph.traverse.mongo.test.ts +24 -0
  34. package/tests/graph/GraphToMermaid.mongo.test.ts +24 -0
  35. package/tests/storage/MongoGraphFactory.test.ts +102 -0
  36. package/tsconfig.json +21 -0
  37. package/tsconfig.perf.json +18 -0
  38. package/tsconfig.prod.json +11 -0
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # grafio-mongo
2
+
3
+ MongoDB storage backend for [grafio](https://github.com/witspry/grafio) — a graph database with pluggable storage architecture.
4
+
5
+ ## Overview
6
+
7
+ This package provides the MongoDB storage provider for grafio, extracted from the core project. It enables **persistent storage** for grafio graphs using MongoDB (>= 5.0.0), with optimized indexes for nodes and edges and native transaction support.
8
+
9
+ ## Features
10
+
11
+ - **MongoDB Backend** — Optional MongoDB backend (>= 5.0.0) with optimized indexes for nodes and edges
12
+ - **Multiple Graph Support** — via `graphId` partitioning (isolated graphs in one MongoDB instance)
13
+ - **Pluggable Storage** — implements the `IStorageProvider` interface from grafio
14
+ - **Native Transactions** — MongoDB sessions for atomic multi-operation updates
15
+ - **Graph Factories** — `MongoGraphFactory` for controlled instance creation
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install grafio-mongo mongodb
21
+
22
+ # peer dependencies
23
+ npm install grafio
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```typescript
29
+ import { MongoClient } from 'mongodb';
30
+ import { MongoGraphFactory } from 'grafio-mongo';
31
+
32
+ // Connect to MongoDB
33
+ const client = new MongoClient('mongodb://localhost:27017');
34
+ await client.connect();
35
+
36
+ const factory = new MongoGraphFactory(client.db('mydb'));
37
+
38
+ // Create indexes once at startup (idempotent — safe to call every time)
39
+ await factory.ensureIndexes();
40
+
41
+ // Get a graph scoped to a named partition
42
+ const graph = factory.forGraph('my-graph');
43
+
44
+ // Add nodes and edges
45
+ const alice = await graph.addNode('Person', { name: 'Alice' });
46
+ const bob = await graph.addNode('Person', { name: 'Bob' });
47
+ await graph.addEdge(alice.id, bob.id, 'KNOWS');
48
+
49
+ // Navigate the graph
50
+ const path = await graph.traverse(alice.id, bob.id, { edgeTypes: ['KNOWS'] });
51
+
52
+ // Caller manages the MongoClient lifecycle
53
+ await client.close();
54
+ ```
55
+
56
+ ## MongoGraphFactory
57
+
58
+ Factory class for creating MongoDB-backed Graph instances:
59
+
60
+ ```typescript
61
+ import { MongoGraphFactory } from 'grafio-mongo';
62
+
63
+ const factory = new MongoGraphFactory(db);
64
+ await factory.ensureIndexes();
65
+
66
+ const graph = factory.forGraph('my-graph');
67
+ // or with custom options
68
+ const graph2 = factory.forGraph('custom-graph', {
69
+ nodesCollection: 'my_nodes', // default: 'sgdb_nodes'
70
+ edgesCollection: 'my_edges', // default: 'sgdb_edges'
71
+ });
72
+ ```
73
+
74
+ ### Factory Options
75
+
76
+ | Option | Type | Default | Description |
77
+ |--------|------|---------|-------------|
78
+ | `nodesCollection` | `string` | `'sgdb_nodes'` | Collection name for nodes |
79
+ | `edgesCollection` | `string` | `'sgdb_edges'` | Collection name for edges |
80
+
81
+ ## Direct MongoStorageProvider Usage
82
+
83
+ For fine-grained control over collection names and graph partitioning:
84
+
85
+ ```typescript
86
+ import { MongoClient } from 'mongodb';
87
+ import { Graph, MongoStorageProvider } from 'grafio-mongo';
88
+
89
+ const client = new MongoClient('mongodb://localhost:27017');
90
+ await client.connect();
91
+
92
+ const provider = new MongoStorageProvider(client.db('mydb'), {
93
+ graphId: 'my-graph', // default: 'default' — partitions data by graph id
94
+ nodesCollection: 'my_nodes', // default: 'sgdb_nodes'
95
+ edgesCollection: 'my_edges', // default: 'sgdb_edges'
96
+ });
97
+
98
+ await provider.ensureIndexes();
99
+
100
+ const graph = new Graph(provider);
101
+ ```
102
+
103
+ ## Indexes
104
+
105
+ The `ensureIndexes()` method creates the following indexes for optimized queries:
106
+
107
+ ### Nodes Collection
108
+
109
+ | Index | Purpose |
110
+ |-------|---------|
111
+ | `{ graphId: 1, id: 1 }` unique | Fast node id lookups within a graph partition |
112
+ | `{ graphId: 1, type: 1 }` | `getNodesByType()` within a graph partition |
113
+ | `{ graphId: 1, properties: 1 }` | Property value lookups within a graph partition |
114
+
115
+ ### Edges Collection
116
+
117
+ | Index | Purpose |
118
+ |-------|---------|
119
+ | `{ graphId: 1, id: 1 }` unique | Fast edge id lookups within a graph partition |
120
+ | `{ graphId: 1, type: 1 }` | `getEdgesByType()` within a graph partition |
121
+ | `{ graphId: 1, sourceId: 1, type: 1 }` | Outgoing adjacency queries |
122
+ | `{ graphId: 1, targetId: 1, type: 1 }` | Incoming adjacency queries |
123
+
124
+ ## Transactions
125
+
126
+ MongoDB storage provider supports native transactions via MongoDB sessions:
127
+
128
+ ```typescript
129
+ import { Graph, GraphTransaction } from 'grafio';
130
+
131
+ const graph = factory.forGraph('my-graph');
132
+ const txn = graph.createTransaction();
133
+ await txn.begin();
134
+
135
+ try {
136
+ const alice = await graph.addNode('Person', { name: 'Alice' }, txn);
137
+ const bob = await graph.addNode('Person', { name: 'Bob' }, txn);
138
+ await graph.addEdge(alice.id, bob.id, 'KNOWS', {}, txn);
139
+ await txn.commit();
140
+ } catch (error) {
141
+ if (txn.isActive()) {
142
+ await txn.rollback();
143
+ }
144
+ throw error;
145
+ }
146
+ ```
147
+
148
+ **Note:** MongoDB storage provider requires a replica set for transaction support.
149
+
150
+ ### Transaction Lifecycle
151
+
152
+ - `begin()` — starts a new transaction
153
+ - `commit()` — applies all changes atomically (throws if transaction failed)
154
+ - `rollback()` — discards all changes
155
+ - `isFailed()` — returns true if a storage operation failed within the transaction
156
+ - `isActive()` — returns true if transaction is active and not failed
157
+
158
+ ## Graph Operations
159
+
160
+ All graph operations from grafio are available when using MongoDB storage. See the [grafio documentation](https://github.com/witspry/grafio) for the complete API reference.
161
+
162
+ ### Example Operations
163
+
164
+ ```typescript
165
+ const graph = factory.forGraph('my-graph');
166
+
167
+ // Node operations
168
+ const alice = await graph.addNode('Person', { name: 'Alice', age: 30 });
169
+ const bob = await graph.addNode('Person', { name: 'Bob' });
170
+ await graph.addEdge(alice.id, bob.id, 'KNOWS');
171
+
172
+ // Navigation
173
+ const parents = await graph.getParents(bob.id);
174
+ const children = await graph.getChildren(alice.id);
175
+
176
+ // Traversal
177
+ const path = await graph.traverse(alice.id, bob.id, { method: 'bfs' });
178
+
179
+ // Type filtering
180
+ const allPersons = await graph.getNodesByType('Person');
181
+
182
+ // Property queries
183
+ const adults = await graph.getNodesByProperty('age', 30);
184
+
185
+ // DAG check and topological sort
186
+ const isDag = await graph.isDAG();
187
+ const order = await graph.topologicalSort();
188
+
189
+ // Export/Import
190
+ const data = await graph.exportJSON();
191
+ await Graph.importJSON(data, new MongoStorageProvider(db, { graphId: 'restored' }));
192
+ ```
193
+
194
+ ## Development
195
+
196
+ ```bash
197
+ # Install dependencies
198
+ npm install
199
+
200
+ # Build TypeScript
201
+ npm run build
202
+
203
+ # Run tests
204
+ npm test
205
+
206
+ # Run tests with coverage
207
+ npm run test:coverage
208
+ ```
209
+
210
+ ## Testing
211
+
212
+ The test suite runs against the MongoDB backend using `mongodb-memory-server` for integration testing.
213
+
214
+ ### Test Structure
215
+
216
+ - `tests/graph/*.mongo.test.ts` — Graph operations via MongoDB provider
217
+ - `tests/EducationGraph.mongo.test.ts` — Education domain graph via MongoDB
218
+ - `tests/SocialGraph.mongo.test.ts` — Social network graph via MongoDB
219
+ - `tests/storage/MongoGraphFactory.test.ts` — Factory lifecycle tests
220
+ - `tests/storage/MongoStorageProvider.test.ts` — Provider unit tests
@@ -0,0 +1,13 @@
1
+ import type { Db } from 'mongodb';
2
+ import { type MongoStorageProviderOptions } from './MongoStorageProvider';
3
+ import { Graph, GraphData, IGraphFactory } from 'grafio';
4
+ type MongoGraphFactoryOptions = Omit<MongoStorageProviderOptions, 'graphId'>;
5
+ export declare class MongoGraphFactory implements IGraphFactory {
6
+ private readonly _db;
7
+ private readonly _opts;
8
+ constructor(db: Db, opts?: MongoGraphFactoryOptions);
9
+ ensureIndexes(): Promise<void>;
10
+ forGraph(graphId?: string): Graph;
11
+ fromGraphData(data: GraphData, graphId?: string): Promise<Graph>;
12
+ }
13
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoGraphFactory.d.ts","sourceRoot":"","sources":["../src/MongoGraphFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEzD;;GAEG;AACH,KAAK,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,EAAE,SAAS,CAAC,CAAC;AAE7E;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IAEjD;;;;;OAKG;gBACS,EAAE,EAAE,EAAE,EAAE,IAAI,GAAE,wBAA6B;IAKvD;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,GAAE,MAAkB,GAAG,KAAK;IAK5C;;;;;;;OAOG;IACG,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,MAAkB,GAAG,OAAO,CAAC,KAAK,CAAC;CAgBlF"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoGraphFactory = void 0;
4
+ const MongoStorageProvider_1 = require("./MongoStorageProvider");
5
+ const grafio_1 = require("grafio");
6
+ class MongoGraphFactory {
7
+ _db;
8
+ _opts;
9
+ constructor(db, opts = {}) {
10
+ this._db = db;
11
+ this._opts = opts;
12
+ }
13
+ async ensureIndexes() {
14
+ const probe = new MongoStorageProvider_1.MongoStorageProvider(this._db, { ...this._opts, graphId: 'default' });
15
+ await probe.ensureIndexes();
16
+ }
17
+ forGraph(graphId = 'default') {
18
+ const provider = new MongoStorageProvider_1.MongoStorageProvider(this._db, { ...this._opts, graphId });
19
+ return new grafio_1.Graph(provider);
20
+ }
21
+ async fromGraphData(data, graphId = 'default') {
22
+ const provider = new MongoStorageProvider_1.MongoStorageProvider(this._db, { ...this._opts, graphId });
23
+ const graph = new grafio_1.Graph(provider);
24
+ const filteredData = {
25
+ graphId,
26
+ nodes: data.graphId === undefined || data.graphId === graphId ? data.nodes : [],
27
+ edges: data.graphId === undefined || data.graphId === graphId ? data.edges : [],
28
+ };
29
+ await grafio_1.Graph.importJSON(filteredData, provider);
30
+ return graph;
31
+ }
32
+ }
33
+ exports.MongoGraphFactory = MongoGraphFactory;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoGraphFactory.js","sourceRoot":"","sources":["../src/MongoGraphFactory.ts"],"names":[],"mappings":";;;AACA,iEAGgC;AAChC,mCAAyD;AAOzD;;;;;;;;;;;;;;;GAeG;AACH,MAAa,iBAAiB;IACX,GAAG,CAAK;IACR,KAAK,CAA2B;IAEjD;;;;;OAKG;IACH,YAAY,EAAM,EAAE,OAAiC,EAAE;QACrD,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,IAAI,2CAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QACxF,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAkB,SAAS;QAClC,MAAM,QAAQ,GAAG,IAAI,2CAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAChF,OAAO,IAAI,cAAK,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CAAC,IAAe,EAAE,UAAkB,SAAS;QAC9D,MAAM,QAAQ,GAAG,IAAI,2CAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAChF,MAAM,KAAK,GAAG,IAAI,cAAK,CAAC,QAAQ,CAAC,CAAC;QAElC,qEAAqE;QACrE,oFAAoF;QACpF,+EAA+E;QAC/E,MAAM,YAAY,GAAc;YAC9B,OAAO;YACP,KAAK,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YAC/E,KAAK,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;SAChF,CAAC;QAEF,MAAM,cAAK,CAAC,UAAU,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAhED,8CAgEC"}
@@ -0,0 +1,48 @@
1
+ import type { Db } from 'mongodb';
2
+ import { IStorageProvider, NodeData, ITransactionHandle, EdgeData, GraphData } from 'grafio';
3
+ export interface MongoStorageProviderOptions {
4
+ graphId?: string;
5
+ nodesCollection?: string;
6
+ edgesCollection?: string;
7
+ batchSize?: number;
8
+ }
9
+ export declare class MongoStorageProvider implements IStorageProvider {
10
+ private readonly _nodes;
11
+ private readonly _edges;
12
+ private readonly _graphId;
13
+ private readonly _batchSize;
14
+ private readonly _client;
15
+ constructor(db: Db, opts?: MongoStorageProviderOptions);
16
+ ensureIndexes(): Promise<void>;
17
+ clear(): Promise<void>;
18
+ insertNode(node: NodeData, transaction?: ITransactionHandle): Promise<void>;
19
+ deleteNode(id: string, transaction?: ITransactionHandle): Promise<void>;
20
+ hasNode(id: string, transaction?: ITransactionHandle): Promise<boolean>;
21
+ getNode(id: string, transaction?: ITransactionHandle): Promise<NodeData | undefined>;
22
+ getAllNodes(limit?: number, transaction?: ITransactionHandle): Promise<NodeData[]>;
23
+ getNodesByType(type: string, transaction?: ITransactionHandle): Promise<NodeData[]>;
24
+ getNodesByProperty(key: string, value: unknown, nodeType?: string, transaction?: ITransactionHandle): Promise<NodeData[]>;
25
+ getEdgesByProperty(key: string, value: unknown, edgeType?: string, transaction?: ITransactionHandle): Promise<EdgeData[]>;
26
+ insertEdge(edge: EdgeData, transaction?: ITransactionHandle): Promise<void>;
27
+ deleteEdge(id: string, transaction?: ITransactionHandle): Promise<void>;
28
+ hasEdge(id: string, transaction?: ITransactionHandle): Promise<boolean>;
29
+ getEdge(id: string, transaction?: ITransactionHandle): Promise<EdgeData | undefined>;
30
+ getAllEdges(transaction?: ITransactionHandle): Promise<EdgeData[]>;
31
+ getEdgesByType(type: string, transaction?: ITransactionHandle): Promise<EdgeData[]>;
32
+ getEdgesBySource(nodeId: string, type?: string, transaction?: ITransactionHandle): Promise<EdgeData[]>;
33
+ getEdgesByTarget(nodeId: string, type?: string, transaction?: ITransactionHandle): Promise<EdgeData[]>;
34
+ exportJSON(): Promise<GraphData>;
35
+ importJSON(data: GraphData): Promise<void>;
36
+ createIndex(target: 'node' | 'edge', propertyKey: string, type?: string): Promise<void>;
37
+ addProperty(target: 'node' | 'edge', id: string, key: string, value: unknown, transaction?: ITransactionHandle): Promise<void>;
38
+ updateProperty(target: 'node' | 'edge', id: string, key: string, value: unknown, transaction?: ITransactionHandle): Promise<void>;
39
+ deleteProperty(target: 'node' | 'edge', id: string, key: string, transaction?: ITransactionHandle): Promise<void>;
40
+ clearProperties(target: 'node' | 'edge', id: string, transaction?: ITransactionHandle): Promise<void>;
41
+ supportsTransactions(): boolean;
42
+ beginTransaction(): Promise<ITransactionHandle>;
43
+ commitTransaction(handle: ITransactionHandle): Promise<void>;
44
+ rollbackTransaction(handle: ITransactionHandle): Promise<void>;
45
+ private _docToNode;
46
+ private _docToEdge;
47
+ private _isDuplicateKeyError;
48
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoStorageProvider.d.ts","sourceRoot":"","sources":["../src/MongoStorageProvider.ts"],"names":[],"mappings":"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"}