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 🙏

© 2024 – Pkg Stats / Ryan Hefner

rehookd

v1.0.0

Published

A React hook framework for optimized state management, real-time collaboration, and more.

Downloads

3

Readme

Rehookd Framework Documentation

Introduction

Rehookd is a powerful React hook framework designed to simplify and optimize state management, concurrency, real-time collaboration, UI handling, and more. The framework introduces a series of macro hooks, each combining multiple hooks to handle specific use cases, such as managing state with undo/redo, handling asynchronous tasks with workers, and virtualizing scroll lists for better performance.

This documentation will guide you through installing the framework, understanding each macro, and using them with detailed examples that demonstrate their full potential.


Installation

To install Rehookd, use npm:

npm install rehookd

Once installed, you can import the necessary macros or hooks directly into your React components:

import { useStateWithHistory, useQueue } from 'rehookd';

Macro Hooks Overview

1. useStateWithHistory (undo/redo and queue)

useStateWithHistory

This hook manages state with undo and redo functionality. It maintains a history of changes, allowing you to revert or redo actions as needed.

useQueue

Adds the ability to manage a queue of state changes or actions, useful for handling sequences like notifications, task sequences, or batched state changes.

Usage Example:

import { useStateWithHistory, useQueue } from 'rehookd';

const TaskQueueComponent = () => {
  // Initial state with undo/redo functionality
  const { state, setState, undo, redo, canUndo, canRedo } = useStateWithHistory('Initial State');
  
  // Queue to handle multiple tasks
  const { enqueue, dequeue, queue } = useQueue();

  const handleStateChange = () => {
    setState('Updated State');
  };

  const handleUndo = () => {
    if (canUndo) undo();
  };

  const handleRedo = () => {
    if (canRedo) redo();
  };

  const addTaskToQueue = (task) => {
    enqueue(task);
  };

  const processQueue = () => {
    const nextTask = dequeue();
    if (nextTask) nextTask(); // Process the task
  };

  return (
    <div>
      <p>Current State: {state}</p>
      <button onClick={handleStateChange}>Update State</button>
      <button onClick={handleUndo} disabled={!canUndo}>Undo</button>
      <button onClick={handleRedo} disabled={!canRedo}>Redo</button>
      
      <button onClick={() => addTaskToQueue(() => console.log('Task 1'))}>Add Task 1</button>
      <button onClick={processQueue}>Process Queue</button>

      <p>Queue Length: {queue.length}</p>
    </div>
  );
};

2. useStateManagement (global state, selectors, sync, and immutability)

useSelector

Selects specific parts of the state for optimized re-renders. This is useful when you need to update only part of a component based on global or local state changes.

useStateSync

Synchronizes state across multiple components without the need for React Context or external state libraries.

useAtom / useStore

Manages global or shared state in a lightweight, Recoil/Jotai-like manner, allowing for a central store of state that is easy to access from any component.

useImmutableState

Ensures immutability in state management, preventing accidental mutations and ensuring a safe state update process.

useProxyState

Automatically tracks and updates state through a proxy, removing the need for manual updates or setter functions.

Usage Example:

import { useStore, useSelector, useStateSync, useImmutableState, useProxyState } from 'rehookd';

const GlobalStateComponent = () => {
  // Create a global store with some initial state
  const [globalState, setGlobalState] = useStore('globalKey', { count: 0, name: 'John' });

  // Select part of the state for optimized re-renders
  const name = useSelector('globalKey', (state) => state.name);

  // Synchronize state across components
  const [syncedState, setSyncedState] = useStateSync('globalKey');

  // Immutable state management
  const [immutableState, setImmutableState] = useImmutableState('immutableKey', { value: 100 });

  // Proxy state for automatic updates
  const proxyState = useProxyState('proxyKey', { clicks: 0 });

  const incrementCounter = () => {
    setGlobalState((prevState) => ({ ...prevState, count: prevState.count + 1 }));
  };

  return (
    <div>
      <p>Global Count: {globalState.count}</p>
      <p>Name: {name}</p>
      <button onClick={incrementCounter}>Increment Counter</button>

      <p>Synced Count: {syncedState.count}</p>
      <button onClick={() => setSyncedState({ count: syncedState.count + 1 })}>Sync Increment</button>

      <p>Immutable Value: {immutableState.value}</p>
      <button onClick={() => setImmutableState({ value: immutableState.value + 10 })}>Increment Immutable Value</button>

      <p>Proxy Clicks: {proxyState.clicks}</p>
      <button onClick={() => proxyState.clicks++}>Increment Proxy Clicks</button>
    </div>
  );
};

3. useTimeManagement (timers, countdowns, and scheduling)

useTimeout

Delays actions or state updates by a specified amount of time.

useCountdown

