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 🙏

© 2025 – Pkg Stats / Ryan Hefner

anod

v0.2.0

Published

anod is a reactive library based on [S.js](https://github.com/adamhaile/S) and [SArray](https://github.com/adamhaile/S-array), but with several changes inspired by [Solid](https://github.com/solidjs/solid), [ivi](https://github.com/localvoid/ivi) and [Sig

Downloads

11

Readme

anod

anod is a reactive library based on S.js and SArray, but with several changes inspired by Solid, ivi and Signals by PreactJS. It provides lightweight wrapper objects that turn regular values and arrays into reactive objects.

Example

import { value, batch, effect } from "anod";
import { array } from "anod/array";

function Member(age, name) {
    this.age = age;
    this.name = name;
}

const members = array([
    new Member(21, "Leif"),
    new Member(35, "Siv"),
    new Member(48, "Sonja")
]);

const eventPlanned = value(false);

const childExists = members.some(member => member.age < 18);
const memberNames = members.map(member => member.name).join(", ");

effect(() => {
    const childText = childExists.val() ? " (has children)" : "";
    const eventText = eventPlanned.val() ? " Event planned, stay tuned!" : "";
    console.log(`Member list${childText}: ${memberNames.val()}.${eventText}`);
});
// Prints "Member list: Leif, Siv, Sonja."

members.push(new Member(15, "Lars"));
// Prints "Member list (has children): Leif, Siv, Sonja, Lars."

members.unshift(new Member(28, "Astrid"));
// Prints "Member list (has children): Astrid, Leif, Siv, Sonja, Lars."

batch(function() {
    members.pop();
    eventPlanned.set(true);
});
// Prints "Member list: Astrid, Leif, Siv, Sonja. Event planned, stay tuned!"

API

root(fn: () => T): DisposableSignal

Creates a root wrapper allowing to dispose any children computations created.

import { root, value, effec } from "anod";
const r1 = root(function() {
    const v1 = value(1);
    effect(function() {
        console.log(v1.val());
    });
});
v1.set(2); // prints 2
r1.dispose();
v1.set(3); // nothing happens, effect is disposed

data<T>(val: T): Signal<T> / value<T>(val: T, eq?: ((a: T, b: T) => boolean) | null): Signal<T>

The basic data types are data and value. data changes whenever set is called, whereas value only updates when set to a different value.

import { value, data, effect } from "anod";
const v1 = value(true);
const d1 = data(true);
effect(function() {
    if (v1.val()) {
        console.log("v1");
    }
    if (d1.val()) {
        console.log("d1");
    }
});
v1.set(true); // nothing happens
v1.set(false); // runs effect
d1.set(true); // runs effect

Both data and value expose peek, which allows reading the value without registering a dependency when called inside a computation or effect.

compute<T>(fn: () => T, opts?: SignalOptions<T> | boolean): ReadonlySignal<T>

compute allows for creating derived signals. The main purpose is to avoid unnecessary re-calculations.

import { value, compute, effect } from "anod";
const $age = value(0);
const $stage = compute(function() {
    const age = $age.val();
    return age < 10 ? "child" : age < 18 ? "teenager" : "adult";
});
effect(function() {
    console.log($stage.val());
});
$age.set(5); // will not trigger effect
$age.set(14); // will trigger, value changed from child to teenager

compute is lazy, and only runs when any other compute or effect tracks its value.

effect(fn: () => void, opts?: SignalOptions<void> | boolean ): DisposableSignal

effect is for creating any functionality derived from signals. It runs upon creation, and whenever any of its dependencies trigger a change.

batch(fn: () => void): void

batch applies all changes before updating computes and effects.

sample<T>(fn: () => T): T

sample works like peek, but takes a callback, and does not register any dependency within it.

cleanup(fn: (final: boolean) => void): void

Registers a cleanup function that runs whenever a compute/effect updates. When final parameter is true, the caller is being disposed.

array<T = any>(val?: T[]): SignalArray<T>

array creates a reactive array object that shims native functions. Mutating functions (push, pop, shift etc) behave like calling set for data. It also exposes several derivations of compute, for non-mutating methods.

ComputeReduce and ComputeArray both derive from the core Compute class. ComputeReduce exposes a compute value for methods like reduce, every, some etc. ComputeArray inherits from the abstract base class ReactiveIterator that is shared with array. This is for methods that return an array, such as map and filter.

import { effect } from "anod";
import { array } from "anod/array";
const a1 = array([1,2,3]);
const sum = a1.filter(v => v < 3).map(v => v * 2).reduce((acc, val) => acc + val);
effect(function() {
    console.log(sum.val()); // prints 6
});
a1.unshift(1, 2, 3); // prints 12
a1.push(4, 5, 6); // does not trigger, value has not changed