@atlaspack/graph
Advanced tools
Comparing version 3.2.1-canary.3565 to 3.2.1-canary.3566
@@ -271,3 +271,3 @@ "use strict"; | ||
*/ | ||
addEdge(from, to, type = 1) { | ||
addEdge(from, to, type = _Graph.NULL_EDGE_TYPE) { | ||
(0, _assert().default)(from < this.#nodes.nextId, `Node ${from} does not exist.`); | ||
@@ -320,3 +320,3 @@ (0, _assert().default)(to < this.#nodes.nextId, `Node ${to} does not exist.`); | ||
*/ | ||
hasEdge(from, to, type = 1) { | ||
hasEdge(from, to, type = _Graph.NULL_EDGE_TYPE) { | ||
let hasEdge = type => { | ||
@@ -340,3 +340,3 @@ let hash = this.#edges.hash(from, to, type); | ||
*/ | ||
removeEdge(from, to, type = 1) { | ||
removeEdge(from, to, type = _Graph.NULL_EDGE_TYPE) { | ||
let hash = this.#edges.hash(from, to, type); | ||
@@ -435,3 +435,3 @@ let edge = this.#edges.addressOf(hash, from, to, type); | ||
*/ | ||
getNodeIdsConnectedFrom(from, type = 1) { | ||
getNodeIdsConnectedFrom(from, type = _Graph.NULL_EDGE_TYPE) { | ||
let matches = node => type === _Graph.ALL_EDGE_TYPES || (Array.isArray(type) ? type.includes(this.#nodes.typeOf(node)) : type === this.#nodes.typeOf(node)); | ||
@@ -474,10 +474,15 @@ let nodes = []; | ||
} | ||
forEachNodeIdConnectedTo(to, fn) { | ||
forEachNodeIdConnectedTo(to, fn, type = _Graph.NULL_EDGE_TYPE) { | ||
const matches = node => type === _Graph.ALL_EDGE_TYPES || type === this.#nodes.typeOf(node); | ||
let node = this.#nodes.head(to); | ||
while (node !== null) { | ||
let edge = this.#nodes.firstIn(node); | ||
while (edge !== null) { | ||
let from = this.#edges.from(edge); | ||
fn(from); | ||
edge = this.#edges.nextIn(edge); | ||
if (matches(node)) { | ||
let edge = this.#nodes.firstIn(node); | ||
while (edge !== null) { | ||
let from = this.#edges.from(edge); | ||
if (fn(from)) { | ||
return; | ||
} | ||
edge = this.#edges.nextIn(edge); | ||
} | ||
} | ||
@@ -495,3 +500,3 @@ node = this.#nodes.next(node); | ||
*/ | ||
getNodeIdsConnectedTo(to, type = 1) { | ||
getNodeIdsConnectedTo(to, type = _Graph.NULL_EDGE_TYPE) { | ||
let matches = node => type === _Graph.ALL_EDGE_TYPES || (Array.isArray(type) ? type.includes(this.#nodes.typeOf(node)) : type === this.#nodes.typeOf(node)); | ||
@@ -498,0 +503,0 @@ let nodes = []; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.default = exports.ALL_EDGE_TYPES = void 0; | ||
exports.default = exports.NULL_EDGE_TYPE = exports.ALL_EDGE_TYPES = void 0; | ||
exports.mapVisitor = mapVisitor; | ||
@@ -20,2 +20,3 @@ var _types = require("./types"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const NULL_EDGE_TYPE = exports.NULL_EDGE_TYPE = 1; | ||
const ALL_EDGE_TYPES = exports.ALL_EDGE_TYPES = -1; | ||
@@ -75,3 +76,3 @@ | ||
} | ||
addEdge(from, to, type = 1) { | ||
addEdge(from, to, type = NULL_EDGE_TYPE) { | ||
if (Number(type) === 0) { | ||
@@ -88,10 +89,10 @@ throw new Error(`Edge type "${type}" not allowed`); | ||
} | ||
hasEdge(from, to, type = 1) { | ||
hasEdge(from, to, type = NULL_EDGE_TYPE) { | ||
return this.adjacencyList.hasEdge(from, to, type); | ||
} | ||
forEachNodeIdConnectedTo(to, fn) { | ||
forEachNodeIdConnectedTo(to, fn, type = NULL_EDGE_TYPE) { | ||
this._assertHasNodeId(to); | ||
this.adjacencyList.forEachNodeIdConnectedTo(to, fn); | ||
this.adjacencyList.forEachNodeIdConnectedTo(to, fn, type); | ||
} | ||
forEachNodeIdConnectedFrom(from, fn, type = ALL_EDGE_TYPES) { | ||
forEachNodeIdConnectedFrom(from, fn, type = NULL_EDGE_TYPE) { | ||
this._assertHasNodeId(from); | ||
@@ -103,7 +104,7 @@ this.adjacencyList.forEachNodeIdConnectedFromReverse(from, id => { | ||
} | ||
getNodeIdsConnectedTo(nodeId, type = 1) { | ||
getNodeIdsConnectedTo(nodeId, type = NULL_EDGE_TYPE) { | ||
this._assertHasNodeId(nodeId); | ||
return this.adjacencyList.getNodeIdsConnectedTo(nodeId, type); | ||
} | ||
getNodeIdsConnectedFrom(nodeId, type = 1) { | ||
getNodeIdsConnectedFrom(nodeId, type = NULL_EDGE_TYPE) { | ||
this._assertHasNodeId(nodeId); | ||
@@ -135,3 +136,3 @@ return this.adjacencyList.getNodeIdsConnectedFrom(nodeId, type); | ||
} | ||
removeEdges(nodeId, type = 1) { | ||
removeEdges(nodeId, type = NULL_EDGE_TYPE) { | ||
if (!this.hasNode(nodeId)) { | ||
@@ -144,3 +145,3 @@ return; | ||
} | ||
removeEdge(from, to, type = 1, removeOrphans = true) { | ||
removeEdge(from, to, type = NULL_EDGE_TYPE, removeOrphans = true) { | ||
if (!this.adjacencyList.hasEdge(from, to, type)) { | ||
@@ -153,3 +154,3 @@ throw new Error(`Edge from ${(0, _types.fromNodeId)(from)} to ${(0, _types.fromNodeId)(to)} not found!`); | ||
// Removes edge and node the edge is to if the node is orphaned | ||
_removeEdge(from, to, type = 1, removeOrphans = true) { | ||
_removeEdge(from, to, type = NULL_EDGE_TYPE, removeOrphans = true) { | ||
if (!this.adjacencyList.hasEdge(from, to, type)) { | ||
@@ -194,3 +195,3 @@ return; | ||
// Update a node's downstream nodes making sure to prune any orphaned branches | ||
replaceNodeIdsConnectedTo(fromNodeId, toNodeIds, replaceFilter, type = 1) { | ||
replaceNodeIdsConnectedTo(fromNodeId, toNodeIds, replaceFilter, type = NULL_EDGE_TYPE) { | ||
this._assertHasNodeId(fromNodeId); | ||
@@ -209,3 +210,3 @@ let outboundEdges = this.getNodeIdsConnectedFrom(fromNodeId, type); | ||
} | ||
traverse(visit, startNodeId, type = 1) { | ||
traverse(visit, startNodeId, type = NULL_EDGE_TYPE) { | ||
let enter = typeof visit === 'function' ? visit : visit.enter; | ||
@@ -225,3 +226,3 @@ if (type === ALL_EDGE_TYPES && enter && (typeof visit === 'function' || !visit.exit)) { | ||
} | ||
traverseAncestors(startNodeId, visit, type = 1) { | ||
traverseAncestors(startNodeId, visit, type = NULL_EDGE_TYPE) { | ||
return this.dfs({ | ||
@@ -228,0 +229,0 @@ visit, |
{ | ||
"name": "@atlaspack/graph", | ||
"version": "3.2.1-canary.3565+2b1e35dc3", | ||
"version": "3.2.1-canary.3566+9ccbb847b", | ||
"description": "Blazing fast, zero configuration web application bundler", | ||
@@ -19,6 +19,6 @@ "license": "(MIT OR Apache-2.0)", | ||
"dependencies": { | ||
"@atlaspack/feature-flags": "2.12.1-canary.3565+2b1e35dc3", | ||
"@atlaspack/feature-flags": "2.12.1-canary.3566+9ccbb847b", | ||
"nullthrows": "^1.1.1" | ||
}, | ||
"gitHead": "2b1e35dc3d51843fba13edcb958c01406ff355e4" | ||
"gitHead": "9ccbb847b43d122706b8ac52bb80c017176405da" | ||
} |
@@ -6,3 +6,8 @@ // @flow | ||
import {fromNodeId, toNodeId} from './types'; | ||
import {ALL_EDGE_TYPES, type NullEdgeType, type AllEdgeTypes} from './Graph'; | ||
import { | ||
ALL_EDGE_TYPES, | ||
NULL_EDGE_TYPE, | ||
type NullEdgeType, | ||
type AllEdgeTypes, | ||
} from './Graph'; | ||
import type {NodeId} from './types'; | ||
@@ -120,3 +125,3 @@ | ||
*/ | ||
export default class AdjacencyList<TEdgeType: number = 1> { | ||
export default class AdjacencyList<TEdgeType: number = NullEdgeType> { | ||
#nodes: NodeTypeMap<TEdgeType | NullEdgeType>; | ||
@@ -368,3 +373,3 @@ #edges: EdgeTypeMap<TEdgeType | NullEdgeType>; | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType = 1, | ||
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
): boolean { | ||
@@ -439,3 +444,6 @@ assert(from < this.#nodes.nextId, `Node ${from} does not exist.`); | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType | Array<TEdgeType | NullEdgeType> = 1, | ||
type: | ||
| TEdgeType | ||
| NullEdgeType | ||
| Array<TEdgeType | NullEdgeType> = NULL_EDGE_TYPE, | ||
): boolean { | ||
@@ -465,3 +473,3 @@ let hasEdge = (type: TEdgeType | NullEdgeType) => { | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType = 1, | ||
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
): void { | ||
@@ -576,3 +584,3 @@ let hash = this.#edges.hash(from, to, type); | ||
| NullEdgeType | ||
| Array<TEdgeType | NullEdgeType> = 1, | ||
| Array<TEdgeType | NullEdgeType> = NULL_EDGE_TYPE, | ||
): NodeId[] { | ||
@@ -628,10 +636,21 @@ let matches = (node) => | ||
forEachNodeIdConnectedTo(to: NodeId, fn: (nodeId: NodeId) => void) { | ||
forEachNodeIdConnectedTo( | ||
to: NodeId, | ||
fn: (nodeId: NodeId) => boolean | void, | ||
type: AllEdgeTypes | TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
) { | ||
const matches = (node) => | ||
type === ALL_EDGE_TYPES || type === this.#nodes.typeOf(node); | ||
let node = this.#nodes.head(to); | ||
while (node !== null) { | ||
let edge = this.#nodes.firstIn(node); | ||
while (edge !== null) { | ||
let from = this.#edges.from(edge); | ||
fn(from); | ||
edge = this.#edges.nextIn(edge); | ||
if (matches(node)) { | ||
let edge = this.#nodes.firstIn(node); | ||
while (edge !== null) { | ||
let from = this.#edges.from(edge); | ||
if (fn(from)) { | ||
return; | ||
} | ||
edge = this.#edges.nextIn(edge); | ||
} | ||
} | ||
@@ -655,3 +674,3 @@ node = this.#nodes.next(node); | ||
| NullEdgeType | ||
| Array<TEdgeType | NullEdgeType> = 1, | ||
| Array<TEdgeType | NullEdgeType> = NULL_EDGE_TYPE, | ||
): NodeId[] { | ||
@@ -658,0 +677,0 @@ let matches = (node) => |
@@ -16,3 +16,4 @@ // @flow strict-local | ||
export type NullEdgeType = 1; | ||
export type GraphOpts<TNode, TEdgeType: number = 1> = {| | ||
export const NULL_EDGE_TYPE: NullEdgeType = 1; | ||
export type GraphOpts<TNode, TEdgeType: number = NullEdgeType> = {| | ||
nodes?: Array<TNode | null>, | ||
@@ -24,3 +25,3 @@ adjacencyList?: SerializedAdjacencyList<TEdgeType>, | ||
export type SerializedGraph<TNode, TEdgeType: number = 1> = {| | ||
export type SerializedGraph<TNode, TEdgeType: number = NullEdgeType> = {| | ||
nodes: Array<TNode | null>, | ||
@@ -79,3 +80,3 @@ adjacencyList: SerializedAdjacencyList<TEdgeType>, | ||
export default class Graph<TNode, TEdgeType: number = 1> { | ||
export default class Graph<TNode, TEdgeType: number = NullEdgeType> { | ||
nodes: Array<TNode | null>; | ||
@@ -144,3 +145,3 @@ adjacencyList: AdjacencyList<TEdgeType>; | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType = 1, | ||
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
): boolean { | ||
@@ -165,3 +166,6 @@ if (Number(type) === 0) { | ||
to: NodeId, | ||
type?: TEdgeType | NullEdgeType | Array<TEdgeType | NullEdgeType> = 1, | ||
type?: | ||
| TEdgeType | ||
| NullEdgeType | ||
| Array<TEdgeType | NullEdgeType> = NULL_EDGE_TYPE, | ||
): boolean { | ||
@@ -171,6 +175,10 @@ return this.adjacencyList.hasEdge(from, to, type); | ||
forEachNodeIdConnectedTo(to: NodeId, fn: (nodeId: NodeId) => void) { | ||
forEachNodeIdConnectedTo( | ||
to: NodeId, | ||
fn: (nodeId: NodeId) => boolean | void, | ||
type: AllEdgeTypes | TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
) { | ||
this._assertHasNodeId(to); | ||
this.adjacencyList.forEachNodeIdConnectedTo(to, fn); | ||
this.adjacencyList.forEachNodeIdConnectedTo(to, fn, type); | ||
} | ||
@@ -181,3 +189,3 @@ | ||
fn: (nodeId: NodeId) => void, | ||
type: AllEdgeTypes | TEdgeType | NullEdgeType = ALL_EDGE_TYPES, | ||
type: AllEdgeTypes | TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
) { | ||
@@ -202,3 +210,3 @@ this._assertHasNodeId(from); | ||
| Array<TEdgeType | NullEdgeType> | ||
| AllEdgeTypes = 1, | ||
| AllEdgeTypes = NULL_EDGE_TYPE, | ||
): Array<NodeId> { | ||
@@ -216,3 +224,3 @@ this._assertHasNodeId(nodeId); | ||
| Array<TEdgeType | NullEdgeType> | ||
| AllEdgeTypes = 1, | ||
| AllEdgeTypes = NULL_EDGE_TYPE, | ||
): Array<NodeId> { | ||
@@ -248,3 +256,3 @@ this._assertHasNodeId(nodeId); | ||
removeEdges(nodeId: NodeId, type: TEdgeType | NullEdgeType = 1) { | ||
removeEdges(nodeId: NodeId, type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE) { | ||
if (!this.hasNode(nodeId)) { | ||
@@ -262,3 +270,3 @@ return; | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType = 1, | ||
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
removeOrphans: boolean = true, | ||
@@ -279,3 +287,3 @@ ) { | ||
to: NodeId, | ||
type: TEdgeType | NullEdgeType = 1, | ||
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
removeOrphans: boolean = true, | ||
@@ -336,3 +344,3 @@ ) { | ||
replaceFilter?: null | ((NodeId) => boolean), | ||
type?: TEdgeType | NullEdgeType = 1, | ||
type?: TEdgeType | NullEdgeType = NULL_EDGE_TYPE, | ||
): void { | ||
@@ -367,3 +375,3 @@ this._assertHasNodeId(fromNodeId); | ||
| Array<TEdgeType | NullEdgeType> | ||
| AllEdgeTypes = 1, | ||
| AllEdgeTypes = NULL_EDGE_TYPE, | ||
): ?TContext { | ||
@@ -402,3 +410,3 @@ let enter = typeof visit === 'function' ? visit : visit.enter; | ||
| Array<TEdgeType | NullEdgeType> | ||
| AllEdgeTypes = 1, | ||
| AllEdgeTypes = NULL_EDGE_TYPE, | ||
): ?TContext { | ||
@@ -405,0 +413,0 @@ return this.dfs({ |
@@ -10,2 +10,3 @@ // @flow strict-local | ||
import {toNodeId} from '../src/types'; | ||
import {ALL_EDGE_TYPES} from '../src/Graph'; | ||
@@ -310,2 +311,22 @@ describe('AdjacencyList', () => { | ||
it('stops traversal if the return value is true', () => { | ||
const graph = new AdjacencyList(); | ||
const a = graph.addNode(); | ||
const b = graph.addNode(); | ||
const c = graph.addNode(); | ||
const d = graph.addNode(); | ||
graph.addEdge(a, d); | ||
graph.addEdge(b, d); | ||
graph.addEdge(c, d); | ||
const nodeIds = []; | ||
graph.forEachNodeIdConnectedTo(d, (nodeId) => { | ||
nodeIds.push(nodeId); | ||
return true; | ||
}); | ||
assert.deepEqual(nodeIds, [a]); | ||
}); | ||
it('terminates if the graph is cyclic', () => { | ||
@@ -328,2 +349,40 @@ const graph = new AdjacencyList(); | ||
}); | ||
it('respects the edge type', () => { | ||
const graph = new AdjacencyList(); | ||
const a = graph.addNode(); | ||
const b = graph.addNode(); | ||
const c = graph.addNode(); | ||
graph.addEdge(a, b); | ||
graph.addEdge(c, b, 2); | ||
const nodeIds = []; | ||
graph.forEachNodeIdConnectedTo(b, (id) => { | ||
nodeIds.push(id); | ||
}); | ||
assert.deepEqual(nodeIds, [a]); | ||
}); | ||
it('iterates all edges if all edge type is provided', () => { | ||
const graph = new AdjacencyList(); | ||
const a = graph.addNode(); | ||
const b = graph.addNode(); | ||
const c = graph.addNode(); | ||
graph.addEdge(a, b); | ||
graph.addEdge(c, b, 2); | ||
const nodeIds = []; | ||
graph.forEachNodeIdConnectedTo( | ||
b, | ||
(id) => { | ||
nodeIds.push(id); | ||
}, | ||
ALL_EDGE_TYPES, | ||
); | ||
assert.deepEqual(nodeIds, [a, c]); | ||
}); | ||
}); | ||
@@ -330,0 +389,0 @@ |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
201510
5655