Manages countdown timers for time-based events like promotions or deadlines.

useSchedule

Schedules tasks to run at specific intervals or times.

Usage Example:

import { useTimeout, useCountdown, useSchedule } from 'rehookd';

const TimeManagementComponent = () => {
  // Delay an action by 2 seconds
  useTimeout(() => console.log('Action delayed by 2 seconds'), 2000);

  // Countdown from 10 to 0
  const [timeLeft, startCountdown, resetCountdown] = useCountdown(10);

  // Schedule a task to run every 1 second
  useSchedule(() => console.log('Scheduled task running every second'), 1000);

  return (
    <div>
      <p>Time Left: {timeLeft}</p>
      <button onClick={startCountdown}>Start Countdown</button>
      <button onClick={resetCountdown}>Reset Countdown</button>
    </div>
  );
};

4. useConcurrency (workers, tasks, loops, and async operations)

useWorker

Manages background tasks using Web Workers to offload expensive computations.

useConcurrentTasks

Manages multiple asynchronous tasks in parallel, ensuring efficient task processing.

useAsyncLoop

Continuously runs tasks or loops asynchronously until a condition is met.

useFork

Manages parallel execution of functions or tasks, similar to forking processes in other languages.

Usage Example:

import { useWorker, useConcurrentTasks, useAsyncLoop, useFork } from 'rehookd';

const ConcurrencyComponent = () => {
  const worker = useWorker((data) => {
    // Expensive computation handled in the worker
    return data.map(item => item * 2);
  });

  const tasks = [
    () => fetch('https://api.example.com/task1').then(res => res.json()),
    () => fetch('https://api.example.com/task2').then(res => res.json()),
  ];

  const { results, runTasks } = useConcurrentTasks(tasks);

  useAsyncLoop(() => {
    console.log('Polling data every second');
  }, 1000, () => results.length > 0);

  useFork(() => console.log('Task 1'), () => console.log('Task 2'));

  return (
    <div>
      <button onClick={() => worker.postMessage([1, 2, 3])}>Run Worker</button>
      <button onClick={runTasks}>Run Concurrent Tasks</button>
    </div>
  );
};

5. useRealTime (sockets, presence, and collaboration)

useSocket

Manages WebSocket connections for real-time communication like chats and live updates.

usePresence

Tracks and manages user presence in collaborative applications (e.g., online/offline, typing status).

useCollaborativeState

Synchronizes state across multiple users in real-time, ideal for collaborative environments like document editing.

Usage Example:

import { useSocket, usePresence, useCollaborativeState } from 'rehookd';

const RealTimeComponent = () => {
  const { sendMessage, receiveMessage } = useSocket('ws://example.com/socket');
  const { isOnline, setPresence } = usePresence();
  const [collabState, setCollabState] = useCollaborativeState('doc', { content: '' });

  receiveMessage((message) => {
    console.log('Received:', message);
  });

  const handleSend = () => {
    sendMessage('Hello, World!');
  };

  return (
    <div>
      <p>Online Status: {isOnline ? 'Online' : 'Offline'}</p>
      <button onClick={() => setPresence(!isOnline)}>Toggle Presence</button>

      <textarea
        value={collabState.content}
        onChange={(e) => setCollabState({ content: e.target.value })}placeholder="Collaborative Document Editing"
      />
      <button onClick={handleSend}>Send Message</button>
    </div>
  );
};

6. useUserActivity (idle detection, page visibility, and clipboard)

useIdle

Detects when the user becomes idle for a specified period. This is useful for session timeouts, showing idle warnings, or triggering background tasks.

usePageVisibility

Detects if the current page is visible or hidden (e.g., to pause media playback or animation when the user switches tabs).

useClipboard

Provides a way to read and write data to the clipboard, supporting features like copying text from your application.

Usage Example:

import { useIdle, usePageVisibility, useClipboard } from 'rehookd';

const ActivityTrackerComponent = () => {
  const isIdle = useIdle(5000); // Detect if idle for 5 seconds
  const isVisible = usePageVisibility();
  const { copyToClipboard, readFromClipboard } = useClipboard();

  const handleCopy = () => {
    copyToClipboard('Copied to clipboard!');
  };

  return (
    <div>
      <p>User is {isIdle ? 'Idle' : 'Active'}</p>
      <p>Page is {isVisible ? 'Visible' : 'Hidden'}</p>

      <button onClick={handleCopy}>Copy Text</button>
      <button onClick={() => readFromClipboard().then((text) => alert(`Clipboard: ${text}`))}>
        Read Clipboard
      </button>
    </div>
  );
};

7. useScrollAndNavigation (scroll restoration, route guards, lazy loading)

useScrollRestoration

