Repository: remeda/remeda
Pull request #798 (2024-08-01 14:25:05)

chore(deps): bump the minor group with 4 updates
Bumps the minor group with 4 updates: [type-fest](https://github.com/sindresorhus/type-fest), [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc), [husky](https://github.com/typicode/husky) and [tsup](https://github.com/egoist/tsup).

Updates `type-fest` from 4.21.0 to 4.23.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/sindresorhus/type-fest/releases">type-fest's releases</a>.</em></p>
<blockquote>
<h2>v4.23.0</h2>
<ul>
<li><code>Paths</code>: Add <code>maxRecursionDepth</code> option (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/920">#920</a>)  052e887</li>
</ul>
<p><a href="https://github.com/sindresorhus/type-fest/compare/v4.22.1...v4.23.0">https://github.com/sindresorhus/type-fest/compare/v4.22.1...v4.23.0</a></p>
<h2>v4.22.1</h2>
<ul>
<li>Fix missing exported internal types (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/918">#918</a>)  4b74444</li>
</ul>
<p><a href="https://github.com/sindresorhus/type-fest/compare/v4.22.0...v4.22.1">https://github.com/sindresorhus/type-fest/compare/v4.22.0...v4.22.1</a></p>
<h2>v4.22.0</h2>
<h3>New types</h3>
<ul>
<li><a href="https://github.com/sindresorhus/type-fest/blob/main/source/array-tail.d.ts"><code>ArrayTail</code></a> (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/913">#913</a>)  128b21e</li>
<li><a href="https://github.com/sindresorhus/type-fest/blob/main/source/non-empty-tuple.d.ts"><code>NonEmptyTuple</code></a> (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/915">#915</a>)  bb57638</li>
<li><a href="https://github.com/sindresorhus/type-fest/blob/main/source/find-global-type.d.ts"><code>FindGlobalType</code></a> (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/908">#908</a>)  0086cd6</li>
<li><a href="https://github.com/sindresorhus/type-fest/blob/main/source/find-global-type.d.ts"><code>FindGlobalInstanceType</code></a> (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/908">#908</a>)  0086cd6</li>
</ul>
<h3>Improvements</h3>
<ul>
<li>Ensure all <code>RequireX</code> types&amp;<a href="https://redirect.github.com/sindresorhus/type-fest/issues/39">#39</a>; second parameter is optional (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/907">#907</a>)  fee4e04</li>
<li><a href="https://github.com/sindresorhus/type-fest/blob/main/source/find-global-type.d.ts"><code>StructuredCloneable</code></a>: Include web-specific types when available (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/908">#908</a>)  0086cd6</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>Exact</code>: Fix type when class is present (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/911">#911</a>)  bf85819</li>
</ul>
<p><a href="https://github.com/sindresorhus/type-fest/compare/v4.21.0...v4.22.0">https://github.com/sindresorhus/type-fest/compare/v4.21.0...v4.22.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/sindresorhus/type-fest/commit/b9838f6d8a4c0e54515b371de82ef1b9e9649628"><code>b9838f6</code></a> 4.23.0</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/052e88784378880f7e5a29b143b8ec8783ba1d9c"><code>052e887</code></a> <code>Paths</code>: Add <code>maxRecursionDepth</code> option (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/920">#920</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/8a45ba048767aaffcebc7d190172d814a739feb0"><code>8a45ba0</code></a> 4.22.1</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/4b744448ccc8f5ef38c153a3f88f5cefb2c6b84b"><code>4b74444</code></a> Fix missing exported internal types (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/918">#918</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/e8d6dfefc6433254fb8ce5bcbcf5f124f6a236d9"><code>e8d6dfe</code></a> 4.22.0</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/0086cd6a33dafa5d6a0b5dc8f331811c43b1e02a"><code>0086cd6</code></a> Add <code>FindGlobalType</code> and <code>FindGlobalInstanceType</code> types (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/908">#908</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/3b1ceeb1dd6ca93b7dadfd511892a6d08cece5a2"><code>3b1ceeb</code></a> Split <code>internal.d.ts</code> into multiple files (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/906">#906</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/bb57638a351be9fcbbb81654e08680b727ec3305"><code>bb57638</code></a> Add <code>NonEmptyTuple</code> type (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/915">#915</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/128b21eed81ef200ce0eb0bc652fa85149707c23"><code>128b21e</code></a> Add <code>ArrayTail</code> type (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/913">#913</a>)</li>
<li><a href="https://github.com/sindresorhus/type-fest/commit/bf85819feca2943a77541a322f9a1c1feb07c2b0"><code>bf85819</code></a> <code>Exact</code>: Fix type when class is present (<a href="https://redirect.github.com/sindresorhus/type-fest/issues/911">#911</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/sindresorhus/type-fest/compare/v4.21.0...v4.23.0">compare view</a></li>
</ul>
</details>
<br />

Updates `eslint-plugin-jsdoc` from 48.5.2 to 48.10.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/gajus/eslint-plugin-jsdoc/releases">eslint-plugin-jsdoc's releases</a>.</em></p>
<blockquote>
<h2>v48.10.2</h2>
<h2><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.10.1...v48.10.2">48.10.2</a> (2024-07-30)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong><code>check-template-names</code>:</strong> check for param and returns tags; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1286">#1286</a> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/12fca71fdc7761d4affb52bf5fe4be25eddabc5b">12fca71</a>)</li>
</ul>
<h2>v48.10.1</h2>
<h2><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.10.0...v48.10.1">48.10.1</a> (2024-07-30)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>add espree as dependency; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1284">#1284</a> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/31e0a35382c5d4c847781df6c4b5d8fb371d8d3c">31e0a35</a>)</li>
</ul>
<h2>v48.10.0</h2>
<h1><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.9.3...v48.10.0">48.10.0</a> (2024-07-30)</h1>
<h3>Features</h3>
<ul>
<li><strong><code>require-template</code>, <code>check-template-names</code>:</strong> add support <code>ClassDeclaration</code> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/31d32555988dca786726420246efcd1589c07316">31d3255</a>)</li>
<li><strong><code>require-template</code>, <code>check-template-names</code>:</strong> add support <code>FunctionDeclaration</code> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/28bc1cb8664b0373ad87f6cb0cd7c781139cc3b8">28bc1cb</a>)</li>
<li><strong><code>require-template</code>, <code>check-template-names</code>:</strong> add support <code>TSInterfaceDeclaration</code> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/320a1ebb5c72d48a5a0cc725a7f8a1ea0170d2f6">320a1eb</a>)</li>
</ul>
<h2>v48.9.3</h2>
<h2><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.9.2...v48.9.3">48.9.3</a> (2024-07-30)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong><code>getJsdocProcessorPlugin</code>:</strong> ensure package.json file is consistently located (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/87a12703b229efa73334e61d7ed4448cb28167a9">87a1270</a>)</li>
</ul>
<h2>v48.9.2</h2>
<h2><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.9.1...v48.9.2">48.9.2</a> (2024-07-29)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples processor:</strong> ensure config can be loaded with plugins (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/2fbd47c3d2b23a41d87b979daa56a648270d3675">2fbd47c</a>)</li>
</ul>
<h2>v48.9.1</h2>
<h2><a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.9.0...v48.9.1">48.9.1</a> (2024-07-29)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>move processor to own file; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1277">#1277</a>; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1278">#1278</a> (<a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/3ba475e589bc1dc83a7f57950378b2da0228e7fc">3ba475e</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/12fca71fdc7761d4affb52bf5fe4be25eddabc5b"><code>12fca71</code></a> fix(<code>check-template-names</code>): check for param and returns tags; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1286">#1286</a></li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/31e0a35382c5d4c847781df6c4b5d8fb371d8d3c"><code>31e0a35</code></a> fix: add espree as dependency; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1284">#1284</a></li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/31d32555988dca786726420246efcd1589c07316"><code>31d3255</code></a> feat(<code>require-template</code>, <code>check-template-names</code>): add support <code>ClassDeclaration</code></li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/28bc1cb8664b0373ad87f6cb0cd7c781139cc3b8"><code>28bc1cb</code></a> feat(<code>require-template</code>, <code>check-template-names</code>): add support `FunctionDeclar...</li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/320a1ebb5c72d48a5a0cc725a7f8a1ea0170d2f6"><code>320a1eb</code></a> feat(<code>require-template</code>, <code>check-template-names</code>): add support `TSInterfaceDec...</li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/87a12703b229efa73334e61d7ed4448cb28167a9"><code>87a1270</code></a> fix(<code>getJsdocProcessorPlugin</code>): ensure package.json file is consistently located</li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/2fbd47c3d2b23a41d87b979daa56a648270d3675"><code>2fbd47c</code></a> fix(examples processor): ensure config can be loaded with plugins</li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/df43df9f4533dcbf7458e41d7f90bc89043331dd"><code>df43df9</code></a> docs: mention in rule message current alternative to <code>check-examples</code> rule</li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/f0f5e1848e4a0d920d743433de12f91ded46d4e1"><code>f0f5e18</code></a> docs: fix docs for <code>getJsdocProcessorPlugin</code></li>
<li><a href="https://github.com/gajus/eslint-plugin-jsdoc/commit/3ba475e589bc1dc83a7f57950378b2da0228e7fc"><code>3ba475e</code></a> fix: move processor to own file; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1277">#1277</a>; fixes <a href="https://redirect.github.com/gajus/eslint-plugin-jsdoc/issues/1278">#1278</a></li>
<li>Additional commits viewable in <a href="https://github.com/gajus/eslint-plugin-jsdoc/compare/v48.5.2...v48.10.2">compare view</a></li>
</ul>
</details>
<br />

Updates `husky` from 9.0.11 to 9.1.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/typicode/husky/releases">husky's releases</a>.</em></p>
<blockquote>
<h2>v9.1.4</h2>
<ul>
<li>Improve deprecation notice</li>
</ul>
<h2>v9.1.3</h2>
<ul>
<li>fix: better handle space in <code>PATH</code></li>
</ul>
<h2>v9.1.2</h2>
<p>Show a message instead of automatically removing deprecated code.</p>
<p>This only concerns projects that still have the following code in their hooks:</p>
<pre lang="diff"><code>- #!/usr/bin/env sh # &lt;- This is deprecated, remove it
- . &quot;$(dirname -- &quot;$0&quot;)/_/husky.sh&quot;  # &lt;- This is deprecated, remove it
<h1>Rest of your hook code</h1>
<p></code></pre></p>
<p><strong>Hooks with these lines will fail in <code>v10.0.0</code></strong></p>
<h2>v9.1.1</h2>
<!-- raw HTML omitted -->
<p><em>Super saiyan <del>god</del> dog! It's over 9.0.0!</em></p>
<h1>What's new</h1>
<p>You can now run package commands directly, no need for <code>npx</code> or equivalents.
It makes writing hooks more intuitive and is also slightly faster 🐺⚡️</p>
<pre lang="diff"><code># .husky/pre-commit
- npx jest
+ jest # ~0.2s faster
</code></pre>
<p>A new recipe has been added to the docs. Lint staged files without external dependencies (inspired by Prettier docs). Feel free to modify it.</p>
<pre lang="shell"><code># .husky/pre-commit
prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown
git update-index --again
</code></pre>
<p>For more advanced use cases, see <a href="https://github.com/lint-staged/lint-staged">lint-staged</a>.</p>
<h1>Fixes</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/typicode/husky/commit/fc549e0e5c8723a6d796f6ad26ef6590769f5d82"><code>fc549e0</code></a> 9.1.4</li>
<li><a href="https://github.com/typicode/husky/commit/9891ace6454b111bccf6d38860f6ce08c4424a5d"><code>9891ace</code></a> clarify deprecation message</li>
<li><a href="https://github.com/typicode/husky/commit/712cb004c17b2bdf824ff74de3ec4855c06d72ef"><code>712cb00</code></a> 9.1.3</li>
<li><a href="https://github.com/typicode/husky/commit/7d296330289b5c6e2feb1940efc3f218b3808e07"><code>7d29633</code></a> fix: better handle spaces in PATH</li>
<li><a href="https://github.com/typicode/husky/commit/35fba846c4a9b83f64a95d8a0bde5aa648fdc449"><code>35fba84</code></a> 9.1.2</li>
<li><a href="https://github.com/typicode/husky/commit/20603175c10e35e58d1eadd20d08a491cfcc5b6a"><code>2060317</code></a> show message instead of automatically remove deprecated code</li>
<li><a href="https://github.com/typicode/husky/commit/f6cc4108837863bfbd31a861fdd8422637a492b1"><code>f6cc410</code></a> Update troubleshoot.md</li>
<li><a href="https://github.com/typicode/husky/commit/0c71e73246968d5c8bdb895d133b839b6a9cf4b2"><code>0c71e73</code></a> update package-lock.json</li>
<li><a href="https://github.com/typicode/husky/commit/2968998755465f69069f297b5bb603e26d6b1772"><code>2968998</code></a> 9.1.1</li>
<li><a href="https://github.com/typicode/husky/commit/902749b18f5ac6c592497eb1890b87930f5c250e"><code>902749b</code></a> docs</li>
<li>Additional commits viewable in <a href="https://github.com/typicode/husky/compare/v9.0.11...v9.1.4">compare view</a></li>
</ul>
</details>
<br />

Updates `tsup` from 8.1.0 to 8.2.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/egoist/tsup/releases">tsup's releases</a>.</em></p>
<blockquote>
<h2>v8.2.3</h2>
<h2><a href="https://github.com/egoist/tsup/compare/v8.2.2...v8.2.3">8.2.3</a> (2024-07-24)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>get metafile on windows (<a href="https://github.com/egoist/tsup/commit/048c93b34671e6fe6cf48600ed6667cab7b6fb1f">048c93b</a>)</li>
</ul>
<h2>v8.2.2</h2>
<h2><a href="https://github.com/egoist/tsup/compare/v8.2.1...v8.2.2">8.2.2</a> (2024-07-22)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Revert &quot;refactor: replace <code>globby</code> with faster alternative (<a href="https://redirect.github.com/egoist/tsup/issues/1158">#1158</a>)&quot; (<a href="https://github.com/egoist/tsup/commit/2de6dd5300882361102b3d133312c1815ee94764">2de6dd5</a>)</li>
</ul>
<h2>v8.2.1</h2>
<h2><a href="https://github.com/egoist/tsup/compare/v8.2.0...v8.2.1">8.2.1</a> (2024-07-20)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>dts:</strong> terminate worker when work is done (<a href="https://redirect.github.com/egoist/tsup/issues/1142">#1142</a>) (<a href="https://github.com/egoist/tsup/commit/44c88a7410919fed1455c8dd1a0d9513f1231b0d">44c88a7</a>)</li>
</ul>
<h2>v8.2.0</h2>
<h1><a href="https://github.com/egoist/tsup/compare/v8.1.2...v8.2.0">8.2.0</a> (2024-07-19)</h1>
<h3>Features</h3>
<ul>
<li>add option to retain node protocol (<a href="https://github.com/egoist/tsup/commit/e7ced3474a559e35fc5b9cbd4cfd4aa39d44e0c0">e7ced34</a>)</li>
</ul>
<h2>v8.1.2</h2>
<h2><a href="https://github.com/egoist/tsup/compare/v8.1.1...v8.1.2">8.1.2</a> (2024-07-17)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>correct sourcemap with treeshake (<a href="https://redirect.github.com/egoist/tsup/issues/1069">#1069</a>) (<a href="https://github.com/egoist/tsup/commit/6ca0cb0aee177a4c920f4e86d06544d0c51d9de3">6ca0cb0</a>)</li>
<li>only import type statement (<a href="https://github.com/egoist/tsup/commit/43cf9f69e2dba57be4fa4b7620f2e0a89bc313b0">43cf9f6</a>), closes <a href="https://redirect.github.com/egoist/tsup/issues/1157">#1157</a> <a href="https://redirect.github.com/egoist/tsup/issues/1156">#1156</a></li>
</ul>
<h2>v8.1.1</h2>
<h2><a href="https://github.com/egoist/tsup/compare/v8.1.0...v8.1.1">8.1.1</a> (2024-07-16)</h2>
<ul>
<li>Upgrade bunch of dependencies (esbuild v0.23).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/egoist/tsup/commit/048c93b34671e6fe6cf48600ed6667cab7b6fb1f"><code>048c93b</code></a> fix: get metafile on windows</li>
<li><a href="https://github.com/egoist/tsup/commit/2de6dd5300882361102b3d133312c1815ee94764"><code>2de6dd5</code></a> fix: Revert &quot;refactor: replace <code>globby</code> with faster alternative (<a href="https://redirect.github.com/egoist/tsup/issues/1158">#1158</a>)&quot;</li>
<li><a href="https://github.com/egoist/tsup/commit/6e66f29a1085f4e7a880cf57cf6e7d40c5ea7e20"><code>6e66f29</code></a> chore: upgrade deps</li>
<li><a href="https://github.com/egoist/tsup/commit/44c88a7410919fed1455c8dd1a0d9513f1231b0d"><code>44c88a7</code></a> fix(dts): terminate worker when work is done (<a href="https://redirect.github.com/egoist/tsup/issues/1142">#1142</a>)</li>
<li><a href="https://github.com/egoist/tsup/commit/0f0b4b205df201e9cdd047764868dd2619a528b0"><code>0f0b4b2</code></a> refactor: replace <code>globby</code> with faster alternative (<a href="https://redirect.github.com/egoist/tsup/issues/1158">#1158</a>)</li>
<li><a href="https://github.com/egoist/tsup/commit/aeda546c1f917aecf2f83ffc8f57bda473745091"><code>aeda546</code></a> refactor: replace colorette with picocolors</li>
<li><a href="https://github.com/egoist/tsup/commit/03037835d8359774cb0ebfb53ba266de8371ea2a"><code>0303783</code></a> docs: update tsup API docs link [ci skip] (<a href="https://redirect.github.com/egoist/tsup/issues/1160">#1160</a>)</li>
<li><a href="https://github.com/egoist/tsup/commit/31cffed93d3e88e0f1353ce70a30f1a2f0b4f2c2"><code>31cffed</code></a> docs: use jsdocs.io for now, closes <a href="https://redirect.github.com/egoist/tsup/issues/1145">#1145</a>, <a href="https://redirect.github.com/egoist/tsup/issues/1159">#1159</a></li>
<li><a href="https://github.com/egoist/tsup/commit/e7ced3474a559e35fc5b9cbd4cfd4aa39d44e0c0"><code>e7ced34</code></a> feat: add option to retain node protocol</li>
<li><a href="https://github.com/egoist/tsup/commit/809c57abb17a31b9c2d5830a47865ab3903bd2ca"><code>809c57a</code></a> chore: upgrade tsup &amp; deps</li>
<li>Additional commits viewable in <a href="https://github.com/egoist/tsup/compare/v8.1.0...v8.2.3">compare view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions


</details>

codesandbox-ci[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/remeda/remeda/pr/798/builds/528191) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 6558584f3fee4339f9de9b0cf967652da72f2bbd:

|Sandbox| Source |
|--|--|
|[remeda-example-vanilla](https://codesandbox.io/s/remeda-example-vanilla-n7py3m)| Configuration |


Patch:
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 2312dc5..c27d889 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,1 +1,1 @@
-npx lint-staged
+lint-staged
diff --git a/docs/package-lock.json b/docs/package-lock.json
index f7a54d3..087b294 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -10,11 +10,11 @@
       "license": "MIT",
       "dependencies": {
         "@astrojs/check": "^0.7.0",
-        "@astrojs/mdx": "^3.1.2",
-        "@astrojs/react": "^3.6.0",
+        "@astrojs/mdx": "^3.1.3",
+        "@astrojs/react": "^3.6.1",
         "@astrojs/sitemap": "^3.1.6",
         "@astrojs/tailwind": "^5.1.0",
-        "@docsearch/react": "^3.6.0",
+        "@docsearch/react": "^3.6.1",
         "@radix-ui/react-collapsible": "^1.1.0",
         "@radix-ui/react-dialog": "^1.1.1",
         "@radix-ui/react-dropdown-menu": "^2.1.1",
@@ -41,26 +41,26 @@
         "@types/react-dom": "^18.3.0",
         "@typescript-eslint/eslint-plugin": "^7.14.1",
         "@typescript-eslint/parser": "^7.14.1",
-        "dompurify": "^3.1.5",
+        "dompurify": "^3.1.6",
         "eslint": "^8.57.0",
         "eslint-config-prettier": "^9.1.0",
-        "eslint-plugin-astro": "^1.2.2",
+        "eslint-plugin-astro": "^1.2.3",
         "eslint-plugin-jsx-a11y": "^6.9.0",
         "eslint-plugin-react": "^7.34.3",
         "eslint-plugin-react-hooks": "^4.6.2",
         "eslint-plugin-unicorn": "^54.0.0",
-        "jsdom": "^24.1.0",
-        "marked": "^13.0.1",
+        "jsdom": "^24.1.1",
+        "marked": "^13.0.3",
         "open-cli": "^8.0.0",
-        "prettier": "^3.3.2",
-        "prettier-plugin-astro": "^0.14.0",
+        "prettier": "^3.3.3",
+        "prettier-plugin-astro": "^0.14.1",
         "prettier-plugin-tailwindcss": "^0.6.5",
-        "tailwindcss": "^3.4.4",
+        "tailwindcss": "^3.4.7",
         "tailwindcss-animate": "^1.0.7",
         "tiny-invariant": "^1.3.3",
         "type-fest": "^4.20.1",
-        "typedoc": "^0.26.3",
-        "typescript": "^5.5.2"
+        "typedoc": "^0.26.5",
+        "typescript": "^5.5.4"
       }
     },
     "node_modules/@algolia/autocomplete-core": {
@@ -298,9 +298,9 @@
       }
     },
     "node_modules/@astrojs/compiler": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.8.1.tgz",
-      "integrity": "sha512-NGfPAgU/9rvDEwsXu82RI1AxiivaxtEYBK9saW1f+2fTHUUqCJQ27HYtb2akG2QxCmFikgZ9zk26BEWgiHho1Q=="
+      "version": "2.10.1",
+      "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.10.1.tgz",
+      "integrity": "sha512-XmM4j6BjvOVMag2xELq0JuG2yKOW8wgIu6dvb9BsjbGYmnvoStJn/pqEzVqc1EBszf2xYT7onIkftIOUz9AwrQ=="
     },
     "node_modules/@astrojs/internal-helpers": {
       "version": "0.4.1",
@@ -371,13 +371,13 @@
       }
     },
     "node_modules/@astrojs/mdx": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.2.tgz",
-      "integrity": "sha512-0EizCWhUi0wdYPm31kNOHsOrGmn8pEJy+YEGQlHWt4Flg2NYfV7nWZuYG8KxoRSK/W397vPhyHYrITCYo7JMYw==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.3.tgz",
+      "integrity": "sha512-hOM4dMM4RfJI254d3p/AnOZuk2VyKszRtuY5FBm+Xc4XdhIpGrR56OXMNEcWchtwz4HQyPe/eJSgvBjSROcQIQ==",
       "dependencies": {
-        "@astrojs/markdown-remark": "5.1.1",
+        "@astrojs/markdown-remark": "5.2.0",
         "@mdx-js/mdx": "^3.0.1",
-        "acorn": "^8.12.0",
+        "acorn": "^8.12.1",
         "es-module-lexer": "^1.5.4",
         "estree-util-visit": "^2.0.0",
         "github-slugger": "^2.0.0",
@@ -386,10 +386,10 @@
         "kleur": "^4.1.5",
         "rehype-raw": "^7.0.0",
         "remark-gfm": "^4.0.0",
-        "remark-smartypants": "^3.0.1",
+        "remark-smartypants": "^3.0.2",
         "source-map": "^0.7.4",
         "unist-util-visit": "^5.0.0",
-        "vfile": "^6.0.1"
+        "vfile": "^6.0.2"
       },
       "engines": {
         "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
@@ -398,6 +398,31 @@
         "astro": "^4.8.0"
       }
     },
+    "node_modules/@astrojs/mdx/node_modules/@astrojs/markdown-remark": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-5.2.0.tgz",
+      "integrity": "sha512-vWGM24KZXz11jR3JO+oqYU3T2qpuOi4uGivJ9SQLCAI01+vEkHC60YJMRvHPc+hwd60F7euNs1PeOEixIIiNQw==",
+      "dependencies": {
+        "@astrojs/prism": "3.1.0",
+        "github-slugger": "^2.0.0",
+        "hast-util-from-html": "^2.0.1",
+        "hast-util-to-text": "^4.0.2",
+        "import-meta-resolve": "^4.1.0",
+        "mdast-util-definitions": "^6.0.0",
+        "rehype-raw": "^7.0.0",
+        "rehype-stringify": "^10.0.0",
+        "remark-gfm": "^4.0.0",
+        "remark-parse": "^11.0.0",
+        "remark-rehype": "^11.1.0",
+        "remark-smartypants": "^3.0.2",
+        "shiki": "^1.10.3",
+        "unified": "^11.0.5",
+        "unist-util-remove-position": "^5.0.0",
+        "unist-util-visit": "^5.0.0",
+        "unist-util-visit-parents": "^6.0.1",
+        "vfile": "^6.0.2"
+      }
+    },
     "node_modules/@astrojs/prism": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.1.0.tgz",
@@ -410,10 +435,9 @@
       }
     },
     "node_modules/@astrojs/react": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-3.6.0.tgz",
-      "integrity": "sha512-YGLxy5jCU9xKG/HAvYsWMcvrQVIhqVe0Sda3Z5UtP32rfXeG6B9J1xQvnx+kRSFTpIrj+7AwPSDSehLbCHJ56w==",
-      "license": "MIT",
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-3.6.1.tgz",
+      "integrity": "sha512-Mpgu+GYTba1TEzLMshojeLxi7y/FqrTNtpGTCvI366bRbnCkqtvznRj/xPQOTybwXnYXSgxsELyUvqD51iFeiw==",
       "dependencies": {
         "@vitejs/plugin-react": "^4.3.1",
         "ultrahtml": "^1.5.3"
@@ -890,20 +914,18 @@
       }
     },
     "node_modules/@docsearch/css": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz",
-      "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==",
-      "license": "MIT"
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz",
+      "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg=="
     },
     "node_modules/@docsearch/react": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz",
-      "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==",
-      "license": "MIT",
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz",
+      "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==",
       "dependencies": {
         "@algolia/autocomplete-core": "1.9.3",
         "@algolia/autocomplete-preset-algolia": "1.9.3",
-        "@docsearch/css": "3.6.0",
+        "@docsearch/css": "3.6.1",
         "algoliasearch": "^4.19.1"
       },
       "peerDependencies": {
@@ -3042,9 +3064,12 @@
       ]
     },
     "node_modules/@shikijs/core": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.0.tgz",
-      "integrity": "sha512-BZcr6FCmPfP6TXaekvujZcnkFmJHZ/Yglu97r/9VjzVndQA56/F4WjUKtJRQUnK59Wi7p/UTAOekMfCJv7jnYg=="
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.12.1.tgz",
+      "integrity": "sha512-biCz/mnkMktImI6hMfMX3H9kOeqsInxWEyCHbSlL8C/2TR1FqfmGxTLRNwYCKsyCyxWLbB8rEqXRVZuyxuLFmA==",
+      "dependencies": {
+        "@types/hast": "^3.0.4"
+      }
     },
     "node_modules/@tailwindcss/typography": {
       "version": "0.5.13",
@@ -3579,10 +3604,9 @@
       "integrity": "sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg=="
     },
     "node_modules/acorn": {
-      "version": "8.12.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
-      "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
-      "license": "MIT",
+      "version": "8.12.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+      "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -5201,9 +5225,9 @@
       }
     },
     "node_modules/dompurify": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz",
-      "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==",
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
+      "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
       "dev": true
     },
     "node_modules/dset": {
@@ -5585,11 +5609,10 @@
       }
     },
     "node_modules/eslint-plugin-astro": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-astro/-/eslint-plugin-astro-1.2.2.tgz",
