Package Exports
- nests
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (nests) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Nests
Easy state storage with a lot of control.
import { Nest, NestEvents } from "nests";
const { nest, emitter } = new Nest();
emitter.on(NestEvents.SET, ({ nest, path, value }) => {
console.log(`set: ${path} = ${value}`);
});
nest.array = [1, 2, 3];
nest.array.push(4);
/* Console Output */
// set: array = 1,2,3
// set: array,3 = 4
// set: array,length = 4Installation
npm i nestsLinks
Features
Concepts
First of all, if you are looking for super speedy ways to store data, this is not the library for you. However, if you can deal with slightly slower response times in trade for a much easier API, this is the library for you.
Instant Deeply Nested Objects
Think of nests as a normal object, but instead of non-existant keys being undefined you get {}, an empty object. Every key already exists.
Every key already exists? Well, that's not really true, but it's close. In order to provide an easier way to store data, any key you access will return an empty object if it doesn't exist. Keep in mind that just accessing a non-existent key for example someFunction(nest.some.new.key) won't create the empty data on the object.
So what does that even mean? This means that you can instantly set a deeply nested value without having to create the entire path manually.
Nests turns this mess:
nest = { this: { is: { a: { nest: { with: { a: { key: "value" } } } } } } };Into this clean implementation:
nest.this.is.a.nest.with.a.key = "value";There's a trap, however! Since nothing on the nest will ever return undefined your logic can suffer!
// Does not work!
if (!nest.some.new.key) {
nest.some.new.key = "value";
}
// Works!
if (!Object.keys(nest.some.new.key).length) {
nest.some.new.key = "value";
}
// Best practice!
// Returns false for only {}.
if (!Nest.has(nest.some.new.key)) {
nest.some.new.key = "value";
}References
Always remember references. If you set an object from the nest to an outside variable, that variable will become a reference to the nest and continue to trigger events. Use a deep copy function to copy the object if you want to detatch it from the nest.
Arrays
Please please please be careful when using arrays in your nests. They can be many times slower than normal which is devestating for performance on large arrays with ~100,000 items.
On my machine it takes ~13ms to use unshift on a normal array with 1,000,000 items, while it takes ~625ms to use unshift the same array in a nest.
But don't run away just yet!
If possible, try to use objects instead of arrays. If you absolutely need to use a large array in your nest, create a nest with the fastArrays option.
Remember references again! When transferring data from a nest to a normal array, remember to use a deep copy function (or the spread operator ([...nest.array]) if array items aren't objects) to get a normal array that isn't attached to the nest.
The fastArrays Option
If you are using a large array in your nest, you can use the fastArrays option to make it faster. This drastically speeds arrays back up.
Using fastArrays boosts the speed from the large array example above to around the same as normal arrays.
However, there's a price. The emitter will no longer emit events from inside arrays. This means you will have to run nest.array = nest.array after modifying the array.
const { nest, emitter } = new Nest({ fastArrays: true });
// Emits!
nest.array = [];
// Doesn't emit.
nest.array.push(1);
// Doesn't emit.
nest.array[1] = 2;
// Emits!
nest.array = nest.array;There is another benefit, however. You no longer need to deep copy the array to detatch it from the nest since it was never attached in the first place.
NestEvents and EventEmitter
Nests uses its own, fast, EventEmitter fit for browsers and a NodeJS environment.
const { nest, emitter } = new Nest();
// You can also use `emitter.once` to only listen for the next event.
emitter.on(NestEvents.SET, ({ nest, path, value }) => {
// `someSetting` was enabled!
console.log(`${path} = ${value}`); // someSetting,enabled = true
});
nest.someSetting.enabled = true;GET
This is called after a value is retrieved.
SET
This is called after a value is set.
DEL
This is called after a value is deleted.
useNest
Nest comes with a handy hook to connect it to a React component.
import { Nest, useNest } from "nests";
const settingsNest = new Nest({
data: {
enabled: true,
name: "",
},
});
const { nest: settings } = settingsNest;
export default function App() {
useNest({
...settingsNest,
// This is run for every emit and makes the hook only update the state if it returns true.
// It's optional, but the default always returns true.
filter: ({ nest, path, value }) => true,
});
return (
<>
<button
onClick={() => {
settings.enabled = !settings.enabled;
}}
>
{settings.enabled ? "Enabled" : "Disabled"}
</button>
<input
type="text"
value={settings.name}
onInput={(event) => {
settings.name = event.target.value;
}}
/>
</>
);
}