From 778318da5bb13596c3c9cab5c5fc2cbbf4e87e20 Mon Sep 17 00:00:00 2001 From: Szymon Chmal Date: Mon, 12 Jan 2026 13:55:17 +0100 Subject: [PATCH 1/4] feat: restart app if it fails to report --- packages/bundler-metro/src/index.ts | 1 + packages/config/src/types.ts | 10 ++ packages/jest/src/errors.ts | 10 ++ packages/jest/src/harness.ts | 135 ++++++++++++++++---- packages/platform-android/tsconfig.json | 3 + packages/platform-android/tsconfig.lib.json | 3 + 6 files changed, 138 insertions(+), 24 deletions(-) diff --git a/packages/bundler-metro/src/index.ts b/packages/bundler-metro/src/index.ts index c176026..19d3d46 100644 --- a/packages/bundler-metro/src/index.ts +++ b/packages/bundler-metro/src/index.ts @@ -1,2 +1,3 @@ export { getMetroInstance } from './factory.js'; export type { MetroInstance, MetroFactory, MetroOptions } from './types.js'; +export type { Reporter, ReportableEvent } from './reporter.js'; diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts index 272a4b4..820b520 100644 --- a/packages/config/src/types.ts +++ b/packages/config/src/types.ts @@ -14,6 +14,16 @@ export const ConfigSchema = z .min(1000, 'Bridge timeout must be at least 1 second') .default(60000), + bundleStartTimeout: z + .number() + .min(1000, 'Bundle start timeout must be at least 1 second') + .default(15000), + + maxAppRestarts: z + .number() + .min(0, 'Max app restarts must be non-negative') + .default(2), + resetEnvironmentBetweenTestFiles: z.boolean().optional().default(true), unstable__skipAlreadyIncludedModules: z.boolean().optional().default(false), unstable__enableMetroCache: z.boolean().optional().default(false), diff --git a/packages/jest/src/errors.ts b/packages/jest/src/errors.ts index 07b0193..e5bf075 100644 --- a/packages/jest/src/errors.ts +++ b/packages/jest/src/errors.ts @@ -20,3 +20,13 @@ export class InitializationTimeoutError extends HarnessError { this.name = 'InitializationTimeoutError'; } } + +export class MaxAppRestartsError extends HarnessError { + constructor(attempts: number) { + super( + `App failed to start after ${attempts} attempts. ` + + `No bundling activity detected within timeout period.` + ); + this.name = 'MaxAppRestartsError'; + } +} diff --git a/packages/jest/src/harness.ts b/packages/jest/src/harness.ts index db2a6f4..2a0468b 100644 --- a/packages/jest/src/harness.ts +++ b/packages/jest/src/harness.ts @@ -1,12 +1,19 @@ -import { getBridgeServer } from '@react-native-harness/bridge/server'; +import { + getBridgeServer, + BridgeServer, +} from '@react-native-harness/bridge/server'; import { BridgeClientFunctions } from '@react-native-harness/bridge'; -import { HarnessPlatform } from '@react-native-harness/platforms'; -import { getMetroInstance } from '@react-native-harness/bundler-metro'; -import { InitializationTimeoutError } from './errors.js'; +import { + HarnessPlatform, + HarnessPlatformRunner, +} from '@react-native-harness/platforms'; +import { + getMetroInstance, + Reporter, + ReportableEvent, +} from '@react-native-harness/bundler-metro'; +import { InitializationTimeoutError, MaxAppRestartsError } from './errors.js'; import { Config as HarnessConfig } from '@react-native-harness/config'; -import pRetry from 'p-retry'; - -const BRIDGE_READY_TIMEOUT = 10000; export type Harness = { runTests: BridgeClientFunctions['runTests']; @@ -14,6 +21,95 @@ export type Harness = { dispose: () => Promise; }; +export const waitForAppReady = async (options: { + metroEvents: Reporter; + serverBridge: BridgeServer; + platformInstance: HarnessPlatformRunner; + bundleStartTimeout: number; + maxRestarts: number; + signal: AbortSignal; +}): Promise => { + const { + metroEvents, + serverBridge, + platformInstance, + bundleStartTimeout, + maxRestarts, + signal, + } = options; + + let restartCount = 0; + let isBundling = false; + let bundleTimeoutId: NodeJS.Timeout | null = null; + + const clearBundleTimeout = () => { + if (bundleTimeoutId) { + clearTimeout(bundleTimeoutId); + bundleTimeoutId = null; + } + }; + + return new Promise((resolve, reject) => { + // Handle abort signal + signal.addEventListener('abort', () => { + clearBundleTimeout(); + reject(new DOMException('The operation was aborted', 'AbortError')); + }); + + // Start/restart the bundle timeout + const startBundleTimeout = () => { + clearBundleTimeout(); + bundleTimeoutId = setTimeout(() => { + if (isBundling) return; // Don't restart while bundling + + if (restartCount >= maxRestarts) { + cleanup(); + reject(new MaxAppRestartsError(restartCount + 1)); + return; + } + + restartCount++; + platformInstance.restartApp().catch(reject); + startBundleTimeout(); // Reset timer for next attempt + }, bundleStartTimeout); + }; + + // Metro event listener + const onMetroEvent = (event: ReportableEvent) => { + if (event.type === 'bundle_build_started') { + isBundling = true; + clearBundleTimeout(); // Cancel restart timer while bundling + } else if ( + event.type === 'bundle_build_done' || + event.type === 'bundle_build_failed' + ) { + isBundling = false; + startBundleTimeout(); // Reset timer after bundle completes + } + }; + + // Bridge ready listener + const onReady = () => { + cleanup(); + resolve(); + }; + + const cleanup = () => { + clearBundleTimeout(); + metroEvents.removeListener(onMetroEvent); + serverBridge.off('ready', onReady); + }; + + // Setup listeners + metroEvents.addListener(onMetroEvent); + serverBridge.once('ready', onReady); + + // Start the app and timeout + platformInstance.restartApp().catch(reject); + startBundleTimeout(); + }); +}; + const getHarnessInternal = async ( config: HarnessConfig, platform: HarnessPlatform, @@ -46,23 +142,14 @@ const getHarnessInternal = async ( } try { - await pRetry( - () => - new Promise((resolve, reject) => { - signal.addEventListener('abort', () => { - reject(new DOMException('The operation was aborted', 'AbortError')); - }); - - serverBridge.once('ready', () => resolve()); - platformInstance.restartApp().catch(reject); - }), - { - minTimeout: BRIDGE_READY_TIMEOUT, - maxTimeout: BRIDGE_READY_TIMEOUT, - retries: Infinity, - signal, - } - ); + await waitForAppReady({ + metroEvents: metroInstance.events, + serverBridge, + platformInstance: platformInstance as HarnessPlatformRunner, + bundleStartTimeout: config.bundleStartTimeout, + maxRestarts: config.maxAppRestarts, + signal, + }); } catch (error) { await dispose(); throw error; diff --git a/packages/platform-android/tsconfig.json b/packages/platform-android/tsconfig.json index 56b5cd9..879e515 100644 --- a/packages/platform-android/tsconfig.json +++ b/packages/platform-android/tsconfig.json @@ -3,6 +3,9 @@ "files": [], "include": [], "references": [ + { + "path": "../config" + }, { "path": "../tools" }, diff --git a/packages/platform-android/tsconfig.lib.json b/packages/platform-android/tsconfig.lib.json index 1ff1d7b..ec9fadc 100644 --- a/packages/platform-android/tsconfig.lib.json +++ b/packages/platform-android/tsconfig.lib.json @@ -11,6 +11,9 @@ }, "include": ["src/**/*.ts"], "references": [ + { + "path": "../config/tsconfig.lib.json" + }, { "path": "../tools/tsconfig.lib.json" }, From 201ea144369d33ac81f081826faa8717c24e816b Mon Sep 17 00:00:00 2001 From: Szymon Chmal Date: Mon, 12 Jan 2026 16:39:58 +0100 Subject: [PATCH 2/4] chore: add version plan --- .nx/version-plans/version-plan-1768232329713.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .nx/version-plans/version-plan-1768232329713.md diff --git a/.nx/version-plans/version-plan-1768232329713.md b/.nx/version-plans/version-plan-1768232329713.md new file mode 100644 index 0000000..17e838d --- /dev/null +++ b/.nx/version-plans/version-plan-1768232329713.md @@ -0,0 +1,5 @@ +--- +__default__: prerelease +--- + +Add automatic app restart functionality when apps fail to report ready within the configured timeout period, improving test reliability by recovering from startup failures. From 9973499cf2baa190a7c7ca2d362f1d21ade4b341 Mon Sep 17 00:00:00 2001 From: Szymon Chmal Date: Mon, 12 Jan 2026 16:42:05 +0100 Subject: [PATCH 3/4] docs: update website --- .../docs/getting-started/configuration.mdx | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/website/src/docs/getting-started/configuration.mdx b/website/src/docs/getting-started/configuration.mdx index 8292b91..9beb81e 100644 --- a/website/src/docs/getting-started/configuration.mdx +++ b/website/src/docs/getting-started/configuration.mdx @@ -93,6 +93,12 @@ For Expo projects, the `entryPoint` should be set to the path specified in the ` // Optional: Bridge timeout in milliseconds (default: 60000) bridgeTimeout?: number; + // Optional: Bundle start timeout in milliseconds (default: 15000) + bundleStartTimeout?: number; + + // Optional: Maximum number of app restarts when app fails to report ready (default: 2) + maxAppRestarts?: number; + // Optional: Reset environment between test files (default: true) resetEnvironmentBetweenTestFiles?: boolean; } @@ -249,6 +255,39 @@ Increase this value if you experience timeout errors, especially on: - Slower devices or simulators - Complex test suites with heavy setup +## Bundle Start Timeout + +The bundle start timeout controls how long React Native Harness waits for Metro to start bundling after the app is restarted. This timeout is used in conjunction with the app restart mechanism to detect when an app has failed to report ready. + +```javascript +{ + bundleStartTimeout: 30000, // 30 seconds in milliseconds +} +``` + +**Default:** 15000 (15 seconds) +**Minimum:** 1000 (1 second) + +This timeout works with the `maxAppRestarts` setting to automatically restart the app when it fails to communicate with the test harness. If no bundling activity is detected within this timeout period, the app will be restarted automatically. + +## Maximum App Restarts + +The maximum app restarts setting controls how many times React Native Harness will attempt to restart the app when it fails to report ready within the configured timeout periods. + +```javascript +{ + maxAppRestarts: 3, // Allow up to 3 restart attempts +} +``` + +**Default:** 2 +**Minimum:** 0 + +When set to 0, automatic app restarting is disabled. Higher values provide more resilience against flaky test environments but may increase test execution time. The app will be restarted when: + +- No bundling activity is detected within the `bundleStartTimeout` period +- The bridge fails to establish communication within the `bridgeTimeout` period + ## Environment-Specific Configurations You can create different configurations for different environments: From 4efa8cc10d4b9317740e0d151d3fed9f0f72db60 Mon Sep 17 00:00:00 2001 From: Szymon Chmal Date: Mon, 12 Jan 2026 17:10:38 +0100 Subject: [PATCH 4/4] chore: update lockfile --- packages/jest/package.json | 1 - pnpm-lock.yaml | 42 ++++++++++++-------------------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/packages/jest/package.json b/packages/jest/package.json index 1c41524..5ca057c 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -43,7 +43,6 @@ "jest-message-util": "^30.2.0", "jest-util": "^30.2.0", "p-limit": "^7.1.1", - "p-retry": "^7.1.0", "tslib": "^2.3.0", "yargs": "^17.7.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c031f2..4530536 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,13 +31,13 @@ importers: version: 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/react-native': specifier: 22.0.4 - version: 22.0.4(b6bdbf441fca35f932c3e030670387b0) + version: 22.0.4(j5mvkpom3exmbpfctoxl2tygky) '@nx/rollup': specifier: 22.0.4 version: 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3) '@nx/vite': specifier: 22.0.4 - version: 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4) + version: 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0)) '@nx/web': specifier: 22.0.4 version: 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) @@ -64,7 +64,7 @@ importers: version: 4.6.0(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0)) '@vitest/coverage-v8': specifier: ^3.0.5 - version: 3.2.4(vitest@3.2.4) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0)) '@vitest/ui': specifier: ^3.0.0 version: 3.2.4(vitest@3.2.4) @@ -311,9 +311,6 @@ importers: p-limit: specifier: ^7.1.1 version: 7.1.1 - p-retry: - specifier: ^7.1.0 - version: 7.1.0 tslib: specifier: ^2.3.0 version: 2.8.1 @@ -5511,10 +5508,6 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-network-error@1.3.0: - resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} - engines: {node: '>=16'} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -6830,10 +6823,6 @@ packages: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} - p-retry@7.1.0: - resolution: {integrity: sha512-xL4PiFRQa/f9L9ZvR4/gUCRNus4N8YX80ku8kv9Jqz+ZokkiZLM0bcvX0gm1F3PDi9SPRsww1BDsTWgE6Y1GLQ==} - engines: {node: '>=20'} - p-timeout@3.2.0: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} @@ -8578,6 +8567,7 @@ packages: whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} @@ -10518,13 +10508,13 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nx/detox@22.0.4(9b1a4b49f421cf013b90dafab0a49a31)': + '@nx/detox@22.0.4(htxksnrdasuzrfoxdvkmoikuza)': dependencies: '@nx/devkit': 22.0.4(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/eslint': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/jest': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3) '@nx/js': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) - '@nx/react': 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4)(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17))) + '@nx/react': 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17))) detox: 20.46.0(@jest/environment@30.2.0)(@jest/types@30.2.0)(expect@30.2.0)(jest-environment-node@30.2.0)(jest@30.2.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@9.1.1(typescript@5.9.3))) tslib: 2.8.1 transitivePeerDependencies: @@ -10750,12 +10740,12 @@ snapshots: '@nx/nx-win32-x64-msvc@22.0.4': optional: true - '@nx/react-native@22.0.4(b6bdbf441fca35f932c3e030670387b0)': + '@nx/react-native@22.0.4(j5mvkpom3exmbpfctoxl2tygky)': dependencies: '@nx/devkit': 22.0.4(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/eslint': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/js': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) - '@nx/react': 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4)(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17))) + '@nx/react': 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17))) ajv: 8.17.1 enhanced-resolve: 5.18.3 ignore: 5.3.2 @@ -10766,7 +10756,7 @@ snapshots: tsconfig-paths: 4.2.0 tslib: 2.8.1 optionalDependencies: - '@nx/detox': 22.0.4(9b1a4b49f421cf013b90dafab0a49a31) + '@nx/detox': 22.0.4(htxksnrdasuzrfoxdvkmoikuza) '@nx/rollup': 22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@types/babel__core@7.20.5)(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3) transitivePeerDependencies: - '@babel/core' @@ -10801,7 +10791,7 @@ snapshots: - webpack - webpack-cli - '@nx/react@22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4)(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17)))': + '@nx/react@22.0.4(@babel/core@7.27.4)(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/helpers@0.5.17)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(ts-node@9.1.1(typescript@5.9.3))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(webpack@5.102.1(@swc/core@1.5.29(@swc/helpers@0.5.17)))': dependencies: '@nx/devkit': 22.0.4(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/eslint': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(@zkochan/js-yaml@0.0.7)(eslint@9.29.0(jiti@2.4.2))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) @@ -10819,7 +10809,7 @@ snapshots: semver: 7.7.2 tslib: 2.8.1 optionalDependencies: - '@nx/vite': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4) + '@nx/vite': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0)) transitivePeerDependencies: - '@babel/core' - '@babel/traverse' @@ -10880,7 +10870,7 @@ snapshots: - typescript - verdaccio - '@nx/vite@22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4)': + '@nx/vite@22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17)))(typescript@5.9.3)(vite@7.2.2(@types/node@20.19.25)(jiti@2.4.2)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))': dependencies: '@nx/devkit': 22.0.4(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) '@nx/js': 22.0.4(@babel/traverse@7.27.4)(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))(nx@22.0.4(@swc-node/register@1.9.2(@swc/core@1.5.29(@swc/helpers@0.5.17))(@swc/types@0.1.23)(typescript@5.9.3))(@swc/core@1.5.29(@swc/helpers@0.5.17))) @@ -12347,7 +12337,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.2.4)': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.25)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(less@4.1.3)(lightningcss@1.27.0)(sass-embedded@1.89.2)(sass@1.89.2)(stylus@0.64.0)(terser@5.42.0)(yaml@2.8.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -15225,8 +15215,6 @@ snapshots: is-negative-zero@2.0.3: {} - is-network-error@1.3.0: {} - is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -17262,10 +17250,6 @@ snapshots: eventemitter3: 4.0.7 p-timeout: 3.2.0 - p-retry@7.1.0: - dependencies: - is-network-error: 1.3.0 - p-timeout@3.2.0: dependencies: p-finally: 1.0.0