-      "integrity": "sha512-3UUWo/gwk/YhurYpFKgLJswV33kR9zhtzXk+u2g3WE5Px07wDtWSR3PoyPadHERA4g/9TCCGjsimU/TZyUKxow==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-astro/-/eslint-plugin-astro-1.2.3.tgz",
+      "integrity": "sha512-asHT0VUs68oppVnTHfp/WgLqs0yCx9kG9AC/PKLmp+87imeh3nGHMdFm0qP46vHxTM0NLDEhvmjFdAVAqw+QPQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@jridgewell/sourcemap-codec": "^1.4.14",
@@ -7166,9 +7189,9 @@
       }
     },
     "node_modules/https-proxy-agent": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
-      "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+      "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
       "dev": true,
       "dependencies": {
         "agent-base": "^7.0.2",
@@ -7930,9 +7953,9 @@
       }
     },
     "node_modules/jsdom": {
-      "version": "24.1.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz",
-      "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==",
+      "version": "24.1.1",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz",
+      "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==",
       "dev": true,
       "dependencies": {
         "cssstyle": "^4.0.1",
@@ -7941,11 +7964,11 @@
         "form-data": "^4.0.0",
         "html-encoding-sniffer": "^4.0.0",
         "http-proxy-agent": "^7.0.2",
-        "https-proxy-agent": "^7.0.4",
+        "https-proxy-agent": "^7.0.5",
         "is-potential-custom-element-name": "^1.0.1",
-        "nwsapi": "^2.2.10",
+        "nwsapi": "^2.2.12",
         "parse5": "^7.1.2",
-        "rrweb-cssom": "^0.7.0",
+        "rrweb-cssom": "^0.7.1",
         "saxes": "^6.0.0",
         "symbol-tree": "^3.2.4",
         "tough-cookie": "^4.1.4",
@@ -7954,7 +7977,7 @@
         "whatwg-encoding": "^3.1.1",
         "whatwg-mimetype": "^4.0.0",
         "whatwg-url": "^14.0.0",
-        "ws": "^8.17.0",
+        "ws": "^8.18.0",
         "xml-name-validator": "^5.0.0"
       },
       "engines": {
@@ -7970,9 +7993,9 @@
       }
     },
     "node_modules/jsdom/node_modules/rrweb-cssom": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.0.tgz",
