
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A lightweight reactive store library that provides a powerful reactivity system for managing state, compatible with any UI framework, including Solid.js, and Preact Signals.
This library provides a powerful reactivity system for creating stateful objects using signals, integrated seamlessly into JavaScript objects and arrays. This library does not depend on any specific reactive library and can be used by any UI framework to manage and react to changes in state effectively.
To use this library, you can install it using npm or yarn:
npm install ustor
yarn add ustor
This library can be integrated with solid-js, @preact/signals-core, ulive, usignal, oby, sinuous any other libarary you can think of for managing reactive signals.
First, import the store function and the api object. You need to initialize api with your preferred signal implementation.
import { store, api } from "./src";
import { createSignal } from "solid-js";
// import { signal } from '@preact/signals-core'; // 'usignal' 'ulive'
// Solid.js setup
api.signal = createSignal;
api.get = (v) => v[0]();
api.set = (signal, v) => signal[1](v);
api.is = (v) =>
(Array.isArray(v) &&
typeof v[0] === "function" &&
typeof v[1] === "function") ||
v[0]?.name?.includes("readSignal");
// @preact/signals-core, usignal or ulive setup
api.signal = signal;
api.get = (v) => v.value;
api.set = (signal, v) => (signal.value = v);
api.is = (v) => v?.peek;
store(values, proto)The store function creates a stateful object that automatically converts properties into reactive signals.
The function returns a reactive store object that maintains the structure of the original values while adding reactivity.
is(value)The is function checks if a given value is a reactive store instance.
Returns true if the value is a reactive store, otherwise false.
api.isThe api.is function checks if a given value is a signal.
Returns true if the value is a signal, otherwise false.
api.signalThe api.signal function is used to create a reactive signal.
Returns a signal that can be used to create reactive state within the store.
api.getThe api.get function retrieves the current value of a signal.
Returns the current value of the signal.
api.setThe api.set function updates the value of a signal.
Updates the signal with the provided value.
const s = store({ a: 1, b: 2 });
console.log(s.a); // 1
s.a = 5;
console.log(s.a); // 5
You can use the store function to create a reactive state object. Assigning a new value to s.a will automatically trigger updates wherever s.a is used.
const s = store({
a: 2,
b: 3,
get sum() {
return this.a + this.b;
},
});
console.log(s.sum); // 5
s.a = 5;
console.log(s.sum); // 8
Here, you can define getters that automatically compute derived state values, and these getters will update whenever the underlying signals change.
The store function can also handle deeply nested objects, converting nested properties into reactive signals:
const s = store({ nested: { deep: { value: 10 } } });
const deepValue = s.nested.deep.value * 2;
console.log(deepValue); // 20
s.nested.deep.value = 15;
console.log(s.nested.deep.value) * 2; // 30
This library can handle arrays and objects seamlessly, automatically wrapping array elements with reactivity:
const s = store({ list: [1, 2, 3] });
const sum = s.list.reduce((acc, item) => acc + item, 0);
console.log(sum); // 6
s.list = [1, 5, 3];
console.log(s.list.reduce((acc, item) => acc + item, 0)); // 9
The signal value trigger with effects to track dependencies and automatically re-run whenever dependencies change:
const s = store({ a: 1 });
let effectValue = 0;
effect(() => {
effectValue = s.a * 2;
});
console.log(effectValue); // 2
s.a = 4;
console.log(effectValue); // 8
state.$propThe $ properties are automatically generated for each property in the store. These $-prefixed properties contain the underlying signal, providing direct access to the signal itself, separate from the reactive value it holds. The $ properties are non-enumerable and are useful when you need to access or manipulate the signal directly, rather than the reactive value.
For example, if you have a store with a count property:
const s = store({ count: 0 });
console.log(s.count); // 0
console.log(s.$count); // The underlying signal object
This library can be used with Solid.js, Preact Signals, or any other UI framework to provide reactive signals.
To use Solid.js:
import { createSignal } from "solid-js";
api.signal = createSignal;
api.get = (v) => v?.[0]();
api.set = (signal, v) => signal?.[1](v);
api.is = (v) =>
(Array.isArray(v) &&
typeof v[0] === "function" &&
typeof v[1] === "function") ||
v?.[0]?.name?.includes("readSignal");
To use Preact Signals, usignal, ulive, etc:
import { signal } from "@preact/signals-core";
api.signal = signal;
api.get = (v) => v?.value;
api.set = (signal, v) => (signal.value = v);
api.is = (v) => v?.peek;
To use any signal library
import ... from "...";
api.signal = ...;
api.get = ...;
api.set = (signal, value) => ...;
api.is = (v) => ...;
const state = store({
count: 0
});
The library provides a unified API to work with different reactive systems, allowing you to switch between Solid.js, Preact Signals, or any other UI framework easily.
This library is provided "as-is" under the MIT license. Feel free to use, modify, and distribute it in your projects.
FAQs
A lightweight reactive store library that provides a powerful reactivity system for managing state, compatible with any UI framework, including Solid.js, and Preact Signals.
We found that ustor demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.