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

boos

v1.0.3

Published

Simple state management library, which make use of a observer object alonside with React to share state between components

Downloads

10

Readme

Boos

Boos is React state management made simple, it makes use of the old fashioned observer pattern and React hooks to access and update state across the application.

Installation

# using npm
npm install boos --save

# using yarn
yarn add boos

It's important to point out that React it's a boos peer dependency so it's necessary to have it installed in your project

What is it a boos?

Boos stands for Boring observer because under the hood that's all that really is, and object that fits with the observer pattern

interface Boos<T> {
  subscribe: (subscriber: Subscriber<T>) => void;
  unsubscribe: (subscriber: Subscriber<T>) => void;
  modifyValue: (modifier: ValueModifier<T>) => T;
  getValue: () => T;
}

This interface expose the following methods

subscribe

Subscribe adds an observer/subscriber to the boos, an observer is a function that will be executed as soon as the boos value is modified. Besides the updated value will be passed to the subscriber to be managed in any way as it's necessary therefore allowing to separate business actions(modify the state) and those actions consequences(subscriber listening)

boos.subscribe(updatedValue => {
  // This will be executed
})

boos.subscribe(updatedValue => {
  // This will be executed too
})

unsubscribe

Sometimes a specific subscriber is not longer necessary by any reason, for instance a React component being removed from the screen thus no longer it's needed to be listening there for those cases unsubscribe method it's handy to avoid memory leaks, this removal is done by reference so same function that was added as the subscriber it must be passed as the function to be removed just as DOM addEventListener and removeEventListener works.

function listenerFunction(updatedValue) {
  // Do something
}

boos.subscribe(listenerFunction)
// Later
boos.unsubscribe(listenerFunction)

modifyValue

modifyValue receives a modifier function which will be passed the current value, it's important to have in mind how state will be changed under the hood, boos as depencency use immer for updating the state in a inmutable way but using a simple syntax so you can choose how you would like to change the state

// Immer simple syntax
boos.modifyValue(state => {
  state.value = "New value";
  state.products[1].price = 1000;
});

// More "inmutable" like syntax
boos.modifyValue(state => {
  return {
    ...state,
    value: "New value",
    products: state.products.map((product, i) => {
      return i === 1 ? {...product, price: 1000} : product
    })
  }
});

getValue

Simply get current boos value wherever is needed.

How create a boos?

The library expose createBoos function to create a boos, in your application create as many as you want, following flux architecture should not always be a must.

// productsBoos.(ts|js)
import { createBoos } from 'boos';

export const products = createBoos({ initialValue: { products: [] } })

// modifiers
export function addProduct(state, newProduct) {
  state.products.push(newProduct);
}

export function removeProduct(state, productToRemove) {
  state.products = state.products.filter(product => product.id !== productToRemove.id)
}

// Piece selectors
export function getExpensiveProducts(state) {
  return state.products.filter(product => product.price > 500)
}

Using it with React

In order to use a boos with React the library expose two hooks so far, useBoos and useBoosPiece

useBoos

Allow to acces to both boos current value and boos modifyValue function

import React from 'react';
import { useBoos } from 'boos';
import { products, removeProduct } from './productsBoos';

function YourComponent() {
  const [state, modifyValue] = useBoos(products)

  return (
    <ul>
      {state.products.map(product => (
        <li key={product.id} onClick={() => {
          modifyValue((state => removeProduct(state, product)))
        }}>
          {product.name}
        </li>
      ))}
    </ul>
  )
}

useBoosPiece

Sometimes is a good idea derived the state from an existing state instead of get the state bigger to hold those values, that's the main reason behind this hook this allows us to get a computed value from the boos as well as gives memoization and value check out the box in order to avoid unnecessary state updates alongside its respective rerenders.

import React from 'react';
import { useBoosPiece} from 'boos';
import { products, getExpensiveProducts } from './productsBoos';

function YourComponent() {
  const expensiveProducts = useBoosPiece(products, getExpensiveProducts);

  return (
    <ul>
      <h2>These are the expensive products</h2>
      {expensiveProducts.map(product => (
        <li key={product.id}>
          <strong>{product.name}: </strong>
          {product.price}
        </li>
      ))}
    </ul>
  )
}

Persistance

Sometimes it's necessary to persist state through user reloads or user sessions therefore boos expose an easy way to save a specific boos value in localStorage, sessionStorage and cookies are comming, this through persistance builders

import { createBoos, createLocalStoragePersistance, createSessionStoragePersistance } from 'boos';

const products = createBoos({
  initialValue: { products: [] },
  options: {
    persistanceBuilder: createLocalStoragePersistance('products') // or createSessionStoragePersistance('products')
  }
});

This will save products value in localStorage/sessionStorage and will refresh the value using the stored value

Logging

Logging it's very important in development for debugging purposes so to enable it the createBoos function offers it through its options

import { createBoos } from 'boos';

const products = createBoos({
  initialValue: { products: [] },
  options: {
    logger: {
      tag: 'products',
      active: true,
    },
  },
});

This will show on the console both last boos value and the new one just after the value was modified by modifyValue.

active property can be a function as well, this function will receive the boos current state so you can show the logs in function of your boos value

import { createBoos } from 'boos';

const products = createBoos({
  initialValue: { products: [] },
  options: {
    logger: {
      tag: 'products',
      active: (state) => state.products.length < 20,
    },
  },
});