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

shimmershards

v0.3.6

Published

shimmershards is a reactive state library

Downloads

136

Readme

ShimmerShards - A Reactive React State Management Library

Shimmer Shards Logo

Size Version

What is ShimmerShards?

ShimmerShards is a powerful reactive React state management library designed to facilitate effortless sharing of states across the app while providing an excellent developer experience and full Typescript support.

Learn more about ShimmerShards: shimmershards.dev

Get Started

Installation

NPM

npm i shimmershards

Yarn

yarn add shimmershards

PNPM

pnpm add shimmershards

Bun

bun add shimmershards

How to use?

Create a shard

In ShimmerShards, creating a shard is a simple process using the shard function. A shard represents a piece of state that you can use similarly to the regular useState hook in React.

import { shard, useShard } from "shimmershards";

const counterShard = shard(0);

const Component = () => {
  const [counter, setCounter] = useShard(counterShard);

  return <div>{counter}</div>;
};

If you want to share the state across the app, you can export the shard.

import { shard, useShard } from "shimmershards";

export const counterShard = shard(0);

Now you can import and use it in other components.

import { counterShard } from "../dir";
import { useShard } from "shimmershards";

const ComponentB = () => {
  const [counter, setCounter] = useShard(counterShard);

  return <div>{counter}</div>;
};

When the state is updated in one place, all components using that shard will be in sync.

Create a Cluster

A cluster is a way to group multiple shards together. It provides a mechanism to manage related state pieces collectively.

import { shard, useCluster } from "shimmershards";
const nameShard = shard("John");
const ageShard = shard(18);
const cluster = {
  useName: nameShard,
  useAge: ageShard,
};

const Component = () => {
  const { useName, useAge } = useCluster(cluster);
  const [name, setName] = useName();
  const [age, setAge] = useAge();

  return (
    <div>
      name: {name} age: {age}
    </div>
  );
};

You can also export the cluster object to use it in different components as shown in the Shard example above.

Scoped State Management with "Scope" in ShimmerShards

ShimmerShards provides a powerful feature called "Scope" that allows you to localize shard states to specific sections of your application. By wrapping components with the Scope component, you can separate shard states, ensuring that updates in one scope do not affect others, even if the same shard is used.

import { Scope, shard, useShard } from "shimmershards";

// Create two shards, one for name and one for age
const nameShard = shard("John");
const ageShard = shard(18);

// Child component that uses the name and age shards
const Child = () => {
  const [age, setAge] = useShard(ageShard);
  const [name, setName] = useShard(nameShard);

  return (
    <div>
      age: {age}
      name: {name}
      <button onClick={() => setAge((prev) => prev + 1)}>increase age</button>
      <input value={name} onChange={(e) => setName(e.target.value)} />
    </div>
  );
};

const Component = () => {
  const [age, setAge] = useShard(ageShard);
  const [name, setName] = useShard(nameShard);

  return (
    <div>
      {/* Outside scope */}
      <p>
        age: {age}
        name: {name}
      </p>
      <br />
      <Scope shards={[nameShard, ageShard]}>
        {/* Scope A */}
        <Child />
      </Scope>
      <br />
      <Scope shards={[nameShard, ageShard]}>
        {/* Scope B */}
        <Child />
      </Scope>
    </div>
  );
};

With the Scope component, you can manage shard states independently within different sections of your application. Any updates to the state within one scope will not impact the state in other scopes or the outside scope, even if you are using the same shards.

But wait! Also working with cluster too.
import { Scope, shard, useCluster } from "shimmershards";

// Create two shards, one for name and one for age
const nameShard = shard("John");
const ageShard = shard(18);

// Create a cluster with the name and age shards
const cluster = {
  useName: nameShard,
  useAge: ageShard,
};

// Child component that uses the cluster
const Child = () => {
  const { useName, useAge } = useCluster(cluster);
  const [age, setAge] = useAge();
  const [name, setName] = useName();

  return (
    <div>
      age: {age}
      name: {name}
      <button onClick={() => setAge((prev) => prev + 1)}>increase age</button>
      <input value={name} onChange={(e) => setName(e.target.value)} />
    </div>
  );
};

const Component = () => {
  const { useName, useAge } = useCluster(cluster);
  const [age, setAge] = useAge();
  const [name, setName] = useName();

  return (
    <div>
      {/* Outside scope */}
      <p>
        age: {age}
        name: {name}
      </p>
      <br />
      <Scope shards={cluster}>
        {/* Scope A */}
        <Child />
      </Scope>
      <br />
      <Scope shards={cluster}>
        {/* Scope B */}
        <Child />
      </Scope>
    </div>
  );
};

ShimmerShards offers a seamless and efficient solution for managing and sharing state in your React applications. Its simplicity and full TypeScript support make it a top-notch choice for state management in your projects.

Persistence

ShimmerShard allows you to persist data without worries about losing data. We'll be keeping the all data that you want. Just keep it there!

Create a persistence shard

The way to create a persistence shard is just like a normal shard but we use persist instead of shard.

import { persist } from "shimmershards";
const examplePersistShard = persist({
  initialValue: 0,
  // localStorage's key
  key: "key",
  // optional
  fallback: 2,
});

To consume the persistance shard you need to use usePersistShard instead ofuseShard.

import { persist, usePersistShard } from "shimmershards";

const examplePersistShard = persist({
  initialValue: 0,
  // localStorage's key
  key: "key",
  // optional
  fallback: 2,
});

const Component = () => {
  const [counter, setCounter] = usePersistShard(examplePersistShard);
  return <div>...</div>;
};

State sharing still uses the same approach as shard. Persistence shard is compatible with Cluster also.

Caveats

The persistence shard will not be able to be Scope.

Memo and Effect

memo and effect functions are tools to handle custom hooks. When you work with a custom hook that shares state or functionality, they won't necessarily use the same instance or cache. That's where memo and effect functions come in handy to address this problem.

memo

memo is a higher-order function that makes your custom function behave like an instance.

effect

effect is a function similar to useEffect that helps you manage dependencies provided to the function.

Caveats

To capture useEffect properly, use effect instead of useEffect. Remember that effect should be exclusively used within the memo function.

Example

import { memo, effect, shard, useShard } from "shimmershards";

const counterShard = shard(0);

export const useCounter = memo(() => {
  const [counter, setCounter] = useShard(counterShard);

  effect(() => {
    console.log(counter);
  }, [counter]);

  return { counter, setCounter };
});

Key Highlights:

  • Easy State Management: With ShimmerShards' shard function, creating and using shards as state variables is straightforward, similar to the useState hook in React.

  • Scoped State Management: The Scope component allows you to create isolated scopes for state management, ensuring that state updates within a scope do not affect others.

  • Cluster Support: ShimmerShards supports clustering related shards together, providing a structured approach to manage and share grouped states.

Check out the documentation at shimmershards.dev to explore more features and examples.

Feel free to contribute, report issues, or suggest improvements. Happy coding! 🚀