### Clone Repository and Install Dependencies (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
This snippet shows how to clone the project repository and install its dependencies using pnpm. It's the initial step for setting up the development environment.
```bash
git clone https://github.com/LovesWorking/rn-better-dev-tools.git
cd rn-better-dev-tools
pnpm install
```
--------------------------------
### Start Development Build (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
Commands to start the development server with hot reloading and to build the desktop application for testing. These are essential for iterative development and debugging.
```bash
# Start in development mode with hot reload
pnpm start
# Build and copy to desktop for testing
pnpm run make:desktop
# Build only
pnpm run make
```
--------------------------------
### Configure Environment Variables (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
This command copies the example environment file and instructs the user to fill in Apple Developer credentials. This is crucial for building and signing the application on macOS.
```bash
cp .env.example .env
# Fill in your Apple Developer credentials in .env:
# APPLE_ID=your.email@example.com
# APPLE_PASSWORD=app-specific-password
# APPLE_TEAM_ID=your-team-id
```
--------------------------------
### Development Commands (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
A collection of useful development commands including a clean install, packaging without distributables, and running the linter. These commands help maintain a clean development environment and ensure code quality.
```bash
# Clean install
pnpm run nuke
# Package without making distributables
pnpm run package
# Run linter
pnpm run lint
```
--------------------------------
### Install React Query External Sync and Socket.IO Client
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
Installs necessary development dependencies for integrating React Query external sync and socket.IO client. Also installs expo-device for automatic device detection on React Native projects.
```bash
# Using npm
npm install --save-dev react-query-external-sync socket.io-client
npm install expo-device # For automatic device detection
# Using yarn
yarn add -D react-query-external-sync socket.io-client
yarn add expo-device # For automatic device detection
# Using pnpm (recommended)
pnpm add -D react-query-external-sync socket.io-client
pnpm add expo-device # For automatic device detection
```
--------------------------------
### Project Structure Overview
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
This section provides a high-level overview of the project's directory structure. It highlights key directories like `src/` for source code, `assets/` for static files, `.github/workflows/` for CI/CD, and `forge.config.ts` for Electron Forge configuration.
```plaintext
.
├── src/ # Source code
│ ├── main.ts # Main process
│ ├── preload.ts # Preload scripts
│ └── components/ # React components
├── assets/ # Static assets
├── .github/workflows/ # GitHub Actions
└── forge.config.ts # Electron Forge config
```
--------------------------------
### Install react-query-external-sync and socket.io-client
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/src/react-query-external-sync/README.md
Installs the necessary packages for real-time React Query state synchronization using npm, yarn, or pnpm. These packages enable the communication between your application and the debugging tools.
```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
```
--------------------------------
### Automate Release Process (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
This snippet demonstrates how to trigger the automated release script, which handles version bumping, building, tagging, and pushing to GitHub. It simplifies the release workflow.
```bash
# Using npm script
pnpm run auto-release
# Or directly
./auto-release.sh
```
--------------------------------
### Enable Debug Logs (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
Instructions to enable debug logs by adding a specific variable to the `.env` file. This is useful for diagnosing issues during development and building.
```bash
DEBUG=electron-osx-sign*
```
--------------------------------
### Local Build and Packaging Script
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Runs a script to build the application locally and create installation packages. The output is placed in a specific folder on the user's Desktop.
```bash
pnpm run pack
```
--------------------------------
### Connect React Query External Sync to Local Network IP with Expo
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
This example shows how to configure the React Query External Sync hook for use with real devices on a local network using Expo. It dynamically retrieves the host machine's IP address and constructs the socket URL accordingly. It also includes setup for various storage types.
```jsx
import Constants from "expo-constants";
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as SecureStore from "expo-secure-store";
import { storage } from "./mmkv"; // Your MMKV instance
// Get the host IP address dynamically
const hostIP =
Constants.expoGoConfig?.debuggerHost?.split(`:`)[0] ||
Constants.expoConfig?.hostUri?.split(`:`)[0];
function AppContent() {
useSyncQueriesExternal({
queryClient,
socketURL: `http://${hostIP}:42831`, // Use local network IP
deviceName: Platform?.OS || "web",
platform: Platform?.OS || "web",
deviceId: Platform?.OS || "web",
extraDeviceInfo: {
appVersion: "1.0.0",
},
enableLogs: false,
envVariables: {
NODE_ENV: process.env.NODE_ENV,
},
// Storage monitoring
mmkvStorage: storage,
asyncStorage: AsyncStorage,
secureStorage: SecureStore,
secureStorageKeys: ["userToken", "refreshToken"],
});
return ;
}
```
--------------------------------
### Fix Permissions and Clean Build Artifacts (Bash)
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/DEVELOPMENT.md
These commands address common permission issues and clean up build artifacts. Running `sudo chown -R $(whoami) .` fixes directory ownership, and `rm -rf .vite out` removes temporary build files.
```bash
# Fix directory permissions
sudo chown -R $(whoami) .
# Clean build artifacts
rm -rf .vite out
```
--------------------------------
### Handle Platform-Specific URL Transformations
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
Provides a function to transform URLs based on the target platform, specifically adjusting 'localhost' to '10.0.2.2' for Android emulators. It includes examples for various platforms and demonstrates how to use the `isDevice` prop to conditionally apply these transformations.
```typescript
import { getPlatformSpecificURL } from "react-query-external-sync";
type PlatformOS =
| "ios" // iPhone, iPad, iPod
| "android" // Android devices
| "web" // Web browsers
| "windows" // Windows desktop/UWP
| "macos" // macOS desktop
| "native" // Generic native
| "tv" // Android TV
| "tvos" // Apple TV
| "visionos" // Apple Vision Pro
| "maccatalyst"; // iOS on macOS
const baseUrl = "http://localhost:42831";
// iOS - returns unchanged
getPlatformSpecificURL(baseUrl, "ios");
// Result: "http://localhost:42831"
// Android emulator - transforms localhost
getPlatformSpecificURL(baseUrl, "android");
// Result: "http://10.0.2.2:42831"
// Web - returns unchanged
getPlatformSpecificURL(baseUrl, "web");
// Result: "http://localhost:42831"
useSyncQueriesExternal({
socketURL: "http://localhost:42831",
platform: "android",
isDevice: ExpoDevice.isDevice,
// ... other props
});
```
--------------------------------
### Configure Real Device Network for DevTools (Expo)
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
This example demonstrates how to configure the DevTools connection for real devices on a local network using Expo. It dynamically detects the host machine's IP address to establish the WebSocket connection, which is necessary when not running on a simulator. This ensures the DevTools can communicate with the app running on a physical device.
```jsx
import Constants from "expo-constants";
import { Platform } from "react-native";
import * as ExpoDevice from "expo-device";
// Dynamically get host IP from Expo debugger configuration
const hostIP =
Constants.expoGoConfig?.debuggerHost?.split(":")[0] ||
Constants.expoConfig?.hostUri?.split(":")[0];
function AppContent() {
useSyncQueriesExternal({
queryClient,
// Use local network IP for real device connections
socketURL: `http://${hostIP}:42831`,
deviceName: `${Platform.OS}-device`,
platform: Platform.OS,
deviceId: Platform.OS,
isDevice: ExpoDevice.isDevice,
enableLogs: true, // Enable for debugging connection issues
});
return ;
}
// Example output when connected:
// [ios-device] Platform: ios, using URL: http://192.168.1.100:42831
// [ios-device] Socket connected successfully
// [ios-device] Dashboard is requesting initial state
// [ios-device] Sent initial state to dashboard (15 queries)
```
--------------------------------
### Integrate useSyncQueriesExternal hook in React Query context
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/src/react-query-external-sync/README.md
Demonstrates how to add the `useSyncQueriesExternal` hook within your React Query `QueryClientProvider`. This setup enables real-time synchronization of React Query state across different platforms, automatically disabling in production.
```jsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useSyncQueriesExternal } from "react-query-external-sync";
// Import Platform for React Native or use other platform detection for web/desktop
import { Platform } from "react-native";
// Create your query client
const queryClient = new QueryClient();
function App() {
return (
);
}
function AppContent() {
// Set up the sync hook - automatically disabled in production!
useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831", // Default port for React Native DevTools
deviceName: Platform?.OS || "web", // Platform detection
platform: Platform?.OS || "web", // Use appropriate platform identifier
deviceId: Platform?.OS || "web", // Use a PERSISTENT identifier (see note below)
extraDeviceInfo: {
// Optional additional info about your device
appVersion: "1.0.0",
// Add any relevant platform info
},
envVariables: {
// Optional environment variables from your app
NODE_ENV: process.env.NODE_ENV,
API_URL: process.env.API_URL,
// Add any relevant environment variables
},
enableLogs: false,
});
// Your app content
return ;
}
```
--------------------------------
### Real Device Network Configuration
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
When testing on real devices over a local network, you need to use the host machine's IP address instead of 'localhost'. This section provides an example of how to dynamically detect the host IP address for Expo applications.
```APIDOC
## Real Device Network Configuration
### Description
Configures the `useSyncQueriesExternal` hook to connect to the DevTools dashboard from a real device on a local network by using the host machine's IP address.
### Method
`useSyncQueriesExternal` (Hook) with dynamic `socketURL` configuration.
### Parameters
#### Hook Options (relevant for this configuration)
- **socketURL** (string) - Required - The URL of the Socket.IO server. This should be dynamically set to the host machine's IP address on the local network.
- **enableLogs** (boolean) - Optional - Recommended to be set to `true` for debugging connection issues.
### Request Example
```jsx
import Constants from "expo-constants";
import { Platform } from "react-native";
import * as ExpoDevice from "expo-device";
// Dynamically get host IP from Expo debugger configuration
const hostIP = Constants.expoGoConfig?.debuggerHost?.split(":")[0] || Constants.expoConfig?.hostUri?.split(":")[0];
function AppContent() {
useSyncQueriesExternal({
queryClient,
// Use local network IP for real device connections
socketURL: `http://${hostIP}:42831`,
deviceName: `${Platform.OS}-device`,
platform: Platform.OS,
deviceId: Platform.OS,
isDevice: ExpoDevice.isDevice,
enableLogs: true, // Enable for debugging connection issues
});
return ;
}
```
### Response Example (Console Output)
```
[ios-device] Platform: ios, using URL: http://192.168.1.100:42831
[ios-device] Socket connected successfully
[ios-device] Dashboard is requesting initial state
[ios-device] Sent initial state to dashboard (15 queries)
```
```
--------------------------------
### Detect Android Device Type for Buoy Desktop
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
This snippet demonstrates how to correctly set the `isDevice` prop in the `useSyncQueriesExternal` hook for Buoy Desktop. It helps distinguish between real Android devices and emulators, which is crucial for proper WebSocket connections. The examples show recommended approaches using Expo Device, React Native's `__DEV__` flag, and `react-native-device-info`.
```jsx
// Best approach using Expo Device (works with bare React Native too)
import * as ExpoDevice from "expo-device";
useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831",
deviceName: Platform.OS,
platform: Platform.OS,
deviceId: Platform.OS,
isDevice: ExpoDevice.isDevice, // Automatically detects real devices vs emulators
// ... other props
});
// Alternative: Simple approach using React Native's __DEV__ flag
isDevice: !__DEV__, // true for production/real devices, false for development/simulators
// Alternative: More sophisticated detection using react-native-device-info
import DeviceInfo from 'react-native-device-info';
isDevice: !DeviceInfo.isEmulator(), // Automatically detects if running on emulator
// Manual control for specific scenarios
isDevice: Platform.OS === 'ios' ? !Platform.isPad : Platform.OS !== 'web',
```
--------------------------------
### Define and Use Query Actions for Dashboard Control
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
Defines TypeScript types for various query actions that can be sent from a dashboard to control query states on connected devices. It also includes the structure for query action messages and an example of simulating network status changes using the onlineManager.
```typescript
type QueryActions =
| "ACTION-REFETCH" // Refetch query without invalidating
| "ACTION-INVALIDATE" // Invalidate and trigger refetch
| "ACTION-RESET" // Reset query to initial state
| "ACTION-REMOVE" // Remove query from cache
| "ACTION-DATA-UPDATE" // Manually update query data
| "ACTION-TRIGGER-ERROR" // Force error state for testing
| "ACTION-RESTORE-ERROR" // Restore from error state
| "ACTION-TRIGGER-LOADING" // Force loading state for testing
| "ACTION-RESTORE-LOADING" // Restore from loading state
| "ACTION-CLEAR-MUTATION-CACHE" // Clear all mutations
| "ACTION-CLEAR-QUERY-CACHE"; // Clear all queries
interface QueryActionMessage {
queryHash: string; // Unique query identifier
queryKey: QueryKey; // React Query key array
data: unknown; // Data payload for updates
action: QueryActions; // Action to perform
deviceId: string; // Target device ID
}
interface OnlineManagerMessage {
action: "ACTION-ONLINE-MANAGER-ONLINE" | "ACTION-ONLINE-MANAGER-OFFLINE";
targetDeviceId: string; // "All" or specific device ID
}
import { onlineManager } from "@tanstack/react-query";
// Simulate offline mode
onlineManager.setOnline(false);
// Return to online mode
onlineManager.setOnline(true);
```
--------------------------------
### Run Pack Script for Manual Release
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/GITHUB_RELEASE.md
Executes the script to build and pack the application for a manual release. This is typically done after setting the GITHUB_TOKEN environment variable.
```bash
pnpm run pack
# or directly with
./build-and-pack.sh
```
--------------------------------
### Integrate React Query DevTools with React Native
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
Demonstrates how to integrate the `useSyncQueriesExternal` hook from `react-query-external-sync` into a React Native application. This hook enables real-time React Query state monitoring and device storage monitoring. It requires configuration for socket URL, device name, platform, device ID, and optionally includes environment variables and storage configurations for MMKV, AsyncStorage, and SecureStore.
```jsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useSyncQueriesExternal } from "react-query-external-sync";
// Import Platform for React Native or use other platform detection for web/desktop
import { Platform } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as SecureStore from "expo-secure-store";
import * as ExpoDevice from "expo-device";
import { storage } from "./mmkv"; // Your MMKV instance
// Create your query client
const queryClient = new QueryClient();
function App() {
return (
);
}
function AppContent() {
// Set up the sync hook - automatically disabled in production!
useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831", // Default port for React Native DevTools
deviceName: Platform?.OS || "web", // Platform detection
platform: Platform?.OS || "web", // Use appropriate platform identifier
deviceId: Platform?.OS || "web", // Use a PERSISTENT identifier (see note below)
isDevice: ExpoDevice.isDevice, // Automatically detects real devices vs emulators
extraDeviceInfo: {
// Optional additional info about your device
appVersion: "1.0.0",
// Add any relevant platform info
},
enableLogs: false,
envVariables: {
NODE_ENV: process.env.NODE_ENV,
// Add any private environment variables you want to monitor
// Public environment variables are automatically loaded
},
// 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 ;
}
```
--------------------------------
### Interact with Storage using React Query Hooks
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
This code demonstrates how to use React Query hooks (`useQuery`, `useMutation`) to interact with different storage types (MMKV, AsyncStorage) that are monitored by React Native DevTools. It shows reading data and updating storage, including invalidating queries to ensure data synchronization.
```jsx
// In your app, use React Query to interact with storage
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
// Read from MMKV storage
const { data: userData } = useQuery({
queryKey: ["#storage", "mmkv", "user"],
// Data will be automatically synced with DevTools
});
// Write to AsyncStorage
const queryClient = useQueryClient();
const updateAsyncStorage = useMutation({
mutationFn: async ({ key, value }) => {
await AsyncStorage.setItem(key, JSON.stringify(value));
// Invalidate to trigger sync
queryClient.invalidateQueries(["#storage", "async", key]);
},
});
```
--------------------------------
### Manual Git Tag Creation and Push
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Creates an annotated git tag for the new release version and pushes it to the remote repository. This action signals the release point and triggers CI/CD pipelines.
```bash
git tag -a vx.y.z -m "Version x.y.z"
git push origin vx.y.z
```
--------------------------------
### Local Build Command for Testing
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Executes the 'make' command locally to perform a build. This is used for testing the build process integrity before creating a formal release.
```bash
pnpm run make
```
--------------------------------
### Run Automated Release Script
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/GITHUB_RELEASE.md
Executes the automated script to manage the release process, including version bumping, committing, tagging, and publishing to GitHub. This script simplifies the release workflow by handling multiple steps interactively.
```bash
pnpm run release
# or directly with
./release-version.sh
```
--------------------------------
### Connect React App to DevTools Dashboard (React Native)
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
The `useSyncQueriesExternal` hook establishes a connection between a React application and the DevTools dashboard. It manages the socket connection, synchronizes React Query state, and handles actions from the dashboard. Dependencies include `@tanstack/react-query`, `react-native`, `react-native-async-storage`, `expo-secure-store`, `expo-device`, and MMKV storage.
```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 * as ExpoDevice from "expo-device";
import { storage } from "./mmkv";
const queryClient = new QueryClient();
function App() {
return (
);
}
function AppContent() {
const { isConnected, connect, disconnect, socket } = useSyncQueriesExternal({
// Required: React Query client instance
queryClient,
// Required: Socket server URL (default DevTools port)
socketURL: "http://localhost:42831",
// Required: Human-readable device name
deviceName: Platform?.OS || "web",
// Required: Platform identifier
platform: Platform?.OS || "web",
// Required: Persistent unique device identifier
deviceId: Platform?.OS || "web",
// Optional: Real device detection (crucial for Android)
isDevice: ExpoDevice.isDevice,
// Optional: Additional device metadata
extraDeviceInfo: {
appVersion: "1.0.0",
buildNumber: "42",
},
// Optional: Enable debug logging
enableLogs: false,
// Optional: Environment variables to monitor
envVariables: {
NODE_ENV: process.env.NODE_ENV,
API_URL: process.env.API_URL,
},
// Optional: Storage instances for monitoring
mmkvStorage: storage,
asyncStorage: AsyncStorage,
secureStorage: SecureStore,
secureStorageKeys: ["userToken", "refreshToken", "deviceId"],
});
return ;
}
```
--------------------------------
### Monitor Storage with React Query Hooks
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
This set of hooks leverages React Query and specific DevTools conventions to provide real-time monitoring and CRUD operations for various storage types (MMKV, AsyncStorage, SecureStorage). Mutations automatically invalidate queries to sync changes with the DevTools.
```jsx
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import AsyncStorage from "@react-native-async-storage/async-storage";
// Read from MMKV storage via DevTools query key convention
function useMMKVData(key: string) {
return useQuery({
queryKey: ["#storage", "mmkv", key],
// Data is automatically synced from device storage
});
}
// Read from AsyncStorage via DevTools query key convention
function useAsyncStorageData(key: string) {
return useQuery({
queryKey: ["#storage", "async", key],
});
}
// Read from SecureStorage via DevTools query key convention
function useSecureStorageData(key: string) {
return useQuery({
queryKey: ["#storage", "secure", key],
});
}
// Write to AsyncStorage with DevTools sync
function useUpdateAsyncStorage() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ key, value }: { key: string; value: any }) => {
await AsyncStorage.setItem(key, JSON.stringify(value));
return value;
},
onSuccess: (_, { key }) => {
// Invalidate to trigger sync with DevTools
queryClient.invalidateQueries({ queryKey: ["#storage", "async", key] });
},
});
}
// Example usage
function UserSettings() {
const { data: userData } = useMMKVData("user");
const { data: settings } = useAsyncStorageData("settings");
const { data: authToken } = useSecureStorageData("userToken");
const updateStorage = useUpdateAsyncStorage();
const handleSaveSettings = () => {
updateStorage.mutate({
key: "settings",
value: { theme: "dark", notifications: true },
});
};
return (
User: {JSON.stringify(userData)}Settings: {JSON.stringify(settings)}Auth: {authToken ? "Authenticated" : "Not logged in"}
);
}
```
--------------------------------
### Set GitHub Token for Manual Release
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/GITHUB_RELEASE.md
Sets the GitHub access token as an environment variable, which is required for manual release operations. The token must have 'repo' permissions to interact with the GitHub repository.
```bash
export GITHUB_TOKEN=your_github_token
```
--------------------------------
### Manage Persistent Device IDs with React Native Storage
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/src/react-query-external-sync/README.md
This snippet demonstrates how to manage persistent device IDs in a React Native application. It shows a simple approach using `Platform.OS` and a more robust method involving `AsyncStorage` to load or create a unique, persistent ID across app restarts and re-renders. This ensures consistent device identification.
```jsx
import React, { useState, useEffect } from 'react';
import { Platform } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Simple approach for single devices
// deviceId: Platform.OS,
// 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();
}, []);
```
--------------------------------
### Manage Persistent Device IDs with React Native
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
Demonstrates how to manage persistent device IDs in React Native applications. It covers a simple approach using Platform.OS and a more robust method involving AsyncStorage to load or generate a unique, persistent ID across app restarts. This ensures each device instance is treated uniquely.
```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();
}, []);
```
--------------------------------
### Create and Push Git Tag for GitHub Actions Release
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/GITHUB_RELEASE.md
Manually creates a new Git tag following semantic versioning and pushes it to the origin. This action triggers the GitHub Actions workflow to build and release the application.
```bash
git tag v1.x.x
git push origin v1.x.x
```
--------------------------------
### Production safety mechanism for useSyncQueries
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/src/react-query-external-sync/README.md
Illustrates the internal logic for disabling the synchronization hook in production environments. When `process.env.NODE_ENV` is 'production', the hook becomes a no-operation function, ensuring no debugging overhead in live 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: [],
});
}
```
--------------------------------
### Manual Git Commit for Version Update
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Stages and commits the updated package.json file to the git repository. This step is part of the manual release process to record the version change.
```bash
git add package.json
git commit -m "Bump version to x.y.z"
```
--------------------------------
### useSyncQueriesExternal Hook
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
The `useSyncQueriesExternal` hook is the primary method for connecting your React application to the DevTools dashboard. It manages the socket connection, synchronizes query state, and handles actions from the dashboard such as refetching, invalidating, and updating data.
```APIDOC
## useSyncQueriesExternal Hook
### Description
Connects React applications to the DevTools dashboard, handling socket connection, query state synchronization, and responding to dashboard actions.
### Method
`useSyncQueriesExternal` (Hook)
### Parameters
#### Hook Options
- **queryClient** (QueryClient) - Required - The React Query client instance.
- **socketURL** (string) - Required - The URL of the Socket.IO server (default DevTools port).
- **deviceName** (string) - Required - A human-readable name for the device.
- **platform** (string) - Required - An identifier for the platform (e.g., 'ios', 'android', 'web').
- **deviceId** (string) - Required - A persistent unique identifier for the device.
- **isDevice** (boolean) - Optional - Real device detection flag (crucial for Android).
- **extraDeviceInfo** (object) - Optional - Additional metadata about the device (e.g., `appVersion`, `buildNumber`).
- **enableLogs** (boolean) - Optional - Enables debug logging for the hook.
- **envVariables** (object) - Optional - Environment variables to monitor.
- **mmkvStorage** (object) - Optional - An instance of MMKV storage for monitoring.
- **asyncStorage** (object) - Optional - An instance of AsyncStorage for monitoring.
- **secureStorage** (object) - Optional - An instance of SecureStorage for monitoring.
- **secureStorageKeys** (array of strings) - Optional - An array of keys to monitor in secure storage.
### Request Example
```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 * as ExpoDevice from "expo-device";
import { storage } from "./mmkv";
const queryClient = new QueryClient();
function App() {
return (
);
}
function AppContent() {
const { isConnected, connect, disconnect, socket } = useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831",
deviceName: Platform?.OS || "web",
platform: Platform?.OS || "web",
deviceId: Platform?.OS || "web",
isDevice: ExpoDevice.isDevice,
extraDeviceInfo: {
appVersion: "1.0.0",
buildNumber: "42",
},
enableLogs: false,
envVariables: {
NODE_ENV: process.env.NODE_ENV,
API_URL: process.env.API_URL,
},
mmkvStorage: storage,
asyncStorage: AsyncStorage,
secureStorage: SecureStore,
secureStorageKeys: ["userToken", "refreshToken", "deviceId"],
});
return ;
}
```
### Response
This hook does not return a direct response in the traditional sense, but it provides connection status and socket control functions.
#### Connection Status & Control
- **isConnected** (boolean) - True if the socket is connected to the dashboard.
- **connect** (function) - Function to manually initiate a connection.
- **disconnect** (function) - Function to manually disconnect the socket.
- **socket** (object) - The underlying Socket.IO socket instance.
```
--------------------------------
### Automated Release Script for React Native DevTools
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Executes an automated script to manage the release process. This script handles version bumping, commit, tag creation, and publishing to GitHub, simplifying the release workflow.
```bash
pnpm run release
```
--------------------------------
### Ensure Production Safety by Disabling Sync
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
Illustrates how the sync functionality is automatically disabled in production builds to prevent unintended behavior or performance issues. The code shows a conditional import and a fallback no-operation function for production environments, ensuring no runtime overhead.
```jsx
if (process.env.NODE_ENV !== "production") {
useSyncQueries = require("./useSyncQueries").useSyncQueries;
} else {
useSyncQueries = () => ({
isConnected: false,
connect: () => {},
disconnect: () => {},
socket: null,
users: [],
});
}
function App() {
const { isConnected } = useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831",
deviceName: Platform.OS,
platform: Platform.OS,
deviceId: Platform.OS,
});
if (__DEV__ && !isConnected) {
console.log("DevTools not connected");
}
return ;
}
```
--------------------------------
### Configure Socket.IO Server for DevTools
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
This configuration outlines the settings for the Socket.IO server used by the DevTools desktop application, which runs on port 42831. It includes CORS settings, allowed transports, and ping timeouts, along with definitions for socket events exchanged between the dashboard and devices.
```typescript
// Server configuration (src/config.ts)
export const SERVER_PORT = 42831;
export const SOCKET_CONFIG = {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
transports: ["websocket", "polling"],
pingTimeout: 30000,
pingInterval: 25000,
};
export const CLIENT_URL = `http://localhost:${SERVER_PORT}`;
// Socket events emitted by devices:
// - "query-sync": Sends dehydrated React Query state to dashboard
// - "message": Debug messages
// Socket events received by devices:
// - "request-initial-state": Dashboard requesting full query state
// - "query-action": Dashboard sending actions (refetch, invalidate, etc.)
// - "online-manager": Dashboard controlling online/offline state
// Example SyncMessage structure sent via "query-sync":
interface SyncMessage {
type: "dehydrated-state";
state: {
queries: DehydratedQuery[]; // All cached queries
mutations: DehydratedMutation[]; // All cached mutations
};
isOnlineManagerOnline: boolean;
persistentDeviceId: string;
}
```
--------------------------------
### Debug Auto-Updater Issues
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/GITHUB_RELEASE.md
Runs the application with the DEBUG environment variable set to 'electron-updater' to enable detailed logging for debugging auto-update issues. This helps in diagnosing problems with the update mechanism.
```bash
DEBUG=electron-updater npm start
```
--------------------------------
### Manual Version Update in package.json
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/RELEASE.md
Manually updates the version number within the package.json file. This is a prerequisite for manual release processes, ensuring the correct version is reflected.
```json
{
"version": "x.y.z",
...
}
```
--------------------------------
### Disable React Query External Sync in Production Builds
Source: https://github.com/buoy-gg/buoy-desktop/blob/main/README.md
This code snippet demonstrates how the React Query External Sync package is automatically disabled in production environments. It checks the NODE_ENV variable and provides a no-operation fallback for production builds to prevent unnecessary operations.
```jsx
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: [],
});
}
```
--------------------------------
### Manage Persistent Device ID with AsyncStorage in React Native
Source: https://context7.com/buoy-gg/buoy-desktop/llms.txt
This hook generates and stores a unique device ID using AsyncStorage to ensure persistence across application restarts. It handles loading existing IDs or creating new ones, with a fallback to the platform name if storage operations fail. This ID is crucial for consistent device tracking.
```jsx
import { useState, useEffect } from "react";
import { Platform } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
function usePersistedDeviceId() {
const [deviceId, setDeviceId] = useState(null);
useEffect(() => {
const loadOrCreateDeviceId = async () => {
try {
// Try to load existing ID
const storedId = await AsyncStorage.getItem("@devtools_device_id");
if (storedId) {
setDeviceId(storedId);
} else {
// First launch - generate and store a persistent ID
const newId = `${Platform.OS}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
await AsyncStorage.setItem("@devtools_device_id", newId);
setDeviceId(newId);
}
} catch (error) {
// Fallback to platform-based ID
setDeviceId(Platform.OS);
}
};
loadOrCreateDeviceId();
}, []);
return deviceId;
}
// Usage in component
function AppContent() {
const deviceId = usePersistedDeviceId();
// Wait for device ID before initializing sync
if (!deviceId) return null;
useSyncQueriesExternal({
queryClient,
socketURL: "http://localhost:42831",
deviceName: Platform.OS,
platform: Platform.OS,
deviceId, // Now persistent across restarts
});
return ;
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.