UNPKG

@sirajju/use-sync

Version:

A package for keep updating the states

385 lines (318 loc) 9.44 kB
# use-sync A powerful React hook for managing state synchronization with intelligent caching, logging, and event-driven updates. ## Features - ⚡ Automatic state synchronization - 📦 Intelligent request caching - 💾 Persistent IndexedDB caching - 🔌 Network status integration - 🎯 Window focus detection - 📡 Custom event triggers - 📋 Configurable logging - 🔒 Request deduplication - 🔄 Redux integration - ⏳ Loading states per item - 🗑️ Manual cache control - 📊 Detailed debug information - 📘 TypeScript support ## Installation ```bash # Using npm npm install @sirajju/use-sync # Using yarn yarn add @sirajju/use-sync # Using pnpm pnpm add @sirajju/use-sync ``` ## Basic Usage ```typescript import { useSync } from "@sirajju/use-sync"; function App() { const endpoints = new Map([ ['users', 'https://api.example.com/users'], ['products', 'https://api.example.com/products'] ]); const fetchOrders = [ { key: "users", action: setUsers, refetchOnFocus: true, refetchOnline: true, triggerEvents: ['scroll', 'resize'], // Only window events options: { headers: { "Content-Type": "application/json" } } } ]; const { isPending, haveError, loadingItems, clearCache, refresh } = useSync({ fetchItems: endpoints, fetchOrder: fetchOrders, logger: true, logLevel: "DEBUG", cacheDuration: 5000, onError: (error) => console.error(error) }); // Access loading state for specific items console.log("Currently loading:", loadingItems); return <div>{/* Your UI */}</div>; } ``` ## 🎯 Latest Features (v2.2) ### Configurable Duplicate Requests ```typescript const fetchOrders = [{ key: "users", action: setUsers, allowDuplicates: true, // Allow parallel requests for same endpoint // ...other config }]; ``` ### Custom Fetch Implementation ```typescript const { isPending } = useSync({ fetchItems: endpoints, fetchOrder: orders, customFetch: async (url, options) => { // Use your own fetch implementation return await axios.get(url, options); } }); ``` ### Enhanced Error Handling ```typescript const order = { key: "users", action: setUsers, options: { errorHandler: (error) => { // Custom error handling per request console.error(`Users sync failed: ${error}`); } } }; ``` ## Advanced Features ### Cache Control ```typescript import { useSync, clearCache } from "@sirajju/use-sync"; // Clear specific item's cache clearCache("users"); // Clear all cache clearCache(); // Configure cache durations (milliseconds) useSync({ // Legacy option - controls both memory and IndexedDB cache if specific durations aren't provided cacheDuration: 10000, // 10 seconds // Specific control over memory cache duration memoryCacheDuration: 5000, // 5 seconds // Specific control over IndexedDB cache duration indexDbCacheDuration: 86400000, // 24 hours // ...other config }); // Control cache durations at request level syncIndividual( "users", { memoryCacheDuration: 30000, // 30 seconds memory cache for this request indexDbCacheDuration: 3600000, // 1 hour IndexedDB cache for this request params: { id: 123 } } ); ``` ### IndexedDB Persistent Cache ```typescript // Enable IndexedDB cache globally useSync({ indexDbCache: true, // Enable persistent storage // Default cache duration is 24 hours // ...other config }); // Enable for specific requests const fetchOrders = [{ key: "users", action: setUsers, indexDbCache: true, // Enable IndexedDB caching for this request // ...other config }]; // Control caching at the individual request level syncIndividual( "users", { useIndexDB: false, // Override any previous settings and disable IndexedDB for this specific call params: { id: 123 } } ); // Background update with immediate cache usage const fetchOrders = [{ key: "users", action: setUsers, options: { indexDbCache: true, updateIndexDbData: true, // Use cache immediately but update in background } }]; // IndexedDB functions are also exported for direct usage import { storeInIndexedDB, getFromIndexedDB, deleteFromIndexedDB, clearIndexedDBCache } from "@sirajju/use-sync"; ``` ### Logging System ```typescript useSync({ logger: true, logLevel: "DEBUG", // "DEBUG" | "INFO" | "WARN" | "ERROR" // ...other config }); ``` ### Window Event Triggers ```typescript const fetchOrders = [{ key: "users", action: setUsers, triggerEvents: ['scroll', 'resize', 'storage'] // Only window events are supported }]; // Data will be automatically refetched on these window events ``` ### Available Window Events Common events you can use: - `scroll` - Window scroll - `resize` - Window resize - `storage` - LocalStorage changes - `offline` - Browser goes offline - `online` - Browser goes online - `focus` - Window gains focus - `blur` - Window loses focus - `visibilitychange` - Tab visibility changes - `beforeunload` - Before window unload - `load` - Window load complete - `DOMContentLoaded` - Initial HTML loaded - `popstate` - Browser history changes ### Manual Sync with Progress Tracking ```typescript import { syncIndividual } from "@sirajju/use-sync"; function RefreshButton() { const handleRefresh = async () => { try { const data = await syncIndividual("users"); console.log("Refresh complete:", data); } catch (error) { console.error("Refresh failed:", error); } }; return <button onClick={handleRefresh}>Refresh</button>; } ``` ## API Reference ### useSync Hook ```typescript interface useSyncProps { fetchItems: Map<string, string>; // API endpoints fetchOrder: order[]; // Sync configurations throwError?: boolean; // Error handling mode onError?: (error: any) => void; // Error callback logger?: boolean; // Enable logging logLevel?: "DEBUG" | "INFO" | "WARN" | "ERROR"; cacheDuration?: number; // Legacy cache duration option (affects both memory and IndexedDB) memoryCacheDuration?: number; // Specific in-memory cache duration in ms indexDbCacheDuration?: number; // Specific IndexedDB cache duration in ms indexDbCache?: boolean; // Enable IndexedDB persistent cache customFetch?: (url: string, options: any) => Promise<Response>; // Custom fetch } ``` ### Order Configuration ```typescript type order = { key: string; // Unique identifier action: (data: any) => any; // Redux action creator allowDuplicates?: boolean; // Allow parallel requests refetchOnFocus?: boolean; // Refetch on window focus refetchOnline?: boolean; // Refetch when online indexDbCache?: boolean; // Use IndexedDB for persistent cache triggerEvents?: (keyof WindowEventMap)[]; // Window event names only options?: RequestInit & { indexDbCache?: boolean; // Enable IndexedDB at option level updateIndexDbData?: boolean; // Use cache, then update in background memoryCacheDuration?: number; // Override memory cache duration for this request indexDbCacheDuration?: number; // Override IndexedDB cache duration for this request }; }; ``` ## TypeScript Type Definitions ```typescript // Core types type SyncKey = string; type EndpointURL = string; type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR"; // Configuration interfaces interface SyncConfig { fetchItems: Map<SyncKey, EndpointURL>; fetchOrder: SyncOrder[]; throwError?: boolean; onError?: ErrorCallback; logger?: boolean; logLevel?: LogLevel; cacheDuration?: number; customFetch?: (url: string, options: any) => Promise<Response>; } interface SyncOrder { key: SyncKey; action: ActionCreator; allowDuplicates?: boolean; refetchOnFocus?: boolean; refetchOnline?: boolean; triggerEvents?: WindowEventName[]; options?: RequestInit; } // Result types interface SyncResult { isPending: boolean; haveError: boolean; loadingItems: SyncKey[]; clearCache: (key?: SyncKey) => void; refresh: () => Promise<void>; } ``` ## Troubleshooting ### Common Issues 1. **Cache Not Clearing** ```typescript // Make sure to use the correct key clearCache("exact-key-name"); ``` 2. **Event Triggers Not Working** ```typescript // Only use valid window events triggerEvents: ['scroll', 'resize'] // ✅ Correct triggerEvents: ['custom-event'] // ❌ Incorrect ``` 3. **Redux Integration** ```typescript // Ensure your action creator is properly typed const action: ActionCreator = (data) => ({ type: 'SET_DATA', payload: data }); ``` ### Debug Mode Enable detailed logging for troubleshooting: ```typescript useSync({ logger: true, logLevel: "DEBUG", // ...other config }); ``` ## Requirements - React 16.8+ - Redux 4.x - React Redux 7.x - TypeScript 4.x (for TypeScript users) ## License ISC License