Socket
Socket
Sign inDemoInstall

unist-util-visit-parents

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unist-util-visit-parents - npm Package Compare versions

Comparing version 5.1.1 to 5.1.2

lib/color.browser.d.ts

121

complex-types.d.ts

@@ -1,112 +0,11 @@

/* eslint-disable @typescript-eslint/ban-types */
// To do: next major: remove this file?
export type {
// Used in `unist-util-visit`:
Matches,
InclusiveDescendant,
VisitorResult,
import type {Node, Parent} from 'unist'
import type {Test} from 'unist-util-is'
/**
* Union of the action types
*/
export type Action = boolean | 'skip'
/**
* Move to the sibling at index next (after node itself is completely
* traversed).
* Useful if mutating the tree, such as removing the node the visitor is
* currently on, or any of its previous siblings (or next siblings, in case of
* reverse) Results less than 0 or greater than or equal to `children.length`
* stop traversing the parent.
*/
export type Index = number
/**
* List with one or two values, the first an action, the second an index.
*/
export type ActionTuple = [
(Action | null | undefined | void)?,
(Index | null | undefined)?
]
/**
* Any value that can be returned from a visitor
*/
export type VisitorResult =
| null
| undefined
| Action
| Index
| ActionTuple
| void
/**
* Internal utility to collect all descendants of in `Tree`.
*/
export type InclusiveDescendant<
Tree extends Node = never,
Found = void
> = Tree extends Parent
?
| Tree
| InclusiveDescendant<
Exclude<Tree['children'][number], Found | Tree>,
Found | Tree
>
: Tree
type Predicate<Fn, Fallback = never> = Fn extends (
value: any
) => value is infer Thing
? Thing
: Fallback
type MatchesOne<Value, Check> =
// Is this a node?
Value extends Node
? // No test.
Check extends null
? Value
: // No test.
Check extends undefined
? Value
: // Function test.
Check extends Function
? Extract<Value, Predicate<Check, Value>>
: // String (type) test.
Value['type'] extends Check
? Value
: // Partial test.
Value extends Check
? Value
: never
: never
export type Matches<Value, Check> =
// Is this a list?
Check extends Array<any>
? MatchesOne<Value, Check[keyof Check]>
: MatchesOne<Value, Check>
/**
* Called when a node (matching test, if given) is found.
* Visitors are free to transform node.
* They can also transform the parent of node (the last of ancestors).
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited.
* If adding or removing previous siblings (or next siblings, in case of reverse) of node,
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed.
* Adding or removing next siblings of node (or previous siblings, in case of reverse)
* is handled as expected without needing to return a new index.
* Removing the children property of an ancestor still results in them being traversed.
*/
export type Visitor<
Visited extends Node = Node,
Ancestor extends Parent = Parent
> = (node: Visited, ancestors: Array<Ancestor>) => VisitorResult
export type BuildVisitor<
Tree extends Node = Node,
Check extends Test = string
> = Visitor<
Matches<InclusiveDescendant<Tree>, Check>,
Extract<InclusiveDescendant<Tree>, Parent>
>
/* eslint-enable @typescript-eslint/ban-types */
// Documented:
Visitor,
BuildVisitor
} from './index.js'

@@ -1,46 +0,10 @@

/**
* Continue traversing as normal
*/
export const CONTINUE: true
/**
* Do not traverse this node’s children
*/
export const SKIP: 'skip'
/**
* Stop traversing immediately
*/
export const EXIT: false
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param [reverse=false]
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visitParents: (<
Tree extends import('unist').Node<import('unist').Data>,
Check extends import('unist-util-is').Test
>(
tree: Tree,
test: Check,
visitor: import('./complex-types.js').BuildVisitor<Tree, Check>,
reverse?: boolean
) => void) &
(<Tree_1 extends import('unist').Node<import('unist').Data>>(
tree: Tree_1,
visitor: import('./complex-types.js').BuildVisitor<Tree_1, string>,
reverse?: boolean
) => void)
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Test = import('unist-util-is').Test
export type Action = import('./complex-types.js').Action
export type Index = import('./complex-types.js').Index
export type ActionTuple = import('./complex-types.js').ActionTuple
export type VisitorResult = import('./complex-types.js').VisitorResult
export type Visitor = import('./complex-types.js').Visitor
export type {Test} from 'unist-util-is'
export type {
Action,
ActionTuple,
BuildVisitor,
Index,
Visitor,
VisitorResult
} from './lib/index.js'
export {CONTINUE, EXIT, SKIP, visitParents} from './lib/index.js'

