simple-graph-query 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.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # simple-graph-query
2
+
3
+ **simple-graph-query** is a lightweight query engine for navigating and extracting tuples from finite graphs using a relational logic inspired by Alloy. It runs entirely client-side and supports a small, composable query language based on set comprehension and relational navigation.
4
+
5
+ ## What It Does
6
+
7
+ This tool lets you run queries like:
8
+
9
+ ```
10
+ { x, y : Person | y in x.friend* }
11
+ { x, y : Person | x.friend = y }
12
+ { x : Person | x in x.friend* }
13
+ ```
14
+
15
+ over JSON-encoded graphs like:
16
+
17
+ ```json
18
+ {
19
+ "nodes": [
20
+ { "id": "a", "type": "Person" },
21
+ { "id": "b", "type": "Person" },
22
+ { "id": "c", "type": "Person" }
23
+ ],
24
+ "edges": [
25
+ { "from": "a", "to": "b", "label": "friend" },
26
+ { "from": "b", "to": "c", "label": "friend" }
27
+ ]
28
+ }
29
+ ```
30
+
31
+ And returns results like:
32
+
33
+ ```json
34
+ [
35
+ ["a", "b"],
36
+ ["a", "c"],
37
+ ["b", "c"]
38
+ ]
39
+ ```
40
+
41
+ ## What Logic Does It Support
42
+
43
+ `simple-graph-query` evaluates first-order relational queries over finite graph structures. Specifically:
44
+
45
+ - Typed variables: `{ x, y : Person | ... }`
46
+ - Set comprehension: `{ tuple | condition }`
47
+ - Relational navigation: `x.friend`, `x.friend.friend`
48
+ - Equality: `x.friend = y`
49
+ - Membership: `y in x.friend`
50
+ - Transitive closure: `x.friend*`
51
+
52
+ This is a subset of Alloy-style relational logic, evaluated over a fixed graph structure, with results returned as sets of tuples.
53
+
54
+ ## Getting Started
55
+
56
+ 1. Clone or unzip the repository.
57
+ 2. Open `public/index.html` in your browser.
58
+ 3. Paste a query like `{ x, y : Person | y in x.friend* }`.
59
+ 4. Click Run and view the results.
60
+
61
+ ## Project Structure
62
+
63
+ - `src/` – parser, evaluator, and AST
64
+ - `examples/graph.json` – sample graph data
65
+ - `public/index.html` – minimal UI to run queries
66
+ - `runQuery(graph, query)` – main API
67
+
68
+ ## TODO
69
+
70
+ - Support for `and`, `!=`, `no`, `some`
71
+ - Regex-style navigation (`friend|coworker`)
72
+ - Type checking and improved error handling
73
+
package/dist/bundle.js ADDED
@@ -0,0 +1 @@
1
+ !function(t,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.SimpleGraphQuery=r():t.SimpleGraphQuery=r()}(this,()=>(()=>{"use strict";var t={d:(r,e)=>{for(var n in e)t.o(e,n)&&!t.o(r,n)&&Object.defineProperty(r,n,{enumerable:!0,get:e[n]})},o:(t,r)=>Object.prototype.hasOwnProperty.call(t,r),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},r={};t.r(r),t.d(r,{default:()=>u,runQuery:()=>n});var e=function(){function t(t,r){this.result=t,this.expression=r}return t.prototype.prettyPrint=function(){return JSON.stringify(this.result,null,2)},t.prototype.noResult=function(){return Array.isArray(this.result)?0===this.result.length:"object"==typeof this.result&&"error"in this.result},t.prototype.singleResult=function(){if(Array.isArray(this.result)&&1===this.result.length&&1===this.result[0].length)return this.result[0][0];throw new Error("Result is not a singleton")},t.prototype.selectedAtoms=function(){return Array.isArray(this.result)?this.result.filter(function(t){return 1===t.length}).map(function(t){return String(t[0])}):[]},t.prototype.selectedTwoples=function(){return Array.isArray(this.result)?this.result.filter(function(t){return 2===t.length}).map(function(t){return[String(t[0]),String(t[1])]}):[]},t.prototype.selectedTuplesAll=function(){return Array.isArray(this.result)?this.result.map(function(t){return t.map(String)}):[]},t.prototype.isError=function(){return"object"==typeof this.result&&"error"in this.result},t.prototype.isSingleton=function(){return!!Array.isArray(this.result)&&1===this.result.length&&1===this.result[0].length},t.prototype.getExpression=function(){return this.expression},t.prototype.getRawResult=function(){return this.result},t}();function n(t,r){for(var e,n=function(t){var r=t.match(/\{\s*(.*?)\s*:\s*(\w+)\s*\|\s*(.*?)\s*\}/);if(!r)throw new Error("Parse error");r[0];var e=r[1],n=r[2],i=r[3];return{vars:e.split(",").map(function(t){return t.trim()}),type:n,condition:i}}(r),o=n.vars,s=n.type,u=n.condition,l=t.nodes.filter(function(t){return t.type===s}).map(function(t){return t.id}),a=[],p=0,f=l;p<f.length;p++)for(var c=f[p],h=0,y=l;h<y.length;h++){var g=y[h];i(u,((e={})[o[0]]=c,e[o[1]]=g,e),t)&&a.push([c,g])}return a}function i(t,r,e){return t.includes("=")?function(t,r,e){var n=t.split("=").map(function(t){return t.trim()}),i=n[0],s=n[1],u=o(i,r,e),l=o(s,r,e).values().next().value;return"string"==typeof l&&u.has(l)}(t,r,e):!!t.includes("in")&&function(t,r,e){var n=t.split("in").map(function(t){return t.trim()}),i=n[0],o=n[1],u=r[i],l=o.split("."),a=l[l.length-1].endsWith("*"),p=l[l.length-1].replace("*",""),f=a?s(u,p,e):function(t,r,e){return new Set(e.edges.filter(function(e){return e.from===t&&e.label===r}).map(function(t){return t.to}))}(u,p,e);return f.has(r[l[0]])}(t,r,e)}function o(t,r,e){if(t.includes(".")){var n=t.replace("*","").split("."),i=n[0],o=n[1],u=r[i];return"string"==typeof u?s(u,o,e):new Set}var l=r[t];return"string"==typeof l?new Set([l]):new Set}function s(t,r,e){for(var n=new Set,i=[t];i.length;){var o=i.pop();if(!n.has(o)){n.add(o);for(var s=0,u=e.edges;s<u.length;s++){var l=u[s];l.from!==o||l.label!==r||n.has(l.to)||i.push(l.to)}}}return n}const u=function(){function t(){this.context=null,this.graph=null}return t.prototype.initialize=function(t){this.context=t,t.processedData&&Array.isArray(t.processedData.nodes)&&Array.isArray(t.processedData.edges)?this.graph=t.processedData:this.graph=null},t.prototype.isReady=function(){return!!this.graph},t.prototype.evaluate=function(t,r){if(!this.graph)throw new Error("Evaluator not initialized");try{var i=n(this.graph,t);return new e(i,t)}catch(r){return new e({error:{message:r.message}},t)}},t}();return r})());
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "simple-graph-query",
3
+ "version": "1.0.0",
4
+ "description": "A simple graph query library bundled for CDN use.",
5
+ "main": "dist/bundle.js",
6
+ "files": [
7
+ "dist/"
8
+ ],
9
+ "scripts": {
10
+ "build": "webpack --mode production",
11
+ "dev": "webpack --mode development --watch"
12
+ },
13
+ "author": "Siddhartha Prasad",
14
+ "license": "MIT",
15
+ "devDependencies": {
16
+ "typescript": "^5.0.0",
17
+ "webpack": "^5.0.0",
18
+ "webpack-cli": "^5.0.0",
19
+ "ts-loader": "^9.0.0"
20
+ }
21
+ }