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

witting

v1.3.0

Published

A minimal single-file library for state management.

Downloads

1

Readme

Witting

v1.1.0

Witting is a minimal single-file library for state management.


Installation

> npm i witting

Usage

witting provides the following interfaces:


First, import witting:

import * as witting from "witting";
import { functionInDemand } from "witting";

var witting = require("witting");

Creates a state and gets the core value:

const stuff: State<string> = createState("anything");
// or const stuff = State("anything");

console.log(stuff.get());
> "anything"

Sets the core value:

stuff.set("something");
console.log(stuff.get());
> "something"

Attends and prepare to react before and to changes:

const { neglect } = stuff.attend(
    (state) => {
        console.log("after a change.");
    },
    (becoming, current) => {
        console.log("before a change.");
    }
);
stuff.set("everything");
> "before a change."
> "after a change."

The callbacks will not be invoked if set the same value:

stuff.set("everything");
> [nothing gets printed]

The callbacks will also not be invoked after being neglected:

neglect();
stuff.set("nothing");
> [nothing gets printed]

Creates a state register:

const { addState, getState, delState } = openStateRegister();

Registers values "mona" and "lisa" as States with keys "person1" and "person2". The second argument can be either the value or a state with the value itself:

addState("person1", createState("Mona"));
addState("person2", "Lisa").attend((state) => console.log("My name is now " + state));

Retrieves the state of key "person2" and set a value to it:

getState("person2").set("Belle");
> "My name is now Belle"

Removes the state of key "person2":

delState("person2");
console.log(getState("person2"));
> undefined

Creates multiple states from an array of values and stores them in an internal state register. getState() is exposed so that the states can be accessed:

const { getState } = createStates(["foo", "bar", "chocolate"]);

To retrieve them, strings of their indices are passed to getState():

getState("1").set("fool");

The argument can also be a linear object other than an array. With this, custom keys can be associated with the states:

const { getState } = createStates({
    rigel: 8.005,
    sirius: 230,
    ross: 5000,
});

Suppose we have a template element:

<template id="traffic-light">
    <div class="traffic-light wrapper" data-color="red">
        <span class="message">stop</span>
    </div>
    <style>
        .traffic-light.wrapper[data-color = "red"] {
            background-color: red;
        }
        .traffic-light.wrapper[data-color = "yellow"] {
            background-color: yellow;
        }
        .traffic-light.wrapper[data-color = "green"] {
            background-color: greend;
        }
    <style>
</template>

Binds Witting state with respective objects, by exposing a setState() onto the object:

function TrafficLightComponent(): HTMLElement & Witting {
    const template = document.getElementByID("traffic-light") as HTMLTemplateElement;
    const component = template.content.cloneNode(true) as HTMLElement;

    const wrapper = component.querySelector(".wrapper") as HTMLElement;
    const message = component.querySelector(".message") as HTMLElement;

    const { privateGetter: getState } = createStates({
        text: "stop",
    });
    privateGetter("text").attend((state) => {
        message.textContent = state;
    });

    const { publicGetter: getState } = createStates({
        color: "red",
    });
    publicGetter("color").attend((state) => {
        const text = privateGetter("text");
        switch(state) {
            case "red": text.setState("stop"); break;
            case "yellow": text.setState("wait"); break;
            case "green": text.setState("go"); break;
            default: break;
        };
        wrapper.setAttribute("data-color", state);
    });

    // inducing `Witting` on `component`
    induceWitting(component, publicGetter);
    return component as HTMLElement & Witting;
}

The above code is a rough implementation of a TrafficLightComponent which changes color and associated messages.

TrafficLightComponent possess 2 states: the private text and public color. text's value depends upon color's value and gets displayed as textContent of the component.

color may be mutated outside of the component such as in a handler of "click" event. But color itself shouldn't be exposed to the outside.

By inducing Witting on TrafficLightComponent and exposing a setState() on the component directly, color can now be mutated from the outside without the need to appear explicitly on the outside.

const trafficLight = TrafficLightComponent();
const changeButton = document.createElement("button");

let pressCount = 0;
changeButton.addEventListener("click", () => {
    pressCount += 1;
    pressCount %= 3;

    switch(pressCount) {
        case 0: trafficLight.setState("red"); break;
        case 1: trafficLight.setState("yellow"); break;
        case 2: trafficLight.setState("green");
    };
});

document.append(trafficLight, changeButton);

Every time changeButton gets clicked, the color of wrapper will change circling through "red", "yellow" and "green" and the text will change accordingly.

induceWitting() attaches two methods to the objects that gets induced Witting: isWitting() which always return true and setState() which allows mutating the internal public state owned by the object.


Checks if the argument is Witting or not:

console.log(isWitting(trafficLight));
console.log(isWitting(2));
> true
> false

Note: being Witting is owning some internal states and exposing a method for mutating them along with a method which tells the object is Witting. The condition is achieved by calling and passing the object to induceWitting().


License

The core files of the library are covered by MIT license.

All rights reserved. © 2023 Sai Aung Kyaw Htet

Dev-dependencies are covered by respective licenses and all the credits and copyrights go to respective authors.