SyncState

SyncState

  • Docs
  • FAQ
  • Github
  • Hire The Creators

›API Reference

Introduction

  • Getting started
  • Installation
  • Motivation
  • Core Concepts

Recipes

  • Recipes

Examples

  • Counter
  • Counter with Undo / Redo
  • Todo app
  • Multi User Counter
  • Multi User Todo
  • Multi User Todo With Undo/Redo

Plugins

  • History
  • Remote

API Reference

  • API Overview
  • createDocStore
  • Store
  • Provider
  • useDoc
  • useSyncState

Tips & Tricks

  • Common Pitfalls & Best Practices
  • Using SyncState without React
  • Performance Tuning

FAQ

  • FAQ's

Store

Store methods:

  • useDoc
  • getState
  • getStateAtPath
  • observe
  • intercept
  • dispatch
  • subscribe
  • useSyncState

The store also has a property called reduxStore which contains the Redux store used internally by SyncState. It might be useful for some advanced use cases.

useDoc

Gives you the state at path and a function to mutate or replace that state

Arguments

  1. path (string?, default: ""): The path to state that you want to fetch

Returns

(Array): An array with the following elements in order

  1. State at path

  2. Setter for state with the following signature

    setDoc

    Arguments

    1. callbackOrNewValue (Function | any): If you want to replace state at path, pass the newValue here or if you want to update some value inside the object or array at path, pass a callback function which receives the state at path to be updated.

    Returns

    (void)

  3. A dispatch function for you to dispatch any action to the internal Redux store.

Example

const [todos, setTodos] = store.useDoc("/todos");

setTodos([{ caption: "Hello", done: false }]); // replaces todos array
// OR
setTodos((todos) => todos.push({ caption: "Hello", done: false })); // pushes a new element to todos array

getPatches

Returns all the patches that have been applied to the document.

Arguments

*None*

Returns

(Array): Array of {patch, inversePatch}

Example

const store = createDocStore({ counter: 0 });

const [doc, setDoc] = store.useDoc();

setDoc((doc) => doc.counter++);

console.log(store.getPatches());
// [
//  {
//      patch: {
//          op: "replace",
//          path: "/counter",
//          value: 1
//      },
//      inversePatch: {
//          op: "replace",
//          path: "/counter",
//          value: 0
//      }
//  },
// ]

getState

Returns the document (root state)

Arguments

*None*

Returns

(any): document (root state)

Example

const store = createDocStore({ todos: [], filter: "all" });

console.log(store.getState());
//   { todos: [], filter: 'all' }

getStateAtPath

Returns the state at path

Arguments

  1. path (string?, default: ""): The path to state that you want to fetch

Returns

(any): State at path

Example

const store = createDocStore({ todos: [], filter: "all" });

console.log(store.getStateAtPath("/filter"));
//  'all'

observe

Observes changes at path and calls the listener function with the new changes/JSON patches

Arguments

  1. path (string): The path to state that you want to observe

  2. listener (Function): listener which receives state at path and patches generated to update the document.

  3. depth (number?, default: 1): The patches which are generated internally have a path property associated. This argument defines till what depth below path you should observe the changes.

    For example,

    0 means that the listener will run only if state at path is being replaced.

    1 means that only the changes made to object/array at path will trigger the listener.

    Infinity means that the listener will run for any level of changes inside path

    For more explanation, refer this.

Returns

(dispose): Dispose function, which you can call to stop observing

Example

store.observe(
    "/todos",
    (todos, change) => {
        console.log("todos has been updated");
        console.log("Updated todos: ", todos);
        console.log("Patch generated: ", change.patch);
    },
    1 // depth to observe
);

intercept

Intercepts changes at path and calls the listener function with the new changes/JSON patches where you can modify of stop the changes.

Arguments

  1. path (string): The path to state that you want to observe
  2. listener (Function): listener which receives previous state at path and patches generated to update the document. You can return the updated change object or null to stop the update.
  3. depth (number?, default: 1): Same as in observe

Returns

(dispose): Dispose function, which you can call to stop intercepting

Example

store.intercept(
  "/todos",
  (todos, change) => {
        console.log("Current value of todos", todos) // before applying patch

    // return modified patches for some case
    if (change.patch.path === "/todos/0/caption"]) {
      return {
                ...change,
        patch: {
                    ...change.patch,
                    value: {
                        ...change.patch.value,
                         caption: "first task: " + change.patch.value.caption
                    }
                },
      };
    } else if (
        // Don't allow adding more than 10 items, return null will stop the change
      change.patch.length === 2 &&
      change.patch.op === "add" &&
      change.patch.path.split("/")[2] > 9
    ) {
      return null;
    }

    // no modification
    return change;
  },
  2 // depth to intercept
);

dispatch

Same as Redux dispatch. This is used to dispatch actions to the internal Redux store.

subscribe

Same as Redux subscribe. This is used to subscribe to the internal Redux store.

useSyncState

Note: This method is for advanced use cases. You might not need it unless you are creating a plugin

In addition to doc which is a JSON document representing your app state, SyncState's internal Redux store contains documents for plugins too. Plugins keep their state in these documents.

The root state of internal Redux store looks like this:

{
  // Document containing app state
    doc: {
        state: {...},
        patches: [...]
    },
  // Document containing plugin1 state
    plugin1: {
        state: {...},
        patches: [...]
    },
  // Document containing plugin2 state
    plugin2: {
        state: {...},
        patches: [...]
    }
}

When you use useDoc, the operation happens on doc.state. To work with other documents, you can use useSyncState.

Arguments

  1. subtree (string): The subtree that you want to fetch the state from
  2. path (string): The path to state that you want to fetch

Returns

(Array): An array with the following elements in order

  • State at path.
  • A function to modify the state.
    • Same as here
  • A dispatch function for you to dispatch any action to the internal Redux store.

Example

const [todos, setTodos] = store.useDoc("/todos");

setTodos([{ caption: "Hello", done: false }]); // replaces todos array
// OR
setTodos((todos) => todos.push({ caption: "Hello", done: false })); // pushes a new element to todos array
← createDocStoreProvider →
  • useDoc
  • getPatches
  • getState
  • getStateAtPath
  • observe
  • intercept
  • dispatch
  • subscribe
  • useSyncState
Docs
Getting StartedExamplesPluginsAPI ReferenceFAQ
Community
TwitterStack OverflowDiscord
More
GitHub   Contribution Guidelines
Stars
Built with ❤️ at GeekyAnts.
Copyright © 2020 SyncState