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.
GitHub
Bundlephobia
NPM
import { Nest, NestEvents } from "nests";
const { store, emitter } = new Nest();
emitter.on({
event: NestEvents.AFTER_SET,
id: "AFTER_SET_EXAMPLE",
listener: (path, value) => {
console.log(`after-set: ${path} = ${value}`);
},
});
store.array = [1, 2, 3];
store.array.push(4);
/* Console Output */
// after-set: array = 1,2,3
// after-set: array,3 = 4
// after-set: array,length = 4Concepts
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.
How can I think of this data structure?
Think of nests as a normal object, but instead of non-existant keys being undefined you get {}, an empty object. Every key already exists.
Instant Deeply Nested Objects
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(store.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:
store = { this: { is: { a: { nest: { with: { a: { key: "value" } } } } } } };Into this clean implementation:
store.this.is.a.nest.with.a.key = "value";There's a trap, however! Since nothing on the store will ever return undefined your logic can suffer!
// Does not work!
if (!store.some.new.key) {
store.some.new.key = "value";
}
// Works!
if (!Object.keys(store.some.new.key).length) {
store.some.new.key = "value";
}
// Lodash.
if (_.isEmpty(store.some.new.key)) {
store.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 ~10ms to use unshift on a normal array with 1,000,000 items, while it takes almost ~750ms to use unshift the same array in a nest.
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 ([...store.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 brings arrays back to around the speed of JavaScript's native array methods.
However, there's a price. The emitter will no longer emit events when you push or splice items. This means you will have to assign to the array directly to get events to emit.
const { store, emitter } = new Nest({ fastArrays: true });Events
Nests uses the EventEmitter from NodeJS to dispatch events.
const { store, emitter } = new Nest();
// You can also use `emitter.once` to only listen for the next event.
emitter.on({
event: NestEvents.AFTER_SET,
id: "SETTINGS",
listener: (path, value) => {
// `someSetting` was enabled!
console.log(`${path} = ${value}`); // someSetting,enabled = true
},
});
store.someSetting.enabled = true;before-get
This is called before a value is retrieved.
after-get
This is called after a value is retrieved.
before-set
This is called before a value is set.
after-set
This is called after a value is set.
before-del
This is called before a value is deleted.
after-del
This is called after a value is deleted.