npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sirajju/use-sync

v3.6.34

Published

A package for keep updating the states

Readme

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