@apollo/query-graphs
Advanced tools
Comparing version 2.4.0-alpha.1 to 2.4.0
# CHANGELOG for `@apollo/query-graphs` | ||
## 2.4.0 | ||
### Patch Changes | ||
- Refactor the internal implementation of selection sets used by the query planner to decrease the code complexity and ([#2387](https://github.com/apollographql/federation/pull/2387)) | ||
improve query plan generation performance in many cases. | ||
- Optimises query plan generation for parts of queries that can statically be known to not cross across subgraphs ([#2449](https://github.com/apollographql/federation/pull/2449)) | ||
- Updated dependencies [[`260c357c`](https://github.com/apollographql/federation/commit/260c357c10b4cf560c66d11f85552036c2638b0b), [`7bc0f8e8`](https://github.com/apollographql/federation/commit/7bc0f8e814ea003802ed3761b5eeeb7137650b0c), [`1a555d98`](https://github.com/apollographql/federation/commit/1a555d98f2030814ebd5074269d035b7f298f71e), [`cab383b2`](https://github.com/apollographql/federation/commit/cab383b22d37bb6bc687b4d8cec6f5c22245f41f)]: | ||
- @apollo/federation-internals@2.4.0 | ||
## 2.4.0-alpha.1 | ||
@@ -15,2 +27,8 @@ ### Patch Changes | ||
## 2.3.4 | ||
### Patch Changes | ||
- Updated dependencies [[`6e2d24b5`](https://github.com/apollographql/federation/commit/6e2d24b5491914316b9930395817f0c3780f181a)]: | ||
- @apollo/federation-internals@2.3.4 | ||
## 2.3.3 | ||
@@ -17,0 +35,0 @@ ### Patch Changes |
@@ -0,1 +1,2 @@ | ||
import { SelectionSet } from "@apollo/federation-internals"; | ||
import { GraphPath, OpGraphPath, OpTrigger } from "./graphPath"; | ||
@@ -6,2 +7,3 @@ import { Edge, QueryGraph, RootVertex, Vertex } from "./querygraph"; | ||
readonly vertex: RV; | ||
readonly localSelections: readonly SelectionSet[] | undefined; | ||
private readonly triggerEquality; | ||
@@ -12,3 +14,6 @@ private readonly childs; | ||
static createOp<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV): OpPathTree<RV>; | ||
static createFromOpPaths<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, paths: OpGraphPath<RV>[]): OpPathTree<RV>; | ||
static createFromOpPaths<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, paths: { | ||
path: OpGraphPath<RV>; | ||
selection?: SelectionSet; | ||
}[]): OpPathTree<RV>; | ||
private static createFromPaths; | ||
@@ -23,2 +28,3 @@ static mergeAllOpTrees<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, trees: OpPathTree<RV>[]): OpPathTree<RV>; | ||
mergeIfNotEqual(other: PathTree<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge>; | ||
private mergeLocalSelectionsWith; | ||
merge(other: PathTree<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge>; | ||
@@ -25,0 +31,0 @@ private equalsSameRoot; |
@@ -28,5 +28,6 @@ "use strict"; | ||
class PathTree { | ||
constructor(graph, vertex, triggerEquality, childs) { | ||
constructor(graph, vertex, localSelections, triggerEquality, childs) { | ||
this.graph = graph; | ||
this.vertex = vertex; | ||
this.localSelections = localSelections; | ||
this.triggerEquality = triggerEquality; | ||
@@ -36,3 +37,3 @@ this.childs = childs; | ||
static create(graph, root, triggerEquality) { | ||
return new PathTree(graph, root, triggerEquality, []); | ||
return new PathTree(graph, root, undefined, triggerEquality, []); | ||
} | ||
@@ -44,5 +45,5 @@ static createOp(graph, root) { | ||
(0, federation_internals_1.assert)(paths.length > 0, `Should compute on empty paths`); | ||
return this.createFromPaths(graph, opTriggerEquality, root, paths.map(p => p[Symbol.iterator]())); | ||
return this.createFromPaths(graph, opTriggerEquality, root, paths.map(({ path, selection }) => ({ path: path[Symbol.iterator](), selection }))); | ||
} | ||
static createFromPaths(graph, triggerEquality, currentVertex, paths) { | ||
static createFromPaths(graph, triggerEquality, currentVertex, pathAndSelections) { | ||
const maxEdges = graph.outEdgesCount(currentVertex); | ||
@@ -54,5 +55,9 @@ const forEdgeIndex = new Array(maxEdges + 1); | ||
let totalChilds = 0; | ||
for (const path of paths) { | ||
const iterResult = path.next(); | ||
let localSelections = undefined; | ||
for (const ps of pathAndSelections) { | ||
const iterResult = ps.path.next(); | ||
if (iterResult.done) { | ||
if (ps.selection) { | ||
localSelections = localSelections ? localSelections.concat(ps.selection) : [ps.selection]; | ||
} | ||
continue; | ||
@@ -69,3 +74,3 @@ } | ||
if (triggerIdx < 0) { | ||
forIndex.push([trigger, conditions, [path]]); | ||
forIndex.push([trigger, conditions, [ps]]); | ||
totalChilds++; | ||
@@ -78,3 +83,3 @@ } | ||
const newPaths = existing[2]; | ||
newPaths.push(path); | ||
newPaths.push(ps); | ||
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths]; | ||
@@ -85,3 +90,3 @@ } | ||
order[currentOrder++] = idx; | ||
forEdgeIndex[idx] = [[trigger, conditions, [path]]]; | ||
forEdgeIndex[idx] = [[trigger, conditions, [ps]]]; | ||
totalChilds++; | ||
@@ -97,3 +102,3 @@ } | ||
const values = forEdgeIndex[edgeIndex]; | ||
for (const [trigger, conditions, subPaths] of values) { | ||
for (const [trigger, conditions, subPathAndSelections] of values) { | ||
childs[idx++] = { | ||
@@ -103,3 +108,3 @@ index, | ||
conditions, | ||
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPaths) | ||
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections) | ||
}; | ||
@@ -109,3 +114,3 @@ } | ||
(0, federation_internals_1.assert)(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`); | ||
return new PathTree(graph, currentVertex, triggerEquality, childs); | ||
return new PathTree(graph, currentVertex, localSelections, triggerEquality, childs); | ||
} | ||
@@ -120,5 +125,14 @@ static mergeAllOpTrees(graph, root, trees) { | ||
const order = new Array(maxEdges + 1); | ||
let localSelections = undefined; | ||
let currentOrder = 0; | ||
let totalChilds = 0; | ||
for (const tree of trees) { | ||
if (tree.localSelections) { | ||
if (localSelections) { | ||
localSelections = localSelections.concat(tree.localSelections); | ||
} | ||
else { | ||
localSelections = tree.localSelections; | ||
} | ||
} | ||
for (const child of tree.childs) { | ||
@@ -169,3 +183,3 @@ const idx = child.index === null ? maxEdges : child.index; | ||
(0, federation_internals_1.assert)(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`); | ||
return new PathTree(graph, currentVertex, triggerEquality, childs); | ||
return new PathTree(graph, currentVertex, localSelections, triggerEquality, childs); | ||
} | ||
@@ -215,2 +229,7 @@ childCount() { | ||
} | ||
mergeLocalSelectionsWith(other) { | ||
return this.localSelections | ||
? (other.localSelections ? this.localSelections.concat(other.localSelections) : this.localSelections) | ||
: other.localSelections; | ||
} | ||
merge(other) { | ||
@@ -228,2 +247,3 @@ if (this === other) { | ||
} | ||
const localSelections = this.mergeLocalSelectionsWith(other); | ||
const mergeIndexes = new Array(other.childs.length); | ||
@@ -253,3 +273,3 @@ let countToAdd = 0; | ||
(0, federation_internals_1.assert)(addIdx === newSize, () => `Expected ${newSize} childs but only got ${addIdx}`); | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree(this.graph, this.vertex, localSelections, this.triggerEquality, newChilds); | ||
} | ||
@@ -276,4 +296,5 @@ equalsSameRoot(that) { | ||
} | ||
const localSelections = this.mergeLocalSelectionsWith(other); | ||
const newChilds = this.childs.concat(other.childs); | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree(this.graph, this.vertex, localSelections, this.triggerEquality, newChilds); | ||
} | ||
@@ -297,3 +318,3 @@ mergePath(path) { | ||
conditions: conditions, | ||
tree: new PathTree(this.graph, currentVertex, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
tree: new PathTree(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
}]; | ||
@@ -312,7 +333,7 @@ } | ||
const currentVertex = edge ? edge.tail : this.vertex; | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, this.childs.concat({ | ||
return new PathTree(this.graph, this.vertex, undefined, this.triggerEquality, this.childs.concat({ | ||
index: edgeIndex, | ||
trigger: trigger, | ||
conditions: conditions, | ||
tree: new PathTree(this.graph, currentVertex, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
tree: new PathTree(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
})); | ||
@@ -329,3 +350,3 @@ } | ||
}; | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree(this.graph, this.vertex, undefined, this.triggerEquality, newChilds); | ||
} | ||
@@ -332,0 +353,0 @@ } |
@@ -10,2 +10,3 @@ import { MultiMap, NamedType, Schema, SchemaRootKind, SelectionSet, MapWithCachedArrays } from '@apollo/federation-internals'; | ||
readonly source: string; | ||
hasReachableCrossSubgraphEdges: boolean; | ||
constructor(index: number, type: NamedType, source: string); | ||
@@ -40,3 +41,3 @@ toString(): string; | ||
readonly vertices: Vertex[]; | ||
private readonly adjacencies; | ||
private readonly _outEdges; | ||
private readonly typesToVertices; | ||
@@ -46,3 +47,3 @@ private readonly rootVertices; | ||
readonly nonTrivialFollowupEdges: (edge: Edge) => readonly Edge[]; | ||
constructor(name: string, vertices: Vertex[], adjacencies: Edge[][], typesToVertices: MultiMap<string, number>, rootVertices: MapWithCachedArrays<SchemaRootKind, RootVertex>, sources: ReadonlyMap<string, Schema>); | ||
constructor(name: string, vertices: Vertex[], _outEdges: Edge[][], typesToVertices: MultiMap<string, number>, rootVertices: MapWithCachedArrays<SchemaRootKind, RootVertex>, sources: ReadonlyMap<string, Schema>); | ||
verticesCount(): number; | ||
@@ -49,0 +50,0 @@ edgesCount(): number; |
@@ -23,2 +23,3 @@ "use strict"; | ||
this.source = source; | ||
this.hasReachableCrossSubgraphEdges = false; | ||
} | ||
@@ -49,3 +50,2 @@ toString() { | ||
constructor(index, head, tail, transition, conditions) { | ||
var _a; | ||
this.index = index; | ||
@@ -55,3 +55,3 @@ this.head = head; | ||
this.transition = transition; | ||
this._conditions = (_a = conditions === null || conditions === void 0 ? void 0 : conditions.clone()) === null || _a === void 0 ? void 0 : _a.freeze(); | ||
this._conditions = conditions; | ||
} | ||
@@ -88,6 +88,4 @@ get conditions() { | ||
this._conditions = this._conditions | ||
? this._conditions.clone() | ||
: new federation_internals_1.SelectionSet(this.head.type); | ||
this._conditions.mergeIn(newConditions); | ||
this._conditions.freeze(); | ||
? new federation_internals_1.SelectionSetUpdates().add(this._conditions).add(newConditions).toSelectionSet(this._conditions.parentType) | ||
: newConditions; | ||
} | ||
@@ -103,6 +101,6 @@ isKeyOrRootTypeEdgeToSelf() { | ||
class QueryGraph { | ||
constructor(name, vertices, adjacencies, typesToVertices, rootVertices, sources) { | ||
constructor(name, vertices, _outEdges, typesToVertices, rootVertices, sources) { | ||
this.name = name; | ||
this.vertices = vertices; | ||
this.adjacencies = adjacencies; | ||
this._outEdges = _outEdges; | ||
this.typesToVertices = typesToVertices; | ||
@@ -117,3 +115,3 @@ this.rootVertices = rootVertices; | ||
edgesCount() { | ||
return this.adjacencies.reduce((acc, v) => acc + v.length, 0); | ||
return this._outEdges.reduce((acc, v) => acc + v.length, 0); | ||
} | ||
@@ -130,10 +128,10 @@ rootKinds() { | ||
outEdges(vertex, includeKeyAndRootTypeEdgesToSelf = false) { | ||
const allEdges = this.adjacencies[vertex.index]; | ||
const allEdges = this._outEdges[vertex.index]; | ||
return includeKeyAndRootTypeEdgesToSelf ? allEdges : allEdges.filter((e) => !e.isKeyOrRootTypeEdgeToSelf()); | ||
} | ||
outEdgesCount(vertex) { | ||
return this.adjacencies[vertex.index].length; | ||
return this._outEdges[vertex.index].length; | ||
} | ||
outEdge(vertex, edgeIndex) { | ||
return this.adjacencies[vertex.index][edgeIndex]; | ||
return this._outEdges[vertex.index][edgeIndex]; | ||
} | ||
@@ -353,4 +351,4 @@ isTerminal(vertex) { | ||
const [v, selectionSet] = stack.pop(); | ||
for (const selection of selectionSet.selections(true)) { | ||
const element = selection.element(); | ||
for (const selection of selectionSet.selectionsInReverseOrder()) { | ||
const element = selection.element; | ||
if (element.kind == 'Field') { | ||
@@ -403,3 +401,4 @@ const fieldDef = element.definition; | ||
this.vertices = verticesCount ? new Array(verticesCount) : []; | ||
this.adjacencies = verticesCount ? new Array(verticesCount) : []; | ||
this.outEdges = verticesCount ? new Array(verticesCount) : []; | ||
this.inEdges = verticesCount ? new Array(verticesCount) : []; | ||
} | ||
@@ -414,6 +413,26 @@ verticesForType(typeName) { | ||
addEdge(head, tail, transition, conditions) { | ||
const edges = this.adjacencies[head.index]; | ||
const edge = new Edge(edges.length, head, tail, transition, conditions); | ||
edges.push(edge); | ||
const headOutEdges = this.outEdges[head.index]; | ||
const tailInEdges = this.inEdges[tail.index]; | ||
const edge = new Edge(headOutEdges.length, head, tail, transition, conditions); | ||
headOutEdges.push(edge); | ||
tailInEdges.push(edge); | ||
if (head.source !== tail.source) { | ||
this.markInEdgesHasReachingCrossSubgraphEdge(head); | ||
} | ||
} | ||
markInEdgesHasReachingCrossSubgraphEdge(from) { | ||
if (from.hasReachableCrossSubgraphEdges) { | ||
return; | ||
} | ||
const stack = [from]; | ||
while (stack.length > 0) { | ||
const v = stack.pop(); | ||
v.hasReachableCrossSubgraphEdges = true; | ||
for (const edge of this.inEdges[v.index]) { | ||
if (edge.head.source === edge.tail.source && !edge.head.hasReachableCrossSubgraphEdges) { | ||
stack.push(edge.head); | ||
} | ||
} | ||
} | ||
} | ||
createNewVertex(type, source, schema, index) { | ||
@@ -428,3 +447,4 @@ if (!index) { | ||
this.typesToVertices.add(type.name, index); | ||
this.adjacencies[index] = []; | ||
this.outEdges[index] = []; | ||
this.inEdges[index] = []; | ||
if (!this.sources.has(source)) { | ||
@@ -446,3 +466,3 @@ this.sources.set(source, schema); | ||
this.rootVertices.set(kind, rootVertex); | ||
const rootEdges = this.adjacencies[vertex.index]; | ||
const rootEdges = this.outEdges[vertex.index]; | ||
for (let i = 0; i < rootEdges.length; i++) { | ||
@@ -475,10 +495,11 @@ rootEdges[i] = rootEdges[i].withNewHead(rootVertex); | ||
edge(head, index) { | ||
return this.adjacencies[head.index][index]; | ||
return this.outEdges[head.index][index]; | ||
} | ||
edges(head) { | ||
return this.adjacencies[head.index]; | ||
return this.outEdges[head.index]; | ||
} | ||
makeCopy(vertex) { | ||
const newVertex = this.createNewVertex(vertex.type, vertex.source, this.sources.get(vertex.source)); | ||
for (const edge of this.adjacencies[vertex.index]) { | ||
newVertex.hasReachableCrossSubgraphEdges = vertex.hasReachableCrossSubgraphEdges; | ||
for (const edge of this.outEdges[vertex.index]) { | ||
this.addEdge(newVertex, edge.tail, edge.transition, edge.conditions); | ||
@@ -490,3 +511,5 @@ } | ||
const newEdge = new Edge(edge.index, edge.head, newTail, edge.transition, edge.conditions); | ||
this.adjacencies[edge.head.index][edge.index] = newEdge; | ||
this.outEdges[edge.head.index][edge.index] = newEdge; | ||
this.inEdges[edge.tail.index] = this.inEdges[edge.tail.index].filter((e) => e !== edge); | ||
this.inEdges[newTail.index].push(newEdge); | ||
return newEdge; | ||
@@ -503,3 +526,3 @@ } | ||
build(name) { | ||
return new QueryGraph(name, this.vertices, this.adjacencies, this.typesToVertices, this.rootVertices, this.sources); | ||
return new QueryGraph(name, this.vertices, this.outEdges, this.typesToVertices, this.rootVertices, this.sources); | ||
} | ||
@@ -506,0 +529,0 @@ } |
{ | ||
"name": "@apollo/query-graphs", | ||
"version": "2.4.0-alpha.1", | ||
"version": "2.4.0", | ||
"description": "Apollo Federation library to work with 'query graphs'", | ||
@@ -26,3 +26,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@apollo/federation-internals": "2.4.0-alpha.1", | ||
"@apollo/federation-internals": "2.4.0", | ||
"deep-equal": "^2.0.5", | ||
@@ -29,0 +29,0 @@ "ts-graphviz": "^1.5.4", |
@@ -1,2 +0,2 @@ | ||
import { arrayEquals, assert, copyWitNewLength } from "@apollo/federation-internals"; | ||
import { arrayEquals, assert, copyWitNewLength, SelectionSet } from "@apollo/federation-internals"; | ||
import { GraphPath, OpGraphPath, OpTrigger, PathIterator } from "./graphPath"; | ||
@@ -39,2 +39,7 @@ import { Edge, QueryGraph, RootVertex, isRootVertex, Vertex } from "./querygraph"; | ||
type IterAndSelection<TTrigger, TNullEdge extends null | never> = { | ||
path: PathIterator<TTrigger, TNullEdge>, | ||
selection?: SelectionSet, | ||
} | ||
export class PathTree<TTrigger, RV extends Vertex = Vertex, TNullEdge extends null | never = never> { | ||
@@ -44,2 +49,3 @@ private constructor( | ||
readonly vertex: RV, | ||
readonly localSelections: readonly SelectionSet[] | undefined, | ||
private readonly triggerEquality: (t1: TTrigger, t2: TTrigger) => boolean, | ||
@@ -55,3 +61,3 @@ private readonly childs: Child<TTrigger, Vertex, TNullEdge>[], | ||
): PathTree<TTrigger, RV, TNullEdge> { | ||
return new PathTree(graph, root, triggerEquality, []); | ||
return new PathTree(graph, root, undefined, triggerEquality, []); | ||
} | ||
@@ -63,3 +69,7 @@ | ||
static createFromOpPaths<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, paths: OpGraphPath<RV>[]): OpPathTree<RV> { | ||
static createFromOpPaths<RV extends Vertex = Vertex>( | ||
graph: QueryGraph, | ||
root: RV, | ||
paths: { path: OpGraphPath<RV>, selection?: SelectionSet }[] | ||
): OpPathTree<RV> { | ||
assert(paths.length > 0, `Should compute on empty paths`); | ||
@@ -71,3 +81,3 @@ | ||
root, | ||
paths.map(p => p[Symbol.iterator]()) | ||
paths.map(({path, selection}) => ({ path: path[Symbol.iterator](), selection })) | ||
); | ||
@@ -80,7 +90,7 @@ } | ||
currentVertex: RV, | ||
paths: PathIterator<TTrigger, TNullEdge>[] | ||
pathAndSelections: IterAndSelection<TTrigger, TNullEdge>[] | ||
): PathTree<TTrigger, RV, TNullEdge> { | ||
const maxEdges = graph.outEdgesCount(currentVertex); | ||
// We store 'null' edges at `maxEdges` index | ||
const forEdgeIndex: [TTrigger, OpPathTree | null, PathIterator<TTrigger, TNullEdge>[]][][] = new Array(maxEdges + 1); | ||
const forEdgeIndex: [TTrigger, OpPathTree | null, IterAndSelection<TTrigger, TNullEdge>[]][][] = new Array(maxEdges + 1); | ||
const newVertices: Vertex[] = new Array(maxEdges); | ||
@@ -90,5 +100,9 @@ const order: number[] = new Array(maxEdges + 1); | ||
let totalChilds = 0; | ||
for (const path of paths) { | ||
const iterResult = path.next(); | ||
let localSelections: SelectionSet[] | undefined = undefined; | ||
for (const ps of pathAndSelections) { | ||
const iterResult = ps.path.next(); | ||
if (iterResult.done) { | ||
if (ps.selection) { | ||
localSelections = localSelections ? localSelections.concat(ps.selection) : [ps.selection]; | ||
} | ||
continue; | ||
@@ -105,3 +119,3 @@ } | ||
if (triggerIdx < 0) { | ||
forIndex.push([trigger, conditions, [path]]); | ||
forIndex.push([trigger, conditions, [ps]]); | ||
totalChilds++; | ||
@@ -113,3 +127,3 @@ } else { | ||
const newPaths = existing[2]; | ||
newPaths.push(path); | ||
newPaths.push(ps); | ||
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths]; | ||
@@ -121,3 +135,3 @@ // Note that as we merge, we don't create a new child | ||
order[currentOrder++] = idx; | ||
forEdgeIndex[idx] = [[trigger, conditions, [path]]]; | ||
forEdgeIndex[idx] = [[trigger, conditions, [ps]]]; | ||
totalChilds++; | ||
@@ -134,3 +148,3 @@ } | ||
const values = forEdgeIndex[edgeIndex]; | ||
for (const [trigger, conditions, subPaths] of values) { | ||
for (const [trigger, conditions, subPathAndSelections] of values) { | ||
childs[idx++] = { | ||
@@ -140,3 +154,3 @@ index, | ||
conditions, | ||
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPaths) | ||
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections) | ||
}; | ||
@@ -146,3 +160,3 @@ } | ||
assert(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`); | ||
return new PathTree<TTrigger, RV, TNullEdge>(graph, currentVertex, triggerEquality, childs); | ||
return new PathTree<TTrigger, RV, TNullEdge>(graph, currentVertex, localSelections, triggerEquality, childs); | ||
} | ||
@@ -166,5 +180,14 @@ | ||
const order: number[] = new Array(maxEdges + 1); | ||
let localSelections: readonly SelectionSet[] | undefined = undefined; | ||
let currentOrder = 0; | ||
let totalChilds = 0; | ||
for (const tree of trees) { | ||
if (tree.localSelections) { | ||
if (localSelections) { | ||
localSelections = localSelections.concat(tree.localSelections); | ||
} else { | ||
localSelections = tree.localSelections; | ||
} | ||
} | ||
for (const child of tree.childs) { | ||
@@ -216,3 +239,3 @@ const idx = child.index === null ? maxEdges : child.index; | ||
assert(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`); | ||
return new PathTree<TTrigger, RV, TNullEdge>(graph, currentVertex, triggerEquality, childs); | ||
return new PathTree<TTrigger, RV, TNullEdge>(graph, currentVertex, localSelections, triggerEquality, childs); | ||
} | ||
@@ -268,2 +291,8 @@ | ||
private mergeLocalSelectionsWith(other: PathTree<TTrigger, RV, TNullEdge>): readonly SelectionSet[] | undefined { | ||
return this.localSelections | ||
? (other.localSelections ? this.localSelections.concat(other.localSelections) : this.localSelections) | ||
: other.localSelections; | ||
} | ||
merge(other: PathTree<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge> { | ||
@@ -284,2 +313,4 @@ // If we somehow end up trying to merge a tree with itself, let's not waste work on it. | ||
const localSelections = this.mergeLocalSelectionsWith(other); | ||
const mergeIndexes: number[] = new Array(other.childs.length); | ||
@@ -310,3 +341,3 @@ let countToAdd = 0; | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree(this.graph, this.vertex, localSelections, this.triggerEquality, newChilds); | ||
} | ||
@@ -340,4 +371,6 @@ | ||
} | ||
const localSelections = this.mergeLocalSelectionsWith(other); | ||
const newChilds = this.childs.concat(other.childs); | ||
return new PathTree(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree(this.graph, this.vertex, localSelections, this.triggerEquality, newChilds); | ||
} | ||
@@ -364,3 +397,3 @@ | ||
conditions: conditions, | ||
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
}]; | ||
@@ -383,2 +416,3 @@ } | ||
this.vertex, | ||
undefined, | ||
this.triggerEquality, | ||
@@ -389,3 +423,3 @@ this.childs.concat({ | ||
conditions: conditions, | ||
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements)) | ||
}) | ||
@@ -402,3 +436,3 @@ ); | ||
}; | ||
return new PathTree<TTrigger, RV, TNullEdge>(this.graph, this.vertex, this.triggerEquality, newChilds); | ||
return new PathTree<TTrigger, RV, TNullEdge>(this.graph, this.vertex, undefined, this.triggerEquality, newChilds); | ||
} | ||
@@ -405,0 +439,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
575058
7786
1
+ Added@apollo/federation-internals@2.4.0(transitive)
+ Added@types/uuid@9.0.8(transitive)
- Removed@apollo/federation-internals@2.4.0-alpha.1(transitive)