rusteerio 1.0.1 → 1.1.0

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.
Files changed (57) hide show
  1. package/Cargo.lock +42 -1
  2. package/Cargo.toml +8 -1
  3. package/README.md +90 -51
  4. package/THIRD_PARTY_NOTICES.md +107 -2
  5. package/dist/{chunk-DMRD3FGC.mjs → chunk-FPRP6UIX.mjs} +2233 -751
  6. package/dist/chunk-FPRP6UIX.mjs.map +1 -0
  7. package/dist/index.cjs +2232 -750
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.mts +2 -2
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.mjs +1 -1
  12. package/dist/slim.cjs +2226 -745
  13. package/dist/slim.cjs.map +1 -1
  14. package/dist/slim.d.mts +2 -2
  15. package/dist/slim.d.ts +2 -2
  16. package/dist/slim.mjs +1 -1
  17. package/dist/{types-BP6TpxE5.d.mts → types-Cs9UP1Vv.d.mts} +3 -3
  18. package/dist/{types-BP6TpxE5.d.ts → types-Cs9UP1Vv.d.ts} +3 -3
  19. package/dist/utils.d.mts +1 -1
  20. package/dist/utils.d.ts +1 -1
  21. package/native/src/arena.rs +219 -80
  22. package/native/src/attributes.rs +11 -5
  23. package/native/src/document_order.rs +711 -0
  24. package/native/src/extraction.rs +15 -3
  25. package/native/src/gc.rs +12 -3
  26. package/native/src/id_hash.rs +42 -0
  27. package/native/src/immutable.rs +256 -0
  28. package/native/src/lib.rs +1039 -171
  29. package/native/src/runtime.rs +189 -33
  30. package/native/src/selector.rs +346 -44
  31. package/native/src/sink.rs +14 -1
  32. package/native/src/snapshot.rs +509 -0
  33. package/native/src/stream.rs +2 -2
  34. package/native/src/tokenizer.rs +29 -12
  35. package/native/vendor/html5ever-0.35.0/src/tokenizer/char_ref/mod.rs +79 -0
  36. package/package.json +3 -1
  37. package/rusteerio.darwin-arm64.node +0 -0
  38. package/rusteerio.darwin-x64.node +0 -0
  39. package/rusteerio.linux-arm64-gnu.node +0 -0
  40. package/rusteerio.linux-arm64-musl.node +0 -0
  41. package/rusteerio.linux-x64-gnu.node +0 -0
  42. package/rusteerio.linux-x64-musl.node +0 -0
  43. package/rusteerio.win32-arm64-msvc.node +0 -0
  44. package/rusteerio.win32-x64-msvc.node +0 -0
  45. package/src/attributes.ts +78 -44
  46. package/src/codec.ts +22 -3
  47. package/src/extract.ts +86 -2
  48. package/src/hooks.ts +148 -2
  49. package/src/index.ts +51 -40
  50. package/src/match.ts +207 -0
  51. package/src/native.ts +9 -1
  52. package/src/nodes.ts +531 -183
  53. package/src/router.ts +792 -229
  54. package/src/selection.ts +239 -125
  55. package/src/snapshot.ts +255 -0
  56. package/src/transport.ts +51 -42
  57. package/dist/chunk-DMRD3FGC.mjs.map +0 -1
package/Cargo.lock CHANGED
@@ -23,6 +23,16 @@ version = "1.5.0"
23
23
  source = "registry+https://github.com/rust-lang/crates.io-index"
24
24
  checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
25
25
 
26
+ [[package]]
27
+ name = "cc"
28
+ version = "1.8.0"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "6651c9ed80effdc7db0ff72512157f901af5e3549e341e24b1dd4887d836d838"
31
+ dependencies = [
32
+ "find-msvc-tools",
33
+ "shlex",
34
+ ]
35
+
26
36
  [[package]]
27
37
  name = "cfg-if"
