From 1adc6541dfce4714edbfa0fe48e400dac03cbb4d Mon Sep 17 00:00:00 2001 From: ematipico Date: Wed, 26 Aug 2026 15:00:13 +0100 Subject: [PATCH 1/4] chore: add benchmarks --- .github/workflows/benchmarks.yml | 48 +++ .gitignore | 2 + .../__bench_e2e__/components.bench.ts | 20 + packages/starlight/__bench_e2e__/fixtures.ts | 143 +++++++ .../fixtures/components/.gitignore | 3 + .../fixtures/components/astro.config.mjs | 6 + .../fixtures/components/package.json | 9 + .../fixtures/components/src/content.config.ts | 7 + .../fixtures/large-sidebar/.gitignore | 3 + .../fixtures/large-sidebar/astro.config.mjs | 12 + .../fixtures/large-sidebar/package.json | 9 + .../large-sidebar/src/content.config.ts | 7 + .../__bench_e2e__/fixtures/locales/.gitignore | 3 + .../fixtures/locales/astro.config.mjs | 16 + .../fixtures/locales/package.json | 9 + .../fixtures/locales/src/content.config.ts | 7 + .../__bench_e2e__/large-sidebar.bench.ts | 20 + .../starlight/__bench_e2e__/locales.bench.ts | 23 ++ .../__bench_fn__/generate-route-data.bench.ts | 50 +++ packages/starlight/__tests__/test-config.ts | 5 +- packages/starlight/package.json | 4 + packages/starlight/vitest.e2e.bench.config.ts | 13 + .../vitest.functional.bench.config.ts | 26 ++ pnpm-lock.yaml | 382 +++++++++++++++--- 24 files changed, 778 insertions(+), 49 deletions(-) create mode 100644 .github/workflows/benchmarks.yml create mode 100644 packages/starlight/__bench_e2e__/components.bench.ts create mode 100644 packages/starlight/__bench_e2e__/fixtures.ts create mode 100644 packages/starlight/__bench_e2e__/fixtures/components/.gitignore create mode 100644 packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs create mode 100644 packages/starlight/__bench_e2e__/fixtures/components/package.json create mode 100644 packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts create mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore create mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs create mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json create mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts create mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/.gitignore create mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs create mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/package.json create mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts create mode 100644 packages/starlight/__bench_e2e__/large-sidebar.bench.ts create mode 100644 packages/starlight/__bench_e2e__/locales.bench.ts create mode 100644 packages/starlight/__bench_fn__/generate-route-data.bench.ts create mode 100644 packages/starlight/vitest.e2e.bench.config.ts create mode 100644 packages/starlight/vitest.functional.bench.config.ts diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 00000000000..65293546ddd --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,48 @@ +name: Benchmarks + +on: + push: + branches: [main] + paths: + - 'packages/starlight/**' + - '!packages/starlight/__tests__/**' + - '!packages/starlight/__e2e__/**' + - 'package.json' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - '.github/workflows/benchmarks.yml' + pull_request: + branches: [main] + paths: + - 'packages/starlight/**' + - '!packages/starlight/__tests__/**' + - '!packages/starlight/__e2e__/**' + - 'package.json' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - '.github/workflows/benchmarks.yml' + workflow_dispatch: + +concurrency: + group: codspeed-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + benchmarks: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.23.1 + cache: pnpm + - run: pnpm i --filter @astrojs/starlight --filter @bench/components --filter @bench/large-sidebar --filter @bench/locales + - name: Run benchmarks + uses: CodSpeedHQ/action@562878fc153dee6c0f3719c99b1799334cfc3ccc # v5 + with: + mode: simulation + run: pnpm --filter @astrojs/starlight bench diff --git a/.gitignore b/.gitignore index 4f7bb9e9f75..0aaef2f245d 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ test-results/ # Vercel output .vercel + +.idea diff --git a/packages/starlight/__bench_e2e__/components.bench.ts b/packages/starlight/__bench_e2e__/components.bench.ts new file mode 100644 index 00000000000..4d7e6dddeb7 --- /dev/null +++ b/packages/starlight/__bench_e2e__/components.bench.ts @@ -0,0 +1,20 @@ +import { bench, describe } from 'vitest'; +import { + buildBenchOptions, + buildFixture, + cleanFixture, + createComponentDocs, + resetFixtureBuild, + writeFixtureDocs, +} from './fixtures'; + +describe('components', () => { + bench('build', () => buildFixture('components'), { + ...buildBenchOptions, + setup: async () => { + await writeFixtureDocs('components', createComponentDocs()); + await resetFixtureBuild('components'); + }, + teardown: () => cleanFixture('components'), + }); +}); diff --git a/packages/starlight/__bench_e2e__/fixtures.ts b/packages/starlight/__bench_e2e__/fixtures.ts new file mode 100644 index 00000000000..241e8f73cff --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures.ts @@ -0,0 +1,143 @@ +import { rmSync } from 'node:fs'; +import { mkdir, rm, writeFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; +import { build } from 'astro'; + +process.env.ASTRO_TELEMETRY_DISABLED = 'true'; +process.env.ASTRO_DISABLE_UPDATE_CHECK = 'true'; + +const componentNames = [ + 'aside', + 'badge', + 'card', + 'card-grid', + 'code', + 'file-tree', + 'icon', + 'link-button', + 'link-card', + 'steps', + 'tab-item', + 'tabs', +] as const; + +type FixtureName = 'large-sidebar' | 'components' | 'locales'; + +interface DocFile { + path: string; + contents: string; +} + +export const buildBenchOptions = { + iterations: 1, + time: 0, + warmupIterations: 0, + warmupTime: 0, +}; + +function getFixtureRoot(name: FixtureName) { + return fileURLToPath(new URL(`./fixtures/${name}/`, import.meta.url)); +} + +function frontmatter(title: string) { + return `---\ntitle: ${title}\n---\n\n`; +} + +function componentContents(component: (typeof componentNames)[number]) { + const imports = `import { ${ + component === 'code' + ? 'Code' + : component + .split('-') + .map((part) => part[0]?.toUpperCase() + part.slice(1)) + .join('') + } } from '@astrojs/starlight/components';\n\n`; + + switch (component) { + case 'aside': + return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; + case 'badge': + return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; + case 'card': + return `${imports}{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; + case 'card-grid': + return `${imports}import { Card } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; + case 'code': + return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; + case 'file-tree': + return `${imports}{Array.from({ length: 100 }, (_, index) =>
  • {\`file-\${index}.ts\`}
)}`; + case 'icon': + return `${imports}{Array.from({ length: 100 }, () => )}`; + case 'link-button': + return `${imports}{Array.from({ length: 100 }, (_, index) => Destination)}`; + case 'link-card': + return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; + case 'steps': + return `${imports}{Array.from({ length: 100 }, (_, index) =>
  1. {\`Step \${index}\`}
)}`; + case 'tab-item': + return `${imports}import { Tabs } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; + case 'tabs': + return `${imports}import { TabItem } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; + } +} + +export function createComponentDocs(locales: string[] = ['']): DocFile[] { + return [ + { path: '404.md', contents: frontmatter('Not found') + 'Benchmark fallback page.\n' }, + ...locales.flatMap((locale) => + componentNames.map((component) => ({ + path: `${locale ? locale + '/' : ''}components/${component}.mdx`, + contents: frontmatter(component) + componentContents(component), + })) + ), + ]; +} + +export function createLargeSidebarDocs(): DocFile[] { + const docs: DocFile[] = [ + { path: '404.md', contents: frontmatter('Not found') + 'Benchmark fallback page.\n' }, + ]; + for (let section = 0; section < 10; section++) { + const nesting = Array.from({ length: 7 }, (_, index) => `level-${index + 1}`).join('/'); + for (let page = 0; page < 100; page++) { + docs.push({ + path: `reference/section-${section}/${nesting}/page-${page}.md`, + contents: frontmatter(`Page ${section}-${page}`) + 'Benchmark content.\n', + }); + } + } + return docs; +} + +export async function writeFixtureDocs(name: FixtureName, docs: DocFile[]) { + const root = getFixtureRoot(name); + const docsRoot = join(root, 'src/content/docs'); + await rm(docsRoot, { recursive: true, force: true }); + await Promise.all( + docs.map(async ({ path, contents }) => { + const filePath = join(docsRoot, path); + await mkdir(dirname(filePath), { recursive: true }); + await writeFile(filePath, contents); + }) + ); +} + +export async function resetFixtureBuild(name: FixtureName) { + const root = getFixtureRoot(name); + await Promise.all([ + rm(join(root, '.astro'), { recursive: true, force: true }), + rm(join(root, 'dist'), { recursive: true, force: true }), + ]); +} + +export async function buildFixture(name: FixtureName) { + await build({ logLevel: 'silent', root: getFixtureRoot(name) }); +} + +export function cleanFixture(name: FixtureName) { + const root = getFixtureRoot(name); + for (const path of ['src/content/docs', '.astro', 'dist']) { + rmSync(join(root, path), { recursive: true, force: true }); + } +} diff --git a/packages/starlight/__bench_e2e__/fixtures/components/.gitignore b/packages/starlight/__bench_e2e__/fixtures/components/.gitignore new file mode 100644 index 00000000000..ec2df0cd5f8 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/components/.gitignore @@ -0,0 +1,3 @@ +src/content/docs/ +.astro/ +dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs new file mode 100644 index 00000000000..c89324f1108 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs @@ -0,0 +1,6 @@ +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + integrations: [starlight({ title: 'Component benchmark', pagefind: false })], +}); diff --git a/packages/starlight/__bench_e2e__/fixtures/components/package.json b/packages/starlight/__bench_e2e__/fixtures/components/package.json new file mode 100644 index 00000000000..ec85458c3ad --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/components/package.json @@ -0,0 +1,9 @@ +{ + "name": "@bench/components", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/starlight": "workspace:*", + "astro": "^7.1.6" + } +} diff --git a/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts new file mode 100644 index 00000000000..d9ee8c9d1c9 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore new file mode 100644 index 00000000000..ec2df0cd5f8 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore @@ -0,0 +1,3 @@ +src/content/docs/ +.astro/ +dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs new file mode 100644 index 00000000000..6f86bf0cf36 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs @@ -0,0 +1,12 @@ +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + integrations: [ + starlight({ + title: 'Large sidebar benchmark', + pagefind: false, + sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }], + }), + ], +}); diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json new file mode 100644 index 00000000000..bafdde7e387 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json @@ -0,0 +1,9 @@ +{ + "name": "@bench/large-sidebar", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/starlight": "workspace:*", + "astro": "^7.1.6" + } +} diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts new file mode 100644 index 00000000000..d9ee8c9d1c9 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore b/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore new file mode 100644 index 00000000000..ec2df0cd5f8 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore @@ -0,0 +1,3 @@ +src/content/docs/ +.astro/ +dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs new file mode 100644 index 00000000000..eda7a4a1b16 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs @@ -0,0 +1,16 @@ +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; +import builtinTranslations from '../../../translations/index.ts'; + +export default defineConfig({ + integrations: [ + starlight({ + title: 'All locales benchmark', + pagefind: false, + defaultLocale: 'en', + locales: Object.fromEntries( + Object.keys(builtinTranslations).map((locale) => [locale, { label: locale }]) + ), + }), + ], +}); diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/package.json b/packages/starlight/__bench_e2e__/fixtures/locales/package.json new file mode 100644 index 00000000000..5b280fa8e55 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/locales/package.json @@ -0,0 +1,9 @@ +{ + "name": "@bench/locales", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/starlight": "workspace:*", + "astro": "^7.1.6" + } +} diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts new file mode 100644 index 00000000000..d9ee8c9d1c9 --- /dev/null +++ b/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__bench_e2e__/large-sidebar.bench.ts b/packages/starlight/__bench_e2e__/large-sidebar.bench.ts new file mode 100644 index 00000000000..7ed9528a9fc --- /dev/null +++ b/packages/starlight/__bench_e2e__/large-sidebar.bench.ts @@ -0,0 +1,20 @@ +import { bench, describe } from 'vitest'; +import { + buildBenchOptions, + buildFixture, + cleanFixture, + createLargeSidebarDocs, + resetFixtureBuild, + writeFixtureDocs, +} from './fixtures'; + +describe('large_sidebar', () => { + bench('build', () => buildFixture('large-sidebar'), { + ...buildBenchOptions, + setup: async () => { + await writeFixtureDocs('large-sidebar', createLargeSidebarDocs()); + await resetFixtureBuild('large-sidebar'); + }, + teardown: () => cleanFixture('large-sidebar'), + }); +}); diff --git a/packages/starlight/__bench_e2e__/locales.bench.ts b/packages/starlight/__bench_e2e__/locales.bench.ts new file mode 100644 index 00000000000..77d932c204c --- /dev/null +++ b/packages/starlight/__bench_e2e__/locales.bench.ts @@ -0,0 +1,23 @@ +import { bench, describe } from 'vitest'; +import builtinTranslations from '../translations'; +import { + buildBenchOptions, + buildFixture, + cleanFixture, + createComponentDocs, + resetFixtureBuild, + writeFixtureDocs, +} from './fixtures'; + +const locales = Object.keys(builtinTranslations); + +describe('locales', () => { + bench('build', () => buildFixture('locales'), { + ...buildBenchOptions, + setup: async () => { + await writeFixtureDocs('locales', createComponentDocs(locales)); + await resetFixtureBuild('locales'); + }, + teardown: () => cleanFixture('locales'), + }); +}); diff --git a/packages/starlight/__bench_fn__/generate-route-data.bench.ts b/packages/starlight/__bench_fn__/generate-route-data.bench.ts new file mode 100644 index 00000000000..535895548c7 --- /dev/null +++ b/packages/starlight/__bench_fn__/generate-route-data.bench.ts @@ -0,0 +1,50 @@ +import { bench, describe, vi } from 'vitest'; +import { getRouteDataTestContext } from '../__tests__/test-utils'; +import { generateRouteData } from '../utils/routing/data'; +import { getRouteBySlugParam } from '../utils/routing'; +import { getSidebar } from '../utils/navigation'; + +const docs = vi.hoisted(() => { + const docs: [string, { title: string }][] = []; + for (let section = 0; section < 10; section++) { + const nesting = Array.from({ length: 7 }, (_, index) => `level-${index + 1}`).join('/'); + for (let page = 0; page < 100; page++) { + docs.push([ + `reference/section-${section}/${nesting}/page-${page}.md`, + { title: `Page ${section}-${page}` }, + ]); + } + } + return docs; +}); + +vi.mock('astro:content', async () => + (await import('../__tests__/test-utils')).mockedAstroContent({ docs }) +); + +const slug = 'reference/section-9/level-1/level-2/level-3/level-4/level-5/level-6/level-7/page-99'; +const route = getRouteBySlugParam(slug); +if (!route) throw new Error('Expected deep benchmark route to exist.'); + +const context = getRouteDataTestContext({ pathname: `/${slug}/` }); +const props = { + ...route, + headings: Array.from({ length: 30 }, (_, index) => ({ + depth: 2, + slug: `heading-${index}`, + text: `Heading ${index}`, + })), +}; + +// Build intermediate sidebar data once so this models subsequent page generation during a build. +getSidebar(context.url.pathname, route.locale); + +describe('routing', () => { + bench('route_data', () => { + generateRouteData({ props, context }); + }); + + bench('sidebar', () => { + getSidebar(context.url.pathname, route.locale); + }); +}); diff --git a/packages/starlight/__tests__/test-config.ts b/packages/starlight/__tests__/test-config.ts index 1366d000222..3d6aec1b003 100644 --- a/packages/starlight/__tests__/test-config.ts +++ b/packages/starlight/__tests__/test-config.ts @@ -13,6 +13,7 @@ export async function defineVitestConfig( build?: Pick; trailingSlash?: AstroConfig['trailingSlash']; command?: 'dev' | 'build' | 'preview'; + snapshotSerializers?: boolean; } ) { const root = new URL('./', import.meta.url); @@ -43,7 +44,9 @@ export async function defineVitestConfig( ), ], test: { - snapshotSerializers: ['../snapshot-serializer-astro-error.ts'], + ...(opts?.snapshotSerializers === false + ? {} + : { snapshotSerializers: ['../snapshot-serializer-astro-error.ts'] }), }, }); } diff --git a/packages/starlight/package.json b/packages/starlight/package.json index a1effb5b559..08b00b38b8d 100644 --- a/packages/starlight/package.json +++ b/packages/starlight/package.json @@ -5,6 +5,9 @@ "scripts": { "test": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest", "test:coverage": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest run --coverage", + "bench": "pnpm bench:functional && pnpm bench:e2e", + "bench:e2e": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest bench --run --config vitest.e2e.bench.config.ts __bench_e2e__/*.bench.ts", + "bench:functional": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest bench --run --config vitest.functional.bench.config.ts __bench_fn__/*.bench.ts", "test:e2e": "playwright install --with-deps chromium && playwright test", "test:e2e:ci": "playwright test" }, @@ -59,6 +62,7 @@ "devDependencies": { "@astrojs/markdown-remark": "^7.2.2", "@playwright/test": "^1.61.1", + "@codspeed/vitest-plugin": "^5.7.1", "@types/node": "^22.19.17", "@vitest/coverage-v8": "^4.1.5", "astro": "^7.1.6", diff --git a/packages/starlight/vitest.e2e.bench.config.ts b/packages/starlight/vitest.e2e.bench.config.ts new file mode 100644 index 00000000000..7948776e8ca --- /dev/null +++ b/packages/starlight/vitest.e2e.bench.config.ts @@ -0,0 +1,13 @@ +import codspeedPlugin from '@codspeed/vitest-plugin'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [codspeedPlugin()], + benchmark: { + include: ['__bench_e2e__/*.bench.ts'], + }, + test: { + fileParallelism: false, + hookTimeout: 600_000, + }, +}); diff --git a/packages/starlight/vitest.functional.bench.config.ts b/packages/starlight/vitest.functional.bench.config.ts new file mode 100644 index 00000000000..42a6ebdb8f3 --- /dev/null +++ b/packages/starlight/vitest.functional.bench.config.ts @@ -0,0 +1,26 @@ +import codspeedPlugin from '@codspeed/vitest-plugin'; +import { defineVitestConfig } from './__tests__/test-config'; + +const testConfig = await defineVitestConfig( + { + title: 'Starlight benchmarks', + sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }], + }, + { snapshotSerializers: false } +); + +export default async (env: Parameters[0]) => { + const config = await testConfig(env); + return { + ...config, + plugins: [...(config.plugins ?? []), codspeedPlugin()], + benchmark: { + include: ['__bench_fn__/*.bench.ts'], + }, + test: { + ...config.test, + fileParallelism: false, + hookTimeout: 600_000, + }, + }; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e1f682eae7..bb004e1265c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -270,6 +270,9 @@ importers: '@astrojs/markdown-remark': specifier: ^7.2.2 version: 7.2.2(supports-color@10.2.2) + '@codspeed/vitest-plugin': + specifier: ^5.7.1 + version: 5.7.1(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2)(tinybench@2.9.0)(vitest@4.1.5) '@playwright/test': specifier: ^1.61.1 version: 1.61.1 @@ -289,6 +292,33 @@ importers: specifier: ^4.1.5 version: 4.1.5(@types/node@22.19.17)(@vitest/coverage-v8@4.1.5)(esbuild@0.28.0)(jiti@2.6.1)(yaml@2.9.0) + packages/starlight/__bench_e2e__/fixtures/components: + dependencies: + '@astrojs/starlight': + specifier: workspace:* + version: link:../../.. + astro: + specifier: ^7.1.6 + version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) + + packages/starlight/__bench_e2e__/fixtures/large-sidebar: + dependencies: + '@astrojs/starlight': + specifier: workspace:* + version: link:../../.. + astro: + specifier: ^7.1.6 + version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) + + packages/starlight/__bench_e2e__/fixtures/locales: + dependencies: + '@astrojs/starlight': + specifier: workspace:* + version: link:../../.. + astro: + specifier: ^7.1.6 + version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) + packages/starlight/__e2e__/fixtures/basics: dependencies: '@astrojs/starlight': @@ -704,22 +734,24 @@ packages: '@clack/core@0.3.4': resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} - '@clack/core@1.3.1': - resolution: {integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==} - engines: {node: '>= 20.12.0'} - '@clack/core@1.4.3': resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} engines: {node: '>= 20.12.0'} - '@clack/prompts@1.4.0': - resolution: {integrity: sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==} - engines: {node: '>= 20.12.0'} - '@clack/prompts@1.7.0': resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} engines: {node: '>= 20.12.0'} + '@codspeed/core@5.7.1': + resolution: {integrity: sha512-7mrFkqaY14rXu3XHv3o7bK3btLK0LFRxfeK3bQC8dLduI/Ty9eq8Hv8rx04FAY/onQbRTx3rUUQg5xprYHpATQ==} + + '@codspeed/vitest-plugin@5.7.1': + resolution: {integrity: sha512-yKNqaYVxZZPJYkhVHpz30Oem4TUgcI+/IRDD9YHvcAgi0P42CL6TB/+qYjuFOWghFzTPrm3TUbNFoBsevSTbUA==} + peerDependencies: + tinybench: '>=2.9.0' + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vitest: ^3.2 || ^4 + '@ctrl/tinycolor@4.1.0': resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} engines: {node: '>=14'} @@ -1790,6 +1822,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + ajv-draft-04@1.0.0: resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} peerDependencies: @@ -1866,6 +1902,9 @@ packages: '@astrojs/markdown-remark': optional: true + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + axe-core@4.10.1: resolution: {integrity: sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==} engines: {node: '>=4'} @@ -1881,6 +1920,9 @@ packages: peerDependencies: playwright: '>1.0.0' + axios@1.19.0: + resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -1925,6 +1967,10 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1967,6 +2013,10 @@ packages: collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -2058,6 +2108,10 @@ packages: defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -2120,6 +2174,10 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -2153,9 +2211,25 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@2.0.0: resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -2327,6 +2401,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -2338,6 +2416,15 @@ packages: resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} engines: {node: '>=8'} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + fontace@0.4.1: resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} @@ -2349,6 +2436,10 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} @@ -2363,6 +2454,9 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2371,10 +2465,18 @@ packages: resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-port@7.1.0: resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} engines: {node: '>=16'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -2398,6 +2500,10 @@ packages: resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} engines: {node: '>=18'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + got@13.0.0: resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} engines: {node: '>=16'} @@ -2416,6 +2522,18 @@ packages: resolution: {integrity: sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==} engines: {node: '>=12'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-embedded@3.0.0: resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} @@ -2509,6 +2627,10 @@ packages: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + human-id@4.2.0: resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==} hasBin: true @@ -2823,6 +2945,10 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2861,6 +2987,10 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} @@ -3037,10 +3167,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} @@ -3092,6 +3230,10 @@ packages: node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -3142,6 +3284,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@6.2.0: resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} engines: {node: '>=18'} @@ -3154,6 +3300,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-queue@9.3.0: resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==} engines: {node: '>=20'} @@ -3162,9 +3312,6 @@ packages: resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} - package-manager-detector@1.6.0: - resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} - package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} @@ -3188,6 +3335,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-expression-matcher@1.5.0: resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} engines: {node: '>=14.0.0'} @@ -3279,6 +3430,10 @@ packages: property-information@7.0.0: resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3516,6 +3671,10 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + stack-trace@1.0.0-pre2: + resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} + engines: {node: '>=16'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -3604,10 +3763,6 @@ packages: resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==} engines: {node: ^16.14.0 || >= 17.3.0} - tinyexec@1.1.1: - resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} - engines: {node: '>=18'} - tinyexec@1.3.0: resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} engines: {node: '>=18'} @@ -4036,11 +4191,6 @@ packages: engines: {node: '>= 14'} hasBin: true - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} - engines: {node: '>= 14.6'} - hasBin: true - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -4374,7 +4524,7 @@ snapshots: '@astrojs/yaml2ts@0.2.3': dependencies: - yaml: 2.8.3 + yaml: 2.9.0 '@babel/helper-string-parser@7.27.1': {} @@ -4544,23 +4694,11 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/core@1.3.1': - dependencies: - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - '@clack/core@1.4.3': dependencies: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@clack/prompts@1.4.0': - dependencies: - '@clack/core': 1.3.1 - fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - '@clack/prompts@1.7.0': dependencies: '@clack/core': 1.4.3 @@ -4568,6 +4706,26 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 + '@codspeed/core@5.7.1(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + axios: 1.19.0(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2) + find-up: 6.3.0 + form-data: 4.0.6 + node-gyp-build: 4.8.4 + stack-trace: 1.0.0-pre2 + transitivePeerDependencies: + - debug + - supports-color + + '@codspeed/vitest-plugin@5.7.1(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2)(tinybench@2.9.0)(vitest@4.1.5)': + dependencies: + '@codspeed/core': 5.7.1(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2) + tinybench: 2.9.0 + vitest: 4.1.5(@types/node@22.19.17)(@vitest/coverage-v8@4.1.5)(esbuild@0.28.0)(jiti@2.6.1)(yaml@2.9.0) + transitivePeerDependencies: + - debug + - supports-color + '@ctrl/tinycolor@4.1.0': {} '@docsearch/css@3.6.0': {} @@ -5536,6 +5694,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + ajv-draft-04@1.0.0(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -5619,7 +5783,7 @@ snapshots: '@astrojs/markdown-satteri': 0.3.5 '@astrojs/telemetry': 3.3.3 '@capsizecss/unpack': 4.0.0 - '@clack/prompts': 1.4.0 + '@clack/prompts': 1.7.0 '@oslojs/encoding': 1.1.0 '@rollup/pluginutils': 5.3.0 am-i-vibing: 0.4.0 @@ -5649,7 +5813,7 @@ snapshots: obug: 2.1.1 p-limit: 7.3.0 p-queue: 9.3.0 - package-manager-detector: 1.6.0 + package-manager-detector: 1.8.0 piccolore: 0.1.3 picomatch: 4.0.5 semver: 7.8.5 @@ -5657,7 +5821,7 @@ snapshots: smol-toml: 1.6.1 svgo: 4.0.1 tinyclip: 0.1.12 - tinyexec: 1.1.1 + tinyexec: 1.3.0 tinyglobby: 0.2.17 ultrahtml: 1.6.0 unifont: 0.7.4 @@ -5712,7 +5876,7 @@ snapshots: '@astrojs/markdown-satteri': 0.3.5 '@astrojs/telemetry': 3.3.3 '@capsizecss/unpack': 4.0.0 - '@clack/prompts': 1.4.0 + '@clack/prompts': 1.7.0 '@oslojs/encoding': 1.1.0 '@rollup/pluginutils': 5.3.0 am-i-vibing: 0.4.0 @@ -5742,7 +5906,7 @@ snapshots: obug: 2.1.1 p-limit: 7.3.0 p-queue: 9.3.0 - package-manager-detector: 1.6.0 + package-manager-detector: 1.8.0 piccolore: 0.1.3 picomatch: 4.0.5 semver: 7.8.5 @@ -5750,7 +5914,7 @@ snapshots: smol-toml: 1.6.1 svgo: 4.0.1 tinyclip: 0.1.12 - tinyexec: 1.1.1 + tinyexec: 1.3.0 tinyglobby: 0.2.17 ultrahtml: 1.6.0 unifont: 0.7.4 @@ -5798,6 +5962,8 @@ snapshots: - uploadthing - yaml + asynckit@0.4.0: {} + axe-core@4.10.1: {} axe-html-reporter@2.2.11(axe-core@4.10.1): @@ -5814,6 +5980,16 @@ snapshots: picocolors: 1.1.1 playwright: 1.61.1 + axios@1.19.0(debug@4.4.3(supports-color@10.2.2))(supports-color@10.2.2): + dependencies: + follow-redirects: 1.16.0(debug@4.4.3(supports-color@10.2.2)) + form-data: 4.0.6 + https-proxy-agent: 5.0.1(supports-color@10.2.2) + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + axobject-query@4.1.0: {} bail@2.0.2: {} @@ -5854,6 +6030,11 @@ snapshots: normalize-url: 8.1.1 responselike: 3.0.0 + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + ccount@2.0.1: {} chai@6.2.2: {} @@ -5886,6 +6067,10 @@ snapshots: collapse-white-space@2.1.0: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} commander@11.1.0: {} @@ -5962,6 +6147,8 @@ snapshots: defu@6.1.7: {} + delayed-stream@1.0.0: {} + depd@2.0.0: {} dequal@2.0.3: {} @@ -6018,6 +6205,12 @@ snapshots: dset@3.1.4: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + ee-first@1.1.1: {} emmet@2.4.7: @@ -6042,8 +6235,23 @@ snapshots: environment@1.1.0: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@2.0.0: {} + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -6273,6 +6481,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat-cache@4.0.1: dependencies: flatted: 3.3.3 @@ -6282,6 +6495,10 @@ snapshots: flattie@1.1.1: {} + follow-redirects@1.16.0(debug@4.4.3(supports-color@10.2.2)): + optionalDependencies: + debug: 4.4.3(supports-color@10.2.2) + fontace@0.4.1: dependencies: fontkitten: 1.0.3 @@ -6292,6 +6509,14 @@ snapshots: form-data-encoder@2.1.4: {} + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + fresh@2.0.0: {} fsevents@2.3.2: @@ -6300,12 +6525,32 @@ snapshots: fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + get-port@7.1.0: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + get-stream@6.0.1: {} get-tsconfig@5.0.0-beta.4: @@ -6324,6 +6569,8 @@ snapshots: globals@17.6.0: {} + gopd@1.2.0: {} + got@13.0.0: dependencies: '@sindresorhus/is': 5.6.0 @@ -6356,6 +6603,16 @@ snapshots: has-flag@5.0.1: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-embedded@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -6590,6 +6847,13 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + https-proxy-agent@5.0.1(supports-color@10.2.2): + dependencies: + agent-base: 6.0.2(supports-color@10.2.2) + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + human-id@4.2.0: {} i18next@26.0.7(typescript@6.0.3): @@ -6812,6 +7076,10 @@ snapshots: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lodash@4.17.21: {} longest-streak@3.1.0: {} @@ -6846,6 +7114,8 @@ snapshots: markdown-table@3.0.4: {} + math-intrinsics@1.1.0: {} + mdast-util-definitions@6.0.0: dependencies: '@types/mdast': 4.0.4 @@ -7314,8 +7584,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -7352,6 +7628,8 @@ snapshots: node-fetch-native@1.6.7: {} + node-gyp-build@4.8.4: {} + node-mock-http@1.0.4: {} normalize-path@3.0.0: {} @@ -7404,6 +7682,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-limit@6.2.0: dependencies: yocto-queue: 1.2.2 @@ -7416,6 +7698,10 @@ snapshots: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-queue@9.3.0: dependencies: eventemitter3: 5.0.4 @@ -7423,8 +7709,6 @@ snapshots: p-timeout@7.0.1: {} - package-manager-detector@1.6.0: {} - package-manager-detector@1.8.0: {} pagefind@1.5.2: @@ -7465,6 +7749,8 @@ snapshots: path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-expression-matcher@1.5.0: {} path-key@3.1.1: {} @@ -7529,6 +7815,8 @@ snapshots: property-information@7.0.0: {} + proxy-from-env@2.1.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -7925,6 +8213,8 @@ snapshots: space-separated-tokens@2.0.2: {} + stack-trace@1.0.0-pre2: {} + stackback@0.0.2: {} starlight-links-validator@0.25.2(@astrojs/starlight@packages+starlight)(astro@7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0))(supports-color@10.2.2): @@ -7942,7 +8232,7 @@ snapshots: satteri: 0.9.3 terminal-link: 5.0.0 unist-util-visit: 5.1.0 - yaml: 2.8.3 + yaml: 2.9.0 transitivePeerDependencies: - supports-color @@ -8024,8 +8314,6 @@ snapshots: tinyclip@0.1.12: {} - tinyexec@1.1.1: {} - tinyexec@1.3.0: {} tinyglobby@0.2.17: @@ -8238,7 +8526,7 @@ snapshots: picomatch: 4.0.5 std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.1.1 + tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 vite: 8.2.0(@types/node@22.19.17)(esbuild@0.28.0)(jiti@2.6.1)(yaml@2.9.0) @@ -8277,7 +8565,7 @@ snapshots: picomatch: 4.0.5 std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.1.1 + tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 vite: 8.2.0(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.6.1)(yaml@2.9.0) @@ -8441,8 +8729,6 @@ snapshots: yaml@2.7.1: {} - yaml@2.8.3: {} - yaml@2.9.0: {} yargs-parser@22.0.0: {} From 5a3f265d186254c5af591c9a1f9a1cf788e055b1 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Tue, 1 Sep 2026 10:48:20 +0100 Subject: [PATCH 2/4] Apply batched suggestions from code review Co-authored-by: Chris Swithinbank --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 65293546ddd..331c45332fc 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -42,7 +42,7 @@ jobs: cache: pnpm - run: pnpm i --filter @astrojs/starlight --filter @bench/components --filter @bench/large-sidebar --filter @bench/locales - name: Run benchmarks - uses: CodSpeedHQ/action@562878fc153dee6c0f3719c99b1799334cfc3ccc # v5 + uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 with: mode: simulation run: pnpm --filter @astrojs/starlight bench From 630c547741a2c0305d1fd094f69d8e888b0f61e9 Mon Sep 17 00:00:00 2001 From: ematipico Date: Tue, 1 Sep 2026 10:52:38 +0100 Subject: [PATCH 3/4] feedback --- packages/starlight/.npmignore | 2 ++ packages/starlight/__tests__/test-config.ts | 5 +---- packages/starlight/vitest.e2e.bench.config.ts | 7 +++---- .../vitest.functional.bench.config.ts | 20 +++++++++---------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/starlight/.npmignore b/packages/starlight/.npmignore index 54ad20802ea..9ee9cf516bb 100644 --- a/packages/starlight/.npmignore +++ b/packages/starlight/.npmignore @@ -2,6 +2,8 @@ __coverage__/ __tests__/ __e2e__/ +__bench_e2e__/ +__bench_fn__/ vitest.* playwright.config.ts # Astro generates this during tests, but we want to ignore it. diff --git a/packages/starlight/__tests__/test-config.ts b/packages/starlight/__tests__/test-config.ts index 3d6aec1b003..1366d000222 100644 --- a/packages/starlight/__tests__/test-config.ts +++ b/packages/starlight/__tests__/test-config.ts @@ -13,7 +13,6 @@ export async function defineVitestConfig( build?: Pick; trailingSlash?: AstroConfig['trailingSlash']; command?: 'dev' | 'build' | 'preview'; - snapshotSerializers?: boolean; } ) { const root = new URL('./', import.meta.url); @@ -44,9 +43,7 @@ export async function defineVitestConfig( ), ], test: { - ...(opts?.snapshotSerializers === false - ? {} - : { snapshotSerializers: ['../snapshot-serializer-astro-error.ts'] }), + snapshotSerializers: ['../snapshot-serializer-astro-error.ts'], }, }); } diff --git a/packages/starlight/vitest.e2e.bench.config.ts b/packages/starlight/vitest.e2e.bench.config.ts index 7948776e8ca..f03163b0bd5 100644 --- a/packages/starlight/vitest.e2e.bench.config.ts +++ b/packages/starlight/vitest.e2e.bench.config.ts @@ -3,11 +3,10 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [codspeedPlugin()], - benchmark: { - include: ['__bench_e2e__/*.bench.ts'], - }, test: { + benchmark: { + include: ['__bench_e2e__/*.bench.ts'], + }, fileParallelism: false, - hookTimeout: 600_000, }, }); diff --git a/packages/starlight/vitest.functional.bench.config.ts b/packages/starlight/vitest.functional.bench.config.ts index 42a6ebdb8f3..c2278f6214c 100644 --- a/packages/starlight/vitest.functional.bench.config.ts +++ b/packages/starlight/vitest.functional.bench.config.ts @@ -1,26 +1,24 @@ import codspeedPlugin from '@codspeed/vitest-plugin'; import { defineVitestConfig } from './__tests__/test-config'; -const testConfig = await defineVitestConfig( - { - title: 'Starlight benchmarks', - sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }], - }, - { snapshotSerializers: false } -); +const testConfig = await defineVitestConfig({ + title: 'Starlight benchmarks', + sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }], +}); export default async (env: Parameters[0]) => { const config = await testConfig(env); return { ...config, plugins: [...(config.plugins ?? []), codspeedPlugin()], - benchmark: { - include: ['__bench_fn__/*.bench.ts'], - }, test: { ...config.test, + // The shared serializer path is not resolvable from this root benchmark config. + snapshotSerializers: [], + benchmark: { + include: ['__bench_fn__/*.bench.ts'], + }, fileParallelism: false, - hookTimeout: 600_000, }, }; }; From ff1417c4e615ace7424e2ffdfe7b3127df48887c Mon Sep 17 00:00:00 2001 From: ematipico Date: Tue, 1 Sep 2026 14:58:21 +0100 Subject: [PATCH 4/4] chore: remove e2e benches --- .github/workflows/benchmarks.yml | 2 +- packages/starlight/.npmignore | 1 - .../__bench_e2e__/components.bench.ts | 20 --- packages/starlight/__bench_e2e__/fixtures.ts | 143 ------------------ .../fixtures/components/.gitignore | 3 - .../fixtures/components/astro.config.mjs | 6 - .../fixtures/components/package.json | 9 -- .../fixtures/components/src/content.config.ts | 7 - .../fixtures/large-sidebar/.gitignore | 3 - .../fixtures/large-sidebar/astro.config.mjs | 12 -- .../fixtures/large-sidebar/package.json | 9 -- .../large-sidebar/src/content.config.ts | 7 - .../__bench_e2e__/fixtures/locales/.gitignore | 3 - .../fixtures/locales/astro.config.mjs | 16 -- .../fixtures/locales/package.json | 9 -- .../fixtures/locales/src/content.config.ts | 7 - .../__bench_e2e__/large-sidebar.bench.ts | 20 --- .../starlight/__bench_e2e__/locales.bench.ts | 23 --- packages/starlight/package.json | 3 +- packages/starlight/vitest.e2e.bench.config.ts | 12 -- pnpm-lock.yaml | 27 ---- 21 files changed, 2 insertions(+), 340 deletions(-) delete mode 100644 packages/starlight/__bench_e2e__/components.bench.ts delete mode 100644 packages/starlight/__bench_e2e__/fixtures.ts delete mode 100644 packages/starlight/__bench_e2e__/fixtures/components/.gitignore delete mode 100644 packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs delete mode 100644 packages/starlight/__bench_e2e__/fixtures/components/package.json delete mode 100644 packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts delete mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore delete mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs delete mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json delete mode 100644 packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts delete mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/.gitignore delete mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs delete mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/package.json delete mode 100644 packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts delete mode 100644 packages/starlight/__bench_e2e__/large-sidebar.bench.ts delete mode 100644 packages/starlight/__bench_e2e__/locales.bench.ts delete mode 100644 packages/starlight/vitest.e2e.bench.config.ts diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 331c45332fc..abc050147be 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -40,7 +40,7 @@ jobs: with: node-version: 22.23.1 cache: pnpm - - run: pnpm i --filter @astrojs/starlight --filter @bench/components --filter @bench/large-sidebar --filter @bench/locales + - run: pnpm i --filter @astrojs/starlight - name: Run benchmarks uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 with: diff --git a/packages/starlight/.npmignore b/packages/starlight/.npmignore index 9ee9cf516bb..097f8c7514e 100644 --- a/packages/starlight/.npmignore +++ b/packages/starlight/.npmignore @@ -2,7 +2,6 @@ __coverage__/ __tests__/ __e2e__/ -__bench_e2e__/ __bench_fn__/ vitest.* playwright.config.ts diff --git a/packages/starlight/__bench_e2e__/components.bench.ts b/packages/starlight/__bench_e2e__/components.bench.ts deleted file mode 100644 index 4d7e6dddeb7..00000000000 --- a/packages/starlight/__bench_e2e__/components.bench.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { bench, describe } from 'vitest'; -import { - buildBenchOptions, - buildFixture, - cleanFixture, - createComponentDocs, - resetFixtureBuild, - writeFixtureDocs, -} from './fixtures'; - -describe('components', () => { - bench('build', () => buildFixture('components'), { - ...buildBenchOptions, - setup: async () => { - await writeFixtureDocs('components', createComponentDocs()); - await resetFixtureBuild('components'); - }, - teardown: () => cleanFixture('components'), - }); -}); diff --git a/packages/starlight/__bench_e2e__/fixtures.ts b/packages/starlight/__bench_e2e__/fixtures.ts deleted file mode 100644 index 241e8f73cff..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { rmSync } from 'node:fs'; -import { mkdir, rm, writeFile } from 'node:fs/promises'; -import { fileURLToPath } from 'node:url'; -import { dirname, join } from 'node:path'; -import { build } from 'astro'; - -process.env.ASTRO_TELEMETRY_DISABLED = 'true'; -process.env.ASTRO_DISABLE_UPDATE_CHECK = 'true'; - -const componentNames = [ - 'aside', - 'badge', - 'card', - 'card-grid', - 'code', - 'file-tree', - 'icon', - 'link-button', - 'link-card', - 'steps', - 'tab-item', - 'tabs', -] as const; - -type FixtureName = 'large-sidebar' | 'components' | 'locales'; - -interface DocFile { - path: string; - contents: string; -} - -export const buildBenchOptions = { - iterations: 1, - time: 0, - warmupIterations: 0, - warmupTime: 0, -}; - -function getFixtureRoot(name: FixtureName) { - return fileURLToPath(new URL(`./fixtures/${name}/`, import.meta.url)); -} - -function frontmatter(title: string) { - return `---\ntitle: ${title}\n---\n\n`; -} - -function componentContents(component: (typeof componentNames)[number]) { - const imports = `import { ${ - component === 'code' - ? 'Code' - : component - .split('-') - .map((part) => part[0]?.toUpperCase() + part.slice(1)) - .join('') - } } from '@astrojs/starlight/components';\n\n`; - - switch (component) { - case 'aside': - return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; - case 'badge': - return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; - case 'card': - return `${imports}{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; - case 'card-grid': - return `${imports}import { Card } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; - case 'code': - return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; - case 'file-tree': - return `${imports}{Array.from({ length: 100 }, (_, index) =>
  • {\`file-\${index}.ts\`}
)}`; - case 'icon': - return `${imports}{Array.from({ length: 100 }, () => )}`; - case 'link-button': - return `${imports}{Array.from({ length: 100 }, (_, index) => Destination)}`; - case 'link-card': - return `${imports}{Array.from({ length: 100 }, (_, index) => )}`; - case 'steps': - return `${imports}{Array.from({ length: 100 }, (_, index) =>
  1. {\`Step \${index}\`}
)}`; - case 'tab-item': - return `${imports}import { Tabs } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; - case 'tabs': - return `${imports}import { TabItem } from '@astrojs/starlight/components';\n\n{Array.from({ length: 100 }, (_, index) => Benchmark content)}`; - } -} - -export function createComponentDocs(locales: string[] = ['']): DocFile[] { - return [ - { path: '404.md', contents: frontmatter('Not found') + 'Benchmark fallback page.\n' }, - ...locales.flatMap((locale) => - componentNames.map((component) => ({ - path: `${locale ? locale + '/' : ''}components/${component}.mdx`, - contents: frontmatter(component) + componentContents(component), - })) - ), - ]; -} - -export function createLargeSidebarDocs(): DocFile[] { - const docs: DocFile[] = [ - { path: '404.md', contents: frontmatter('Not found') + 'Benchmark fallback page.\n' }, - ]; - for (let section = 0; section < 10; section++) { - const nesting = Array.from({ length: 7 }, (_, index) => `level-${index + 1}`).join('/'); - for (let page = 0; page < 100; page++) { - docs.push({ - path: `reference/section-${section}/${nesting}/page-${page}.md`, - contents: frontmatter(`Page ${section}-${page}`) + 'Benchmark content.\n', - }); - } - } - return docs; -} - -export async function writeFixtureDocs(name: FixtureName, docs: DocFile[]) { - const root = getFixtureRoot(name); - const docsRoot = join(root, 'src/content/docs'); - await rm(docsRoot, { recursive: true, force: true }); - await Promise.all( - docs.map(async ({ path, contents }) => { - const filePath = join(docsRoot, path); - await mkdir(dirname(filePath), { recursive: true }); - await writeFile(filePath, contents); - }) - ); -} - -export async function resetFixtureBuild(name: FixtureName) { - const root = getFixtureRoot(name); - await Promise.all([ - rm(join(root, '.astro'), { recursive: true, force: true }), - rm(join(root, 'dist'), { recursive: true, force: true }), - ]); -} - -export async function buildFixture(name: FixtureName) { - await build({ logLevel: 'silent', root: getFixtureRoot(name) }); -} - -export function cleanFixture(name: FixtureName) { - const root = getFixtureRoot(name); - for (const path of ['src/content/docs', '.astro', 'dist']) { - rmSync(join(root, path), { recursive: true, force: true }); - } -} diff --git a/packages/starlight/__bench_e2e__/fixtures/components/.gitignore b/packages/starlight/__bench_e2e__/fixtures/components/.gitignore deleted file mode 100644 index ec2df0cd5f8..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/components/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -src/content/docs/ -.astro/ -dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs deleted file mode 100644 index c89324f1108..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/components/astro.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -import starlight from '@astrojs/starlight'; -import { defineConfig } from 'astro/config'; - -export default defineConfig({ - integrations: [starlight({ title: 'Component benchmark', pagefind: false })], -}); diff --git a/packages/starlight/__bench_e2e__/fixtures/components/package.json b/packages/starlight/__bench_e2e__/fixtures/components/package.json deleted file mode 100644 index ec85458c3ad..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/components/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@bench/components", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/starlight": "workspace:*", - "astro": "^7.1.6" - } -} diff --git a/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts deleted file mode 100644 index d9ee8c9d1c9..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/components/src/content.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), -}; diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore deleted file mode 100644 index ec2df0cd5f8..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -src/content/docs/ -.astro/ -dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs deleted file mode 100644 index 6f86bf0cf36..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/astro.config.mjs +++ /dev/null @@ -1,12 +0,0 @@ -import starlight from '@astrojs/starlight'; -import { defineConfig } from 'astro/config'; - -export default defineConfig({ - integrations: [ - starlight({ - title: 'Large sidebar benchmark', - pagefind: false, - sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }], - }), - ], -}); diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json deleted file mode 100644 index bafdde7e387..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@bench/large-sidebar", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/starlight": "workspace:*", - "astro": "^7.1.6" - } -} diff --git a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts deleted file mode 100644 index d9ee8c9d1c9..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/large-sidebar/src/content.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), -}; diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore b/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore deleted file mode 100644 index ec2df0cd5f8..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/locales/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -src/content/docs/ -.astro/ -dist/ diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs b/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs deleted file mode 100644 index eda7a4a1b16..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/locales/astro.config.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import starlight from '@astrojs/starlight'; -import { defineConfig } from 'astro/config'; -import builtinTranslations from '../../../translations/index.ts'; - -export default defineConfig({ - integrations: [ - starlight({ - title: 'All locales benchmark', - pagefind: false, - defaultLocale: 'en', - locales: Object.fromEntries( - Object.keys(builtinTranslations).map((locale) => [locale, { label: locale }]) - ), - }), - ], -}); diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/package.json b/packages/starlight/__bench_e2e__/fixtures/locales/package.json deleted file mode 100644 index 5b280fa8e55..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/locales/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@bench/locales", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/starlight": "workspace:*", - "astro": "^7.1.6" - } -} diff --git a/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts b/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts deleted file mode 100644 index d9ee8c9d1c9..00000000000 --- a/packages/starlight/__bench_e2e__/fixtures/locales/src/content.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), -}; diff --git a/packages/starlight/__bench_e2e__/large-sidebar.bench.ts b/packages/starlight/__bench_e2e__/large-sidebar.bench.ts deleted file mode 100644 index 7ed9528a9fc..00000000000 --- a/packages/starlight/__bench_e2e__/large-sidebar.bench.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { bench, describe } from 'vitest'; -import { - buildBenchOptions, - buildFixture, - cleanFixture, - createLargeSidebarDocs, - resetFixtureBuild, - writeFixtureDocs, -} from './fixtures'; - -describe('large_sidebar', () => { - bench('build', () => buildFixture('large-sidebar'), { - ...buildBenchOptions, - setup: async () => { - await writeFixtureDocs('large-sidebar', createLargeSidebarDocs()); - await resetFixtureBuild('large-sidebar'); - }, - teardown: () => cleanFixture('large-sidebar'), - }); -}); diff --git a/packages/starlight/__bench_e2e__/locales.bench.ts b/packages/starlight/__bench_e2e__/locales.bench.ts deleted file mode 100644 index 77d932c204c..00000000000 --- a/packages/starlight/__bench_e2e__/locales.bench.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { bench, describe } from 'vitest'; -import builtinTranslations from '../translations'; -import { - buildBenchOptions, - buildFixture, - cleanFixture, - createComponentDocs, - resetFixtureBuild, - writeFixtureDocs, -} from './fixtures'; - -const locales = Object.keys(builtinTranslations); - -describe('locales', () => { - bench('build', () => buildFixture('locales'), { - ...buildBenchOptions, - setup: async () => { - await writeFixtureDocs('locales', createComponentDocs(locales)); - await resetFixtureBuild('locales'); - }, - teardown: () => cleanFixture('locales'), - }); -}); diff --git a/packages/starlight/package.json b/packages/starlight/package.json index 82f4a1a5e8d..dafa65c0827 100644 --- a/packages/starlight/package.json +++ b/packages/starlight/package.json @@ -5,8 +5,7 @@ "scripts": { "test": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest", "test:coverage": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest run --coverage", - "bench": "pnpm bench:functional && pnpm bench:e2e", - "bench:e2e": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest bench --run --config vitest.e2e.bench.config.ts __bench_e2e__/*.bench.ts", + "bench": "pnpm bench:functional", "bench:functional": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest bench --run --config vitest.functional.bench.config.ts __bench_fn__/*.bench.ts", "test:e2e": "playwright install --with-deps chromium && playwright test", "test:e2e:ci": "playwright test" diff --git a/packages/starlight/vitest.e2e.bench.config.ts b/packages/starlight/vitest.e2e.bench.config.ts deleted file mode 100644 index f03163b0bd5..00000000000 --- a/packages/starlight/vitest.e2e.bench.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import codspeedPlugin from '@codspeed/vitest-plugin'; -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - plugins: [codspeedPlugin()], - test: { - benchmark: { - include: ['__bench_e2e__/*.bench.ts'], - }, - fileParallelism: false, - }, -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec2df629707..de2b95124f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -292,33 +292,6 @@ importers: specifier: ^4.1.5 version: 4.1.5(@types/node@22.19.17)(@vitest/coverage-v8@4.1.5)(esbuild@0.28.0)(jiti@2.6.1)(yaml@2.9.0) - packages/starlight/__bench_e2e__/fixtures/components: - dependencies: - '@astrojs/starlight': - specifier: workspace:* - version: link:../../.. - astro: - specifier: ^7.1.6 - version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) - - packages/starlight/__bench_e2e__/fixtures/large-sidebar: - dependencies: - '@astrojs/starlight': - specifier: workspace:* - version: link:../../.. - astro: - specifier: ^7.1.6 - version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) - - packages/starlight/__bench_e2e__/fixtures/locales: - dependencies: - '@astrojs/starlight': - specifier: workspace:* - version: link:../../.. - astro: - specifier: ^7.1.6 - version: 7.1.6(@astrojs/markdown-remark@7.2.2(supports-color@10.2.2))(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@types/node@24.12.4)(jiti@2.6.1)(yaml@2.9.0) - packages/starlight/__e2e__/fixtures/basics: dependencies: '@astrojs/starlight':