-      "integrity": "sha512-KlSv0pm9kgQSRxXEMgtivPJ4h826YHsuob8pSHcfSZsSXGtvpEAie8S0AnXuObEJ7nhikOb4ahwxDm0H2yW17g==",
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
+      "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
       "dev": true
     },
     "node_modules/jsesc": {
@@ -8317,9 +8340,9 @@
       }
     },
     "node_modules/marked": {
-      "version": "13.0.1",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.1.tgz",
-      "integrity": "sha512-7kBohS6GrZKvCsNXZyVVXSW7/hGBHe49ng99YPkDCckSUrrG7MSFLCexsRxptzOmyW2eT5dySh4Md1V6my52fA==",
+      "version": "13.0.3",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz",
+      "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==",
       "dev": true,
       "bin": {
         "marked": "bin/marked.js"
@@ -9544,9 +9567,9 @@
       }
     },
     "node_modules/nwsapi": {
-      "version": "2.2.10",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz",
-      "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==",
+      "version": "2.2.12",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
+      "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==",
       "dev": true
     },
     "node_modules/object-assign": {
@@ -10349,11 +10372,10 @@
       }
     },
     "node_modules/prettier": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
-      "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+      "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
       "devOptional": true,
-      "license": "MIT",
       "bin": {
         "prettier": "bin/prettier.cjs"
       },
@@ -10365,12 +10387,12 @@
       }
     },
     "node_modules/prettier-plugin-astro": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.14.0.tgz",
-      "integrity": "sha512-7jRGJsexaRIyUzTk8uzXlP45cw6DQ5Ci4bTe0xCBCcuO1Fff8jJy9oI+kRCQKSdDFTSAArMSg8GpvzlKBtSaZA==",
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.14.1.tgz",
+      "integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==",
       "devOptional": true,
       "dependencies": {
-        "@astrojs/compiler": "^1.5.5",
+        "@astrojs/compiler": "^2.9.1",
         "prettier": "^3.0.0",
         "sass-formatter": "^0.7.6"
       },
@@ -10378,12 +10400,6 @@
         "node": "^14.15.0 || >=16.0.0"
       }
     },
-    "node_modules/prettier-plugin-astro/node_modules/@astrojs/compiler": {
-      "version": "1.8.2",
-      "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-1.8.2.tgz",
-      "integrity": "sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==",
-      "devOptional": true
-    },
     "node_modules/prettier-plugin-tailwindcss": {
       "version": "0.6.5",
       "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.5.tgz",
@@ -11009,9 +11025,9 @@
       }
     },
     "node_modules/remark-smartypants": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.1.tgz",
-      "integrity": "sha512-qyshfCl2eLO0i0558e79ZJsfojC5wjnYLByjt0FmjJQN6aYwcRxpoj784LZJSoWCdnA2ubh5rLNGb8Uur/wDng==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz",
+      "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==",
       "dependencies": {
         "retext": "^9.0.0",
         "retext-smartypants": "^6.0.0",
@@ -11508,11 +11524,12 @@
       }
     },
     "node_modules/shiki": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.0.tgz",
-      "integrity": "sha512-YD2sXQ+TMD/F9BimV9Jn0wj35pqOvywvOG/3PB6hGHyGKlM7TJ9tyJ02jOb2kF8F0HfJwKNYrh3sW7jEcuRlXA==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.12.1.tgz",
+      "integrity": "sha512-nwmjbHKnOYYAe1aaQyEBHvQymJgfm86ZSS7fT8OaPRr4sbAcBNz7PbfAikMEFSDQ6se2j2zobkXvVKcBOm0ysg==",
       "dependencies": {
-        "@shikijs/core": "1.10.0"
+        "@shikijs/core": "1.12.1",
+        "@types/hast": "^3.0.4"
       }
     },
     "node_modules/side-channel": {
@@ -12073,10 +12090,9 @@
       }
     },
     "node_modules/tailwindcss": {
-      "version": "3.4.4",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
-      "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
-      "license": "MIT",
+      "version": "3.4.7",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz",
+      "integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==",
       "dependencies": {
         "@alloc/quick-lru": "^5.2.0",
         "arg": "^5.0.2",
@@ -12441,9 +12457,9 @@
       }
     },
     "node_modules/typedoc": {
-      "version": "0.26.3",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.3.tgz",
-      "integrity": "sha512-6d2Sw9disvvpdk4K7VNjKr5/3hzijtfQVHRthhDqJgnhMHy1wQz4yPMJVKXElvnZhFr0nkzo+GzjXDTRV5yLpg==",
+      "version": "0.26.5",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.5.tgz",
+      "integrity": "sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==",
       "dev": true,
       "dependencies": {
         "lunr": "^2.3.9",
@@ -12468,10 +12484,9 @@
       "integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="
     },
     "node_modules/typescript": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
-      "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
-      "license": "Apache-2.0",
+      "version": "5.5.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -12795,9 +12810,9 @@
       }
     },
     "node_modules/vfile": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz",
-      "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz",
+      "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==",
       "dependencies": {
         "@types/unist": "^3.0.0",
         "unist-util-stringify-position": "^4.0.0",
@@ -13456,9 +13471,9 @@
       "dev": true
     },
     "node_modules/ws": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