28
38
  version = "1.0.5"
@@ -161,6 +171,12 @@ version = "1.0.2"
161
171
  source = "registry+https://github.com/rust-lang/crates.io-index"
162
172
  checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
163
173
 
174
+ [[package]]
175
+ name = "find-msvc-tools"
176
+ version = "0.1.14"
177
+ source = "registry+https://github.com/rust-lang/crates.io-index"
178
+ checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484"
179
+
164
180
  [[package]]
165
181
  name = "foldhash"
166
182
  version = "0.2.0"
@@ -359,6 +375,15 @@ dependencies = [
359
375
  "windows-link",
360
376
  ]
361
377
 
378
+ [[package]]
379
+ name = "libmimalloc-sys"
380
+ version = "0.1.49"
381
+ source = "registry+https://github.com/rust-lang/crates.io-index"
382
+ checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
383
+ dependencies = [
384
+ "cc",
385
+ ]
386
+
362
387
  [[package]]
363
388
  name = "litemap"
364
389
  version = "0.8.3"
@@ -412,6 +437,15 @@ version = "2.8.3"
412
437
  source = "registry+https://github.com/rust-lang/crates.io-index"
413
438
  checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
414
439
 
440
+ [[package]]
441
+ name = "mimalloc"
442
+ version = "0.1.52"
443
+ source = "registry+https://github.com/rust-lang/crates.io-index"
444
+ checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
445
+ dependencies = [
446
+ "libmimalloc-sys",
447
+ ]
448
+
415
449
  [[package]]
416
450
  name = "napi"
417
451
  version = "2.16.17"