Automatically restores the scroll position when navigating between routes, ensuring that users return to the same scroll position they left.

useRouteGuard

Prevents unauthorized access to routes by enforcing specific conditions before navigation.

useLazyRouteLoader

Lazily loads routes to optimize performance, especially in large applications where loading everything upfront would be inefficient.

Usage Example:

import { useScrollRestoration, useRouteGuard, useLazyRouteLoader } from 'rehookd';

const NavigationComponent = () => {
  useScrollRestoration(); // Automatically restore scroll position on navigation

  const isAuthenticated = false; // Replace with actual auth logic
  useRouteGuard(isAuthenticated, '/login'); // Prevent navigation to protected routes

  const { loadRoute, isLoading } = useLazyRouteLoader(() => import('./HeavyComponent'));

  return (
    <div>
      <button onClick={loadRoute}>Load Heavy Component</button>
      {isLoading ? <p>Loading...</p> : <HeavyComponent />}
    </div>
  );
};

8. useSpeech (recognition, synthesis, and media handling)

useSpeechRecognition

Integrates speech recognition, allowing voice commands or dictation in your application.

useSpeechSynthesis

Handles text-to-speech functionality for user feedback or accessibility.

useMeta

Dynamically updates meta tags for better SEO and social sharing, ensuring your app’s metadata is always relevant.

Usage Example:

import { useSpeechRecognition, useSpeechSynthesis, useMeta } from 'rehookd';

const SpeechComponent = () => {
  const { transcript, startRecognition, stopRecognition } = useSpeechRecognition();
  const { speak, cancelSpeech } = useSpeechSynthesis();

  // Dynamically update meta tags
  useMeta({ title: 'Speech Example', description: 'A speech recognition and synthesis demo' });

  return (
    <div>
      <p>Transcript: {transcript}</p>
      <button onClick={startRecognition}>Start Recognition</button>
      <button onClick={stopRecognition}>Stop Recognition</button>

      <button onClick={() => speak('Hello, world!')}>Speak</button>
      <button onClick={cancelSpeech}>Cancel Speech</button>
    </div>
  );
};

9. useVirtual (scroll and lists)

useVirtualScroll

Optimizes scrolling performance by only rendering the visible portion of a large dataset (virtual scrolling).

useVirtualList

Efficiently manages large lists or tables by rendering only the visible rows or items, improving the performance of large datasets.

Usage Example:

import { useVirtualScroll, useVirtualList } from 'rehookd';

const VirtualListComponent = () => {
  const items = Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`);
  const { visibleItems, containerProps } = useVirtualList(items, 50); // Assume 50px height per item

  return (
    <div {...containerProps} style={{ height: '400px', overflow: 'auto' }}>
      {visibleItems.map((item, index) => (
        <div key={index} style={{ height: '50px' }}>
          {item}
        </div>
      ))}
    </div>
  );
};

10. useReactiveStreams (observables, subjects, and pipes)

useObservable

Handles reactive streams of data, allowing components to subscribe to and react to asynchronous events.

useSubject

Manages a reactive subject, allowing components to both emit and subscribe to a stream of values.

usePipe

Chains operations together in a pipeline to handle complex data transformations, similar to RxJS pipes.

Usage Example:

import { useObservable, useSubject, usePipe } from 'rehookd';

const ReactiveStreamsComponent = () => {
  const { subscribe, emit } = useSubject();

  subscribe((data) => {
    console.log('Received data:', data);
  });

  const pipeline = usePipe(
    (data) => data * 2,
    (data) => data + 1
  );

  const handleEmit = () => {
    const transformedData = pipeline.execute(5); // Pipeline: (5 * 2) + 1 = 11
    emit(transformedData);
  };

  return (
    <div>
      <button onClick={handleEmit}>Emit Data</button>
    </div>
  );
};

11. useUI (modals, snackbars, tabs, and gestures)

useModal

Manages modal dialogs, including open/close state and animations.

useSnackbar

Displays snackbars or toast notifications for user feedback.

useTabs

Manages tabbed interfaces, allowing easy navigation between sections of a page.

useGestures

Tracks touch and gesture-based interactions, such as swiping or pinching, especially useful for mobile-friendly UIs.

Usage Example:

import { useModal, useSnackbar, useTabs, useGestures } from 'rehookd';

const UIComponent = () => {
  const { open, close, isOpen } = useModal();
  const { showSnackbar } = useSnackbar();
  const { activeTab, setActiveTab } = useTabs(['Tab1', 'Tab2', 'Tab3']);
  const { detectSwipe } = useGestures();

  detectSwipe((direction) => console.log('Swipe detected:', direction));

  return (
    <div>
      <button onClick={open}>Open Modal</button>
      <button onClick={() => showSnackbar('Hello, Snackbar!')}>Show Snackbar</button>

      {isOpen && <div>Modal Content <button onClick={close}>Close</button></div>}

      <div>
        <button onClick={() => setActiveTab('Tab1')}>Tab 1</button>
        <button onClick={() => setActiveTab('Tab2')}>Tab 2</button>
        <button onClick={() => setActiveTab('Tab3')}>Tab 3</button>
      </div>

      <p>Active Tab: {activeTab}</p>
    </div>
  );
};

12. useWebComponents (custom elements, shadow DOM, slots)

useCustomElement

Integrates custom HTML elements or Web Components into your React application.

useShadowDOM

Encapsulates styles and content in a Shadow DOM, preventing style leakage.

useSlot

Allows flexible content distribution in components, similar to Web Component slots.

Usage Example:

import { useCustomElement, useShadowDOM, useSlot } from 'rehookd';

class MyCustomElement extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<div><slot></slot></div>`;
  }
}

