Gathering detailed insights and metrics for usignal
Gathering detailed insights and metrics for usignal
Gathering detailed insights and metrics for usignal
Gathering detailed insights and metrics for usignal
signaldb-plugin-usignal
This is the [µsignal](https://github.com/WebReflection/usignal) plugin for [SignalDB](https://github.com/maxnowack/signaldb). SignalDB is a local JavaScript database with a MongoDB-like interface and TypeScript support, enabling optimistic UI with signal-
signal-struct
Cumulative signal structure
@signaldb/usignal
This is the [µsignal](https://github.com/WebReflection/usignal) plugin for [SignalDB](https://github.com/maxnowack/signaldb). SignalDB is a local-first JavaScript database with real-time sync, enabling optimistic UI with signal-based reactivity across mul
A blend of @preact/signals-core and solid-js basic reactivity API
npm install usignal
Typescript
Module System
Node Version
NPM Version
74.3
Supply Chain
98.9
Quality
79.7
Maintenance
100
Vulnerability
100
License
JavaScript (92.06%)
HTML (5.58%)
TypeScript (2.37%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
ISC License
252 Stars
232 Commits
15 Forks
10 Watchers
8 Branches
7 Contributors
Updated on Jul 09, 2025
Latest Version
0.10.0
Package Id
usignal@0.10.0
Unpacked Size
45.93 kB
Size
11.76 kB
File Count
32
NPM Version
11.3.0
Node Version
24.0.1
Published on
May 16, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Social Media Photo by Carlos Alberto Gómez Iñiguez on Unsplash
A blend of @preact/signals-core and solid-js basic reactivity API, with API and DX mostly identical to @preact/signals-core but extra goodness inspired by solid-js, 816 bytes minified with brotli.
1import {signal, computed, effect, batch, Signal} from 'usignal'; 2// const {signal, computed, effect, batch, Signal} = require('usignal'); 3 4signal(0) instanceof Signal; // true 5computed(() => {}) instanceof Signal; // true 6 7effect( 8 () => { console.log('fx') }, 9 void 0, // optional value to pass along the callback as initial/prev value 10 {async: true} // optionally make the effect async: false by default 11); 12 13// try every example shown in 14// https://github.com/preactjs/signals 15// or see test/index.js file to see it in action
This is a dual module so it works in either CommonJS or ECMAScript module systems.
usignal/sync
exports with an enforced sync effectusignal/async
exports with an enforced async effectusignal
in browsers exports usignal/async
and usignal/sync
in servers or by defaultusignal/core
just exports the effect as callback that accepts an effect and an optionally asynchronous true
flag, used by all other exports by default, but you decide if a specific effect should sync or async.usignal/core
, so that all effects are sync by default but can be async passing true
as second parameterCurrent exports are exactly these:
1import { 2 signal, 3 computed, 4 effect, 5 batch, 6 Signal 7} from 'usignal';
The Signal
export is useful only as brand check for either computed or signal references, but it cannot be used as constructor right away.
To allow developers to try and use different patterns there are a few variants of this module, still based on the very same core primitives:
usignal/fn
, with its */sync
and */async
variants, where signals are callbacks so that signal()
returns a its value, and signal(value)
updates its value and return the new one, inspired by S. Computeds do not update anything so computed()
returns values. This is a variant around the .value
accessor pattern I don't necessarily disike, specially when we'd like to signal that a signal is being observed: effect(() => { mySignal(); })
usignal/solid
, with its */sync
and */async
variants, where the module exports createEffect, createMemo, and createSignal, mimicking the behavior (and returned values) as solid-js basic reactivity API. This is handy to compare the two or drop-in usignal in solid-js already based code.the default comparison for equality is not based on ===
but on Object.is. This might be a tiny, hopefully irrelevant, performance penalty, but I feel like guarding NaN cases in reactivity is a step forward to avoid infinite loops out of NaN poisoning some computation. +0 and -0 are less interesting cases to tackle, still these might be fundamental in some case, hence preserved in this moudle.
this library has lazy, non side-effecting, computed values, something @preact/signals-core recently introduced and Solid 2.0 is planning to improve.
computed accepts an initial value otherwise passed as previous one by default, mimicking solid-js useMemo(fn[, value[, options]])
signature.
effect passes along its initial value or the previoulsy returned one. If this is a function though, it runs it before re-executing, passing along its returned value, if any.
both signal(value[, options])
and computed(fn[, value[, options]])
accept an optionally options argument, currently implementing equals as explained in solid-js documentation.
both signal and computed also have a toJSON
and a valueOf()
allowing to implicitly use their values, e.g.
1const one = signal(1); 2const two = signal(2); 3const three = computed(() => one + two); 4 5three.value; // 3 indeed!
The benchmark currently compares S, solid, preact/signals, and cellx against usignal.
Please note preact is currently not able to solve nested effects so its logic might be simpler than other libraries.
1npm run benchmark
This module is 100% code covered, including the WeakRef possible leaks which is tested through the test/leak.js file, which is part of the build script process.
To use other libraries as reference, I have also added preact/signals-core and solid-js dev-dependencies within the test folder.
Please note preact is currently not able to solve nested effects so its logic might be simpler than other libraries.
The following instructions are needed to test other libraries too:
1cd usignal 2npm i 3cd test 4npm i 5cd .. 6 7# normal tests 8npm test usignal # shows also code-coverage 9npm test solid 10npm test preact 11 12# leak test 13npm run leak usignal # calculate leaks via internals 14npm run leak solid 15npm run leak preact
This file is not meant at all as meaningful benchmark against other libraries, it's simply there to allow me to spot regressions on future updates of the library:
You create a following mixin function. Your class inherits from Mixin. Please see the demo for details.
1import { effect, signal } from 'usignal'; 2 3export function WithUsignal(Base){ 4 return class WithUsignal extends Base { 5 #disposeEffect 6 #reactivePropUpdate = signal(0); 7 8 disconnectedCallback() { 9 this.#disposeEffect?.(); 10 } 11 12 performUpdate() { 13 if (!this.isUpdatePending) { 14 return; 15 } 16 17 if (this.#disposeEffect) { 18 this.#reactivePropUpdate.value++; 19 return; 20 } 21 22 this.#disposeEffect = effect(() => { 23 this.isUpdatePending = true; 24 this.#reactivePropUpdate.value; 25 super.performUpdate(); 26 }); 27 } 28 }; 29}
No vulnerabilities found.
No security vulnerabilities found.