Skip to content

Commit 9f4813b

Browse files
committedJan 24, 2023
Refactor to move implementation to lib/
1 parent 69cbec6 commit 9f4813b

7 files changed

+182
-117
lines changed
 

‎.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.DS_Store
2-
index.d.ts
2+
lib/index.d.ts
33
test.d.ts
44
*.log
55
coverage/

‎complex-types.d.ts

+2-54
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,2 @@
1-
import type {Node, Parent} from 'unist'
2-
import type {Test} from 'unist-util-is'
3-
import type {
4-
VisitorResult,
5-
Matches,
6-
InclusiveDescendant
7-
} from 'unist-util-visit-parents/complex-types.js'
8-
9-
/**
10-
* Called when a node (matching test, if given) is found.
11-
* Visitors are free to transform node.
12-
* They can also transform the parent of node (the last of ancestors).
13-
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited.
14-
* If adding or removing previous siblings (or next siblings, in case of reverse) of node,
15-
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed.
16-
* Adding or removing next siblings of node (or previous siblings, in case of reverse)
17-
* is handled as expected without needing to return a new index.
18-
* Removing the children property of an ancestor still results in them being traversed.
19-
*/
20-
export type Visitor<
21-
Visited extends Node = Node,
22-
Ancestor extends Parent = Parent
23-
> = (
24-
node: Visited,
25-
index: Visited extends Node ? number | null : never,
26-
parent: Ancestor extends Node ? Ancestor | null : Ancestor
27-
) => VisitorResult
28-
29-
type ParentsOf<
30-
Ancestor extends Node,
31-
Child extends Node
32-
> = Ancestor extends Parent
33-
? Child extends Ancestor['children'][number]
34-
? Ancestor
35-
: never
36-
: never
37-
38-
type BuildVisitorFromMatch<
39-
Visited extends Node,
40-
Ancestor extends Parent
41-
> = Visitor<Visited, ParentsOf<Ancestor, Visited>>
42-
43-
type BuildVisitorFromDescendants<
44-
Descendant extends Node,
45-
Check extends Test
46-
> = BuildVisitorFromMatch<
47-
Matches<Descendant, Check>,
48-
Extract<Descendant, Parent>
49-
>
50-
51-
export type BuildVisitor<
52-
Tree extends Node = Node,
53-
Check extends Test = string
54-
> = BuildVisitorFromDescendants<InclusiveDescendant<Tree>, Check>
1+
// To do: next major: remove this file.
2+
export type {Visitor, BuildVisitor} from './index.js'

‎index.d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export type {Test} from 'unist-util-is'
2+
export type {
3+
Action,
4+
ActionTuple,
5+
Index,
6+
VisitorResult
7+
} from 'unist-util-visit-parents'
8+
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'
9+
export type {Visitor, BuildVisitor} from './lib/index.js'
10+
export {visit} from './lib/index.js'

‎index.js

+2-60
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,3 @@
1-
/**
2-
* @typedef {import('unist').Node} Node
3-
* @typedef {import('unist').Parent} Parent
4-
* @typedef {import('unist-util-is').Test} Test
5-
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
6-
* @typedef {import('./complex-types.js').Visitor} Visitor
7-
*/
8-
9-
import {visitParents} from 'unist-util-visit-parents'
10-
11-
/**
12-
* Visit children of tree which pass test.
13-
*
14-
* @param tree
15-
* Tree to walk
16-
* @param [test]
17-
* `unist-util-is`-compatible test
18-
* @param visitor
19-
* Function called for nodes that pass `test`.
20-
* @param reverse
21-
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
22-
*/
23-
export const visit =
24-
/**
25-
* @type {(
26-
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
27-
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
28-
* )}
29-
*/
30-
(
31-
/**
32-
* @param {Node} tree
33-
* @param {Test} test
34-
* @param {import('./complex-types.js').Visitor} visitor
35-
* @param {boolean} [reverse]
36-
*/
37-
function (tree, test, visitor, reverse) {
38-
if (typeof test === 'function' && typeof visitor !== 'function') {
39-
reverse = visitor
40-
visitor = test
41-
test = null
42-
}
43-
44-
visitParents(tree, test, overload, reverse)
45-
46-
/**
47-
* @param {Node} node
48-
* @param {Array<Parent>} parents
49-
*/
50-
function overload(node, parents) {
51-
const parent = parents[parents.length - 1]
52-
return visitor(
53-
node,
54-
parent ? parent.children.indexOf(node) : null,
55-
parent
56-
)
57-
}
58-
}
59-
)
60-
1+
// Note: types exported from `index.d.ts`
612
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'
3+
export {visit} from './lib/index.js'