-      "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+      "version": "8.18.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
       "dev": true,
       "engines": {
         "node": ">=10.0.0"
diff --git a/docs/package.json b/docs/package.json
index 25bb956..88a1746 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -18,11 +18,11 @@
   },
   "dependencies": {
     "@astrojs/check": "^0.7.0",
-    "@astrojs/mdx": "^3.1.2",
-    "@astrojs/react": "^3.6.0",
+    "@astrojs/mdx": "^3.1.3",
+    "@astrojs/react": "^3.6.1",
     "@astrojs/sitemap": "^3.1.6",
     "@astrojs/tailwind": "^5.1.0",
-    "@docsearch/react": "^3.6.0",
+    "@docsearch/react": "^3.6.1",
     "@radix-ui/react-collapsible": "^1.1.0",
     "@radix-ui/react-dialog": "^1.1.1",
     "@radix-ui/react-dropdown-menu": "^2.1.1",
@@ -49,25 +49,25 @@
     "@types/react-dom": "^18.3.0",
     "@typescript-eslint/eslint-plugin": "^7.14.1",
     "@typescript-eslint/parser": "^7.14.1",
-    "dompurify": "^3.1.5",
+    "dompurify": "^3.1.6",
     "eslint": "^8.57.0",
     "eslint-config-prettier": "^9.1.0",
-    "eslint-plugin-astro": "^1.2.2",
+    "eslint-plugin-astro": "^1.2.3",
     "eslint-plugin-jsx-a11y": "^6.9.0",
     "eslint-plugin-react": "^7.34.3",
     "eslint-plugin-react-hooks": "^4.6.2",
     "eslint-plugin-unicorn": "^54.0.0",
-    "jsdom": "^24.1.0",
-    "marked": "^13.0.1",
+    "jsdom": "^24.1.1",
+    "marked": "^13.0.3",
     "open-cli": "^8.0.0",
-    "prettier": "^3.3.2",
-    "prettier-plugin-astro": "^0.14.0",
+    "prettier": "^3.3.3",
+    "prettier-plugin-astro": "^0.14.1",
     "prettier-plugin-tailwindcss": "^0.6.5",
-    "tailwindcss": "^3.4.4",
+    "tailwindcss": "^3.4.7",
     "tailwindcss-animate": "^1.0.7",
     "tiny-invariant": "^1.3.3",
     "type-fest": "^4.20.1",
-    "typedoc": "^0.26.3",
-    "typescript": "^5.5.2"
+    "typedoc": "^0.26.5",
+    "typescript": "^5.5.4"
   }
 }
diff --git a/package-lock.json b/package-lock.json
index 3743c52..3bbec38 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
       "version": "2.0.0",
       "license": "MIT",
       "dependencies": {
-        "type-fest": "^4.21.0"
+        "type-fest": "^4.23.0"
       },
       "devDependencies": {
         "@arethetypeswrong/cli": "^0.15.3",
@@ -20,14 +20,14 @@
         "@vitest/coverage-v8": "^2.0.1",
         "eslint": "^8.57.0",
         "eslint-config-prettier": "^9.1.0",
-        "eslint-plugin-jsdoc": "^48.5.2",
+        "eslint-plugin-jsdoc": "^48.10.2",
         "eslint-plugin-unicorn": "^54.0.0",
-        "husky": "^9.0.11",
+        "husky": "^9.1.4",
         "lint-staged": "^15.2.7",
         "prettier": "^3.3.2",
         "publint": "^0.2.8",
         "semantic-release": "^24.0.0",
-        "tsup": "^8.1.0",
+        "tsup": "^8.2.3",
         "typescript": "^5.5.3",
         "typescript-eslint": "^7.16.0",
         "vitest": "^2.0.1"
@@ -282,17 +282,13 @@
       }
     },
     "node_modules/@es-joy/jsdoccomment": {
-      "version": "0.43.1",
-      "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz",
-      "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==",
+      "version": "0.46.0",
+      "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz",
+      "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "@types/eslint": "^8.56.5",
-        "@types/estree": "^1.0.5",
-        "@typescript-eslint/types": "^7.2.0",
         "comment-parser": "1.4.1",
-        "esquery": "^1.5.0",
+        "esquery": "^1.6.0",
         "jsdoc-type-pratt-parser": "~4.0.0"
       },
       "engines": {
@@ -605,6 +601,22 @@
         "node": ">=12"
       }
     },
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz",
+      "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/@esbuild/openbsd-x64": {
       "version": "0.21.5",
       "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
@@ -901,19 +913,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/@jest/schemas": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
-      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@sinclair/typebox": "^0.27.8"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
     "node_modules/@jridgewell/gen-mapping": {
       "version": "0.3.5",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
@@ -1176,7 +1175,6 @@
       "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
       "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
       },
@@ -1230,224 +1228,208 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
-      "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.2.tgz",
+      "integrity": "sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==",
       "cpu": [
         "arm"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "android"
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
-      "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.2.tgz",
+      "integrity": "sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==",
       "cpu": [
         "arm64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "android"
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
-      "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.2.tgz",
+      "integrity": "sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==",
       "cpu": [
         "arm64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "darwin"
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
-      "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.2.tgz",
+      "integrity": "sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==",
       "cpu": [
         "x64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "darwin"
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
-      "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.2.tgz",
+      "integrity": "sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==",
       "cpu": [
         "arm"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
-      "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.2.tgz",
+      "integrity": "sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==",
       "cpu": [
         "arm"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
-      "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.2.tgz",
+      "integrity": "sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==",
       "cpu": [
         "arm64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
-      "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.2.tgz",
+      "integrity": "sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==",
       "cpu": [
         "arm64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
-      "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.2.tgz",
+      "integrity": "sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==",
       "cpu": [
         "ppc64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
-      "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.2.tgz",
+      "integrity": "sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==",
       "cpu": [
         "riscv64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
-      "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.2.tgz",
+      "integrity": "sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==",
       "cpu": [
         "s390x"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
-      "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.2.tgz",
+      "integrity": "sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==",
       "cpu": [
         "x64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
-      "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.2.tgz",
+      "integrity": "sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==",
       "cpu": [
         "x64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "linux"
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
-      "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.2.tgz",
+      "integrity": "sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==",
       "cpu": [
         "arm64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "win32"
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
-      "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.2.tgz",
+      "integrity": "sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==",
       "cpu": [
         "ia32"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "win32"
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
-      "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.2.tgz",
+      "integrity": "sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==",
       "cpu": [
         "x64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
         "win32"
@@ -1749,13 +1731,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@sinclair/typebox": {
-      "version": "0.27.8",
-      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
-      "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/@sindresorhus/is": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
@@ -2106,11 +2081,10 @@
       "license": "ISC"
     },
     "node_modules/@vitest/coverage-v8": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.1.tgz",
-      "integrity": "sha512-ACcSlJtWlravv0QyJSCO9rvm06msj6x0HooXouB0NXKG6PGxUN5VX4X8QEATfTMGsJlZLqWvq0dEY9W1V0rcSw==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
+      "integrity": "sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "^2.3.0",
         "@bcoe/v8-coverage": "^0.2.3",
@@ -2121,41 +2095,51 @@
         "istanbul-reports": "^3.1.7",
         "magic-string": "^0.30.10",
         "magicast": "^0.3.4",
-        "picocolors": "^1.0.1",
         "std-env": "^3.7.0",
-        "strip-literal": "^2.1.0",
-        "test-exclude": "^7.0.1"
+        "test-exclude": "^7.0.1",
+        "tinyrainbow": "^1.2.0"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       },
       "peerDependencies": {
-        "vitest": "2.0.1"
+        "vitest": "2.0.5"
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.1.tgz",
-      "integrity": "sha512-yw70WL3ZwzbI2O3MOXYP2Shf4vqVkS3q5FckLJ6lhT9VMMtDyWdofD53COZcoeuHwsBymdOZp99r5bOr5g+oeA==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz",
+      "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "@vitest/spy": "2.0.1",
-        "@vitest/utils": "2.0.1",
-        "chai": "^5.1.1"
+        "@vitest/spy": "2.0.5",
+        "@vitest/utils": "2.0.5",
+        "chai": "^5.1.1",
+        "tinyrainbow": "^1.2.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/vitest"
+      }
+    },
+    "node_modules/@vitest/pretty-format": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz",
+      "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==",
+      "dev": true,
+      "dependencies": {
+        "tinyrainbow": "^1.2.0"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.1.tgz",
-      "integrity": "sha512-XfcSXOGGxgR2dQ466ZYqf0ZtDLLDx9mZeQcKjQDLQ9y6Cmk2Wl7wxMuhiYK4Fo1VxCtLcFEGW2XpcfMuiD1Maw==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz",
+      "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "@vitest/utils": "2.0.1",
+        "@vitest/utils": "2.0.5",
         "pathe": "^1.1.2"
       },
       "funding": {
@@ -2163,26 +2147,24 @@
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.1.tgz",
-      "integrity": "sha512-rst79a4Q+J5vrvHRapdfK4BdqpMH0eF58jVY1vYeBo/1be+nkyenGI5SCSohmjf6MkCkI20/yo5oG+0R8qrAnA==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz",
+      "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
+        "@vitest/pretty-format": "2.0.5",
         "magic-string": "^0.30.10",
-        "pathe": "^1.1.2",
-        "pretty-format": "^29.7.0"
+        "pathe": "^1.1.2"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/@vitest/spy": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.1.tgz",
-      "integrity": "sha512-NLkdxbSefAtJN56GtCNcB4GiHFb5i9q1uh4V229lrlTZt2fnwsTyjLuWIli1xwK2fQspJJmHXHyWx0Of3KTXWA==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz",
+      "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "tinyspy": "^3.0.0"
       },
@@ -2191,16 +2173,15 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.1.tgz",
-      "integrity": "sha512-STH+2fHZxlveh1mpU4tKzNgRk7RZJyr6kFGJYCI5vocdfqfPsQrgVC6k7dBWHfin5QNB4TLvRS0Ckly3Dt1uWw==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz",
+      "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "diff-sequences": "^29.6.3",
+        "@vitest/pretty-format": "2.0.5",
         "estree-walker": "^3.0.3",
         "loupe": "^3.1.1",
-        "pretty-format": "^29.7.0"
+        "tinyrainbow": "^1.2.0"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
@@ -2402,7 +2383,6 @@
       "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
       "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=12"
       }
@@ -2512,11 +2492,10 @@
       }
     },
     "node_modules/bundle-require": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.2.1.tgz",
-      "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.0.0.tgz",
+      "integrity": "sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "load-tsconfig": "^0.2.3"
       },
@@ -2524,7 +2503,7 @@
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
       "peerDependencies": {
-        "esbuild": ">=0.17"
+        "esbuild": ">=0.18"
       }
     },
     "node_modules/cac": {
@@ -2587,7 +2566,6 @@
       "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz",
       "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "assertion-error": "^2.0.1",
         "check-error": "^2.1.1",
@@ -2631,7 +2609,6 @@
       "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
       "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">= 16"
       }
@@ -3001,7 +2978,6 @@
       "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
       "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">= 12.0.0"
       }
@@ -3035,6 +3011,15 @@
         "proto-list": "~1.2.1"
       }
     },
+    "node_modules/consola": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz",
+      "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==",
+      "dev": true,
+      "engines": {
+        "node": "^14.18.0 || >=16.10.0"
+      }
+    },
     "node_modules/conventional-changelog-angular": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz",
@@ -3222,7 +3207,6 @@
       "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
       "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=6"
       }
@@ -3244,16 +3228,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/diff-sequences": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
-      "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
     "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -3382,8 +3356,7 @@
       "version": "1.5.4",
       "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
       "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
-      "dev": true,
-      "license": "MIT"
+      "dev": true
     },
     "node_modules/esbuild": {
       "version": "0.21.5",
@@ -3517,22 +3490,22 @@
       }
     },
     "node_modules/eslint-plugin-jsdoc": {
-      "version": "48.5.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.2.tgz",
-      "integrity": "sha512-VXBJFviQz30rynlOEQ+dNWLmeopjoAgutUVrWOZwm6Ki4EVDm4XkyIqAV/Zhf7FcDr0AG0aGmRn5FxxCtAF0tA==",
+      "version": "48.10.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.10.2.tgz",
+      "integrity": "sha512-xTkf/MmEeVrTbezc6kDqCJmK9RcseIKo8X4oyoDCMvV4LY8dqrQi8kmfRrv9n0gNBkCclevaOh2Lkmu6Fs8SLg==",
       "dev": true,
-      "license": "BSD-3-Clause",
       "dependencies": {
-        "@es-joy/jsdoccomment": "~0.43.1",
+        "@es-joy/jsdoccomment": "~0.46.0",
         "are-docs-informative": "^0.0.2",
         "comment-parser": "1.4.1",
         "debug": "^4.3.5",
         "escape-string-regexp": "^4.0.0",
-        "esquery": "^1.5.0",
-        "parse-imports": "^2.1.0",
-        "semver": "^7.6.2",
+        "espree": "^10.1.0",
+        "esquery": "^1.6.0",
+        "parse-imports": "^2.1.1",
+        "semver": "^7.6.3",
         "spdx-expression-parse": "^4.0.0",
-        "synckit": "^0.9.0"
+        "synckit": "^0.9.1"
       },
       "engines": {
         "node": ">=18"
@@ -3541,6 +3514,35 @@
         "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
       }
     },
+    "node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+      "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+      "dev": true,
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-plugin-jsdoc/node_modules/espree": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
+      "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.12.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^4.0.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
     "node_modules/eslint-plugin-unicorn": {
       "version": "54.0.0",
       "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz",
@@ -3706,11 +3708,10 @@
       }
     },
     "node_modules/esquery": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
-      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
       "dev": true,
-      "license": "BSD-3-Clause",
       "dependencies": {
         "estraverse": "^5.1.0"
       },
@@ -3746,7 +3747,6 @@
       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
       "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@types/estree": "^1.0.0"
       }
