simple-graph-query 2.7.0 → 2.7.2

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.
@@ -48626,10 +48626,19 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
48626
48626
  // Convert numeric and boolean strings to their actual types
48627
48627
  relationAtoms = relationAtoms.map((tuple) => tuple.map((value) => this.isConvertibleToNumber(value) ? Number(value) : value));
48628
48628
  relationAtoms = relationAtoms.map((tuple) => tuple.map((value) => this.isConvertibleToBoolean(value) ? this.convertToBoolean(value) : value));
48629
- this.relationCache.set(relation.name, relationAtoms);
48630
- // Build index for this relation: first element -> all tuples starting with that element
48629
+ // Relation NAMES are not unique — only the qualified id (`Sig<:label`) is.
48630
+ // e.g. `open util/ordering[A]` and `open util/ordering[B]` both expose a field
48631
+ // named `Next` (`A/Ord<:Next` and `B/Ord<:Next`). A bare-name reference must
48632
+ // resolve to the UNION of every relation sharing that name; keying by name and
48633
+ // overwriting silently erases all but the last. https://github.com/sidprasad/simple-graph-query/issues/55
48634
+ const existing = this.relationCache.get(relation.name);
48635
+ this.relationCache.set(relation.name, existing ? existing.concat(relationAtoms) : relationAtoms);
48636
+ }
48637
+ // Build first-element indexes from the merged (union'd) tuples, so an index
48638
+ // never reflects only a subset of a name's relations.
48639
+ for (const [name, tuples] of this.relationCache.entries()) {
48631
48640
  const relationIndex = new Map();
48632
- for (const tuple of relationAtoms) {
48641
+ for (const tuple of tuples) {
48633
48642
  if (tuple.length > 0) {
48634
48643
  const key = tuple[0];
48635
48644
  if (!relationIndex.has(key)) {
@@ -48638,7 +48647,7 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
48638
48647
  relationIndex.get(key).push(tuple);
48639
48648
  }
48640
48649
  }
48641
- this.relationIndexCache.set(relation.name, relationIndex);
48650
+ this.relationIndexCache.set(name, relationIndex);
48642
48651
  }
48643
48652
  }
48644
48653
  //helper function
@@ -50821,10 +50830,17 @@ const UNKNOWN = { kind: "unknown" };
50821
50830
  class SchemaInfo {
50822
50831
  constructor(schema) {
50823
50832
  this.typesById = new Map(schema.getTypes().map((t) => [t.id, t]));
50824
- this.relationsByName = new Map(schema.getRelations().map((r) => [r.name, r]));
50833
+ this.relationsByName = new Map();
50834
+ for (const r of schema.getRelations()) {
50835
+ const existing = this.relationsByName.get(r.name);
50836
+ if (existing)
50837
+ existing.push(r);
50838
+ else
50839
+ this.relationsByName.set(r.name, [r]);
50840
+ }
50825
50841
  }
50826
50842
  getType(id) { return this.typesById.get(id); }
50827
- getRelation(name) { return this.relationsByName.get(name); }
50843
+ getRelations(name) { return this.relationsByName.get(name) ?? []; }
50828
50844
  // A ⊆ B when B is in A's lineage. `IType.types` is the lineage in ascending
50829
50845
  // order, conventionally starting with the type itself.
50830
50846
  isSubtypeOf(a, b) {
@@ -50965,7 +50981,7 @@ class ForgeExprStaticAnalyzer extends AbstractParseTreeVisitor_1.AbstractParseTr
50965
50981
  if (!this.schema)
50966
50982
  return undefined;
50967
50983
  for (const name of names) {
50968
- if (this.schema.getType(name) || this.schema.getRelation(name)) {
50984
+ if (this.schema.getType(name) || this.schema.getRelations(name).length > 0) {
50969
50985
  return {
50970
50986
  kind: "ill-typed",
50971
50987
  reason: `cannot bind variable named '${name}': it is a reserved schema ` +
@@ -51746,11 +51762,26 @@ class ForgeExprStaticAnalyzer extends AbstractParseTreeVisitor_1.AbstractParseTr
51746
51762
  const t = this.schema.getType(id);
51747
51763
  if (t)
51748
51764
  return { kind: "typed", arity: 1, columnTypes: [t.id] };
51749
- const r = this.schema.getRelation(id);
51750
- if (r) {
51751
- const cols = r.types;
51765
+ const rels = this.schema.getRelations(id);
51766
+ if (rels.length === 1) {
51767
+ const cols = rels[0].types;
51752
51768
  return { kind: "typed", arity: cols.length, columnTypes: cols };
51753
51769
  }
51770
+ if (rels.length > 1) {
51771
+ // A bare name denotes the union of every relation sharing it. Different
51772
+ // arities have no single typing, so stay UNKNOWN. When arities agree,
51773
+ // keep the arity; keep per-column types only where every relation agrees
51774
+ // (otherwise omit, so downstream disjointness checks soundly skip rather
51775
+ // than fire on a widened column).
51776
+ const arity = rels[0].types.length;
51777
+ if (rels.every((r) => r.types.length === arity)) {
51778
+ const cols = rels[0].types.map((col, i) => rels.every((r) => r.types[i] === col) ? col : undefined);
51779
+ const allKnown = cols.every((c) => c !== undefined);
51780
+ return allKnown
51781
+ ? { kind: "typed", arity, columnTypes: cols }
51782
+ : { kind: "typed", arity };
51783
+ }
51784
+ }
51754
51785
  }
51755
51786
  return UNKNOWN;
51756
51787
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-graph-query",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "TypeScript evaluator for Forge expressions with browser-compatible UMD bundle",
5
5
  "main": "dist/simple-graph-query.bundle.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,10 +33,15 @@
33
33
  "prepublishOnly": "npm run build:full",
34
34
  "serve": "python3 -m http.server 8080",
35
35
  "test": "jest",
36
- "antlr4ts": "cd src/forge-antlr && antlr4ts -visitor ForgeLexer.g4 Forge.g4 && cd ../.."
36
+ "antlr4ts": "cd src/forge-antlr && antlr4ts -visitor ForgeLexer.g4 Forge.g4 && cd ../..",
37
+ "release:tag": "git diff-index --quiet HEAD -- || (echo 'Working tree is dirty, commit first' && exit 1) && git tag v$npm_package_version && git push origin v$npm_package_version"
37
38
  },
38
39
  "author": "Siddhartha Prasad",
39
40
  "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/sidprasad/simple-graph-query.git"
44
+ },
40
45
  "devDependencies": {
41
46
  "@types/jest": "^29.5.14",
42
47
  "antlr4ts-cli": "^0.5.0-alpha.4",