const WebComponentExample = () => {
  useCustomElement('my-custom-element', MyCustomElement);

  const containerRef = useShadowDOM();
  const { setSlotContent } = useSlot(containerRef);

  return (
    <div ref={containerRef}>
      <my-custom-element>
        <span>Content inside the Web Component</span>
      </my-custom-element>
      <button onClick={() => setSlotContent('Updated content in slot')}>
        Update Slot Content
      </button>
    </div>
  );
};

13. useDatabaseAndTransactions (ORM and transactions)

useORM

Simplifies database interactions by providing an ORM-like hook to manage data models.

useTransaction

Handles batched updates

or state changes as atomic transactions, ensuring consistency and preventing partial updates.

Usage Example:

import { useORM, useTransaction } from 'rehookd';

const DatabaseComponent = () => {
  const { find, insert, update } = useORM('users');
  const { startTransaction, commit, rollback } = useTransaction();

  const addUser = () => {
    startTransaction();
    insert({ id: 1, name: 'Alice' });
    commit();
  };

  const handleUpdate = () => {
    startTransaction();
    update(1, { name: 'Updated Alice' });
    commit();
  };

  return (
    <div>
      <button onClick={addUser}>Add User</button>
      <button onClick={handleUpdate}>Update User</button>
    </div>
  );
};

14. useBrowserNotifications

useNotification

Manages browser notifications to engage users, useful for event alerts or reminders.

Usage Example:

import { useNotification } from 'rehookd';

const NotificationComponent = () => {
  const { requestPermission, showNotification } = useNotification();

  const sendNotification = () => {
    requestPermission().then(() => {
      showNotification('New Message', { body: 'You have a new message!' });
    });
  };

  return <button onClick={sendNotification}>Send Notification</button>;
};

15. useTaskLoop (repeated task execution)

useLoop

Continuously runs a task until a condition is satisfied, automating processes like data fetching or event polling.

Usage Example:

import { useLoop } from 'rehookd';

const TaskLoopComponent = () => {
  const [count, setCount] = useState(0);

  useLoop(() => {
    setCount((prev) => prev + 1);
  }, 1000, () => count >= 10);

  return <p>Count: {count}</p>;
};

16. useLazyEvaluation (deferred computation)

useLazyEvaluation

Defers calculations until they are absolutely necessary, optimizing performance for expensive operations.

Usage Example:

import { useLazyEvaluation } from 'rehookd';

const ExpensiveComponent = () => {
  const { evaluate, getResult } = useLazyEvaluation(() => {
    return Array(1000000).fill(0).reduce((acc, _, i) => acc + i, 0);
  });

  return (
    <div>
      <p>Result: {getResult()}</p>
      <button onClick={evaluate}>Evaluate Expensive Calculation</button>
    </div>
  );
};

17. useActivity (tracking component usage)

useActivity

Assigns unique IDs to components and tracks their usage (e.g., clicks, focus events) in real-time, saving data to localStorage. Data can later be sent to a backend for analytics.

Usage Example:

import { useActivity } from 'rehookd';

const ActivityComponent = () => {
  const { componentId, trackClick, trackFocus, getActivityData, clearActivityData } = useActivity('ComponentA');

  const sendDataToBackend = () => {
    const data = getActivityData();
    console.log('Sending activity data:', data);
    clearActivityData();
  };

  return (
    <div>
      <p>Component ID: {componentId}</p>
      <button onClick={trackClick}>Track Click</button>
      <input onFocus={trackFocus} placeholder="Focus here" />

      <button onClick={sendDataToBackend}>Send Activity Data</button>
    </div>
  );
};

Conclusion

Rehookd provides a suite of powerful, reusable hooks for React developers. From state management with undo/redo, concurrency, and real-time communication, to UI components and virtualized scrolling, this framework simplifies complex workflows and boosts performance.