@@ -4087,7 +4087,6 @@
       "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
       "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": "*"
       }
@@ -4375,13 +4374,12 @@
       }
     },
     "node_modules/husky": {
-      "version": "9.0.11",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
-      "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
+      "version": "9.1.4",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.4.tgz",
+      "integrity": "sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==",
       "dev": true,
-      "license": "MIT",
       "bin": {
-        "husky": "bin.mjs"
+        "husky": "bin.js"
       },
       "engines": {
         "node": ">=18"
@@ -4860,7 +4858,6 @@
       "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
       "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=12.0.0"
       }
@@ -5074,7 +5071,6 @@
       "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
       "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
@@ -5251,7 +5247,6 @@
       "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz",
       "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "get-func-name": "^2.0.1"
       }
@@ -8466,11 +8461,10 @@
       }
     },
     "node_modules/parse-imports": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.0.tgz",
-      "integrity": "sha512-JQWgmK2o4w8leUkZeZPatWdAny6vXGU/3siIUvMF6J2rDCud9aTt8h/px9oZJ6U3EcfhngBJ635uPFI0q0VAeA==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.1.tgz",
+      "integrity": "sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==",
       "dev": true,
-      "license": "Apache 2.0",
       "dependencies": {
         "es-module-lexer": "^1.5.3",
         "slashes": "^3.0.12"
@@ -8603,15 +8597,13 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
       "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
-      "dev": true,
-      "license": "MIT"
+      "dev": true
     },
     "node_modules/pathval": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
       "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">= 14.16"
       }
@@ -8786,9 +8778,9 @@
       }
     },
     "node_modules/postcss-load-config": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
-      "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+      "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
       "dev": true,
       "funding": [
         {
@@ -8800,23 +8792,29 @@
           "url": "https://github.com/sponsors/ai"
         }
       ],
-      "license": "MIT",
       "dependencies": {
-        "lilconfig": "^3.0.0",
-        "yaml": "^2.3.4"
+        "lilconfig": "^3.1.1"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       },
       "peerDependencies": {
+        "jiti": ">=1.21.0",
         "postcss": ">=8.0.9",
-        "ts-node": ">=9.0.0"
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
       },
       "peerDependenciesMeta": {
+        "jiti": {
+          "optional": true
+        },
         "postcss": {
           "optional": true
         },
-        "ts-node": {
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
           "optional": true
         }
       }
@@ -8832,11 +8830,10 @@
       }
     },
     "node_modules/prettier": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
-      "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+      "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
       "dev": true,
-      "license": "MIT",
       "bin": {
         "prettier": "bin/prettier.cjs"
       },
@@ -8847,34 +8844,6 @@
         "url": "https://github.com/prettier/prettier?sponsor=1"
       }
     },
-    "node_modules/pretty-format": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
-      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^18.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/pretty-format/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/pretty-ms": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz",
@@ -8906,11 +8875,10 @@
       "license": "ISC"
     },
     "node_modules/publint": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/publint/-/publint-0.2.8.tgz",
-      "integrity": "sha512-C5MjGJ7gpanqaDpgBN+6QhjvXcoj0/YpbucoW29oO5729CGTMzfr3wZTIYcpzB1xl9ZfEqj4KL86P2Z50pt/JA==",
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/publint/-/publint-0.2.9.tgz",
+      "integrity": "sha512-nITKS1NSwD68PQlts0ntryhxrWObep6P0CCycwi1lgXI+K7uKyacMYRRCQi7hTae8imkI3FCi0FlgnwLxjM8yA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "npm-packlist": "^5.1.3",
         "picocolors": "^1.0.1",
@@ -8983,13 +8951,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/react-is": {
-      "version": "18.3.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
-      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/read-package-up": {
       "version": "11.0.0",
       "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
@@ -9424,11 +9385,10 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.18.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
-      "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.2.tgz",
+      "integrity": "sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@types/estree": "1.0.5"
       },
@@ -9440,22 +9400,22 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.18.0",
-        "@rollup/rollup-android-arm64": "4.18.0",
-        "@rollup/rollup-darwin-arm64": "4.18.0",
-        "@rollup/rollup-darwin-x64": "4.18.0",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
-        "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
-        "@rollup/rollup-linux-arm64-gnu": "4.18.0",
-        "@rollup/rollup-linux-arm64-musl": "4.18.0",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
-        "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
-        "@rollup/rollup-linux-s390x-gnu": "4.18.0",
-        "@rollup/rollup-linux-x64-gnu": "4.18.0",
-        "@rollup/rollup-linux-x64-musl": "4.18.0",
-        "@rollup/rollup-win32-arm64-msvc": "4.18.0",
-        "@rollup/rollup-win32-ia32-msvc": "4.18.0",
-        "@rollup/rollup-win32-x64-msvc": "4.18.0",
+        "@rollup/rollup-android-arm-eabi": "4.19.2",
+        "@rollup/rollup-android-arm64": "4.19.2",
+        "@rollup/rollup-darwin-arm64": "4.19.2",
+        "@rollup/rollup-darwin-x64": "4.19.2",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.19.2",
+        "@rollup/rollup-linux-arm-musleabihf": "4.19.2",
+        "@rollup/rollup-linux-arm64-gnu": "4.19.2",
+        "@rollup/rollup-linux-arm64-musl": "4.19.2",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.19.2",
+        "@rollup/rollup-linux-riscv64-gnu": "4.19.2",
+        "@rollup/rollup-linux-s390x-gnu": "4.19.2",
+        "@rollup/rollup-linux-x64-gnu": "4.19.2",
+        "@rollup/rollup-linux-x64-musl": "4.19.2",
+        "@rollup/rollup-win32-arm64-msvc": "4.19.2",
+        "@rollup/rollup-win32-ia32-msvc": "4.19.2",
+        "@rollup/rollup-win32-x64-msvc": "4.19.2",
         "fsevents": "~2.3.2"
       }
     },
@@ -9740,11 +9700,10 @@
       }
     },
     "node_modules/semver": {
-      "version": "7.6.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
-      "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+      "version": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
       "dev": true,
-      "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
       },
@@ -9960,8 +9919,7 @@
       "version": "3.0.12",
       "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz",
       "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==",
-      "dev": true,
-      "license": "ISC"
+      "dev": true
     },
     "node_modules/slice-ansi": {
       "version": "5.0.0",
@@ -10249,26 +10207,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/strip-literal": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz",
-      "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "js-tokens": "^9.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "node_modules/strip-literal/node_modules/js-tokens": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",
-      "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/sucrase": {
       "version": "3.35.0",
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@@ -10410,11 +10348,10 @@
       }
     },
     "node_modules/synckit": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz",
-      "integrity": "sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==",
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
+      "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@pkgr/core": "^0.1.0",
         "tslib": "^2.6.2"
@@ -10607,12 +10544,20 @@
         "node": "^18.0.0 || >=20.0.0"
       }
     },
+    "node_modules/tinyrainbow": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz",
+      "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
     "node_modules/tinyspy": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz",
       "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=14.0.0"
       }
@@ -10704,29 +10649,29 @@
       "version": "2.6.3",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
       "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
-      "dev": true,
-      "license": "0BSD"
+      "dev": true
     },
     "node_modules/tsup": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.1.0.tgz",
-      "integrity": "sha512-UFdfCAXukax+U6KzeTNO2kAARHcWxmKsnvSPXUcfA1D+kU05XDccCrkffCQpFaWDsZfV0jMyTsxU39VfCp6EOg==",
+      "version": "8.2.3",
+      "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.2.3.tgz",
+      "integrity": "sha512-6YNT44oUfXRbZuSMNmN36GzwPPIlD2wBccY7looM2fkTcxkf2NEmwr3OZuDZoySklnrIG4hoEtzy8yUXYOqNcg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "bundle-require": "^4.0.0",
-        "cac": "^6.7.12",
-        "chokidar": "^3.5.1",
-        "debug": "^4.3.1",
-        "esbuild": "^0.21.4",
-        "execa": "^5.0.0",
-        "globby": "^11.0.3",
-        "joycon": "^3.0.1",
-        "postcss-load-config": "^4.0.1",
+        "bundle-require": "^5.0.0",
+        "cac": "^6.7.14",
+        "chokidar": "^3.6.0",
+        "consola": "^3.2.3",
+        "debug": "^4.3.5",
+        "esbuild": "^0.23.0",
+        "execa": "^5.1.1",
+        "globby": "^11.1.0",
+        "joycon": "^3.1.1",
+        "picocolors": "^1.0.1",
+        "postcss-load-config": "^6.0.1",
         "resolve-from": "^5.0.0",
-        "rollup": "^4.0.2",
+        "rollup": "^4.19.0",
         "source-map": "0.8.0-beta.0",
-        "sucrase": "^3.20.3",
+        "sucrase": "^3.35.0",
         "tree-kill": "^1.2.2"
       },
       "bin": {
@@ -10757,6 +10702,413 @@
         }
       }
     },
+    "node_modules/tsup/node_modules/@esbuild/aix-ppc64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz",
+      "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/android-arm": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz",
+      "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/android-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz",
+      "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/android-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz",
+      "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/darwin-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz",
+      "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/darwin-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz",
+      "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz",
+      "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/freebsd-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz",
+      "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-arm": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz",
+      "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz",
+      "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-ia32": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz",
+      "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-loong64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz",
+      "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-mips64el": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz",
+      "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-ppc64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz",
+      "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-riscv64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz",
+      "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-s390x": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz",
+      "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/linux-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz",
+      "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/netbsd-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz",
+      "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/openbsd-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz",
+      "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/sunos-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz",
+      "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/win32-arm64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz",
+      "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/win32-ia32": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz",
+      "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/@esbuild/win32-x64": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz",
+      "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/tsup/node_modules/esbuild": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz",
+      "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.23.0",
+        "@esbuild/android-arm": "0.23.0",
+        "@esbuild/android-arm64": "0.23.0",
+        "@esbuild/android-x64": "0.23.0",
+        "@esbuild/darwin-arm64": "0.23.0",
+        "@esbuild/darwin-x64": "0.23.0",
+        "@esbuild/freebsd-arm64": "0.23.0",
+        "@esbuild/freebsd-x64": "0.23.0",
+        "@esbuild/linux-arm": "0.23.0",
+        "@esbuild/linux-arm64": "0.23.0",
+        "@esbuild/linux-ia32": "0.23.0",
+        "@esbuild/linux-loong64": "0.23.0",
+        "@esbuild/linux-mips64el": "0.23.0",
+        "@esbuild/linux-ppc64": "0.23.0",
+        "@esbuild/linux-riscv64": "0.23.0",
+        "@esbuild/linux-s390x": "0.23.0",
+        "@esbuild/linux-x64": "0.23.0",
+        "@esbuild/netbsd-x64": "0.23.0",
+        "@esbuild/openbsd-arm64": "0.23.0",
+        "@esbuild/openbsd-x64": "0.23.0",
+        "@esbuild/sunos-x64": "0.23.0",
+        "@esbuild/win32-arm64": "0.23.0",
+        "@esbuild/win32-ia32": "0.23.0",
+        "@esbuild/win32-x64": "0.23.0"
+      }
+    },
     "node_modules/tsup/node_modules/execa": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -10941,10 +11293,9 @@
       }
     },
     "node_modules/type-fest": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.21.0.tgz",
