Skip to content

Seamlessly share state between different parts of a Podium application using reactive state

License

Notifications You must be signed in to change notification settings

podium-lib/store

Repository files navigation

@podium/store

This is a client-side library that provides a reactive data store using nanostores on top of @podium/browser's MessageBus. It includes some ready-made stores and helpers for you to make reactive stores for your own events.

By using reactive state backed by MessageBus you can seamlessly share state between different parts of a Podium application. If a podlet changes the value of shared state, all other podlets using that value can update.

Usage

To install:

npm install @podium/store

Use an included store in your client-side application:

// store/user.js
import { $authentication } from '@podium/store';
import { computed } from 'nanostores';

// You can optionally make a computed value based on the included store
export const $loggedIn = computed($authentication, (authentication) =>
    Boolean(authentication.token),
);

// Colocating actions with the store makes it easier to
// see what can trigger updates.
export function logIn(token) {
    $authentication.set({ token });
}

export function logOut() {
    $authentication.set({ token: null });
}

Use the reactive store to do minimal updates of your UI when state changes. Nanostores supports multiple view frameworks:

This example shows a React component:

// components/user.jsx
import { useStore } from '@nanostores/react';
import { $loggedIn } from '../stores/user.js';

export const User = () => {
    const loggedIn = useStore($loggedIn);
    return <p>{loggedIn ? 'Welcome!' : 'Please log in'}</p>;
};

This is the same component in Lit:

// components/user.js
import { StoreController } from '@nanostores/lit';
import { $loggedIn } from '../stores/user.js';

class User extends LitElement {
    loggedInController = new StoreController(this, $loggedIn);

    render() {
        return html`<p>
            ${this.loggedInController.value ? 'Welcome!' : 'Please log in'}
        </p>`;
    }
}

customElements.define('a-user', User);

Create your own reactive state

By using the included helper you can make your reactive state sync between the different parts of a Podium application.

API

$authentication

Type: map

import { $authentication } from '@podium/store';

atom(channel, topic, initialValue)

Create your own atom that syncs between parts of a Podium application using the MessageBus.

This method requires the following arguments:

option type details
channel string Name of the channel
topic string Name of the topic
payload object The initial value. Replaced if peek(channel, topic) returns a value.
import { atom } from '@podium/store';

const $reminders = atom('reminders', 'list', []);

map(channel, topic, initialValue)

Create your own map that syncs between parts of a Podium application using the MessageBus.

This method requires the following arguments:

option type details
channel string Name of the channel
topic string Name of the topic
payload object The initial value. Replaced if peek(channel, topic) returns a value.
import { map } from '@podium/store';

const $user = map('user', 'profile', { displayName: 'foobar' });

deepMap(channel, topic, initialValue)

Create your own deepMap that syncs between parts of a Podium application using the MessageBus.

This method requires the following arguments:

option type details
channel string Name of the channel
topic string Name of the topic
payload object The initial value. Replaced if peek(channel, topic) returns a value.
import { deepMap, listenKeys } from '@podium/store';

export const $profile = deepMap({
    hobbies: [
        {
            name: 'woodworking',
            friends: [{ id: 123, name: 'Ron Swanson' }],
        },
    ],
    skills: [['Carpentry', 'Sanding'], ['Varnishing']],
});

listenKeys($profile, ['hobbies[0].friends[0].name', 'skills[0][0]']);

About

Seamlessly share state between different parts of a Podium application using reactive state

Resources

License

Stars

Watchers

Forks

Packages

No packages published