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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gluonjs/reactivity

v1.1.0

Published

DOM-free reactive state primitives for Gluon.

Readme

DOM-free reactive state primitives for Gluon. The package is part of the lockstep Gluon 1.1.0 release line.

import { computed, effect, nextTick, reactive, ref } from '@gluonjs/reactivity';

const count = ref(1);
const state = reactive({ multiplier: 2 });
const total = computed(() => count.value * state.multiplier);

effect(() => {
  console.log(total.value);
}, { flush: 'pre' });

count.value = 2;
await nextTick();

API

  • ref, shallowRef, isRef, and unref
  • reactive, shallowReactive, readonly, and shallowReadonly
  • isReactive, isReadonly, isProxy, and toRaw
  • effect, stop, lazy activation, scheduling hooks, and development-only onTrack/onTrigger callbacks
  • lazy, cached readonly and writable computed values
  • batch, untracked, phased queue helpers, and nextTick
  • attached or detached effectScope ownership and onScopeDispose
  • scheduled watch and watchEffect with deterministic cleanup
  • global, scope-local, job-local, and effect-local error handlers

Optional external Signals

The @gluonjs/reactivity/signals subpath bridges TC39 proposal Signals from [email protected]. The independent @gluonjs/reactivity/preact-signals subpath supports @preact/signals-core >=1.14.4 <2. Neither optional peer is imported by the stable Reactivity entry.

Both adapters read the external graph directly, coalesce scheduled notifications, expose explicit connect()/disconnect() ownership, and remain disconnected for SSR unless the application opts in. See the interoperability contract and the runnable examples/signals application.

Deep reactive proxies support plain objects, arrays, Map, and Set. The package source compiles with the ES2022 library and no DOM or Node ambient types.

Scheduler contract

Queued work is deduplicated by function within its phase. A flush runs pre, update, and post phases in that order. Within a phase, smaller numeric IDs run before larger IDs so parent owners can precede children; equal or omitted IDs retain insertion order. Work queued for a phase that already completed runs in the next cycle of the same flush. nextTick() resolves only after every cycle, including post-flush work, is complete. A queued job may return a promise; the current phase waits for it and routes rejection through the same error channel. Synchronous jobs in one phase run back-to-back without an inserted microtask; an actual promise pauses later jobs until it settles.

Effects are synchronous by default. flush: 'pre', flush: 'update', and flush: 'post' opt into the matching shared microtask phase. lazy: true returns a runner without executing it; onSchedule runs synchronously before an invalidated effect enters its selected phase. batch() deduplicates synchronous invalidations until the outermost synchronous batch returns; it does not extend across an await boundary.

An attached scope stops its owned effects in reverse creation order, then child scopes in reverse creation order, then cleanup callbacks in reverse registration order. A detached scope has independent ownership. Stopping a scope cancels its queued effects and watchers and prevents their runners from executing again. If an effect stop hook throws, the scope reports a cleanup error and continues stopping the remaining effects and resources.

Errors are delivered to the closest explicit effect, watcher, job, or scope handler. When no local handler exists, the handler installed by setReactivityErrorHandler receives them. The default channel uses platform reportError when present and otherwise console.error. Handler failures are contained by the default channel so scheduler flushes and nextTick do not become unhandled promise rejections.

License

MIT — Copyright © 2026 Marc Malerei.