0.0.7 • Published 5 years ago

mobx-stored-observable v0.0.7

Weekly downloads
1
License
MIT
Repository
-
Last release
5 years ago

Mobx-stored-observable

Build Status NPM Version Size

Mobx Observables that are persisted in web storage (local or session storage).

Observables persisted in localStorage are synced between different browser tabs using storage events.

Why? Examples

  • Persist state between tabs (uses localStorage & storage events)
  • Make state survive page refresh

How

Example of Mobx store for session data.

It persists session state to localStorage, so browser tabs can share it.

import { storedObservable } from 'mobx-stored-observable';

interface StoredObservableOptions<T> {
  key: string; // key in local/sessionStorage
  initialValue?: T; // initial value
  debounce?: number; // how often is data saved to storage
  storageType?: 'localStorage' | 'sessionStorage';
  // provide if you want to handle storage update events by yourself.
  // if given, observable state is not automatically updated based on storage events 
  handleUpdateFromStorage?: (newValue: T, observable: T & IObservableObject) => void;
}

class SessionStore {

  private readonly _sessionData: SessionData;
  private readonly loadInitialValue: () => void;
  private readonly disposer: () => void;
  private readonly sessionService = new SessionService();

  constructor() {
    super();
    const initialValue: SessionData = {
      name: null,
      userId: null,
      username: null,
    };
    const storedObservableOptions: StoredObservableOptions<SessionData = { 
      initialValue, key: 'session', storageType: 'localStorage'
   };
    const { value, loadInitialValue, disposer } = storedObservable<SessionData>(
        { initialValue, key: 'session', storageType: 'localStorage'},
    );
    this._sessionData = observableValue;
    this.loadInitialValue = loadInitialValue;
    this.resolveSessionData = this.resolveSessionData.bind(this);
    this.logout = this.logout.bind(this);
    this.disposer = disposer;
  }

  public async resolveSessionStatus(): Promise<SessionData> {
    // read persisted data from storage (when app starts) if needed
    this.loadInitialValue();
    // read session from server when app starts
    const newSessionData = await this.authenticationService.getSessionData();
    this.setSessionData(newSessionData);
    return this.sessionData;
  }

  @action.bound
  private setSessionData(newData: SessionData): void {
    Object.assign(this._sessionData, newData);
  }

  public async logout(): Promise<void> {
    await sessionService.logout();
    // clear local userinfo state. Other browser tabs will logout user too. 
    this.setSessionData({ name: null, userId: null, username: null });

    // stop persiting changes to localstorage and stop listening localStorage changes
    this.disposer();
  }
  

  @computed
  public get sessionData(): SessionData {
    return this._sessionData;
  }

React

import { runInAction } from 'mobx';
import { useObserver } from 'mobx-react-lite';
import { usePersistedStore } from 'mobx-stored-observable/react';

const TodoComponent: React.FunctionComponent<{ storageKey: string }> = ({ storageKey }) => {
  const todo = usePersistedStore({
    key: storageKey,
    debounce: 1,
    getInitialValue: () => ({
      title: 'Click to toggle',
      done: false,
      toggle(): void {
        runInAction(() => {
          this.done = this.done !== true;
        });
      },
      get isDone(): string {
        return this.done ? 'YES' : 'NO';
      },
    }),
  });
  return useObserver(() => (
    <div>
      <h3 onClick={todo.toggle}>
        {todo.title}
      </h3>
      <p>Toggled: {todo.isDone}</p>
    </div>
  ));
};

Compatibility

Should work in modern browsers. LocalStorage might be disabled/unusable in private browsing modes in certain browsers.

If web storage is not usable, observables returned by this library work normally, just without local storage.

NOTE: this library uses JSON.stringify and JSON.parse to persist data to web storage, so any objects you use, should work with those.

0.0.7

5 years ago

0.0.6

5 years ago

0.0.5

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago