diff --git a/.github/frameworks.json b/.github/frameworks.json index bd3c3075..ca33af7f 100644 --- a/.github/frameworks.json +++ b/.github/frameworks.json @@ -38,6 +38,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -81,6 +84,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -111,6 +117,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -154,6 +163,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -197,6 +209,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -240,6 +255,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -283,6 +301,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, @@ -326,6 +347,9 @@ }, { "type": "dependencies" + }, + { + "type": "browserBaseline" } ] }, diff --git a/.github/workflows/generate-stats.yml b/.github/workflows/generate-stats.yml index 462b8301..b929e979 100644 --- a/.github/workflows/generate-stats.yml +++ b/.github/workflows/generate-stats.yml @@ -10,6 +10,7 @@ on: - '!packages/starter-*/install-stats.json' - '!packages/starter-*/build-stats.json' - '!packages/starter-*/corejs-stats.json' + - '!packages/starter-*/browser-baseline-stats.json' - '!packages/starter-*/e18e-stats.json' - 'packages/app-*/**' - '!packages/app-*/ci-stats.json' diff --git a/.github/workflows/measure-framework.yml b/.github/workflows/measure-framework.yml index e6013f2f..3605274c 100644 --- a/.github/workflows/measure-framework.yml +++ b/.github/workflows/measure-framework.yml @@ -107,6 +107,10 @@ jobs: - name: Scan build output for vendored core-js run: pnpm --filter @framework-tracker/stats-generator run:corejs ${{ matrix.framework.package }} + - name: Scan build output for browser baseline requirements + if: contains(toJson(matrix.framework.measurements), 'browserBaseline') + run: pnpm --filter @framework-tracker/stats-generator run:browser-baseline ${{ matrix.framework.package }} + - name: Upload build stats uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: @@ -123,6 +127,15 @@ jobs: retention-days: 1 if-no-files-found: warn + - name: Upload browser baseline stats + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: contains(toJson(matrix.framework.measurements), 'browserBaseline') + with: + name: browser-baseline-stats-${{ matrix.framework.name }} + path: packages/${{ matrix.framework.package }}/browser-baseline-stats.json + retention-days: 1 + if-no-files-found: error + measure-ssr-request-throughput: if: inputs.ssr-request-throughput-matrix != '[]' runs-on: depot-ubuntu-24.04 diff --git a/.github/workflows/preview-stats.yml b/.github/workflows/preview-stats.yml index 2eb14b36..049a39c7 100644 --- a/.github/workflows/preview-stats.yml +++ b/.github/workflows/preview-stats.yml @@ -46,6 +46,7 @@ jobs: echo "install=[]" >> $GITHUB_OUTPUT echo "build=[]" >> $GITHUB_OUTPUT echo "ssr-request-throughput=[]" >> $GITHUB_OUTPUT + echo "deps=[]" >> $GITHUB_OUTPUT exit 0 fi diff --git a/.github/workflows/validate-stats.yml b/.github/workflows/validate-stats.yml index af6812ac..31097f55 100644 --- a/.github/workflows/validate-stats.yml +++ b/.github/workflows/validate-stats.yml @@ -17,6 +17,7 @@ on: - '!packages/starter-*/install-stats.json' - '!packages/starter-*/build-stats.json' - '!packages/starter-*/corejs-stats.json' + - '!packages/starter-*/browser-baseline-stats.json' - '!packages/starter-*/e18e-stats.json' jobs: @@ -91,6 +92,15 @@ jobs: (cd packages/$PKG && npx @e18e/cli@0.5.0 analyze --json > e18e-stats.json || true) done + echo "" + echo "=== Running browser baseline scans ===" + FRAMEWORKS=$(cat .github/frameworks.json) + echo "$FRAMEWORKS" | jq -c '.[] | select(.starter) | select(.starter.measurements | map(.type) | contains(["browserBaseline"]))' | while read -r framework; do + PKG=$(echo "$framework" | jq -r '.starter.package') + echo "Scanning browser baseline requirements for $PKG..." + pnpm --filter @framework-tracker/stats-generator run:browser-baseline $PKG + done + echo "" echo "=== Running client-side rendered benchmarks ===" FRAMEWORKS=$(cat .github/frameworks.json) diff --git a/packages/docs/src/components/BrowserBaselineTable.astro b/packages/docs/src/components/BrowserBaselineTable.astro new file mode 100644 index 00000000..626e47cf --- /dev/null +++ b/packages/docs/src/components/BrowserBaselineTable.astro @@ -0,0 +1,33 @@ +--- +import { browserBaselineTableData } from '../lib/collections' +import { getFrameworkSlug } from '../lib/utils' +import StatsTable from './StatsTable.astro' + +interface Props { + packageName?: string + label?: string +} + +const { packageName, label = 'Browser baseline by framework' } = Astro.props + +const data = + packageName == null + ? browserBaselineTableData + : browserBaselineTableData.filter((row) => row.package === packageName) + +const columns = [ + { + key: 'name', + header: 'Framework', + nameCell: true, + href: (row: Record) => + `/framework/${getFrameworkSlug(row.package as string)}`, + }, + { key: 'status', header: 'Baseline' }, + { key: 'feature', header: 'Feature' }, + { key: 'year', header: 'Year' }, + { key: 'features', header: 'Features' }, +] +--- + + diff --git a/packages/docs/src/content.config.ts b/packages/docs/src/content.config.ts index 2d66a0d7..8799b119 100644 --- a/packages/docs/src/content.config.ts +++ b/packages/docs/src/content.config.ts @@ -37,6 +37,19 @@ const devtimeCollection = defineCollection({ .optional(), vendoredCoreJsSize: z.number().optional(), vendoredCoreJsUnnecessaryModules: z.array(z.string()).optional(), + browserBaselineTests: z + .object({ + baselineStatus: z.union([ + z.literal('high'), + z.literal('low'), + z.literal(false), + z.null(), + ]), + baselineYear: z.number().nullable(), + baselineReason: z.string().nullable(), + baselineFeatureCount: z.number(), + }) + .optional(), timingMeasuredAt: z.string(), runner: z.string(), frameworkVersion: z.string().optional(), diff --git a/packages/docs/src/content/devtime/starter-astro.json b/packages/docs/src/content/devtime/starter-astro.json index e15d9925..f877d26d 100644 --- a/packages/docs/src/content/devtime/starter-astro.json +++ b/packages/docs/src/content/devtime/starter-astro.json @@ -123,5 +123,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": null, + "baselineYear": null, + "baselineReason": null, + "baselineFeatureCount": 0 + } } diff --git a/packages/docs/src/content/devtime/starter-mastro.json b/packages/docs/src/content/devtime/starter-mastro.json index a119b423..da41d68f 100644 --- a/packages/docs/src/content/devtime/starter-mastro.json +++ b/packages/docs/src/content/devtime/starter-mastro.json @@ -31,5 +31,11 @@ "depInstallSize": 28724892, "e18eMessages": [], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": null, + "baselineYear": null, + "baselineReason": null, + "baselineFeatureCount": 0 + } } diff --git a/packages/docs/src/content/devtime/starter-next-js.json b/packages/docs/src/content/devtime/starter-next-js.json index 5ca9ecd5..a8047a38 100644 --- a/packages/docs/src/content/devtime/starter-next-js.json +++ b/packages/docs/src/content/devtime/starter-next-js.json @@ -406,5 +406,11 @@ "web.url-search-params.delete", "web.url-search-params.has", "web.url-search-params.size" - ] + ], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 46 + } } diff --git a/packages/docs/src/content/devtime/starter-nuxt.json b/packages/docs/src/content/devtime/starter-nuxt.json index b62e4f5c..3b407fb9 100644 --- a/packages/docs/src/content/devtime/starter-nuxt.json +++ b/packages/docs/src/content/devtime/starter-nuxt.json @@ -353,5 +353,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": false, + "baselineYear": null, + "baselineReason": "temporal", + "baselineFeatureCount": 40 + } } diff --git a/packages/docs/src/content/devtime/starter-react-router.json b/packages/docs/src/content/devtime/starter-react-router.json index 7aa25d4b..2a00e9f7 100644 --- a/packages/docs/src/content/devtime/starter-react-router.json +++ b/packages/docs/src/content/devtime/starter-react-router.json @@ -83,5 +83,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/docs/src/content/devtime/starter-solid-start.json b/packages/docs/src/content/devtime/starter-solid-start.json index 8758f597..c60c59fd 100644 --- a/packages/docs/src/content/devtime/starter-solid-start.json +++ b/packages/docs/src/content/devtime/starter-solid-start.json @@ -433,5 +433,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 29 + } } diff --git a/packages/docs/src/content/devtime/starter-sveltekit.json b/packages/docs/src/content/devtime/starter-sveltekit.json index 7273a468..74f762bc 100644 --- a/packages/docs/src/content/devtime/starter-sveltekit.json +++ b/packages/docs/src/content/devtime/starter-sveltekit.json @@ -43,5 +43,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/docs/src/content/devtime/starter-tanstack-start-react.json b/packages/docs/src/content/devtime/starter-tanstack-start-react.json index 30f7541f..a8f06fca 100644 --- a/packages/docs/src/content/devtime/starter-tanstack-start-react.json +++ b/packages/docs/src/content/devtime/starter-tanstack-start-react.json @@ -108,5 +108,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 45 + } } diff --git a/packages/docs/src/lib/collections.ts b/packages/docs/src/lib/collections.ts index e6362a5b..bb78dbfa 100644 --- a/packages/docs/src/lib/collections.ts +++ b/packages/docs/src/lib/collections.ts @@ -293,3 +293,45 @@ export const coreJsTableData = starterStats.map((f) => { : '—', } }) + +function formatBaselineStatus( + status: 'high' | 'low' | false | null | undefined, + featureCount: number | undefined, +) { + if (featureCount === 0) return '—' + if (status === 'high') return 'High' + if (status === 'low') return 'Low' + if (status === false) return 'Limited' + return '—' +} + +function formatBaselineReason( + reason: string | string[] | null | undefined, +): string { + if (Array.isArray(reason)) return reason.length > 0 ? reason.join(', ') : '—' + return reason ?? '—' +} + +export const browserBaselineTableData = starterStats.map((f) => { + const baseline = f.browserBaselineTests + return { + name: f.name, + package: f.package, + isFocused: f.isFocused, + status: formatBaselineStatus( + baseline?.baselineStatus, + baseline?.baselineFeatureCount, + ), + feature: formatBaselineReason(baseline?.baselineReason), + year: + baseline?.baselineFeatureCount === 0 + ? '—' + : baseline?.baselineYear != null + ? String(baseline.baselineYear) + : '—', + features: + baseline?.baselineFeatureCount != null + ? baseline.baselineFeatureCount.toLocaleString() + : '—', + } +}) diff --git a/packages/docs/src/pages/dev-time.astro b/packages/docs/src/pages/dev-time.astro index 70c18d6e..b83034ba 100644 --- a/packages/docs/src/pages/dev-time.astro +++ b/packages/docs/src/pages/dev-time.astro @@ -1,5 +1,6 @@ --- import BuildInstallStatsTable from '../components/BuildInstallStatsTable.astro' +import BrowserBaselineTable from '../components/BrowserBaselineTable.astro' import BuildSizeCharts from '../components/BuildSizeCharts.astro' import CoreJsTable from '../components/CoreJsTable.astro' import DependencyCharts from '../components/DependencyCharts.astro' @@ -38,4 +39,7 @@ import Layout from '../layouts/Layout.astro' label="Core-JS Polyfills" /> +

Browser Baseline

+ + diff --git a/packages/docs/src/pages/framework/[slug].astro b/packages/docs/src/pages/framework/[slug].astro index cb676185..2e5c9d15 100644 --- a/packages/docs/src/pages/framework/[slug].astro +++ b/packages/docs/src/pages/framework/[slug].astro @@ -1,6 +1,7 @@ --- import { getCollection } from 'astro:content' import BackLink from '../../components/BackLink.astro' +import BrowserBaselineTable from '../../components/BrowserBaselineTable.astro' import DevTimeChart from '../../components/DevTimeChart.astro' import PageHeader from '../../components/PageHeader.astro' import DetailsLink from '../../components/DetailsLink.astro' @@ -271,6 +272,12 @@ const serverSideRenderedData = runtime?.serverSideRenderedTests href="/methodology#build-and-install-times" label="Build and Install Times" /> +

Browser Baseline

+ + { coreJsModules.length > 0 && ( diff --git a/packages/docs/src/pages/index.astro b/packages/docs/src/pages/index.astro index 6df9a292..772d2aa3 100644 --- a/packages/docs/src/pages/index.astro +++ b/packages/docs/src/pages/index.astro @@ -1,5 +1,6 @@ --- import BuildSizeCharts from '../components/BuildSizeCharts.astro' +import BrowserBaselineTable from '../components/BrowserBaselineTable.astro' import CoreJsTable from '../components/CoreJsTable.astro' import DependencyCharts from '../components/DependencyCharts.astro' import ServerSideRenderedCharts from '../components/ServerSideRenderedCharts.astro' @@ -73,6 +74,9 @@ import DepotLogo from '../assets/depot-logo-horizontal.svg' href="/methodology#core-js-polyfills" label="Core-JS Polyfills" /> +

Browser Baseline

+ +

Runtime Performance

Client Side Rendered Tests

diff --git a/packages/docs/src/pages/methodology.astro b/packages/docs/src/pages/methodology.astro index 161c4bc5..05267a1a 100644 --- a/packages/docs/src/pages/methodology.astro +++ b/packages/docs/src/pages/methodology.astro @@ -123,6 +123,43 @@ import Layout from '../layouts/Layout.astro' +
+

Browser Baseline

+
    +
  • + The scanner uses baseline-detector to statically analyze JavaScript from each starter package's browser-facing + production build output. +
  • +
  • + The scan includes source-like files that baseline-detector supports from + the production build output, including JavaScript, TypeScript, Vue, and + Svelte files. Known server, cache, trace, type, and build-tool output is + excluded. +
  • +
  • + Baseline is baseline-detector's overall target result: high, low, or limited. When the result is not high, baseline-detector also reports the feature ID that determined it. +
  • +
  • + Feature is the feature ID that determined a non-high Baseline result. +
  • +
  • + Year is the Baseline year the project targets: the newest feature it + relies on, or blank if any detected feature is not yet Baseline. +
  • +
  • + Features is the number of unique web platform feature IDs detected in + the browser-facing build output. +
  • +
+
+

Duplicate Dependencies

    diff --git a/packages/starter-astro/ci-stats.json b/packages/starter-astro/ci-stats.json index 9aefb931..c106abbf 100644 --- a/packages/starter-astro/ci-stats.json +++ b/packages/starter-astro/ci-stats.json @@ -117,5 +117,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": null, + "baselineYear": null, + "baselineReason": null, + "baselineFeatureCount": 0 + } } diff --git a/packages/starter-astro/stats/5.16.15.json b/packages/starter-astro/stats/5.16.15.json index 9aefb931..c106abbf 100644 --- a/packages/starter-astro/stats/5.16.15.json +++ b/packages/starter-astro/stats/5.16.15.json @@ -117,5 +117,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": null, + "baselineYear": null, + "baselineReason": null, + "baselineFeatureCount": 0 + } } diff --git a/packages/starter-mastro/ci-stats.json b/packages/starter-mastro/ci-stats.json index 6c0afeeb..54ba968d 100644 --- a/packages/starter-mastro/ci-stats.json +++ b/packages/starter-mastro/ci-stats.json @@ -26,5 +26,11 @@ "depInstallSize": 28724892, "e18eMessages": [], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": null, + "baselineYear": null, + "baselineReason": null, + "baselineFeatureCount": 0 + } } diff --git a/packages/starter-next-js/ci-stats.json b/packages/starter-next-js/ci-stats.json index 908b6377..8c1c95ed 100644 --- a/packages/starter-next-js/ci-stats.json +++ b/packages/starter-next-js/ci-stats.json @@ -400,5 +400,11 @@ "web.url-search-params.delete", "web.url-search-params.has", "web.url-search-params.size" - ] + ], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 46 + } } diff --git a/packages/starter-next-js/stats/16.1.1.json b/packages/starter-next-js/stats/16.1.1.json index 908b6377..8c1c95ed 100644 --- a/packages/starter-next-js/stats/16.1.1.json +++ b/packages/starter-next-js/stats/16.1.1.json @@ -400,5 +400,11 @@ "web.url-search-params.delete", "web.url-search-params.has", "web.url-search-params.size" - ] + ], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 46 + } } diff --git a/packages/starter-nuxt/ci-stats.json b/packages/starter-nuxt/ci-stats.json index 19808c26..863b26d1 100644 --- a/packages/starter-nuxt/ci-stats.json +++ b/packages/starter-nuxt/ci-stats.json @@ -347,5 +347,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": false, + "baselineYear": null, + "baselineReason": "temporal", + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-nuxt/stats/4.2.2.json b/packages/starter-nuxt/stats/4.2.2.json index 19808c26..863b26d1 100644 --- a/packages/starter-nuxt/stats/4.2.2.json +++ b/packages/starter-nuxt/stats/4.2.2.json @@ -347,5 +347,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": false, + "baselineYear": null, + "baselineReason": "temporal", + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-react-router/ci-stats.json b/packages/starter-react-router/ci-stats.json index b1666129..ca0e680d 100644 --- a/packages/starter-react-router/ci-stats.json +++ b/packages/starter-react-router/ci-stats.json @@ -77,5 +77,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-react-router/stats/7.10.1.json b/packages/starter-react-router/stats/7.10.1.json index b1666129..ca0e680d 100644 --- a/packages/starter-react-router/stats/7.10.1.json +++ b/packages/starter-react-router/stats/7.10.1.json @@ -77,5 +77,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-solid-start/ci-stats.json b/packages/starter-solid-start/ci-stats.json index ffe2d733..452e23ec 100644 --- a/packages/starter-solid-start/ci-stats.json +++ b/packages/starter-solid-start/ci-stats.json @@ -427,5 +427,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 29 + } } diff --git a/packages/starter-solid-start/stats/1.2.1.json b/packages/starter-solid-start/stats/1.2.1.json index ffe2d733..452e23ec 100644 --- a/packages/starter-solid-start/stats/1.2.1.json +++ b/packages/starter-solid-start/stats/1.2.1.json @@ -427,5 +427,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 29 + } } diff --git a/packages/starter-sveltekit/ci-stats.json b/packages/starter-sveltekit/ci-stats.json index 2aa0b5aa..ffea5c3c 100644 --- a/packages/starter-sveltekit/ci-stats.json +++ b/packages/starter-sveltekit/ci-stats.json @@ -37,5 +37,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-sveltekit/stats/2.49.4.json b/packages/starter-sveltekit/stats/2.49.4.json index 2aa0b5aa..ffea5c3c 100644 --- a/packages/starter-sveltekit/stats/2.49.4.json +++ b/packages/starter-sveltekit/stats/2.49.4.json @@ -37,5 +37,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2020, + "baselineReason": null, + "baselineFeatureCount": 40 + } } diff --git a/packages/starter-tanstack-start-react/ci-stats.json b/packages/starter-tanstack-start-react/ci-stats.json index c4a87160..095259bd 100644 --- a/packages/starter-tanstack-start-react/ci-stats.json +++ b/packages/starter-tanstack-start-react/ci-stats.json @@ -102,5 +102,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 45 + } } diff --git a/packages/starter-tanstack-start-react/stats/1.145.3.json b/packages/starter-tanstack-start-react/stats/1.145.3.json index c4a87160..095259bd 100644 --- a/packages/starter-tanstack-start-react/stats/1.145.3.json +++ b/packages/starter-tanstack-start-react/stats/1.145.3.json @@ -102,5 +102,11 @@ } ], "vendoredCoreJsSize": 0, - "vendoredCoreJsUnnecessaryModules": [] + "vendoredCoreJsUnnecessaryModules": [], + "browserBaselineTests": { + "baselineStatus": "high", + "baselineYear": 2022, + "baselineReason": null, + "baselineFeatureCount": 45 + } } diff --git a/packages/stats-generator/package.json b/packages/stats-generator/package.json index accb3cb2..803a360f 100644 --- a/packages/stats-generator/package.json +++ b/packages/stats-generator/package.json @@ -12,6 +12,7 @@ "run:install": "node src/run-install-benchmark.ts", "run:build": "node src/run-build-benchmark.ts", "run:corejs": "node src/run-corejs-scan.ts", + "run:browser-baseline": "node src/run-browser-baseline-scan.ts", "save:ci-stats": "node src/save-ci-stats.ts", "generate:preview-comment": "node src/generate-preview-comment.ts", "validate": "node src/validate-stats.ts", @@ -22,6 +23,7 @@ }, "dependencies": { "autocannon": "^8.0.0", + "baseline-detector": "0.3.1", "core-js-compat": "^3.48.0", "lighthouse": "^13.4.0", "puppeteer-core": "^25.3.0", diff --git a/packages/stats-generator/src/collect-stats.ts b/packages/stats-generator/src/collect-stats.ts index b0f7ae45..007d83db 100644 --- a/packages/stats-generator/src/collect-stats.ts +++ b/packages/stats-generator/src/collect-stats.ts @@ -4,7 +4,12 @@ import { getFrameworks } from './get-frameworks.ts' import { packagesDir } from './constants.ts' import { saveStats } from './save-stats.ts' import { getCIStats } from './get-ci-stats.ts' -import type { FrameworkStats, PackageJson, FrameworkConfig } from './types.ts' +import type { + BrowserBaselineStats, + FrameworkStats, + PackageJson, + FrameworkConfig, +} from './types.ts' async function getDependencyCountsFromPackageJson(pkgDir: string) { const packageJsonPath = join(packagesDir, pkgDir, 'package.json') @@ -17,6 +22,24 @@ async function getDependencyCountsFromPackageJson(pkgDir: string) { } } +async function getBrowserBaselineStats(pkgDir: string) { + const browserBaselineStatsPath = join( + packagesDir, + pkgDir, + 'browser-baseline-stats.json', + ) + + try { + const content = await readFile(browserBaselineStatsPath, 'utf-8') + const stats = JSON.parse(content) as BrowserBaselineStats + return { + browserBaselineTests: stats, + } + } catch { + return {} + } +} + async function processStarter(framework: FrameworkConfig, order: number) { const starter = framework.starter if (!starter) return @@ -31,6 +54,13 @@ async function processStarter(framework: FrameworkConfig, order: number) { hasDependencies && ciStats.prodDependencies === undefined ? await getDependencyCountsFromPackageJson(pkgDir) : {} + const hasBrowserBaseline = measurements.some( + (m) => m.type === 'browserBaseline', + ) + const browserBaselineStats = + hasBrowserBaseline && ciStats.browserBaselineTests === undefined + ? await getBrowserBaselineStats(pkgDir) + : {} const stats: FrameworkStats = { name: displayName, @@ -39,6 +69,7 @@ async function processStarter(framework: FrameworkConfig, order: number) { isFocused: framework.focusedFramework, order, ...dependencyStats, + ...browserBaselineStats, ...ciStats, } diff --git a/packages/stats-generator/src/run-browser-baseline-scan.ts b/packages/stats-generator/src/run-browser-baseline-scan.ts new file mode 100644 index 00000000..12b9d2de --- /dev/null +++ b/packages/stats-generator/src/run-browser-baseline-scan.ts @@ -0,0 +1,148 @@ +import { access, copyFile, mkdir, mkdtemp, rm } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { + detectBaselineTarget, + detectBaselineYear, + detectFeatures, +} from 'baseline-detector' +import { glob } from 'tinyglobby' +import { packagesDir } from './constants.ts' +import { getFrameworkByPackage, parseArgs, writeJsonFile } from './utils.ts' +import type { BrowserBaselineStats } from './types.ts' + +type BaselineStatus = BrowserBaselineStats['baselineStatus'] +type BrowserBaselineTarget = { + status: BaselineStatus + reason: string | null +} + +const IGNORED_BUILD_SEGMENTS = [ + '/build/', + '/cache/', + '/diagnostics/', + '/server/', + '/standalone/', + '/trace/', + '/types/', +] +const IGNORED_BUILD_FILES = [ + '/env.js', + '/handler.js', + '/index.js', + '/required-server-files.js', + '/shims.js', +] +const SOURCE_FILE_GLOB = '**/*.{js,jsx,mjs,cjs,ts,mts,cts,tsx,vue,svelte}' + +function normalizeBaselineTarget( + featureIds: string[], + target: Awaited>, +): BrowserBaselineTarget { + if (featureIds.length === 0) { + return { status: null, reason: null } + } + + return target +} + +function isBrowserSourceFile(filePath: string) { + const normalized = `/${filePath.split('\\').join('/')}` + + if (IGNORED_BUILD_FILES.includes(normalized)) { + return false + } + + return !IGNORED_BUILD_SEGMENTS.some((segment) => normalized.includes(segment)) +} + +async function stageBrowserBuildFiles(buildOutputPath: string) { + await access(buildOutputPath) + + const scanDir = await mkdtemp(join(tmpdir(), 'framework-browser-baseline-')) + const sourceFiles = await glob(SOURCE_FILE_GLOB, { + cwd: buildOutputPath, + absolute: false, + }).catch(() => []) + const browserSourceFiles = sourceFiles.filter(isBrowserSourceFile) + + for (const file of browserSourceFiles) { + const outputPath = join(scanDir, file) + await mkdir(dirname(outputPath), { recursive: true }) + await copyFile(join(buildOutputPath, file), outputPath) + } + + return { + scanDir, + copiedFileCount: browserSourceFiles.length, + } +} + +async function main() { + const { packageName } = parseArgs( + 'Usage: run-browser-baseline-scan \nExample: run-browser-baseline-scan starter-astro', + ) + + const { testConfig } = await getFrameworkByPackage(packageName) + const buildOutputPath = join( + packagesDir, + packageName, + testConfig.buildOutputDir, + ) + const { scanDir, copiedFileCount } = + await stageBrowserBuildFiles(buildOutputPath) + + try { + console.info( + `Scanning browser baseline features in ${packageName} build output...\n`, + ) + console.info(` Build output: ${buildOutputPath}`) + console.info(` Staged ${copiedFileCount} browser source file(s).`) + + const [featuresByFile, detectedTarget, detectedBaselineYear] = + await Promise.all([ + detectFeatures({ cwd: scanDir }), + detectBaselineTarget({ cwd: scanDir }), + detectBaselineYear({ cwd: scanDir }), + ]) + + const featureIds = [ + ...new Set([...featuresByFile.values()].flatMap((ids) => [...ids])), + ].sort() + const target = normalizeBaselineTarget(featureIds, detectedTarget) + + const stats: BrowserBaselineStats = { + baselineStatus: target.status, + baselineYear: featureIds.length === 0 ? null : detectedBaselineYear, + baselineReason: target.reason, + baselineFeatureCount: featureIds.length, + } + + const label = + target.status === null + ? 'none' + : target.status === false + ? 'limited' + : target.status + console.info(` Detected ${featureIds.length} web platform feature(s).`) + console.info( + ` Baseline target: ${label}${target.reason ? ` (${target.reason})` : ''}`, + ) + + const outputPath = join( + packagesDir, + packageName, + 'browser-baseline-stats.json', + ) + writeJsonFile(outputPath, stats) + + console.info(`\n✓ Saved browser baseline stats to ${outputPath}`) + } finally { + await rm(scanDir, { recursive: true, force: true }) + } +} + +main().catch((error) => { + console.error('Browser baseline scan failed:', error) + process.exit(1) +}) diff --git a/packages/stats-generator/src/save-ci-stats.ts b/packages/stats-generator/src/save-ci-stats.ts index c6ffbbd6..ec742baf 100644 --- a/packages/stats-generator/src/save-ci-stats.ts +++ b/packages/stats-generator/src/save-ci-stats.ts @@ -7,6 +7,7 @@ import type { InstallStats, BuildStats, CoreJsStats, + BrowserBaselineStats, E18eStats, } from './types.ts' @@ -103,6 +104,27 @@ async function main() { ) } + // Load browser baseline stats from artifact + const browserBaselineArtifactPath = join( + artifactsDir, + `browser-baseline-stats-${name}`, + 'browser-baseline-stats.json', + ) + const browserBaselineStats = readJsonFile( + browserBaselineArtifactPath, + ) + if (browserBaselineStats) { + console.info(` ✓ Found browser baseline stats artifact`) + stats = { + ...stats, + browserBaselineTests: browserBaselineStats, + } + } else { + console.warn( + `No browser baseline stats artifact found at ${browserBaselineArtifactPath}`, + ) + } + // Load e18e stats from artifact const e18eArtifactPath = join( artifactsDir, diff --git a/packages/stats-generator/src/schemas.ts b/packages/stats-generator/src/schemas.ts index 3f416841..6bc1e68e 100644 --- a/packages/stats-generator/src/schemas.ts +++ b/packages/stats-generator/src/schemas.ts @@ -19,6 +19,18 @@ export const BuildStatsSchema = z.object({ buildOutputSize: z.number().nonnegative(), }) +export const BrowserBaselineStatsSchema = z.object({ + baselineStatus: z.union([ + z.literal('high'), + z.literal('low'), + z.literal(false), + z.null(), + ]), + baselineYear: z.number().nullable(), + baselineReason: z.string().nullable(), + baselineFeatureCount: z.number().nonnegative(), +}) + export const SSRRequestThroughputStatsSchema = z.object({ ssrRequestThroughputTests: z.object({ opsPerSec: z.number().positive(), @@ -71,6 +83,7 @@ export const SSRLoadStatsSchema = z.object({ export type InstallStats = z.infer export type BuildStats = z.infer +export type BrowserBaselineStats = z.infer export type SSRRequestThroughputStats = z.infer< typeof SSRRequestThroughputStatsSchema > diff --git a/packages/stats-generator/src/types.ts b/packages/stats-generator/src/types.ts index 23688739..1f738fd6 100644 --- a/packages/stats-generator/src/types.ts +++ b/packages/stats-generator/src/types.ts @@ -3,6 +3,7 @@ export type MeasurementType = | 'build' | 'test' | 'dependencies' + | 'browserBaseline' | 'ssrRequestThroughput' | 'ssrLoad' | 'clientSideRendered' @@ -95,6 +96,8 @@ export interface CIStats { // Core-js vendored polyfill stats vendoredCoreJsSize?: number vendoredCoreJsUnnecessaryModules?: string[] + // Browser baseline stats + browserBaselineTests?: BrowserBaselineStats // Dependency stats (from e18e analysis) prodDependencies?: number devDependencies?: number @@ -131,6 +134,13 @@ export interface CoreJsStats { unnecessaryModules: string[] } +export interface BrowserBaselineStats { + baselineStatus: 'high' | 'low' | false | null + baselineYear: number | null + baselineReason: string | null + baselineFeatureCount: number +} + export interface TimeStat { avgMs: number minMs: number diff --git a/packages/stats-generator/src/utils.ts b/packages/stats-generator/src/utils.ts index a6d4dba7..80ec7d90 100644 --- a/packages/stats-generator/src/utils.ts +++ b/packages/stats-generator/src/utils.ts @@ -110,6 +110,10 @@ export function normalizeCIStats(stats: T): T { clientSideRenderedFCPMs?: unknown clientSideRenderedINPMs?: unknown clientSideRenderedRuns?: unknown + baselineStatus?: unknown + baselineYear?: unknown + baselineReason?: unknown + baselineFeatureCount?: unknown mpaFirstPaintMs?: unknown mpaFCPMs?: unknown mpaINPMs?: unknown @@ -201,6 +205,26 @@ export function normalizeCIStats(stats: T): T { } } + if ( + stats.browserBaselineTests == null && + (legacyStats.baselineStatus === 'high' || + legacyStats.baselineStatus === 'low' || + legacyStats.baselineStatus === false || + legacyStats.baselineStatus === null) && + (typeof legacyStats.baselineYear === 'number' || + legacyStats.baselineYear === null) && + (typeof legacyStats.baselineReason === 'string' || + legacyStats.baselineReason === null) && + typeof legacyStats.baselineFeatureCount === 'number' + ) { + stats.browserBaselineTests = { + baselineStatus: legacyStats.baselineStatus, + baselineYear: legacyStats.baselineYear, + baselineReason: legacyStats.baselineReason, + baselineFeatureCount: legacyStats.baselineFeatureCount, + } + } + delete legacyStats.ssrOpsPerSec delete legacyStats.serverRenderThroughputTests delete legacyStats.ssrAvgLatencyMs @@ -224,6 +248,10 @@ export function normalizeCIStats(stats: T): T { delete legacyStats.clientSideRenderedFCPMs delete legacyStats.clientSideRenderedINPMs delete legacyStats.clientSideRenderedRuns + delete legacyStats.baselineStatus + delete legacyStats.baselineYear + delete legacyStats.baselineReason + delete legacyStats.baselineFeatureCount delete legacyStats.mpaFirstPaintMs delete legacyStats.mpaFCPMs delete legacyStats.mpaINPMs diff --git a/packages/stats-generator/src/validate-stats.ts b/packages/stats-generator/src/validate-stats.ts index 185ae131..09a1b5e9 100644 --- a/packages/stats-generator/src/validate-stats.ts +++ b/packages/stats-generator/src/validate-stats.ts @@ -6,11 +6,13 @@ import { readJsonFile } from './utils.ts' import { InstallStatsSchema, BuildStatsSchema, + BrowserBaselineStatsSchema, SSRRequestThroughputStatsSchema, SSRLoadStatsSchema, } from './schemas.ts' -type BenchmarkType = 'install' | 'build' | 'ssrRequestThroughput' | 'ssrLoad' +type BenchmarkType = + 'install' | 'build' | 'browserBaseline' | 'ssrRequestThroughput' | 'ssrLoad' interface BenchmarkConfig { type: BenchmarkType @@ -21,6 +23,11 @@ interface BenchmarkConfig { const STARTER_BENCHMARKS: BenchmarkConfig[] = [ { type: 'install', file: 'install-stats.json', schema: InstallStatsSchema }, { type: 'build', file: 'build-stats.json', schema: BuildStatsSchema }, + { + type: 'browserBaseline', + file: 'browser-baseline-stats.json', + schema: BrowserBaselineStatsSchema, + }, ] const APP_BENCHMARKS: BenchmarkConfig[] = [ @@ -73,6 +80,13 @@ async function main() { const errors: string[] = [] for (const { type: benchType, file, schema } of STARTER_BENCHMARKS) { if (filterType && filterType !== benchType) continue + if ( + !framework.starter.measurements.some( + (measurement) => measurement.type === benchType, + ) + ) { + continue + } const filePath = join(packagesDir, pkg, file) const fileErrors = validateFile(filePath, schema) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4275b6b5..3ed124bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,6 +67,9 @@ importers: autocannon: specifier: ^8.0.0 version: 8.0.0 + baseline-detector: + specifier: 0.3.1 + version: 0.3.1(typescript@6.0.3) core-js-compat: specifier: ^3.48.0 version: 3.49.0 @@ -104,6 +107,68 @@ packages: '@assemblyscript/loader@0.19.23': resolution: {integrity: sha512-ulkCYfFbYj01ie1MDOyxv2F6SpRN1TOj7fQxbP07D6HmeR+gr2JLSmINKjga2emB+b1L2KGrFKBTc+e00p54nw==} + '@ast-grep/napi-darwin-arm64@0.44.1': + resolution: {integrity: sha512-JPcb1PvOkwKgccGbBgtoc4e6qfx/luvAtlc6SEtNPhvSwV8qagLb9MCSDcCiuqrqICx3qHj2CXouGbs66lCFvA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@ast-grep/napi-darwin-x64@0.44.1': + resolution: {integrity: sha512-TZj9CnCoe30mj2Nri/mMDORgkp1nkeCiw03CIRPOaUqNOvCNyMWLQhxwGJcG1KpY9MuTZsbLcQ3jju0fXZJjwQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@ast-grep/napi-linux-arm64-gnu@0.44.1': + resolution: {integrity: sha512-tw/7ruKolNcy97tDf/24Arb8wo/Ho2FRHk98lrmYQZZr18fFaiYjRXTCJTizOsdo6wL/asht4Rpdo/eRPuDhVw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-arm64-musl@0.44.1': + resolution: {integrity: sha512-IJlY4GnuDqABa40xMvJp62nEQWYmk6wXtZc2sbPiQoemxAPG6X2m+eWwYpE9heAQOe6iNkXsILNH8YZHRTYayA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-linux-x64-gnu@0.44.1': + resolution: {integrity: sha512-6YyLrXn0RcKCS/FpqAFVWWtbGNFYia5tNI6mX1PqVQPCMT5EojHDXpW2/eo6uV/BnGCsVpTocAWSpac6tACa6g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-x64-musl@0.44.1': + resolution: {integrity: sha512-P8ze2Srap/4RsxbrzMy/NSvkRfLwNfvfoEbwBqS/q199t3wVkpS2gT13QkANrgU+RLUgAIawnFBpjbm5XinIuQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-win32-arm64-msvc@0.44.1': + resolution: {integrity: sha512-ty5fItgu6aTDJg1fVkWwx0qboB5pFsyjRHSgi5uqXFzLbno1vOKog1pMzu3xcKcLqMiNI0axML+HdFOqSFQz0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@ast-grep/napi-win32-ia32-msvc@0.44.1': + resolution: {integrity: sha512-1wTv2MrQLygnaZhlgH8aYpOkHW051CwWWowTr2AFGkn+2PMfsTTG4SEWcZArOIKlAGdWAvvlut66tLyzKhAFyw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@ast-grep/napi-win32-x64-msvc@0.44.1': + resolution: {integrity: sha512-U8CK5JaH8YUezTJnyk97I3C5Twh9gKDB/Q3KztQdOZGeoYqthnQzM4Ntvlz8aWaVSssn7OyGMr3O8ZoK0W8aJg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@ast-grep/napi@0.44.1': + resolution: {integrity: sha512-dJAJVYRKmUjXn+4mXUgfRvMrWujB9mLzPSq/2e8J7n6Hn3dY4jpZNpChj6hMi7PlZ2J2c7coAVoDBaax06uvXw==} + engines: {node: '>= 10'} + '@astrojs/check@0.9.9': resolution: {integrity: sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg==} hasBin: true @@ -1514,6 +1579,15 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-detector@0.3.1: + resolution: {integrity: sha512-yz2/pim4u4g6VLNpZxY4+RjoxQ4su48/DyEXNkGLE56QlKN1fbTuTqBxn5/i+wxUGlkpa06/E+cnoKK6alaOMA==} + hasBin: true + peerDependencies: + typescript: ^6.0.3 + peerDependenciesMeta: + typescript: + optional: true + big.js@7.0.1: resolution: {integrity: sha512-iFgV784tD8kq4ccF1xtNMZnXeZzVuXWWM+ERFzKQjv+A5G9HC8CY3DuV45vgzFFcW+u2tIvmF95+AzWgs6BjCg==} @@ -3326,6 +3400,9 @@ packages: web-features@3.30.0: resolution: {integrity: sha512-IF5V6RRMD2DO7Dy/s2ApI99SnnPUEomLU/j9PgBBEQHJHyM7swVzktmbVXTsaI9u7bxp6o+LlclS2HoMEjz9nw==} + web-features@3.32.0: + resolution: {integrity: sha512-PQBbTofqV8FtMP65oT9tLPjbN4FSB2dRdNxLM0A9j4bNifVpFhEP/ATXSMMJAqPPWb/pgUOh6B+98yzfNEVbNw==} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -3450,6 +3527,45 @@ snapshots: '@assemblyscript/loader@0.19.23': {} + '@ast-grep/napi-darwin-arm64@0.44.1': + optional: true + + '@ast-grep/napi-darwin-x64@0.44.1': + optional: true + + '@ast-grep/napi-linux-arm64-gnu@0.44.1': + optional: true + + '@ast-grep/napi-linux-arm64-musl@0.44.1': + optional: true + + '@ast-grep/napi-linux-x64-gnu@0.44.1': + optional: true + + '@ast-grep/napi-linux-x64-musl@0.44.1': + optional: true + + '@ast-grep/napi-win32-arm64-msvc@0.44.1': + optional: true + + '@ast-grep/napi-win32-ia32-msvc@0.44.1': + optional: true + + '@ast-grep/napi-win32-x64-msvc@0.44.1': + optional: true + + '@ast-grep/napi@0.44.1': + optionalDependencies: + '@ast-grep/napi-darwin-arm64': 0.44.1 + '@ast-grep/napi-darwin-x64': 0.44.1 + '@ast-grep/napi-linux-arm64-gnu': 0.44.1 + '@ast-grep/napi-linux-arm64-musl': 0.44.1 + '@ast-grep/napi-linux-x64-gnu': 0.44.1 + '@ast-grep/napi-linux-x64-musl': 0.44.1 + '@ast-grep/napi-win32-arm64-msvc': 0.44.1 + '@ast-grep/napi-win32-ia32-msvc': 0.44.1 + '@ast-grep/napi-win32-x64-msvc': 0.44.1 + '@astrojs/check@0.9.9(prettier-plugin-astro@0.14.1)(prettier@3.9.4)(typescript@6.0.3)': dependencies: '@astrojs/language-server': 2.16.7(prettier-plugin-astro@0.14.1)(prettier@3.9.4)(typescript@6.0.3) @@ -4968,6 +5084,14 @@ snapshots: baseline-browser-mapping@2.10.11: {} + baseline-detector@0.3.1(typescript@6.0.3): + dependencies: + '@ast-grep/napi': 0.44.1 + ignore: 7.0.5 + web-features: 3.32.0 + optionalDependencies: + typescript: 6.0.3 + big.js@7.0.1: {} bignumber.js@9.3.1: {} @@ -6777,6 +6901,8 @@ snapshots: web-features@3.30.0: {} + web-features@3.32.0: {} + web-streams-polyfill@3.3.3: {} webdriver-bidi-protocol@0.4.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d166a05f..e59adebe 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,3 +6,6 @@ packages: allowBuilds: esbuild: true sharp: true + +minimumReleaseAgeExclude: + - baseline-detector@0.3.1