@atlaspack/graph 3.4.1-canary.52 → 3.4.1-canary.521
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 +432 -0
- package/benchmark/BitSet.js +37 -0
- package/dist/AdjacencyList.js +1348 -0
- package/dist/BitSet.js +108 -0
- package/dist/ContentGraph.js +70 -0
- package/dist/Graph.js +504 -0
- package/dist/index.js +17 -0
- package/dist/shared-buffer.js +24 -0
- package/dist/types.js +10 -0
- package/lib/AdjacencyList.js +35 -11
- package/lib/BitSet.js +36 -5
- package/lib/ContentGraph.js +2 -6
- package/lib/Graph.js +26 -13
- package/lib/index.js +2 -3
- package/lib/shared-buffer.js +5 -1
- package/lib/types/AdjacencyList.d.ts +609 -0
- package/lib/types/BitSet.d.ts +19 -0
- package/lib/types/ContentGraph.d.ts +23 -0
- package/lib/types/Graph.d.ts +92 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/shared-buffer.d.ts +2 -0
- package/lib/types/types.d.ts +9 -0
- package/lib/types.js +1 -0
- package/package.json +16 -6
- package/src/{AdjacencyList.js → AdjacencyList.ts} +135 -107
- package/src/{BitSet.js → BitSet.ts} +31 -3
- package/src/{ContentGraph.js → ContentGraph.ts} +21 -20
- package/src/{Graph.js → Graph.ts} +104 -74
- package/src/{index.js → index.ts} +0 -2
- package/src/{shared-buffer.js → shared-buffer.ts} +6 -3
- package/src/{types.js → types.ts} +5 -7
- package/test/{AdjacencyList.test.js → AdjacencyList.test.ts} +21 -29
- package/test/{BitSet.test.js → BitSet.test.ts} +45 -5
- package/test/{ContentGraph.test.js → ContentGraph.test.ts} +2 -4
- package/test/{Graph.test.js → Graph.test.ts} +44 -36
- package/tsconfig.json +18 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
1
|
import type {ContentKey, NodeId} from './types';
|
|
3
2
|
|
|
4
|
-
import Graph, {
|
|
3
|
+
import Graph, {SerializedGraph, GraphOpts} from './Graph';
|
|
5
4
|
import nullthrows from 'nullthrows';
|
|
6
5
|
|
|
7
|
-
export type ContentGraphOpts<TNode, TEdgeType
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
export type ContentGraphOpts<TNode, TEdgeType extends number = 1> = GraphOpts<
|
|
7
|
+
TNode,
|
|
8
|
+
TEdgeType
|
|
9
|
+
> & {
|
|
10
|
+
_contentKeyToNodeId: Map<ContentKey, NodeId>;
|
|
11
|
+
_nodeIdToContentKey: Map<NodeId, ContentKey>;
|
|
12
|
+
};
|
|
13
|
+
export type SerializedContentGraph<
|
|
14
|
+
TNode,
|
|
15
|
+
TEdgeType extends number = 1,
|
|
16
|
+
> = SerializedGraph<TNode, TEdgeType> & {
|
|
17
|
+
_contentKeyToNodeId: Map<ContentKey, NodeId>;
|
|
18
|
+
};
|
|
16
19
|
|
|
17
|
-
export default class ContentGraph<
|
|
20
|
+
export default class ContentGraph<
|
|
18
21
|
TNode,
|
|
19
|
-
TEdgeType,
|
|
20
|
-
> {
|
|
22
|
+
TEdgeType extends number = 1,
|
|
23
|
+
> extends Graph<TNode, TEdgeType> {
|
|
21
24
|
_contentKeyToNodeId: Map<ContentKey, NodeId>;
|
|
22
25
|
_nodeIdToContentKey: Map<NodeId, ContentKey>;
|
|
23
26
|
|
|
24
|
-
constructor(opts
|
|
27
|
+
constructor(opts?: ContentGraphOpts<TNode, TEdgeType> | null) {
|
|
25
28
|
if (opts) {
|
|
26
29
|
let {_contentKeyToNodeId, _nodeIdToContentKey, ...rest} = opts;
|
|
27
30
|
super(rest);
|
|
@@ -34,19 +37,17 @@ export default class ContentGraph<TNode, TEdgeType: number = 1> extends Graph<
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
static deserialize(
|
|
40
|
+
static deserialize<TNode, TEdgeType extends number = 1>(
|
|
39
41
|
opts: ContentGraphOpts<TNode, TEdgeType>,
|
|
40
42
|
): ContentGraph<TNode, TEdgeType> {
|
|
41
43
|
return new ContentGraph(opts);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
// $FlowFixMe[prop-missing]
|
|
45
46
|
serialize(): SerializedContentGraph<TNode, TEdgeType> {
|
|
46
|
-
// $FlowFixMe[prop-missing]
|
|
47
47
|
return {
|
|
48
48
|
...super.serialize(),
|
|
49
49
|
_contentKeyToNodeId: this._contentKeyToNodeId,
|
|
50
|
+
// @ts-expect-error TS2353
|
|
50
51
|
_nodeIdToContentKey: this._nodeIdToContentKey,
|
|
51
52
|
};
|
|
52
53
|
}
|
|
@@ -68,7 +69,7 @@ export default class ContentGraph<TNode, TEdgeType: number = 1> extends Graph<
|
|
|
68
69
|
: this.addNodeByContentKey(contentKey, node);
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
getNodeByContentKey(contentKey: ContentKey):
|
|
72
|
+
getNodeByContentKey(contentKey: ContentKey): TNode | null | undefined {
|
|
72
73
|
let nodeId = this._contentKeyToNodeId.get(contentKey);
|
|
73
74
|
if (nodeId != null) {
|
|
74
75
|
return super.getNode(nodeId);
|
|
@@ -1,45 +1,44 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import {fromNodeId} from './types';
|
|
4
|
-
import AdjacencyList, {
|
|
2
|
+
import AdjacencyList, {SerializedAdjacencyList} from './AdjacencyList';
|
|
5
3
|
import type {Edge, NodeId} from './types';
|
|
6
4
|
import type {
|
|
7
5
|
TraversalActions,
|
|
8
6
|
GraphVisitor,
|
|
9
7
|
GraphTraversalCallback,
|
|
10
|
-
} from '@atlaspack/types';
|
|
8
|
+
} from '@atlaspack/types-internal';
|
|
11
9
|
import {BitSet} from './BitSet';
|
|
12
10
|
|
|
13
11
|
import nullthrows from 'nullthrows';
|
|
14
12
|
|
|
15
13
|
export type NullEdgeType = 1;
|
|
16
14
|
export const NULL_EDGE_TYPE: NullEdgeType = 1;
|
|
17
|
-
export type GraphOpts<TNode, TEdgeType
|
|
18
|
-
nodes?: Array<TNode | null
|
|
19
|
-
adjacencyList?: SerializedAdjacencyList<TEdgeType
|
|
20
|
-
rootNodeId?:
|
|
21
|
-
initialCapacity?: number
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
|
15
|
+
export type GraphOpts<TNode, TEdgeType extends number = NullEdgeType> = {
|
|
16
|
+
nodes?: Array<TNode | null>;
|
|
17
|
+
adjacencyList?: SerializedAdjacencyList<TEdgeType> | AdjacencyList<TEdgeType>;
|
|
18
|
+
rootNodeId?: NodeId | null | undefined;
|
|
19
|
+
initialCapacity?: number;
|
|
20
|
+
initialNodeCapacity?: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type SerializedGraph<TNode, TEdgeType extends number = NullEdgeType> = {
|
|
24
|
+
nodes: Array<TNode | null>;
|
|
25
|
+
adjacencyList: SerializedAdjacencyList<TEdgeType>;
|
|
26
|
+
rootNodeId: NodeId | null | undefined;
|
|
27
|
+
};
|
|
29
28
|
|
|
30
29
|
export type AllEdgeTypes = -1;
|
|
31
30
|
export const ALL_EDGE_TYPES: AllEdgeTypes = -1;
|
|
32
31
|
|
|
33
|
-
type DFSCommandVisit<TContext> = {
|
|
34
|
-
nodeId: NodeId
|
|
35
|
-
context: TContext | null
|
|
36
|
-
|
|
32
|
+
type DFSCommandVisit<TContext> = {
|
|
33
|
+
nodeId: NodeId;
|
|
34
|
+
context: TContext | null;
|
|
35
|
+
};
|
|
37
36
|
|
|
38
|
-
type DFSCommandExit<TContext> = {
|
|
39
|
-
nodeId: NodeId
|
|
40
|
-
exit: GraphTraversalCallback<NodeId, TContext
|
|
41
|
-
context: TContext | null
|
|
42
|
-
|
|
37
|
+
type DFSCommandExit<TContext> = {
|
|
38
|
+
nodeId: NodeId;
|
|
39
|
+
exit: GraphTraversalCallback<NodeId, TContext>;
|
|
40
|
+
context: TContext | null;
|
|
41
|
+
};
|
|
43
42
|
|
|
44
43
|
/**
|
|
45
44
|
* Internal type used for queue iterative DFS implementation.
|
|
@@ -51,8 +50,8 @@ type DFSCommand<TContext> =
|
|
|
51
50
|
/**
|
|
52
51
|
* Options for DFS traversal.
|
|
53
52
|
*/
|
|
54
|
-
export type DFSParams<TContext> = {
|
|
55
|
-
visit: GraphVisitor<NodeId, TContext
|
|
53
|
+
export type DFSParams<TContext> = {
|
|
54
|
+
visit: GraphVisitor<NodeId, TContext>;
|
|
56
55
|
/**
|
|
57
56
|
* Custom function to get next entries to visit.
|
|
58
57
|
*
|
|
@@ -71,34 +70,40 @@ export type DFSParams<TContext> = {|
|
|
|
71
70
|
*
|
|
72
71
|
* Only due to the latter we aren't replacing this.
|
|
73
72
|
*/
|
|
74
|
-
getChildren: (nodeId: NodeId) => Array<NodeId
|
|
75
|
-
startNodeId?:
|
|
76
|
-
|
|
73
|
+
getChildren: (nodeId: NodeId) => Array<NodeId>;
|
|
74
|
+
startNodeId?: NodeId | null | undefined;
|
|
75
|
+
};
|
|
77
76
|
|
|
78
|
-
export default class Graph<TNode, TEdgeType
|
|
77
|
+
export default class Graph<TNode, TEdgeType extends number = NullEdgeType> {
|
|
79
78
|
nodes: Array<TNode | null>;
|
|
80
79
|
adjacencyList: AdjacencyList<TEdgeType>;
|
|
81
|
-
rootNodeId:
|
|
82
|
-
_visited:
|
|
80
|
+
rootNodeId: NodeId | null | undefined;
|
|
81
|
+
_visited: BitSet | null | undefined;
|
|
83
82
|
|
|
84
|
-
constructor(opts
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
constructor(opts?: GraphOpts<TNode, TEdgeType> | null) {
|
|
84
|
+
let {nodes, rootNodeId, adjacencyList, ...adjacencyListOpts} = opts ?? {};
|
|
85
|
+
|
|
86
|
+
this.nodes = nodes ?? [];
|
|
87
|
+
this.setRootNodeId(rootNodeId);
|
|
87
88
|
|
|
88
|
-
let adjacencyList = opts?.adjacencyList;
|
|
89
|
-
let initialCapacity = opts?.initialCapacity;
|
|
90
89
|
this.adjacencyList = adjacencyList
|
|
91
|
-
? AdjacencyList
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
? adjacencyList instanceof AdjacencyList
|
|
91
|
+
? adjacencyList
|
|
92
|
+
: AdjacencyList.deserialize(adjacencyList)
|
|
93
|
+
: new AdjacencyList<TEdgeType>(adjacencyListOpts);
|
|
94
|
+
|
|
95
|
+
if (opts?.nodes && !opts.adjacencyList) {
|
|
96
|
+
for (let i = 0; i < this.nodes.length; i++) {
|
|
97
|
+
this.adjacencyList.addNode();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
setRootNodeId(id
|
|
102
|
+
setRootNodeId(id?: NodeId | null) {
|
|
98
103
|
this.rootNodeId = id;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
static deserialize(
|
|
106
|
+
static deserialize<TNode, TEdgeType extends number = NullEdgeType>(
|
|
102
107
|
opts: GraphOpts<TNode, TEdgeType>,
|
|
103
108
|
): Graph<TNode, TEdgeType> {
|
|
104
109
|
return new this({
|
|
@@ -132,7 +137,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
132
137
|
return this.nodes[id] != null;
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
getNode(id: NodeId):
|
|
140
|
+
getNode(id: NodeId): TNode | null | undefined {
|
|
136
141
|
return this.nodes[id];
|
|
137
142
|
}
|
|
138
143
|
|
|
@@ -159,7 +164,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
159
164
|
hasEdge(
|
|
160
165
|
from: NodeId,
|
|
161
166
|
to: NodeId,
|
|
162
|
-
type
|
|
167
|
+
type:
|
|
163
168
|
| TEdgeType
|
|
164
169
|
| NullEdgeType
|
|
165
170
|
| Array<TEdgeType | NullEdgeType> = NULL_EDGE_TYPE,
|
|
@@ -169,7 +174,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
169
174
|
|
|
170
175
|
forEachNodeIdConnectedTo(
|
|
171
176
|
to: NodeId,
|
|
172
|
-
fn: (nodeId: NodeId) => boolean |
|
|
177
|
+
fn: (nodeId: NodeId) => boolean | undefined,
|
|
173
178
|
type: AllEdgeTypes | TEdgeType | NullEdgeType = NULL_EDGE_TYPE,
|
|
174
179
|
) {
|
|
175
180
|
this._assertHasNodeId(to);
|
|
@@ -327,9 +332,9 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
327
332
|
// Update a node's downstream nodes making sure to prune any orphaned branches
|
|
328
333
|
replaceNodeIdsConnectedTo(
|
|
329
334
|
fromNodeId: NodeId,
|
|
330
|
-
toNodeIds:
|
|
331
|
-
replaceFilter?: null | ((NodeId) => boolean),
|
|
332
|
-
type
|
|
335
|
+
toNodeIds: ReadonlyArray<NodeId>,
|
|
336
|
+
replaceFilter?: null | ((arg1: NodeId) => boolean),
|
|
337
|
+
type: TEdgeType | NullEdgeType = NULL_EDGE_TYPE,
|
|
333
338
|
removeOrphans: boolean = true,
|
|
334
339
|
): void {
|
|
335
340
|
this._assertHasNodeId(fromNodeId);
|
|
@@ -355,13 +360,13 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
355
360
|
|
|
356
361
|
traverse<TContext>(
|
|
357
362
|
visit: GraphVisitor<NodeId, TContext>,
|
|
358
|
-
startNodeId
|
|
363
|
+
startNodeId?: NodeId | null,
|
|
359
364
|
type:
|
|
360
365
|
| TEdgeType
|
|
361
366
|
| NullEdgeType
|
|
362
367
|
| Array<TEdgeType | NullEdgeType>
|
|
363
368
|
| AllEdgeTypes = NULL_EDGE_TYPE,
|
|
364
|
-
):
|
|
369
|
+
): TContext | null | undefined {
|
|
365
370
|
let enter = typeof visit === 'function' ? visit : visit.enter;
|
|
366
371
|
if (
|
|
367
372
|
type === ALL_EDGE_TYPES &&
|
|
@@ -379,23 +384,23 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
379
384
|
}
|
|
380
385
|
|
|
381
386
|
filteredTraverse<TValue, TContext>(
|
|
382
|
-
filter: (NodeId, TraversalActions) =>
|
|
387
|
+
filter: (arg1: NodeId, arg2: TraversalActions) => TValue | null | undefined,
|
|
383
388
|
visit: GraphVisitor<TValue, TContext>,
|
|
384
|
-
startNodeId
|
|
389
|
+
startNodeId?: NodeId | null,
|
|
385
390
|
type?: TEdgeType | Array<TEdgeType | NullEdgeType> | AllEdgeTypes,
|
|
386
|
-
):
|
|
391
|
+
): TContext | null | undefined {
|
|
387
392
|
return this.traverse(mapVisitor(filter, visit), startNodeId, type);
|
|
388
393
|
}
|
|
389
394
|
|
|
390
395
|
traverseAncestors<TContext>(
|
|
391
|
-
startNodeId:
|
|
396
|
+
startNodeId: NodeId | null | undefined,
|
|
392
397
|
visit: GraphVisitor<NodeId, TContext>,
|
|
393
398
|
type:
|
|
394
399
|
| TEdgeType
|
|
395
400
|
| NullEdgeType
|
|
396
401
|
| Array<TEdgeType | NullEdgeType>
|
|
397
402
|
| AllEdgeTypes = NULL_EDGE_TYPE,
|
|
398
|
-
):
|
|
403
|
+
): TContext | null | undefined {
|
|
399
404
|
return this.dfs({
|
|
400
405
|
visit,
|
|
401
406
|
startNodeId,
|
|
@@ -405,8 +410,8 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
405
410
|
|
|
406
411
|
dfsFast<TContext>(
|
|
407
412
|
visit: GraphTraversalCallback<NodeId, TContext>,
|
|
408
|
-
startNodeId
|
|
409
|
-
):
|
|
413
|
+
startNodeId?: NodeId | null,
|
|
414
|
+
): TContext | null | undefined {
|
|
410
415
|
let traversalStartNode = nullthrows(
|
|
411
416
|
startNodeId ?? this.rootNodeId,
|
|
412
417
|
'A start node is required to traverse',
|
|
@@ -437,6 +442,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
437
442
|
|
|
438
443
|
let queue = [{nodeId: traversalStartNode, context: null}];
|
|
439
444
|
while (queue.length !== 0) {
|
|
445
|
+
// @ts-expect-error TS2339
|
|
440
446
|
let {nodeId, context} = queue.pop();
|
|
441
447
|
if (!this.hasNode(nodeId) || visited.has(nodeId)) continue;
|
|
442
448
|
visited.add(nodeId);
|
|
@@ -444,7 +450,6 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
444
450
|
skipped = false;
|
|
445
451
|
let newContext = visit(nodeId, context, actions);
|
|
446
452
|
if (typeof newContext !== 'undefined') {
|
|
447
|
-
// $FlowFixMe[reassign-const]
|
|
448
453
|
context = newContext;
|
|
449
454
|
}
|
|
450
455
|
|
|
@@ -472,7 +477,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
472
477
|
// A post-order implementation of dfsFast
|
|
473
478
|
postOrderDfsFast(
|
|
474
479
|
visit: GraphTraversalCallback<NodeId, TraversalActions>,
|
|
475
|
-
startNodeId
|
|
480
|
+
startNodeId?: NodeId | null,
|
|
476
481
|
): void {
|
|
477
482
|
let traversalStartNode = nullthrows(
|
|
478
483
|
startNodeId ?? this.rootNodeId,
|
|
@@ -542,7 +547,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
542
547
|
visit,
|
|
543
548
|
startNodeId,
|
|
544
549
|
getChildren,
|
|
545
|
-
}: DFSParams<TContext>):
|
|
550
|
+
}: DFSParams<TContext>): TContext | null | undefined {
|
|
546
551
|
let traversalStartNode = nullthrows(
|
|
547
552
|
startNodeId ?? this.rootNodeId,
|
|
548
553
|
'A start node is required to traverse',
|
|
@@ -578,11 +583,13 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
578
583
|
while (queue.length !== 0) {
|
|
579
584
|
const command = queue.pop();
|
|
580
585
|
|
|
586
|
+
// @ts-expect-error TS18048
|
|
581
587
|
if (command.exit != null) {
|
|
588
|
+
// @ts-expect-error TS2339
|
|
582
589
|
let {nodeId, context, exit} = command;
|
|
590
|
+
// @ts-expect-error TS18048
|
|
583
591
|
let newContext = exit(nodeId, command.context, actions);
|
|
584
592
|
if (typeof newContext !== 'undefined') {
|
|
585
|
-
// $FlowFixMe[reassign-const]
|
|
586
593
|
context = newContext;
|
|
587
594
|
}
|
|
588
595
|
|
|
@@ -595,6 +602,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
595
602
|
return context;
|
|
596
603
|
}
|
|
597
604
|
} else {
|
|
605
|
+
// @ts-expect-error TS2339
|
|
598
606
|
let {nodeId, context} = command;
|
|
599
607
|
if (!this.hasNode(nodeId) || visited.has(nodeId)) continue;
|
|
600
608
|
visited.add(nodeId);
|
|
@@ -603,7 +611,6 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
603
611
|
if (enter) {
|
|
604
612
|
let newContext = enter(nodeId, context, actions);
|
|
605
613
|
if (typeof newContext !== 'undefined') {
|
|
606
|
-
// $FlowFixMe[reassign-const]
|
|
607
614
|
context = newContext;
|
|
608
615
|
}
|
|
609
616
|
}
|
|
@@ -641,7 +648,9 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
641
648
|
this._visited = visited;
|
|
642
649
|
}
|
|
643
650
|
|
|
644
|
-
bfs(
|
|
651
|
+
bfs(
|
|
652
|
+
visit: (nodeId: NodeId) => boolean | null | undefined,
|
|
653
|
+
): NodeId | null | undefined {
|
|
645
654
|
let rootNodeId = nullthrows(
|
|
646
655
|
this.rootNodeId,
|
|
647
656
|
'A root node is required to traverse',
|
|
@@ -657,6 +666,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
657
666
|
return node;
|
|
658
667
|
}
|
|
659
668
|
|
|
669
|
+
// @ts-expect-error TS2345
|
|
660
670
|
for (let child of this.getNodeIdsConnectedFrom(node)) {
|
|
661
671
|
if (!visited.has(child)) {
|
|
662
672
|
visited.add(child);
|
|
@@ -682,7 +692,10 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
682
692
|
return sorted.reverse();
|
|
683
693
|
}
|
|
684
694
|
|
|
685
|
-
findAncestor(
|
|
695
|
+
findAncestor(
|
|
696
|
+
nodeId: NodeId,
|
|
697
|
+
fn: (nodeId: NodeId) => boolean,
|
|
698
|
+
): NodeId | null | undefined {
|
|
686
699
|
let res = null;
|
|
687
700
|
this.traverseAncestors(nodeId, (nodeId, ctx, traversal) => {
|
|
688
701
|
if (fn(nodeId)) {
|
|
@@ -697,7 +710,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
697
710
|
nodeId: NodeId,
|
|
698
711
|
fn: (nodeId: NodeId) => boolean,
|
|
699
712
|
): Array<NodeId> {
|
|
700
|
-
let res = [];
|
|
713
|
+
let res: Array<NodeId> = [];
|
|
701
714
|
this.traverseAncestors(nodeId, (nodeId, ctx, traversal) => {
|
|
702
715
|
if (fn(nodeId)) {
|
|
703
716
|
res.push(nodeId);
|
|
@@ -707,7 +720,10 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
707
720
|
return res;
|
|
708
721
|
}
|
|
709
722
|
|
|
710
|
-
findDescendant(
|
|
723
|
+
findDescendant(
|
|
724
|
+
nodeId: NodeId,
|
|
725
|
+
fn: (nodeId: NodeId) => boolean,
|
|
726
|
+
): NodeId | null | undefined {
|
|
711
727
|
let res = null;
|
|
712
728
|
this.traverse((nodeId, ctx, traversal) => {
|
|
713
729
|
if (fn(nodeId)) {
|
|
@@ -722,7 +738,7 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
722
738
|
nodeId: NodeId,
|
|
723
739
|
fn: (nodeId: NodeId) => boolean,
|
|
724
740
|
): Array<NodeId> {
|
|
725
|
-
let res = [];
|
|
741
|
+
let res: Array<NodeId> = [];
|
|
726
742
|
this.traverse((nodeId, ctx, traversal) => {
|
|
727
743
|
if (fn(nodeId)) {
|
|
728
744
|
res.push(nodeId);
|
|
@@ -740,11 +756,21 @@ export default class Graph<TNode, TEdgeType: number = NullEdgeType> {
|
|
|
740
756
|
}
|
|
741
757
|
|
|
742
758
|
export function mapVisitor<NodeId, TValue, TContext>(
|
|
743
|
-
filter: (NodeId, TraversalActions) =>
|
|
759
|
+
filter: (arg1: NodeId, arg2: TraversalActions) => TValue | null | undefined,
|
|
744
760
|
visit: GraphVisitor<TValue, TContext>,
|
|
745
761
|
): GraphVisitor<NodeId, TContext> {
|
|
746
|
-
function makeEnter(
|
|
747
|
-
|
|
762
|
+
function makeEnter(
|
|
763
|
+
visit: (
|
|
764
|
+
node: TValue,
|
|
765
|
+
context: TContext | null | undefined,
|
|
766
|
+
actions: TraversalActions,
|
|
767
|
+
) => TContext | null | undefined,
|
|
768
|
+
) {
|
|
769
|
+
return function mappedEnter(
|
|
770
|
+
nodeId: NodeId,
|
|
771
|
+
context: TContext | null | undefined,
|
|
772
|
+
actions: TraversalActions,
|
|
773
|
+
) {
|
|
748
774
|
let value = filter(nodeId, actions);
|
|
749
775
|
if (value != null) {
|
|
750
776
|
return visit(value, context, actions);
|
|
@@ -756,13 +782,17 @@ export function mapVisitor<NodeId, TValue, TContext>(
|
|
|
756
782
|
return makeEnter(visit);
|
|
757
783
|
}
|
|
758
784
|
|
|
759
|
-
let mapped = {};
|
|
785
|
+
let mapped: Record<string, any> = {};
|
|
760
786
|
if (visit.enter != null) {
|
|
761
787
|
mapped.enter = makeEnter(visit.enter);
|
|
762
788
|
}
|
|
763
789
|
|
|
764
790
|
if (visit.exit != null) {
|
|
765
|
-
mapped.exit = function mappedExit(
|
|
791
|
+
mapped.exit = function mappedExit(
|
|
792
|
+
nodeId: NodeId,
|
|
793
|
+
context: TContext | null | undefined,
|
|
794
|
+
actions: TraversalActions,
|
|
795
|
+
) {
|
|
766
796
|
let exit = visit.exit;
|
|
767
797
|
if (!exit) {
|
|
768
798
|
return;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
//
|
|
1
|
+
// flow-to-ts helpers
|
|
2
|
+
export type Class<T> = new (...args: any[]) => T;
|
|
3
|
+
// /flow-to-ts helpers
|
|
4
|
+
|
|
2
5
|
// Copy from @atlaspack/utils to fix: https://github.com/stackblitz/core/issues/1855
|
|
3
6
|
export let SharedBuffer: Class<ArrayBuffer> | Class<SharedArrayBuffer>;
|
|
4
7
|
|
|
5
|
-
//
|
|
8
|
+
// @ts-expect-error TS2339
|
|
6
9
|
if (process.browser) {
|
|
7
10
|
SharedBuffer = ArrayBuffer;
|
|
8
11
|
// Safari has removed the constructor
|
|
@@ -12,7 +15,7 @@ if (process.browser) {
|
|
|
12
15
|
// Firefox might throw when sending the Buffer over a MessagePort
|
|
13
16
|
channel.port1.postMessage(new SharedArrayBuffer(0));
|
|
14
17
|
SharedBuffer = SharedArrayBuffer;
|
|
15
|
-
} catch (_) {
|
|
18
|
+
} catch (_: any) {
|
|
16
19
|
// NOOP
|
|
17
20
|
}
|
|
18
21
|
channel.port1.close();
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
// forcing NodeId to be opaque as it should only be created once
|
|
4
2
|
export type NodeId = number;
|
|
5
3
|
export function toNodeId(x: number): NodeId {
|
|
@@ -11,8 +9,8 @@ export function fromNodeId(x: NodeId): number {
|
|
|
11
9
|
|
|
12
10
|
export type ContentKey = string;
|
|
13
11
|
|
|
14
|
-
export type Edge<TEdgeType
|
|
15
|
-
from: NodeId
|
|
16
|
-
to: NodeId
|
|
17
|
-
type: TEdgeType
|
|
18
|
-
|
|
12
|
+
export type Edge<TEdgeType extends number> = {
|
|
13
|
+
from: NodeId;
|
|
14
|
+
to: NodeId;
|
|
15
|
+
type: TEdgeType;
|
|
16
|
+
};
|