Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/calm-bats-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@rozenite/redux-devtools-plugin": minor
---

Redux DevTools now uses Rozenite CDP/bridge messaging instead of the previous relay-based flow.

User-facing improvements:
- Better reliability for Redux DevTools controls in the plugin panel.
- Works with Rozenite for Web by enabling the plugin runtime on web targets.
- Supports naming store instances via `rozeniteDevToolsEnhancer({ name })`, making multi-store apps easier to debug.
- Playground now demonstrates two independent Redux stores and counters for easier validation.
4 changes: 2 additions & 2 deletions apps/playground/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { useMMKVDevTools } from '@rozenite/mmkv-plugin';
import { useNetworkActivityDevTools } from '@rozenite/network-activity-plugin';

Check warning on line 7 in apps/playground/src/app/App.tsx

View workflow job for this annotation

GitHub Actions / Validate

'/home/runner/work/rozenite/rozenite/apps/playground/node_modules/@rozenite/network-activity-plugin/dist/react-native.js' imported multiple times
import { usePerformanceMonitorDevTools } from '@rozenite/performance-monitor-plugin';
import { useReactNavigationDevTools } from '@rozenite/react-navigation-plugin';
import { useTanStackQueryDevTools } from '@rozenite/tanstack-query-plugin';
Expand All @@ -25,9 +25,9 @@
import { ReduxTestScreen } from './screens/ReduxTestScreen';
import { RequestBodyTestScreen } from './screens/RequestBodyTestScreen';
import { RequireProfilerTestScreen } from './screens/RequireProfilerTestScreen';
import { store } from './store';
import { primaryStore } from './store';
import { useRequireProfilerDevTools } from '@rozenite/require-profiler-plugin';
import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin';

Check warning on line 30 in apps/playground/src/app/App.tsx

View workflow job for this annotation

GitHub Actions / Validate

'/home/runner/work/rozenite/rozenite/apps/playground/node_modules/@rozenite/network-activity-plugin/dist/react-native.js' imported multiple times
import { RozeniteOverlay } from '@rozenite/overlay-plugin';

withOnBootNetworkActivityRecording();
Expand Down Expand Up @@ -128,7 +128,7 @@
});