-      "integrity": "sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==",
-      "license": "(MIT OR CC0-1.0)",
+      "version": "4.23.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz",
+      "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==",
       "engines": {
         "node": ">=16"
       },
@@ -10953,11 +11304,10 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.5.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
-      "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
+      "version": "5.5.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
       "dev": true,
-      "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -11161,11 +11511,10 @@
       }
     },
     "node_modules/vite": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
-      "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==",
+      "version": "5.3.5",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz",
+      "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "esbuild": "^0.21.3",
         "postcss": "^8.4.39",
@@ -11217,16 +11566,15 @@
       }
     },
     "node_modules/vite-node": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.1.tgz",
-      "integrity": "sha512-nVd6kyhPAql0s+xIVJzuF+RSRH8ZimNrm6U8ZvTA4MXv8CHI17TFaQwRaFiK75YX6XeFqZD4IoAaAfi9OR1XvQ==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz",
+      "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "cac": "^6.7.14",
         "debug": "^4.3.5",
         "pathe": "^1.1.2",
-        "picocolors": "^1.0.1",
+        "tinyrainbow": "^1.2.0",
         "vite": "^5.0.0"
       },
       "bin": {
@@ -11240,30 +11588,30 @@
       }
     },
     "node_modules/vitest": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.1.tgz",
-      "integrity": "sha512-PBPvNXRJiywtI9NmbnEqHIhcXlk8mB0aKf6REQIaYGY4JtWF1Pg8Am+N0vAuxdg/wUSlxPSVJr8QdjwcVxc2Hg==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz",
+      "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "^2.3.0",
-        "@vitest/expect": "2.0.1",
-        "@vitest/runner": "2.0.1",
-        "@vitest/snapshot": "2.0.1",
-        "@vitest/spy": "2.0.1",
-        "@vitest/utils": "2.0.1",
+        "@vitest/expect": "2.0.5",
+        "@vitest/pretty-format": "^2.0.5",
+        "@vitest/runner": "2.0.5",
+        "@vitest/snapshot": "2.0.5",
+        "@vitest/spy": "2.0.5",
+        "@vitest/utils": "2.0.5",
         "chai": "^5.1.1",
         "debug": "^4.3.5",
         "execa": "^8.0.1",
         "magic-string": "^0.30.10",
         "pathe": "^1.1.2",
-        "picocolors": "^1.0.1",
         "std-env": "^3.7.0",
         "tinybench": "^2.8.0",
         "tinypool": "^1.0.0",
+        "tinyrainbow": "^1.2.0",
         "vite": "^5.0.0",
