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

@muchekechege/pulsesync

v1.2.0

Published

High-performance pull-model sync for React

Downloads

393

Readme

PulseSync ⚡️

A high-performance, Pull-Model state synchronization library for React. Specifically engineered for high-frequency data (Trading Bots, WebSockets, Tickers) where traditional React state or "push" models (like standard Redux or MobX) cause UI lag and "data skipping" on mobile devices.


🚀 The Problem: "The Push Bottleneck"

In high-frequency environments (like XAUUSD markets), ticks arrive constantly. Traditional state managers push every update to React: WebSocket -> Store -> Notify -> React Render -> Browser Paint

On a mobile device, if the "Paint" takes too long, the next tick is blocked. This leads to:

  • Skipped Ticks: The WebSocket buffer overflows because the UI thread is stuck.
  • UI Stutters: The Garbage Collector (GC) works overtime cleaning up discarded state objects.
  • Crashes: Memory pressure builds up until the mobile browser kills the tab.

🛡️ The Solution: "The Pull Model"

PulseSync reverses the flow. It updates a silent internal store instantly ($<0.1ms$) and allows React to pull the data only when the browser is ready to draw a frame: WebSocket -> Store (Instant Mutation) Browser Heartbeat -> requestAnimationFrame -> Pull Latest -> React Render


📦 Installation

npm install @muchekechege/pulsesync

usage

1. Create a Store

Define your initial state and initialize the store. This creates a singleton-like instance and a custom hook.

// stores/marketStore.ts
import { createPulseStore } from '@muchekechege/pulsesync';

export const { store, useSync } = createPulseStore({
  price: 0,
  timeStamp: 0,
  isCalculated: false
});

// Helper to update the store outside of the component
export const increment = () => {
  store.update({ price: store.getSnapshot().price + 1 });
};

export const decrement = () => {
  store.update({ price: store.getSnapshot().price - 1 });
};

2. Silent Updates (High Frequency)

Update the store inside your WebSocket listeners or calculation loops. These updates are "silent"—they do not trigger React's heavy rendering cycle immediately.

// logic/bot.ts
import { store } from './stores/marketStore';

socket.on('message', (data) => {
  // Ultra-fast mutation using Object.assign
  // Marks state as 'dirty' to trigger a sync on the next frame
  store.update({
    price: data.p,
    timeStamp: data.d
  });
});

3. Consume in React

Use the useSync hook with a selector. The component will only re-render if the specific slice of data you selected has changed during the last "heartbeat".

import { useSync } from './stores/marketStore';

const PriceDisplay = () => {
  // Only pulls 'price'. Ignores updates to 'timeStamp'.
  // Default equality is strict (a === b)
  const price = useSync(state => state.price);

  return <h1>${price.toFixed(2)}</h1>;
};

4. Advanced: Custom Equality

For selectors that return arrays or objects, pass a custom equality function as a second argument to useSync to prevent unnecessary renders.

const orders = useSync(
  state => state.orders,
  (prev, next) => prev.length === next.length // Custom comparison
);

🔥 Key Performance Features

  • Zero-Allocation Mutations: Internally uses Object.assign to update the state object. This prevents the creation of millions of temporary objects, keeping the Garbage Collector silent and avoiding mobile "hiccups".
  • isDirty CPU Shock Absorber: The internal heartbeat loop only notifies listeners if an update was actually triggered via store.update(). This saves massive CPU cycles during market "quiet" periods.
  • Global Heartbeat: Uses a single requestAnimationFrame loop for all active hooks. No matter how many components you have, there is only ever one sync loop running.
  • Backpressure Handling: If the device heats up or the CPU is throttled, the UI naturally drops from 60fps to 30fps, but the WebSocket logic continues at full speed in the background.

💡 Best Practices

  • Leaf Components: Use useSync in the smallest possible component. Instead of one large Dashboard hook, use small hooks in PriceLabel, DigitBox, and StatusIcon.
  • Simple Selectors: Keep your selectors simple (e.g., s => s.value). If you need complex derived math, perform it inside the store.update() phase, not in the UI hook.
  • Cleanup: PulseSync automatically stops its internal heartbeat when the last component unmounts, ensuring zero memory leaks.