@@ -1,156 +0,2 @@

/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist-util-is').Test} Test
* @typedef {import('./complex-types.js').Action} Action
* @typedef {import('./complex-types.js').Index} Index
* @typedef {import('./complex-types.js').ActionTuple} ActionTuple
* @typedef {import('./complex-types.js').VisitorResult} VisitorResult
* @typedef {import('./complex-types.js').Visitor} Visitor
*/
import {convert} from 'unist-util-is'
import {color} from './color.js'
/**
* Continue traversing as normal
*/
export const CONTINUE = true
/**
* Do not traverse this node’s children
*/
export const SKIP = 'skip'
/**
* Stop traversing immediately
*/
export const EXIT = false
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param [reverse=false]
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visitParents =
/**
* @type {(
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
* )}
*/
(
/**
* @param {Node} tree
* @param {Test} test
* @param {import('./complex-types.js').Visitor<Node>} visitor
* @param {boolean} [reverse=false]
*/
function (tree, test, visitor, reverse) {
if (typeof test === 'function' && typeof visitor !== 'function') {
reverse = visitor
// @ts-expect-error no visitor given, so `visitor` is test.
visitor = test
test = null
}
const is = convert(test)
const step = reverse ? -1 : 1
factory(tree, null, [])()
/**
* @param {Node} node
* @param {number?} index
* @param {Array<Parent>} parents
*/
function factory(node, index, parents) {
/** @type {Record<string, unknown>} */
// @ts-expect-error: hush
const value = typeof node === 'object' && node !== null ? node : {}
/** @type {string|undefined} */
let name
if (typeof value.type === 'string') {
name =
typeof value.tagName === 'string'
? value.tagName
: typeof value.name === 'string'
? value.name
: undefined
Object.defineProperty(visit, 'name', {
value:
'node (' +
color(value.type + (name ? '<' + name + '>' : '')) +
')'
})
}
return visit
function visit() {
/** @type {ActionTuple} */
let result = []
/** @type {ActionTuple} */
let subresult
/** @type {number} */
let offset
/** @type {Array<Parent>} */
let grandparents
if (!test || is(node, index, parents[parents.length - 1] || null)) {
result = toResult(visitor(node, parents))
if (result[0] === EXIT) {
return result
}
}
// @ts-expect-error looks like a parent.
if (node.children && result[0] !== SKIP) {
// @ts-expect-error looks like a parent.
offset = (reverse ? node.children.length : -1) + step
// @ts-expect-error looks like a parent.
grandparents = parents.concat(node)
// @ts-expect-error looks like a parent.
while (offset > -1 && offset < node.children.length) {
// @ts-expect-error looks like a parent.
subresult = factory(node.children[offset], offset, grandparents)()
if (subresult[0] === EXIT) {
return subresult
}
offset =
typeof subresult[1] === 'number' ? subresult[1] : offset + step
}
}
return result
}
}
}
)
/**
* @param {VisitorResult} value
* @returns {ActionTuple}
*/
function toResult(value) {
if (Array.isArray(value)) {
return value
}
if (typeof value === 'number') {
return [CONTINUE, value]
}
return [value]
}
// Note: types exported from `index.d.ts`
export {CONTINUE, EXIT, SKIP, visitParents} from './lib/index.js'
{
"name": "unist-util-visit-parents",
"version": "5.1.1",
"version": "5.1.2",
"description": "unist utility to recursively walk over nodes, with ancestral information",

@@ -34,13 +34,10 @@ "license": "MIT",

"browser": {
"./color.js": "./color.browser.js"
"./lib/color.js": "./lib/color.browser.js"
},
"react-native": {
"./color.js": "./color.browser.js"
"./lib/color.js": "./lib/color.browser.js"
},
"types": "index.d.ts",
"files": [
"color.d.ts",
"color.js",
"color.browser.d.ts",
"color.browser.js",
"lib/",
"complex-types.d.ts",

@@ -57,3 +54,3 @@ "index.d.ts",

"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"@types/node": "^18.0.0",
"c8": "^7.0.0",

@@ -66,16 +63,14 @@ "mdast-util-from-markdown": "^1.0.0",

"remark-preset-wooorm": "^9.0.0",
"rimraf": "^3.0.0",
"strip-ansi": "^7.0.0",
"tape": "^5.0.0",
"tsd": "^0.22.0",
"tsd": "^0.25.0",
"type-coverage": "^2.0.0",
"typescript": "^4.7.0",
"xo": "^0.51.0"
"xo": "^0.53.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{color,color.browser,index,test}.d.ts\" && tsc && tsd && type-coverage",
"format": "remark . -qfo && prettier . --write --loglevel warn && xo --fix",
"test-api": "node test.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
"build": "tsc --build --clean && tsc --build && tsd && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node --conditions development test.js",
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"

@@ -99,3 +94,3 @@ },

"plugins": [
"preset-wooorm"
"remark-preset-wooorm"
]

@@ -110,5 +105,5 @@ },

