diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 000000000..63145fb80 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,50 @@ +name: CodSpeed + +on: + push: + branches: + - main + - next/* + - feat/* + - fix/* + - perf/* + - v1 + - v1.* + pull_request: + branches: + - main + - next/* + - feat/* + - fix/* + - perf/* + - v1 + - v1.* + workflow_dispatch: + +permissions: + contents: read + id-token: write + +jobs: + benchmarks: + name: Run Benchmarks + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".node-version" + cache: "npm" + + - name: Install NPM Dependencies + run: npm ci + + - name: Run Benchmarks with CodSpeed + uses: CodSpeedHQ/action@v4 + with: + mode: simulation + run: npx vitest bench --run --config vitest.bench.config.js diff --git a/README.md b/README.md index a1c7a348d..f3cbb706c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![UnitTests](https://badgen.net/https/wzcozo2uwacu4dfvawkdkmxi640guflx.lambda-url.us-east-1.on.aws?cache=300)](https://github.com/Semantic-Org/Semantic-Next/actions/workflows/ci.yml) [![E2ETests](https://badgen.net/https/ien5pqfy4lsyqy5a2vegyvevpa0petpj.lambda-url.us-east-1.on.aws?cache=300)](https://github.com/Semantic-Org/Semantic-Next/actions/workflows/ci.yml) [![Coverage](https://badgen.net/https/fnipttzwzg6ieemy4winuladuu0jhqef.lambda-url.us-east-1.on.aws?cache=300)](https://github.com/Semantic-Org/Semantic-Next/actions/workflows/ci.yml) +[![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/Semantic-Org/Semantic-Next?utm_source=badge) A modern, lightweight UI framework built with Web Components. diff --git a/benchmarks/arrays.bench.js b/benchmarks/arrays.bench.js new file mode 100644 index 000000000..05143a604 --- /dev/null +++ b/benchmarks/arrays.bench.js @@ -0,0 +1,92 @@ +import { bench, describe } from 'vitest'; +import { + difference, + flatten, + groupBy, + intersection, + range, + sortBy, + unique, + uniqueItems, +} from '../packages/utils/src/arrays.js'; + +describe('array utilities', () => { + const smallArray = range(0, 20); + const mediumArray = range(0, 100); + const largeArray = range(0, 500); + + bench('unique - small array', () => { + unique([...smallArray, ...smallArray]); + }); + + bench('unique - medium array', () => { + unique([...mediumArray, ...mediumArray]); + }); + + bench('flatten - nested arrays', () => { + const nested = [[1, 2], [3, 4], [[5, 6], [7, 8]], [9, 10]]; + flatten(nested); + }); + + bench('flatten - deeply nested', () => { + const nested = [[[[[1, 2]]], [[3, 4]]], [[[5, 6]], [[7, 8]]]]; + flatten(nested); + }); + + bench('sortBy - numeric property', () => { + const data = mediumArray.map((i) => ({ id: i, value: Math.random() })); + sortBy(data, 'value'); + }); + + bench('sortBy - multiple keys', () => { + const data = mediumArray.map((i) => ({ + category: i % 5, + priority: i % 3, + value: Math.random(), + })); + sortBy(data, ['category', 'priority', 'value']); + }); + + bench('groupBy - small dataset', () => { + const data = smallArray.map((i) => ({ category: i % 5, value: i })); + groupBy(data, 'category'); + }); + + bench('groupBy - large dataset', () => { + const data = largeArray.map((i) => ({ category: i % 10, value: i })); + groupBy(data, 'category'); + }); + + bench('intersection - small arrays', () => { + const arr1 = range(0, 20); + const arr2 = range(10, 30); + const arr3 = range(15, 35); + intersection(arr1, arr2, arr3); + }); + + bench('intersection - largearrays', () => { + const arr1 = range(0, 200); + const arr2 = range(100, 300); + const arr3 = range(150, 350); + intersection(arr1, arr2, arr3); + }); + + bench('difference - small arrays', () => { + const arr1 = range(0, 20); + const arr2 = range(10, 30); + difference(arr1, arr2); + }); + + bench('difference - large arrays', () => { + const arr1 = range(0, 200); + const arr2 = range(100, 300); + difference(arr1, arr2); + }); + + bench('uniqueItems - multiple arrays', () => { + const arr1 = range(0, 30); + const arr2 = range(20, 50); + const arr3 = range(40, 70); + uniqueItems(arr1, arr2, arr3); + }); +}); diff --git a/benchmarks/strings.bench.js b/benchmarks/strings.bench.js new file mode 100644 index 000000000..ce9454f33 --- /dev/null +++ b/benchmarks/strings.bench.js @@ -0,0 +1,86 @@ +import { bench, describe } from 'vitest'; +import { + camelToKebab, + capitalize, + capitalizeWords, + escapeHTML, + getArticle, + joinWords, + kebabToCamel, + toTitleCase, + truncate, +} from '../packages/utils/src/strings.js'; + +describe('string utilities', () => { + const shortString = 'hello world'; + const longString = 'the quick brown fox jumps over the lazy dog '.repeat(10); + const htmlString = ' &
content
'; + const kebabString = 'this-is-a-kebab-case-string-with-many-words'; + const camelString = 'thisIsACamelCaseStringWithManyWords'; + + bench('kebabToCamel - short string', () => { + kebabToCamel('hello-world'); + }); + + bench('kebabToCamel - long string', () => { + kebabToCamel(kebabString); + }); + + bench('camelToKebab - short string', () => { + camelToKebab('helloWorld'); + }); + + bench('camelToKebab - long string', () => { + camelToKebab(camelString); + }); + + bench('capitalize', () => { + capitalize(shortString); + }); + + bench('capitalizeWords', () => { + capitalizeWords(longString); + }); + + bench('toTitleCase - short', () => { + toTitleCase('the quick brown fox'); + }); + + bench('toTitleCase - long', () => { + toTitleCase(longString); + }); + + bench('joinWords - small list', () => { + joinWords(['apple', 'banana', 'cherry']); + }); + + bench('joinWords - large list with options', () => { + const words = Array.from({ length: 20 }, (_, i) => `item${i}`); + joinWords(words, { oxford: true, quotes: true }); + }); + + bench('getArticle', () => { + getArticle('umbrella'); + getArticle('house'); + }); + + bench('truncate - short text', () => { + truncate(shortString, 50); + }); + + bench('truncate - long text with word boundary', () => { + truncate(longString, 100, { wordBoundary: true }); + }); + + bench('truncate - long text without word boundary', () => { + truncate(longString, 100, { wordBoundary: false }); + }); + + bench('escapeHTML - simple', () => { + escapeHTML('
test
'); + }); + + bench('escapeHTML - complex', () => { + escapeHTML(htmlString); + }); +}); diff --git a/package-lock.json b/package-lock.json index a94cf0dbf..714ce0b18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@semantic-ui/specs": "^0.17.0" }, "devDependencies": { + "@codspeed/vitest-plugin": "^5.1.0", "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/node": "^24.3.0", @@ -467,6 +468,51 @@ "node": ">=18" } }, + "node_modules/@codspeed/core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@codspeed/core/-/core-5.1.0.tgz", + "integrity": "sha512-DFO8c7/wd42QbabBdTYR7UsO8g77eHWE9Q4Eyr6yUJSoWhb1qaSoXiqX77RtN3Sbw8RGhhXiwaUC+vVr08+OMg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "axios": "^1.4.0", + "find-up": "^6.3.0", + "form-data": "^4.0.4", + "node-gyp-build": "^4.6.0" + } + }, + "node_modules/@codspeed/core/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@codspeed/vitest-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@codspeed/vitest-plugin/-/vitest-plugin-5.1.0.tgz", + "integrity": "sha512-rA+8DdsbAYxO7lo49K8ZBJqEk7b14Uztpz47ZKm6k8RJcTijffk7OjpG3kOJVUWWta2BVI1bPVj9ENmdfUwrfA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@codspeed/core": "^5.1.0" + }, + "peerDependencies": { + "tinybench": ">=2.9.0", + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "vitest": "^3.2 || ^4" + } + }, "node_modules/@commitlint/cli": { "version": "19.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.1.tgz", @@ -3525,6 +3571,25 @@ "node": ">=12" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3620,6 +3685,20 @@ "node": ">=8" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3860,6 +3939,19 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -4084,6 +4176,16 @@ "license": "MIT", "peer": true }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4158,6 +4260,21 @@ "@dprint/win32-x64": "0.50.1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4226,6 +4343,26 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", @@ -4233,6 +4370,35 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", @@ -4854,6 +5020,27 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -4871,6 +5058,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -4886,6 +5090,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4906,6 +5120,45 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/git-raw-commits": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", @@ -5020,6 +5273,19 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "license": "MIT" }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5044,6 +5310,48 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -5819,6 +6127,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/meow": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", @@ -5997,6 +6315,18 @@ "dev": true, "license": "MIT" }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -6314,6 +6644,13 @@ "dev": true, "license": "ISC" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index d06ee05ac..8b8eca34f 100755 --- a/package.json +++ b/package.json @@ -233,6 +233,7 @@ "@pagefind/modular-ui": "^1.3.0" }, "devDependencies": { + "@codspeed/vitest-plugin": "^5.1.0", "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/node": "^24.3.0", diff --git a/vitest.bench.config.js b/vitest.bench.config.js new file mode 100644 index 000000000..7611a3044 --- /dev/null +++ b/vitest.bench.config.js @@ -0,0 +1,15 @@ +import codspeedPlugin from '@codspeed/vitest-plugin'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [codspeedPlugin()], + test: { + benchmark: { + include: ['**/*.bench.{js,ts}'], + }, + }, + server: { + host: '127.0.0.1', + hmr: false, + }, +});