@@ -686,11 +720,12 @@ dependencies = [
686
720
 
687
721
  [[package]]
688
722
  name = "rusteerio"
689
- version = "1.0.1"
723
+ version = "1.1.0"
690
724
  dependencies = [
691
725
  "ego-tree",
692
726
  "html5ever",
693
727
  "html5gum",
728
+ "mimalloc",
694
729
  "napi",
695
730
  "napi-build",
696
731
  "napi-derive",
@@ -801,6 +836,12 @@ dependencies = [
801
836
  "stable_deref_trait",
802
837
  ]
803
838
 
839
+ [[package]]
840
+ name = "shlex"
841
+ version = "2.0.1"
842
+ source = "registry+https://github.com/rust-lang/crates.io-index"
843
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
844
+
804
845
  [[package]]
805
846
  name = "siphasher"
806
847
  version = "1.0.4"
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rusteerio"
3
- version = "1.0.1"
3
+ version = "1.1.0"
4
4
  edition = "2021"
5
5
  description = "Rust HTML5 parser and CSS selector engine for the rusteerio Node.js package"
6
6
  license = "MIT"
@@ -21,6 +21,13 @@ scraper = { version = "0.24", default-features = false, features = ["atomic", "d
21
21
  serde = { version = "1", features = ["derive"] }
22
22
  serde_json = { version = "1", features = ["preserve_order"] }
23
23
 
24
+ # Parsing and tree writes allocate many small objects, which glibc's and musl's
25
+ # allocators serve slowly. The addon is loaded with dlopen, so mimalloc uses the
26
+ # dynamic TLS model; other platforms keep their allocator, since macOS mimalloc
27
+ # stores its thread heap in a fixed TLS slot that a second copy would share.
28
+ [target.'cfg(target_os = "linux")'.dependencies]
29
+ mimalloc = { version = "0.1", default-features = false, features = ["local_dynamic_tls"] }
30
+
24
31
  [build-dependencies]
25
32
  napi-build = "2"
26
33
 
package/README.md CHANGED
@@ -113,7 +113,11 @@ The per-batch `threads` option can lower a batch's parallelism within that share
113
113
  budget. Results preserve input order. `{ xml: true, threads: 4 }` works too.
114
114
  `workerPoolInfo()` reports `threads`, `activeBatches`, `activeWorkers` and
115
115
  `peakActiveWorkers`. The cap measures active CPU work; streams can have additional
116
- parked threads waiting for input or a JavaScript callback.
116
+ parked threads waiting for input or a JavaScript callback. Synchronous calls use
117
+ idle workers of the same pool for large internal work, such as copying a large
118
+ parse tree into the mutable tree on its first write or freeing a large tree, and
119
+ never wait for a busy worker. Before the pool exists, one background thread frees
120
+ large trees, so collecting a large document does not stall JavaScript.
117
121
 
118
122
  Synchronous `load()`, queries, mutations and serialization **block the main
119
123
  thread** while they run. The async APIs move heavy native work onto workers;
@@ -138,9 +142,14 @@ JavaScript. Arbitrary custom tokenizers can refer to earlier source offsets, so
138
142
  that path retains the source until completion. Source locations retain extra
139
143
  metadata; avoid enabling them when you do not need it.
140
144
 
141
- DOM views expose writable Cheerio-compatible fields and stable identity. Removed
142
- branches stay usable while their selections or nodes are held; unreachable
143
- branches can be reclaimed and their Rust storage reused. The optional `dom`
145
+ DOM views expose writable Cheerio-compatible fields and stable identity. Their
146
+ fields are accessors on the prototype, so `Object.keys(node)` is empty; read
147
+ `node.attribs`, `node.children` and the other fields directly. Change the tree
148
+ through the Cheerio API or by assigning node fields: writing an index or the
149
+ `length` of a `children` array changes only that array. Removed branches stay
150
+ usable while their selections or nodes are held, and a held node keeps its
151
+ document alive; unreachable branches can be reclaimed and their Rust storage
152
+ reused. The optional `dom`
144
153
  namespace exports constructors such as `dom.Element`, `dom.Text` and
145
154
  `dom.Document`. Nodes imported from another DOM retain their original prototype.
146
155
  Fresh Rust-backed nodes have Rusteerio's constructors: an `instanceof` check
@@ -148,57 +157,86 @@ against an independently installed `domhandler.Element` requires importing those
148
157
  nodes or supplying a tree adapter that creates that class.
149
158
 
150
159
  Each document reports its approximate native size to V8, so the garbage
151
- collector reclaims unreachable documents under native memory pressure. Node.js
152
- frees native memory after the current task completes. A long synchronous loop,
153
- or a chain of already-resolved `await`s, that loads many large documents should
154
- yield to the event loop periodically, for example with `await setImmediate()`
155
- from `node:timers/promises`.
160
+ collector reclaims unreachable documents under native memory pressure. A
161
+ document's Rust tree is freed when V8 collects the document, including during
162
+ a long synchronous loop: loading 60 documents of 36 MB each in one synchronous
163
+ loop grows RSS by about 100 MB after the first 20, where earlier releases held
164
+ every tree until the loop ended.
156
165
 
157
166
  ## Benchmarks
158
167
 
159
168
  These measurements compare **Cheerio 1.2.0** against rusteerio on a Linux x64
160
- **VM with 8 vCPUs and 16 GB RAM**, running Node 24.18.1. Both engines have the
161
- same enforced CPU budget. Batch comparisons give Cheerio a reused Node worker
162
- pool and include each engine's input and result conversion. Values are medians
163
- of nine samples, with equal output checked for all **810 measured samples**.
164
-
165
- Rusteerio was faster in **39 of 45 cases**. Representative results, including
166
- each kind of measured loss:
167
-
168
- | Workload | CPUs | Cheerio | rusteerio | Rust latency |
169
+ **VM with 8 vCPUs and 16 GB RAM** (AMD Ryzen 9 9950X host), running Node
170
+ 24.18.1. Every benchmark checks that both engines produce the same output.
171
+
172
+ **Real pages.** 5,000 pages from a public Common Crawl archive each ran a
173
+ typical extraction job: load, title and metadata, headings, links, images with
174
+ their link ancestry and depth, structured data, a paragraph filter, an element
175
+ count, removal of scripts and styles, body text and serialization. Outputs were
176
+ identical on all 5,000 pages, and times include loading.
177
+
178
+ | Measure | Result |
179
+ | --- | --- |
180
+ | Total time | Cheerio 17.8 s, rusteerio 9.1 s: **1.97× faster** |
181
+ | Pages where rusteerio was faster | **4,973 of 5,000** |
182
+ | Per-page speedup, 10th / 50th / 90th percentile | 1.21× / 1.51× / 1.92× |
183
+ | Slowest page | 0.78×, a 4 KB page |
184
+
185
+ The 27 slower pages are all small, where a few microseconds decide the ratio.
186
+
187
+ **Single operations.** `bench/operations.mjs` times 25 operations on freshly
188
+ loaded generated documents of 200 and 2,000 cards. Including each engine's load
189
+ time, rusteerio was faster for **48 to 49 of 50** HTML measurements across three
190
+ runs (median 1.81–1.89×). XML results varied more between runs: **29 to 41 of 50**
191
+ (median 1.08–1.38×). HTML loading alone was 1.76–1.96× faster; XML loading of the
192
+ large document ranged from parity to 1.39× faster.
193
+
194
+ **Matched CPU budgets.** `bench/fair.mjs` gives both engines the same enforced
195
+ CPU budget; batch comparisons give Cheerio a reused Node worker pool and include
196
+ each engine's input and result conversion. Values are medians of nine samples.
197
+ Rusteerio was faster in **all 45 cases**. Representative results:
198
+
199
+ | Workload | CPUs | Cheerio | rusteerio | rusteerio |
169
200
  | --- | ---: | ---: | ---: | --- |
170
- | Load/query, 500 articles | 1 | 35.25 ms | 4.08 ms | 8.64× faster |
171
- | Load/query, 5,000 articles | 1 | 150.57 ms | 41.64 ms | 3.62× faster |
172
- | HTML mutations, 5,000 articles | 1 | 239.65 ms | 189.49 ms | 1.26× faster |
173
- | Extract 16 documents × 5,000 articles | 1 | 2,887.61 ms | 511.48 ms | 5.65× faster |
174
- | Extract 16 documents × 5,000 articles | 8 | 797.55 ms | 114.70 ms | 6.95× faster |
175
- | Nested callback extraction, 8 × 500 articles | 8 | 54.30 ms | 174.06 ms | 3.21× slower |
176
- | Cold extraction, 16 × 20 articles | 8 | 169.23 ms | 27.37 ms | 6.18× faster |
177
- | HTML stream, 50,000 elements | 1 | 1,107.78 ms | 346.21 ms | 3.20× faster |
178
- | XML stream, 50,000 elements | 8 | 119.85 ms | 162.28 ms | 1.35× slower |
179
- | Append/update/remove, 4,000 cycles | 1 | 593.28 ms | 614.76 ms | 1.04× slower |
201
+ | Load/query, 500 articles | 1 | 38.01 ms | 3.61 ms | 10.52× faster |
202
+ | Load/query, 5,000 articles | 1 | 172.87 ms | 39.17 ms | 4.41× faster |
203
+ | HTML mutations, 5,000 articles | 1 | 249.72 ms | 84.42 ms | 2.96× faster |
204
+ | XML load/query, 5,000 articles | 1 | 69.34 ms | 18.20 ms | 3.81× faster |
205
+ | Extract 16 documents × 5,000 articles | 1 | 3,441.82 ms | 533.58 ms | 6.45× faster |
206
+ | Extract 16 documents × 5,000 articles | 8 | 1,126.61 ms | 179.02 ms | 6.29× faster |
207
+ | Nested callback extraction, 8 × 500 articles | 8 | 78.27 ms | 52.03 ms | 1.50× faster |
208
+ | Cold extraction, 16 × 20 articles | 8 | 179.01 ms | 33.78 ms | 5.30× faster |
209
+ | 8 concurrent batches × 8 × 300 articles | 8 | 125.86 ms | 22.99 ms | 5.47× faster |
210
+ | HTML stream, 50,000 elements | 1 | 1,364.09 ms | 328.79 ms | 4.15× faster |
211
+ | XML stream, 50,000 elements | 8 | 123.17 ms | 100.52 ms | 1.23× faster |
212
+ | Append/update/remove, 4,000 cycles | 1 | 666.87 ms | 458.55 ms | 1.45× faster |
180
213
 
181
214
  Cold measurements include engine import, pool initialization and the first
182
- batch. Warm extraction excludes initialization. Large extraction improved
183
- from 511.48 ms with one Rust worker to 114.70 ms with eight, a **4.46×** scaling
184
- gain. Concurrent batches also respected the shared native CPU cap.
185
-
186
- Callbacks remain JavaScript work. Cheerio's benchmark workers execute callbacks
187
- on their own threads; rusteerio preserves user closures on the calling thread.
188
- All four callback workloads were slower than the Cheerio worker pool. Native
189
- async work also involves main-thread conversion: the large eight CPU extraction
190
- case had 24.06 ms median maximum timer lag, versus 3.49 ms for Cheerio's workers.
191
-
192
- Memory results vary. The HTML stream's median end RSS was 372.6 MB for rusteerio
193
- and 698.5 MB for Cheerio at one CPU; the XML stream used 275.4 MB versus 228.7 MB
194
- at eight CPUs. Removed-node storage plateaued after warm-up in the retention
195
- workload, but RSS still grew initially. RSS includes initialization and resident
196
- input, and sampled peaks do not establish a universal memory bound.
197
-
198
- These deterministic generated fixtures describe this VM and revision. Hardware,
199
- runtime and input shape affect results. See [all 45 results](bench/results/fair/comparison.json)
200
- and [the methodology, raw samples and reproduction steps](bench/README.md),
201
- including regressions against the previous Rust implementation.
215
+ batch.
216
+
217
+ **Where Cheerio can be faster.** Rusteerio builds node objects lazily from the
218
+ native tree, so code that visits every node through DOM properties (walking
219
+ `children` and reading `attribs` of every element) pays for creating those
220
+ objects. Including load, that walk was 0.83–0.99× in HTML and 0.37–0.83× in XML,
221
+ where Cheerio's htmlparser2 parser leaves less load time to win back. On the
222
+ large XML document, wrapping thousands of elements one by one (`$(element)` with
223
+ `.attr()`, `.parents()`, `.siblings()` or `.next()`), appending to thousands of
224
+ elements and rewriting attributes element by element measured 0.58–0.97×. Very
225
+ small pages can measure either way.
226
+
227
+ **Memory.** A batch extracting 16 documents of 5,000 articles with eight CPUs
228
+ ended at 595 MB RSS for rusteerio and 2,535 MB for Cheerio's worker pool, and the
229
+ HTML stream of 50,000 elements at 491 MB versus 664 MB. The XML stream ended
230
+ higher, at 421 MB versus 218 MB, and the append/update/remove workload about even
231
+ (93 MB versus 90 MB). Linux builds use mimalloc, which keeps freed pages briefly
232
+ for reuse; setting `MIMALLOC_PURGE_DELAY=0` returns them at once and lowered the
233
+ streams to 363 MB (HTML) and 286 MB (XML), at a cost in speed for later
234
+ documents. RSS includes initialization and resident input, and sampled peaks do
235
+ not establish a universal memory bound.
236
+
237
+ These results describe this VM and revision; hardware, runtime and input shape
238
+ affect them. See [the results](bench/results/2026-10-14/) and
239
+ [the methodology and reproduction steps](bench/README.md).
202
240
 
203
241
  ## Compatibility and tests
204
242
 
@@ -207,9 +245,10 @@ The compatibility target is **Cheerio 1.2.0**. All **777 upstream tests across a
207
245
  and fixtures are unchanged; implementation imports are redirected. An integrity
208
246
  check verifies the complete inventory and source checksums before each run.
209
247
 
210
- The additional **418 runtime and release checks** cover custom parser hooks,
211
- streaming encodings and HTTP, detached-node retention, extraction callbacks and
212
- shared CPU limits. **53 Rust tests**, strict TypeScript consumer checks, and clean
248
+ The additional **501 runtime and release checks** cover custom parser hooks,
249
+ streaming encodings and HTTP, detached-node retention and reuse, cross-document
250
+ moves, memory release, extraction callbacks, shared CPU limits and Cheerio's
251
+ selection order. **57 Rust tests**, strict TypeScript consumer checks, and clean
213
252
  npm tarball installation checks run as well. CI builds and tests all eight
214
253
  native targets
215
254
  and checks Node 20.19, 22 and 24. GNU binaries are built and run on glibc 2.28;
@@ -4,7 +4,7 @@ This file preserves third-party license and attribution notices for the Rust nat
4
4
 
5
5
  Generated by `node scripts/generate-notices.mjs` from `cargo metadata --locked`, crate license files, and the pinned supplemental sources recorded in `scripts/notices/sources.json`. It includes build dependencies and dependencies for all target platforms; a particular binary may use a subset. Identical notice texts are reproduced once and referenced below. The html5ever, markup5ever and html5gum crates contain local observer-hook and opt-in UTF-16 transport patches; their complete patched source and original notices are included in `native/vendor`. Other dependency source files are unmodified.
6
6
 
7
- Cargo.lock SHA-256: `42f353a71e79c84b5415fbfa8581ddd3c1aefa2b8c15f78a876631c8a9be2a68`.
7
+ Cargo.lock SHA-256: `a7962957958e0640ea9e40f025e877864c03bd5934a1ca2e19df80a5481d72ff`.
8
8
 
9
9
  ## Source availability
10
10
 
@@ -24,7 +24,7 @@ The htmlparser2-compatible markup tokenizer in `native/src/markup_tokenizer.rs`
24
24
 
25
25
  - [htmlparser2 MIT LICENSE](#notice-204cfa747341660e) — [upstream source](https://github.com/fb55/htmlparser2/blob/57ace50bf6eb3bfab0468deafe10d0a8a2f233aa/LICENSE)
26
26
 
27
- ## Rust dependencies (112 locked packages)
27
+ ## Rust dependencies (117 locked packages)
28
28
 
29
29
  ### aho-corasick 1.1.5
30
30
 
@@ -55,6 +55,15 @@ Source: [byteorder 1.5.0 source archive](https://crates.io/api/v1/crates/byteord
55
55
  - [LICENSE-MIT](#notice-0f96a83840e146e4) — [notice source](https://docs.rs/crate/byteorder/1.5.0/source/LICENSE-MIT)
56
56
  - [UNLICENSE](#notice-7e12e5df4bae12cb) — [notice source](https://docs.rs/crate/byteorder/1.5.0/source/UNLICENSE)
57
57
 
58
+ ### cc 1.8.0
59
+
60
+ Declared license: `MIT OR Apache-2.0`.
61
+
62
+ Source: [cc 1.8.0 source archive](https://crates.io/api/v1/crates/cc/1.8.0/download).
63
+
64
+ - [LICENSE-APACHE](#notice-a60eea8175145316) — [notice source](https://docs.rs/crate/cc/1.8.0/source/LICENSE-APACHE)
65
+ - [LICENSE-MIT](#notice-378f5840b258e277) — [notice source](https://docs.rs/crate/cc/1.8.0/source/LICENSE-MIT)
66
+
58
67
  ### cfg-if 1.0.5
59
68
 
60
69
  Declared license: `MIT OR Apache-2.0`.
@@ -192,6 +201,15 @@ Source: [equivalent 1.0.2 source archive](https://crates.io/api/v1/crates/equiva
192
201
  - [LICENSE-APACHE](#notice-a60eea8175145316) — [notice source](https://docs.rs/crate/equivalent/1.0.2/source/LICENSE-APACHE)
193
202
  - [LICENSE-MIT](#notice-7365cc8878a1d7ce) — [notice source](https://docs.rs/crate/equivalent/1.0.2/source/LICENSE-MIT)
194
203
 
204
+ ### find-msvc-tools 0.1.14
205
+
206
+ Declared license: `MIT OR Apache-2.0`.
207
+
208
+ Source: [find-msvc-tools 0.1.14 source archive](https://crates.io/api/v1/crates/find-msvc-tools/0.1.14/download).
209
+
210
+ - [LICENSE-APACHE](#notice-a60eea8175145316) — [notice source](https://docs.rs/crate/find-msvc-tools/0.1.14/source/LICENSE-APACHE)
211
+ - [LICENSE-MIT](#notice-378f5840b258e277) — [notice source](https://docs.rs/crate/find-msvc-tools/0.1.14/source/LICENSE-MIT)
212
+
195
213
  ### foldhash 0.2.0
196
214
 
197
215
  Declared license: `Zlib`.
@@ -377,6 +395,16 @@ Source: [libloading 0.8.9 source archive](https://crates.io/api/v1/crates/libloa
377
395
 
378
396
  - [LICENSE](#notice-b29f8b01452350c2) — [notice source](https://docs.rs/crate/libloading/0.8.9/source/LICENSE)
379
397
 
398
+ ### libmimalloc-sys 0.1.49
399
+
400
+ Declared license: `MIT`.
401
+
402
+ Source: [libmimalloc-sys 0.1.49 source archive](https://crates.io/api/v1/crates/libmimalloc-sys/0.1.49/download).
403
+
404
+ - [LICENSE.txt](#notice-a08554fab028af3a) — [notice source](https://docs.rs/crate/libmimalloc-sys/0.1.49/source/LICENSE.txt)
405
+ - [c_src/mimalloc/v2/LICENSE](#notice-82ade5d7d9b02904) — [notice source](https://docs.rs/crate/libmimalloc-sys/0.1.49/source/c_src/mimalloc/v2/LICENSE)
406
+ - [c_src/mimalloc/v3/LICENSE](#notice-82ade5d7d9b02904) — [notice source](https://docs.rs/crate/libmimalloc-sys/0.1.49/source/c_src/mimalloc/v3/LICENSE)
407
+
380
408
  ### litemap 0.8.3
381
409
 
382
410
  Declared license: `Unicode-3.0`.
@@ -448,6 +476,14 @@ Source: [memchr 2.8.3 source archive](https://crates.io/api/v1/crates/memchr/2.8
448
476
  - [LICENSE-MIT](#notice-0f96a83840e146e4) — [notice source](https://docs.rs/crate/memchr/2.8.3/source/LICENSE-MIT)
449
477
  - [UNLICENSE](#notice-7e12e5df4bae12cb) — [notice source](https://docs.rs/crate/memchr/2.8.3/source/UNLICENSE)
450
478
 
479
+ ### mimalloc 0.1.52
480
+
481
+ Declared license: `MIT`.
482
+
483
+ Source: [mimalloc 0.1.52 source archive](https://crates.io/api/v1/crates/mimalloc/0.1.52/download).
484
+
485
+ - [LICENSE.txt](#notice-a08554fab028af3a) — [notice source](https://docs.rs/crate/mimalloc/0.1.52/source/LICENSE.txt)
486
+
451
487
  ### napi 2.16.17
452
488
 
453
489
  Declared license: `MIT`.
@@ -792,6 +828,15 @@ Source: [servo_arc 0.4.3 source archive](https://crates.io/api/v1/crates/servo_a
792
828
  - [LICENSE-APACHE](#notice-a60eea8175145316) — [notice source](https://docs.rs/crate/servo_arc/0.4.3/source/LICENSE-APACHE)
793
829
  - [LICENSE-MIT](#notice-23f18e03dc49df91) — [notice source](https://docs.rs/crate/servo_arc/0.4.3/source/LICENSE-MIT)
794
830
 
831
+ ### shlex 2.0.1
832
+
833
+ Declared license: `MIT OR Apache-2.0`.
834
+
835
+ Source: [shlex 2.0.1 source archive](https://crates.io/api/v1/crates/shlex/2.0.1/download).
836
+
837
+ - [LICENSE-APACHE](#notice-553fffcd9b1cb158) — [notice source](https://docs.rs/crate/shlex/2.0.1/source/LICENSE-APACHE)
838
+ - [LICENSE-MIT](#notice-4455bf75a9115410) — [notice source](https://docs.rs/crate/shlex/2.0.1/source/LICENSE-MIT)
839
+
795
840
  ### siphasher 1.0.4
796
841
 
797
842
  Declared license: `MIT OR Apache-2.0`.
@@ -4680,6 +4725,34 @@ OTHER DEALINGS IN THE SOFTWARE.
4680
4725
  For more information, please refer to <http://unlicense.org/>
4681
4726
  ```
4682
4727
 
4728
+ <a id="notice-82ade5d7d9b02904"></a>
4729
+
4730
+ ### Notice 82ade5d7d9b02904
4731
+
4732
+ ```text
4733
+ MIT License
4734
+
4735
+ Copyright (c) 2018-2025 Microsoft Corporation, Daan Leijen
4736
+
4737
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4738
+ of this software and associated documentation files (the "Software"), to deal
4739
+ in the Software without restriction, including without limitation the rights
4740
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4741
+ copies of the Software, and to permit persons to whom the Software is
4742
+ furnished to do so, subject to the following conditions:
4743
+
4744
+ The above copyright notice and this permission notice shall be included in all
4745
+ copies or substantial portions of the Software.
4746
+
4747
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4748
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4749
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4750
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4751
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4752
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4753
+ SOFTWARE.
4754
+ ```
4755
+
4683
4756
  <a id="notice-861399f8c21c042b"></a>
4684
4757
 
4685
4758
  ### Notice 861399f8c21c042b
@@ -5052,6 +5125,38 @@ The Rand project includes code from the Rust project
5052
5125
  published under these same licenses.
5053
5126
  ```
5054
5127
 
5128
+ <a id="notice-a08554fab028af3a"></a>
5129
+
5130
+ ### Notice a08554fab028af3a
5131
+
5132
+ ```text
5133
+ Copyright 2019 Octavian Oncescu
5134
+
5135
+ Permission is hereby granted, free of charge, to any
5136
+ person obtaining a copy of this software and associated
5137
+ documentation files (the "Software"), to deal in the
5138
+ Software without restriction, including without
5139
+ limitation the rights to use, copy, modify, merge,
5140
+ publish, distribute, sublicense, and/or sell copies of
5141
+ the Software, and to permit persons to whom the Software
5142
+ is furnished to do so, subject to the following
5143
+ conditions:
5144
+
5145
+ The above copyright notice and this permission notice
5146
+ shall be included in all copies or substantial portions
5147
+ of the Software.
5148
+
5149
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
5150
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
5151
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
5152
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
5153
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
5154
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
5155
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
5156
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
5157
+ DEALINGS IN THE SOFTWARE.
5158
+ ```
5159
+
5055
5160
  <a id="notice-a60eea8175145316"></a>
5056
5161
 
5057
5162
  ### Notice a60eea8175145316