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
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";
}
// Best practice!
if (!"key" in nest.some.new) {
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
If you want to get the most performance out of arrays in nests as possible, use the fastArrays option.
When you're using arrays that are greater in size than ~500 items use 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.
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;
}}
/>
</>
);
}