Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kyza/nests
Fast and easy state storage with a lot of control.
https://github.com/kyza/nests
easy flux javascript nests redux state store
Last synced: 2 months ago
JSON representation
Fast and easy state storage with a lot of control.
- Host: GitHub
- URL: https://github.com/kyza/nests
- Owner: Kyza
- License: mit
- Created: 2021-07-03T04:13:43.000Z (over 3 years ago)
- Default Branch: v2
- Last Pushed: 2023-08-03T05:51:38.000Z (over 1 year ago)
- Last Synced: 2024-11-09T14:43:43.521Z (3 months ago)
- Topics: easy, flux, javascript, nests, redux, state, store
- Language: TypeScript
- Homepage:
- Size: 336 KB
- Stars: 13
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Nests
Fast and easy state storage with a lot of control.---
---
```js
import * as nests from "nests";
const nest = nests.make();nest.on(nests.Events.SET, (eventType, { path, value }) => {
console.log(`set: ${path} = ${value}`);
});nest.store.array = [1, 2, 3];
nest.store.array.push(4);
nest.store.instant.deeply.nested.state = true;/* Console Output */
// set: array = 1,2,3
// set: array,3 = 4
// set: array,length = 4
// set: instant,deeply,nested,state = true
```## Installation
```bash
npm i nests
```When importing you can specify `nests/esm` or `nests/mjs` if your bundler is giving you problems.
```js
import * as nests from "nests";
```## Links
- [GitHub](https://github.com/Kyza/nests)
- [NPM](https://www.npmjs.com/package/nests)
- [Bundlephobia](https://bundlephobia.com/package/nests@latest)## Features
- [Instant Deeply Nested Objects](#instant-deeply-nested-objects)
- [Automatic Events](#automatic-events)
- [Ghost](#ghost)
- [React](#react)
- [Solid](#solid)## Concepts
### Store
The store is an object that lets you store data in an instantly deeply nested structure which automatically emits events to subscribers for you.
#### Instant Deeply Nested Objects
Have you ever had to do something like this?
```js
const storage = {};if (!storage.hasOwnProperty("foo")) {
storage.foo = "bar";
}
```With Nests this isn't necessary anymore.
```js
const nest = nests.make();nest.store.foo = "bar";
```The code is even shorter and more readable.
You can go as deep as you want instantly without having to check if the property exists.
```js
nest.store.foo.bar.baz = "qux";
```Getting a property that doesn't exist will return `{}` instead of `undefined`. Use [ghost](#ghost) to check for non-existent properties correctly.
```js
nest.store.foo.bar.baz; // {}
```### Automatic Events
Nests comes with a small, custom, and fast, browser-ready EventEmitter.
```js
nest.on(nests.Events.SET, (eventType, { path, value }) => {
console.log(`set: ${path} = ${value}`);
});nest.store.array = [1, 2, 3];
nest.store.array.push(4);
nest.store.instant.deeply.nested.state = true;/* Console Output */
// set: array = 1,2,3
// set: array,3 = 4
// set: array,length = 4
// set: instant,deeply,nested,state = true
```### Ghost
The ghost is an object that is dual-synced with the store but isn't instantly deeply nested, doesn't emit events and is faster.
Each nest has a `ghost` property that can be used to modify the store's data without triggering events. This is super handy for doing heavy calculations with many mutations and creating transient React components easily.
The ghost of each nest is directly tied to the store so modifications to the ghost will be reflected in the store.
```js
nest.on(nests.Events.SET, (eventType, { path, value }) => {
console.log(`set: ${path} = ${value}`);
});nest.ghost.array = [1, 2, 3];
nest.ghost.array.push(4);nest.store.array.push(5);
console.log("The sync goes both ways:", nest.ghost.array);
/* Console Output */
// set: array,4 = 5
// set: array,length = 5
// The sync goes both ways: 1,2,3,4,5
```If you want to trigger an event manually without using the store, you can use any of these functions.
```js
// Use this.
nest.update();
// Using these is discouraged.
nest.get();
nest.set();
nest.delete();
```The downfall of ghost is that it doesn't support [Instant Deeply Nested Objects](#instant-deeply-nested-objects).
```js
nest.ghost.foo.bar.baz = "qux"; // Error!
```This is also a good thing. It allows you to check for non-existent properties unlike the store.
```js
if (!nest.ghost.foo?.bar?.baz) {
// ...
}
```## React
Here's an example of a React component.
```js
import * as nests from "nests";
import { useNest } from "nests/react";const settings = nests.make({
enabled: true,
name: "",
});export default function App() {
// Automatically subscribe to changes in the store.
useNest(settings);return (
<>
{
settings.store.enabled = !settings.store.enabled;
}}
>
{settings.ghost.enabled ? "Enabled" : "Disabled"}
{
settings.store.name = event.target.value;
}}
/>
>
);
}
```Here's an example of a transient React component.
```js
import * as nests from "nests";
import { useNest } from "nests/react";const counter = nests.make({
count: 0,
});setInterval(() => {
// Increment using the ghost to not update the component.
counter.ghost.count++;
}, 0);export default function App() {
// Automatically subscribe to changes in the store.
// Pass true to indicate that it's a transient component.
// Here we have a filter as well to only update the component when we want to.
// That lets us avoid updating the component when a property we don't care about is changed.
useNest(
counter,
true,
(event, type) => event === "UPDATE" && type === "counter"
);return (
<>
{counter.ghost.count}
{
// Whenever the button is clicked, cause an update on the store.
// You can pass data to the update function which passes it to the filter in the useNest above.
counter.update("counter");
}}
>
Update
>
);
}
```Notice that whenever any data is displayed the ghost is used to retrieve it. This is because the ghost is faster and doesn't emit events.
## Solid
Here's an example of a Solid component.
Notice the key difference between Solid and React's `useNest` hooks. While both hooks return the ghost, you're required to use the ghost the Solid hook returns in order for the component to update.
```js
import * as nests from "nests";
import { useNest } from "nests/solid-js";const settings = nests.make({
enabled: true,
name: "",
});export default function App() {
// Automatically subscribe to changes in the store.
const signalGhost = useNest(settings);return (
<>
{
settings.store.enabled = !settings.store.enabled;
}}
>
{signalGhost.enabled ? "Enabled" : "Disabled"}
{
settings.store.name = event.target.value;
}}
/>
>
);
}
```Here's an example of a transient Solid component.
```js
import * as nests from "nests";
import { useNest } from "nests/solid-js";const counter = nests.make({
count: 0,
});setInterval(() => {
// Increment using the ghost to not update the component.
counter.ghost.count++;
}, 0);export default function App() {
// Automatically subscribe to changes in the store.
// Pass true to indicate that it's a transient component.
// Here we have a filter as well to only update the component when we want to.
// That lets us avoid updating the component when a property we don't care about is changed.
const signalGhost = useNest(
counter,
true,
(event, type) => event === "UPDATE" && type === "counter"
);return (
<>
{signalGhost.count}
{
// Whenever the button is clicked, cause an update on the store.
// You can pass data to the update function which passes it to the filter in the useNest above.
counter.update("counter");
}}
>
Update
>
);
}
```Notice that whenever any data is displayed the ghost is used to retrieve it. This is because the ghost is faster and doesn't emit events.