arrow-left

All pages
gitbookPowered by GitBook
1 of 2

Loading...

Loading...

@atomico/store

@atomico/store a more predictable and natural model for asynchrony when controlling states.

hashtag
@atomico/store is Naturally asynchronous.

hashtag
Objectives

  1. Asynchrony management.

  2. Finitely predictable asynchrony.

  3. Modularity and composition.

hashtag
Asynchrony management

Application events and service calls are naturally asynchronous, with @atomico/store you can use asynchronous functions or asynchronous generators to define the update cycle.

update cycle? By this I mean the states that occur sequentially when dispatching the action, example:

The previous action will generate 2 states when dispatched:

  1. state 1:{loading: true, products:[]}

  2. state 2: {loading: false, products:[...product]}

The advantage of this is that the process is clearly observable by the store and by whoever dispatches the action.

hashtag
Finitely predictable asynchrony

Every action in @atomico/store is wrapped in a promise that defines when it ends its cycle, this will let you execute actions sequentially, example:

hashtag
Modularity and composition

@atomico/store allows to decouple the actions and the state of the store, for a better modularization , example:

hashtag
API

interface State {
  api: string;
  loading: boolean;
  products: { id: number; title: string; price: number };
}

const initialState = (state: State) => ({
  api: "",
  loading: false,
  products: [],
});

async function* getProducts(state: State) {
  yield { ...state, loading: true };
  return {
    ...(yield),
    loading: false,
    products: await (await fetch(state.api)).json(),
  };
}

const store = new Store(initialState, {
  actions: { getProducts },
});
Storechevron-right
async function* getProducts(state: State) {
  yield { ...state, loading: true };
  return {
    ...(yield),
    loading: false,
    products: await (await fetch(state.api)).json(),
  };
}
await store.actions.orderyBy();
await store.actions.insert({ id: 1000 });
await store.actions.updateAll();
export interface State {
  api: string;
  loading: boolean;
  products: { id: number; title: string; price: number };
}

export const initialState = (state: State) => ({
  api: "",
  loading: false,
  products: [],
});

export async function* getProducts(state: State) {
  yield { ...state, loading: true };
  return {
    ...(yield),
    loading: false,
    products: await (await fetch(state.api)).json(),
  };
}
import * as Actions from "./actions";

export default new Store(Actions.initialStore, { actions: { Actions } });
GitHub - atomicojs/storeGitHubchevron-right

Store

It is a minimalist solution for synchronizing the state of applications or component systems that require controlled bidirectional data management.

hashtag
Getting Started

Stores in Atomico are web components with behavior similar to the Atomico context API, for example:

hashtag
Creating the store

hashtag
Defining the store

hashtag
Consuming the store

hashtag
Bidirectional State Management?

If you're familiar with the Atomico context API, you'll know it's unidirectional, meaning the parent dispatches updates to the child. @atomico/store is bidirectional, allowing any store consumer to synchronize. This means the parent can dispatch updates to the child, and the child can dispatch updates to the parent.

import { createContext } from "@atomico/store";

const MyStore = createContext({ counter: 0 });

customElements.define("my-store", MyStore);
import { c } from "atomico";
import { MyStore } from "./my-store";

export const MyApp = c(() => {
  return (
    <host>
      <MyStore state={{ counter: 0 }}>
        <slot />
      </MyStore>
    </host>
  );
});
import { c } from "atomico";
import { useStore } from "@atomico/store";
import { MyStore } from "./my-store";

export const MyApp = c(() => {
  const store = useStore(MyStore);
  return (
    <host>
      <button onclick={() => store.counter++}>
        Increment: {store.counter}
      </button>
    </host>
  );
});
Logo