From 8a3fd8aa9d13f1ec15ed1c78b9e37032a4531101 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Thu, 22 Oct 2026 12:26:59 +0100 Subject: [PATCH 1/2] chore(testers): add Rozenite DevTools plugins to tester apps Wrap the tester-app, MF v1/v2 host and tester-expo configs with withRozenite, gated behind WITH_ROZENITE=true, and wire up the network activity plugin, plus React Navigation and AsyncStorage (ScriptManager cache) plugins in the Module Federation hosts. --- CONTRIBUTING.md | 2 + apps/tester-app/index.js | 3 + apps/tester-app/package.json | 2 + apps/tester-app/rspack.config.mjs | 7 +- apps/tester-app/src/App.tsx | 3 + apps/tester-app/webpack.config.mjs | 7 +- apps/tester-expo/app/_layout.tsx | 3 + apps/tester-expo/package.json | 2 + apps/tester-expo/rspack.config.mjs | 10 +- apps/tester-federation-v2/config.host-app.mts | 7 +- apps/tester-federation-v2/package.json | 4 + apps/tester-federation-v2/src/host/App.tsx | 25 +- apps/tester-federation-v2/src/host/index.js | 3 + apps/tester-federation/config.host-app.mts | 7 +- apps/tester-federation/package.json | 4 + apps/tester-federation/src/host/App.tsx | 25 +- apps/tester-federation/src/host/index.js | 3 + pnpm-lock.yaml | 719 +++++++++++++++++- pnpm-workspace.yaml | 4 + 19 files changed, 822 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa48925f0..a2a202510 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,8 @@ All development is done directly on GitHub, and all work is public. 2. Run `pnpm install` to install & set up the development environment. 3. Do the changes you want and test them out in the TesterApp (`apps/tester-app`) before sending a pull request. +To get extra [Rozenite](https://www.rozenite.dev) panels (network activity, plus navigation and storage in the Module Federation hosts) in React Native DevTools while testing, start a tester app's dev server with `WITH_ROZENITE=true`, e.g. `WITH_ROZENITE=true pnpm start`. + ### Commit message convention We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: diff --git a/apps/tester-app/index.js b/apps/tester-app/index.js index 3d2e8e19a..51cef7418 100644 --- a/apps/tester-app/index.js +++ b/apps/tester-app/index.js @@ -1,3 +1,4 @@ +import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry } from 'react-native'; import { name as appName } from './app.json'; import App from './src/App'; @@ -5,4 +6,6 @@ import App from './src/App'; // ScriptManager setup import './src/setup'; +withOnBootNetworkActivityRecording(); + AppRegistry.registerComponent(appName, () => App); diff --git a/apps/tester-app/package.json b/apps/tester-app/package.json index a64da2e76..84a71c34b 100644 --- a/apps/tester-app/package.json +++ b/apps/tester-app/package.json @@ -44,6 +44,8 @@ "@react-native/babel-preset": "catalog:testers", "@react-native/metro-config": "catalog:testers", "@react-native/typescript-config": "catalog:testers", + "@rozenite/network-activity-plugin": "catalog:testers", + "@rozenite/repack": "catalog:testers", "@rsdoctor/rspack-plugin": "1.6.4", "@rspack/core": "catalog:", "@svgr/webpack": "^8.1.0", diff --git a/apps/tester-app/rspack.config.mjs b/apps/tester-app/rspack.config.mjs index 641ffbb37..1432943f5 100644 --- a/apps/tester-app/rspack.config.mjs +++ b/apps/tester-app/rspack.config.mjs @@ -2,6 +2,7 @@ import path from 'node:path'; import * as Repack from '@callstack/repack'; import { NativeWindPlugin } from '@callstack/repack-plugin-nativewind'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; +import { withRozenite } from '@rozenite/repack'; // Rsdoctor (through rslog) throws on import under Node < 20, so only load it // when it's actually enabled to keep the Node 18 test matrix working. @@ -11,7 +12,7 @@ const { RsdoctorRspackPlugin } = process.env.RSDOCTOR const dirname = Repack.getDirname(import.meta.url); -export default Repack.defineRspackConfig((env) => { +const config = Repack.defineRspackConfig((env) => { const { mode = 'development', context = dirname, @@ -134,3 +135,7 @@ export default Repack.defineRspackConfig((env) => { ].filter(Boolean), }; }); + +export default withRozenite(config, { + enabled: process.env.WITH_ROZENITE === 'true', +}); diff --git a/apps/tester-app/src/App.tsx b/apps/tester-app/src/App.tsx index dc6c0187c..3de6da3d1 100644 --- a/apps/tester-app/src/App.tsx +++ b/apps/tester-app/src/App.tsx @@ -1,3 +1,4 @@ +import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; import { Appearance } from 'react-native'; // nativewind styles @@ -16,6 +17,8 @@ import { SectionContainer } from './ui/SectionContainer'; Appearance.setColorScheme('light'); const App = () => { + useNetworkActivityDevTools(); + return ( diff --git a/apps/tester-app/webpack.config.mjs b/apps/tester-app/webpack.config.mjs index 37709ff0a..bcc0bd798 100644 --- a/apps/tester-app/webpack.config.mjs +++ b/apps/tester-app/webpack.config.mjs @@ -2,11 +2,12 @@ import path from 'node:path'; import * as Repack from '@callstack/repack'; import { NativeWindPlugin } from '@callstack/repack-plugin-nativewind'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; +import { withRozenite } from '@rozenite/repack'; import TerserPlugin from 'terser-webpack-plugin'; const dirname = Repack.getDirname(import.meta.url); -export default Repack.defineWebpackConfig((env) => { +const config = Repack.defineWebpackConfig((env) => { const { mode = 'development', context = dirname, @@ -133,3 +134,7 @@ export default Repack.defineWebpackConfig((env) => { ], }; }); + +export default withRozenite(config, { + enabled: process.env.WITH_ROZENITE === 'true', +}); diff --git a/apps/tester-expo/app/_layout.tsx b/apps/tester-expo/app/_layout.tsx index 624cfe6c7..47d437509 100644 --- a/apps/tester-expo/app/_layout.tsx +++ b/apps/tester-expo/app/_layout.tsx @@ -1,5 +1,8 @@ +import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; import { Stack } from 'expo-router'; export default function RootLayout() { + useNetworkActivityDevTools(); + return ; } diff --git a/apps/tester-expo/package.json b/apps/tester-expo/package.json index 9db2d3ba3..9f4895336 100644 --- a/apps/tester-expo/package.json +++ b/apps/tester-expo/package.json @@ -39,6 +39,8 @@ "@react-native-community/cli-platform-ios": "catalog:testers", "@react-native/babel-preset": "catalog:testers", "@react-native/community-cli-plugin": "catalog:testers", + "@rozenite/network-activity-plugin": "catalog:testers", + "@rozenite/repack": "catalog:testers", "@rspack/core": "catalog:", "@types/react": "catalog:testers", "babel-preset-expo": "catalog:expo58", diff --git a/apps/tester-expo/rspack.config.mjs b/apps/tester-expo/rspack.config.mjs index f118f29be..e94818c9a 100644 --- a/apps/tester-expo/rspack.config.mjs +++ b/apps/tester-expo/rspack.config.mjs @@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url'; import * as Repack from '@callstack/repack'; import { ExpoPlugin } from '@callstack/repack-expo/rspack'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; +import { withRozenite } from '@rozenite/repack'; const require = createRequire(import.meta.url); const projectRoot = path.dirname(fileURLToPath(import.meta.url)); @@ -18,7 +19,7 @@ const SHARED_SINGLETONS = [ 'expo-font', ]; -export default (env) => { +const config = (env) => { const { mode = 'development', platform = process.env.PLATFORM, @@ -64,3 +65,10 @@ export default (env) => { ], }; }; + +export default withRozenite(config, { + enabled: process.env.WITH_ROZENITE === 'true', + // Re.Pack serves DevTools through React Native's dev-middleware, not the copy + // bundled with Expo's CLI, so Rozenite has to patch that one. + projectType: 'react-native-cli', +}); diff --git a/apps/tester-federation-v2/config.host-app.mts b/apps/tester-federation-v2/config.host-app.mts index 39e509b2b..c3654b22d 100644 --- a/apps/tester-federation-v2/config.host-app.mts +++ b/apps/tester-federation-v2/config.host-app.mts @@ -1,6 +1,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import type * as Repack from '@callstack/repack'; +import { withRozenite } from '@rozenite/repack'; import rspackConfig from './configs/rspack.host-app.mts'; import webpackConfig from './configs/webpack.host-app.mts'; @@ -10,8 +11,12 @@ const __dirname = path.dirname(__filename); const useWebpack = Boolean(process.env.USE_WEBPACK); -export default (env: Repack.EnvOptions) => { +const config = (env: Repack.EnvOptions) => { env.context = __dirname; return useWebpack ? webpackConfig(env) : rspackConfig(env); }; + +export default withRozenite(config, { + enabled: process.env.WITH_ROZENITE === 'true', +}); diff --git a/apps/tester-federation-v2/package.json b/apps/tester-federation-v2/package.json index ed90c3d62..d90b09671 100644 --- a/apps/tester-federation-v2/package.json +++ b/apps/tester-federation-v2/package.json @@ -35,6 +35,10 @@ "@react-native/community-cli-plugin": "catalog:testers", "@react-native/metro-config": "catalog:testers", "@react-native/typescript-config": "catalog:testers", + "@rozenite/network-activity-plugin": "catalog:testers", + "@rozenite/react-navigation-plugin": "catalog:testers", + "@rozenite/repack": "catalog:testers", + "@rozenite/storage-plugin": "catalog:testers", "@rsdoctor/rspack-plugin": "1.6.4", "@rspack/core": "catalog:", "@swc/helpers": "catalog:", diff --git a/apps/tester-federation-v2/src/host/App.tsx b/apps/tester-federation-v2/src/host/App.tsx index 4fd1a6851..014c41058 100644 --- a/apps/tester-federation-v2/src/host/App.tsx +++ b/apps/tester-federation-v2/src/host/App.tsx @@ -1,9 +1,30 @@ -import { NavigationContainer } from '@react-navigation/native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { + NavigationContainer, + useNavigationContainerRef, +} from '@react-navigation/native'; +import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; +import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; +import { + createAsyncStorageAdapter, + useRozeniteStoragePlugin, +} from '@rozenite/storage-plugin'; import MainNavigator from './navigation/MainNavigator'; +// ScriptManager caches remote scripts in AsyncStorage (see index.js). +const storages = [ + createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), +]; + const App = () => { + const navigationRef = useNavigationContainerRef(); + + useNetworkActivityDevTools(); + useReactNavigationDevTools({ ref: navigationRef }); + useRozeniteStoragePlugin({ storages }); + return ( - + ); diff --git a/apps/tester-federation-v2/src/host/index.js b/apps/tester-federation-v2/src/host/index.js index 61610d410..ec2981a48 100644 --- a/apps/tester-federation-v2/src/host/index.js +++ b/apps/tester-federation-v2/src/host/index.js @@ -1,11 +1,14 @@ import { ScriptManager } from '@callstack/repack/client'; import { preloadRemote } from '@module-federation/runtime'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry } from 'react-native'; import { components } from '../../app.json'; import App from './App'; +withOnBootNetworkActivityRecording(); + if (__WITH_PRELOAD__) { // enable caching of scripts in the AsyncStorage ScriptManager.shared.setStorage(AsyncStorage); diff --git a/apps/tester-federation/config.host-app.mts b/apps/tester-federation/config.host-app.mts index 39e509b2b..c3654b22d 100644 --- a/apps/tester-federation/config.host-app.mts +++ b/apps/tester-federation/config.host-app.mts @@ -1,6 +1,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import type * as Repack from '@callstack/repack'; +import { withRozenite } from '@rozenite/repack'; import rspackConfig from './configs/rspack.host-app.mts'; import webpackConfig from './configs/webpack.host-app.mts'; @@ -10,8 +11,12 @@ const __dirname = path.dirname(__filename); const useWebpack = Boolean(process.env.USE_WEBPACK); -export default (env: Repack.EnvOptions) => { +const config = (env: Repack.EnvOptions) => { env.context = __dirname; return useWebpack ? webpackConfig(env) : rspackConfig(env); }; + +export default withRozenite(config, { + enabled: process.env.WITH_ROZENITE === 'true', +}); diff --git a/apps/tester-federation/package.json b/apps/tester-federation/package.json index f5f52e46d..b6afa05ae 100644 --- a/apps/tester-federation/package.json +++ b/apps/tester-federation/package.json @@ -35,6 +35,10 @@ "@react-native/babel-preset": "catalog:testers", "@react-native/metro-config": "catalog:testers", "@react-native/typescript-config": "catalog:testers", + "@rozenite/network-activity-plugin": "catalog:testers", + "@rozenite/react-navigation-plugin": "catalog:testers", + "@rozenite/repack": "catalog:testers", + "@rozenite/storage-plugin": "catalog:testers", "@rsdoctor/rspack-plugin": "1.6.4", "@rspack/core": "catalog:", "@swc/helpers": "catalog:", diff --git a/apps/tester-federation/src/host/App.tsx b/apps/tester-federation/src/host/App.tsx index 4fd1a6851..014c41058 100644 --- a/apps/tester-federation/src/host/App.tsx +++ b/apps/tester-federation/src/host/App.tsx @@ -1,9 +1,30 @@ -import { NavigationContainer } from '@react-navigation/native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { + NavigationContainer, + useNavigationContainerRef, +} from '@react-navigation/native'; +import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; +import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; +import { + createAsyncStorageAdapter, + useRozeniteStoragePlugin, +} from '@rozenite/storage-plugin'; import MainNavigator from './navigation/MainNavigator'; +// ScriptManager caches remote scripts in AsyncStorage (see index.js). +const storages = [ + createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), +]; + const App = () => { + const navigationRef = useNavigationContainerRef(); + + useNetworkActivityDevTools(); + useReactNavigationDevTools({ ref: navigationRef }); + useRozeniteStoragePlugin({ storages }); + return ( - + ); diff --git a/apps/tester-federation/src/host/index.js b/apps/tester-federation/src/host/index.js index 5e2ad7832..569c9af84 100644 --- a/apps/tester-federation/src/host/index.js +++ b/apps/tester-federation/src/host/index.js @@ -1,10 +1,13 @@ import { Federated, ScriptManager } from '@callstack/repack/client'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry, Platform } from 'react-native'; import { components } from '../../app.json'; import App from './App'; +withOnBootNetworkActivityRecording(); + ScriptManager.shared.setStorage(AsyncStorage); const resolveURL = Federated.createURLResolver({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b55062204..c9ea740b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -104,6 +104,18 @@ catalogs: '@react-native/typescript-config': specifier: 0.88.0 version: 0.88.0 + '@rozenite/network-activity-plugin': + specifier: 2.5.0 + version: 2.5.0 + '@rozenite/react-navigation-plugin': + specifier: 2.5.0 + version: 2.5.0 + '@rozenite/repack': + specifier: 2.5.0 + version: 2.5.0 + '@rozenite/storage-plugin': + specifier: 2.5.0 + version: 2.5.0 '@types/react': specifier: ^19.2.0 version: 19.2.17 @@ -256,6 +268,12 @@ importers: '@react-native/typescript-config': specifier: catalog:testers version: 0.88.0 + '@rozenite/network-activity-plugin': + specifier: catalog:testers + version: 2.5.0(@types/react@19.2.17)(expo@58.0.13)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/repack': + specifier: catalog:testers + version: 2.5.0(@callstack/repack@packages+repack)(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) '@rsdoctor/rspack-plugin': specifier: 1.6.4 version: 1.6.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@rsbuild/core@2.2.12(@module-federation/runtime-tools@2.9.2)(core-js@3.42.0))(@rspack/core@1.6.0(@swc/helpers@0.5.23))(webpack@5.105.4(@swc/core@1.15.46(@swc/helpers@0.5.23))) @@ -392,6 +410,12 @@ importers: '@react-native/community-cli-plugin': specifier: catalog:testers version: 0.88.0(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7)) + '@rozenite/network-activity-plugin': + specifier: catalog:testers + version: 2.5.0(@types/react@19.2.17)(expo@58.0.13)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/repack': + specifier: catalog:testers + version: 2.5.0(@callstack/repack@packages+repack)(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) '@rspack/core': specifier: 'catalog:' version: 1.6.0(@swc/helpers@0.5.23) @@ -517,6 +541,18 @@ importers: '@react-native/typescript-config': specifier: catalog:testers version: 0.88.0 + '@rozenite/network-activity-plugin': + specifier: catalog:testers + version: 2.5.0(@types/react@19.2.17)(expo@58.0.13)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/react-navigation-plugin': + specifier: catalog:testers + version: 2.5.0(@react-navigation/core@7.21.11(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/repack': + specifier: catalog:testers + version: 2.5.0(@callstack/repack@packages+repack)(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/storage-plugin': + specifier: catalog:testers + version: 2.5.0(@react-native-async-storage/async-storage@3.1.1(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0) '@rsdoctor/rspack-plugin': specifier: 1.6.4 version: 1.6.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@rsbuild/core@2.2.12(@module-federation/runtime-tools@2.9.2)(core-js@3.42.0))(@rspack/core@1.6.0(@swc/helpers@0.5.23))(webpack@5.105.4) @@ -605,6 +641,18 @@ importers: '@react-native/typescript-config': specifier: catalog:testers version: 0.88.0 + '@rozenite/network-activity-plugin': + specifier: catalog:testers + version: 2.5.0(@types/react@19.2.17)(expo@58.0.13)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/react-navigation-plugin': + specifier: catalog:testers + version: 2.5.0(@react-navigation/core@7.21.11(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@rozenite/repack': + specifier: catalog:testers + version: 2.5.0(@callstack/repack@packages+repack)(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/storage-plugin': + specifier: catalog:testers + version: 2.5.0(@react-native-async-storage/async-storage@3.1.1(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0) '@rsdoctor/rspack-plugin': specifier: 1.6.4 version: 1.6.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@rsbuild/core@2.2.12(@module-federation/runtime-tools@2.9.2)(core-js@3.42.0))(@rspack/core@1.6.0(@swc/helpers@0.5.23))(webpack@5.105.4) @@ -787,10 +835,10 @@ importers: version: 20.19.43 nativewind: specifier: ^4.1.23 - version: 4.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)) + version: 4.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2) react-native-css-interop: specifier: ^0.1.22 - version: 0.1.22(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)) + version: 0.1.22(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2) webpack: specifier: 'catalog:' version: 5.105.4 @@ -1977,6 +2025,33 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@base-ui/react@1.9.0': + resolution: {integrity: sha512-S8CSYosASBKtpL8SWUfS78rFElfLijiCgA7oHOK22jCJ95FULsYyKwBNFOgudt0RA+/7yNc7F81bOvQnRgbBiQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@date-fns/tz': ^1.2.0 + '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@date-fns/tz': + optional: true + '@types/react': + optional: true + date-fns: + optional: true + + '@base-ui/utils@0.5.0': + resolution: {integrity: sha512-dYGGcEttjkYiMoa5nHm8vLaJ2UcuTWxo3BFAwOYXeRg/q7UVVvA6cacEIXEs3FgBfK1CGtW1ptElqs7wsx+t9A==} + peerDependencies: + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -2675,6 +2750,21 @@ packages: '@fastify/sensible@6.0.4': resolution: {integrity: sha512-1vxcCUlPMew6WroK8fq+LVOwbsLtX+lmuRuqpcp6eYqu6vmkLwbKTdBWAZwbeaSgCfW4tzUpTIHLLvTiQQ1BwQ==} + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/react-dom@2.1.9': + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -4254,6 +4344,94 @@ packages: cpu: [x64] os: [win32] + '@rozenite/agent-bridge@2.5.0': + resolution: {integrity: sha512-Y84VcAo/UaqhAyJZMNWNUdCcFI+6J/0El73eNrCVx0A4uZEy/t5GHvQKJuN3lR2SkU59D7zd+bcqqu+H/9EYZw==} + engines: {node: '>=20'} + peerDependencies: + react: '>=17' + + '@rozenite/agent-shared@2.5.0': + resolution: {integrity: sha512-odly7RJ5xX8X+/8ysYgaYiVpY5B/SJSXmXkfx8jnpiu6ZblGMLDU2+dypqYXN7C3r8UmuTNBeadHcaTaPpqWAA==} + engines: {node: '>=20'} + + '@rozenite/app@2.5.0': + resolution: {integrity: sha512-l3IkfFzCokcrsiQD4WMzQu9+tGXUM32/ggnLl+cx6XOauJKzPhI3MgN8h4BNusTfU065MVPlMHEtSPUIQRZ8SQ==} + engines: {node: '>=20'} + + '@rozenite/middleware@2.5.0': + resolution: {integrity: sha512-iWuBJvQwXTKH7qnVL6bgqDviPZaI41sjwLpoZD+sDuUcQFLczkK7S/aqFzI4pjWW7RGVDgZciPFBvUvMWJAt1Q==} + engines: {node: '>=20.19.0'} + + '@rozenite/network-activity-plugin@2.5.0': + resolution: {integrity: sha512-qTmtaLv4THbRySopifK1fwoL2y5J2+v4/OgzJQg9ch9PbMzl6EwJHax+GzXUuBhgbQvb+Si3vwzxhzgJaSI/Gw==} + peerDependencies: + expo: '*' + react-native-nitro-fetch: '*' + react-native-sse: '*' + peerDependenciesMeta: + expo: + optional: true + react-native-nitro-fetch: + optional: true + react-native-sse: + optional: true + + '@rozenite/plugin-bridge@2.5.0': + resolution: {integrity: sha512-6sfl58ZqeU8uVEJZRMZPM6Oq0aQa2XV6dsOXr3BgGoZNNcF0KewTD95ZoMsx2KpRpcjo9ozKr2pcIHYQL5Strw==} + engines: {node: '>=20'} + peerDependencies: + react: '>=17' + + '@rozenite/react-navigation-plugin@2.5.0': + resolution: {integrity: sha512-JzsFt5G8em6n0aBw5x8pH7GXx6EURRkW9ZPhDgU4e1LuVrGDV3480u8rZqdAzge3K9bAq9Y3U+7PMiE9pZAByg==} + peerDependencies: + '@react-navigation/core': ^7.12.1 + + '@rozenite/repack@2.5.0': + resolution: {integrity: sha512-+MC6X5mksCYM5aG787zFTb0Jl9YZC/Sr6Qq5GONw60grS5jB6AvxgqHJnDnHXMP1I11k7o+nAj5da3a7QnbV8g==} + engines: {node: '>=20'} + peerDependencies: + '@callstack/repack': ^5.2 + + '@rozenite/runtime@2.5.0': + resolution: {integrity: sha512-GtsVZ/jRLOxdJmdf+dtolRLZ11/nAkRwuWEnfgxvjGTjiuys3LyaHJ3Ji3HvrkguhPDTpdN7CXyViK5vbC0sSQ==} + engines: {node: '>=20'} + + '@rozenite/shell@2.5.0': + resolution: {integrity: sha512-BwssRcdGd2XEalDrT8jHbKn0WMUcAF+4W5/K7dSW8uU8ya60yxAjYFN0q6SfkUJEZUcnG3JW3yj8X9ja1oDRmQ==} + engines: {node: '>=20'} + peerDependencies: + vitest: ^4.0.18 + peerDependenciesMeta: + vitest: + optional: true + + '@rozenite/storage-plugin@2.5.0': + resolution: {integrity: sha512-WC5Nw1bjI/mTFY2cw4Nd89axXwAsr8oyz5nROVGV+iBVSbEOlmGaHZNTiL3VIuUmIwNhjHQnxrATWgwhJ5b/cg==} + peerDependencies: + '@react-native-async-storage/async-storage': '*' + expo-secure-store: '*' + react: '*' + react-native: '*' + react-native-mmkv: '*' + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + expo-secure-store: + optional: true + react-native-mmkv: + optional: true + + '@rozenite/tools@2.5.0': + resolution: {integrity: sha512-7HUbyZ2623mIl7ehx3zCYh17czIyyOqleQkuFH7O4E+lsswqUwAgza2LBw0w2LafNkMBWC5hZ47PoOsYpur8QQ==} + + '@rozenite/ui@2.5.0': + resolution: {integrity: sha512-n2GCnycRKK9W7EoDvuWZ3Xy80jIMwHv/DWKF8A9RHeobS4KqqPWBPeq8+ls/Xth/9pD3/QMoOXN6Qu6P/knZjw==} + engines: {node: '>=20'} + peerDependencies: + react: '>=19' + react-dom: '>=19' + '@rsbuild/core@1.3.18': resolution: {integrity: sha512-ocnz3pVapMTeuoP3zZ1shYcxnAQtRf6RzLl8n7acNi8Hu+ku6SiDGR65foclwcubWF6e9nZPohH94rXnmEVfrw==} engines: {node: '>=16.10.0'} @@ -4885,6 +5063,17 @@ packages: '@swc/types@0.1.27': resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==} + '@tanstack/react-table@8.21.3': + resolution: {integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/table-core@8.21.3': + resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} + engines: {node: '>=12'} + '@turbo/darwin-64@2.10.7': resolution: {integrity: sha512-/c9cSBRermWDv85oufLhoH6XRLOVbvzJLRd+WLyfJCP+i0HFLQj4PVNDrHcY17/ve5l8X0Oua4bJBqJUgJPnZA==} cpu: [x64] @@ -5958,6 +6147,10 @@ packages: resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} engines: {node: '>=18'} + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} + engines: {node: '>=18'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -5969,6 +6162,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -6611,6 +6808,10 @@ packages: exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + express@5.3.0: + resolution: {integrity: sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==} + engines: {node: '>= 18'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -6717,6 +6918,10 @@ packages: resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-babel-config@2.1.2: resolution: {integrity: sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==} @@ -6817,6 +7022,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-extra@11.4.0: resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==} engines: {node: '>=14.14'} @@ -7171,6 +7380,10 @@ packages: iobuffer@6.0.1: resolution: {integrity: sha512-SZWYkWNfjIXIBYSDpXDYIgshqtbOPsi4lviawAEceR1Kqk+sHDlcQjWrzNQsii80AyBY0q5c8HCTNjqo74ul+Q==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + ipaddr.js@2.4.0: resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} engines: {node: '>= 10'} @@ -7269,6 +7482,9 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -7852,6 +8068,11 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@0.263.1: + resolution: {integrity: sha512-keqxAx97PlaEN89PXZ6ki1N8nRjGWtDa4021GFYLNj0RgruM5odbpl8GHTExj0hhPq3sF6Up0gnxt6TSHu+ovw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 + luxon@3.7.2: resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} @@ -7976,6 +8197,10 @@ packages: memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -8252,6 +8477,10 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoevents@9.1.0: + resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} + engines: {node: ^18.0.0 || >=20.0.0} + nanoid@3.3.20: resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -8726,6 +8955,10 @@ packages: property-information@7.2.0: resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -8761,6 +8994,11 @@ packages: react-devtools-core@6.1.5: resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + react-dom@19.3.0: resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} peerDependencies: @@ -8923,6 +9161,16 @@ packages: peerDependencies: react: '>=19' + react-resizable-panels@4.17.0: + resolution: {integrity: sha512-ln2vGr4/cBmK8OllGpyaeo6sfeYvlzmCaE40RDVSAiyGpmgaYsxrI+EBy06Vo6bQBd17jcMKaEKOAA+w+i03bQ==} + peerDependencies: + '@types/react': ^18.2.6 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-router-dom@7.18.4: resolution: {integrity: sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==} engines: {node: '>=20.0.0'} @@ -8940,6 +9188,16 @@ packages: react-dom: optional: true + react-virtuoso@4.18.20: + resolution: {integrity: sha512-2G/Hdi/QHRtJtzSZOkAwJFdUzBmhNIQCAmw6gLGUZTGbjVL6+TOBIFJOCnpm6xgWGBfrrMiZV5rJNkQ9gEgAdQ==} + peerDependencies: + react: '>=16 || >=17 || >= 18 || >= 19' + react-dom: '>=16 || >=17 || >= 18 || >=19' + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + react@19.3.0: resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} engines: {node: '>=0.10.0'} @@ -9067,6 +9325,9 @@ packages: reselect@4.1.8: resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} + reselect@5.3.0: + resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -9126,6 +9387,10 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + rsbuild-plugin-dts@0.6.9: resolution: {integrity: sha512-mcB4mxfUqkHHzR5VV6PuXRGpLC1Gdly0BN/jRzbPmdWDtvfBO6LLOniiBzVVemibqs9gBQhl2OEilJs4Cyoq5w==} engines: {node: '>=16.7.0'} @@ -9239,6 +9504,10 @@ packages: resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + serialize-error@2.1.0: resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} engines: {node: '>=0.10.0'} @@ -9247,6 +9516,10 @@ packages: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} @@ -9541,6 +9814,9 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} @@ -9693,6 +9969,9 @@ packages: resolution: {integrity: sha512-GHx6WExIFSKNJ5qMlzDpXBXlu9ApxaMjqxAVrCNcW94xf/+uqgIz41SAuRUMbXva2ExNAaY/h8V0q90SWSzmRw==} hasBin: true + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} @@ -9822,6 +10101,11 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -11116,6 +11400,52 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@base-ui/react@1.9.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.29.7 + '@base-ui/utils': 0.5.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@floating-ui/react-dom': 2.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@floating-ui/utils': 0.2.12 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.7.0(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.17 + + '@base-ui/react@1.9.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.7 + '@base-ui/utils': 0.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@floating-ui/react-dom': 2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@floating-ui/utils': 0.2.12 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + use-sync-external-store: 1.7.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.2.17 + + '@base-ui/utils@0.5.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.29.7 + '@floating-ui/utils': 0.2.12 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + reselect: 5.3.0 + use-sync-external-store: 1.7.0(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.17 + + '@base-ui/utils@0.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.7 + '@floating-ui/utils': 0.2.12 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + reselect: 5.3.0 + use-sync-external-store: 1.7.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.2.17 + '@bcoe/v8-coverage@0.2.3': {} '@biomejs/biome@2.5.6': @@ -12061,6 +12391,29 @@ snapshots: type-is: 2.1.0 vary: 1.1.2 + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/react-dom@2.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@floating-ui/react-dom@2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@floating-ui/utils@0.2.12': {} + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -14221,6 +14574,189 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.62.2': optional: true + '@rozenite/agent-bridge@2.5.0(react@19.3.0)': + dependencies: + '@rozenite/agent-shared': 2.5.0 + '@rozenite/plugin-bridge': 2.5.0(react@19.3.0) + react: 19.3.0 + tslib: 2.8.1 + + '@rozenite/agent-shared@2.5.0': + dependencies: + '@rozenite/tools': 2.5.0 + tslib: 2.8.1 + + '@rozenite/app@2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0))': + dependencies: + '@rozenite/agent-shared': 2.5.0 + '@rozenite/plugin-bridge': 2.5.0(react@19.2.3) + '@rozenite/shell': 2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/tools': 2.5.0 + '@rozenite/ui': 2.5.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + - vitest + + '@rozenite/middleware@2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0))': + dependencies: + '@rozenite/agent-shared': 2.5.0 + '@rozenite/app': 2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/runtime': 2.5.0 + '@rozenite/shell': 2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/tools': 2.5.0 + express: 5.3.0 + semver: 7.8.5 + tslib: 2.8.1 + ws: 8.21.3 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - bufferutil + - date-fns + - supports-color + - utf-8-validate + - vitest + + '@rozenite/network-activity-plugin@2.5.0(@types/react@19.2.17)(expo@58.0.13)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@rozenite/agent-bridge': 2.5.0(react@19.3.0) + '@rozenite/agent-shared': 2.5.0 + '@rozenite/plugin-bridge': 2.5.0(react@19.3.0) + '@rozenite/ui': 2.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + base64-js: 1.5.1 + nanoevents: 9.1.0 + optionalDependencies: + expo: 58.0.13(@babel/core@7.29.7)(@expo/metro-runtime@58.0.14)(expo-router@58.0.22)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0)(typescript@7.0.2) + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + - react + - react-dom + + '@rozenite/plugin-bridge@2.5.0(react@19.2.3)': + dependencies: + react: 19.2.3 + tslib: 2.8.1 + + '@rozenite/plugin-bridge@2.5.0(react@19.3.0)': + dependencies: + react: 19.3.0 + tslib: 2.8.1 + + '@rozenite/react-navigation-plugin@2.5.0(@react-navigation/core@7.21.11(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@react-navigation/core': 7.21.11(react@19.3.0) + '@rozenite/agent-bridge': 2.5.0(react@19.3.0) + '@rozenite/agent-shared': 2.5.0 + '@rozenite/plugin-bridge': 2.5.0(react@19.3.0) + '@rozenite/ui': 2.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + fast-deep-equal: 3.1.3 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + - react + - react-dom + + '@rozenite/repack@2.5.0(@callstack/repack@packages+repack)(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0))': + dependencies: + '@callstack/repack': link:packages/repack + '@rozenite/middleware': 2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0)) + '@rozenite/runtime': 2.5.0 + '@rozenite/tools': 2.5.0 + semver: 7.8.5 + tslib: 2.8.1 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - bufferutil + - date-fns + - supports-color + - utf-8-validate + - vitest + + '@rozenite/runtime@2.5.0': + dependencies: + '@rozenite/tools': 2.5.0 + tslib: 2.8.1 + + '@rozenite/shell@2.5.0(@types/react@19.2.17)(vitest@4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0))': + dependencies: + '@rozenite/plugin-bridge': 2.5.0(react@19.2.3) + '@rozenite/ui': 2.5.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + lucide-react: 0.263.1(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + vitest: 4.1.11(@types/node@26.1.1)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + + '@rozenite/storage-plugin@2.5.0(@react-native-async-storage/async-storage@3.1.1(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0))(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0)': + dependencies: + '@rozenite/agent-bridge': 2.5.0(react@19.3.0) + '@rozenite/agent-shared': 2.5.0 + '@rozenite/plugin-bridge': 2.5.0(react@19.3.0) + '@rozenite/ui': 2.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react: 19.3.0 + react-native: 0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0) + optionalDependencies: + '@react-native-async-storage/async-storage': 3.1.1(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.3.0))(react@19.3.0) + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + - react-dom + + '@rozenite/tools@2.5.0': {} + + '@rozenite/ui@2.5.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@base-ui/react': 1.9.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-table': 8.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + class-variance-authority: 0.7.1 + clsx: 2.1.1 + lucide-react: 0.263.1(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-resizable-panels: 4.17.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react-virtuoso: 4.18.20(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tailwind-merge: 3.6.0 + tailwindcss: 4.2.2 + tslib: 2.8.1 + tw-animate-css: 1.4.0 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + + '@rozenite/ui@2.5.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@base-ui/react': 1.9.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-table': 8.21.3(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + class-variance-authority: 0.7.1 + clsx: 2.1.1 + lucide-react: 0.263.1(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react-resizable-panels: 4.17.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react-virtuoso: 4.18.20(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + tailwind-merge: 3.6.0 + tailwindcss: 4.2.2 + tslib: 2.8.1 + tw-animate-css: 1.4.0 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - date-fns + '@rsbuild/core@1.3.18': dependencies: '@rspack/core': 1.3.9(@swc/helpers@0.5.23) @@ -15005,6 +15541,20 @@ snapshots: dependencies: '@swc/counter': 0.1.3 + '@tanstack/react-table@8.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/table-core': 8.21.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@tanstack/react-table@8.21.3(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/table-core': 8.21.3 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@tanstack/table-core@8.21.3': {} + '@turbo/darwin-64@2.10.7': optional: true @@ -16163,12 +16713,16 @@ snapshots: content-disposition@1.0.1: {} + content-disposition@2.0.1: {} + content-type@1.0.5: {} content-type@2.0.0: {} convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} + cookie@0.7.2: {} cookie@1.1.1: {} @@ -16984,6 +17538,39 @@ snapshots: exponential-backoff@3.1.3: {} + express@5.3.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 2.0.1 + content-type: 2.0.0 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + extend@3.0.2: {} fast-decode-uri-component@1.0.1: {} @@ -17114,6 +17701,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + find-babel-config@2.1.2: dependencies: json5: 2.2.3 @@ -17207,6 +17805,8 @@ snapshots: fresh@0.5.2: {} + fresh@2.0.0: {} + fs-extra@11.4.0: dependencies: graceful-fs: 4.2.11 @@ -17665,6 +18265,8 @@ snapshots: iobuffer@6.0.1: {} + ipaddr.js@1.9.1: {} + ipaddr.js@2.4.0: {} is-absolute-url@4.0.1: {} @@ -17734,6 +18336,8 @@ snapshots: is-plain-object@5.0.0: {} + is-promise@4.0.0: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -18520,6 +19124,14 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@0.263.1(react@19.2.3): + dependencies: + react: 19.2.3 + + lucide-react@0.263.1(react@19.3.0): + dependencies: + react: 19.3.0 + luxon@3.7.2: {} magic-string@0.30.21: @@ -18763,6 +19375,8 @@ snapshots: memoize-one@5.2.1: {} + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -19290,6 +19904,8 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nanoevents@9.1.0: {} + nanoid@3.3.20: {} nativewind@4.2.6(65131ab4b69ad60b869660d529711dc4): @@ -19306,12 +19922,12 @@ snapshots: - react-native-svg - supports-color - nativewind@4.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)): + nativewind@4.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2): dependencies: comment-json: 4.6.2 debug: 4.4.3 - react-native-css-interop: 0.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)) - tailwindcss: 3.4.19(yaml@2.9.0) + react-native-css-interop: 0.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2) + tailwindcss: 4.2.2 transitivePeerDependencies: - react - react-native @@ -19801,6 +20417,11 @@ snapshots: property-information@7.2.0: {} + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + proxy-from-env@2.1.0: {} pure-rand@6.1.0: {} @@ -19840,6 +20461,11 @@ snapshots: - bufferutil - utf-8-validate + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + react-dom@19.3.0(react@19.3.0): dependencies: react: 19.3.0 @@ -19859,7 +20485,7 @@ snapshots: react-lazy-with-preload@2.2.1: {} - react-native-css-interop@0.1.22(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)): + react-native-css-interop@0.1.22(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2): dependencies: '@babel/helper-module-imports': 7.29.7 '@babel/traverse': 7.29.7 @@ -19870,7 +20496,7 @@ snapshots: react-native: 0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0) react-native-reanimated: 4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0) semver: 7.8.5 - tailwindcss: 3.4.19(yaml@2.9.0) + tailwindcss: 4.2.2 transitivePeerDependencies: - supports-color @@ -19892,7 +20518,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-css-interop@0.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@3.4.19(yaml@2.9.0)): + react-native-css-interop@0.2.6(react-native-reanimated@4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0)(tailwindcss@4.2.2): dependencies: '@babel/helper-module-imports': 7.29.7 '@babel/traverse': 7.29.7 @@ -19903,7 +20529,7 @@ snapshots: react-native: 0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0) react-native-reanimated: 4.7.1(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7)(@react-native-community/cli@20.2.0(typescript@7.0.2))(@react-native/metro-config@0.88.0(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.0))(react@19.3.0) semver: 7.8.5 - tailwindcss: 3.4.19(yaml@2.9.0) + tailwindcss: 4.2.2 transitivePeerDependencies: - supports-color @@ -20162,6 +20788,20 @@ snapshots: react: 19.3.0 react-reconciler: 0.33.0(react@19.3.0) + react-resizable-panels@4.17.0(@types/react@19.2.17)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.17 + + react-resizable-panels@4.17.0(@types/react@19.2.17)(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.2.17 + react-router-dom@7.18.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0): dependencies: react: 19.3.0 @@ -20176,6 +20816,18 @@ snapshots: optionalDependencies: react-dom: 19.3.0(react@19.3.0) + react-virtuoso@4.18.20(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + react-virtuoso@4.18.20(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + react@19.2.3: {} + react@19.3.0: {} read-cache@1.0.0: @@ -20355,6 +21007,8 @@ snapshots: reselect@4.1.8: {} + reselect@5.3.0: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -20434,6 +21088,16 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.62.2 fsevents: 2.3.3 + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + rsbuild-plugin-dts@0.6.9(@rsbuild/core@1.3.18)(typescript@7.0.2): dependencies: '@ast-grep/napi': 0.37.0 @@ -20537,6 +21201,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + serialize-error@2.1.0: {} serve-static@1.16.3: @@ -20548,6 +21228,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + server-only@0.0.1: {} set-blocking@2.0.0: {} @@ -20873,6 +21562,8 @@ snapshots: - tsx - yaml + tailwindcss@4.2.2: {} + tapable@2.3.0: {} tapable@2.3.3: {} @@ -21013,6 +21704,8 @@ snapshots: '@turbo/windows-64': 2.10.7 '@turbo/windows-arm64': 2.10.7 + tw-animate-css@1.4.0: {} + type-detect@4.0.8: {} type-detect@4.1.0: {} @@ -21149,6 +21842,14 @@ snapshots: dependencies: react: 19.3.0 + use-sync-external-store@1.7.0(react@19.2.3): + dependencies: + react: 19.2.3 + + use-sync-external-store@1.7.0(react@19.3.0): + dependencies: + react: 19.3.0 + util-deprecate@1.0.2: {} utils-merge@1.0.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2b91bf139..e41e2aa30 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -90,3 +90,7 @@ catalogs: "react-native-safe-area-context": "5.10.1" "react-native-screens": "4.30.0" "react-native-worklets": "0.13.0" + "@rozenite/network-activity-plugin": "2.5.0" + "@rozenite/react-navigation-plugin": "2.5.0" + "@rozenite/repack": "2.5.0" + "@rozenite/storage-plugin": "2.5.0" From 4b4f357df3be2865c5b5a2772c8d76353b8d4d7e Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Wed, 4 Nov 2026 12:04:08 +0000 Subject: [PATCH 2/2] chore(testers): only load Rozenite when WITH_ROZENITE is set The tester configs imported @rozenite/repack and the apps imported the Rozenite plugins in every run, so default dev runs and E2E builds bundled and ran DevTools code even with the flag off. Configs now import @rozenite/repack only when WITH_ROZENITE=true, and each tester requires its plugins from rozenitePlugins.ts behind a __WITH_ROZENITE__ define, so the bundler drops them otherwise. Documented in CONTRIBUTING.md and AGENTS.md. --- AGENTS.md | 2 ++ CONTRIBUTING.md | 2 ++ apps/tester-app/index.js | 4 +-- apps/tester-app/rspack.config.mjs | 12 +++++--- apps/tester-app/src/App.tsx | 4 +-- apps/tester-app/src/global.d.ts | 2 ++ apps/tester-app/src/rozenite.ts | 8 ++++++ apps/tester-app/src/rozenitePlugins.ts | 12 ++++++++ apps/tester-app/webpack.config.mjs | 12 +++++--- apps/tester-expo/app/_layout.tsx | 4 +-- apps/tester-expo/components/rozenite.ts | 7 +++++ .../tester-expo/components/rozenitePlugins.ts | 5 ++++ apps/tester-expo/rspack.config.mjs | 19 ++++++++----- apps/tester-expo/types/globals.d.ts | 1 + apps/tester-federation-v2/config.host-app.mts | 8 +++--- .../configs/rspack.host-app.mts | 1 + .../configs/webpack.host-app.mts | 1 + apps/tester-federation-v2/src/globals.d.ts | 1 + apps/tester-federation-v2/src/host/App.tsx | 17 ++--------- apps/tester-federation-v2/src/host/index.js | 4 +-- .../tester-federation-v2/src/host/rozenite.ts | 8 ++++++ .../src/host/rozenitePlugins.ts | 28 +++++++++++++++++++ apps/tester-federation/config.host-app.mts | 8 +++--- .../configs/rspack.host-app.mts | 3 ++ .../configs/webpack.host-app.mts | 3 ++ apps/tester-federation/src/globals.d.ts | 1 + apps/tester-federation/src/host/App.tsx | 17 ++--------- apps/tester-federation/src/host/index.js | 4 +-- apps/tester-federation/src/host/rozenite.ts | 8 ++++++ .../src/host/rozenitePlugins.ts | 28 +++++++++++++++++++ 30 files changed, 171 insertions(+), 63 deletions(-) create mode 100644 apps/tester-app/src/rozenite.ts create mode 100644 apps/tester-app/src/rozenitePlugins.ts create mode 100644 apps/tester-expo/components/rozenite.ts create mode 100644 apps/tester-expo/components/rozenitePlugins.ts create mode 100644 apps/tester-expo/types/globals.d.ts create mode 100644 apps/tester-federation-v2/src/host/rozenite.ts create mode 100644 apps/tester-federation-v2/src/host/rozenitePlugins.ts create mode 100644 apps/tester-federation/src/globals.d.ts create mode 100644 apps/tester-federation/src/host/rozenite.ts create mode 100644 apps/tester-federation/src/host/rozenitePlugins.ts diff --git a/AGENTS.md b/AGENTS.md index afc7276ab..36382cfd8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,8 @@ Re.Pack is a toolkit for building and developing React Native applications with - `apps/tester-federation/`: Module Federation v1 validation app. - `apps/tester-federation-v2/`: Module Federation v2 validation app. +Rozenite DevTools in the tester apps are opt-in (`WITH_ROZENITE=true`); keep plugin imports in each tester's `rozenitePlugins.ts` so default and E2E runs never load them (see `CONTRIBUTING.md`). + ### Tests - `tests/integration/`: Integration-level automated coverage. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a2a202510..4c168d365 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,8 @@ All development is done directly on GitHub, and all work is public. To get extra [Rozenite](https://www.rozenite.dev) panels (network activity, plus navigation and storage in the Module Federation hosts) in React Native DevTools while testing, start a tester app's dev server with `WITH_ROZENITE=true`, e.g. `WITH_ROZENITE=true pnpm start`. +Without the flag, nothing Rozenite-related is loaded by the dev server or bundled into the app, so default runs and E2E tests are unaffected. Keep it that way when adding a plugin: import it only from the tester's `rozenitePlugins.ts`, which is required only when `__WITH_ROZENITE__` is true. + ### Commit message convention We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: diff --git a/apps/tester-app/index.js b/apps/tester-app/index.js index 51cef7418..1faffab41 100644 --- a/apps/tester-app/index.js +++ b/apps/tester-app/index.js @@ -1,11 +1,11 @@ -import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry } from 'react-native'; import { name as appName } from './app.json'; import App from './src/App'; +import { startDevTools } from './src/rozenite'; // ScriptManager setup import './src/setup'; -withOnBootNetworkActivityRecording(); +startDevTools(); AppRegistry.registerComponent(appName, () => App); diff --git a/apps/tester-app/rspack.config.mjs b/apps/tester-app/rspack.config.mjs index 1432943f5..a9cafe7d3 100644 --- a/apps/tester-app/rspack.config.mjs +++ b/apps/tester-app/rspack.config.mjs @@ -2,7 +2,7 @@ import path from 'node:path'; import * as Repack from '@callstack/repack'; import { NativeWindPlugin } from '@callstack/repack-plugin-nativewind'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; -import { withRozenite } from '@rozenite/repack'; +import { DefinePlugin } from '@rspack/core'; // Rsdoctor (through rslog) throws on import under Node < 20, so only load it // when it's actually enabled to keep the Node 18 test matrix working. @@ -10,6 +10,8 @@ const { RsdoctorRspackPlugin } = process.env.RSDOCTOR ? await import('@rsdoctor/rspack-plugin') : {}; +const withDevTools = process.env.WITH_ROZENITE === 'true'; + const dirname = Repack.getDirname(import.meta.url); const config = Repack.defineRspackConfig((env) => { @@ -131,11 +133,13 @@ const config = Repack.defineRspackConfig((env) => { unstable_disableTransform: true, }), new NativeWindPlugin({ cssInteropOptions: { inlineRem: 16 } }), + new DefinePlugin({ __WITH_ROZENITE__: withDevTools }), process.env.RSDOCTOR && new RsdoctorRspackPlugin(), ].filter(Boolean), }; }); -export default withRozenite(config, { - enabled: process.env.WITH_ROZENITE === 'true', -}); +// Rozenite is only loaded with WITH_ROZENITE=true (see CONTRIBUTING.md). +export default withDevTools + ? (await import('@rozenite/repack')).withRozenite(config, { enabled: true }) + : config; diff --git a/apps/tester-app/src/App.tsx b/apps/tester-app/src/App.tsx index 3de6da3d1..66da82398 100644 --- a/apps/tester-app/src/App.tsx +++ b/apps/tester-app/src/App.tsx @@ -1,4 +1,3 @@ -import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; import { Appearance } from 'react-native'; // nativewind styles @@ -10,6 +9,7 @@ import { MiniAppsContainer } from './miniapp/MiniAppsContainer'; import { NativeWindView } from './nativewind/NativeWindView'; import { ReanimatedBox } from './reanimated/ReanimatedBox'; import { RemoteContainer } from './remoteChunks/RemoteContainer'; +import { useDevTools } from './rozenite'; import { AppContainer } from './ui/AppContainer'; import { Section } from './ui/Section'; import { SectionContainer } from './ui/SectionContainer'; @@ -17,7 +17,7 @@ import { SectionContainer } from './ui/SectionContainer'; Appearance.setColorScheme('light'); const App = () => { - useNetworkActivityDevTools(); + useDevTools(); return ( diff --git a/apps/tester-app/src/global.d.ts b/apps/tester-app/src/global.d.ts index e238d01ca..a589e5a84 100644 --- a/apps/tester-app/src/global.d.ts +++ b/apps/tester-app/src/global.d.ts @@ -1,2 +1,4 @@ declare module '*.png'; declare module '*.svg'; + +declare const __WITH_ROZENITE__: boolean; diff --git a/apps/tester-app/src/rozenite.ts b/apps/tester-app/src/rozenite.ts new file mode 100644 index 000000000..e35a6f2c5 --- /dev/null +++ b/apps/tester-app/src/rozenite.ts @@ -0,0 +1,8 @@ +// Rozenite DevTools plugins are opt-in. `__WITH_ROZENITE__` is only true when +// the dev server runs with WITH_ROZENITE=true; otherwise the bundler drops the +// require below and the app (including E2E runs) contains no DevTools code. +const plugins: typeof import('./rozenitePlugins') | undefined = + __WITH_ROZENITE__ ? require('./rozenitePlugins') : undefined; + +export const startDevTools = plugins?.startDevTools ?? (() => {}); +export const useDevTools = plugins?.useDevTools ?? (() => {}); diff --git a/apps/tester-app/src/rozenitePlugins.ts b/apps/tester-app/src/rozenitePlugins.ts new file mode 100644 index 000000000..03697481a --- /dev/null +++ b/apps/tester-app/src/rozenitePlugins.ts @@ -0,0 +1,12 @@ +import { + useNetworkActivityDevTools, + withOnBootNetworkActivityRecording, +} from '@rozenite/network-activity-plugin'; + +export function startDevTools() { + withOnBootNetworkActivityRecording(); +} + +export function useDevTools() { + useNetworkActivityDevTools(); +} diff --git a/apps/tester-app/webpack.config.mjs b/apps/tester-app/webpack.config.mjs index bcc0bd798..0eb57efb6 100644 --- a/apps/tester-app/webpack.config.mjs +++ b/apps/tester-app/webpack.config.mjs @@ -2,8 +2,10 @@ import path from 'node:path'; import * as Repack from '@callstack/repack'; import { NativeWindPlugin } from '@callstack/repack-plugin-nativewind'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; -import { withRozenite } from '@rozenite/repack'; import TerserPlugin from 'terser-webpack-plugin'; +import webpack from 'webpack'; + +const withDevTools = process.env.WITH_ROZENITE === 'true'; const dirname = Repack.getDirname(import.meta.url); @@ -131,10 +133,12 @@ const config = Repack.defineWebpackConfig((env) => { }), new ReanimatedPlugin(), new NativeWindPlugin(), + new webpack.DefinePlugin({ __WITH_ROZENITE__: withDevTools }), ], }; }); -export default withRozenite(config, { - enabled: process.env.WITH_ROZENITE === 'true', -}); +// Rozenite is only loaded with WITH_ROZENITE=true (see CONTRIBUTING.md). +export default withDevTools + ? (await import('@rozenite/repack')).withRozenite(config, { enabled: true }) + : config; diff --git a/apps/tester-expo/app/_layout.tsx b/apps/tester-expo/app/_layout.tsx index 47d437509..2a5ef9164 100644 --- a/apps/tester-expo/app/_layout.tsx +++ b/apps/tester-expo/app/_layout.tsx @@ -1,8 +1,8 @@ -import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; import { Stack } from 'expo-router'; +import { useDevTools } from '../components/rozenite'; export default function RootLayout() { - useNetworkActivityDevTools(); + useDevTools(); return ; } diff --git a/apps/tester-expo/components/rozenite.ts b/apps/tester-expo/components/rozenite.ts new file mode 100644 index 000000000..668a18965 --- /dev/null +++ b/apps/tester-expo/components/rozenite.ts @@ -0,0 +1,7 @@ +// Rozenite DevTools plugins are opt-in. `__WITH_ROZENITE__` is only true when +// the dev server runs with WITH_ROZENITE=true; otherwise the bundler drops the +// require below and the app contains no DevTools code. +const plugins: typeof import('./rozenitePlugins') | undefined = + __WITH_ROZENITE__ ? require('./rozenitePlugins') : undefined; + +export const useDevTools = plugins?.useDevTools ?? (() => {}); diff --git a/apps/tester-expo/components/rozenitePlugins.ts b/apps/tester-expo/components/rozenitePlugins.ts new file mode 100644 index 000000000..1ca61a2b4 --- /dev/null +++ b/apps/tester-expo/components/rozenitePlugins.ts @@ -0,0 +1,5 @@ +import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; + +export function useDevTools() { + useNetworkActivityDevTools(); +} diff --git a/apps/tester-expo/rspack.config.mjs b/apps/tester-expo/rspack.config.mjs index e94818c9a..605cb612d 100644 --- a/apps/tester-expo/rspack.config.mjs +++ b/apps/tester-expo/rspack.config.mjs @@ -4,9 +4,10 @@ import { fileURLToPath } from 'node:url'; import * as Repack from '@callstack/repack'; import { ExpoPlugin } from '@callstack/repack-expo/rspack'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; -import { withRozenite } from '@rozenite/repack'; +import { DefinePlugin } from '@rspack/core'; const require = createRequire(import.meta.url); +const withDevTools = process.env.WITH_ROZENITE === 'true'; const projectRoot = path.dirname(fileURLToPath(import.meta.url)); // Must match the widget's shared list. Versions come from the installed @@ -44,6 +45,7 @@ const config = (env) => { plugins: [ new ReanimatedPlugin({ unstable_disableTransform: true }), new ExpoPlugin({ platform }), + new DefinePlugin({ __WITH_ROZENITE__: withDevTools }), new Repack.plugins.ModuleFederationPluginV2({ name: 'ExpoHost', dts: false, @@ -66,9 +68,12 @@ const config = (env) => { }; }; -export default withRozenite(config, { - enabled: process.env.WITH_ROZENITE === 'true', - // Re.Pack serves DevTools through React Native's dev-middleware, not the copy - // bundled with Expo's CLI, so Rozenite has to patch that one. - projectType: 'react-native-cli', -}); +// Rozenite is only loaded with WITH_ROZENITE=true (see CONTRIBUTING.md). +export default withDevTools + ? (await import('@rozenite/repack')).withRozenite(config, { + enabled: true, + // Re.Pack serves DevTools through React Native's dev-middleware, not the + // copy bundled with Expo's CLI, so Rozenite has to patch that one. + projectType: 'react-native-cli', + }) + : config; diff --git a/apps/tester-expo/types/globals.d.ts b/apps/tester-expo/types/globals.d.ts new file mode 100644 index 000000000..9bd6b3a4e --- /dev/null +++ b/apps/tester-expo/types/globals.d.ts @@ -0,0 +1 @@ +declare const __WITH_ROZENITE__: boolean; diff --git a/apps/tester-federation-v2/config.host-app.mts b/apps/tester-federation-v2/config.host-app.mts index c3654b22d..e9b43d083 100644 --- a/apps/tester-federation-v2/config.host-app.mts +++ b/apps/tester-federation-v2/config.host-app.mts @@ -1,7 +1,6 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import type * as Repack from '@callstack/repack'; -import { withRozenite } from '@rozenite/repack'; import rspackConfig from './configs/rspack.host-app.mts'; import webpackConfig from './configs/webpack.host-app.mts'; @@ -17,6 +16,7 @@ const config = (env: Repack.EnvOptions) => { return useWebpack ? webpackConfig(env) : rspackConfig(env); }; -export default withRozenite(config, { - enabled: process.env.WITH_ROZENITE === 'true', -}); +// Rozenite is only loaded with WITH_ROZENITE=true (see CONTRIBUTING.md). +export default process.env.WITH_ROZENITE === 'true' + ? (await import('@rozenite/repack')).withRozenite(config, { enabled: true }) + : config; diff --git a/apps/tester-federation-v2/configs/rspack.host-app.mts b/apps/tester-federation-v2/configs/rspack.host-app.mts index 138dbf24c..7e81ef40f 100644 --- a/apps/tester-federation-v2/configs/rspack.host-app.mts +++ b/apps/tester-federation-v2/configs/rspack.host-app.mts @@ -58,6 +58,7 @@ export default Repack.defineRspackConfig((env) => { resourceRegExp: /^@react-native-masked-view/, }), new rspack.DefinePlugin({ + __WITH_ROZENITE__: process.env.WITH_ROZENITE === 'true', __WITH_PRELOAD__: process.env.WITH_PRELOAD === 'true' || process.env.WITH_PRELOAD === '1', diff --git a/apps/tester-federation-v2/configs/webpack.host-app.mts b/apps/tester-federation-v2/configs/webpack.host-app.mts index 45ac79aed..c529498e7 100644 --- a/apps/tester-federation-v2/configs/webpack.host-app.mts +++ b/apps/tester-federation-v2/configs/webpack.host-app.mts @@ -54,6 +54,7 @@ export default Repack.defineWebpackConfig((env) => { resourceRegExp: /^@react-native-masked-view/, }), new webpack.DefinePlugin({ + __WITH_ROZENITE__: process.env.WITH_ROZENITE === 'true', __WITH_PRELOAD__: process.env.WITH_PRELOAD === 'true' || process.env.WITH_PRELOAD === '1', diff --git a/apps/tester-federation-v2/src/globals.d.ts b/apps/tester-federation-v2/src/globals.d.ts index f51151309..c26fc67d0 100644 --- a/apps/tester-federation-v2/src/globals.d.ts +++ b/apps/tester-federation-v2/src/globals.d.ts @@ -6,3 +6,4 @@ declare module 'MiniApp/MiniAppNavigator' { const MiniAppNavigator: ComponentType; export default MiniAppNavigator; } +declare const __WITH_ROZENITE__: boolean; diff --git a/apps/tester-federation-v2/src/host/App.tsx b/apps/tester-federation-v2/src/host/App.tsx index 014c41058..b333f15ed 100644 --- a/apps/tester-federation-v2/src/host/App.tsx +++ b/apps/tester-federation-v2/src/host/App.tsx @@ -1,27 +1,14 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer, useNavigationContainerRef, } from '@react-navigation/native'; -import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; -import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; -import { - createAsyncStorageAdapter, - useRozeniteStoragePlugin, -} from '@rozenite/storage-plugin'; import MainNavigator from './navigation/MainNavigator'; - -// ScriptManager caches remote scripts in AsyncStorage (see index.js). -const storages = [ - createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), -]; +import { useDevTools } from './rozenite'; const App = () => { const navigationRef = useNavigationContainerRef(); - useNetworkActivityDevTools(); - useReactNavigationDevTools({ ref: navigationRef }); - useRozeniteStoragePlugin({ storages }); + useDevTools(navigationRef); return ( diff --git a/apps/tester-federation-v2/src/host/index.js b/apps/tester-federation-v2/src/host/index.js index ec2981a48..7091e6bf6 100644 --- a/apps/tester-federation-v2/src/host/index.js +++ b/apps/tester-federation-v2/src/host/index.js @@ -1,13 +1,13 @@ import { ScriptManager } from '@callstack/repack/client'; import { preloadRemote } from '@module-federation/runtime'; import AsyncStorage from '@react-native-async-storage/async-storage'; -import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry } from 'react-native'; import { components } from '../../app.json'; import App from './App'; +import { startDevTools } from './rozenite'; -withOnBootNetworkActivityRecording(); +startDevTools(); if (__WITH_PRELOAD__) { // enable caching of scripts in the AsyncStorage diff --git a/apps/tester-federation-v2/src/host/rozenite.ts b/apps/tester-federation-v2/src/host/rozenite.ts new file mode 100644 index 000000000..e35a6f2c5 --- /dev/null +++ b/apps/tester-federation-v2/src/host/rozenite.ts @@ -0,0 +1,8 @@ +// Rozenite DevTools plugins are opt-in. `__WITH_ROZENITE__` is only true when +// the dev server runs with WITH_ROZENITE=true; otherwise the bundler drops the +// require below and the app (including E2E runs) contains no DevTools code. +const plugins: typeof import('./rozenitePlugins') | undefined = + __WITH_ROZENITE__ ? require('./rozenitePlugins') : undefined; + +export const startDevTools = plugins?.startDevTools ?? (() => {}); +export const useDevTools = plugins?.useDevTools ?? (() => {}); diff --git a/apps/tester-federation-v2/src/host/rozenitePlugins.ts b/apps/tester-federation-v2/src/host/rozenitePlugins.ts new file mode 100644 index 000000000..3bf3dbd79 --- /dev/null +++ b/apps/tester-federation-v2/src/host/rozenitePlugins.ts @@ -0,0 +1,28 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import type { NavigationContainerRefWithCurrent } from '@react-navigation/native'; +import { + useNetworkActivityDevTools, + withOnBootNetworkActivityRecording, +} from '@rozenite/network-activity-plugin'; +import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; +import { + createAsyncStorageAdapter, + useRozeniteStoragePlugin, +} from '@rozenite/storage-plugin'; + +// ScriptManager caches remote scripts in AsyncStorage (see index.js). +const storages = [ + createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), +]; + +export function startDevTools() { + withOnBootNetworkActivityRecording(); +} + +export function useDevTools( + navigationRef: NavigationContainerRefWithCurrent +) { + useNetworkActivityDevTools(); + useReactNavigationDevTools({ ref: navigationRef }); + useRozeniteStoragePlugin({ storages }); +} diff --git a/apps/tester-federation/config.host-app.mts b/apps/tester-federation/config.host-app.mts index c3654b22d..e9b43d083 100644 --- a/apps/tester-federation/config.host-app.mts +++ b/apps/tester-federation/config.host-app.mts @@ -1,7 +1,6 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import type * as Repack from '@callstack/repack'; -import { withRozenite } from '@rozenite/repack'; import rspackConfig from './configs/rspack.host-app.mts'; import webpackConfig from './configs/webpack.host-app.mts'; @@ -17,6 +16,7 @@ const config = (env: Repack.EnvOptions) => { return useWebpack ? webpackConfig(env) : rspackConfig(env); }; -export default withRozenite(config, { - enabled: process.env.WITH_ROZENITE === 'true', -}); +// Rozenite is only loaded with WITH_ROZENITE=true (see CONTRIBUTING.md). +export default process.env.WITH_ROZENITE === 'true' + ? (await import('@rozenite/repack')).withRozenite(config, { enabled: true }) + : config; diff --git a/apps/tester-federation/configs/rspack.host-app.mts b/apps/tester-federation/configs/rspack.host-app.mts index 238dc550a..392d88d2c 100644 --- a/apps/tester-federation/configs/rspack.host-app.mts +++ b/apps/tester-federation/configs/rspack.host-app.mts @@ -32,6 +32,9 @@ export default Repack.defineRspackConfig((env) => { ], }, plugins: [ + new rspack.DefinePlugin({ + __WITH_ROZENITE__: process.env.WITH_ROZENITE === 'true', + }), new Repack.RepackPlugin({ extraChunks: [ { diff --git a/apps/tester-federation/configs/webpack.host-app.mts b/apps/tester-federation/configs/webpack.host-app.mts index 299887b48..a53c17f00 100644 --- a/apps/tester-federation/configs/webpack.host-app.mts +++ b/apps/tester-federation/configs/webpack.host-app.mts @@ -27,6 +27,9 @@ export default Repack.defineWebpackConfig((env) => { ], }, plugins: [ + new webpack.DefinePlugin({ + __WITH_ROZENITE__: process.env.WITH_ROZENITE === 'true', + }), // @ts-expect-error new Repack.RepackPlugin({ extraChunks: [ diff --git a/apps/tester-federation/src/globals.d.ts b/apps/tester-federation/src/globals.d.ts new file mode 100644 index 000000000..9bd6b3a4e --- /dev/null +++ b/apps/tester-federation/src/globals.d.ts @@ -0,0 +1 @@ +declare const __WITH_ROZENITE__: boolean; diff --git a/apps/tester-federation/src/host/App.tsx b/apps/tester-federation/src/host/App.tsx index 014c41058..b333f15ed 100644 --- a/apps/tester-federation/src/host/App.tsx +++ b/apps/tester-federation/src/host/App.tsx @@ -1,27 +1,14 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer, useNavigationContainerRef, } from '@react-navigation/native'; -import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin'; -import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; -import { - createAsyncStorageAdapter, - useRozeniteStoragePlugin, -} from '@rozenite/storage-plugin'; import MainNavigator from './navigation/MainNavigator'; - -// ScriptManager caches remote scripts in AsyncStorage (see index.js). -const storages = [ - createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), -]; +import { useDevTools } from './rozenite'; const App = () => { const navigationRef = useNavigationContainerRef(); - useNetworkActivityDevTools(); - useReactNavigationDevTools({ ref: navigationRef }); - useRozeniteStoragePlugin({ storages }); + useDevTools(navigationRef); return ( diff --git a/apps/tester-federation/src/host/index.js b/apps/tester-federation/src/host/index.js index 569c9af84..ff432d5a0 100644 --- a/apps/tester-federation/src/host/index.js +++ b/apps/tester-federation/src/host/index.js @@ -1,12 +1,12 @@ import { Federated, ScriptManager } from '@callstack/repack/client'; import AsyncStorage from '@react-native-async-storage/async-storage'; -import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin'; import { AppRegistry, Platform } from 'react-native'; import { components } from '../../app.json'; import App from './App'; +import { startDevTools } from './rozenite'; -withOnBootNetworkActivityRecording(); +startDevTools(); ScriptManager.shared.setStorage(AsyncStorage); diff --git a/apps/tester-federation/src/host/rozenite.ts b/apps/tester-federation/src/host/rozenite.ts new file mode 100644 index 000000000..e35a6f2c5 --- /dev/null +++ b/apps/tester-federation/src/host/rozenite.ts @@ -0,0 +1,8 @@ +// Rozenite DevTools plugins are opt-in. `__WITH_ROZENITE__` is only true when +// the dev server runs with WITH_ROZENITE=true; otherwise the bundler drops the +// require below and the app (including E2E runs) contains no DevTools code. +const plugins: typeof import('./rozenitePlugins') | undefined = + __WITH_ROZENITE__ ? require('./rozenitePlugins') : undefined; + +export const startDevTools = plugins?.startDevTools ?? (() => {}); +export const useDevTools = plugins?.useDevTools ?? (() => {}); diff --git a/apps/tester-federation/src/host/rozenitePlugins.ts b/apps/tester-federation/src/host/rozenitePlugins.ts new file mode 100644 index 000000000..3bf3dbd79 --- /dev/null +++ b/apps/tester-federation/src/host/rozenitePlugins.ts @@ -0,0 +1,28 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import type { NavigationContainerRefWithCurrent } from '@react-navigation/native'; +import { + useNetworkActivityDevTools, + withOnBootNetworkActivityRecording, +} from '@rozenite/network-activity-plugin'; +import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin'; +import { + createAsyncStorageAdapter, + useRozeniteStoragePlugin, +} from '@rozenite/storage-plugin'; + +// ScriptManager caches remote scripts in AsyncStorage (see index.js). +const storages = [ + createAsyncStorageAdapter({ storages: { ScriptManager: AsyncStorage } }), +]; + +export function startDevTools() { + withOnBootNetworkActivityRecording(); +} + +export function useDevTools( + navigationRef: NavigationContainerRefWithCurrent +) { + useNetworkActivityDevTools(); + useReactNavigationDevTools({ ref: navigationRef }); + useRozeniteStoragePlugin({ storages }); +}