UNPKG

react-query-external-sync

Version:

A tool for syncing React Query state to an external Dev Tools

205 lines (157 loc) 8.02 kB
# React Query External Sync A powerful debugging tool for React Query state and device storage in any React-based application. Whether you're building for mobile, web, desktop, TV, or VR - this package has you covered. It works seamlessly across all platforms where React runs, with zero configuration to disable in production. Pairs perfectly with [React Native DevTools](https://github.com/LovesWorking/rn-better-dev-tools) for a complete development experience. ![React Query External Sync Demo](https://github.com/user-attachments/assets/39e5c417-be4d-46af-8138-3589d73fce9f) ### If you need internal React Query dev tools within the device you can use my other package here! https://github.com/LovesWorking/react-native-react-query-devtools ## Features - 🔄 Real-time React Query state synchronization - 💾 **Device storage monitoring with CRUD operations** - MMKV, AsyncStorage, and SecureStorage - 📱 Works with any React-based framework (React, React Native, Expo, Next.js, etc.) - 🖥️ Platform-agnostic: Web, iOS, Android, macOS, Windows, Linux, tvOS, VR - you name it! - 🔌 Socket.IO integration for reliable communication - 📊 Query status, data, and error monitoring - ⚡️ Simple integration with minimal setup - 🧩 Perfect companion to React Native DevTools - 🛑 Zero-config production safety - automatically disabled in production builds ## 📦 Installation ```bash # Using npm npm install --save-dev react-query-external-sync socket.io-client # Using yarn yarn add -D react-query-external-sync socket.io-client # Using pnpm pnpm add -D react-query-external-sync socket.io-client ``` ## 🚀 Quick Start Add the hook to your application where you set up your React Query context: ```jsx import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useSyncQueriesExternal } from "react-query-external-sync"; import { Platform } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import * as SecureStore from "expo-secure-store"; import { storage } from "./mmkv"; // Your MMKV instance // Create your query client const queryClient = new QueryClient(); function App() { return ( <QueryClientProvider client={queryClient}> <AppContent /> </QueryClientProvider> ); } function AppContent() { // Unified storage queries and external sync - all in one hook! useSyncQueriesExternal({ queryClient, socketURL: "http://localhost:42831", deviceName: Platform.OS, platform: Platform.OS, deviceId: Platform.OS, extraDeviceInfo: { appVersion: "1.0.0", }, enableLogs: true, envVariables: { NODE_ENV: process.env.NODE_ENV, }, // Storage monitoring with CRUD operations mmkvStorage: storage, // MMKV storage for ['#storage', 'mmkv', 'key'] queries + monitoring asyncStorage: AsyncStorage, // AsyncStorage for ['#storage', 'async', 'key'] queries + monitoring secureStorage: SecureStore, // SecureStore for ['#storage', 'secure', 'key'] queries + monitoring secureStorageKeys: [ "userToken", "refreshToken", "biometricKey", "deviceId", ], // SecureStore keys to monitor }); // Your app content return <YourApp />; } ``` ## 🔒 Production Safety This package is automatically disabled in production builds. ```jsx // The package handles this internally: if (process.env.NODE_ENV !== "production") { useSyncQueries = require("./new-sync/useSyncQueries").useSyncQueries; } else { // In production, this becomes a no-op function useSyncQueries = () => ({ isConnected: false, connect: () => {}, disconnect: () => {}, socket: null, users: [], }); } ``` ## 💡 Usage with DevTools For the best experience, use this package with the [React Native DevTools](https://github.com/LovesWorking/rn-better-dev-tools) application: 1. Download and launch the DevTools application 2. Integrate this package in your React application 3. Start your application 4. DevTools will automatically detect and connect to your running application > **Note**: For optimal connection, launch DevTools before starting your application. ## ⚙️ Configuration Options The `useSyncQueriesExternal` hook accepts the following options: | Option | Type | Required | Description | | ------------------- | ------------ | -------- | ----------------------------------------------------------------------- | | `queryClient` | QueryClient | Yes | Your React Query client instance | | `socketURL` | string | Yes | URL of the socket server (e.g., 'http://localhost:42831') | | `deviceName` | string | Yes | Human-readable name for your device | | `platform` | string | Yes | Platform identifier ('ios', 'android', 'web', 'macos', 'windows', etc.) | | `deviceId` | string | Yes | Unique identifier for your device | | `extraDeviceInfo` | object | No | Additional device metadata to display in DevTools | | `enableLogs` | boolean | No | Enable console logging for debugging (default: false) | | `isDevice` | boolean | No | Set to true if this is a device (default: false) | | `envVariables` | object | No | Environment variables to sync with DevTools | | `mmkvStorage` | MmkvStorage | No | MMKV storage instance for real-time monitoring | | `asyncStorage` | AsyncStorage | No | AsyncStorage instance for polling-based monitoring | | `secureStorage` | SecureStore | No | SecureStore instance for secure data monitoring | | `secureStorageKeys` | string[] | No | Array of SecureStore keys to monitor (required if using secureStorage) | ## 🐛 Troubleshooting ### Quick Checklist 1. **DevTools Connection** - Look for "Connected" status in the top-left corner of the DevTools app - If it shows "Disconnected", restart the DevTools app 2. **No Devices Appearing** - Verify the Socket.IO client is installed (`npm list socket.io-client`) - Ensure the hook is properly set up in your app - Check that `socketURL` matches the DevTools port (default: 42831) - Restart both your app and the DevTools 3. **Data Not Syncing** - Confirm you're passing the correct `queryClient` instance - Set `enableLogs: true` to see connection information That's it! If you're still having issues, visit the [GitHub repository](https://github.com/LovesWorking/react-query-external-sync/issues) for support. ## ⚠️ Important Note About Device IDs The `deviceId` parameter must be **persistent** across app restarts and re-renders. Using a value that changes (like `Date.now()`) will cause each render to be treated as a new device. **Recommended approaches:** ```jsx // Simple approach for single devices deviceId: Platform.OS, // Works if you only have one device per platform // Better approach for multiple simulators/devices of same type // Using AsyncStorage, MMKV, or another storage solution const [deviceId, setDeviceId] = useState(Platform.OS); useEffect(() => { const loadOrCreateDeviceId = async () => { // Try to load existing ID const storedId = await AsyncStorage.getItem('deviceId'); if (storedId) { setDeviceId(storedId); } else { // First launch - generate and store a persistent ID const newId = `${Platform.OS}-${Date.now()}`; await AsyncStorage.setItem('deviceId', newId); setDeviceId(newId); } }; loadOrCreateDeviceId(); }, []); ``` ## 📄 License MIT --- Made with ❤️ by [LovesWorking](https://github.com/LovesWorking)