@siteimprove/alfa-graph 0.89.5
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/CHANGELOG.md +157 -0
- package/dist/graph.d.ts +63 -0
- package/dist/graph.js +211 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +40 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# @siteimprove/alfa-graph
|
|
2
|
+
|
|
3
|
+
## 0.89.3
|
|
4
|
+
|
|
5
|
+
## 0.89.2
|
|
6
|
+
|
|
7
|
+
### Patch Changes
|
|
8
|
+
|
|
9
|
+
- **Changed:** Trying to fix a problem in generating provenance statements ([#1674](https://github.com/Siteimprove/alfa/pull/1674))
|
|
10
|
+
|
|
11
|
+
## 0.89.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- **Added:** Trying to publish Alfa packages on the npm registry ([#1673](https://github.com/Siteimprove/alfa/pull/1673))
|
|
16
|
+
|
|
17
|
+
## 0.89.0
|
|
18
|
+
|
|
19
|
+
## 0.88.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- **Fixed:** The publish flow was updated to a new version. ([`a2f19cf9a6c7c72b8bf085597e4f1a95ac3e4eb2`](https://github.com/Siteimprove/alfa/commit/a2f19cf9a6c7c72b8bf085597e4f1a95ac3e4eb2))
|
|
24
|
+
|
|
25
|
+
Some 0.87.\* versions were generating uninstallable package. This should be fixed now.
|
|
26
|
+
|
|
27
|
+
## 0.87.12
|
|
28
|
+
|
|
29
|
+
## 0.87.11
|
|
30
|
+
|
|
31
|
+
## 0.87.10
|
|
32
|
+
|
|
33
|
+
## 0.87.7
|
|
34
|
+
|
|
35
|
+
## 0.87.6
|
|
36
|
+
|
|
37
|
+
## 0.87.5
|
|
38
|
+
|
|
39
|
+
## 0.87.4
|
|
40
|
+
|
|
41
|
+
## 0.87.3
|
|
42
|
+
|
|
43
|
+
## 0.87.2
|
|
44
|
+
|
|
45
|
+
## 0.87.1
|
|
46
|
+
|
|
47
|
+
## 0.87.0
|
|
48
|
+
|
|
49
|
+
### Minor Changes
|
|
50
|
+
|
|
51
|
+
- **Breaking:** Optional serialization type parameters have been removed. ([#1651](https://github.com/Siteimprove/alfa/pull/1651))
|
|
52
|
+
|
|
53
|
+
## 0.86.2
|
|
54
|
+
|
|
55
|
+
## 0.86.1
|
|
56
|
+
|
|
57
|
+
## 0.86.0
|
|
58
|
+
|
|
59
|
+
### Minor Changes
|
|
60
|
+
|
|
61
|
+
- **Breaking:** TS resolution has been changed to `Node16`, target to `es2022`. ([#1636](https://github.com/Siteimprove/alfa/pull/1636))
|
|
62
|
+
|
|
63
|
+
- **Breaking:** Alfa is now distributed as ESM rather than CJS modules; projects using it must be ESM or use dynamic `import()`. ([#1636](https://github.com/Siteimprove/alfa/pull/1636))
|
|
64
|
+
|
|
65
|
+
⚠️ This is the last of a series of changes on the internal structure and build process of distributed packages that was started with v0.85.0.
|
|
66
|
+
|
|
67
|
+
## 0.85.1
|
|
68
|
+
|
|
69
|
+
## 0.85.0
|
|
70
|
+
|
|
71
|
+
### Minor Changes
|
|
72
|
+
|
|
73
|
+
- **Breaking:** The .js files are now built in the `dist` folder rather than in `src`. ([#1628](https://github.com/Siteimprove/alfa/pull/1628))
|
|
74
|
+
|
|
75
|
+
⚠️ This is the first of a series of changes on the internal structure and build process of distributed packages. It is probably better to not use this version and wait until more of these internal changes have been done to jump directly to the final result. We are internally releasing these changes for validation purpose only.
|
|
76
|
+
|
|
77
|
+
This should not impact consumers, the `package.json` files should be set correctly to consume these files.
|
|
78
|
+
|
|
79
|
+
## 0.84.0
|
|
80
|
+
|
|
81
|
+
## 0.83.1
|
|
82
|
+
|
|
83
|
+
## 0.83.0
|
|
84
|
+
|
|
85
|
+
## 0.82.0
|
|
86
|
+
|
|
87
|
+
### Minor Changes
|
|
88
|
+
|
|
89
|
+
- **Added:** Serialization options are now accepted, and passed on, by `toJSON()` on these types. ([#1622](https://github.com/Siteimprove/alfa/pull/1622))
|
|
90
|
+
|
|
91
|
+
- **Breaking:** Node 18 is no longer supported. ([#1618](https://github.com/Siteimprove/alfa/pull/1618))
|
|
92
|
+
|
|
93
|
+
## 0.81.0
|
|
94
|
+
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- **Added:** Each package now contains its internal dependency graph in its `docs` directory. ([#1610](https://github.com/Siteimprove/alfa/pull/1610))
|
|
98
|
+
|
|
99
|
+
## 0.80.0
|
|
100
|
+
|
|
101
|
+
## 0.79.1
|
|
102
|
+
|
|
103
|
+
## 0.79.0
|
|
104
|
+
|
|
105
|
+
## 0.78.2
|
|
106
|
+
|
|
107
|
+
## 0.78.1
|
|
108
|
+
|
|
109
|
+
## 0.78.0
|
|
110
|
+
|
|
111
|
+
## 0.77.0
|
|
112
|
+
|
|
113
|
+
## 0.76.0
|
|
114
|
+
|
|
115
|
+
## 0.75.2
|
|
116
|
+
|
|
117
|
+
## 0.75.1
|
|
118
|
+
|
|
119
|
+
## 0.75.0
|
|
120
|
+
|
|
121
|
+
## 0.74.0
|
|
122
|
+
|
|
123
|
+
## 0.73.0
|
|
124
|
+
|
|
125
|
+
## 0.72.0
|
|
126
|
+
|
|
127
|
+
## 0.71.1
|
|
128
|
+
|
|
129
|
+
## 0.71.0
|
|
130
|
+
|
|
131
|
+
## 0.70.0
|
|
132
|
+
|
|
133
|
+
## 0.69.0
|
|
134
|
+
|
|
135
|
+
## 0.68.0
|
|
136
|
+
|
|
137
|
+
## 0.67.0
|
|
138
|
+
|
|
139
|
+
## 0.66.0
|
|
140
|
+
|
|
141
|
+
## 0.65.1
|
|
142
|
+
|
|
143
|
+
## 0.65.0
|
|
144
|
+
|
|
145
|
+
## 0.64.0
|
|
146
|
+
|
|
147
|
+
## 0.63.3
|
|
148
|
+
|
|
149
|
+
## 0.63.2
|
|
150
|
+
|
|
151
|
+
## 0.63.1
|
|
152
|
+
|
|
153
|
+
## 0.63.0
|
|
154
|
+
|
|
155
|
+
## 0.62.2
|
|
156
|
+
|
|
157
|
+
## 0.62.1
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Equatable } from "@siteimprove/alfa-equatable";
|
|
2
|
+
import type { Hashable, Hash } from "@siteimprove/alfa-hash";
|
|
3
|
+
import { Iterable } from "@siteimprove/alfa-iterable";
|
|
4
|
+
import { Serializable } from "@siteimprove/alfa-json";
|
|
5
|
+
import { Map } from "@siteimprove/alfa-map";
|
|
6
|
+
import { Sequence } from "@siteimprove/alfa-sequence";
|
|
7
|
+
import { Set } from "@siteimprove/alfa-set";
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare class Graph<T> implements Iterable<[T, Iterable<T>]>, Equatable, Hashable, Serializable<Graph.JSON<T>> {
|
|
12
|
+
static of<T>(nodes: Map<T, Set<T>>): Graph<T>;
|
|
13
|
+
private static _empty;
|
|
14
|
+
static empty<T>(): Graph<T>;
|
|
15
|
+
private readonly _nodes;
|
|
16
|
+
private constructor();
|
|
17
|
+
get size(): number;
|
|
18
|
+
isEmpty(): this is Graph<never>;
|
|
19
|
+
nodes(): Iterable<T>;
|
|
20
|
+
neighbors(node: T): Iterable<T>;
|
|
21
|
+
has(node: T): boolean;
|
|
22
|
+
add(node: T): Graph<T>;
|
|
23
|
+
delete(node: T): Graph<T>;
|
|
24
|
+
connect(from: T, to: T): Graph<T>;
|
|
25
|
+
disconnect(from: T, to: T): Graph<T>;
|
|
26
|
+
traverse(root: T, traversal?: Graph.Traversal): Sequence<[node: T, parent: T]>;
|
|
27
|
+
path(from: T, to: T, traversal?: Graph.Traversal): Sequence<T>;
|
|
28
|
+
hasPath(from: T, to: T): boolean;
|
|
29
|
+
reverse(): Graph<T>;
|
|
30
|
+
sort(): Iterable<T>;
|
|
31
|
+
equals<T>(value: Graph<T>): boolean;
|
|
32
|
+
equals(value: unknown): value is this;
|
|
33
|
+
hash(hash: Hash): void;
|
|
34
|
+
iterator(): Iterator<[T, Iterable<T>]>;
|
|
35
|
+
[Symbol.iterator](): Iterator<[T, Iterable<T>]>;
|
|
36
|
+
toArray(): Array<[T, Array<T>]>;
|
|
37
|
+
toJSON(options?: Serializable.Options): Graph.JSON<T>;
|
|
38
|
+
toString(): string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export declare namespace Graph {
|
|
44
|
+
type JSON<T> = Array<[
|
|
45
|
+
Serializable.ToJSON<T>,
|
|
46
|
+
Array<Serializable.ToJSON<T>>
|
|
47
|
+
]>;
|
|
48
|
+
function isGraph<T>(value: Iterable<readonly [T, Iterable<T>]>): value is Graph<T>;
|
|
49
|
+
function isGraph<T>(value: unknown): value is Graph<T>;
|
|
50
|
+
function from<T>(iterable: Iterable<readonly [T, Iterable<T>]>): Graph<T>;
|
|
51
|
+
interface Traversal {
|
|
52
|
+
<T>(graph: Graph<T>, root: T): Iterable<[node: T, parent: T]>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* {@link https://en.wikipedia.org/wiki/Depth-first_search}
|
|
56
|
+
*/
|
|
57
|
+
const DepthFirst: Traversal;
|
|
58
|
+
/**
|
|
59
|
+
* {@link https://en.wikipedia.org/wiki/Breadth-first_search}
|
|
60
|
+
*/
|
|
61
|
+
const BreadthFirst: Traversal;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=graph.d.ts.map
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Iterable } from "@siteimprove/alfa-iterable";
|
|
2
|
+
import { Serializable } from "@siteimprove/alfa-json";
|
|
3
|
+
import { Map } from "@siteimprove/alfa-map";
|
|
4
|
+
import { Sequence } from "@siteimprove/alfa-sequence";
|
|
5
|
+
import { Set } from "@siteimprove/alfa-set";
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export class Graph {
|
|
10
|
+
static of(nodes) {
|
|
11
|
+
return new Graph(nodes);
|
|
12
|
+
}
|
|
13
|
+
static _empty = new Graph(Map.empty());
|
|
14
|
+
static empty() {
|
|
15
|
+
return this._empty;
|
|
16
|
+
}
|
|
17
|
+
_nodes;
|
|
18
|
+
constructor(nodes) {
|
|
19
|
+
this._nodes = nodes;
|
|
20
|
+
}
|
|
21
|
+
get size() {
|
|
22
|
+
return this._nodes.size;
|
|
23
|
+
}
|
|
24
|
+
isEmpty() {
|
|
25
|
+
return this._nodes.isEmpty();
|
|
26
|
+
}
|
|
27
|
+
nodes() {
|
|
28
|
+
return this._nodes.keys();
|
|
29
|
+
}
|
|
30
|
+
neighbors(node) {
|
|
31
|
+
return this._nodes.get(node).getOr([]);
|
|
32
|
+
}
|
|
33
|
+
has(node) {
|
|
34
|
+
return this._nodes.has(node);
|
|
35
|
+
}
|
|
36
|
+
add(node) {
|
|
37
|
+
if (this.has(node)) {
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
return new Graph(this._nodes.set(node, Set.empty()));
|
|
41
|
+
}
|
|
42
|
+
delete(node) {
|
|
43
|
+
const nodes = this._nodes;
|
|
44
|
+
if (!nodes.has(node)) {
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
return new Graph(nodes.delete(node).map((neighbors) => neighbors.delete(node)));
|
|
48
|
+
}
|
|
49
|
+
connect(from, to) {
|
|
50
|
+
let nodes = this._nodes;
|
|
51
|
+
if (!nodes.has(from)) {
|
|
52
|
+
nodes = nodes.set(from, Set.empty());
|
|
53
|
+
}
|
|
54
|
+
if (!nodes.has(to)) {
|
|
55
|
+
nodes = nodes.set(to, Set.empty());
|
|
56
|
+
}
|
|
57
|
+
return new Graph(nodes.set(from, nodes
|
|
58
|
+
.get(from)
|
|
59
|
+
.map((from) => from.add(to))
|
|
60
|
+
// Presence of from is guaranteed by first test.
|
|
61
|
+
.getUnsafe()));
|
|
62
|
+
}
|
|
63
|
+
disconnect(from, to) {
|
|
64
|
+
if (!this.has(from) || !this.has(to)) {
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
const nodes = this._nodes;
|
|
68
|
+
return new Graph(nodes.set(from, nodes
|
|
69
|
+
.get(from)
|
|
70
|
+
.map((from) => from.delete(to))
|
|
71
|
+
// presence of from is guaranteed by first test.
|
|
72
|
+
.getUnsafe()));
|
|
73
|
+
}
|
|
74
|
+
traverse(root, traversal = Graph.DepthFirst) {
|
|
75
|
+
return Sequence.from(traversal(this, root));
|
|
76
|
+
}
|
|
77
|
+
path(from, to, traversal = Graph.BreadthFirst) {
|
|
78
|
+
const parents = Map.from(traversal(this, from));
|
|
79
|
+
const path = [];
|
|
80
|
+
while (parents.has(to)) {
|
|
81
|
+
const parent = parents
|
|
82
|
+
.get(to)
|
|
83
|
+
// presence of to is guaranteed by the loop condition
|
|
84
|
+
.getUnsafe();
|
|
85
|
+
path.unshift(to);
|
|
86
|
+
to = parent;
|
|
87
|
+
}
|
|
88
|
+
return Sequence.from(path);
|
|
89
|
+
}
|
|
90
|
+
hasPath(from, to) {
|
|
91
|
+
if (!this.has(from) || !this.has(to)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return this.traverse(from)
|
|
95
|
+
.map(([node]) => node)
|
|
96
|
+
.includes(to);
|
|
97
|
+
}
|
|
98
|
+
reverse() {
|
|
99
|
+
let reversed = Graph.empty();
|
|
100
|
+
for (const [node, neighbors] of this._nodes) {
|
|
101
|
+
reversed = reversed.add(node);
|
|
102
|
+
for (const neighbor of neighbors) {
|
|
103
|
+
reversed = reversed.connect(neighbor, node);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return reversed;
|
|
107
|
+
}
|
|
108
|
+
*sort() {
|
|
109
|
+
let incoming = this.reverse();
|
|
110
|
+
const queue = incoming
|
|
111
|
+
.toArray()
|
|
112
|
+
.filter(([, edges]) => edges.length === 0)
|
|
113
|
+
.map(([node]) => node);
|
|
114
|
+
while (queue.length > 0) {
|
|
115
|
+
const next = queue.shift();
|
|
116
|
+
yield next;
|
|
117
|
+
for (const neighbor of this.neighbors(next)) {
|
|
118
|
+
incoming = incoming.disconnect(neighbor, next);
|
|
119
|
+
if (Iterable.isEmpty(incoming.neighbors(neighbor))) {
|
|
120
|
+
queue.push(neighbor);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
equals(value) {
|
|
126
|
+
return value instanceof Graph && value._nodes.equals(this._nodes);
|
|
127
|
+
}
|
|
128
|
+
hash(hash) {
|
|
129
|
+
hash.writeHashable(this._nodes);
|
|
130
|
+
}
|
|
131
|
+
*iterator() {
|
|
132
|
+
yield* this._nodes;
|
|
133
|
+
}
|
|
134
|
+
[Symbol.iterator]() {
|
|
135
|
+
return this.iterator();
|
|
136
|
+
}
|
|
137
|
+
toArray() {
|
|
138
|
+
return [...this].map(([node, neighbors]) => [node, [...neighbors]]);
|
|
139
|
+
}
|
|
140
|
+
toJSON(options) {
|
|
141
|
+
return this.toArray().map(([node, neighbors]) => [
|
|
142
|
+
Serializable.toJSON(node, options),
|
|
143
|
+
neighbors.map((node) => Serializable.toJSON(node, options)),
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
toString() {
|
|
147
|
+
const entries = this.toArray()
|
|
148
|
+
.map(([node, edges]) => {
|
|
149
|
+
const entries = edges.join(", ");
|
|
150
|
+
return `${node}${entries === "" ? "" : ` => [ ${entries} ]`}`;
|
|
151
|
+
})
|
|
152
|
+
.join(", ");
|
|
153
|
+
return `Graph {${entries === "" ? "" : ` ${entries} `}}`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @public
|
|
158
|
+
*/
|
|
159
|
+
(function (Graph) {
|
|
160
|
+
function isGraph(value) {
|
|
161
|
+
return value instanceof Graph;
|
|
162
|
+
}
|
|
163
|
+
Graph.isGraph = isGraph;
|
|
164
|
+
function from(iterable) {
|
|
165
|
+
if (isGraph(iterable)) {
|
|
166
|
+
return iterable;
|
|
167
|
+
}
|
|
168
|
+
return Graph.of(Map.from(Iterable.map(iterable, ([node, neighbours]) => [
|
|
169
|
+
node,
|
|
170
|
+
Set.from(neighbours),
|
|
171
|
+
])));
|
|
172
|
+
}
|
|
173
|
+
Graph.from = from;
|
|
174
|
+
/**
|
|
175
|
+
* {@link https://en.wikipedia.org/wiki/Depth-first_search}
|
|
176
|
+
*/
|
|
177
|
+
Graph.DepthFirst = function* (graph, root) {
|
|
178
|
+
const stack = [...graph.neighbors(root)].map((node) => [node, root]);
|
|
179
|
+
let seen = Set.of(root);
|
|
180
|
+
while (stack.length > 0) {
|
|
181
|
+
const next = stack.pop();
|
|
182
|
+
if (seen.has(next[0])) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
yield next;
|
|
186
|
+
seen = seen.add(next[0]);
|
|
187
|
+
for (const neighbor of graph.neighbors(next[0])) {
|
|
188
|
+
stack.push([neighbor, next[0]]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* {@link https://en.wikipedia.org/wiki/Breadth-first_search}
|
|
194
|
+
*/
|
|
195
|
+
Graph.BreadthFirst = function* (graph, root) {
|
|
196
|
+
const queue = [...graph.neighbors(root)].map((node) => [node, root]);
|
|
197
|
+
let seen = Set.of(root, ...graph.neighbors(root));
|
|
198
|
+
while (queue.length > 0) {
|
|
199
|
+
const next = queue.shift();
|
|
200
|
+
yield next;
|
|
201
|
+
for (const neighbor of graph.neighbors(next[0])) {
|
|
202
|
+
if (seen.has(neighbor)) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
seen = seen.add(neighbor);
|
|
206
|
+
queue.push([neighbor, next[0]]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
})(Graph || (Graph = {}));
|
|
211
|
+
//# sourceMappingURL=graph.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json.schemastore.org/package",
|
|
3
|
+
"name": "@siteimprove/alfa-graph",
|
|
4
|
+
"homepage": "https://alfa.siteimprove.com",
|
|
5
|
+
"version": "0.89.5",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"description": "An implementation of an immutable, directed graph",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "github:Siteimprove/alfa",
|
|
11
|
+
"directory": "packages/alfa-graph"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/siteimprove/alfa/issues",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20.0.0"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "dist/index.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/**/*.js",
|
|
22
|
+
"dist/**/*.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@siteimprove/alfa-equatable": "^0.89.5",
|
|
26
|
+
"@siteimprove/alfa-hash": "^0.89.5",
|
|
27
|
+
"@siteimprove/alfa-iterable": "^0.89.5",
|
|
28
|
+
"@siteimprove/alfa-json": "^0.89.5",
|
|
29
|
+
"@siteimprove/alfa-map": "^0.89.5",
|
|
30
|
+
"@siteimprove/alfa-sequence": "^0.89.5",
|
|
31
|
+
"@siteimprove/alfa-set": "^0.89.5"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@siteimprove/alfa-test": "^0.89.5"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"registry": "https://npm.pkg.github.com/"
|
|
39
|
+
}
|
|
40
|
+
}
|