index.d.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. export function visitParents<
  2. Tree extends import('unist').Node,
  3. Check extends Test
  4. >(
  5. tree: Tree,
  6. check: Check,
  7. visitor: BuildVisitor<Tree, Check>,
  8. reverse?: boolean | null | undefined
  9. ): undefined
  10. export function visitParents<
  11. Tree extends import('unist').Node,
  12. Check extends Test
  13. >(
  14. tree: Tree,
  15. visitor: BuildVisitor<Tree, Test>,
  16. reverse?: boolean | null | undefined
  17. ): undefined
  18. /**
  19. * Continue traversing as normal.
  20. */
  21. export const CONTINUE: true
  22. /**
  23. * Stop traversing immediately.
  24. */
  25. export const EXIT: false
  26. /**
  27. * Do not traverse this node’s children.
  28. */
  29. export const SKIP: 'skip'
  30. export type UnistNode = import('unist').Node
  31. export type UnistParent = import('unist').Parent
  32. /**
  33. * Test from `unist-util-is`.
  34. *
  35. * Note: we have remove and add `undefined`, because otherwise when generating
  36. * automatic `.d.ts` files, TS tries to flatten paths from a local perspective,
  37. * which doesn’t work when publishing on npm.
  38. */
  39. export type Test = Exclude<import('unist-util-is').Test, undefined> | undefined
  40. /**
  41. * Get the value of a type guard `Fn`.
  42. */
  43. export type Predicate<Fn, Fallback> = Fn extends (
  44. value: any
  45. ) => value is infer Thing
  46. ? Thing
  47. : Fallback
  48. /**
  49. * Check whether a node matches a primitive check in the type system.
  50. */
  51. export type MatchesOne<Value, Check> = Check extends null | undefined
  52. ? Value
  53. : Value extends {
  54. type: Check
  55. }
  56. ? Value
  57. : Value extends Check
  58. ? Value
  59. : Check extends Function
  60. ? Predicate<Check, Value> extends Value
  61. ? Predicate<Check, Value>
  62. : never
  63. : never
  64. /**
  65. * Check whether a node matches a check in the type system.
  66. */
  67. export type Matches<Value, Check> = Check extends Array<any>
  68. ? MatchesOne<Value, Check[keyof Check]>
  69. : MatchesOne<Value, Check>
  70. /**
  71. * Number; capped reasonably.
  72. */
  73. export type Uint = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
  74. /**
  75. * Increment a number in the type system.
  76. */
  77. export type Increment<I extends Uint = 0> = I extends 0
  78. ? 1
  79. : I extends 1
  80. ? 2
  81. : I extends 2
  82. ? 3
  83. : I extends 3
  84. ? 4
  85. : I extends 4
  86. ? 5
  87. : I extends 5
  88. ? 6
  89. : I extends 6
  90. ? 7
  91. : I extends 7
  92. ? 8
  93. : I extends 8
  94. ? 9
  95. : 10
  96. /**
  97. * Collect nodes that can be parents of `Child`.
  98. */
  99. export type InternalParent<
  100. Node extends import('unist').Node,
  101. Child extends import('unist').Node
  102. > = Node extends import('unist').Parent
  103. ? Node extends {
  104. children: (infer Children)[]
  105. }
  106. ? Child extends Children
  107. ? Node
  108. : never
  109. : never
  110. : never
  111. /**
  112. * Collect nodes in `Tree` that can be parents of `Child`.
  113. */
  114. export type Parent<
  115. Tree extends import('unist').Node,
  116. Child extends import('unist').Node
  117. > = InternalParent<InclusiveDescendant<Tree>, Child>
  118. /**
  119. * Collect nodes in `Tree` that can be ancestors of `Child`.
  120. */
  121. export type InternalAncestor<
  122. Node extends import('unist').Node,
  123. Child extends import('unist').Node,
  124. Max extends Uint = 10,
  125. Depth extends Uint = 0
  126. > = Depth extends Max
  127. ? never
  128. :
  129. | InternalParent<Node, Child>
  130. | InternalAncestor<
  131. Node,
  132. InternalParent<Node, Child>,
  133. Max,
  134. Increment<Depth>
  135. >
  136. /**
  137. * Collect nodes in `Tree` that can be ancestors of `Child`.
  138. */
  139. export type Ancestor<
  140. Tree extends import('unist').Node,
  141. Child extends import('unist').Node
  142. > = InternalAncestor<InclusiveDescendant<Tree>, Child>
  143. /**
  144. * Collect all (inclusive) descendants of `Tree`.
  145. *
  146. * > 👉 **Note**: for performance reasons, this seems to be the fastest way to
  147. * > recurse without actually running into an infinite loop, which the
  148. * > previous version did.
  149. * >
  150. * > Practically, a max of `2` is typically enough assuming a `Root` is
  151. * > passed, but it doesn’t improve performance.
  152. * > It gets higher with `List > ListItem > Table > TableRow > TableCell`.
  153. * > Using up to `10` doesn’t hurt or help either.
  154. */
  155. export type InclusiveDescendant<
  156. Tree extends import('unist').Node,
  157. Max extends Uint = 10,
  158. Depth extends Uint = 0
  159. > = Tree extends UnistParent
  160. ? Depth extends Max
  161. ? Tree
  162. :
  163. | Tree
  164. | InclusiveDescendant<Tree['children'][number], Max, Increment<Depth>>
  165. : Tree
  166. /**
  167. * Union of the action types.
  168. */
  169. export type Action = 'skip' | boolean
  170. /**
  171. * Move to the sibling at `index` next (after node itself is completely
  172. * traversed).
  173. *
  174. * Useful if mutating the tree, such as removing the node the visitor is
  175. * currently on, or any of its previous siblings.
  176. * Results less than 0 or greater than or equal to `children.length` stop
  177. * traversing the parent.
  178. */
  179. export type Index = number
  180. /**
  181. * List with one or two values, the first an action, the second an index.
  182. */
  183. export type ActionTuple = [
  184. (Action | null | undefined | void)?,
  185. (Index | null | undefined)?
  186. ]
  187. /**
  188. * Any value that can be returned from a visitor.
  189. */
  190. export type VisitorResult =
  191. | Action
  192. | [(void | Action | null | undefined)?, (number | null | undefined)?]
  193. | Index
  194. | null
  195. | undefined
  196. | void
  197. /**
  198. * Handle a node (matching `test`, if given).
  199. *
  200. * Visitors are free to transform `node`.
  201. * They can also transform the parent of node (the last of `ancestors`).
  202. *
  203. * Replacing `node` itself, if `SKIP` is not returned, still causes its
  204. * descendants to be walked (which is a bug).
  205. *
  206. * When adding or removing previous siblings of `node` (or next siblings, in
  207. * case of reverse), the `Visitor` should return a new `Index` to specify the
  208. * sibling to traverse after `node` is traversed.
  209. * Adding or removing next siblings of `node` (or previous siblings, in case
  210. * of reverse) is handled as expected without needing to return a new `Index`.
  211. *
  212. * Removing the children property of an ancestor still results in them being
  213. * traversed.
  214. */
  215. export type Visitor<
  216. Visited extends import('unist').Node = import('unist').Node,
  217. VisitedParents extends import('unist').Parent = import('unist').Parent
  218. > = (node: Visited, ancestors: Array<VisitedParents>) => VisitorResult
  219. /**
  220. * Build a typed `Visitor` function from a tree and a test.
  221. *
  222. * It will infer which values are passed as `node` and which as `parents`.
  223. */
  224. export type BuildVisitor<
  225. Tree extends import('unist').Node = import('unist').Node,
  226. Check extends Test = Test
  227. > = Visitor<
  228. Matches<InclusiveDescendant<Tree>, Check>,
  229. Ancestor<Tree, Matches<InclusiveDescendant<Tree>, Check>>
  230. >