0.0.4 • Published 2 years ago

@j4ndrw/lightweight-signals v0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Lightweight Signals

Core functionality

You can use the signal, computed and effect primitives to make your program reactive. Think of this being a way to use React's useState, useMemo and useEffect in non-React / non-frontend applications.

I mostly implemented those to learn more about ways of implementing reactivity. It works well enough as a PoC, but I wouldn't recommend using it in production.

React bindings

React already comes with reactive primitives, but I wanted to add a simple way to create a store. The useSignalStore binding is heavily inspired by Valtio.

Usage

Node

import { signal, computed, effect } from "@j4ndrw/lightweight-signals";

// Create a signal:
const count = signal(0);

// Create a computed signal:
const doubledCount = computed(() => count.unwrap() * 2, [count]);
// Will update when `count` updates.

// Create an effect:
effect(() => {
    console.log(`The value of the doubled count is ${doubledCount.unwrap()}`);
}, [doubledCount]);
// Will run every type `doubledCount` is updated.

// Update a signal
count.set(7);
// Will cause `doubledCount` to update to `count * 2` (7 * 2 = 14). It will also trigger the effect.

// Update a signal based on its previous value
count.setFrom((prev) => prev - 3);
// Will cause `doubledCount` to update to `count * 2` ((7 - 3) * 2 = 8). It will also trigger the effect.

React

// useStore.tsx
import { useSignalStore } from "@j4ndrw/lightweight-signals/dist/react";

interface Store {
    realName: string;
    heroName: string;
}

const store: Store = {
    realName: "Peter Parker",
    heroName: "Spider-Man",
};

export const useStore = () => useSignalStore(store);

// App.tsx
import { useStore } from "./useStore";

export const App = () => {
    const { store } = useStore();
    const { realName, heroName } = store.unwrap();

    useEffect(() => {
        store.set("realName", "Bruce Wayne");
        store.set("heroName", "Batman");
    }, []);

    return (
        <div>
            <p>
                {heroName}'s real name is {realName}
            </p>
        </div>
    );
};