‎lib/index.js

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist').Parent} Parent
4+
* @typedef {import('unist-util-is').Test} Test
5+
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
6+
*/
7+
8+
/**
9+
* Check if `Child` can be a child of `Ancestor`.
10+
*
11+
* Returns the ancestor when `Child` can be a child of `Ancestor`, or returns
12+
* `never`.
13+
*
14+
* @template {Node} Ancestor
15+
* Node type.
16+
* @template {Node} Child
17+
* Node type.
18+
* @typedef {(
19+
* Ancestor extends Parent
20+
* ? Child extends Ancestor['children'][number]
21+
* ? Ancestor
22+
* : never
23+
* : never
24+
* )} ParentsOf
25+
*/
26+
27+
/**
28+
* @template {Node} [Visited=Node]
29+
* Visited node type.
30+
* @template {Parent} [Ancestor=Parent]
31+
* Ancestor type.
32+
* @callback Visitor
33+
* Handle a node (matching `test`, if given).
34+
*
35+
* Visitors are free to transform `node`.
36+
* They can also transform `parent`.
37+
*
38+
* Replacing `node` itself, if `SKIP` is not returned, still causes its
39+
* descendants to be walked (which is a bug).
40+
*
41+
* When adding or removing previous siblings of `node` (or next siblings, in
42+
* case of reverse), the `Visitor` should return a new `Index` to specify the
43+
* sibling to traverse after `node` is traversed.
44+
* Adding or removing next siblings of `node` (or previous siblings, in case
45+
* of reverse) is handled as expected without needing to return a new `Index`.
46+
*
47+
* Removing the children property of `parent` still results in them being
48+
* traversed.
49+
* @param {Visited} node
50+
* Found node.
51+
* @param {Visited extends Node ? number | null : never} index
52+
* Index of `node` in `parent`.
53+
* @param {Ancestor extends Node ? Ancestor | null : never} parent
54+
* Parent of `node`.
55+
* @returns {VisitorResult}
56+
* What to do next.
57+
*
58+
* An `Index` is treated as a tuple of `[CONTINUE, Index]`.
59+
* An `Action` is treated as a tuple of `[Action]`.
60+
*
61+
* Passing a tuple back only makes sense if the `Action` is `SKIP`.
62+
* When the `Action` is `EXIT`, that action can be returned.
63+
* When the `Action` is `CONTINUE`, `Index` can be returned.
64+
*/
65+
66+
/**
67+
* Build a typed `Visitor` function from a node and all possible parents.
68+
*
69+
* It will infer which values are passed as `node` and which as `parent`.
70+
*
71+
* @template {Node} Visited
72+
* Node type.
73+
* @template {Parent} Ancestor
74+
* Parent type.
75+
* @typedef {Visitor<Visited, ParentsOf<Ancestor, Visited>>} BuildVisitorFromMatch
76+
*/
77+
78+
/**
79+
* Build a typed `Visitor` function from a list of descendants and a test.
80+
*
81+
* It will infer which values are passed as `node` and which as `parent`.
82+
*
83+
* @template {Node} Descendant
84+
* Node type.
85+
* @template {Test} Check
86+
* Test type.
87+
* @typedef {(
88+
* BuildVisitorFromMatch<
89+
* import('unist-util-visit-parents/complex-types.js').Matches<Descendant, Check>,
90+
* Extract<Descendant, Parent>
91+
* >
92+
* )} BuildVisitorFromDescendants
93+
*/
94+
95+
/**
96+
* Build a typed `Visitor` function from a tree and a test.
97+
*
98+
* It will infer which values are passed as `node` and which as `parent`.
99+
*
100+
* @template {Node} [Tree=Node]
101+
* Node type.
102+
* @template {Test} [Check=string]
103+
* Test type.
104+
* @typedef {(
105+
* BuildVisitorFromDescendants<
106+
* import('unist-util-visit-parents/complex-types.js').InclusiveDescendant<Tree>,
107+
* Check
108+
* >
109+
* )} BuildVisitor
110+
*/
111+
112+
import {visitParents} from 'unist-util-visit-parents'
113+
114+
/**
115+
* Visit children of tree which pass test.
116+
*
117+
* @param tree
118+
* Tree to walk
119+
* @param [test]
120+
* `unist-util-is`-compatible test
121+
* @param visitor
122+
* Function called for nodes that pass `test`.
123+
* @param reverse
124+
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
125+
*/
126+
export const visit =
127+
/**
128+
* @type {(
129+
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
130+
* (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean) => void)
131+
* )}
132+
*/
133+
(
134+
/**
135+
* @param {Node} tree
136+
* @param {Test} test
137+
* @param {Visitor} visitor
138+
* @param {boolean} [reverse]
139+
*/
140+
function (tree, test, visitor, reverse) {
141+
if (typeof test === 'function' && typeof visitor !== 'function') {
142+
reverse = visitor
143+
visitor = test
144+
test = null
145+
}
146+
147+
visitParents(tree, test, overload, reverse)
148+
149+
/**
150+
* @param {Node} node
151+
* @param {Array<Parent>} parents
152+
*/
153+
function overload(node, parents) {
154+
const parent = parents[parents.length - 1]
155+
return visitor(
156+
node,
157+
parent ? parent.children.indexOf(node) : null,
158+
parent
159+
)
160+
}
161+
}
162+
)
163+
164+
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"main": "index.js",
4444
"types": "index.d.ts",
4545
"files": [
46+
"lib/",
4647
"complex-types.d.ts",
4748
"index.d.ts",
4849
"index.js"
@@ -92,7 +93,7 @@
9293
},
9394
"remarkConfig": {
9495
"plugins": [
95-
"preset-wooorm"
96+
"remark-preset-wooorm"
9697
]
9798
},
9899
"typeCoverage": {

‎tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"include": ["**/*.js", "complex-types.d.ts"],
2+
"include": ["**/*.js", "complex-types.d.ts", "index.d.ts"],
33
"exclude": ["coverage/", "node_modules/"],
44
"compilerOptions": {
55
"checkJs": true,

0 commit comments

Comments
 (0)
Please sign in to comment.