-        "vite-node": "2.0.1",
-        "why-is-node-running": "^2.2.2"
+        "vite-node": "2.0.5",
+        "why-is-node-running": "^2.3.0"
       },
       "bin": {
         "vitest": "vitest.mjs"
@@ -11277,8 +11625,8 @@
       "peerDependencies": {
         "@edge-runtime/vm": "*",
         "@types/node": "^18.0.0 || >=20.0.0",
-        "@vitest/browser": "2.0.1",
-        "@vitest/ui": "2.0.1",
+        "@vitest/browser": "2.0.5",
+        "@vitest/ui": "2.0.5",
         "happy-dom": "*",
         "jsdom": "*"
       },
diff --git a/package.json b/package.json
index dd30c64..1a69f36 100644
--- a/package.json
+++ b/package.json
@@ -61,25 +61,25 @@
     "typecheck:dist": "tsc --project tsconfig.dist.json"
   },
   "dependencies": {
-    "type-fest": "^4.21.0"
+    "type-fest": "^4.23.0"
   },
   "devDependencies": {
     "@arethetypeswrong/cli": "^0.15.3",
     "@eslint/js": "^8.57.0",
-    "@types/eslint-config-prettier": "^6.11.3",
     "@types/eslint__js": "^8.42.3",
+    "@types/eslint-config-prettier": "^6.11.3",
     "@types/node": "^20.14.10",
     "@vitest/coverage-v8": "^2.0.1",
     "eslint": "^8.57.0",
     "eslint-config-prettier": "^9.1.0",
-    "eslint-plugin-jsdoc": "^48.5.2",
+    "eslint-plugin-jsdoc": "^48.10.2",
     "eslint-plugin-unicorn": "^54.0.0",
-    "husky": "^9.0.11",
+    "husky": "^9.1.4",
     "lint-staged": "^15.2.7",
     "prettier": "^3.3.2",
     "publint": "^0.2.8",
     "semantic-release": "^24.0.0",
-    "tsup": "^8.1.0",
+    "tsup": "^8.2.3",
     "typescript": "^5.5.3",
     "typescript-eslint": "^7.16.0",
     "vitest": "^2.0.1"
diff --git a/src/chunk.ts b/src/chunk.ts
index 17feb1e..816fed6 100644
--- a/src/chunk.ts
+++ b/src/chunk.ts
@@ -1,13 +1,204 @@
-import type { IterableContainer, NonEmptyArray } from "./internal/types";
+import {
+  type IfNever,
+  type IntRange,
+  type IsNumericLiteral,
+  type LessThan,
+  type Subtract,
+  type ValueOf,
+} from "type-fest";
+import type {
+  IterableContainer,
+  NonEmptyArray,
+  NTuple,
+  TupleParts,
+} from "./internal/types";
 import { purry } from "./purry";
 
-type Chunked<T extends IterableContainer> = T[number] extends never
+// This prevents typescript from failing on complex arrays and large chunks. It
+// allows the typing to remain useful even when very large chunks are needed,
+// without loosing fidelity on smaller ones. It was chosen by trial-and-error,
+// and given some more wiggle room because the complexity of the array also
+// plays a role in when typescript fails to recurse.
+// See the type tests for an example.
+type MAX_LITERAL_SIZE = 350;
+
+type Chunk<
+  T extends IterableContainer,
+  N extends number,
+> = T extends readonly []
   ? []
-  : T extends
-        | readonly [...Array<unknown>, unknown]
-        | readonly [unknown, ...Array<unknown>]
-    ? NonEmptyArray<NonEmptyArray<T[number]>>
-    : Array<NonEmptyArray<T[number]>>;
+  : IsNumericLiteral<N> extends true
+    ? LessThan<N, 1> extends true
+      ? never
+      : LessThan<N, MAX_LITERAL_SIZE> extends true
+        ? // The spread here is used as a form of "Simplify" for arrays; without
+          // it our return type isn't useful.
+          [...LiteralChunk<T, N>]
+        : GenericChunk<T>
+    : GenericChunk<T>;
+
+type LiteralChunk<
+  T,
+  N extends number,
+  // TupleParts allows us to optimize the algorithm by taking all items up to
+  // the rest param, all items after the rest param, and the type of the rest
+  // param, in a single recursive scan, so that all other parts of our algorithm
+  // don't need to recurse again in order to handle them.
+  Parts extends TupleParts<T> = TupleParts<T>,
+> =
+  | ChunkInfinite<
+      // Our result will always have the prefix tuple chunked the same way, so
+      // we compute it once here and send it to the main logic below
+      ChunkFinite<Parts["prefix"], N>,
+      Parts["item"],
+      Parts["suffix"],
+      N
+    >
+  // If both the prefix and suffix tuples are empty then our input is a simple
+  // array of the form `Array<Item>`. This means it could also be empty, so we
+  // need to add the empty output to our return type.
+  | ([...Parts["prefix"], ...Parts["suffix"]]["length"] extends 0 ? [] : never);
+
+/**
+ * This type **only** works if the input array `T` is a finite tuple (
+ * `[number, "abc", true, { a: "hello" }]` etc..., and it doesn't contain a rest
+ * parameter). For these inputs the chunked output could be computed as literal
+ * finite tuples too.
+ */
+type ChunkFinite<
+  T,
+  N extends number,
+  // Important! Result is initialized with an empty array (and not `[[]]`)
+  // because the result of `chunk` on an empty array is `[]` and not `[[]]`.
+  Result = [],
+> = T extends readonly [infer Head, ...infer Rest]
+  ? // We continue consuming the input tuple recursively item by item.
+    ChunkFinite<
+      Rest,
+      N,
+      Result extends [
+        ...infer Previous extends Array<Array<unknown>>,
+        infer Current extends Array<unknown>,
+      ]
+        ? // We take a look at the last chunk in the result, this is the
+          // "current" chunk where new items would be added, all chunks before
+          // it are already full.
+          Current["length"] extends N
+          ? // The current chunk is full, create a new chunk and put Head in it.
+            [...Previous, Current, [Head]]
+          : // The current chunk is not full yet, so we add Head to it.
+            [...Previous, [...Current, Head]]
+        : // This would only happen on the first iteration, when result is
+          // still empty. In this case we create the first chunk and put Head
+          // in it.
+          [[Head]]
+    >
+  : // We know T is a finite tuple, so the only case where we would reach this
+    // is when T is empty, and in that case our results array contains the whole
+    // input chunked by N.
+    Result;
+
+/**
+ * Here lies the main complexity of building the chunk type. It takes the prefix
+ * chunks, the rest param item type, and the suffix (not chunked!) and it
+ * creates all possible combinations of adding items to the prefix and suffix
+ * for all possible scenarios for how many items the rest param "represents".
+ */
+type ChunkInfinite<
+  PrefixChunks,
+  Item,
+  Suffix extends Array<unknown>,
+  N extends number,
+> = IfNever<
+  Item,
+  // The rest param is never when there is no rest param, the whole array is
+  // a finite tuple and is represented already by the prefix chunks. Suffix is
+  // assumed to be empty in this case.
+  PrefixChunks,
+  PrefixChunks extends [
+    ...infer PrefixFullChunks extends Array<Array<unknown>>,
+    infer LastPrefixChunk extends Array<unknown>,
+  ]
+    ? // When our prefix chunks are not empty it means we need to look at all
+      // combinations of mixing the prefix, the suffix, and different counts of
+      // the rest param until we cover all possible scenarios.
+      | ValueOf<{
+            // We want to iterate over all possible padding sizes we can add to
+            // the last prefix chunk until we reach N
+            // (`0..N-LastPrefixChunk.length`). We need to do this because until
+            // the last prefix chunk is full, we need to consider the suffix
+            // being part of it too...
+            [Padding in IntRangeInclusive<
+              0,
+              Subtract<N, LastPrefixChunk["length"]>
+            >]: [
+              ...PrefixFullChunks,
+              ...ChunkFinite<
+                // Create a new array that would **not** contain a rest param
+                // (so it's finite) made of the last prefix chunk, padding from
+                // the rest param, and the suffix.
+                [...LastPrefixChunk, ...NTuple<Item, Padding>, ...Suffix],
+                N
+              >,
+            ];
+          }>
+        // Additionally, we need to consider the case where the last prefix
+        // chunk **is** full, and follow it with an array of chunks of the rest
+        // param (and only them), and then followed by all possible variations
+        // of the suffix chunks.
+        | [
+            ...PrefixFullChunks,
+            [
+              // Fully padded last prefix chunk
+              ...LastPrefixChunk,
+              ...NTuple<Item, Subtract<N, LastPrefixChunk["length"]>>,
+            ],
+            ...Array<NTuple<Item, N>>,
+            ...SuffixChunk<Suffix, Item, N>,
+          ]
+    : // When our prefix chunks are empty we only need to handle the suffix
+      [...Array<NTuple<Item, N>>, ...SuffixChunk<Suffix, Item, N>]
+>;
+
+/**
+ * This type assumes it takes a finite tuple that represents the suffix of our
+ * input array. It builds all possible combinations of adding items to the
+ * **head** of the suffix in order to pad the suffix until the last chunk is
+ * full.
+ */
+type SuffixChunk<
+  T extends Array<unknown>,
+  Item,
+  N extends number,
+> = T extends readonly []
+  ? // If we don't have a suffix we simply create a single chunk with all
+    // possible non-empty sub-arrays of `Item` up to size `N`.
+    [ValueOf<{ [K in IntRangeInclusive<1, N>]: NTuple<Item, K> }>]
+  : ValueOf<{
+      // When suffix isn't empty we pad the head of the suffix and compute it's
+      // chunks for all possible padding sizes.
+      [Padding in IntRange<0, N>]: ChunkFinite<
+        [...NTuple<Item, Padding>, ...T],
+        N
+      >;
+    }>;
+
+/**
+ * This is the legacy type used when we don't know what N is. We can only adjust
+ * our output based on if we know for sure that the array is empty or not.
+ */
+type GenericChunk<T extends IterableContainer> = T extends
+  | readonly [...Array<unknown>, unknown]
+  | readonly [unknown, ...Array<unknown>]
+  ? NonEmptyArray<NonEmptyArray<T[number]>>
+  : Array<NonEmptyArray<T[number]>>;
+
+/**
+ * Type-fest's IntRange doesn't include the `To` value, but we need it!
+ */
+type IntRangeInclusive<From extends number, To extends number> =
+  | IntRange<From, To>
+  | To;
 
 /**
  * Split an array into groups the length of `size`. If `array` can't be split evenly, the final chunk will be the remaining elements.
@@ -22,10 +213,10 @@ type Chunked<T extends IterableContainer> = T[number] extends never
  * @dataFirst
  * @category Array
  */
-export function chunk<T extends IterableContainer>(
+export function chunk<T extends IterableContainer, N extends number>(
   array: T,
-  size: number,
-): Chunked<T>;
+  size: N,
+): Chunk<T, N>;
 
 /**
  * Split an array into groups the length of `size`. If `array` can't be split evenly, the final chunk will be the remaining elements.
@@ -39,21 +230,49 @@ export function chunk<T extends IterableContainer>(
  * @dataLast
  * @category Array
  */
-export function chunk<T extends IterableContainer>(
-  size: number,
-): (array: T) => Chunked<T>;
+export function chunk<N extends number>(
+  size: N,
+): <T extends IterableContainer>(array: T) => Chunk<T, N>;
 
 export function chunk(...args: ReadonlyArray<unknown>): unknown {
   return purry(chunkImplementation, args);
 }
 
 function chunkImplementation<T>(
-  array: ReadonlyArray<T>,
+  data: ReadonlyArray<T>,
   size: number,
 ): Array<Array<T>> {
-  const ret: Array<Array<T>> = [];
-  for (let offset = 0; offset < array.length; offset += size) {
-    ret.push(array.slice(offset, offset + size));
+  if (size < 1) {
+    throw new RangeError(
+      `chunk: A chunk size of '${size}' would result in an infinite array`,
+    );
+  }
+
+  if (data.length === 0) {
+    return [];
   }
-  return ret;
+
+  if (size >= data.length) {
+    // Optimized for when there is only one chunk.
+    return [[...data]];
+  }
+
+  const chunks = Math.ceil(data.length / size);
+
+  // eslint-disable-next-line unicorn/no-new-array -- This is OK, a sparse array allows us to handle very large arrays more efficiently.
+  const result = new Array<Array<T>>(chunks);
+
+  if (size === 1) {
+    // Optimized for when we don't need slice.
+    for (const [index, item] of data.entries()) {
+      result[index] = [item];
+    }
+  } else {
+    for (let index = 0; index < chunks; index += 1) {
+      const start = index * size;
+      result[index] = data.slice(start, start + size);
+    }
+  }
+
+  return result;
 }
diff --git a/src/internal/types.ts b/src/internal/types.ts
index d64966d..b8d8e7e 100644
--- a/src/internal/types.ts
+++ b/src/internal/types.ts
@@ -234,3 +234,43 @@ export type GuardType<T, Fallback = never> = T extends (
 ) => x is infer U
   ? U
   : Fallback;
+
+/**
+ * An array with *exactly* N elements in it.
+ *
+ * Only literal N values are supported. For very large N the type might result
+ * in a recurse depth error. For negative N the type would result in an infinite
+ * recursion. None of these have protections because this is an internal type!
+ */
+export type NTuple<
+  T,
+  N extends number,
+  Result extends Array<unknown> = [],
+> = Result["length"] extends N ? Result : NTuple<T, N, [...Result, T]>;
+
+/**
+ * Takes an array and returns the types that make up it's parts. The suffix is
+ * anything before the rest parameter (if any), the prefix is anything after the
+ * rest parameter (if any), and the item is the type of the rest parameter.
+ *
+ * The output could be used to reconstruct the input: `[
+ *   ...TupleParts<T>["prefix"],
+ *   ...Array<TupleParts<T>["item"]>,
+ *   ...TupleParts<T>["suffix"],
+ * ]`.
+ */
+export type TupleParts<
+  T,
+  Prefix extends Array<unknown> = [],
+  Suffix extends Array<unknown> = [],
+> = T extends readonly [infer Head, ...infer Tail]
+  ? TupleParts<Tail, [...Prefix, Head], Suffix>
+  : T extends readonly [...infer Head, infer Tail]
+    ? TupleParts<Head, Prefix, [Tail, ...Suffix]>
+    : T extends ReadonlyArray<infer Item>
+      ? {
+          prefix: Prefix;
+          item: Item;
+          suffix: Suffix;
+        }
+      : never;


Test patch:
diff --git a/src/chunk.test-d.ts b/src/chunk.test-d.ts
index 8408444..122de6f 100644
--- a/src/chunk.test-d.ts
+++ b/src/chunk.test-d.ts
@@ -1,74 +1,410 @@
 import { chunk } from "./chunk";
 import { type NonEmptyArray } from "./internal/types";
 
-test("empty tuple", () => {
-  const input: [] = [];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<[]>();
-});
+describe("edge-cases", () => {
+  test("0 chunk size", () => {
+    const result = chunk([1, 2, 3], 0);
+    expectTypeOf(result).toEqualTypeOf<never>();
+  });
 
-test("readonly empty tuple", () => {
-  const input = [] as const;
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<[]>();
+  test("negative chunk size", () => {
+    const result = chunk([1, 2, 3], -10);
+    expectTypeOf(result).toEqualTypeOf<never>();
+  });
 });
 
-test("array", () => {
-  const input: Array<number> = [];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<Array<NonEmptyArray<number>>>();
-});
+describe("regular (non-literal) size", () => {
+  describe("mutable", () => {
+    test("empty tuple", () => {
+      const result = chunk([] as [], 2 as number);
+      expectTypeOf(result).toEqualTypeOf<[]>();
+    });
 
-test("readonly array", () => {
-  const input: ReadonlyArray<number> = [];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<Array<NonEmptyArray<number>>>();
-});
+    test("array", () => {
+      const result = chunk([] as Array<number>, 2 as number);
+      expectTypeOf(result).toEqualTypeOf<Array<NonEmptyArray<number>>>();
+    });
 
-test("tuple", () => {
-  const input: [number, number, number] = [123, 456, 789];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+    test("tuple", () => {
+      const result = chunk(
+        [123, 456, 789] as [number, number, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
 
-test("readonly tuple", () => {
-  const input: readonly [number, number, number] = [123, 456, 789];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+    test("tuple with rest tail", () => {
+      const result = chunk(
+        [123, 456] as [number, ...Array<number>],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
 
-test("tuple with rest tail", () => {
-  const input: [number, ...Array<number>] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+    test("tuple with rest middle", () => {
+      const result = chunk(
+        [123, 456] as [number, ...Array<number>, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
 
-test("readonly tuple with rest tail", () => {
-  const input: readonly [number, ...Array<number>] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+    test("tuple with rest head", () => {
+      const result = chunk(
+        [123, 456] as [...Array<number>, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
+  });
 
-test("tuple with rest middle", () => {
-  const input: [number, ...Array<number>, number] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+  describe("readonly", () => {
+    test("empty tuple", () => {
+      const result = chunk([] as const, 2 as number);
+      expectTypeOf(result).toEqualTypeOf<[]>();
+    });
 
-test("readonly tuple with rest middle", () => {
-  const input: readonly [number, ...Array<number>, number] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
-});
+    test("array", () => {
+      const result = chunk([] as ReadonlyArray<number>, 2 as number);
+      expectTypeOf(result).toEqualTypeOf<Array<NonEmptyArray<number>>>();
+    });
 
-test("tuple with rest head", () => {
-  const input: [...Array<number>, number] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
+    test("tuple", () => {
+      const result = chunk(
+        [123, 456, 789] as readonly [number, number, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
+
+    test("tuple with rest tail", () => {
+      const result = chunk(
+        [123, 456] as readonly [number, ...Array<number>],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
+
+    test("tuple with rest middle", () => {
+      const result = chunk(
+        [123, 456] as readonly [number, ...Array<number>, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
+
+    test("tuple with rest head", () => {
+      const result = chunk(
+        [123, 456] as readonly [...Array<number>, number],
+        2 as number,
+      );
+      expectTypeOf(result).toEqualTypeOf<
+        NonEmptyArray<NonEmptyArray<number>>
+      >();
+    });
+  });
 });
 
-test("readonly tuple with rest head", () => {
-  const input: readonly [...Array<number>, number] = [123, 456];
-  const result = chunk(input, 2);
-  expectTypeOf(result).toEqualTypeOf<NonEmptyArray<NonEmptyArray<number>>>();
+describe("literal size", () => {
+  describe("mutable", () => {
+    test("empty tuple", () => {
+      const result = chunk([] as [], 2);
+      expectTypeOf(result).toEqualTypeOf<[]>();
+    });
+
+    test("array", () => {
+      const result = chunk([] as Array<number>, 2);
+      expectTypeOf(result).toEqualTypeOf<
+        [...Array<[number, number]>, [number, number] | [number]] | []
+      >();
+    });
+
+    test("tuple", () => {
+      const result = chunk([123, 456, 789] as [number, number, number], 2);
+      expectTypeOf(result).toEqualTypeOf<[[number, number], [number]]>();
+    });
+
+    describe("infinite tuples (rest/spread item)", () => {
+      describe("prefix arrays", () => {
+        test("prefix is shorter than chunk size", () => {
+          const result = chunk([1] as [number, ...Array<boolean>], 2);
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, boolean],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            // TODO: Ideally the following two lines should be folded into a
+            // single line: `[[number] | [number, boolean]]`
+            | [[number, boolean]]
+            | [[number]]
+          >();
+        });
+
+        test("prefix is same size as chunk size", () => {
+          const result = chunk(
+            [1, 2] as [number, number, ...Array<boolean>],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, number],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            | [[number, number]]
+          >();
+        });
+
+        test("prefix is longer than chunk size", () => {
+          const result = chunk(
+            [1, 2, 3] as [number, number, number, ...Array<boolean>],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, number],
+                [number, boolean],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            // TODO: Ideally the following two lines should be folded into a
+            // single line: `[[number, number], [number] | [number, boolean]]`
+            | [[number, number], [number, boolean]]
+            | [[number, number], [number]]
+          >();
+        });
+      });
+
+      describe("suffix arrays", () => {
+        test("suffix is shorter than chunk size", () => {
+          const result = chunk([1] as [...Array<boolean>, number], 2);
+          expectTypeOf(result).toEqualTypeOf<
+            | [...Array<[boolean, boolean]>, [boolean, number]]
+            | [...Array<[boolean, boolean]>, [number]]
+          >();
+        });
+
+        test("suffix is same size as chunk size", () => {
+          const result = chunk(
+            [1, 2] as [...Array<boolean>, number, number],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [...Array<[boolean, boolean]>, [boolean, number], [number]]
+            | [...Array<[boolean, boolean]>, [number, number]]
+          >();
+        });
+
+        test("suffix is larger than chunk size", () => {
+          const result = chunk(
+            [1, 2, 3] as [...Array<boolean>, number, number, number],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                ...Array<[boolean, boolean]>,
+                [boolean, number],
+                [number, number],
+              ]
+            | [...Array<[boolean, boolean]>, [number, number], [number]]
+          >();
+        });
+      });
+
+      test("both prefix and suffix", () => {
+        const result = chunk(
+          [123, "abc"] as [number, ...Array<boolean>, string],
+          2,
+        );
+        expectTypeOf(result).toEqualTypeOf<
+          | [[number, boolean], ...Array<[boolean, boolean]>, [boolean, string]]
+          | [[number, boolean], ...Array<[boolean, boolean]>, [string]]
+          // TODO: This is the same type as the previous line (for an empty
+          // array), but it's hard to build the types to be aware of it because
+          // they come from different branches of the type.
+          | [[number, boolean], [string]]
+          | [[number, string]]
+        >();
+      });
+    });
+  });
+
+  describe("readonly", () => {
+    test("empty tuple", () => {
+      const result = chunk([] as const, 2);
+      expectTypeOf(result).toEqualTypeOf<[]>();
+    });
+
+    test("array", () => {
+      const result = chunk([] as ReadonlyArray<number>, 2);
+      expectTypeOf(result).toEqualTypeOf<
+        [...Array<[number, number]>, [number, number] | [number]] | []
+      >();
+    });
+
+    test("tuple", () => {
+      const result = chunk(
+        [123, 456, 789] as readonly [number, number, number],
+        2,
+      );
+      expectTypeOf(result).toEqualTypeOf<[[number, number], [number]]>();
+    });
+
+    test("const", () => {
+      const result = chunk([123, 456, 789] as const, 2);
+      expectTypeOf(result).toEqualTypeOf<[[123, 456], [789]]>();
+    });
+
+    describe("infinite tuples (rest/spread item)", () => {
+      describe("prefix arrays", () => {
+        test("prefix is shorter than chunk size", () => {
+          const result = chunk([1] as readonly [number, ...Array<boolean>], 2);
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, boolean],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            // TODO: Ideally the following two lines should be folded into a
+            // single line: `[[number] | [number, boolean]]`
+            | [[number, boolean]]
+            | [[number]]
+          >();
+        });
+
+        test("prefix is same size as chunk size", () => {
+          const result = chunk(
+            [1, 2] as readonly [number, number, ...Array<boolean>],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, number],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            | [[number, number]]
+          >();
+        });
+
+        test("prefix is longer than chunk size", () => {
+          const result = chunk(
+            [1, 2, 3] as readonly [number, number, number, ...Array<boolean>],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                [number, number],
+                [number, boolean],
+                ...Array<[boolean, boolean]>,
+                [boolean, boolean] | [boolean],
+              ]
+            // TODO: Ideally the following two lines should be folded into a
+            // single line: `[[number, number], [number] | [number, boolean]]`
+            | [[number, number], [number, boolean]]
+            | [[number, number], [number]]
+          >();
+        });
+      });
+
+      describe("suffix arrays", () => {
+        test("suffix is shorter than chunk size", () => {
+          const result = chunk([1] as readonly [...Array<boolean>, number], 2);
+          expectTypeOf(result).toEqualTypeOf<
+            | [...Array<[boolean, boolean]>, [boolean, number]]
+            | [...Array<[boolean, boolean]>, [number]]
+          >();
+        });
+
+        test("suffix is same size as chunk size", () => {
+          const result = chunk(
+            [1, 2] as readonly [...Array<boolean>, number, number],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [...Array<[boolean, boolean]>, [boolean, number], [number]]
+            | [...Array<[boolean, boolean]>, [number, number]]
+          >();
+        });
+
+        test("suffix is larger than chunk size", () => {
+          const result = chunk(
+            [1, 2, 3] as readonly [...Array<boolean>, number, number, number],
+            2,
+          );
+          expectTypeOf(result).toEqualTypeOf<
+            | [
+                ...Array<[boolean, boolean]>,
+                [boolean, number],
+                [number, number],
+              ]
+            | [...Array<[boolean, boolean]>, [number, number], [number]]
+          >();
+        });
+      });
+
+      test("both prefix and suffix", () => {
+        const result = chunk(
+          [123, "abc"] as readonly [number, ...Array<boolean>, string],
+          2,
+        );
+        expectTypeOf(result).toEqualTypeOf<
+          | [[number, boolean], ...Array<[boolean, boolean]>, [boolean, string]]
+          | [[number, boolean], ...Array<[boolean, boolean]>, [string]]
+          // TODO: This is the same type as the previous line (for an empty
+          // array), but it's hard to build the types to be aware of it because
+          // they come from different branches of the type.
+          | [[number, boolean], [string]]
+          | [[number, string]]
+        >();
+      });
+    });
+  });
+
+  describe("max literal chunk size", () => {
+    test("below max", () => {
+      const [[firstItem, secondItem, ...otherItems]] = chunk(
+        ["abc", true] as [string, ...Array<number>, boolean],
+        200,
+      );
+      expectTypeOf(firstItem).toEqualTypeOf<string>();
+      expectTypeOf(secondItem).toEqualTypeOf<boolean | number>();
+      expectTypeOf(otherItems[197]).toEqualTypeOf<
+        boolean | number | undefined
+      >();
+      // @ts-expect-error [ts2339] - This item doesn't exist!
+      expectTypeOf(otherItems[198]).toEqualTypeOf<undefined>();
+    });
+  });
+
+  test("above max", () => {
+    const result = chunk(
+      ["abc", true] as [string, ...Array<number>, boolean],
+      1000,
+    );
+    expectTypeOf(result).toEqualTypeOf<
+      // These are simple non-empty arrays
+      [
+        [boolean | number | string, ...Array<boolean | number | string>],
+        ...Array<
+          [boolean | number | string, ...Array<boolean | number | string>]
+        >,
+      ]
+    >();
+  });
 });
diff --git a/src/chunk.test.ts b/src/chunk.test.ts
index 0b40dfb..726a21b 100644
--- a/src/chunk.test.ts
+++ b/src/chunk.test.ts
@@ -2,33 +2,58 @@ import { chunk } from "./chunk";
 
 describe("data first", () => {
   test("equal size", () => {
-    expect(chunk(["a", "b", "c", "d"] as const, 2)).toEqual([
+    expect(chunk(["a", "b", "c", "d"], 2)).toEqual([
       ["a", "b"],
       ["c", "d"],
     ]);
   });
 
   test("not equal size", () => {
-    expect(chunk(["a", "b", "c", "d"] as const, 3)).toEqual([
-      ["a", "b", "c"],
-      ["d"],
-    ]);
+    expect(chunk(["a", "b", "c", "d"], 3)).toEqual([["a", "b", "c"], ["d"]]);
   });
 
   test("1 element", () => {
-    expect(chunk(["x"] as const, 3)).toEqual([["x"]]);
+    expect(chunk(["x"], 3)).toEqual([["x"]]);
   });
 
   test("empty array", () => {
-    expect(chunk([] as const, 3)).toEqual([]);
+    expect(chunk([], 3)).toEqual([]);
   });
 });
 
 describe("data last", () => {
   test("equal size", () => {
-    expect(chunk(2)(["a", "b", "c", "d"] as const)).toEqual([
+    expect(chunk(2)(["a", "b", "c", "d"])).toEqual([
       ["a", "b"],
       ["c", "d"],
     ]);
   });
 });
+
+describe("edge-cases", () => {
+  it("throws on 0 size", () => {
+    expect(() => chunk(["a", "b", "c", "d"], 0)).toThrow(
+      "chunk: A chunk size of '0' would result in an infinite array",
+    );
+  });
+
+  it("throws on negative size", () => {
+    expect(() => chunk(["a", "b", "c", "d"], -10)).toThrow(
+      "chunk: A chunk size of '-10' would result in an infinite array",
+    );
+  });
+
+  test("size > data.length", () => {
+    const data = [1, 2, 3] as const;
+    const result = chunk(data, 10);
+    expect(result).toStrictEqual([data]);
+    // We expect the result to be a shallow clone
+    expect(result[0]).not.toBe(data);
+  });
+
+  test("chunk of size 1", () => {
+    const data = [1, 2, 3, 4, 5] as const;
+    const result = chunk(data, 1);
+    expect(result).toStrictEqual([[1], [2], [3], [4], [5]]);
+  });
+});
diff --git a/src/internal/types.test-d.ts b/src/internal/types.test-d.ts
index 3f4cf77..dbedd6d 100644
--- a/src/internal/types.test-d.ts
+++ b/src/internal/types.test-d.ts
@@ -4,6 +4,8 @@ import {
   type IfBoundedRecord,
   type EnumerableStringKeyedValueOf,
   type EnumerableStringKeyOf,
+  type NTuple,
+  type TupleParts,
 } from "./types";
 
 declare const SymbolFoo: unique symbol;
@@ -306,3 +308,165 @@ describe("EnumerableStringKeyedValueOf", () => {
     >().toEqualTypeOf<never>();
   });
 });
+
+describe("NTuple", () => {
+  test("size 0", () => {
+    const result = nTuple("foo", 0);
+    expectTypeOf(result).toEqualTypeOf<[]>();
+  });
+
+  test("non-trivial size", () => {
+    const result = nTuple("foo", 3);
+    expectTypeOf(result).toEqualTypeOf<[string, string, string]>();
+  });
+});
+
+describe("TupleParts", () => {
+  describe("mutable", () => {
+    test("empty array", () => {
+      const data = [] as [];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: never;
+        suffix: [];
+      }>();
+    });
+
+    test("regular array", () => {
+      const data = [] as Array<number>;
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: number;
+        suffix: [];
+      }>();
+    });
+
+    test("fixed tuple", () => {
+      const data = [1, 2, 3] as [1, 2, 3];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [1, 2, 3];
+        item: never;
+        suffix: [];
+      }>();
+    });
+
+    test("array with prefix", () => {
+      const data = ["a"] as [string, ...Array<boolean>];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [string];
+        item: boolean;
+        suffix: [];
+      }>();
+    });
+
+    test("array with suffix", () => {
+      const data = ["a"] as [...Array<boolean>, string];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: boolean;
+        suffix: [string];
+      }>();
+    });
+
+    test("array with prefix and suffix", () => {
+      const data = [1, "a"] as [number, ...Array<boolean>, string];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [number];
+        item: boolean;
+        suffix: [string];
+      }>();
+    });
+  });
+
+  describe("readonly", () => {
+    test("empty array", () => {
+      const data = [] as const;
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: never;
+        suffix: [];
+      }>();
+    });
+
+    test("regular array", () => {
+      const data = [] as ReadonlyArray<number>;
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: number;
+        suffix: [];
+      }>();
+    });
+
+    test("fixed tuple", () => {
+      const data = [1, 2, 3] as const;
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [1, 2, 3];
+        item: never;
+        suffix: [];
+      }>();
+    });
+
+    test("array with prefix", () => {
+      const data = ["a"] as readonly [string, ...Array<boolean>];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [string];
+        item: boolean;
+        suffix: [];
+      }>();
+    });
+
+    test("array with suffix", () => {
+      const data = ["a"] as readonly [...Array<boolean>, string];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [];
+        item: boolean;
+        suffix: [string];
+      }>();
+    });
+
+    test("array with prefix and suffix", () => {
+      const data = [1, "a"] as readonly [number, ...Array<boolean>, string];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<{
+        prefix: [number];
+        item: boolean;
+        suffix: [string];
+      }>();
+    });
+  });
+
+  describe("unions", () => {
+    test("union of arrays", () => {
+      const data = [] as Array<boolean> | Array<number>;
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<
+        | { prefix: []; item: boolean; suffix: [] }
+        | { prefix: []; item: number; suffix: [] }
+      >();
+    });
+
+    test("mixed unions", () => {
+      const data = [] as Array<boolean> | [number, string];
+      const result = tupleParts(data);
+      expectTypeOf(result).toEqualTypeOf<
+        | { prefix: []; item: boolean; suffix: [] }
+        | { prefix: [number, string]; item: never; suffix: [] }
+      >();
+    });
+  });
+});
+
+declare function nTuple<T, N extends number>(x: T, n: N): NTuple<T, N>;
+
+declare function tupleParts<T>(x: T): TupleParts<T>;