4
4
* @typedef {import('unist-util-is').Test } Test
5
5
*/
6
6
7
+ /**
8
+ * @typedef {(
9
+ * Fn extends (value: any) => value is infer Thing
10
+ * ? Thing
11
+ * : Fallback
12
+ * )} Predicate
13
+ * Get the value of a type guard `Fn`.
14
+ * @template Fn
15
+ * Value; typically function that is a type guard (such as `(x): x is Y`).
16
+ * @template Fallback
17
+ * Value to yield if `Fn` is not a type guard.
18
+ */
19
+
20
+ /**
21
+ * @typedef {(
22
+ * Value extends Node
23
+ * ? Check extends null | undefined // No test.
24
+ * ? Value
25
+ * : Check extends Function // Function test.
26
+ * ? Extract<Value, Predicate<Check, Value>>
27
+ * : Value['type'] extends Check // String (type) test.
28
+ * ? Value
29
+ * : Value extends Check // Partial test.
30
+ * ? Value
31
+ * : never
32
+ * : never
33
+ * )} MatchesOne
34
+ * Check whether a node matches a primitive check in the type system.
35
+ * @template Value
36
+ * Value; typically unist `Node`.
37
+ * @template Check
38
+ * Value; typically `unist-util-is`-compatible test, but not arrays.
39
+ */
40
+
41
+ /**
42
+ * @typedef {(
43
+ * Check extends Array<any>
44
+ * ? MatchesOne<Value, Check[keyof Check]>
45
+ * : MatchesOne<Value, Check>
46
+ * )} Matches
47
+ * Check whether a node matches a check in the type system.
48
+ * @template Value
49
+ * Value; typically unist `Node`.
50
+ * @template Check
51
+ * Value; typically `unist-util-is`-compatible test.
52
+ */
53
+
54
+ /**
55
+ * @typedef {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 } Uint
56
+ * Number; capped reasonably.
57
+ */
58
+
59
+ /**
60
+ * @typedef {I extends 0 ? 1 : I extends 1 ? 2 : I extends 2 ? 3 : I extends 3 ? 4 : I extends 4 ? 5 : I extends 5 ? 6 : I extends 6 ? 7 : I extends 7 ? 8 : I extends 8 ? 9 : 10 } Increment
61
+ * Increment a number in the type system.
62
+ * @template {Uint} [I=0]
63
+ * Index.
64
+ */
65
+
66
+ /**
67
+ * @typedef {(
68
+ * Tree extends Parent
69
+ * ? Depth extends Max
70
+ * ? Tree
71
+ * : Tree | InclusiveDescendant<Tree['children'][number], Max, Increment<Depth>>
72
+ * : Tree
73
+ * )} InclusiveDescendant
74
+ * Collect all (inclusive) descendants of `Tree`.
75
+ *
76
+ * > 👉 **Note**: for performance reasons, this seems to be the fastest way to
77
+ * > recurse without actually running into an infinite loop, which the
78
+ * > previous version did.
79
+ * >
80
+ * > Practically, a max of `2` is typically enough assuming a `Root` is
81
+ * > passed, but it doesn’t improve performance.
82
+ * > It gets higher with `List > ListItem > Table > TableRow > TableCell`.
83
+ * > Using up to `10` doesn’t hurt or help either.
84
+ * @template {Node} Tree
85
+ * Tree type.
86
+ * @template {Uint} [Max=10]
87
+ * Max; searches up to this depth.
88
+ * @template {Uint} [Depth=0]
89
+ * Current depth.
90
+ */
91
+
7
92
/**
8
93
* @typedef {'skip' | boolean } Action
9
94
* Union of the action types.
25
110
*/
26
111
27
112
/**
28
- * @template {Node} [Visited=Node]
29
- * Visited node type.
30
- * @template {Parent} [Ancestor=Parent]
31
- * Ancestor type.
32
113
* @callback Visitor
33
114
* Handle a node (matching `test`, if given).
34
115
*
59
140
* Passing a tuple back only makes sense if the `Action` is `SKIP`.
60
141
* When the `Action` is `EXIT`, that action can be returned.
61
142
* When the `Action` is `CONTINUE`, `Index` can be returned.
143
+ * @template {Node} [Visited=Node]
144
+ * Visited node type.
145
+ * @template {Parent} [Ancestor=Parent]
146
+ * Ancestor type.
62
147
*/
63
148
64
149
/**
150
+ * @typedef {Visitor<Matches<InclusiveDescendant<Tree>, Check>, Extract<InclusiveDescendant<Tree>, Parent>> } BuildVisitor
151
+ * Build a typed `Visitor` function from a tree and a test.
152
+ *
153
+ * It will infer which values are passed as `node` and which as `parents`.
65
154
* @template {Node} [Tree=Node]
66
155
* Tree type.
67
156
* @template {Test} [Check=Test]
68
157
* Test type.
69
- * @typedef {Visitor<import('./complex-types.js').Matches<import('./complex-types.js').InclusiveDescendant<Tree>, Check>, Extract<import('./complex-types.js').InclusiveDescendant<Tree>, Parent>> } BuildVisitor
70
- * Build a typed `Visitor` function from a tree and a test.
71
- *
72
- * It will infer which values are passed as `node` and which as `parents`.
73
158
*/
74
159
75
160
import { convert } from 'unist-util-is'
@@ -111,9 +196,6 @@ export const SKIP = 'skip'
111
196
* You can change the tree.
112
197
* See `Visitor` for more info.
113
198
*
114
- * @template {Node} Tree
115
- * @template {Test} Check
116
- *
117
199
* @overload
118
200
* @param {Tree } tree
119
201
* @param {Check } check
@@ -137,6 +219,11 @@ export const SKIP = 'skip'
137
219
* Traverse in reverse preorder (NRL) instead of the default preorder (NLR).
138
220
* @returns {undefined }
139
221
* Nothing.
222
+ *
223
+ * @template {Node} Tree
224
+ * Node type.
225
+ * @template {Test} Check
226
+ * `unist-util-is`-compatible test.
140
227
*/
141
228
export function visitParents ( tree , test , visitor , reverse ) {
142
229
/** @type {Test } */
0 commit comments