return (
<Provider store={store}>
<Provider store={primaryStore}>
<QueryClientProvider client={queryClient}>
<SafeAreaProvider style={{ backgroundColor: '#0a0a0a' }}>
<NavigationContainer ref={navigationRef} linking={linking}>
Expand Down
126 changes: 74 additions & 52 deletions apps/playground/src/app/screens/ReduxTestScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,54 @@ import {
StyleSheet,
SafeAreaView,
} from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../store';
import { increment, decrement, reset } from '../store/counterSlice';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import { NavigationProp } from '../navigation/types';
import { decrement, increment, reset } from '../store/counterSlice';
import { primaryStore, secondaryStore, RootState } from '../store';

export const ReduxTestScreen = () => {
const navigation = useNavigation<NavigationProp>();
type CounterCardProps = {
title: string;
};

const CounterCard = ({ title }: CounterCardProps) => {
const dispatch = useDispatch();
const count = useSelector((state: RootState) => state.counter.value);

return (
<View style={styles.counterCard}>
<Text style={styles.counterTitle}>{title}</Text>
<Text style={styles.counterValue}>{count}</Text>

<View style={styles.buttonContainer}>
<TouchableOpacity
style={[styles.button, styles.decrementButton]}
onPress={() => dispatch(decrement())}
>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>

<TouchableOpacity
style={[styles.button, styles.incrementButton]}
onPress={() => dispatch(increment())}
>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>

<TouchableOpacity
style={[styles.button, styles.resetButton]}
onPress={() => dispatch(reset())}
>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
</View>
</View>
);
};

export const ReduxTestScreen = () => {
const navigation = useNavigation<NavigationProp>();

return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
Expand All @@ -25,44 +62,24 @@ export const ReduxTestScreen = () => {
>
<Text style={styles.backButtonText}>← Back</Text>
</TouchableOpacity>
<Text style={styles.title}>Redux Counter Test</Text>
<Text style={styles.title}>Redux Multi-Store Test</Text>
</View>

<View style={styles.content}>
<View style={styles.counterContainer}>
<Text style={styles.counterLabel}>Counter Value:</Text>
<Text style={styles.counterValue}>{count}</Text>
</View>

<View style={styles.buttonContainer}>
<TouchableOpacity
style={[styles.button, styles.decrementButton]}
onPress={() => dispatch(decrement())}
>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<Provider store={primaryStore}>
<CounterCard title="Primary Store Counter" />
</Provider>

<TouchableOpacity
style={[styles.button, styles.incrementButton]}
onPress={() => dispatch(increment())}
>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
</View>

<TouchableOpacity
style={[styles.button, styles.resetButton]}
onPress={() => dispatch(reset())}
>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
<Provider store={secondaryStore}>
<CounterCard title="Secondary Store Counter" />
</Provider>

<View style={styles.infoContainer}>
<Text style={styles.infoText}>
This counter uses Redux for state management.
This screen uses two independent Redux stores.
</Text>
<Text style={styles.infoText}>
Open the Redux DevTools to see the state changes in real-time.
Open Redux DevTools and switch instances to inspect each store.
</Text>
</View>
</View>
Expand Down Expand Up @@ -98,33 +115,39 @@ const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 20,
},
counterContainer: {
gap: 16,
},
counterCard: {
backgroundColor: '#141414',
borderRadius: 12,
borderWidth: 1,
borderColor: '#2b2b2b',
paddingVertical: 18,
paddingHorizontal: 16,
alignItems: 'center',
marginBottom: 40,
},
counterLabel: {
counterTitle: {
color: '#ccc',
fontSize: 16,
fontSize: 14,
marginBottom: 10,
},
counterValue: {
color: '#fff',
fontSize: 48,
fontSize: 40,
fontWeight: 'bold',
marginBottom: 12,
},
buttonContainer: {
flexDirection: 'row',
marginBottom: 20,
alignItems: 'center',
},
button: {
paddingHorizontal: 30,
paddingVertical: 15,
paddingHorizontal: 16,
paddingVertical: 10,
borderRadius: 8,
marginHorizontal: 10,
minWidth: 60,
marginHorizontal: 6,
minWidth: 56,
alignItems: 'center',
},
decrementButton: {
Expand All @@ -135,21 +158,20 @@ const styles = StyleSheet.create({
},
resetButton: {
backgroundColor: '#FF9500',
paddingHorizontal: 40,
},
buttonText: {
color: '#fff',
fontSize: 18,
fontSize: 16,
fontWeight: 'bold',
},
infoContainer: {
marginTop: 40,
paddingHorizontal: 20,
marginTop: 8,
paddingHorizontal: 10,
},
infoText: {
color: '#999',
fontSize: 14,
fontSize: 13,
textAlign: 'center',
marginBottom: 8,
marginBottom: 6,
},
});
31 changes: 18 additions & 13 deletions apps/playground/src/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@ import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './store/counterSlice';
import { rozeniteDevToolsEnhancer } from '@rozenite/redux-devtools-plugin';

export const store = configureStore({
reducer: {
counter: counterReducer,
},
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers().concat(
rozeniteDevToolsEnhancer({
maxAge: 150
})
),
});
const createCounterStore = (name: string) =>
configureStore({
reducer: {
counter: counterReducer,
},
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers().concat(
rozeniteDevToolsEnhancer({
name,
maxAge: 150,
})
),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export const primaryStore = createCounterStore('playground-primary-counter');
export const secondaryStore = createCounterStore('playground-secondary-counter');

export type RootState = ReturnType<typeof primaryStore.getState>;
export type AppDispatch = typeof primaryStore.dispatch;
36 changes: 9 additions & 27 deletions packages/redux-devtools-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[![mit licence][license-badge]][license] [![npm downloads][npm-downloads-badge]][npm-downloads] [![Chat][chat-badge]][chat] [![PRs Welcome][prs-welcome-badge]][prs-welcome]

The Rozenite Redux DevTools Plugin provides Redux state inspection and debugging capabilities within your React Native DevTools environment. It offers a partial Redux DevTools experience, including state inspection and action history (time travel and action dispatch are currently unavailable in remote mode).
The Rozenite Redux DevTools Plugin provides Redux state inspection and debugging capabilities within your React Native DevTools environment, including action dispatch and time-travel controls.

![Redux DevTools Plugin](https://rozenite.dev/redux-devtools-plugin.png)

Expand All @@ -19,22 +19,12 @@ The Rozenite Redux DevTools Plugin provides Redux state inspection and debugging

### 1. Install the Plugin

Install the Redux DevTools plugin and peer dependencies:
Install the Redux DevTools plugin:

```bash
npm install -D @rozenite/redux-devtools-plugin
npm install react-native-get-random-values
```

**Important**: After installing `react-native-get-random-values`, you need to import it at the very top of your entry file (usually `index.js` or `App.js`):

```javascript
import 'react-native-get-random-values';
// ... rest of your imports
```

For more detailed setup instructions, please refer to the [react-native-get-random-values documentation](https://github.com/LinusU/react-native-get-random-values).

### 2. Set up the Store Enhancer

Add the Redux DevTools enhancer to your Redux store:
Expand Down Expand Up @@ -75,28 +65,20 @@ export default store;

##### Configuration Options

To see more actions in the Redux DevTools, increase the `maxAge` option:
To distinguish multiple stores, set a custom `name` per store:

```ts
rozeniteDevToolsEnhancer({ maxAge: 150 }) // Default is 50
const appStoreEnhancer = rozeniteDevToolsEnhancer({ name: 'app-store' });
const sessionStoreEnhancer = rozeniteDevToolsEnhancer({ name: 'session-store' });
```

### 3. Configure Metro

Wrap your Metro configuration with `withRozeniteReduxDevTools`:
To see more actions in the Redux DevTools, increase `maxAge`:

```typescript
// metro.config.js
import { withRozeniteReduxDevTools } from '@rozenite/redux-devtools-plugin/metro';

export default withRozeniteReduxDevTools({
// your existing metro config
});
```ts
rozeniteDevToolsEnhancer({ maxAge: 150 }) // Default is 50
```

This setup enables the WebSocket relay that allows the Redux DevTools to communicate with your React Native app.

### 4. Access DevTools
### 3. Access DevTools

Start your development server and open React Native DevTools. You'll find the "Redux DevTools" panel in the DevTools interface.

Expand Down
9 changes: 4 additions & 5 deletions packages/redux-devtools-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
"lint": "eslint ."
},
"dependencies": {
"@redux-devtools/remote": "^0.9.5",
"@redux-devtools/instrument": "^2.2.0",
"@redux-devtools/utils": "^3.1.1",
"@rozenite/plugin-bridge": "workspace:*",
"@redux-devtools/cli": "^4.0.3",
"jsan": "^3.1.14",
"@rozenite/tools": "workspace:*"
},
"devDependencies": {
Expand All @@ -42,7 +43,6 @@
"react": "catalog:",
"react-dom": "catalog:",
"react-native": "catalog:",
"react-native-get-random-values": "^1.11.0",
"react-native-web": "^0.21.2",
"react-redux": "^9.2.0",
"redux": "^5.0.1",
Expand All @@ -56,8 +56,7 @@
},
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-get-random-values": "*"
"react-native": "*"
},
"license": "MIT"
}
Loading
Loading