From 202d43f468fd8c752730802c35bdfa522f7b1362 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 20:44:01 +0000 Subject: [PATCH 1/5] build(deps-dev): bump he from 1.2.0 to 2.0.0 Bumps [he](https://github.com/mathiasbynens/he) from 1.2.0 to 2.0.0. - [Commits](https://github.com/mathiasbynens/he/compare/v1.2.0...v2.0.0) --- updated-dependencies: - dependency-name: he dependency-version: 2.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 13 ++++++++----- package.json | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index d29d83af..ac558a54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "he": "^1.2.0", + "he": "^2.0.0", "html-entities": "^2.6.0", "parse-entities": "^4.0.2", "tinybench": "^6.2.0", @@ -2798,13 +2798,16 @@ } }, "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/he/-/he-2.0.0.tgz", + "integrity": "sha512-0jE+JPv08nhXWmI1dULybzqNt34RbkH6Ul6V4cmDONpjYx1SfyObKF38FJLaJ1K7WWD93LWL9lewzk4E1Ria4A==", "dev": true, "license": "MIT", "bin": { - "he": "bin/he" + "he": "bin/he.mjs" + }, + "engines": { + "node": ">=22" } }, "node_modules/hookified": { diff --git a/package.json b/package.json index 755fe4a1..b99e1bfc 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "he": "^1.2.0", + "he": "^2.0.0", "html-entities": "^2.6.0", "parse-entities": "^4.0.2", "tinybench": "^6.2.0", From 44c1e154596809acd9a6cd561d11ab2ca4081941 Mon Sep 17 00:00:00 2001 From: Felix Boehm <188768+fb55@users.noreply.github.com> Date: Fri, 9 Oct 2026 13:42:11 +0100 Subject: [PATCH 2/5] build: isolate he in the benchmark dependency package --- .github/dependabot.yml | 6 +++++ .github/workflows/nodejs-test.yml | 2 ++ eslint.config.mjs | 2 +- package-lock.json | 22 ---------------- package.json | 4 +-- readme.md | 10 +++++++- scripts/{ => benchmark}/benchmark.ts | 4 +-- scripts/benchmark/package-lock.json | 38 ++++++++++++++++++++++++++++ scripts/benchmark/package.json | 18 +++++++++++++ scripts/benchmark/tsconfig.json | 5 ++++ tsconfig.eslint.json | 2 +- 11 files changed, 83 insertions(+), 30 deletions(-) rename scripts/{ => benchmark}/benchmark.ts (97%) create mode 100644 scripts/benchmark/package-lock.json create mode 100644 scripts/benchmark/package.json create mode 100644 scripts/benchmark/tsconfig.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5cbae383..846e7246 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,12 @@ updates: interval: daily open-pull-requests-limit: 10 versioning-strategy: increase + - package-ecosystem: npm + directory: "/scripts/benchmark" + schedule: + interval: daily + open-pull-requests-limit: 10 + versioning-strategy: increase - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/workflows/nodejs-test.yml b/.github/workflows/nodejs-test.yml index 11a7a91a..03afcc93 100644 --- a/.github/workflows/nodejs-test.yml +++ b/.github/workflows/nodejs-test.yml @@ -23,7 +23,9 @@ jobs: node-version: lts/* cache: npm - run: npm ci + - run: npm ci --prefix scripts/benchmark - run: npm run lint + - run: npm --prefix scripts/benchmark run lint test: name: Node ${{ matrix.node }} diff --git a/eslint.config.mjs b/eslint.config.mjs index ffa36b51..ae1afd2e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -16,7 +16,7 @@ export default defineConfig([ }, }, { - ignores: ["eslint.config.{js,cjs,mjs}"], + ignores: ["eslint.config.{js,cjs,mjs}", "scripts/benchmark/**"], }, ...feedicFlatConfig, { diff --git a/package-lock.json b/package-lock.json index ac558a54..82572fe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,10 @@ "@biomejs/biome": "^2.5.14", "@eslint/compat": "^2.1.1", "@feedic/eslint-config": "^0.5.0", - "@types/he": "^1.2.3", "@types/node": "^26.6.4", "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "he": "^2.0.0", "html-entities": "^2.6.0", "parse-entities": "^4.0.2", "tinybench": "^6.2.0", @@ -1432,13 +1430,6 @@ "@types/unist": "*" } }, - "node_modules/@types/he": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.3.tgz", - "integrity": "sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2797,19 +2788,6 @@ "node": ">=20" } }, - "node_modules/he": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/he/-/he-2.0.0.tgz", - "integrity": "sha512-0jE+JPv08nhXWmI1dULybzqNt34RbkH6Ul6V4cmDONpjYx1SfyObKF38FJLaJ1K7WWD93LWL9lewzk4E1Ria4A==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he.mjs" - }, - "engines": { - "node": ">=22" - } - }, "node_modules/hookified": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", diff --git a/package.json b/package.json index b99e1bfc..07a5ec93 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "!**/*.spec.ts" ], "scripts": { - "benchmark": "node --import=tsx scripts/benchmark.ts", + "benchmark": "npm --prefix scripts/benchmark run benchmark", "build": "tsc", "build:docs": "typedoc --hideGenerator src/index.ts", "build:encode-trie": "node --import=tsx scripts/write-encode-map.ts", @@ -62,12 +62,10 @@ "@biomejs/biome": "^2.5.14", "@eslint/compat": "^2.1.1", "@feedic/eslint-config": "^0.5.0", - "@types/he": "^1.2.3", "@types/node": "^26.6.4", "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "he": "^2.0.0", "html-entities": "^2.6.0", "parse-entities": "^4.0.2", "tinybench": "^6.2.0", diff --git a/readme.md b/readme.md index d571412d..5f2b0963 100644 --- a/readme.md +++ b/readme.md @@ -40,7 +40,15 @@ entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '" Benchmarked in September 2025 with Node v24.6.0 on Apple M2 using `tinybench`. Higher ops/s is better; `avg (μs)` is the mean time per operation. -See `scripts/benchmark.ts` to reproduce. +See `scripts/benchmark/benchmark.ts` to reproduce. The benchmark requires Node +v22+ and installs `he` separately from the main development dependencies: + +```sh +npm ci +npm ci --prefix scripts/benchmark +npm --prefix scripts/benchmark run lint +npm run benchmark +``` ### Decoding diff --git a/scripts/benchmark.ts b/scripts/benchmark/benchmark.ts similarity index 97% rename from scripts/benchmark.ts rename to scripts/benchmark/benchmark.ts index 0d4c36d5..5411d650 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark/benchmark.ts @@ -1,8 +1,8 @@ -import he from "he"; +import * as he from "he"; import * as htmlEntities from "html-entities"; import { parseEntities } from "parse-entities"; import { Bench } from "tinybench"; -import * as entities from "../src/index.js"; +import * as entities from "../../src/index.js"; const htmlEntitiesHtml5EncodeOptions: htmlEntities.EncodeOptions = { level: "html5", diff --git a/scripts/benchmark/package-lock.json b/scripts/benchmark/package-lock.json new file mode 100644 index 00000000..470d11d5 --- /dev/null +++ b/scripts/benchmark/package-lock.json @@ -0,0 +1,38 @@ +{ + "name": "entities-benchmark", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "entities-benchmark", + "dependencies": { + "he": "^2.0.0" + }, + "devDependencies": { + "@types/he": "^1.2.3" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@types/he": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.3.tgz", + "integrity": "sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/he": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/he/-/he-2.0.0.tgz", + "integrity": "sha512-0jE+JPv08nhXWmI1dULybzqNt34RbkH6Ul6V4cmDONpjYx1SfyObKF38FJLaJ1K7WWD93LWL9lewzk4E1Ria4A==", + "license": "MIT", + "bin": { + "he": "bin/he.mjs" + }, + "engines": { + "node": ">=22" + } + } + } +} diff --git a/scripts/benchmark/package.json b/scripts/benchmark/package.json new file mode 100644 index 00000000..c6abf7a0 --- /dev/null +++ b/scripts/benchmark/package.json @@ -0,0 +1,18 @@ +{ + "name": "entities-benchmark", + "private": true, + "type": "module", + "scripts": { + "benchmark": "node --import=tsx benchmark.ts", + "lint": "tsc --noEmit" + }, + "dependencies": { + "he": "^2.0.0" + }, + "devDependencies": { + "@types/he": "^1.2.3" + }, + "engines": { + "node": ">=22" + } +} diff --git a/scripts/benchmark/tsconfig.json b/scripts/benchmark/tsconfig.json new file mode 100644 index 00000000..ade57d85 --- /dev/null +++ b/scripts/benchmark/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.eslint.json", + "include": ["benchmark.ts"], + "exclude": [] +} diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 3fdb051d..6699d7d9 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -6,5 +6,5 @@ "types": ["node"] }, "include": ["src", "scripts"], - "exclude": [] + "exclude": ["scripts/benchmark"] } From 3a0c6aefe75d29d0456b7c53a25ec01521b05cfe Mon Sep 17 00:00:00 2001 From: Felix Boehm <188768+fb55@users.noreply.github.com> Date: Fri, 9 Oct 2026 14:02:30 +0100 Subject: [PATCH 3/5] build: isolate remaining benchmark-only dependencies --- package-lock.json | 118 ----------------------- package.json | 3 - scripts/benchmark/package-lock.json | 142 +++++++++++++++++++++++++++- scripts/benchmark/package.json | 5 +- 4 files changed, 145 insertions(+), 123 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82572fe3..dcfc62d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,6 @@ "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "html-entities": "^2.6.0", - "parse-entities": "^4.0.2", - "tinybench": "^6.2.0", "tsx": "^4.23.15", "typedoc": "^0.28.20", "typescript": "^6.0.3", @@ -1924,39 +1921,6 @@ "dev": true, "license": "MIT" }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -2030,20 +1994,6 @@ } } }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2858,32 +2808,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-builtin-module": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", @@ -2900,17 +2824,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2934,17 +2847,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -3590,26 +3492,6 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/parse-imports-exports": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", diff --git a/package.json b/package.json index 07a5ec93..5e6fae6b 100644 --- a/package.json +++ b/package.json @@ -66,9 +66,6 @@ "eslint": "^10.12.0", "eslint-config-biome": "^2.1.3", "globals": "^17.13.0", - "html-entities": "^2.6.0", - "parse-entities": "^4.0.2", - "tinybench": "^6.2.0", "tsx": "^4.23.15", "typedoc": "^0.28.20", "typescript": "^6.0.3", diff --git a/scripts/benchmark/package-lock.json b/scripts/benchmark/package-lock.json index 470d11d5..d8818812 100644 --- a/scripts/benchmark/package-lock.json +++ b/scripts/benchmark/package-lock.json @@ -6,7 +6,10 @@ "": { "name": "entities-benchmark", "dependencies": { - "he": "^2.0.0" + "he": "^2.0.0", + "html-entities": "^2.6.0", + "parse-entities": "^4.0.2", + "tinybench": "^6.2.0" }, "devDependencies": { "@types/he": "^1.2.3" @@ -22,6 +25,55 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/he": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/he/-/he-2.0.0.tgz", @@ -33,6 +85,94 @@ "engines": { "node": ">=22" } + }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tinybench": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.1.tgz", + "integrity": "sha512-IAbQaPJIIdhVxi0mqy9lez1wEwje0UQf9F1vwtbelEG5Nbgn0nPOxCvU+mNeNS9gyJTAhrHp74CbUaSynQpZcQ==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } } } } diff --git a/scripts/benchmark/package.json b/scripts/benchmark/package.json index c6abf7a0..4e624f3d 100644 --- a/scripts/benchmark/package.json +++ b/scripts/benchmark/package.json @@ -7,7 +7,10 @@ "lint": "tsc --noEmit" }, "dependencies": { - "he": "^2.0.0" + "he": "^2.0.0", + "html-entities": "^2.6.0", + "parse-entities": "^4.0.2", + "tinybench": "^6.2.0" }, "devDependencies": { "@types/he": "^1.2.3" From eaf3dab2669ae40ea9f55dd74e34967b4a88f4e8 Mon Sep 17 00:00:00 2001 From: Felix Boehm <188768+fb55@users.noreply.github.com> Date: Fri, 9 Oct 2026 15:08:51 +0100 Subject: [PATCH 4/5] docs: distinguish historical benchmark results from current runs --- readme.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 5f2b0963..baae922e 100644 --- a/readme.md +++ b/readme.md @@ -40,8 +40,14 @@ entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '" Benchmarked in September 2025 with Node v24.6.0 on Apple M2 using `tinybench`. Higher ops/s is better; `avg (μs)` is the mean time per operation. -See `scripts/benchmark/benchmark.ts` to reproduce. The benchmark requires Node -v22+ and installs `he` separately from the main development dependencies: +The tables below are historical measurements of the listed library versions, +including `he` 1.2.0. The current benchmark uses the versions in +`scripts/benchmark/package-lock.json`, including `he` 2.0.0, and does not reproduce +these historical results. + +To run the current comparison, use `scripts/benchmark/benchmark.ts`. It requires +Node v22+ and installs benchmark dependencies separately from the main development +dependencies: ```sh npm ci From b70b531349f0b77d51d1170ec1fb38ff6f335918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=B6hm?= Date: Sat, 10 Oct 2026 08:49:56 +0100 Subject: [PATCH 5/5] ci: use current Node major versions --- .github/workflows/nodejs-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs-test.yml b/.github/workflows/nodejs-test.yml index 03afcc93..b07c2cd2 100644 --- a/.github/workflows/nodejs-test.yml +++ b/.github/workflows/nodejs-test.yml @@ -35,7 +35,7 @@ jobs: fail-fast: false matrix: node: - - '20.19.0' + - '20' - '22' - '24' - 'lts/*'