"ignoreFiles": [
"complex-types.d.ts"
"lib/complex-types.d.ts"
]
}
}

@@ -21,2 +21,12 @@ # unist-util-visit-parents

* [`visitParents(tree[, test], visitor[, reverse])`](#visitparentstree-test-visitor-reverse)
* [`CONTINUE`](#continue)
* [`EXIT`](#exit)
* [`SKIP`](#skip)
* [`Action`](#action)
* [`ActionTuple`](#actiontuple)
* [`BuildVisitor`](#buildvisitor)
* [`Index`](#index)
* [`Test`](#test)
* [`Visitor`](#visitor)
* [`VisitorResult`](#visitorresult)
* [Types](#types)

@@ -43,3 +53,3 @@ * [Compatibility](#compatibility)

This package is [ESM only][esm].
In Node.js (version 12.20+, 14.14+, 16.0+, 18.0+), install with [npm][]:
In Node.js (version 14.14+ and 16.0+), install with [npm][]:

@@ -53,3 +63,3 @@ ```sh

```js
import {visitParents} from "https://esm.sh/unist-util-visit-parents@5"
import {visitParents} from 'https://esm.sh/unist-util-visit-parents@5'
```

@@ -61,3 +71,3 @@

<script type="module">
import {visitParents} from "https://esm.sh/unist-util-visit-parents@5?bundle"
import {visitParents} from 'https://esm.sh/unist-util-visit-parents@5?bundle'
</script>

@@ -87,4 +97,4 @@ ```

This package exports the identifiers `visitParents`, `SKIP`, `CONTINUE`, and
`EXIT`.
This package exports the identifiers [`CONTINUE`][api-continue],
[`EXIT`][api-exit], [`SKIP`][api-skip], and [`visitParents`][api-visitparents].
There is no default export.

@@ -94,19 +104,20 @@

Walk the `tree` ([`Node`][node]) and visit [*inclusive descendants*][descendant]
with ancestral information.
Visit nodes, with ancestral information.
This algorithm performs *[depth-first][]* *[tree traversal][tree-traversal]* in
*[preorder][]* (**NLR**), or if `reverse` is given, in *reverse preorder*
This algorithm performs *[depth-first][]* *[tree traversal][tree-traversal]*
in *[preorder][]* (**NLR**) or if `reverse` is given, in *reverse preorder*
(**NRL**).
You can choose for which nodes `visitor` is called by passing a `test`.
For complex tests, you should test yourself in `visitor`, as it will be
faster and will have improved type information.
Walking the tree is an intensive task.
Make use of the return values of the visitor when possible.
Instead of walking a tree multiple times with different `test`s, walk it once
without a test, and use [`unist-util-is`][unist-util-is] to check if a node
matches a test, and then perform different operations.
Instead of walking a tree multiple times, walk it once, use
[`unist-util-is`][unist-util-is] to check if a node matches, and then perform
different operations.
You can change the tree.
See `visitor` below for more info.
See [`Visitor`][api-visitor] for more info.

@@ -117,71 +128,147 @@ ###### Parameters

— tree to traverse
* `test` ([`Test`][test], optional)
* `test` ([`Test`][api-test], optional)
— [`unist-util-is`][unist-util-is]-compatible test
* `visitor` ([Function][visitor])
— function called for nodes that pass `test`
* `visitor` ([`Visitor`][api-visitor])
— handle each node
* `reverse` (`boolean`, default: `false`)
— traverse in reverse preorder (NRL) instead of preorder (NLR) (default
— traverse in reverse preorder (NRL) instead of the default preorder (NLR)
#### `next? = visitor(node, ancestors)`
###### Returns
Called when a node (matching `test`, if given) is entered.
Nothing (`void`).
Visitors are free to change `node`.
They can also transform the [parent][] of node (the last of `ancestors`).
Replacing `node` itself is okay if `SKIP` is returned.
When adding or removing previous [sibling][]s (or next siblings, in case of
`reverse`) of `node`, `visitor` must return a new [`index`][index] (`number`)
to specify the sibling to move to after `node` is traversed.
Adding or removing next siblings of `node` (or previous siblings, in case of
`reverse`) is fine without needing to return a new `index`.
Replacing the `children` of a node is fine, but replacing them on an ancestor
is not okay and still causes them to be visited.
### `CONTINUE`
###### Parameters
Continue traversing as normal (`true`).
* `node` ([`Node`][node]) — found node
* `ancestors` (`Array<Node>`) — [ancestor][]s of `node`
### `EXIT`
##### Returns
Stop traversing immediately (`false`).
The return value can have the following forms:
### `SKIP`
* [`index`][index] (`number`) — like a tuple of `[CONTINUE, index]`
* `action` (`*`) — like a tuple of `[action]`
* `tuple` (`[action, index?]`) — array with one or two values, the first an
`action`, the second and `index`.
Do not traverse this node’s children (`'skip'`).
> 👉 **Note**: yielding a tuple only makes sense if the `action` is `SKIP`.
> Otherwise, if the `action` is `EXIT`, that action can be returned.
> Or if the `action` is `CONTINUE`, `index` can be returned.
### `Action`
###### `action`
Union of the action types (TypeScript type).
An action can have the following values:
###### Type
* `EXIT` (`false`) — stop traversing immediately
* `CONTINUE` (`true`) — continue traversing as normal
* `SKIP` (`'skip'`) — do not traverse this node’s children
```ts
type Action = typeof CONTINUE | typeof EXIT | typeof SKIP
```
###### `index`
### `ActionTuple`
Next [`index`][index] (`number`).
Defines that the sibling at `index` should be moved to (after `node` itself is
completely traversed).
List with one or two values, the first an action, the second an index
(TypeScript type).
###### Type
```ts
type ActionTuple = [
(Action | null | undefined | void)?,
(Index | null | undefined)?
]
```
### `BuildVisitor`
Build a typed `Visitor` function from a tree and a test (TypeScript type).
It will infer which values are passed as `node` and which as `parents`.
###### Type parameters
* `Tree` ([`Node`][node], default: `Node`)
— tree type
* `Check` ([`Test`][api-test], default: `string`)
— test type
###### Returns
[`Visitor`][api-visitor].
### `Index`
Move to the sibling at `index` next (after node itself is completely
traversed) (TypeScript type).
Useful if mutating the tree, such as removing the node the visitor is currently
on, or any of its previous siblings (or next siblings, in case of `reverse`).
on, or any of its previous siblings.
Results less than `0` or greater than or equal to `children.length` stop
traversing the parent
traversing the parent.
###### Type
```ts
type Index = number
```
### `Test`
[`unist-util-is`][unist-util-is] compatible test (TypeScript type).
### `Visitor`
Handle a node (matching `test`, if given) (TypeScript type).
Visitors are free to transform `node`.
They can also transform the parent of node (the last of `ancestors`).
Replacing `node` itself, if `SKIP` is not returned, still causes its
descendants to be walked (which is a bug).
When adding or removing previous siblings of `node` (or next siblings, in
case of reverse), the `Visitor` should return a new `Index` to specify the
sibling to traverse after `node` is traversed.
Adding or removing next siblings of `node` (or previous siblings, in case
of reverse) is handled as expected without needing to return a new `Index`.
Removing the children property of an ancestor still results in them being
traversed.
###### Parameters
* `node` ([`Node`][node])
— found node
* `parents` ([`Array<Node>`][node])
— ancestors of `node`
###### Returns
What to do next.
An `Index` is treated as a tuple of `[CONTINUE, Index]`.
An `Action` is treated as a tuple of `[Action]`.
Passing a tuple back only makes sense if the `Action` is `SKIP`.
When the `Action` is `EXIT`, that action can be returned.
When the `Action` is `CONTINUE`, `Index` can be returned.
### `VisitorResult`
Any value that can be returned from a visitor (TypeScript type).
###### Type
```ts
type VisitorResult =
| Action
| ActionTuple
| Index
| null
| undefined
| void
```
## Types
This package is fully typed with [TypeScript][].
It exports the additional types `Test`, `Action`, `Index`, `ActionTuple`,
`VisitorResult`, and `Visitor`.
It exports the additional types [`Action`][api-action],
[`ActionTuple`][api-actiontuple], [`BuildVisitor`][api-buildvisitor],
[`Index`][api-index], [`Test`][api-test], [`Visitor`][api-visitor], and
[`VisitorResult`][api-visitorresult].
It also exports the types `BuildVisitor<Tree extends Node = Node, Check extends
Test = string>` to properly type visitors from a tree and a test, and
`Visitor<Visited extends Node = Node, Ancestor extends Parent = Parent>` to
build an arbitrary visitor, from `unist-util-visit-parents/complex-types.d.ts`.
## Compatibility

@@ -191,3 +278,3 @@

versions of Node.js.
As of now, that is Node.js 12.20+, 14.14+, 16.0+, and 18.0+.
As of now, that is Node.js 14.14+ and 16.0+.
Our projects sometimes work with older versions, but this is not guaranteed.

@@ -282,18 +369,26 @@

[descendant]: https://github.com/syntax-tree/unist#descendant
[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit
[parent]: https://github.com/syntax-tree/unist#parent-1
[unist-util-is]: https://github.com/syntax-tree/unist-util-is
[sibling]: https://github.com/syntax-tree/unist#sibling
[api-visitparents]: #visitparentstree-test-visitor-reverse
[index]: https://github.com/syntax-tree/unist#index
[api-continue]: #continue
[ancestor]: https://github.com/syntax-tree/unist#ancestor
[api-exit]: #exit
[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit
[api-skip]: #skip
[unist-util-is]: https://github.com/syntax-tree/unist-util-is
[api-action]: #action
[test]: https://github.com/syntax-tree/unist-util-is#test
[api-actiontuple]: #actiontuple
[visitor]: #next--visitornode-ancestors
[api-buildvisitor]: #buildvisitor
[api-index]: #index
[api-test]: #test
[api-visitor]: #visitor
[api-visitorresult]: #visitorresult
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc