From 04613de99dfe11af5c285d64c63c4ab8b03f36a6 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 00:17:13 -0700 Subject: [PATCH 01/10] feat(runtime): expose bundler entrypoints --- packages/runtime-tools/package.json | 4 ++++ packages/runtime-tools/src/bundler.ts | 2 ++ packages/runtime-tools/tsdown.config.ts | 1 + packages/runtime/package.json | 4 ++++ packages/runtime/src/bundler.ts | 1 + packages/runtime/tsdown.config.ts | 1 + packages/webpack-bundler-runtime/package.json | 4 ++++ packages/webpack-bundler-runtime/src/bundler.ts | 2 ++ packages/webpack-bundler-runtime/tsdown.config.ts | 1 + 9 files changed, 20 insertions(+) create mode 100644 packages/runtime-tools/src/bundler.ts create mode 100644 packages/runtime/src/bundler.ts create mode 100644 packages/webpack-bundler-runtime/src/bundler.ts diff --git a/packages/runtime-tools/package.json b/packages/runtime-tools/package.json index 6fed77ac936..9fefed09662 100644 --- a/packages/runtime-tools/package.json +++ b/packages/runtime-tools/package.json @@ -60,6 +60,7 @@ "default": "./dist/webpack-bundler-runtime.cjs" } }, + "./bundler": "./dist/bundler.js", "./*": "./*" }, "typesVersions": { @@ -75,6 +76,9 @@ ], "runtime-core": [ "./dist/runtime-core.d.ts" + ], + "bundler": [ + "./dist/bundler.d.ts" ] } }, diff --git a/packages/runtime-tools/src/bundler.ts b/packages/runtime-tools/src/bundler.ts new file mode 100644 index 00000000000..c218ac14272 --- /dev/null +++ b/packages/runtime-tools/src/bundler.ts @@ -0,0 +1,2 @@ +export { default } from './index'; +export * from './index'; diff --git a/packages/runtime-tools/tsdown.config.ts b/packages/runtime-tools/tsdown.config.ts index 9d6afbce829..f5311b7ee3e 100644 --- a/packages/runtime-tools/tsdown.config.ts +++ b/packages/runtime-tools/tsdown.config.ts @@ -15,6 +15,7 @@ export default defineConfig([ runtime: 'src/runtime.ts', 'runtime-core': 'src/runtime-core.ts', 'webpack-bundler-runtime': 'src/webpack-bundler-runtime.ts', + bundler: 'src/bundler.ts', }, external: ['@module-federation/*'], dts: { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 641a7c6361d..e72daba102f 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -63,6 +63,7 @@ "default": "./dist/core.cjs" } }, + "./bundler": "./dist/bundler.js", "./*": "./*" }, "typesVersions": { @@ -78,6 +79,9 @@ ], "core": [ "./dist/core.d.ts" + ], + "bundler": [ + "./dist/bundler.d.ts" ] } }, diff --git a/packages/runtime/src/bundler.ts b/packages/runtime/src/bundler.ts new file mode 100644 index 00000000000..ea465c2a34a --- /dev/null +++ b/packages/runtime/src/bundler.ts @@ -0,0 +1 @@ +export * from './index'; diff --git a/packages/runtime/tsdown.config.ts b/packages/runtime/tsdown.config.ts index 535b5740f91..1e5fea6ec61 100644 --- a/packages/runtime/tsdown.config.ts +++ b/packages/runtime/tsdown.config.ts @@ -30,6 +30,7 @@ const buildConfig = { helpers: 'src/helpers.ts', types: 'src/types.ts', core: 'src/core.ts', + bundler: 'src/bundler.ts', }, external: ['@module-federation/*'], dts: { diff --git a/packages/webpack-bundler-runtime/package.json b/packages/webpack-bundler-runtime/package.json index 8f8ebba2a66..dd693105901 100644 --- a/packages/webpack-bundler-runtime/package.json +++ b/packages/webpack-bundler-runtime/package.json @@ -50,6 +50,7 @@ "default": "./dist/constant.cjs" } }, + "./bundler": "./dist/bundler.js", "./*": "./*" }, "typesVersions": { @@ -59,6 +60,9 @@ ], "constant": [ "./dist/constant.d.ts" + ], + "bundler": [ + "./dist/bundler.d.ts" ] } }, diff --git a/packages/webpack-bundler-runtime/src/bundler.ts b/packages/webpack-bundler-runtime/src/bundler.ts new file mode 100644 index 00000000000..c218ac14272 --- /dev/null +++ b/packages/webpack-bundler-runtime/src/bundler.ts @@ -0,0 +1,2 @@ +export { default } from './index'; +export * from './index'; diff --git a/packages/webpack-bundler-runtime/tsdown.config.ts b/packages/webpack-bundler-runtime/tsdown.config.ts index fb9b36f5f1b..04ea06f2b8b 100644 --- a/packages/webpack-bundler-runtime/tsdown.config.ts +++ b/packages/webpack-bundler-runtime/tsdown.config.ts @@ -14,6 +14,7 @@ export default defineConfig([ entry: { index: 'src/index.ts', constant: 'src/constant.ts', + bundler: 'src/bundler.ts', }, external: ['@module-federation/*', 'webpack'], dts: { From 335b04186166bb89571dff48ceba171d641dceaa Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 00:17:47 -0700 Subject: [PATCH 02/10] fix(enhanced): improve optimization tree shaking --- .changeset/breezy-walls-burn.md | 8 ++ .../bridge/bridge-react/src/lazy/utils.ts | 7 +- .../runtime/FederationRuntimePlugin.ts | 80 ++++++++++--- .../experiments-optimization/index.js | 61 ++++++++++ .../experiments-optimization/noop.js | 2 + .../webpack.config.js | 107 ++++++++++++++++++ .../container/FederationRuntimePlugin.test.ts | 96 ++++++++++++++-- .../__tests__/ModuleFederationPlugin.spec.ts | 69 +++++++++++ packages/rspack/src/ModuleFederationPlugin.ts | 83 +++++++++++--- packages/runtime-core/src/core.ts | 4 +- .../src/plugins/generate-preload-assets.ts | 4 +- .../src/plugins/snapshot/SnapshotHandler.ts | 4 +- .../src/plugins/snapshot/index.ts | 4 +- packages/runtime-core/src/remote/index.ts | 8 +- packages/runtime-core/src/utils/env.ts | 6 +- packages/runtime-core/src/utils/load.ts | 6 +- packages/runtime-core/src/utils/tool.ts | 8 +- packages/sdk/README.md | 12 +- packages/sdk/__tests__/utils.spec.ts | 35 ++++-- packages/sdk/src/env.ts | 22 +++- 20 files changed, 549 insertions(+), 77 deletions(-) create mode 100644 .changeset/breezy-walls-burn.md create mode 100644 packages/enhanced/test/configCases/container/experiments-optimization/index.js create mode 100644 packages/enhanced/test/configCases/container/experiments-optimization/noop.js create mode 100644 packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js create mode 100644 packages/rspack/__tests__/ModuleFederationPlugin.spec.ts diff --git a/.changeset/breezy-walls-burn.md b/.changeset/breezy-walls-burn.md new file mode 100644 index 00000000000..1901630b107 --- /dev/null +++ b/.changeset/breezy-walls-burn.md @@ -0,0 +1,8 @@ +--- +"@module-federation/sdk": minor +"@module-federation/runtime-core": minor +--- + +Add `isBrowserEnvValue` as a tree-shakable ENV_TARGET-aware constant while +preserving the `isBrowserEnv()` function. Internal callers use the constant to +enable bundler dead-code elimination without breaking the public API. diff --git a/packages/bridge/bridge-react/src/lazy/utils.ts b/packages/bridge/bridge-react/src/lazy/utils.ts index 7f1025cbfc3..40497c4adb8 100644 --- a/packages/bridge/bridge-react/src/lazy/utils.ts +++ b/packages/bridge/bridge-react/src/lazy/utils.ts @@ -1,4 +1,7 @@ -import { isBrowserEnv, composeKeyWithSeparator } from '@module-federation/sdk'; +import { + isBrowserEnvValue, + composeKeyWithSeparator, +} from '@module-federation/sdk'; import logger from './logger'; import { DOWNGRADE_KEY, @@ -153,7 +156,7 @@ export async function fetchData( _id: id, }); }; - if (isBrowserEnv()) { + if (isBrowserEnvValue) { const dataFetchItem = getDataFetchItem(id); if (!dataFetchItem) { throw new Error(`dataFetchItem not found, id: ${id}`); diff --git a/packages/enhanced/src/lib/container/runtime/FederationRuntimePlugin.ts b/packages/enhanced/src/lib/container/runtime/FederationRuntimePlugin.ts index f83ca81f55b..6eb142c926e 100644 --- a/packages/enhanced/src/lib/container/runtime/FederationRuntimePlugin.ts +++ b/packages/enhanced/src/lib/container/runtime/FederationRuntimePlugin.ts @@ -34,23 +34,73 @@ const { mkdirpSync } = require( normalizeWebpackPath('webpack/lib/util/fs'), ) as typeof import('webpack/lib/util/fs'); -function resolveRuntimePaths(implementation?: string) { - const ext = process.env.IS_ESM_BUILD === 'true' ? '.js' : '.cjs'; - const runtimeToolsSpec = `@module-federation/runtime-tools/dist/index${ext}`; - const bundlerRuntimeSpec = `@module-federation/webpack-bundler-runtime/dist/index${ext}`; - const runtimeSpec = `@module-federation/runtime/dist/index${ext}`; +type ResolveFn = typeof require.resolve; +type RuntimeEntrySpec = { + bundler: string; + esm: string; + cjs: string; +}; + +function resolveRuntimeEntry( + spec: RuntimeEntrySpec, + implementation: string | undefined, + resolve: ResolveFn = require.resolve, +) { + const candidates = [spec.bundler, spec.esm, spec.cjs]; + const modulePaths = implementation ? [implementation] : undefined; + let lastError: unknown; + + for (const candidate of candidates) { + try { + return modulePaths + ? resolve(candidate, { paths: modulePaths }) + : resolve(candidate); + } catch (error) { + lastError = error; + } + } - const runtimeToolsPath = require.resolve(runtimeToolsSpec); - const modulePaths = implementation ? [implementation] : [runtimeToolsPath]; + throw lastError; +} + +export function resolveRuntimePaths( + implementation?: string, + resolve: ResolveFn = require.resolve, +) { + // Prefer the dedicated bundler subpath so webpack can tree-shake across the + // runtime package boundary. Fall back to the legacy dist contract for older + // custom implementations that have not published /bundler yet. + const runtimeToolsPath = resolveRuntimeEntry( + { + bundler: '@module-federation/runtime-tools/bundler', + esm: '@module-federation/runtime-tools/dist/index.js', + cjs: '@module-federation/runtime-tools/dist/index.cjs', + }, + undefined, + resolve, + ); + const moduleBase = implementation || runtimeToolsPath; return { runtimeToolsPath, - bundlerRuntimePath: require.resolve(bundlerRuntimeSpec, { - paths: modulePaths, - }), - runtimePath: require.resolve(runtimeSpec, { - paths: modulePaths, - }), + bundlerRuntimePath: resolveRuntimeEntry( + { + bundler: '@module-federation/webpack-bundler-runtime/bundler', + esm: '@module-federation/webpack-bundler-runtime/dist/index.js', + cjs: '@module-federation/webpack-bundler-runtime/dist/index.cjs', + }, + moduleBase, + resolve, + ), + runtimePath: resolveRuntimeEntry( + { + bundler: '@module-federation/runtime/bundler', + esm: '@module-federation/runtime/dist/index.js', + cjs: '@module-federation/runtime/dist/index.cjs', + }, + moduleBase, + resolve, + ), }; } @@ -225,7 +275,7 @@ class FederationRuntimePlugin { : fs; try { fsLike.readFileSync(filePath); - } catch (err) { + } catch { mkdirpSync(fsLike as any, TEMP_DIR); fsLike.writeFileSync( filePath, @@ -277,7 +327,7 @@ class FederationRuntimePlugin { compiler.context, federationRuntimeDependency, { name: undefined }, - (err, module) => { + (err) => { if (err) { return callback(err); } diff --git a/packages/enhanced/test/configCases/container/experiments-optimization/index.js b/packages/enhanced/test/configCases/container/experiments-optimization/index.js new file mode 100644 index 00000000000..1230a4a0e47 --- /dev/null +++ b/packages/enhanced/test/configCases/container/experiments-optimization/index.js @@ -0,0 +1,61 @@ +/* global __non_webpack_require__, __dirname, globalThis, it, expect */ +const fs = __non_webpack_require__('fs'); +const path = __non_webpack_require__('path'); + +if (!globalThis.__EXPERIMENTS_OPTIMIZATION_CASE__) { + globalThis.__EXPERIMENTS_OPTIMIZATION_CASE__ = true; + + const readOutput = (filename) => + fs.readFileSync(path.join(__dirname, filename), 'utf-8'); + + const webRemoteEntry = readOutput('remoteEntry-web.js'); + const nodeRemoteEntry = readOutput('remoteEntry-node.js'); + const webRemoteEntryEsm = readOutput('module/remoteEntry-web.mjs'); + const nodeRemoteEntryEsm = readOutput('module/remoteEntry-node.mjs'); + + it('should replace optimization define flags with static values', () => { + expect(webRemoteEntry).not.toContain('ENV_TARGET'); + expect(webRemoteEntry).not.toContain( + 'FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN', + ); + + expect(nodeRemoteEntry).not.toContain('ENV_TARGET'); + expect(nodeRemoteEntry).not.toContain( + 'FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN', + ); + + expect(webRemoteEntryEsm).not.toContain('ENV_TARGET'); + expect(webRemoteEntryEsm).not.toContain( + 'FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN', + ); + + expect(nodeRemoteEntryEsm).not.toContain('ENV_TARGET'); + expect(nodeRemoteEntryEsm).not.toContain( + 'FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN', + ); + }); + + it('should eliminate snapshot plugins from the web optimized CJS bundle', () => { + expect(webRemoteEntry).not.toContain('snapshot-plugin'); + expect(webRemoteEntry).not.toContain('generate-preload-assets-plugin'); + expect(webRemoteEntry).not.toContain('attrs:{name'); + }); + + it('should preserve node loading and snapshot plugins in the node CJS bundle', () => { + expect(nodeRemoteEntry).toContain('snapshot-plugin'); + expect(nodeRemoteEntry).toContain('generate-preload-assets-plugin'); + expect(nodeRemoteEntry).toContain('attrs:{name'); + }); + + it('should eliminate snapshot plugins from the web optimized ESM bundle', () => { + expect(webRemoteEntryEsm).not.toContain('snapshot-plugin'); + expect(webRemoteEntryEsm).not.toContain('generate-preload-assets-plugin'); + expect(webRemoteEntryEsm).not.toContain('attrs:{name'); + }); + + it('should preserve node loading and snapshot plugins in the node ESM bundle', () => { + expect(nodeRemoteEntryEsm).toContain('snapshot-plugin'); + expect(nodeRemoteEntryEsm).toContain('generate-preload-assets-plugin'); + expect(nodeRemoteEntryEsm).toContain('attrs:{name'); + }); +} diff --git a/packages/enhanced/test/configCases/container/experiments-optimization/noop.js b/packages/enhanced/test/configCases/container/experiments-optimization/noop.js new file mode 100644 index 00000000000..9036594d706 --- /dev/null +++ b/packages/enhanced/test/configCases/container/experiments-optimization/noop.js @@ -0,0 +1,2 @@ +/* eslint-env node */ +module.exports = 'noop'; diff --git a/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js b/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js new file mode 100644 index 00000000000..a5124bc7d80 --- /dev/null +++ b/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js @@ -0,0 +1,107 @@ +/* eslint-env node */ +const { ModuleFederationPlugin } = require('../../../../dist/src'); + +/** + * This case emits CommonJS and ESM federation bundles into the same output + * directory so the test can statically inspect how experiments.optimization + * affects the emitted runtime code. + */ +const commonConfig = { + optimization: { + minimize: true, + chunkIds: 'named', + moduleIds: 'named', + }, + exposes: { + './noop': './noop.js', + }, + remotes: { + remote: 'remote@http://localhost:3001/remoteEntry.js', + }, +}; + +const createConfig = ({ + entry, + outputModule, + optimizationTarget, + disableSnapshot, + uniqueName, + containerName, + filename, +}) => ({ + entry, + target: outputModule ? 'node14' : 'async-node', + experiments: outputModule + ? { + outputModule: true, + } + : undefined, + output: { + publicPath: '/', + chunkFilename: outputModule ? 'module/[id].mjs' : '[id].js', + uniqueName, + }, + optimization: commonConfig.optimization, + plugins: [ + new ModuleFederationPlugin({ + name: containerName, + filename, + manifest: true, + library: outputModule + ? { + type: 'module', + } + : { + type: 'commonjs-module', + name: containerName, + }, + exposes: commonConfig.exposes, + remotes: commonConfig.remotes, + experiments: { + optimization: { + target: optimizationTarget, + disableSnapshot, + }, + }, + }), + ], +}); + +module.exports = [ + createConfig({ + entry: './index.js', + outputModule: false, + optimizationTarget: 'web', + disableSnapshot: true, + uniqueName: 'experiments-optimization-web-cjs', + containerName: 'experiments_optimization_web_cjs', + filename: 'remoteEntry-web.js', + }), + createConfig({ + entry: './noop.js', + outputModule: false, + optimizationTarget: 'node', + disableSnapshot: false, + uniqueName: 'experiments-optimization-node-cjs', + containerName: 'experiments_optimization_node_cjs', + filename: 'remoteEntry-node.js', + }), + createConfig({ + entry: './noop.js', + outputModule: true, + optimizationTarget: 'web', + disableSnapshot: true, + uniqueName: 'experiments-optimization-web-esm', + containerName: 'experiments_optimization_web_esm', + filename: 'module/remoteEntry-web.mjs', + }), + createConfig({ + entry: './noop.js', + outputModule: true, + optimizationTarget: 'node', + disableSnapshot: false, + uniqueName: 'experiments-optimization-node-esm', + containerName: 'experiments_optimization_node_esm', + filename: 'module/remoteEntry-node.mjs', + }), +]; diff --git a/packages/enhanced/test/unit/container/FederationRuntimePlugin.test.ts b/packages/enhanced/test/unit/container/FederationRuntimePlugin.test.ts index 74069c11b74..bcf566c975b 100644 --- a/packages/enhanced/test/unit/container/FederationRuntimePlugin.test.ts +++ b/packages/enhanced/test/unit/container/FederationRuntimePlugin.test.ts @@ -1,6 +1,8 @@ -import FederationRuntimePlugin from '../../../src/lib/container/runtime/FederationRuntimePlugin'; +import FederationRuntimePlugin, { + resolveRuntimePaths, +} from '../../../src/lib/container/runtime/FederationRuntimePlugin'; import type { Compiler } from 'webpack'; -import { rs, Mock } from '@rstest/core'; +import { rs } from '@rstest/core'; // Use rs.hoisted() to create mock functions that are hoisted along with rs.mock() const mocks = rs.hoisted(() => ({ @@ -216,7 +218,7 @@ describe('FederationRuntimePlugin runtimePluginCalls', () => { } }); - it('prefers cjs runtime entry when IS_ESM_BUILD is false', () => { + it('prefers esm runtime entry even when IS_ESM_BUILD is false', () => { process.env.IS_ESM_BUILD = 'false'; const plugin = new FederationRuntimePlugin({ implementation: '/legacy/runtime-tools', @@ -226,7 +228,85 @@ describe('FederationRuntimePlugin runtimePluginCalls', () => { } as unknown as Compiler); expect(normalizePath(runtimePath)).toMatch( - /\/runtime\/dist\/index\.cjs(?:\.cjs)?$/, + /\/runtime\/dist\/bundler\.js$/, + ); + }); + + it('falls back to legacy esm runtime entries for older implementations', () => { + const resolve = rs.fn( + (request: string, options?: { paths?: string[] }) => { + const basedFromLegacy = + options?.paths?.[0] === '/legacy/runtime-tools'; + + if (request === '@module-federation/runtime-tools/bundler') { + return '/workspace/runtime-tools/dist/bundler.js'; + } + if (basedFromLegacy && request.endsWith('/bundler')) { + throw new Error(`Cannot find module '${request}'`); + } + if (request === '@module-federation/runtime/dist/index.js') { + return '/legacy/runtime/dist/index.js'; + } + if ( + request === + '@module-federation/webpack-bundler-runtime/dist/index.js' + ) { + return '/legacy/webpack-bundler-runtime/dist/index.js'; + } + + throw new Error(`Unexpected request: ${request}`); + }, + ); + + const resolved = resolveRuntimePaths('/legacy/runtime-tools', resolve); + + expect(normalizePath(resolved.runtimeToolsPath)).toBe( + '/workspace/runtime-tools/dist/bundler.js', + ); + expect(normalizePath(resolved.runtimePath)).toBe( + '/legacy/runtime/dist/index.js', + ); + expect(normalizePath(resolved.bundlerRuntimePath)).toBe( + '/legacy/webpack-bundler-runtime/dist/index.js', + ); + }); + + it('falls back to legacy cjs runtime entries when esm legacy builds are unavailable', () => { + const resolve = rs.fn( + (request: string, options?: { paths?: string[] }) => { + const basedFromLegacy = + options?.paths?.[0] === '/legacy/runtime-tools'; + + if (request === '@module-federation/runtime-tools/bundler') { + return '/workspace/runtime-tools/dist/bundler.js'; + } + if ( + basedFromLegacy && + (request.endsWith('/bundler') || request.endsWith('/dist/index.js')) + ) { + throw new Error(`Cannot find module '${request}'`); + } + if (request === '@module-federation/runtime/dist/index.cjs') { + return '/legacy/runtime/dist/index.cjs'; + } + if ( + request === + '@module-federation/webpack-bundler-runtime/dist/index.cjs' + ) { + return '/legacy/webpack-bundler-runtime/dist/index.cjs'; + } + + throw new Error(`Unexpected request: ${request}`); + }, + ); + + const resolved = resolveRuntimePaths('/legacy/runtime-tools', resolve); + + expect(normalizePath(resolved.runtimePath)).toBe( + '/legacy/runtime/dist/index.cjs', + ); + expect(normalizePath(resolved.bundlerRuntimePath)).toBe( + '/legacy/webpack-bundler-runtime/dist/index.cjs', ); }); @@ -243,11 +323,11 @@ describe('FederationRuntimePlugin runtimePluginCalls', () => { } as unknown as Compiler); expect(normalizePath(runtimePath)).toMatch( - /\/runtime\/dist\/index\.(?:js|esm\.js)$/, + /\/runtime\/dist\/bundler\.js$/, ); }); - it('resolves runtime-tools alias for CJS mode when runtime alias is preset', () => { + it('resolves runtime-tools alias to esm when IS_ESM_BUILD is false', () => { process.env.IS_ESM_BUILD = 'false'; const plugin = new FederationRuntimePlugin({} as any); const compiler = { @@ -267,7 +347,7 @@ describe('FederationRuntimePlugin runtimePluginCalls', () => { '@module-federation/runtime-tools$' ], ), - ).toMatch(/\/runtime-tools\/dist\/index\.cjs(?:\.cjs)?$/); + ).toMatch(/\/runtime-tools\/dist\/bundler\.js$/); }); it('resolves runtime-tools alias for ESM mode when runtime alias is preset', () => { @@ -290,7 +370,7 @@ describe('FederationRuntimePlugin runtimePluginCalls', () => { '@module-federation/runtime-tools$' ], ), - ).toMatch(/\/runtime-tools\/dist\/index\.(?:js|esm\.js)$/); + ).toMatch(/\/runtime-tools\/dist\/bundler\.js$/); }); }); }); diff --git a/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts b/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts new file mode 100644 index 00000000000..f8e9cfa355e --- /dev/null +++ b/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts @@ -0,0 +1,69 @@ +import { + resolveRspackRuntimeAlias, + resolveRspackRuntimeImplementation, +} from '../src/ModuleFederationPlugin'; + +describe('runtime resolution compatibility', () => { + it('prefers the bundler implementation when available', () => { + const resolve = jest.fn((request: string) => { + if (request === '@module-federation/runtime-tools/bundler') { + return '/workspace/runtime-tools/dist/bundler.js'; + } + + throw new Error(`Unexpected request: ${request}`); + }) as typeof require.resolve; + + expect(resolveRspackRuntimeImplementation(undefined, resolve)).toBe( + '/workspace/runtime-tools/dist/bundler.js', + ); + }); + + it('falls back to legacy esm runtime entries for older implementations', () => { + const resolve = jest.fn( + (request: string, options?: { paths?: string[] }) => { + const basedFromLegacy = options?.paths?.[0] === '/legacy/runtime-tools'; + + if ( + basedFromLegacy && + request === '@module-federation/runtime/bundler' + ) { + throw new Error(`Cannot find module '${request}'`); + } + if (request === '@module-federation/runtime/dist/index.js') { + return '/legacy/runtime/dist/index.js'; + } + + throw new Error(`Unexpected request: ${request}`); + }, + ) as typeof require.resolve; + + expect(resolveRspackRuntimeAlias('/legacy/runtime-tools', resolve)).toBe( + '/legacy/runtime/dist/index.js', + ); + }); + + it('falls back to legacy cjs runtime entries when esm legacy builds are unavailable', () => { + const resolve = jest.fn( + (request: string, options?: { paths?: string[] }) => { + const basedFromLegacy = options?.paths?.[0] === '/legacy/runtime-tools'; + + if ( + basedFromLegacy && + (request === '@module-federation/runtime/bundler' || + request === '@module-federation/runtime/dist/index.js') + ) { + throw new Error(`Cannot find module '${request}'`); + } + if (request === '@module-federation/runtime/dist/index.cjs') { + return '/legacy/runtime/dist/index.cjs'; + } + + throw new Error(`Unexpected request: ${request}`); + }, + ) as typeof require.resolve; + + expect(resolveRspackRuntimeAlias('/legacy/runtime-tools', resolve)).toBe( + '/legacy/runtime/dist/index.cjs', + ); + }); +}); diff --git a/packages/rspack/src/ModuleFederationPlugin.ts b/packages/rspack/src/ModuleFederationPlugin.ts index 37f12dac7fc..011dcef5767 100644 --- a/packages/rspack/src/ModuleFederationPlugin.ts +++ b/packages/rspack/src/ModuleFederationPlugin.ts @@ -37,6 +37,66 @@ declare global { } export const PLUGIN_NAME = 'RspackModuleFederationPlugin'; + +type ResolveFn = typeof require.resolve; +type RuntimeEntrySpec = { + bundler: string; + esm: string; + cjs: string; +}; + +function resolveRuntimeEntry( + spec: RuntimeEntrySpec, + implementation: string | undefined, + resolve: ResolveFn = require.resolve, +) { + const candidates = [spec.bundler, spec.esm, spec.cjs]; + const modulePaths = implementation ? [implementation] : undefined; + let lastError: unknown; + + for (const candidate of candidates) { + try { + return modulePaths + ? resolve(candidate, { paths: modulePaths }) + : resolve(candidate); + } catch (error) { + lastError = error; + } + } + + throw lastError; +} + +export function resolveRspackRuntimeImplementation( + implementation?: string, + resolve: ResolveFn = require.resolve, +) { + return resolveRuntimeEntry( + { + bundler: '@module-federation/runtime-tools/bundler', + esm: '@module-federation/runtime-tools/dist/index.js', + cjs: '@module-federation/runtime-tools/dist/index.cjs', + }, + implementation, + resolve, + ); +} + +export function resolveRspackRuntimeAlias( + implementation: string, + resolve: ResolveFn = require.resolve, +) { + return resolveRuntimeEntry( + { + bundler: '@module-federation/runtime/bundler', + esm: '@module-federation/runtime/dist/index.js', + cjs: '@module-federation/runtime/dist/index.cjs', + }, + implementation, + resolve, + ); +} + export class ModuleFederationPlugin implements RspackPluginInstance { readonly name = PLUGIN_NAME; private _options: moduleFederationPlugin.ModuleFederationPluginOptions; @@ -128,9 +188,7 @@ export class ModuleFederationPlugin implements RspackPluginInstance { const runtimePlugins = options.runtimePlugins || []; options.runtimePlugins = runtimePlugins.concat( - require.resolve( - '@module-federation/inject-external-runtime-core-plugin', - ), + require.resolve('@module-federation/inject-external-runtime-core-plugin'), ); } @@ -141,12 +199,9 @@ export class ModuleFederationPlugin implements RspackPluginInstance { }).apply(compiler); } - const runtimeToolsSpecifier = - process.env.IS_ESM_BUILD === 'true' - ? '@module-federation/runtime-tools/dist/index.js' - : '@module-federation/runtime-tools/dist/index.cjs'; - const implementationPath = - options.implementation || require.resolve(runtimeToolsSpecifier); + const implementationPath = options.implementation + ? options.implementation + : resolveRspackRuntimeImplementation(); options.implementation = implementationPath; let disableManifest = options.manifest === false; let disableDts = options.dts === false; @@ -173,19 +228,13 @@ export class ModuleFederationPlugin implements RspackPluginInstance { options as unknown as ModuleFederationPluginOptions, ).apply(compiler); - const runtimeEntrySpecifier = - process.env.IS_ESM_BUILD === 'true' - ? '@module-federation/runtime/dist/index.js' - : '@module-federation/runtime/dist/index.cjs'; let runtimePath: string; try { - runtimePath = require.resolve(runtimeEntrySpecifier, { - paths: [implementationPath], - }); + runtimePath = resolveRspackRuntimeAlias(implementationPath); } catch (err) { const detail = err instanceof Error ? err.message : String(err); throw new Error( - `[ ModuleFederationPlugin ]: Unable to resolve runtime entry at ${runtimeEntrySpecifier} (paths: [${implementationPath}]): ${detail}`, + `[ ModuleFederationPlugin ]: Unable to resolve runtime entry (paths: [${implementationPath}]): ${detail}`, ); } diff --git a/packages/runtime-core/src/core.ts b/packages/runtime-core/src/core.ts index 411dbefce01..b1641295a37 100644 --- a/packages/runtime-core/src/core.ts +++ b/packages/runtime-core/src/core.ts @@ -1,4 +1,4 @@ -import { isBrowserEnv } from '@module-federation/sdk'; +import { isBrowserEnvValue } from '@module-federation/sdk'; import type { CreateScriptHookReturn, GlobalModuleInfo, @@ -190,7 +190,7 @@ export class ModuleFederation { plugins, remotes: [], shared: {}, - inBrowser: isBrowserEnv(), + inBrowser: isBrowserEnvValue, }; this.name = userOptions.name; diff --git a/packages/runtime-core/src/plugins/generate-preload-assets.ts b/packages/runtime-core/src/plugins/generate-preload-assets.ts index 4ac4ee56b0c..c23143d28b4 100644 --- a/packages/runtime-core/src/plugins/generate-preload-assets.ts +++ b/packages/runtime-core/src/plugins/generate-preload-assets.ts @@ -4,7 +4,7 @@ import { ProviderModuleInfo, isManifestProvider, getResourceUrl, - isBrowserEnv, + isBrowserEnvValue, } from '@module-federation/sdk'; import { EntryAssets, @@ -324,7 +324,7 @@ export const generatePreloadAssetsPlugin: () => ModuleFederationRuntimePlugin = globalSnapshot, remoteSnapshot, } = args; - if (!isBrowserEnv()) { + if (!isBrowserEnvValue) { return { cssAssets: [], jsAssetsWithoutEntry: [], diff --git a/packages/runtime-core/src/plugins/snapshot/SnapshotHandler.ts b/packages/runtime-core/src/plugins/snapshot/SnapshotHandler.ts index 6bff9331640..f4715d4908b 100644 --- a/packages/runtime-core/src/plugins/snapshot/SnapshotHandler.ts +++ b/packages/runtime-core/src/plugins/snapshot/SnapshotHandler.ts @@ -4,7 +4,7 @@ import { ModuleInfo, generateSnapshotFromManifest, isManifestProvider, - isBrowserEnv, + isBrowserEnvValue, } from '@module-federation/sdk'; import { RUNTIME_003, @@ -186,7 +186,7 @@ export class SnapshotHandler { // global snapshot includes manifest or module info includes manifest if (globalRemoteSnapshot) { if (isManifestProvider(globalRemoteSnapshot)) { - const remoteEntry = isBrowserEnv() + const remoteEntry = isBrowserEnvValue ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || diff --git a/packages/runtime-core/src/plugins/snapshot/index.ts b/packages/runtime-core/src/plugins/snapshot/index.ts index b501c097c12..fa09668b674 100644 --- a/packages/runtime-core/src/plugins/snapshot/index.ts +++ b/packages/runtime-core/src/plugins/snapshot/index.ts @@ -1,7 +1,7 @@ import { ModuleInfo, getResourceUrl, - isBrowserEnv, + isBrowserEnvValue, } from '@module-federation/sdk'; import { ModuleFederationRuntimePlugin } from '../../type/plugin'; import { RUNTIME_011, runtimeDescMap } from '@module-federation/error-codes'; @@ -25,7 +25,7 @@ export function assignRemoteInfo( let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url); - if (!isBrowserEnv() && !entryUrl.startsWith('http')) { + if (!isBrowserEnvValue && !entryUrl.startsWith('http')) { entryUrl = `https:${entryUrl}`; } diff --git a/packages/runtime-core/src/remote/index.ts b/packages/runtime-core/src/remote/index.ts index 128016dc874..a84d01e2909 100644 --- a/packages/runtime-core/src/remote/index.ts +++ b/packages/runtime-core/src/remote/index.ts @@ -1,5 +1,5 @@ import { - isBrowserEnv, + isBrowserEnvValue, warn, composeKeyWithSeparator, ModuleInfo, @@ -429,7 +429,11 @@ export class RemoteHandler { } // Set the remote entry to a complete path if ('entry' in remote) { - if (isBrowserEnv() && !remote.entry.startsWith('http')) { + if ( + isBrowserEnvValue && + typeof window !== 'undefined' && + !remote.entry.startsWith('http') + ) { remote.entry = new URL(remote.entry, window.location.origin).href; } } diff --git a/packages/runtime-core/src/utils/env.ts b/packages/runtime-core/src/utils/env.ts index 94fa980ebb6..b80c05a22f0 100644 --- a/packages/runtime-core/src/utils/env.ts +++ b/packages/runtime-core/src/utils/env.ts @@ -1,4 +1,8 @@ -export { isBrowserEnv, isDebugMode } from '@module-federation/sdk'; +export { + isBrowserEnv, + isBrowserEnvValue, + isDebugMode, +} from '@module-federation/sdk'; export function isDevelopmentMode(): boolean { return true; diff --git a/packages/runtime-core/src/utils/load.ts b/packages/runtime-core/src/utils/load.ts index d3573139aa7..d949a87296f 100644 --- a/packages/runtime-core/src/utils/load.ts +++ b/packages/runtime-core/src/utils/load.ts @@ -2,7 +2,7 @@ import { loadScript, loadScriptNode, composeKeyWithSeparator, - isBrowserEnv, + isBrowserEnvValue, } from '@module-federation/sdk'; import { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant'; import { ModuleFederation } from '../core'; @@ -258,11 +258,11 @@ export async function getRemoteEntry(params: { if (res) { return res; } - // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnv, must keep this + // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue const isWebEnvironment = typeof ENV_TARGET !== 'undefined' ? ENV_TARGET === 'web' - : isBrowserEnv(); + : isBrowserEnvValue; return isWebEnvironment ? loadEntryDom({ diff --git a/packages/runtime-core/src/utils/tool.ts b/packages/runtime-core/src/utils/tool.ts index f96a2c70899..2fdd19b8e33 100644 --- a/packages/runtime-core/src/utils/tool.ts +++ b/packages/runtime-core/src/utils/tool.ts @@ -2,7 +2,7 @@ import { RemoteWithEntry, ModuleInfo, RemoteEntryType, - isBrowserEnv, + isBrowserEnvValue, isReactNativeEnv, } from '@module-federation/sdk'; import { Remote, RemoteInfoOptionalVersion } from '../type'; @@ -88,7 +88,11 @@ export function getRemoteEntryInfoFromSnapshot(snapshot: ModuleInfo): { type: 'global', globalName: '', }; - if (isBrowserEnv() || isReactNativeEnv() || !('ssrRemoteEntry' in snapshot)) { + if ( + isBrowserEnvValue || + isReactNativeEnv() || + !('ssrRemoteEntry' in snapshot) + ) { return 'remoteEntry' in snapshot ? { url: snapshot.remoteEntry, diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 5ab9727c752..83fffe73c56 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -11,7 +11,7 @@ // The SDK can be used to parse entry strings, encode and decode module names, and generate filenames for exposed modules and shared packages. // It also includes a logger for debugging and environment detection utilities. // Additionally, it provides a function to generate a snapshot from a manifest and environment detection utilities. -import { parseEntry, encodeName, decodeName, generateExposeFilename, generateShareFilename, createLogger, isBrowserEnv, isDebugMode, getProcessEnv, generateSnapshotFromManifest } from '@module-federation/sdk'; +import { parseEntry, encodeName, decodeName, generateExposeFilename, generateShareFilename, createLogger, isBrowserEnv, isBrowserEnvValue, isDebugMode, getProcessEnv, generateSnapshotFromManifest } from '@module-federation/sdk'; // Parse an entry string into a RemoteEntryInfo object parseEntry('entryString'); @@ -32,7 +32,8 @@ generateShareFilename('packageName', true); const logger = createLogger('identifier'); // Check if the current environment is a browser -isBrowserEnv(); +const inBrowser = isBrowserEnv(); +const inBrowserStatic = isBrowserEnvValue; // Check if the current environment is in debug mode isDebugMode(); @@ -76,9 +77,14 @@ generateSnapshotFromManifest(manifest, options); ### isBrowserEnv -- Type: `isBrowserEnv()` +- Type: `isBrowserEnv(): boolean` - Checks if the current environment is a browser. +### isBrowserEnvValue + +- Type: `isBrowserEnvValue: boolean` +- Static browser environment flag (tree-shakable when ENV_TARGET is defined). + ### isDebugMode - Type: `isDebugMode()` diff --git a/packages/sdk/__tests__/utils.spec.ts b/packages/sdk/__tests__/utils.spec.ts index ed1c4e35c9c..812a9d6ffb4 100644 --- a/packages/sdk/__tests__/utils.spec.ts +++ b/packages/sdk/__tests__/utils.spec.ts @@ -1,11 +1,21 @@ import { getResourceUrl } from '../src/utils'; import { ModuleInfo } from '../src/types'; -import { isBrowserEnv, isReactNativeEnv } from '../src/env'; +import * as env from '../src/env'; -jest.mock('../src/env', () => ({ - isBrowserEnv: jest.fn(), - isReactNativeEnv: jest.fn(), -})); +jest.mock('../src/env', () => { + const mock = { + isBrowserEnvValue: false, + isBrowserEnv: jest.fn(() => mock.isBrowserEnvValue), + isReactNativeEnv: jest.fn(), + }; + return mock; +}); + +const mockedEnv = env as unknown as { + isBrowserEnvValue: boolean; + isBrowserEnv: jest.Mock; + isReactNativeEnv: jest.Mock; +}; describe('getResourceUrl', () => { let module: ModuleInfo; @@ -13,8 +23,9 @@ describe('getResourceUrl', () => { beforeEach(() => { sourceUrl = 'test.js'; - (isBrowserEnv as jest.Mock).mockReset(); - (isReactNativeEnv as jest.Mock).mockReset(); + mockedEnv.isBrowserEnvValue = false; + mockedEnv.isBrowserEnv.mockClear(); + mockedEnv.isReactNativeEnv.mockReset(); }); test('should return url with getPublicPath', () => { @@ -34,7 +45,7 @@ describe('getResourceUrl', () => { test('should return url with publicPath in browser or RN env', () => { const publicPath = 'https://public.com/'; module = { publicPath } as ModuleInfo; - (isBrowserEnv as jest.Mock).mockReturnValue(true); + mockedEnv.isBrowserEnvValue = true; const result = getResourceUrl(module, sourceUrl); expect(result).toBe('https://public.com/test.js'); }); @@ -43,8 +54,8 @@ describe('getResourceUrl', () => { const publicPath = 'https://public.com/'; const ssrPublicPath = 'https://ssr.com/'; module = { publicPath, ssrPublicPath } as ModuleInfo; - (isBrowserEnv as jest.Mock).mockReturnValue(false); - (isReactNativeEnv as jest.Mock).mockReturnValue(false); + mockedEnv.isBrowserEnvValue = false; + mockedEnv.isReactNativeEnv.mockReturnValue(false); const result = getResourceUrl(module, sourceUrl); expect(result).toBe('https://ssr.com/test.js'); }); @@ -52,8 +63,8 @@ describe('getResourceUrl', () => { test('should fallback to publicPath when ssrPublicPath is undefined', () => { const publicPath = 'https://public.com/'; module = { publicPath, ssrPublicPath: undefined } as ModuleInfo; - (isBrowserEnv as jest.Mock).mockReturnValue(false); - (isReactNativeEnv as jest.Mock).mockReturnValue(false); + mockedEnv.isBrowserEnv.mockReturnValue(false); + mockedEnv.isReactNativeEnv.mockReturnValue(false); const result = getResourceUrl(module, sourceUrl); expect(result).toBe('https://public.com/test.js'); }); diff --git a/packages/sdk/src/env.ts b/packages/sdk/src/env.ts index bb054e58a61..b8f21069b13 100644 --- a/packages/sdk/src/env.ts +++ b/packages/sdk/src/env.ts @@ -5,10 +5,18 @@ declare global { var FEDERATION_DEBUG: string | undefined; } +// Declare the ENV_TARGET constant that will be defined by DefinePlugin +declare const ENV_TARGET: 'web' | 'node'; + +const detectBrowserEnv = () => + typeof ENV_TARGET !== 'undefined' + ? ENV_TARGET === 'web' + : typeof window !== 'undefined' && typeof window.document !== 'undefined'; + +const isBrowserEnvValue = detectBrowserEnv(); + function isBrowserEnv(): boolean { - return ( - typeof window !== 'undefined' && typeof window.document !== 'undefined' - ); + return detectBrowserEnv(); } function isReactNativeEnv(): boolean { @@ -48,4 +56,10 @@ const getProcessEnv = function (): Record { return typeof process !== 'undefined' && process.env ? process.env : {}; }; -export { isBrowserEnv, isReactNativeEnv, isDebugMode, getProcessEnv }; +export { + isBrowserEnv, + isBrowserEnvValue, + isReactNativeEnv, + isDebugMode, + getProcessEnv, +}; From 634d0a7878c67f9121ad428aa274990745f688a5 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 00:17:54 -0700 Subject: [PATCH 03/10] chore(codex): add local ci skill --- .codex/skills/local-ci/SKILL.md | 103 ++++++++++++++++++++++ .codex/skills/local-ci/agents/openai.yaml | 4 + .codex/skills/local-ci/references/jobs.md | 75 ++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 .codex/skills/local-ci/SKILL.md create mode 100644 .codex/skills/local-ci/agents/openai.yaml create mode 100644 .codex/skills/local-ci/references/jobs.md diff --git a/.codex/skills/local-ci/SKILL.md b/.codex/skills/local-ci/SKILL.md new file mode 100644 index 00000000000..556a34b8f2a --- /dev/null +++ b/.codex/skills/local-ci/SKILL.md @@ -0,0 +1,103 @@ +--- +name: local-ci +description: Run this repository's local CI parity commands and `pnpm run ci:local` jobs. Use when validating a change against the same job shapes used in GitHub Actions, choosing the smallest local CI job for a package, workflow, E2E, Metro, devtools, bundle-size, or build-and-test change. +--- + +# Local CI + +Use the local CI runner and Turbo/package scripts as the source of truth for validation in this repo. + +## Quick Start + +1. Start with the smallest deterministic check that matches the change. +2. Prefer `pnpm run ci:local --only=` for CI-parity validation. +3. Prefer direct Turbo or package scripts only when they are the smaller equivalent of the CI job. +4. Report exactly which command ran, what failed first, and which expected checks were skipped. + +## Workflow + +### 1. Inspect available local CI jobs + +Run: + +```bash +pnpm run ci:local --list +``` + +Use this when the right job is unclear or when the repo may have added or renamed jobs. + +For the current job map, read [references/jobs.md](./references/jobs.md). + +### 2. Pick the smallest matching job + +Use these defaults: + +- Package code in `packages/*`: start with `build-and-test` only if the change is broad; otherwise prefer package build/test commands. +- Metro packages or Metro workflow changes: use `build-metro`, then Metro E2E jobs only if relevant. +- E2E app changes: run the matching `e2e-*` job instead of `build-and-test`. +- Devtools workflow or Playwright/devtools changes: run `devtools`. +- Bundle-size workflow/reporting changes: run `bundle-size`. +- GitHub workflow syntax only: use `actionlint` locally only to see skip behavior; the actual action is CI-only. +- Broad CI, packaging, publint, Turbo, or shared runtime changes: run `build-and-test`. + +### 3. Run commands in CI order + +When reproducing CI, use the same command shape as the repo: + +```bash +pnpm run ci:local --only=build-and-test +pnpm run ci:local --only=devtools +pnpm run ci:local --only=e2e-runtime +``` + +To run more than one job: + +```bash +pnpm run ci:local --only=build-and-test,bundle-size +``` + +### 4. Interpret failures correctly + +- Treat the first failing step as the actionable failure. +- Ignore known noisy warnings unless they exit non-zero. +- Distinguish repo-wide drift from changed-file gates. +- If `ci:local` fails in `Check code format`, inspect the changed-file formatter result before running broader builds. +- If a dependency build outside the touched scope fails, note it separately as an unrelated blocker. + +## Common Cases + +### Broad package or runtime/plugin change + +Run: + +```bash +pnpm run ci:local --only=build-and-test +``` + +If that fails on format first, fix the changed files before rerunning the whole job. + +### One package only + +Prefer the smaller direct command first: + +```bash +pnpm exec turbo run build --filter=@module-federation/ +pnpm exec turbo run test --filter=@module-federation/ --force +``` + +Then run `build-and-test` only if the user asks for CI parity or the package change affects shared build/runtime behavior. + +### E2E change + +Run the matching job from [references/jobs.md](./references/jobs.md), not the whole matrix. + +### Workflow change + +Use the local CI job if one exists for the workflow's behavior. For workflow syntax, pair local validation with the repo's actionlint path when relevant. + +## Notes + +- `ci:local` sets `CI=true` and mirrors the repo workflow order. +- Some jobs intentionally skip GitHub-only actions such as `actionlint` and `bundle-size-comment`. +- The repo uses `pnpm`, Node 20, and Turbo as the standard execution path. +- In worktrees, still use Turbo/package scripts directly as documented by the repo instructions. diff --git a/.codex/skills/local-ci/agents/openai.yaml b/.codex/skills/local-ci/agents/openai.yaml new file mode 100644 index 00000000000..6cef9338c93 --- /dev/null +++ b/.codex/skills/local-ci/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Local CI" + short_description: "Run repo CI parity jobs locally" + default_prompt: "Use $local-ci to choose and run the smallest local CI parity command for this repo change." diff --git a/.codex/skills/local-ci/references/jobs.md b/.codex/skills/local-ci/references/jobs.md new file mode 100644 index 00000000000..29a9f767cd4 --- /dev/null +++ b/.codex/skills/local-ci/references/jobs.md @@ -0,0 +1,75 @@ +# Local CI job map + +Use `pnpm run ci:local --list` if you need to refresh this list from the repo. + +## Core jobs + +- `build-and-test` + - Full package-oriented CI parity job. + - Includes install, Cypress install, changed-file format check, Turbo/publint verification, package build, and affected package tests. + - Use for shared runtime, plugin, CI, packaging, publint, or broad package changes. + +- `build-metro` + - Metro-specific parity job. + - Use for `packages/metro*` and related Metro workflow changes. + +- `bundle-size` + - Bundle-size measurement workflow parity. + - Use for bundle-size collection or reporting logic. + +- `devtools` + - Devtools workflow parity job. + - Use for `packages/chrome-devtools`, Playwright/devtools setup, and devtools workflow changes. + +## E2E jobs + +- `e2e-modern` +- `e2e-runtime` +- `e2e-manifest` +- `e2e-node` +- `e2e-next-dev` +- `e2e-next-prod` +- `e2e-treeshake` +- `e2e-modern-ssr` +- `e2e-router` +- `metro-affected-check` +- `metro-android-e2e` +- `metro-ios-e2e` +- `e2e-shared-tree-shaking` + +Use the smallest job that matches the app/runtime surface you changed. + +## CI-only local skips + +- `actionlint` + - Listed for parity, but skipped because the GitHub-only action does not fully execute locally. + +- `bundle-size-comment` + - Listed for parity, but skipped locally because it depends on GitHub workflow-run artifacts. + +## Helpful commands + +List jobs: + +```bash +pnpm run ci:local --list +``` + +Run one job: + +```bash +pnpm run ci:local --only=build-and-test +``` + +Run multiple jobs: + +```bash +pnpm run ci:local --only=build-and-test,bundle-size +``` + +Run a smaller non-`ci:local` package check: + +```bash +pnpm exec turbo run build --filter=@module-federation/ +pnpm exec turbo run test --filter=@module-federation/ --force +``` From 018088822786cf24085db848cb9843dcca0c8b21 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 00:20:58 -0700 Subject: [PATCH 04/10] chore(codex): format local ci skill metadata --- .codex/skills/local-ci/agents/openai.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.codex/skills/local-ci/agents/openai.yaml b/.codex/skills/local-ci/agents/openai.yaml index 6cef9338c93..ff61100bfd2 100644 --- a/.codex/skills/local-ci/agents/openai.yaml +++ b/.codex/skills/local-ci/agents/openai.yaml @@ -1,4 +1,4 @@ interface: - display_name: "Local CI" - short_description: "Run repo CI parity jobs locally" - default_prompt: "Use $local-ci to choose and run the smallest local CI parity command for this repo change." + display_name: 'Local CI' + short_description: 'Run repo CI parity jobs locally' + default_prompt: 'Use $local-ci to choose and run the smallest local CI parity command for this repo change.' From 45cc382d39089174d1ff8330e72e0ee289d05d5c Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 16:42:23 -0700 Subject: [PATCH 05/10] fix(ci): improve bundle size reporting --- scripts/bundle-size-report.mjs | 711 +++++++++++++++++++++++++++++---- 1 file changed, 636 insertions(+), 75 deletions(-) diff --git a/scripts/bundle-size-report.mjs b/scripts/bundle-size-report.mjs index dc75de32537..41ef8d00947 100755 --- a/scripts/bundle-size-report.mjs +++ b/scripts/bundle-size-report.mjs @@ -5,8 +5,9 @@ // Compare: node scripts/bundle-size-report.mjs --compare base.json --current current.json --output stats.txt // Output includes: // - package dist total (raw) -// - ESM entry gzip -// - web/node bundles (gzip, ENV_TARGET=web/node) +// - root ESM entry gzip +// - web/node bundles for the root entry (gzip, ENV_TARGET=web/node) +// - tracked tree-shakable subpath entries like ./bundler import { readFileSync, @@ -17,10 +18,12 @@ import { mkdirSync, } from 'fs'; import { join, resolve, relative, extname } from 'path'; +import { createRequire } from 'module'; import { tmpdir } from 'os'; import { gzipSync } from 'zlib'; const ROOT = resolve(import.meta.dirname, '..'); +const require = createRequire(import.meta.url); // ── Helpers ────────────────────────────────────────────────────────────────── @@ -71,6 +74,7 @@ function formatDeltaMaybe(current, base) { } let rslibPromise; +let webpackPromise; const ASSET_RULES = [ { test: /\.(css|scss|sass|less|styl)$/i, type: 'asset/resource' }, @@ -81,6 +85,7 @@ const ASSET_RULES = [ ]; const JS_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']); +const TRACKED_EXPORT_SUBPATHS = ['./bundler']; async function loadRslib() { if (!rslibPromise) { @@ -89,6 +94,13 @@ async function loadRslib() { return rslibPromise; } +async function loadWebpack() { + if (!webpackPromise) { + webpackPromise = Promise.resolve(require('webpack')); + } + return webpackPromise; +} + /** Recursively sum all file sizes in a directory, excluding .map files */ function dirSize(dir) { let total = 0; @@ -154,6 +166,73 @@ function findEsmEntry(pkgDir, pkg) { return null; } +function resolveExportTarget(pkgDir, target) { + if (!target) return null; + + if (typeof target === 'string') { + const resolved = join(pkgDir, target); + return existsSync(resolved) ? resolved : null; + } + + if (typeof target !== 'object') { + return null; + } + + const preferredKeys = [ + 'import', + 'default', + 'module', + 'browser', + 'node', + 'require', + ]; + for (const key of preferredKeys) { + if (!(key in target)) continue; + const resolved = resolveExportTarget(pkgDir, target[key]); + if (resolved) return resolved; + } + + for (const value of Object.values(target)) { + const resolved = resolveExportTarget(pkgDir, value); + if (resolved) return resolved; + } + + return null; +} + +function findTrackedEntries(pkgDir, pkg) { + const entries = []; + const rootEntry = findEsmEntry(pkgDir, pkg); + + if (rootEntry) { + entries.push({ + id: '.', + label: 'Package root', + path: rootEntry, + }); + } + + if (!pkg?.exports || typeof pkg.exports !== 'object') { + return entries; + } + + for (const subpath of TRACKED_EXPORT_SUBPATHS) { + if (!(subpath in pkg.exports)) continue; + + const resolved = resolveExportTarget(pkgDir, pkg.exports[subpath]); + if (!resolved) continue; + if (entries.some((entry) => entry.path === resolved)) continue; + + entries.push({ + id: subpath, + label: `${subpath} export`, + path: resolved, + }); + } + + return entries; +} + function createTempDir(pkgName, target) { const stamp = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; const dir = join(tmpdir(), 'mf-bundle-size', pkgName, target, stamp); @@ -278,6 +357,231 @@ async function bundleEntry(entryPath, options) { } } +async function measureEntry(entry, pkgName, pkgDir) { + const entryGzip = gzipSize(entry.path); + const [webResult, nodeResult] = await Promise.all([ + bundleEntry(entry.path, { + target: 'web', + packageName: pkgName, + entryName: entry.id === '.' ? 'bundle' : sanitizeEntryId(entry.id), + define: { ENV_TARGET: JSON.stringify('web') }, + }), + bundleEntry(entry.path, { + target: 'node', + packageName: pkgName, + entryName: entry.id === '.' ? 'bundle' : sanitizeEntryId(entry.id), + define: { ENV_TARGET: JSON.stringify('node') }, + }), + ]); + + const bundleErrors = {}; + if (webResult.error) bundleErrors.web = webResult.error; + if (nodeResult.error) bundleErrors.node = nodeResult.error; + + return { + label: entry.label, + entry: relative(pkgDir, entry.path), + gzip: entryGzip, + webBundleBytes: webResult.bytes, + webBundleGzip: webResult.gzip, + nodeBundleBytes: nodeResult.bytes, + nodeBundleGzip: nodeResult.gzip, + bundleErrors: Object.keys(bundleErrors).length ? bundleErrors : null, + }; +} + +function sanitizeEntryId(entryId) { + return ( + entryId.replace(/[^a-z0-9]+/gi, '-').replace(/^-+|-+$/g, '') || 'entry' + ); +} + +function findPackage(packages, name) { + return packages.find((pkg) => pkg.name === name) || null; +} + +function createScenarioResult(label, data) { + return { + label, + webBytes: data.webBytes ?? null, + webGzip: data.webGzip ?? null, + nodeBytes: data.nodeBytes ?? null, + nodeGzip: data.nodeGzip ?? null, + details: data.details ?? null, + errors: data.errors ?? null, + }; +} + +async function runWebpackBuild(config) { + const webpack = await loadWebpack(); + const compiler = webpack(config); + + return new Promise((resolveBuild, rejectBuild) => { + compiler.run((error, stats) => { + const done = (closeError) => { + if (error) { + rejectBuild(error); + return; + } + if (closeError) { + rejectBuild(closeError); + return; + } + if (!stats) { + rejectBuild(new Error('webpack returned no stats')); + return; + } + if (stats.hasErrors()) { + rejectBuild( + new Error( + stats.toString({ + all: false, + errors: true, + errorDetails: true, + }), + ), + ); + return; + } + resolveBuild(stats); + }; + + if (typeof compiler.close === 'function') { + compiler.close(done); + } else { + done(); + } + }); + }); +} + +async function measureEnhancedRemoteScenario(packagesDir, packages) { + const enhancedPkg = findPackage(packages, '@module-federation/enhanced'); + if (!enhancedPkg) { + return createScenarioResult('Enhanced remoteEntry', { + errors: { scenario: 'package not found' }, + }); + } + + const enhancedEntry = join(enhancedPkg.dir, 'dist/src/index.js'); + if (!existsSync(enhancedEntry)) { + return createScenarioResult('Enhanced remoteEntry', { + errors: { scenario: 'built enhanced entry not found' }, + }); + } + + const { ModuleFederationPlugin } = require(enhancedEntry); + const scenarioRoot = createTempDir('scenario-enhanced-remote', 'matrix'); + const entryPath = join(scenarioRoot, 'index.js'); + const exposePath = join(scenarioRoot, 'noop.js'); + writeFileSync(entryPath, 'module.exports = 1;\n', 'utf8'); + writeFileSync(exposePath, 'module.exports = () => "noop";\n', 'utf8'); + + const buildTarget = async ({ + optimizationTarget, + disableSnapshot, + suffix, + }) => { + const outputPath = join(scenarioRoot, `dist-${suffix}`); + mkdirSync(outputPath, { recursive: true }); + const filename = `remoteEntry-${suffix}.js`; + + await runWebpackBuild({ + mode: 'production', + context: scenarioRoot, + entry: './index.js', + target: 'async-node', + infrastructureLogging: { level: 'error' }, + stats: 'errors-only', + output: { + path: outputPath, + filename: '[name].js', + chunkFilename: '[name].js', + publicPath: '/', + uniqueName: `bundle-size-enhanced-${suffix}`, + clean: true, + }, + optimization: { + minimize: true, + chunkIds: 'named', + moduleIds: 'named', + }, + plugins: [ + new ModuleFederationPlugin({ + name: `bundle_size_${suffix}`, + filename, + library: { + type: 'commonjs-module', + name: `bundle_size_${suffix}`, + }, + exposes: { + './noop': './noop.js', + }, + remotes: { + remote: 'remote@http://localhost:3001/remoteEntry.js', + }, + manifest: false, + experiments: { + optimization: { + target: optimizationTarget, + disableSnapshot, + }, + }, + }), + ], + }); + + const outputFile = join(outputPath, filename); + return { + bytes: statSync(outputFile).size, + gzip: gzipSize(outputFile), + file: outputFile, + }; + }; + + try { + const [webResult, nodeResult] = await Promise.all([ + buildTarget({ + optimizationTarget: 'web', + disableSnapshot: true, + suffix: 'web', + }), + buildTarget({ + optimizationTarget: 'node', + disableSnapshot: false, + suffix: 'node', + }), + ]); + + return createScenarioResult('Enhanced remoteEntry', { + webBytes: webResult.bytes, + webGzip: webResult.gzip, + nodeBytes: nodeResult.bytes, + nodeGzip: nodeResult.gzip, + details: { + webFile: relative(ROOT, webResult.file), + nodeFile: relative(ROOT, nodeResult.file), + packagesDir: relative(ROOT, packagesDir), + }, + }); + } catch (error) { + return createScenarioResult('Enhanced remoteEntry', { + errors: { + scenario: error?.message ? error.message : String(error), + }, + }); + } +} + +async function measureScenarios(packagesDir, packages) { + const scenarios = {}; + scenarios.enhancedRemoteEntry = await measureEnhancedRemoteScenario( + packagesDir, + packages, + ); + return scenarios; +} + // ── Discovery ──────────────────────────────────────────────────────────────── /** Find package directories from workspace package manifests */ @@ -332,59 +636,75 @@ async function measure(packagesDir) { const pkgJson = readPackageJson(pkg.dir); const distDir = join(pkg.dir, 'dist'); const totalSize = dirSize(distDir); - const esmEntry = findEsmEntry(pkg.dir, pkgJson); - const esmGzip = gzipSize(esmEntry); - let webBundle = { bytes: null, gzip: null }; - let nodeBundle = { bytes: null, gzip: null }; - const bundleErrors = {}; - - if (esmEntry) { - const [webResult, nodeResult] = await Promise.all([ - bundleEntry(esmEntry, { - target: 'web', - packageName: pkg.name, - entryName: 'bundle', - define: { ENV_TARGET: JSON.stringify('web') }, - }), - bundleEntry(esmEntry, { - target: 'node', - packageName: pkg.name, - entryName: 'bundle', - define: { ENV_TARGET: JSON.stringify('node') }, - }), - ]); + const measuredEntries = findTrackedEntries(pkg.dir, pkgJson); + const entrypoints = {}; - webBundle = webResult; - nodeBundle = nodeResult; - - if (webResult.error) bundleErrors.web = webResult.error; - if (nodeResult.error) bundleErrors.node = nodeResult.error; + for (const entry of measuredEntries) { + entrypoints[entry.id] = await measureEntry(entry, pkg.name, pkg.dir); } + const rootMetrics = entrypoints['.'] || { + entry: null, + gzip: 0, + webBundleBytes: null, + webBundleGzip: null, + nodeBundleBytes: null, + nodeBundleGzip: null, + bundleErrors: null, + }; + results[pkg.name] = { totalDist: totalSize, - esmGzip, - esmEntry: esmEntry ? relative(pkg.dir, esmEntry) : null, - webBundleBytes: webBundle.bytes, - webBundleGzip: webBundle.gzip, - nodeBundleBytes: nodeBundle.bytes, - nodeBundleGzip: nodeBundle.gzip, - bundleEntry: esmEntry ? relative(pkg.dir, esmEntry) : null, - bundleErrors: Object.keys(bundleErrors).length ? bundleErrors : null, + esmGzip: rootMetrics.gzip, + esmEntry: rootMetrics.entry, + webBundleBytes: rootMetrics.webBundleBytes, + webBundleGzip: rootMetrics.webBundleGzip, + nodeBundleBytes: rootMetrics.nodeBundleBytes, + nodeBundleGzip: rootMetrics.nodeBundleGzip, + bundleEntry: rootMetrics.entry, + bundleErrors: rootMetrics.bundleErrors, + entrypoints, }; } - return results; + return { + packages: results, + scenarios: await measureScenarios(packagesDir, packages), + }; } // ── Compare ────────────────────────────────────────────────────────────────── +function normalizeMeasuredData(data) { + if ( + data && + typeof data === 'object' && + 'packages' in data && + 'scenarios' in data + ) { + return { + packages: data.packages || {}, + scenarios: data.scenarios || {}, + }; + } + + return { + packages: data || {}, + scenarios: {}, + }; +} + function compare(baseData, currentData) { + const normalizedBase = normalizeMeasuredData(baseData); + const normalizedCurrent = normalizeMeasuredData(currentData); + const basePackages = normalizedBase.packages; + const currentPackages = normalizedCurrent.packages; + const baseScenarios = normalizedBase.scenarios; + const currentScenarios = normalizedCurrent.scenarios; const allPackages = new Set([ - ...Object.keys(baseData), - ...Object.keys(currentData), + ...Object.keys(basePackages), + ...Object.keys(currentPackages), ]); - const changed = []; let unchangedCount = 0; const emptyPackageMetrics = { totalDist: 0, @@ -404,44 +724,133 @@ function compare(baseData, currentData) { ]; const allMetrics = [...distMetrics, ...bundleMetrics]; - - for (const name of [...allPackages].sort()) { - const base = baseData[name] || emptyPackageMetrics; - const current = currentData[name] || emptyPackageMetrics; - - const hasChange = allMetrics.some(({ key }) => { - const baseValue = base[key]; - const currentValue = current[key]; + const changedRootRows = []; + const changedEntrypointRows = []; + const changedPackages = new Set(); + + const hasMetricChange = (base, current, metrics) => + metrics.some(({ key }) => { + const baseValue = base?.[key]; + const currentValue = current?.[key]; if (typeof baseValue === 'number' && typeof currentValue === 'number') { return baseValue !== currentValue; } return typeof baseValue === 'number' || typeof currentValue === 'number'; }); - if (hasChange) { - changed.push({ name, base, current }); - } else { - unchangedCount++; + const getEntrypoints = (pkg) => { + const entrypoints = { ...(pkg?.entrypoints || {}) }; + if (!entrypoints['.']) { + entrypoints['.'] = { + label: 'Package root', + entry: pkg?.bundleEntry ?? pkg?.esmEntry ?? null, + gzip: pkg?.esmGzip ?? 0, + webBundleBytes: pkg?.webBundleBytes ?? null, + webBundleGzip: pkg?.webBundleGzip ?? null, + nodeBundleBytes: pkg?.nodeBundleBytes ?? null, + nodeBundleGzip: pkg?.nodeBundleGzip ?? null, + bundleErrors: pkg?.bundleErrors ?? null, + }; + } + return entrypoints; + }; + + for (const name of [...allPackages].sort()) { + const base = basePackages[name] || emptyPackageMetrics; + const current = currentPackages[name] || emptyPackageMetrics; + const baseEntrypoints = getEntrypoints(base); + const currentEntrypoints = getEntrypoints(current); + + if (hasMetricChange(base, current, allMetrics)) { + changedRootRows.push({ name, base, current }); + changedPackages.add(name); + } + + const trackedEntrypoints = new Set([ + ...Object.keys(baseEntrypoints), + ...Object.keys(currentEntrypoints), + ]); + trackedEntrypoints.delete('.'); + + for (const entryId of [...trackedEntrypoints].sort()) { + const baseEntry = baseEntrypoints[entryId] || {}; + const currentEntry = currentEntrypoints[entryId] || {}; + const entryMetrics = [ + { key: 'gzip' }, + { key: 'webBundleGzip' }, + { key: 'nodeBundleGzip' }, + ]; + + if (!hasMetricChange(baseEntry, currentEntry, entryMetrics)) { + continue; + } + + changedEntrypointRows.push({ + name, + entryId, + base: baseEntry, + current: currentEntry, + }); + changedPackages.add(name); } } + const changed = [...changedPackages].sort(); + unchangedCount = allPackages.size - changed.length; + const sumMetric = (data, key) => Object.values(data).reduce((sum, item) => { const value = item?.[key]; return typeof value === 'number' ? sum + value : sum; }, 0); - const totalDistBase = sumMetric(baseData, 'totalDist'); - const totalDistCurrent = sumMetric(currentData, 'totalDist'); - const totalEsmBase = sumMetric(baseData, 'esmGzip'); - const totalEsmCurrent = sumMetric(currentData, 'esmGzip'); - const totalWebBase = sumMetric(baseData, 'webBundleGzip'); - const totalWebCurrent = sumMetric(currentData, 'webBundleGzip'); - const totalNodeBase = sumMetric(baseData, 'nodeBundleGzip'); - const totalNodeCurrent = sumMetric(currentData, 'nodeBundleGzip'); - - const buildTable = (title, metrics) => { - if (changed.length === 0) return []; + const sumEntrypointMetric = (data, entryId, key) => + Object.values(data).reduce((sum, item) => { + const value = item?.entrypoints?.[entryId]?.[key]; + return typeof value === 'number' ? sum + value : sum; + }, 0); + + const totalDistBase = sumMetric(basePackages, 'totalDist'); + const totalDistCurrent = sumMetric(currentPackages, 'totalDist'); + const totalEsmBase = sumMetric(basePackages, 'esmGzip'); + const totalEsmCurrent = sumMetric(currentPackages, 'esmGzip'); + const totalWebBase = sumMetric(basePackages, 'webBundleGzip'); + const totalWebCurrent = sumMetric(currentPackages, 'webBundleGzip'); + const totalNodeBase = sumMetric(basePackages, 'nodeBundleGzip'); + const totalNodeCurrent = sumMetric(currentPackages, 'nodeBundleGzip'); + const totalBundlerEntryBase = sumEntrypointMetric( + basePackages, + './bundler', + 'gzip', + ); + const totalBundlerEntryCurrent = sumEntrypointMetric( + currentPackages, + './bundler', + 'gzip', + ); + const totalBundlerWebBase = sumEntrypointMetric( + basePackages, + './bundler', + 'webBundleGzip', + ); + const totalBundlerWebCurrent = sumEntrypointMetric( + currentPackages, + './bundler', + 'webBundleGzip', + ); + const totalBundlerNodeBase = sumEntrypointMetric( + basePackages, + './bundler', + 'nodeBundleGzip', + ); + const totalBundlerNodeCurrent = sumEntrypointMetric( + currentPackages, + './bundler', + 'nodeBundleGzip', + ); + + const buildTable = (title, metrics, rowsData) => { + if (rowsData.length === 0) return []; const rows = []; rows.push(`### ${title}`); rows.push(''); @@ -453,7 +862,7 @@ function compare(baseData, currentData) { rows.push(`| ${headers.join(' | ')} |`); rows.push(`| ${headers.map(() => '---').join(' | ')} |`); - for (const { name, base, current } of changed) { + for (const { name, base, current } of rowsData) { const cells = [`\`${name}\``]; for (const metric of metrics) { const currentValue = current[metric.key]; @@ -470,6 +879,94 @@ function compare(baseData, currentData) { return rows; }; + const formatSignedBytes = (bytes) => { + if (typeof bytes !== 'number' || bytes === 0) return '0 B'; + return `${bytes > 0 ? '+' : '-'}${formatBytes(Math.abs(bytes))}`; + }; + + const buildEntrypointTable = () => { + if (changedEntrypointRows.length === 0) return []; + + const rows = []; + rows.push('### Tree-shakable entrypoints'); + rows.push(''); + rows.push( + '| Package | Export | Entry gzip | Delta | Web bundle (gzip) | Delta | Node bundle (gzip) | Delta | Gap (node-web) | Delta |', + ); + rows.push('| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |'); + + for (const { name, entryId, base, current } of changedEntrypointRows) { + const currentGap = + typeof current.nodeBundleGzip === 'number' && + typeof current.webBundleGzip === 'number' + ? current.nodeBundleGzip - current.webBundleGzip + : null; + const baseGap = + typeof base.nodeBundleGzip === 'number' && + typeof base.webBundleGzip === 'number' + ? base.nodeBundleGzip - base.webBundleGzip + : null; + + rows.push( + [ + `\`${name}\``, + `\`${entryId}\``, + formatMaybe(current.gzip), + formatDeltaMaybe(current.gzip, base.gzip), + formatMaybe(current.webBundleGzip), + formatDeltaMaybe(current.webBundleGzip, base.webBundleGzip), + formatMaybe(current.nodeBundleGzip), + formatDeltaMaybe(current.nodeBundleGzip, base.nodeBundleGzip), + currentGap === null ? 'n/a' : formatSignedBytes(currentGap), + currentGap === null || baseGap === null + ? 'n/a' + : formatSignedBytes(currentGap - baseGap), + ].join(' | '), + ); + rows[rows.length - 1] = `| ${rows[rows.length - 1]} |`; + } + + rows.push(''); + return rows; + }; + + const buildScenarioTable = () => { + const scenarioNames = new Set([ + ...Object.keys(baseScenarios), + ...Object.keys(currentScenarios), + ]); + if (scenarioNames.size === 0) return []; + + const rows = []; + rows.push('### Consumer scenarios'); + rows.push(''); + rows.push( + '| Scenario | Web output (gzip) | Delta | Node output (gzip) | Delta | Gap (node-web) | Delta |', + ); + rows.push('| --- | --- | --- | --- | --- | --- | --- |'); + + for (const name of [...scenarioNames].sort()) { + const base = baseScenarios[name] || {}; + const current = currentScenarios[name] || {}; + const currentGap = + typeof current.nodeGzip === 'number' && + typeof current.webGzip === 'number' + ? current.nodeGzip - current.webGzip + : null; + const baseGap = + typeof base.nodeGzip === 'number' && typeof base.webGzip === 'number' + ? base.nodeGzip - base.webGzip + : null; + + rows.push( + `| ${current.label || base.label || `\`${name}\``} | ${formatMaybe(current.webGzip)} | ${formatDeltaMaybe(current.webGzip, base.webGzip)} | ${formatMaybe(current.nodeGzip)} | ${formatDeltaMaybe(current.nodeGzip, base.nodeGzip)} | ${currentGap === null ? 'n/a' : formatSignedBytes(currentGap)} | ${currentGap === null || baseGap === null ? 'n/a' : formatSignedBytes(currentGap - baseGap)} |`, + ); + } + + rows.push(''); + return rows; + }; + // Build markdown const lines = []; lines.push('## Bundle Size Report'); @@ -485,8 +982,12 @@ function compare(baseData, currentData) { lines.push(''); } - lines.push(...buildTable('Package dist + ESM entry', distMetrics)); - lines.push(...buildTable('Bundle targets', bundleMetrics)); + lines.push( + ...buildTable('Package dist + ESM entry', distMetrics, changedRootRows), + ); + lines.push(...buildTable('Bundle targets', bundleMetrics, changedRootRows)); + lines.push(...buildEntrypointTable()); + lines.push(...buildScenarioTable()); lines.push( `**Total dist (raw):** ${formatBytes(totalDistCurrent)} (${formatDelta(totalDistCurrent, totalDistBase)})`, @@ -500,22 +1001,65 @@ function compare(baseData, currentData) { lines.push( `**Total node bundle (gzip):** ${formatBytes(totalNodeCurrent)} (${formatDelta(totalNodeCurrent, totalNodeBase)})`, ); + if ( + totalBundlerEntryBase > 0 || + totalBundlerEntryCurrent > 0 || + totalBundlerWebBase > 0 || + totalBundlerWebCurrent > 0 || + totalBundlerNodeBase > 0 || + totalBundlerNodeCurrent > 0 + ) { + lines.push( + `**Tracked ./bundler entry gzip:** ${formatBytes(totalBundlerEntryCurrent)} (${formatDelta(totalBundlerEntryCurrent, totalBundlerEntryBase)})`, + ); + lines.push( + `**Tracked ./bundler web bundle (gzip):** ${formatBytes(totalBundlerWebCurrent)} (${formatDelta(totalBundlerWebCurrent, totalBundlerWebBase)})`, + ); + lines.push( + `**Tracked ./bundler node bundle (gzip):** ${formatBytes(totalBundlerNodeCurrent)} (${formatDelta(totalBundlerNodeCurrent, totalBundlerNodeBase)})`, + ); + } lines.push(''); lines.push( - '_Bundle sizes are generated with rslib (Rspack). Web/node bundles set ENV_TARGET and enable tree-shaking. Bare imports are externalized to keep sizes consistent with prior reporting, and assets are emitted as resources._', + '_Bundle sizes are generated with rslib (Rspack). Package-root metrics preserve the historical report. Tracked subpath exports such as `./bundler` are measured separately so ENV_TARGET-driven tree-shaking is visible. Bare imports are externalized to keep package-level sizes consistent, and assets are emitted as resources._', ); lines.push(''); - const errored = Object.entries(currentData).filter( - ([, data]) => data?.bundleErrors, - ); + const errored = []; + for (const [name, data] of Object.entries(currentPackages)) { + const entrypoints = getEntrypoints(data); + for (const [entryId, entry] of Object.entries(entrypoints)) { + if (!entry?.bundleErrors) continue; + errored.push({ + name, + entryId, + bundleErrors: entry.bundleErrors, + }); + } + } + if (errored.length) { lines.push('### Bundle errors'); - for (const [name, data] of errored) { - const parts = Object.entries(data.bundleErrors).map( + for (const item of errored) { + const parts = Object.entries(item.bundleErrors).map( + ([target, error]) => `${target}: ${error}`, + ); + const entryLabel = item.entryId === '.' ? '' : ` ${item.entryId}`; + lines.push(`- \`${item.name}${entryLabel}\`: ${parts.join('; ')}`); + } + lines.push(''); + } + + const erroredScenarios = Object.values(currentScenarios).filter( + (scenario) => scenario?.errors, + ); + if (erroredScenarios.length) { + lines.push('### Scenario errors'); + for (const scenario of erroredScenarios) { + const parts = Object.entries(scenario.errors).map( ([target, error]) => `${target}: ${error}`, ); - lines.push(`- \`${name}\`: ${parts.join('; ')}`); + lines.push(`- ${scenario.label || 'Scenario'}: ${parts.join('; ')}`); } lines.push(''); } @@ -557,7 +1101,7 @@ async function main() { console.log(`Scanning packages in ${packagesDir}...`); const results = await measure(packagesDir); - const packageCount = Object.keys(results).length; + const packageCount = Object.keys(results.packages).length; writeFileSync(outputPath, JSON.stringify(results, null, 2), 'utf8'); console.log(`Measured ${packageCount} packages → ${outputPath}`); @@ -567,7 +1111,7 @@ async function main() { let totalEsm = 0; let totalWeb = 0; let totalNode = 0; - for (const [name, data] of Object.entries(results)) { + for (const [name, data] of Object.entries(results.packages)) { totalDist += data.totalDist; totalEsm += data.esmGzip; if (typeof data.webBundleGzip === 'number') @@ -580,6 +1124,23 @@ async function main() { console.log( ` ${name}: dist=${formatBytes(data.totalDist)}, esm-gzip=${formatBytes(data.esmGzip)}, web-gzip=${formatMaybe(data.webBundleGzip)}, node-gzip=${formatMaybe(data.nodeBundleGzip)}${bundleErrorNote}`, ); + for (const [entryId, entry] of Object.entries(data.entrypoints || {})) { + if (entryId === '.') continue; + const entryBundleErrorNote = entry.bundleErrors + ? ` (bundle errors: ${Object.keys(entry.bundleErrors).join(', ')})` + : ''; + console.log( + ` ${entryId}: entry-gzip=${formatMaybe(entry.gzip)}, web-gzip=${formatMaybe(entry.webBundleGzip)}, node-gzip=${formatMaybe(entry.nodeBundleGzip)}${entryBundleErrorNote}`, + ); + } + } + for (const scenario of Object.values(results.scenarios || {})) { + const scenarioErrorNote = scenario.errors + ? ` (errors: ${Object.keys(scenario.errors).join(', ')})` + : ''; + console.log( + ` scenario ${scenario.label}: web-gzip=${formatMaybe(scenario.webGzip)}, node-gzip=${formatMaybe(scenario.nodeGzip)}${scenarioErrorNote}`, + ); } console.log( `Total dist: ${formatBytes(totalDist)}, Total ESM gzip: ${formatBytes(totalEsm)}, Total web gzip: ${formatBytes(totalWeb)}, Total node gzip: ${formatBytes(totalNode)}`, From a07016a09100f0e86da0c3ad4147eaca319d9606 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 17:19:29 -0700 Subject: [PATCH 06/10] fix(assemble-release-plan): restore source entry file --- packages/assemble-release-plan/src/index.ts | 657 ++++---------------- 1 file changed, 124 insertions(+), 533 deletions(-) diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index 1aaaee42ce2..2eafb119178 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -1,475 +1,29 @@ import { InternalError } from '@changesets/errors'; import { getDependentsGraph } from '@changesets/get-dependents-graph'; import { shouldSkipPackage } from '@changesets/should-skip-package'; +import { + Config, + NewChangeset, + PackageGroup, + PreState, + ReleasePlan, +} from '@changesets/types'; +import { Package, Packages } from '@manypkg/get-packages'; import semverParse from 'semver/functions/parse'; -import semverGt from 'semver/functions/gt'; -import semverSatisfies from 'semver/functions/satisfies'; -import semverInc from 'semver/functions/inc'; - -function _toPrimitive(t, r) { - if ('object' != typeof t || !t) return t; - var e = t[Symbol.toPrimitive]; - if (void 0 !== e) { - var i = e.call(t, r || 'default'); - if ('object' != typeof i) return i; - throw new TypeError('@@toPrimitive must return a primitive value.'); - } - return ('string' === r ? String : Number)(t); -} -function _toPropertyKey(t) { - var i = _toPrimitive(t, 'string'); - return 'symbol' == typeof i ? i : i + ''; -} -function _defineProperty(e, r, t) { - return ( - (r = _toPropertyKey(r)) in e - ? Object.defineProperty(e, r, { - value: t, - enumerable: !0, - configurable: !0, - writable: !0, - }) - : (e[r] = t), - e - ); -} -function ownKeys(e, r) { - var t = Object.keys(e); - if (Object.getOwnPropertySymbols) { - var o = Object.getOwnPropertySymbols(e); - (r && - (o = o.filter(function (r) { - return Object.getOwnPropertyDescriptor(e, r).enumerable; - })), - t.push.apply(t, o)); - } - return t; -} -function _objectSpread2(e) { - for (var r = 1; r < arguments.length; r++) { - var t = null != arguments[r] ? arguments[r] : {}; - r % 2 - ? ownKeys(Object(t), !0).forEach(function (r) { - _defineProperty(e, r, t[r]); - }) - : Object.getOwnPropertyDescriptors - ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) - : ownKeys(Object(t)).forEach(function (r) { - Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); - }); - } - return e; -} -function getHighestReleaseType(releases) { - if (releases.length === 0) { - throw new Error( - `Large internal Changesets error when calculating highest release type in the set of releases. Please contact the maintainers`, - ); - } - let highestReleaseType = 'none'; - for (let release of releases) { - switch (release.type) { - case 'major': - return 'major'; - case 'minor': - highestReleaseType = 'minor'; - break; - case 'patch': - if (highestReleaseType === 'none') { - highestReleaseType = 'patch'; - } - break; - } - } - return highestReleaseType; -} -function getCurrentHighestVersion(packageGroup, packagesByName) { - let highestVersion; - for (let pkgName of packageGroup) { - let pkg = packagesByName.get(pkgName); - if (!pkg) { - console.error( - `FATAL ERROR IN CHANGESETS! We were unable to version for package group: ${pkgName} in package group: ${packageGroup.toString()}`, - ); - throw new Error(`fatal: could not resolve linked packages`); - } - if ( - highestVersion === undefined || - semverGt(pkg.packageJson.version, highestVersion) - ) { - highestVersion = pkg.packageJson.version; - } - } - return highestVersion; -} - -/* - WARNING: - Important note for understanding how this package works: - - We are doing some kind of wacky things with manipulating the objects within the - releases array, despite the fact that this was passed to us as an argument. We are - aware that this is generally bad practice, but have decided to to this here as - we control the entire flow of releases. - - We could solve this by inlining this function, or by returning a deep-cloned then - modified array, but we decided both of those are worse than this solution. -*/ -function applyLinks(releases, packagesByName, linked) { - let updated = false; - - // We do this for each set of linked packages - for (let linkedPackages of linked) { - // First we filter down to all the relevant releases for one set of linked packages - let releasingLinkedPackages = [...releases.values()].filter( - (release) => - linkedPackages.includes(release.name) && release.type !== 'none', - ); - - // If we proceed any further we do extra work with calculating highestVersion for things that might - // not need one, as they only have workspace based packages - if (releasingLinkedPackages.length === 0) continue; - let highestReleaseType = getHighestReleaseType(releasingLinkedPackages); - let highestVersion = getCurrentHighestVersion( - linkedPackages, - packagesByName, - ); - - // Finally, we update the packages so all of them are on the highest version - for (let linkedPackage of releasingLinkedPackages) { - if (linkedPackage.type !== highestReleaseType) { - updated = true; - linkedPackage.type = highestReleaseType; - } - if (linkedPackage.oldVersion !== highestVersion) { - updated = true; - linkedPackage.oldVersion = highestVersion; - } - } - } - return updated; -} -function incrementVersion(release, preInfo) { - if (release.type === 'none') { - return release.oldVersion; - } - let version = semverInc(release.oldVersion, release.type); - if (preInfo !== undefined && preInfo.state.mode !== 'exit') { - let preVersion = preInfo.preVersions.get(release.name); - if (preVersion === undefined) { - throw new InternalError( - `preVersion for ${release.name} does not exist when preState is defined`, - ); - } - // why are we adding this ourselves rather than passing 'pre' + versionType to semver.inc? - // because semver.inc with prereleases is confusing and this seems easier - version += `-${preInfo.state.tag}.${preVersion}`; - } - return version; -} - -/* - WARNING: - Important note for understanding how this package works: - - We are doing some kind of wacky things with manipulating the objects within the - releases array, despite the fact that this was passed to us as an argument. We are - aware that this is generally bad practice, but have decided to to this here as - we control the entire flow of releases. - - We could solve this by inlining this function, or by returning a deep-cloned then - modified array, but we decided both of those are worse than this solution. -*/ -function determineDependents({ - releases, - packagesByName, - dependencyGraph, - preInfo, - config, -}) { - let updated = false; - // NOTE this is intended to be called recursively - let pkgsToSearch = [...releases.values()]; - while (pkgsToSearch.length > 0) { - // nextRelease is our dependency, think of it as "avatar" - const nextRelease = pkgsToSearch.shift(); - if (!nextRelease) continue; - // pkgDependents will be a list of packages that depend on nextRelease ie. ['avatar-group', 'comment'] - const pkgDependents = dependencyGraph.get(nextRelease.name); - if (!pkgDependents) { - throw new Error( - `Error in determining dependents - could not find package in repository: ${nextRelease.name}`, - ); - } - pkgDependents - .map((dependent) => { - let type; - const dependentPackage = packagesByName.get(dependent); - if (!dependentPackage) throw new Error('Dependency map is incorrect'); - if ( - shouldSkipPackage(dependentPackage, { - ignore: config.ignore, - allowPrivatePackages: config.privatePackages.version, - }) - ) { - type = 'none'; - } else { - const dependencyVersionRanges = getDependencyVersionRanges( - dependentPackage.packageJson, - nextRelease, - ); - for (const { depType, versionRange } of dependencyVersionRanges) { - if (nextRelease.type === 'none') { - continue; - } else if ( - shouldBumpMajor({ - dependent, - depType, - versionRange, - releases, - nextRelease, - preInfo, - onlyUpdatePeerDependentsWhenOutOfRange: - config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH - .onlyUpdatePeerDependentsWhenOutOfRange, - }) - ) { - type = 'major'; - } else if ( - (!releases.has(dependent) || - releases.get(dependent).type === 'none') && - (config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH - .updateInternalDependents === 'always' || - !semverSatisfies( - incrementVersion(nextRelease, preInfo), - versionRange, - )) - ) { - switch (depType) { - case 'dependencies': - case 'optionalDependencies': - case 'peerDependencies': - if (type !== 'major' && type !== 'minor') { - type = 'patch'; - } - break; - case 'devDependencies': { - // We don't need a version bump if the package is only in the devDependencies of the dependent package - if ( - type !== 'major' && - type !== 'minor' && - type !== 'patch' - ) { - type = 'none'; - } - } - } - } - } - } - if (releases.has(dependent) && releases.get(dependent).type === type) { - type = undefined; - } - return { - name: dependent, - type, - pkgJSON: dependentPackage.packageJson, - }; - }) - .filter((dependentItem) => !!dependentItem.type) - .forEach(({ name, type, pkgJSON }) => { - // At this point, we know if we are making a change - updated = true; - const existing = releases.get(name); - // For things that are being given a major bump, we check if we have already - // added them here. If we have, we update the existing item instead of pushing it on to search. - // It is safe to not add it to pkgsToSearch because it should have already been searched at the - // largest possible bump type. - - if (existing && type === 'major' && existing.type !== 'major') { - existing.type = 'major'; - pkgsToSearch.push(existing); - } else { - let newDependent = { - name, - type, - oldVersion: pkgJSON.version, - changesets: [], - }; - pkgsToSearch.push(newDependent); - releases.set(name, newDependent); - } - }); - } - return updated; -} - -/* - Returns an array of objects in the shape { depType: DependencyType, versionRange: string } - The array can contain more than one elements in case a dependency appears in multiple - dependency lists. For example, a package that is both a peerDepenency and a devDependency. -*/ -function getDependencyVersionRanges(dependentPkgJSON, dependencyRelease) { - const DEPENDENCY_TYPES = [ - 'dependencies', - 'devDependencies', - 'peerDependencies', - 'optionalDependencies', - ]; - const dependencyVersionRanges = []; - for (const type of DEPENDENCY_TYPES) { - var _dependentPkgJSON$typ; - const versionRange = - (_dependentPkgJSON$typ = dependentPkgJSON[type]) === null || - _dependentPkgJSON$typ === void 0 - ? void 0 - : _dependentPkgJSON$typ[dependencyRelease.name]; - if (!versionRange) continue; - if (versionRange.startsWith('workspace:')) { - dependencyVersionRanges.push({ - depType: type, - versionRange: - // intentionally keep other workspace ranges untouched - // this has to be fixed but this should only be done when adding appropriate tests - versionRange === 'workspace:*' - ? // workspace:* actually means the current exact version, and not a wildcard similar to a reguler * range - dependencyRelease.oldVersion - : versionRange.replace(/^workspace:/, ''), - }); - } else { - dependencyVersionRanges.push({ - depType: type, - versionRange, - }); - } - } - return dependencyVersionRanges; -} -function shouldBumpMajor({ - dependent, - depType, - versionRange, - releases, - nextRelease, - preInfo, - onlyUpdatePeerDependentsWhenOutOfRange, -}) { - //disable major bump due to peer dep - if (depType === 'peerDependencies') { - return false; - } - // we check if it is a peerDependency because if it is, our dependent bump type might need to be major. - return ( - //@ts-ignore - depType === 'peerDependencies' && - nextRelease.type !== 'none' && - nextRelease.type !== 'patch' && - // 1. If onlyUpdatePeerDependentsWhenOutOfRange set to true, bump major if the version is leaving the range. - // 2. If onlyUpdatePeerDependentsWhenOutOfRange set to false, bump major regardless whether or not the version is leaving the range. - (!onlyUpdatePeerDependentsWhenOutOfRange || - !semverSatisfies(incrementVersion(nextRelease, preInfo), versionRange)) && - // bump major only if the dependent doesn't already has a major release. - (!releases.has(dependent) || - (releases.has(dependent) && releases.get(dependent).type !== 'major')) - ); -} +import applyLinks from './apply-links'; +import determineDependents from './determine-dependents'; +import flattenReleases from './flatten-releases'; +import { incrementVersion } from './increment'; +import matchFixedConstraint from './match-fixed-constraint'; +import { InternalRelease, PreInfo } from './types'; -// This function takes in changesets and returns one release per -function flattenReleases(changesets, packagesByName, config) { - let releases = new Map(); - changesets.forEach((changeset) => { - changeset.releases - // Filter out skipped packages because they should not trigger a release - // If their dependencies need updates, they will be added to releases by `determineDependents()` with release type `none` - .filter( - ({ name }) => - !shouldSkipPackage(packagesByName.get(name), { - ignore: config.ignore, - allowPrivatePackages: config.privatePackages.version, - }), - ) - .forEach(({ name, type }) => { - let release = releases.get(name); - let pkg = packagesByName.get(name); - if (!pkg) { - throw new Error( - `"${changeset.id}" changeset mentions a release for a package "${name}" but such a package could not be found.`, - ); - } - if (!release) { - release = { - name, - type, - oldVersion: pkg.packageJson.version, - changesets: [changeset.id], - }; - } else { - if ( - type === 'major' || - ((release.type === 'patch' || release.type === 'none') && - (type === 'minor' || type === 'patch')) - ) { - release.type = type; - } - // Check whether the bumpType will change - // If the bumpType has changed recalc newVersion - // push new changeset to releases - release.changesets.push(changeset.id); - } - releases.set(name, release); - }); - }); - return releases; -} -function matchFixedConstraint(releases, packagesByName, config) { - let updated = false; - for (let fixedPackages of config.fixed) { - let releasingFixedPackages = [...releases.values()].filter( - (release) => - fixedPackages.includes(release.name) && release.type !== 'none', - ); - if (releasingFixedPackages.length === 0) continue; - let highestReleaseType = getHighestReleaseType(releasingFixedPackages); - let highestVersion = getCurrentHighestVersion( - fixedPackages, - packagesByName, - ); +type SnapshotReleaseParameters = { + tag?: string | undefined; + commit?: string | undefined; +}; - // Finally, we update the packages so all of them are on the highest version - for (let pkgName of fixedPackages) { - if ( - shouldSkipPackage(packagesByName.get(pkgName), { - ignore: config.ignore, - allowPrivatePackages: config.privatePackages.version, - }) - ) { - continue; - } - let release = releases.get(pkgName); - if (!release) { - updated = true; - releases.set(pkgName, { - name: pkgName, - type: highestReleaseType, - oldVersion: highestVersion, - changesets: [], - }); - continue; - } - if (release.type !== highestReleaseType) { - updated = true; - release.type = highestReleaseType; - } - if (release.oldVersion !== highestVersion) { - updated = true; - release.oldVersion = highestVersion; - } - } - } - return updated; -} -function getPreVersion(version) { - let parsed = semverParse(version); +function getPreVersion(version: string) { + let parsed = semverParse(version)!; let preVersion = parsed.prerelease[1] === undefined ? -1 : parsed.prerelease[1]; if (typeof preVersion !== 'number') { @@ -478,8 +32,13 @@ function getPreVersion(version) { preVersion++; return preVersion; } -function getSnapshotSuffix(template, snapshotParameters) { + +function getSnapshotSuffix( + template: Config['snapshot']['prereleaseTemplate'], + snapshotParameters: SnapshotReleaseParameters, +): string { let snapshotRefDate = new Date(); + const placeholderValues = { commit: snapshotParameters.commit, tag: snapshotParameters.tag, @@ -497,12 +56,17 @@ function getSnapshotSuffix(template, snapshotParameters) { .filter(Boolean) .join('-'); } - const placeholders = Object.keys(placeholderValues); + + const placeholders = Object.keys(placeholderValues) as Array< + keyof typeof placeholderValues + >; + if (!template.includes(`{tag}`) && placeholderValues.tag !== undefined) { throw new Error( `Failed to compose snapshot version: "{tag}" placeholder is missing, but the snapshot parameter is defined (value: '${placeholderValues.tag}')`, ); } + return placeholders.reduce((prev, key) => { return prev.replace(new RegExp(`\\{${key}\\}`, 'g'), () => { const value = placeholderValues[key]; @@ -511,16 +75,18 @@ function getSnapshotSuffix(template, snapshotParameters) { `Failed to compose snapshot version: "{${key}}" placeholder is used without having a value defined!`, ); } + return value; }); }, template); } + function getSnapshotVersion( - release, - preInfo, - useCalculatedVersion, - snapshotSuffix, -) { + release: InternalRelease, + preInfo: PreInfo | undefined, + useCalculatedVersion: boolean, + snapshotSuffix: string, +): string { if (release.type === 'none') { return release.oldVersion; } @@ -537,60 +103,65 @@ function getSnapshotVersion( const baseVersion = useCalculatedVersion ? incrementVersion(release, preInfo) : `0.0.0`; + return `${baseVersion}-${snapshotSuffix}`; } -function getNewVersion(release, preInfo) { + +function getNewVersion( + release: InternalRelease, + preInfo: PreInfo | undefined, +): string { if (release.type === 'none') { return release.oldVersion; } + return incrementVersion(release, preInfo); } + +type OptionalProp = Omit & Partial>; + function assembleReleasePlan( - changesets, - packages, - config, + changesets: NewChangeset[], + packages: Packages, + config: OptionalProp, // intentionally not using an optional parameter here so the result of `readPreState` has to be passed in here - preState, + preState: PreState | undefined, // snapshot: undefined -> not using snaphot // snapshot: { tag: undefined } -> --snapshot (empty tag) // snapshot: { tag: "canary" } -> --snapshot canary - snapshot, -) { + snapshot?: SnapshotReleaseParameters | string | boolean, +): ReleasePlan { // TODO: remove `refined*` in the next major version of this package // just use `config` and `snapshot` parameters directly, typed as: `config: Config, snapshot?: SnapshotReleaseParameters` - const refinedConfig = config.snapshot - ? config - : _objectSpread2( - _objectSpread2({}, config), - {}, - { - snapshot: { - prereleaseTemplate: null, - useCalculatedVersion: - config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH - .useCalculatedVersionForSnapshots, - }, + const refinedConfig: Config = config.snapshot + ? (config as Config) + : { + ...config, + snapshot: { + prereleaseTemplate: null, + useCalculatedVersion: ( + config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH as any + ).useCalculatedVersionForSnapshots, }, - ); - const refinedSnapshot = + }; + const refinedSnapshot: SnapshotReleaseParameters | undefined = typeof snapshot === 'string' - ? { - tag: snapshot, - } + ? { tag: snapshot } : typeof snapshot === 'boolean' - ? { - tag: undefined, - } + ? { tag: undefined } : snapshot; + let packagesByName = new Map( packages.packages.map((x) => [x.packageJson.name, x]), ); + const relevantChangesets = getRelevantChangesets( changesets, packagesByName, refinedConfig, preState, ); + const preInfo = getPreInfo( changesets, packagesByName, @@ -606,10 +177,12 @@ function assembleReleasePlan( packagesByName, refinedConfig, ); + let dependencyGraph = getDependentsGraph(packages, { bumpVersionsWithWorkspaceProtocolOnly: refinedConfig.bumpVersionsWithWorkspaceProtocolOnly, }); + let releasesValidated = false; while (releasesValidated === false) { // The map passed in to determineDependents will be mutated @@ -632,13 +205,12 @@ function assembleReleasePlan( packagesByName, refinedConfig.linked, ); + releasesValidated = !linksUpdated && !dependentAdded && !fixedConstraintUpdated; } - if ( - (preInfo === null || preInfo === void 0 ? void 0 : preInfo.state.mode) === - 'exit' - ) { + + if (preInfo?.state.mode === 'exit') { for (let pkg of packages.packages) { // If a package had a prerelease, but didn't trigger a version bump in the regular release, // we want to give it a patch release. @@ -672,28 +244,32 @@ function assembleReleasePlan( refinedConfig.snapshot.prereleaseTemplate, refinedSnapshot, ); + return { changesets: relevantChangesets, releases: [...releases.values()].map((incompleteRelease) => { - return _objectSpread2( - _objectSpread2({}, incompleteRelease), - {}, - { - newVersion: snapshotSuffix - ? getSnapshotVersion( - incompleteRelease, - preInfo, - refinedConfig.snapshot.useCalculatedVersion, - snapshotSuffix, - ) - : getNewVersion(incompleteRelease, preInfo), - }, - ); + return { + ...incompleteRelease, + newVersion: snapshotSuffix + ? getSnapshotVersion( + incompleteRelease, + preInfo, + refinedConfig.snapshot.useCalculatedVersion, + snapshotSuffix, + ) + : getNewVersion(incompleteRelease, preInfo), + }; }), - preState: preInfo === null || preInfo === void 0 ? void 0 : preInfo.state, + preState: preInfo?.state, }; } -function getRelevantChangesets(changesets, packagesByName, config, preState) { + +function getRelevantChangesets( + changesets: NewChangeset[], + packagesByName: Map, + config: Config, + preState: PreState | undefined, +): NewChangeset[] { for (const changeset of changesets) { // Using the following 2 arrays to decide whether a changeset // contains both skipped and not skipped packages @@ -701,7 +277,7 @@ function getRelevantChangesets(changesets, packagesByName, config, preState) { const notSkippedPackages = []; for (const release of changeset.releases) { if ( - shouldSkipPackage(packagesByName.get(release.name), { + shouldSkipPackage(packagesByName.get(release.name)!, { ignore: config.ignore, allowPrivatePackages: config.privatePackages.version, }) @@ -711,6 +287,7 @@ function getRelevantChangesets(changesets, packagesByName, config, preState) { notSkippedPackages.push(release.name); } } + if (skippedPackages.length > 0 && notSkippedPackages.length > 0) { throw new Error( `Found mixed changeset ${changeset.id}\n` + @@ -720,36 +297,49 @@ function getRelevantChangesets(changesets, packagesByName, config, preState) { ); } } + if (preState && preState.mode !== 'exit') { let usedChangesetIds = new Set(preState.changesets); return changesets.filter( (changeset) => !usedChangesetIds.has(changeset.id), ); } + return changesets; } -function getHighestPreVersion(packageGroup, packagesByName) { + +function getHighestPreVersion( + packageGroup: PackageGroup, + packagesByName: Map, +): number { let highestPreVersion = 0; for (let pkg of packageGroup) { highestPreVersion = Math.max( - getPreVersion(packagesByName.get(pkg).packageJson.version), + getPreVersion(packagesByName.get(pkg)!.packageJson.version), highestPreVersion, ); } return highestPreVersion; } -function getPreInfo(changesets, packagesByName, config, preState) { + +function getPreInfo( + changesets: NewChangeset[], + packagesByName: Map, + config: Config, + preState: PreState | undefined, +): PreInfo | undefined { if (preState === undefined) { return; } - let updatedPreState = _objectSpread2( - _objectSpread2({}, preState), - {}, - { - changesets: changesets.map((changeset) => changeset.id), - initialVersions: _objectSpread2({}, preState.initialVersions), + + let updatedPreState = { + ...preState, + changesets: changesets.map((changeset) => changeset.id), + initialVersions: { + ...preState.initialVersions, }, - ); + }; + for (const [, pkg] of packagesByName) { if (updatedPreState.initialVersions[pkg.packageJson.name] === undefined) { updatedPreState.initialVersions[pkg.packageJson.name] = @@ -758,7 +348,7 @@ function getPreInfo(changesets, packagesByName, config, preState) { } // Populate preVersion // preVersion is the map between package name and its next pre version number. - let preVersions = new Map(); + let preVersions = new Map(); for (const [, pkg] of packagesByName) { preVersions.set( pkg.packageJson.name, @@ -777,10 +367,11 @@ function getPreInfo(changesets, packagesByName, config, preState) { preVersions.set(linkedPackage, highestPreVersion); } } + return { state: updatedPreState, preVersions, }; } -export { assembleReleasePlan as default }; +export default assembleReleasePlan; From 3553782452183160a959f820c0d6553cad59debf Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 19:36:25 -0700 Subject: [PATCH 07/10] fix(sdk): make browser env flag static --- packages/sdk/src/env.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/sdk/src/env.ts b/packages/sdk/src/env.ts index b8f21069b13..3baf6d4c709 100644 --- a/packages/sdk/src/env.ts +++ b/packages/sdk/src/env.ts @@ -8,15 +8,13 @@ declare global { // Declare the ENV_TARGET constant that will be defined by DefinePlugin declare const ENV_TARGET: 'web' | 'node'; -const detectBrowserEnv = () => +const isBrowserEnvValue = typeof ENV_TARGET !== 'undefined' ? ENV_TARGET === 'web' : typeof window !== 'undefined' && typeof window.document !== 'undefined'; -const isBrowserEnvValue = detectBrowserEnv(); - function isBrowserEnv(): boolean { - return detectBrowserEnv(); + return isBrowserEnvValue; } function isReactNativeEnv(): boolean { From 954c73a8377a9f30346d438d79be8afedda186bb Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 23:08:30 -0700 Subject: [PATCH 08/10] fix(assemble-release-plan): move build to tsdown --- .../assemble-release-plan/babel.config.js | 11 - packages/assemble-release-plan/package.json | 38 +- .../assemble-release-plan/tsconfig.lib.json | 11 + .../assemble-release-plan/tsdown.config.mts | 24 + pnpm-lock.yaml | 1085 +---------------- 5 files changed, 59 insertions(+), 1110 deletions(-) delete mode 100644 packages/assemble-release-plan/babel.config.js create mode 100644 packages/assemble-release-plan/tsconfig.lib.json create mode 100644 packages/assemble-release-plan/tsdown.config.mts diff --git a/packages/assemble-release-plan/babel.config.js b/packages/assemble-release-plan/babel.config.js deleted file mode 100644 index 8640f046530..00000000000 --- a/packages/assemble-release-plan/babel.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - presets: [ - [ - '@babel/preset-env', - { - targets: { node: 8 }, - }, - ], - ], - overrides: [{ test: '**/*.ts', presets: ['@babel/preset-typescript'] }], -}; diff --git a/packages/assemble-release-plan/package.json b/packages/assemble-release-plan/package.json index 23e5c024221..013c5337b40 100644 --- a/packages/assemble-release-plan/package.json +++ b/packages/assemble-release-plan/package.json @@ -3,25 +3,23 @@ "version": "6.0.4", "private": true, "description": "Reads changesets and adds information on dependents that need bumping", - "main": "dist/changesets-assemble-release-plan.cjs.js", - "module": "dist/changesets-assemble-release-plan.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "exports": { ".": { - "types": { - "import": "./dist/changesets-assemble-release-plan.cjs.mjs", - "default": "./dist/changesets-assemble-release-plan.cjs.js" - }, - "module": "./dist/changesets-assemble-release-plan.esm.js", - "import": "./dist/changesets-assemble-release-plan.cjs.mjs", - "default": "./dist/changesets-assemble-release-plan.cjs.js" + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "default": "./dist/index.cjs" }, "./package.json": "./package.json" }, "scripts": { "test": "echo 'skip'", - "build": "preconstruct build", - "watch": "preconstruct watch", - "postinstall": "preconstruct dev", + "build": "pnpm exec tsdown --config tsdown.config.mts", + "watch": "pnpm exec tsdown --config tsdown.config.mts --watch", + "postinstall": "pnpm run build", "lint": "echo 'noop'", "types:check": "tsc", "changeset": "packages/cli/bin.js", @@ -44,20 +42,6 @@ "semver": "^7.5.3" }, "devDependencies": { - "@babel/preset-env": "^7.28.0", - "@babel/preset-typescript": "^7.27.1", - "@changesets/config": "*", - "@preconstruct/cli": "^2.8.1" - }, - "preconstruct": { - "packages": [ - "." - ], - "exports": { - "importConditionDefaultExport": "default" - }, - "___experimentalFlags_WILL_CHANGE_IN_PATCH": { - "importsConditions": true - } + "@changesets/config": "*" } } diff --git a/packages/assemble-release-plan/tsconfig.lib.json b/packages/assemble-release-plan/tsconfig.lib.json new file mode 100644 index 00000000000..62830fb86cd --- /dev/null +++ b/packages/assemble-release-plan/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "noEmit": false, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"] +} diff --git a/packages/assemble-release-plan/tsdown.config.mts b/packages/assemble-release-plan/tsdown.config.mts new file mode 100644 index 00000000000..ca4667e4b00 --- /dev/null +++ b/packages/assemble-release-plan/tsdown.config.mts @@ -0,0 +1,24 @@ +import { defineConfig } from 'tsdown'; +import { + createDualFormatConfig, + packageDirFromMetaUrl, +} from '../../tools/scripts/tsdown/config-helpers.mjs'; + +const packageDir = packageDirFromMetaUrl(import.meta.url); + +export default defineConfig([ + { + ...createDualFormatConfig({ + name: 'assemble-release-plan-build', + packageDir, + entry: { + index: 'src/index.ts', + }, + external: [/^[^./]/], + dts: { + resolver: 'tsc', + }, + unbundle: true, + }), + }, +]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0fb786377f1..6cef5e6dfef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1104,7 +1104,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)))(react@18.3.1) + version: 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1123,7 +1123,7 @@ importers: version: 2.59.0(typescript@5.0.4) '@modern-js/app-tools': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) + version: 3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@5.0.4) @@ -1162,7 +1162,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)))(react@18.3.1) + version: 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1181,7 +1181,7 @@ importers: version: 2.59.0(typescript@5.0.4) '@modern-js/app-tools': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) + version: 3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@5.0.4) @@ -2884,18 +2884,9 @@ importers: specifier: ^7.5.3 version: 7.6.3 devDependencies: - '@babel/preset-env': - specifier: ^7.28.0 - version: 7.28.6(@babel/core@7.29.0) - '@babel/preset-typescript': - specifier: ^7.27.1 - version: 7.28.5(@babel/core@7.29.0) '@changesets/config': specifier: '*' version: 3.1.2 - '@preconstruct/cli': - specifier: ^2.8.1 - version: 2.8.12 packages/bridge/bridge-react: dependencies: @@ -4084,7 +4075,7 @@ importers: version: 21.2.3(@babel/traverse@7.29.0)(@swc-node/register@1.10.10(@swc/core@1.15.10(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.10(@swc/helpers@0.5.18))(@swc/helpers@0.5.18)(esbuild@0.25.0)(next@14.2.35(@babel/core@7.28.6)(@playwright/test@1.57.0)(@swc/core@1.7.26(@swc/helpers@0.5.13))(babel-plugin-macros@3.1.0)(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.3)(webpack-cli@5.1.4))(nx@21.2.3(@swc-node/register@1.10.10(@swc/core@1.15.10(@swc/helpers@0.5.18))(@swc/types@0.1.25)(typescript@5.9.3))(@swc/core@1.15.10(@swc/helpers@0.5.18)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(verdaccio@6.1.2(encoding@0.1.13)(typanion@3.14.0))(vue-tsc@2.2.12(typescript@5.9.3))(webpack-cli@5.1.4) '@rsbuild/core': specifier: 2.0.0-beta.2 - version: 2.0.0-beta.2(@module-federation/runtime-tools@0.23.0)(core-js@3.48.0) + version: 2.0.0-beta.2(@module-federation/runtime-tools@0.15.0)(core-js@3.48.0) '@storybook/core': specifier: ^8.4.6 version: 8.6.14(prettier@3.8.1)(storybook@8.6.17(prettier@3.8.1)) @@ -9226,13 +9217,6 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@preconstruct/cli@2.8.12': - resolution: {integrity: sha512-SMsMICUWROmu/vb4cmrk7EJUiWhgNjB3U3tM654K9bu9yECXqrPN473vliO7KPV3CSLhmtl3S4nfcMirEJmyZg==} - hasBin: true - - '@preconstruct/hook@0.4.0': - resolution: {integrity: sha512-a7mrlPTM3tAFJyz43qb4pPVpUx8j8TzZBFsNFqcKcE/sEakNXRlQAuCT4RGZRf9dQiiUnBahzSIWawU4rENl+Q==} - '@publint/pack@0.1.3': resolution: {integrity: sha512-dHDWeutAerz+Z2wFYAce7Y51vd4rbLBfUh0BNnyul4xKoVsPUVJBrOAFsJvtvYBwGFJSqKsxyyHf/7evZ8+Q5Q==} engines: {node: '>=18'} @@ -10931,12 +10915,6 @@ packages: '@rolldown/pluginutils@1.0.0-rc.5': resolution: {integrity: sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw==} - '@rollup/plugin-alias@3.1.9': - resolution: {integrity: sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==} - engines: {node: '>=8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} engines: {node: '>=14.0.0'} @@ -10946,28 +10924,6 @@ packages: rollup: optional: true - '@rollup/plugin-commonjs@15.1.0': - resolution: {integrity: sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^2.22.0 - - '@rollup/plugin-json@4.1.0': - resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - - '@rollup/plugin-node-resolve@11.2.1': - resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} - engines: {node: '>= 10.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - - '@rollup/plugin-replace@2.4.2': - resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - '@rollup/plugin-replace@6.0.1': resolution: {integrity: sha512-2sPh9b73dj5IxuMmDAsQWVFT7mR+yoHweBaXG2W/R8vQ+IWZlnaI7BR7J6EguVQUp1hd8Z7XuozpDjEKQAAC2Q==} engines: {node: '>=14.0.0'} @@ -10977,12 +10933,6 @@ packages: rollup: optional: true - '@rollup/pluginutils@3.1.0': - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -13221,9 +13171,6 @@ packages: '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - '@types/estree@0.0.39': - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - '@types/estree@0.0.51': resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} @@ -13473,9 +13420,6 @@ packages: '@types/react@19.2.10': resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} - '@types/resolve@1.17.1': - resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} - '@types/resolve@1.20.6': resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} @@ -15349,10 +15293,6 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - builtin-status-codes@3.0.0: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} @@ -16480,9 +16420,6 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - dataloader@2.2.3: - resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} - date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} @@ -17640,9 +17577,6 @@ packages: estree-util-visit@2.0.0: resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} - estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -17817,9 +17751,6 @@ packages: fast-copy@4.0.2: resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==} - fast-deep-equal@2.0.1: - resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -18367,13 +18298,6 @@ packages: github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} - glob-base@0.3.0: - resolution: {integrity: sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==} - engines: {node: '>=0.10.0'} - - glob-parent@2.0.0: - resolution: {integrity: sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==} - glob-parent@3.1.0: resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} @@ -18973,9 +18897,6 @@ packages: ignore-by-default@1.0.1: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - ignore-walk@3.0.4: - resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} - ignore-walk@5.0.1: resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -19230,10 +19151,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true - is-dotfile@1.0.3: - resolution: {integrity: sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==} - engines: {node: '>=0.10.0'} - is-expression@4.0.0: resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} @@ -19245,10 +19162,6 @@ packages: resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} engines: {node: '>=0.10.0'} - is-extglob@1.0.0: - resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} - engines: {node: '>=0.10.0'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -19281,10 +19194,6 @@ packages: resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} - is-glob@2.0.1: - resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} - engines: {node: '>=0.10.0'} - is-glob@3.1.0: resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} engines: {node: '>=0.10.0'} @@ -19323,9 +19232,6 @@ packages: is-mobile@5.0.0: resolution: {integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==} - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-nan@1.3.2: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} @@ -19406,9 +19312,6 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -19710,10 +19613,6 @@ packages: resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-worker@26.6.2: - resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} - engines: {node: '>= 10.13.0'} - jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -20283,9 +20182,6 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -21160,16 +21056,10 @@ packages: resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} engines: {node: '>=14.16'} - npm-bundled@1.1.2: - resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} - npm-bundled@2.0.1: resolution: {integrity: sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - npm-normalize-package-bin@1.0.1: - resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} - npm-normalize-package-bin@2.0.0: resolution: {integrity: sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -21178,11 +21068,6 @@ packages: resolution: {integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==} engines: {node: ^16.14.0 || >=18.0.0} - npm-packlist@2.2.2: - resolution: {integrity: sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==} - engines: {node: '>=10'} - hasBin: true - npm-packlist@5.1.3: resolution: {integrity: sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -21521,10 +21406,6 @@ packages: parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - parse-glob@3.0.4: - resolution: {integrity: sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==} - engines: {node: '>=0.10.0'} - parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -23871,11 +23752,6 @@ packages: resolution: {integrity: sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==} engines: {node: '>=8.3'} - rollup@2.79.2: - resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} - engines: {node: '>=10.0.0'} - hasBin: true - rollup@4.57.0: resolution: {integrity: sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -24598,10 +24474,6 @@ packages: engines: {node: '>= 8'} deprecated: The work that was done in this beta branch won't be included in future versions - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - space-separated-tokens@1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} @@ -26182,9 +26054,6 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - v8-compile-cache@2.4.0: - resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} - v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -27353,17 +27222,9 @@ snapshots: eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1)': - dependencies: - '@babel/core': 7.29.0 - '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.57.1 - eslint-visitor-keys: 2.1.0 - semver: 6.3.1 - '@babel/eslint-plugin@7.27.1(@babel/eslint-parser@7.28.6(@babel/core@7.28.6)(eslint@8.57.1))(eslint@8.57.1)': dependencies: - '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) + '@babel/eslint-parser': 7.28.6(@babel/core@7.28.6)(eslint@8.57.1) eslint: 8.57.1 eslint-rule-composer: 0.3.0 @@ -27417,19 +27278,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.29.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27437,13 +27285,6 @@ snapshots: regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - regexpu-core: 6.4.0 - semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27455,17 +27296,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@8.1.1) - lodash.debounce: 4.0.8 - resolve: 1.22.11 - transitivePeerDependencies: - - supports-color - '@babel/helper-globals@7.28.0': {} '@babel/helper-member-expression-to-functions@7.28.5': @@ -27533,15 +27363,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27551,15 +27372,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.29.0 @@ -27610,34 +27422,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27647,15 +27441,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27664,14 +27449,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-proposal-decorators@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27708,10 +27485,6 @@ snapshots: dependencies: '@babel/core': 7.28.6 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27777,11 +27550,6 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27822,11 +27590,6 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27922,33 +27685,17 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27958,15 +27705,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -27976,35 +27714,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28013,14 +27732,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28029,14 +27740,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28049,30 +27752,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-globals': 7.28.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/template': 7.28.6 - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28081,58 +27766,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28141,34 +27796,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28183,14 +27820,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28200,55 +27829,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28257,14 +27857,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28273,14 +27865,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28291,16 +27875,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28309,56 +27883,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28370,17 +27915,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28389,24 +27923,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28415,14 +27936,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 @@ -28433,11 +27946,6 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28446,14 +27954,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28463,25 +27963,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28531,33 +28017,17 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28575,11 +28045,6 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28588,44 +28053,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28637,63 +28079,29 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/compat-data': 7.28.6 @@ -28770,82 +28178,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-env@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/compat-data': 7.28.6 - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) - '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-async-generator-functions': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-regenerator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/preset-flow@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28860,13 +28192,6 @@ snapshots: '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/types': 7.29.0 - esutils: 2.0.3 - '@babel/preset-react@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -28890,17 +28215,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/register@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -31369,7 +30683,7 @@ snapshots: '@modern-js-app/eslint-config@2.59.0(typescript@5.9.3)': dependencies: '@babel/core': 7.28.6 - '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) + '@babel/eslint-parser': 7.28.6(@babel/core@7.28.6)(eslint@8.57.1) '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.28.6(@babel/core@7.28.6)(eslint@8.57.1))(eslint@8.57.1) '@modern-js/babel-preset': 2.59.0(@rsbuild/core@1.0.1-rc.4) '@rsbuild/core': 1.0.1-rc.4 @@ -31664,57 +30978,6 @@ snapshots: - webpack - webpack-hot-middleware - '@modern-js/app-tools@3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4))': - dependencies: - '@babel/parser': 7.29.0 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@modern-js/builder': 3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) - '@modern-js/i18n-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0) - '@swc/helpers': 0.5.18 - es-module-lexer: 1.7.0 - esbuild: 0.25.5 - esbuild-register: 3.6.0(esbuild@0.25.5) - flatted: 3.3.3 - mlly: 1.8.0 - ndepe: 0.1.13(encoding@0.1.13)(rollup@4.57.0) - pkg-types: 1.3.1 - std-env: 3.10.0 - optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@20.19.5)(typescript@5.0.4) - tsconfig-paths: 4.2.0 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - '@parcel/css' - - '@rspack/core' - - '@swc/css' - - bufferutil - - clean-css - - core-js - - csso - - debug - - devcert - - encoding - - lightningcss - - react - - react-dom - - rollup - - supports-color - - tslib - - typescript - - utf-8-validate - - webpack - - webpack-hot-middleware - '@modern-js/app-tools@3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(core-js@3.48.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.4.0)(typescript@5.9.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: '@babel/parser': 7.29.0 @@ -31949,57 +31212,6 @@ snapshots: - webpack - webpack-hot-middleware - '@modern-js/builder@3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4))': - dependencies: - '@modern-js/flight-server-transform-plugin': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0) - '@rsbuild/plugin-assets-retry': 1.5.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-check-syntax': 1.6.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-css-minimizer': 1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) - '@rsbuild/plugin-less': 1.6.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-react': 1.4.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0))(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-rem': 1.0.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0))(typescript@5.0.4)(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-type-check': 1.3.3(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0))(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(tslib@2.8.1)(typescript@5.0.4) - '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)) - '@swc/core': 1.15.10(@swc/helpers@0.5.18) - '@swc/helpers': 0.5.18 - autoprefixer: 10.4.24(postcss@8.5.6) - browserslist: 4.28.1 - core-js: 3.48.0 - cssnano: 6.1.2(postcss@8.5.6) - html-minifier-terser: 7.2.0 - lodash: 4.17.23 - postcss: 8.5.6 - postcss-custom-properties: 13.3.12(postcss@8.5.6) - postcss-flexbugs-fixes: 5.0.2(postcss@8.5.6) - postcss-font-variant: 5.0.0(postcss@8.5.6) - postcss-initial: 4.0.1(postcss@8.5.6) - postcss-media-minmax: 5.0.0(postcss@8.5.6) - postcss-nesting: 12.1.5(postcss@8.5.6) - postcss-page-break: 3.0.4(postcss@8.5.6) - rspack-manifest-plugin: 5.2.1(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18)) - ts-deepmerge: 7.0.3 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - '@parcel/css' - - '@rspack/core' - - '@swc/css' - - clean-css - - csso - - esbuild - - lightningcss - - react - - react-dom - - supports-color - - tslib - - typescript - - webpack - - webpack-hot-middleware - '@modern-js/builder@3.0.1(@module-federation/runtime-tools@2.1.0)(@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: '@modern-js/flight-server-transform-plugin': 3.0.1 @@ -32405,15 +31617,6 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-server-dom-webpack: 19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@modern-js/render@3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)))(react@18.3.1)': - dependencies: - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.18 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-server-dom-webpack: 19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) - '@modern-js/rsbuild-plugin-esbuild@2.70.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(webpack-cli@5.1.4)': dependencies: '@swc/helpers': 0.5.18 @@ -32608,35 +31811,6 @@ snapshots: - core-js - react-server-dom-webpack - '@modern-js/runtime@3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)))(react@18.3.1)': - dependencies: - '@loadable/component': 5.16.7(react@18.3.1) - '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)))(react@18.3.1) - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.18 - '@swc/plugin-loadable-components': 11.5.0 - '@types/loadable__component': 5.13.10 - '@types/react-helmet': 6.1.11 - cookie: 0.7.2 - entities: 7.0.1 - es-module-lexer: 1.7.0 - esbuild: 0.25.5 - invariant: 2.2.4 - isbot: 3.8.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet: 6.1.0(react@18.3.1) - react-is: 18.3.1 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - core-js - - react-server-dom-webpack - '@modern-js/server-core@2.70.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@modern-js/plugin': 2.70.2 @@ -34658,56 +33832,6 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@preconstruct/cli@2.8.12': - dependencies: - '@babel/code-frame': 7.28.6 - '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.28.6 - '@babel/runtime': 7.28.2 - '@preconstruct/hook': 0.4.0 - '@rollup/plugin-alias': 3.1.9(rollup@2.79.2) - '@rollup/plugin-commonjs': 15.1.0(rollup@2.79.2) - '@rollup/plugin-json': 4.1.0(rollup@2.79.2) - '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.2) - '@rollup/plugin-replace': 2.4.2(rollup@2.79.2) - builtin-modules: 3.3.0 - chalk: 4.1.2 - ci-info: 3.9.0 - dataloader: 2.2.3 - detect-indent: 6.1.0 - enquirer: 2.4.1 - estree-walker: 2.0.2 - fast-deep-equal: 2.0.1 - fast-glob: 3.3.2 - fs-extra: 9.1.0 - is-reference: 1.2.1 - jest-worker: 26.6.2 - magic-string: 0.30.21 - ms: 2.1.3 - normalize-path: 3.0.0 - npm-packlist: 2.2.2 - p-limit: 3.1.0 - parse-glob: 3.0.4 - parse-json: 5.2.0 - quick-lru: 5.1.1 - resolve-from: 5.0.0 - rollup: 2.79.2 - semver: 7.6.3 - terser: 5.46.0 - v8-compile-cache: 2.4.0 - zod: 3.25.76 - transitivePeerDependencies: - - supports-color - - '@preconstruct/hook@0.4.0': - dependencies: - '@babel/core': 7.28.6 - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) - pirates: 4.0.7 - source-map-support: 0.5.21 - transitivePeerDependencies: - - supports-color - '@publint/pack@0.1.3': {} '@quansync/fs@1.0.0': @@ -37217,47 +36341,10 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.5': {} - '@rollup/plugin-alias@3.1.9(rollup@2.79.2)': - dependencies: - rollup: 2.79.2 - slash: 3.0.0 - '@rollup/plugin-alias@5.1.1(rollup@4.57.0)': optionalDependencies: rollup: 4.57.0 - '@rollup/plugin-commonjs@15.1.0(rollup@2.79.2)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - commondir: 1.0.1 - estree-walker: 2.0.2 - glob: 7.2.0 - is-reference: 1.2.1 - magic-string: 0.25.9 - resolve: 1.22.8 - rollup: 2.79.2 - - '@rollup/plugin-json@4.1.0(rollup@2.79.2)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - rollup: 2.79.2 - - '@rollup/plugin-node-resolve@11.2.1(rollup@2.79.2)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - '@types/resolve': 1.17.1 - builtin-modules: 3.3.0 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 2.79.2 - - '@rollup/plugin-replace@2.4.2(rollup@2.79.2)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - magic-string: 0.25.9 - rollup: 2.79.2 - '@rollup/plugin-replace@6.0.1(rollup@4.57.0)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.57.0) @@ -37265,13 +36352,6 @@ snapshots: optionalDependencies: rollup: 4.57.0 - '@rollup/pluginutils@3.1.0(rollup@2.79.2)': - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 2.79.2 - '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -37426,9 +36506,9 @@ snapshots: core-js: 3.47.0 jiti: 2.6.1 - '@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@0.23.0)(core-js@3.48.0)': + '@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@0.15.0)(core-js@3.48.0)': dependencies: - '@rspack/core': 2.0.0-beta.0(@module-federation/runtime-tools@0.23.0)(@swc/helpers@0.5.18) + '@rspack/core': 2.0.0-beta.0(@module-federation/runtime-tools@0.15.0)(@swc/helpers@0.5.18) '@swc/helpers': 0.5.18 jiti: 2.6.1 optionalDependencies: @@ -37629,21 +36709,6 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-css-minimizer@1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4))': - dependencies: - css-minimizer-webpack-plugin: 7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)) - reduce-configs: 1.1.1 - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.1.0)(core-js@3.48.0) - transitivePeerDependencies: - - '@parcel/css' - - '@swc/css' - - clean-css - - csso - - esbuild - - lightningcss - - webpack - '@rsbuild/plugin-less@1.5.0(@rsbuild/core@1.7.2)': dependencies: '@rsbuild/core': 1.7.2 @@ -38692,12 +37757,12 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.18 - '@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@0.23.0)(@swc/helpers@0.5.18)': + '@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@0.15.0)(@swc/helpers@0.5.18)': dependencies: '@rspack/binding': 2.0.0-beta.0 '@rspack/lite-tapable': 1.1.0 optionalDependencies: - '@module-federation/runtime-tools': 0.23.0 + '@module-federation/runtime-tools': 0.15.0 '@swc/helpers': 0.5.18 '@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.1.0)(@swc/helpers@0.5.18)': @@ -39218,7 +38283,7 @@ snapshots: '@storybook/cli@7.6.21(encoding@0.1.13)': dependencies: '@babel/core': 7.28.6 - '@babel/preset-env': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.28.6(@babel/core@7.28.6) '@babel/types': 7.29.0 '@ndelangen/get-tarball': 3.0.9 '@storybook/codemod': 7.6.21 @@ -40518,8 +39583,6 @@ snapshots: dependencies: '@types/estree': 1.0.8 - '@types/estree@0.0.39': {} - '@types/estree@0.0.51': {} '@types/estree@1.0.8': {} @@ -40803,10 +39866,6 @@ snapshots: dependencies: csstype: 3.2.3 - '@types/resolve@1.17.1': - dependencies: - '@types/node': 20.19.5 - '@types/resolve@1.20.6': {} '@types/retry@0.12.2': {} @@ -43495,15 +42554,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): - dependencies: - '@babel/compat-data': 7.28.6 - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.6): dependencies: '@babel/core': 7.28.6 @@ -43512,14 +42562,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.28.6): dependencies: '@babel/core': 7.28.6 @@ -43527,13 +42569,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - babel-plugin-styled-components@1.13.3(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)): dependencies: '@babel/helper-annotate-as-pure': 7.27.3 @@ -43961,8 +42996,6 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - builtin-modules@3.3.0: {} - builtin-status-codes@3.0.0: {} bundle-name@4.1.0: @@ -45056,18 +44089,6 @@ snapshots: optionalDependencies: esbuild: 0.25.5 - css-minimizer-webpack-plugin@7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - cssnano: 7.1.2(postcss@8.4.49) - jest-worker: 29.7.0 - postcss: 8.4.49 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - webpack: 5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4) - optionalDependencies: - esbuild: 0.25.5 - css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -45435,8 +44456,6 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - dataloader@2.2.3: {} - date-fns@2.30.0: dependencies: '@babel/runtime': 7.28.2 @@ -47109,8 +46128,6 @@ snapshots: '@types/estree-jsx': 1.0.5 '@types/unist': 3.0.3 - estree-walker@1.0.1: {} - estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -47442,8 +46459,6 @@ snapshots: fast-copy@4.0.2: {} - fast-deep-equal@2.0.1: {} - fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -48058,15 +47073,6 @@ snapshots: github-slugger@2.0.0: {} - glob-base@0.3.0: - dependencies: - glob-parent: 2.0.0 - is-glob: 2.0.1 - - glob-parent@2.0.0: - dependencies: - is-glob: 2.0.1 - glob-parent@3.1.0: dependencies: is-glob: 3.1.0 @@ -48947,10 +47953,6 @@ snapshots: ignore-by-default@1.0.1: {} - ignore-walk@3.0.4: - dependencies: - minimatch: 3.1.2 - ignore-walk@5.0.1: dependencies: minimatch: 5.1.6 @@ -49196,8 +48198,6 @@ snapshots: is-docker@3.0.0: {} - is-dotfile@1.0.3: {} - is-expression@4.0.0: dependencies: acorn: 7.4.1 @@ -49209,8 +48209,6 @@ snapshots: dependencies: is-plain-object: 2.0.4 - is-extglob@1.0.0: {} - is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -49237,10 +48235,6 @@ snapshots: has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 - is-glob@2.0.1: - dependencies: - is-extglob: 1.0.0 - is-glob@3.1.0: dependencies: is-extglob: 2.1.1 @@ -49270,8 +48264,6 @@ snapshots: is-mobile@5.0.0: {} - is-module@1.0.0: {} - is-nan@1.3.2: dependencies: call-bind: 1.0.8 @@ -49324,10 +48316,6 @@ snapshots: is-promise@4.0.0: {} - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.8 - is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -49993,12 +48981,6 @@ snapshots: jest-util: 29.7.0 string-length: 4.0.2 - jest-worker@26.6.2: - dependencies: - '@types/node': 20.19.5 - merge-stream: 2.0.0 - supports-color: 7.2.0 - jest-worker@27.5.1: dependencies: '@types/node': 20.19.5 @@ -50130,7 +49112,7 @@ snapshots: temp: 0.8.4 write-file-atomic: 2.4.3 optionalDependencies: - '@babel/preset-env': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.28.6(@babel/core@7.28.6) transitivePeerDependencies: - supports-color @@ -50737,10 +49719,6 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -52105,16 +51083,10 @@ snapshots: normalize-url@8.1.1: {} - npm-bundled@1.1.2: - dependencies: - npm-normalize-package-bin: 1.0.1 - npm-bundled@2.0.1: dependencies: npm-normalize-package-bin: 2.0.0 - npm-normalize-package-bin@1.0.1: {} - npm-normalize-package-bin@2.0.0: {} npm-package-arg@11.0.1: @@ -52124,13 +51096,6 @@ snapshots: semver: 7.6.3 validate-npm-package-name: 5.0.1 - npm-packlist@2.2.2: - dependencies: - glob: 7.2.0 - ignore-walk: 3.0.4 - npm-bundled: 1.1.2 - npm-normalize-package-bin: 1.0.1 - npm-packlist@5.1.3: dependencies: glob: 8.1.0 @@ -52557,13 +51522,6 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 - parse-glob@3.0.4: - dependencies: - glob-base: 0.3.0 - is-dotfile: 1.0.3 - is-extglob: 1.0.0 - is-glob: 2.0.1 - parse-json@4.0.0: dependencies: error-ex: 1.3.4 @@ -55707,15 +54665,6 @@ snapshots: webpack: 5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) webpack-sources: 3.3.4 - react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4)): - dependencies: - acorn-loose: 8.5.2 - neo-async: 2.6.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - webpack: 5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.3)(webpack-cli@5.1.4) - webpack-sources: 3.3.4 - react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.18.20)(webpack-cli@5.1.4)): dependencies: acorn-loose: 8.5.2 @@ -56376,10 +55325,6 @@ snapshots: globby: 10.0.1 is-plain-object: 3.0.1 - rollup@2.79.2: - optionalDependencies: - fsevents: 2.3.3 - rollup@4.57.0: dependencies: '@types/estree': 1.0.8 @@ -57218,8 +56163,6 @@ snapshots: dependencies: whatwg-url: 7.1.0 - sourcemap-codec@1.4.8: {} - space-separated-tokens@1.1.5: {} space-separated-tokens@2.0.2: {} @@ -59448,8 +58391,6 @@ snapshots: v8-compile-cache-lib@3.0.1: {} - v8-compile-cache@2.4.0: {} - v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 From 11c085aa711e344c0e5683db6d5ae2c11dbb9fef Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 23:49:10 -0700 Subject: [PATCH 09/10] chore: preserve peer dependency bump guard --- packages/assemble-release-plan/src/determine-dependents.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/assemble-release-plan/src/determine-dependents.ts b/packages/assemble-release-plan/src/determine-dependents.ts index be917797fb5..9042af7ac5e 100644 --- a/packages/assemble-release-plan/src/determine-dependents.ts +++ b/packages/assemble-release-plan/src/determine-dependents.ts @@ -230,7 +230,8 @@ function shouldBumpMajor({ preInfo: PreInfo | undefined; onlyUpdatePeerDependentsWhenOutOfRange: boolean; }) { - //disable major bump due to peer dep + // This fork intentionally never escalates peer dependency changes into + // major dependent releases. Preserve that lock even when refactoring. if (depType === 'peerDependencies') { return false; } From 53f7b89b845a325478410dcb074783ba567a1f83 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 11 Mar 2026 23:54:00 -0700 Subject: [PATCH 10/10] chore: exclude assemble-release-plan from bundle size --- scripts/bundle-size-report.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/bundle-size-report.mjs b/scripts/bundle-size-report.mjs index 41ef8d00947..d2d1d82212f 100755 --- a/scripts/bundle-size-report.mjs +++ b/scripts/bundle-size-report.mjs @@ -86,6 +86,7 @@ const ASSET_RULES = [ const JS_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']); const TRACKED_EXPORT_SUBPATHS = ['./bundler']; +const EXCLUDED_PACKAGE_NAMES = new Set(['@changesets/assemble-release-plan']); async function loadRslib() { if (!rslibPromise) { @@ -613,6 +614,7 @@ function discoverPackages(packagesDir) { try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); if (!packageJson?.name) continue; + if (EXCLUDED_PACKAGE_NAMES.has(packageJson.name)) continue; packages.push({ name: packageJson.name, dir: pkgDir,