@asamuzakjp/dom-selector 8.0.1 → 8.1.1

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/README.md CHANGED
@@ -4,175 +4,214 @@
4
4
  [![CodeQL](https://github.com/asamuzaK/domSelector/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/asamuzaK/domSelector/actions/workflows/github-code-scanning/codeql)
5
5
  [![npm (scoped)](https://img.shields.io/npm/v/@asamuzakjp/dom-selector)](https://www.npmjs.com/package/@asamuzakjp/dom-selector)
6
6
 
7
- A CSS selector engine.
7
+ A CSS selector engine built for strict specification compliance.
8
+
9
+ ## Features
10
+
11
+ * **Strict Specification Compliance**: Strictly adheres to modern web standards. It accurately parses, evaluates, and extracts elements across complex combinations of pseudo-classes and HTML attributes. Features comprehensive support for CSS Selectors Level 4 (e.g., `:is()`, `:not()`, `:where()`, `:has()`) and Shadow DOM pseudo-classes (`:host`, `:host-context`).
12
+ * **Utility Functions**: Provides utility methods alongside standard querying, such as `check()` for AST evaluation and `extractSubjects()` for extracting subject keys from selectors.
13
+ * **jsdom's Default Engine**: Adopted as the CSS selector engine for [jsdom](https://github.com/jsdom/jsdom).
8
14
 
9
15
  ## Install
10
16
 
11
- ```console
17
+ ``` console
12
18
  npm i @asamuzakjp/dom-selector
13
19
  ```
14
20
 
15
21
  ## Usage
16
22
 
17
- ```javascript
23
+ ``` javascript
18
24
  import { DOMSelector } from '@asamuzakjp/dom-selector';
19
25
  import { JSDOM } from 'jsdom';
20
26
 
21
27
  const { window } = new JSDOM();
28
+
29
+ // Destructuring methods (all methods are bound to the instance)
22
30
  const {
23
- closest, matches, querySelector, querySelectorAll
31
+ check, closest, extractSubjects, matches, querySelector, querySelectorAll, supports
24
32
  } = new DOMSelector(window);
25
33
  ```
26
34
 
27
- <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
35
+ ## API
36
+
37
+ ### `new DOMSelector(window, document?, opt?)`
38
+
39
+ Creates an instance of the DOMSelector.
28
40
 
29
- ### matches(selector, node, opt)
41
+ * `window` **{Window}** The window object.
42
+ * `document` **{Document}?** The document object. Defaults to window.document.
43
+ * `opt` **{object}?** Options:
44
+ * `opt.cacheSize` **{number}?** Maximum number of items to store in the internal cache. Default is 2048.
30
45
 
31
- matches - equivalent to [Element.matches()][64]
46
+ ### `matches(selector, node, opt?)`
32
47
 
33
- #### Parameters
48
+ Equivalent to [Element.matches()](https://developer.mozilla.org/docs/Web/API/Element/matches).
34
49
 
35
- - `selector` **[string][59]** CSS selector
36
- - `node` **[object][60]** Element node
37
- - `opt` **[object][60]?** options
38
- - `opt.noexcept` **[boolean][61]?** no exception
39
- - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class
50
+ * `selector` **{string}** CSS selector.
51
+ * `node` **{Element}** Element node.
52
+ * `opt` **{object}?** Options:
53
+ * `opt.noexcept` **{boolean}?** Do not throw exceptions.
54
+ * `opt.warn` **{boolean}?** Console warn (e.g. unsupported pseudo-class).
55
+ * **Returns** **{boolean}** `true` if matched, `false` otherwise.
40
56
 
41
- Returns **[boolean][61]** `true` if matched, `false` otherwise
57
+ ### `closest(selector, node, opt?)`
42
58
 
59
+ Equivalent to [Element.closest()](https://developer.mozilla.org/docs/Web/API/Element/closest).
43
60
 
44
- ### closest(selector, node, opt)
61
+ * `selector` **{string}** CSS selector.
62
+ * `node` **{Element}** Element node.
63
+ * `opt` **{object}?** Options:
64
+ * `opt.noexcept` **{boolean}?** Do not throw exceptions.
65
+ * `opt.warn` **{boolean}?** Console warn (e.g. unsupported pseudo-class).
66
+ * **Returns** **{Element | null}** The matched ancestor node or `null`.
45
67
 
46
- closest - equivalent to [Element.closest()][65]
68
+ ### `querySelector(selector, node, opt?)`
47
69
 
48
- #### Parameters
70
+ Equivalent to [Document.querySelector()](https://developer.mozilla.org/docs/Web/API/Document/querySelector), [DocumentFragment.querySelector()](https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelector) and [Element.querySelector()](https://developer.mozilla.org/docs/Web/API/Element/querySelector).
49
71
 
50
- - `selector` **[string][59]** CSS selector
51
- - `node` **[object][60]** Element node
52
- - `opt` **[object][60]?** options
53
- - `opt.noexcept` **[boolean][61]?** no exception
54
- - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class
72
+ * `selector` **{string}** CSS selector.
73
+ * `node` **{Document | DocumentFragment | Element}** Node to find within.
74
+ * `opt` **{object}?** Options:
75
+ * `opt.noexcept` **{boolean}?** Do not throw exceptions.
76
+ * `opt.warn` **{boolean}?** Console warn (e.g. unsupported pseudo-class).
77
+ * **Returns** **{Element | null}** The matched node or `null`.
55
78
 
56
- Returns **[object][60]?** matched node
79
+ ### `querySelectorAll(selector, node, opt?)`
57
80
 
81
+ Equivalent to [Document.querySelectorAll()](https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll), [DocumentFragment.querySelectorAll()](https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelectorAll) and [Element.querySelectorAll()](https://developer.mozilla.org/docs/Web/API/Element/querySelectorAll).
82
+ **NOTE**: Returns a standard `Array`, not a `NodeList`.
58
83
 
59
- ### querySelector(selector, node, opt)
84
+ * `selector` **{string}** CSS selector.
85
+ * `node` **{Document | DocumentFragment | Element}** Node to find within.
86
+ * `opt` **{object}?** Options:
87
+ * `opt.noexcept` **{boolean}?** Do not throw exceptions.
88
+ * `opt.warn` **{boolean}?** Console warn (e.g. unsupported pseudo-class).
89
+ * **Returns** **{Array}** Array of matched nodes.
60
90
 
61
- querySelector - equivalent to [Document.querySelector()][66], [DocumentFragment.querySelector()][67] and [Element.querySelector()][68]
91
+ ### `check(selector, node, opt?)`
62
92
 
63
- #### Parameters
93
+ Checks if an element matches a CSS selector and returns additional abstract syntax tree (AST) information.
94
+ **NOTE**: Any pseudo-elements in the selector are excluded from the matching evaluation.
64
95
 
65
- - `selector` **[string][59]** CSS selector
66
- - `node` **[object][60]** Document, DocumentFragment or Element node
67
- - `opt` **[object][60]?** options
68
- - `opt.noexcept` **[boolean][61]?** no exception
69
- - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class
96
+ * `selector` **{string}** CSS selector.
97
+ * `node` **{Element}** Element node.
98
+ * `opt` **{object}?** Options:
99
+ * `opt.noexcept` **{boolean}?** Do not throw exceptions.
100
+ * `opt.warn` **{boolean}?** Console warn (e.g. unsupported pseudo-class).
101
+ * **Returns** **{object}** An object containing the following properties:
102
+ * `match` **{boolean}** `true` if the element matches the selector, `false` otherwise.
103
+ * `pseudoElement` **{string | null}** The pseudo-element extracted from the selector, if any.
104
+ * `ast` **{object | null}** The parsed AST object.
70
105
 
71
- Returns **[object][60]?** matched node
106
+ ### `extractSubjects(selector, caseSensitive?)`
72
107
 
108
+ Parses a selector and extracts the rightmost subject keys (Id, Class, Tag).
73
109
 
74
- ### querySelectorAll(selector, node, opt)
110
+ * `selector` **{string}** CSS selector.
111
+ * `caseSensitive` **{boolean}?** `true` if the tag key should be case sensitive. Defaults to `false`.
112
+ * **Returns** **{Array\<{id: string|null, className: string|null, tag: string|null}\>}** An array of extracted keys.
75
113
 
76
- querySelectorAll - equivalent to [Document.querySelectorAll()][69], [DocumentFragment.querySelectorAll()][70] and [Element.querySelectorAll()][71]
77
- **NOTE**: returns Array, not NodeList
114
+ ### `supports(selector)`
78
115
 
79
- #### Parameters
116
+ Checks if the given CSS selector is supported by this engine.
117
+ See the table below for the full list of supported selectors.
80
118
 
81
- - `selector` **[string][59]** CSS selector
82
- - `node` **[object][60]** Document, DocumentFragment or Element node
83
- - `opt` **[object][60]?** options
84
- - `opt.noexcept` **[boolean][61]?** no exception
85
- - `opt.warn` **[boolean][61]?** console warn e.g. unsupported pseudo-class
119
+ * `selector` **{string}** CSS selector.
120
+ * **Returns** **{boolean}** `true` if the selector is supported, `false` otherwise.
86
121
 
87
- Returns **[Array][62]&lt;([object][60] \| [undefined][63])>** array of matched nodes
122
+ ### `clear(clearAll?)`
88
123
 
124
+ Clears the internal caches to free up memory.
125
+
126
+ * `clearAll` **{boolean}?** Whether to clear all caches. If false, only cached matching results are cleared. Defaults to `false`.
127
+ * **Returns** **{void}**
89
128
 
90
129
  ## Supported CSS selectors
91
130
 
92
- |Pattern|Supported|Note|
93
- |:--------|:-------:|:--------|
94
- |\*|✓| |
95
- |E|✓| |
96
- |ns\|E|✓| |
97
- |\*\|E|✓| |
98
- |\|E|✓| |
99
- |E&nbsp;F|✓| |
100
- |E > F|✓| |
101
- |E + F|✓| |
102
- |E ~ F|✓| |
103
- |F \|\| E|Unsupported| |
104
- |E.warning|✓| |
105
- |E#myid|✓| |
106
- |E\[foo\]|✓| |
107
- |E\[foo="bar"\]|✓| |
108
- |E\[foo="bar"&nbsp;i\]|✓| |
109
- |E\[foo="bar"&nbsp;s\]|✓| |
110
- |E\[foo~="bar"\]|✓| |
111
- |E\[foo^="bar"\]|✓| |
112
- |E\[foo$="bar"\]|✓| |
113
- |E\[foo*="bar"\]|✓| |
114
- |E\[foo\|="en"\]|✓| |
115
- |E:is(s1, s2, …)|✓| |
116
- |E:not(s1, s2, …)|✓| |
117
- |E:where(s1, s2, …)|✓| |
118
- |E:has(rs1, rs2, …)|✓| |
119
- |E:defined|Partially supported|Matching with MathML is not yet supported.|
120
- |E:dir(ltr)|✓| |
121
- |E:lang(en)|✓| |
122
- |E:any&#8209;link|✓| |
123
- |E:link|✓| |
124
- |E:visited|✓|Returns `false` or `null` to prevent fingerprinting.|
125
- |E:local&#8209;link|✓| |
126
- |E:target|✓| |
127
- |E:target&#8209;within|✓| |
128
- |E:scope|✓| |
129
- |E:hover|✓| |
130
- |E:active|✓| |
131
- |E:focus|✓| |
132
- |E:focus&#8209;visible|✓| |
133
- |E:focus&#8209;within|✓| |
134
- |E:current|Unsupported| |
135
- |E:current(s)|Unsupported| |
136
- |E:past|Unsupported| |
137
- |E:future|Unsupported| |
138
- |E:open<br>E:closed|Partially supported|Matching with &lt;select&gt;, e.g. `select:open`, is not supported.|
139
- |E:popover-open|Unsupported| |
140
- |E:enabled<br>E:disabled|✓| |
141
- |E:read&#8209;write<br>E:read&#8209;only|✓| |
142
- |E:placeholder&#8209;shown|✓| |
143
- |E:default|✓| |
144
- |E:checked|✓| |
145
- |E:indeterminate|✓| |
146
- |E:blank|Unsupported| |
147
- |E:valid<br>E:invalid|✓| |
148
- |E:in-range<br>E:out-of-range|✓| |
149
- |E:required<br>E:optional|✓| |
150
- |E:user&#8209;valid<br>E:user&#8209;invalid|Unsupported| |
151
- |E:root|✓| |
152
- |E:empty|✓| |
153
- |E:nth&#8209;child(n&nbsp;[of&nbsp;S]?)|✓| |
154
- |E:nth&#8209;last&#8209;child(n&nbsp;[of&nbsp;S]?)|✓| |
155
- |E:first&#8209;child|✓| |
156
- |E:last&#8209;child|✓| |
157
- |E:only&#8209;child|✓| |
158
- |E:nth&#8209;of&#8209;type(n)|✓| |
159
- |E:nth&#8209;last&#8209;of&#8209;type(n)|✓| |
160
- |E:first&#8209;of&#8209;type|✓| |
161
- |E:last&#8209;of&#8209;type|✓| |
162
- |E:only&#8209;of&#8209;type|✓| |
163
- |E:nth&#8209;col(n)|Unsupported| |
164
- |E:nth&#8209;last&#8209;col(n)|Unsupported| |
165
- |CE:state(v)|✓|*1|
166
- |:host|✓| |
167
- |:host(s)|✓| |
168
- |:host(:state(v))|✓|*1|
169
- |:host:has(rs1, rs2, ...)|✓| |
170
- |:host(s):has(rs1, rs2, ...)|✓| |
171
- |:host&#8209;context(s)|✓| |
172
- |:host&#8209;context(s):has(rs1, rs2, ...)|✓| |
173
- |&amp;|✓|Only supports outermost `&`, i.e. equivalent to `:scope`|
174
-
175
- *1: `ElementInternals.states`, i.e. `CustomStateSet`, is not implemented in jsdom, so you need to apply a patch in the custom element constructor.
131
+ | Pattern | Supported | Note |
132
+ | :--- | :---: | :--- |
133
+ | `*` | ✓ | |
134
+ | `E` | ✓ | |
135
+ | <code>ns\|E</code> | ✓ | |
136
+ | <code>*\|E</code> | ✓ | |
137
+ | <code>\|E</code> | ✓ | |
138
+ | `E F` | ✓ | |
139
+ | `E > F` | ✓ | |
140
+ | `E + F` | ✓ | |
141
+ | `E ~ F` | ✓ | |
142
+ | <code>F \|\| E</code> | Unsupported | |
143
+ | `E.warning` | ✓ | |
144
+ | `E#myid` | ✓ | |
145
+ | `E[foo]` | ✓ | |
146
+ | `E[foo="bar"]` | ✓ | |
147
+ | `E[foo="bar" i]` | ✓ | |
148
+ | `E[foo="bar" s]` | ✓ | |
149
+ | `E[foo~="bar"]` | ✓ | |
150
+ | `E[foo^="bar"]` | ✓ | |
151
+ | `E[foo$="bar"]` | ✓ | |
152
+ | `E[foo*="bar"]` | ✓ | |
153
+ | <code>E[foo\|="en"]</code> | ✓ | |
154
+ | `E:is(s1, s2, …)` | ✓ | |
155
+ | `E:not(s1, s2, …)` | ✓ | |
156
+ | `E:where(s1, s2, …)` | ✓ | |
157
+ | `E:has(rs1, rs2, …)` | ✓ | |
158
+ | `E:defined` | Partially supported | Matching with MathML is not yet supported. |
159
+ | `E:dir(ltr)` | ✓ | |
160
+ | `E:lang(en)` | ✓ | |
161
+ | `E:any-link` | ✓ | |
162
+ | `E:link` | ✓ | |
163
+ | `E:visited` | ✓ | Returns `false` or `null` to prevent fingerprinting. |
164
+ | `E:local-link` | ✓ | |
165
+ | `E:target` | ✓ | |
166
+ | `E:target-within` | | Removed from spec. |
167
+ | `E:scope` | ✓ | |
168
+ | `E:hover` | ✓ | |
169
+ | `E:active` | ✓ | |
170
+ | `E:focus` | ✓ | |
171
+ | `E:focus-visible` | ✓ | |
172
+ | `E:focus-within` | ✓ | |
173
+ | `E:current` | Unsupported | |
174
+ | `E:current(s)` | Unsupported | |
175
+ | `E:past` | Unsupported | |
176
+ | `E:future` | Unsupported | |
177
+ | `E:open` | Partially supported | Matching with `<select>`, e.g. `select:open`, or `<input type="color">` are not supported. |
178
+ | `E:popover-open` | Unsupported | |
179
+ | `E:enabled`<br>`E:disabled` | ✓ | |
180
+ | `E:read-write`<br>`E:read-only` | ✓ | |
181
+ | `E:placeholder-shown` | ✓ | |
182
+ | `E:default` | ✓ | |
183
+ | `E:checked` | ✓ | |
184
+ | `E:indeterminate` | ✓ | |
185
+ | `E:blank` | Unsupported | |
186
+ | `E:valid`<br>`E:invalid` | ✓ | |
187
+ | `E:in-range`<br>`E:out-of-range` | ✓ | |
188
+ | `E:required`<br>`E:optional` | ✓ | |
189
+ | `E:user-valid`<br>`E:user-invalid` | Unsupported | |
190
+ | `E:root` | ✓ | |
191
+ | `E:empty` | ✓ | |
192
+ | `E:nth-child(n [of S]?)` | ✓ | |
193
+ | `E:nth-last-child(n [of S]?)` | ✓ | |
194
+ | `E:first-child` | ✓ | |
195
+ | `E:last-child` | ✓ | |
196
+ | `E:only-child` | ✓ | |
197
+ | `E:nth-of-type(n)` | ✓ | |
198
+ | `E:nth-last-of-type(n)` | ✓ | |
199
+ | `E:first-of-type` | ✓ | |
200
+ | `E:last-of-type` | ✓ | |
201
+ | `E:only-of-type` | ✓ | |
202
+ | `E:nth-col(n)` | Unsupported | |
203
+ | `E:nth-last-col(n)` | Unsupported | |
204
+ | `CE:state(v)` | ✓ | \*1 |
205
+ | `:host` | ✓ | |
206
+ | `:host(s)` | ✓ | |
207
+ | `:host(:state(v))` | ✓ | \*1 |
208
+ | `:host:has(rs1, rs2, ...)` | ✓ | |
209
+ | `:host(s):has(rs1, rs2, ...)` | ✓ | |
210
+ | `:host-context(s)` | ✓ | |
211
+ | `:host-context(s):has(rs1, rs2, ...)` | ✓ | |
212
+ | `&` | ✓ | Only supports outermost `&`, i.e. equivalent to `:scope` |
213
+
214
+ \*1: `ElementInternals.states`, i.e. `CustomStateSet`, is not implemented in jsdom, so you need to apply a patch in the custom element constructor.
176
215
 
177
216
  ``` javascript
178
217
  class LabeledCheckbox extends window.HTMLElement {
@@ -202,43 +241,19 @@ class LabeledCheckbox extends window.HTMLElement {
202
241
  }
203
242
  ```
204
243
 
205
-
206
244
  ## Performance
207
245
 
208
246
  See [benchmark](https://github.com/asamuzaK/domSelector/actions/workflows/benchmark.yml) for the latest results.
209
247
 
210
-
211
248
  ## Acknowledgments
212
249
 
213
250
  The following resources have been of great help in the development of the DOM Selector.
214
251
 
215
- - [CSSTree](https://github.com/csstree/csstree)
216
- - [selery](https://github.com/danburzo/selery)
217
- - [jsdom](https://github.com/jsdom/jsdom)
218
- - [nwsapi](https://github.com/dperini/nwsapi)
252
+ * [CSSTree](https://github.com/csstree/csstree)
253
+ * [selery](https://github.com/danburzo/selery)
254
+ * [jsdom](https://github.com/jsdom/jsdom)
255
+ * [nwsapi](https://github.com/dperini/nwsapi)
219
256
 
220
257
  ---
221
- Copyright (c) 2023 [asamuzaK (Kazz)](https://github.com/asamuzaK/)
222
-
223
258
 
224
- [1]: #matches
225
- [2]: #parameters
226
- [3]: #closest
227
- [4]: #parameters-1
228
- [5]: #queryselector
229
- [6]: #parameters-2
230
- [7]: #queryselectorall
231
- [8]: #parameters-3
232
- [59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
233
- [60]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
234
- [61]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
235
- [62]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
236
- [63]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined
237
- [64]: https://developer.mozilla.org/docs/Web/API/Element/matches
238
- [65]: https://developer.mozilla.org/docs/Web/API/Element/closest
239
- [66]: https://developer.mozilla.org/docs/Web/API/Document/querySelector
240
- [67]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelector
241
- [68]: https://developer.mozilla.org/docs/Web/API/Element/querySelector
242
- [69]: https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll
243
- [70]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelectorAll
244
- [71]: https://developer.mozilla.org/docs/Web/API/Element/querySelectorAll
259
+ Copyright (c) 2023 [asamuzaK (Kazz)](https://github.com/asamuzaK/)
package/package.json CHANGED
@@ -16,6 +16,7 @@
16
16
  "types"
17
17
  ],
18
18
  "type": "module",
19
+ "types": "./types/index.d.ts",
19
20
  "exports": {
20
21
  ".": {
21
22
  "types": "./types/index.d.ts",
@@ -24,31 +25,31 @@
24
25
  "./package.json": "./package.json"
25
26
  },
26
27
  "dependencies": {
27
- "@asamuzakjp/generational-cache": "^2.0.1",
28
+ "@asamuzakjp/generational-cache": "^2.0.4",
28
29
  "bidi-js": "^1.0.3",
29
30
  "css-tree": "^3.2.1",
30
31
  "is-potential-custom-element-name": "^1.0.1"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/css-tree": "^2.3.11",
34
- "@types/node": "^25.6.0",
35
+ "@types/node": "^25.9.3",
35
36
  "c8": "^11.0.0",
36
37
  "chai": "^6.2.2",
37
- "commander": "^14.0.3",
38
+ "commander": "^15.0.0",
38
39
  "eslint": "^9.39.4",
39
40
  "eslint-config-prettier": "^10.1.8",
40
- "eslint-plugin-jsdoc": "^62.9.0",
41
- "eslint-plugin-prettier": "^5.5.5",
41
+ "eslint-plugin-jsdoc": "^63.0.2",
42
+ "eslint-plugin-prettier": "^5.5.6",
42
43
  "eslint-plugin-regexp": "^3.1.0",
43
- "eslint-plugin-unicorn": "^64.0.0",
44
+ "eslint-plugin-unicorn": "^65.0.1",
44
45
  "globals": "^17.6.0",
45
46
  "jsdom": "^29.1.1",
46
47
  "mitata": "^1.0.34",
47
- "mocha": "^11.7.5",
48
+ "mocha": "^11.7.6",
48
49
  "neostandard": "^0.13.0",
49
- "prettier": "^3.8.3",
50
- "sinon": "^21.1.2",
51
- "tinybench": "^6.0.1",
50
+ "prettier": "^3.8.4",
51
+ "sinon": "^22.0.0",
52
+ "tinybench": "^6.0.2",
52
53
  "typescript": "^6.0.3",
53
54
  "wpt-runner": "^7.0.0"
54
55
  },
@@ -69,6 +70,12 @@
69
70
  "bench": "node benchmark/bench.js",
70
71
  "bench:cache": "node benchmark/bench-cache.js",
71
72
  "bench:nwsapi": "node benchmark/bench-nwsapi.js",
73
+ "bench:ps-form": "node benchmark/bench-default.js && node benchmark/bench-indeterminate.js && node benchmark/bench-valid-invalid.js",
74
+ "bench:ps-has": "node benchmark/bench-has.js",
75
+ "bench:ps-nth": "node benchmark/bench-nth-child.js && node benchmark/bench-nth-of-type.js",
76
+ "bench:ps-traverse": "node benchmark/bench-dir.js && node benchmark/bench-lang.js",
77
+ "bench:ts": "node benchmark/bench-testing-library.js",
78
+ "bench:universal": "node benchmark/bench-universal.js",
72
79
  "build": "npm run tsc && npm run lint && npm test",
73
80
  "lint": "eslint --fix .",
74
81
  "test": "c8 --reporter=text mocha --exit test/**/*.test.js",
@@ -79,5 +86,5 @@
79
86
  "engines": {
80
87
  "node": "^22.13.0 || >=24.0.0"
81
88
  },
82
- "version": "8.0.1"
89
+ "version": "8.1.1"
83
90
  }