3.6.34 • Published 3 months ago

@sirajju/use-sync v3.6.34

Weekly downloads
-
License
ISC
Repository
github
Last release
3 months ago

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

# Using npm
npm install @sirajju/use-sync

# Using yarn
yarn add @sirajju/use-sync

# Using pnpm
pnpm add @sirajju/use-sync

Basic Usage

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

const fetchOrders = [{
  key: "users",
  action: setUsers,
  allowDuplicates: true, // Allow parallel requests for same endpoint
  // ...other config
}];

Custom Fetch Implementation

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

const order = {
  key: "users",
  action: setUsers,
  options: {
    errorHandler: (error) => {
      // Custom error handling per request
      console.error(`Users sync failed: ${error}`);
    }
  }
};

Advanced Features

Cache Control

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

// 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

useSync({
  logger: true,
  logLevel: "DEBUG", // "DEBUG" | "INFO" | "WARN" | "ERROR"
  // ...other config
});

Window Event Triggers

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

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

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

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

// 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

    // Make sure to use the correct key
    clearCache("exact-key-name");
  2. Event Triggers Not Working

    // Only use valid window events
    triggerEvents: ['scroll', 'resize'] // ✅ Correct
    triggerEvents: ['custom-event']     // ❌ Incorrect
  3. Redux Integration

    // Ensure your action creator is properly typed
    const action: ActionCreator = (data) => ({
      type: 'SET_DATA',
      payload: data
    });

Debug Mode

Enable detailed logging for troubleshooting:

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

3.6.34

3 months ago

3.6.33

3 months ago

3.6.32

3 months ago

3.6.31

3 months ago

3.6.30

3 months ago

3.6.29

3 months ago

3.6.28

3 months ago

3.6.27

3 months ago

3.6.26

4 months ago

3.6.25

4 months ago

3.6.24

6 months ago

3.6.23

6 months ago

3.6.22

6 months ago

3.6.21

6 months ago

3.6.20

6 months ago

3.6.19

6 months ago

3.6.18

7 months ago

3.6.17

7 months ago

3.6.15

7 months ago

3.6.14

7 months ago

3.6.13

7 months ago

3.6.12

7 months ago

3.6.11

7 months ago

3.6.10

7 months ago

3.6.9

7 months ago

3.6.8

7 months ago

3.6.7

7 months ago

3.6.6

7 months ago

3.6.5

7 months ago

3.6.4

7 months ago

3.6.3

7 months ago

3.6.2

7 months ago

3.6.1

7 months ago

3.6.0

7 months ago

3.5.0

7 months ago

3.4.0

7 months ago

3.3.0

7 months ago

3.2.0

7 months ago

3.1.0

7 months ago

3.0.0

7 months ago

2.3.0

7 months ago

2.2.0

8 months ago

2.1.0

8 months ago

2.0.0

8 months ago

1.0.4

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago