Coder Social home page Coder Social logo

ismail-codar / reactive-crdt Goto Github PK

View Code? Open in Web Editor NEW

This project forked from yousefed/syncedstore

1.0 1.0 0.0 3.25 MB

Reactive CRDT is an easy-to-use library for building collaborative applications that sync automatically.

License: MIT License

JavaScript 1.34% TypeScript 98.66%

reactive-crdt's Introduction

Reactive CRDT

npm version Coverage Status

Reactive CRDT is an easy-to-use library for building collaborative applications that sync automatically. It's built on top of Yjs, a proven, high performance CRDT implementation.

Example

Have a look at the collaborative Todo list examples (React, Vue) to get up to speed. Or, read along for a quick overview.

example app screencapture

View source and run: React, Vue.

Quick overview

Setup:

import { crdt, Y } from "@reactivedata/reactive-crdt";

// Create a document that syncs automatically using Y-WebRTC
const doc = new Y.Doc();
const webrtcProvider = new WebrtcProvider("my-document-id", doc);

// (optional, define types for TypeScript)
type Vehicle = { color: string; type: string };

type StoreType = {
  vehicles: Vehicle[];
};

// Create your reactive-crdt store
export const store = crdt<StoreType>(doc);

// initialize vehicles as an empty array:
store.vehicles = [];

From now on, the store object is synced automatically:

User 1:

store.vehicles.push({ type: "car", color: "red" });

User 2 (on a different device):

console.log(store.vehicles.length); // Outputs: 1

Reacting to updates

Now that State can be modified by connected peers, you probably want to observe changes and automatically display updates. This is easy to do, because Reactive CRDT works closely with the Reactive library.

Let's look at some examples:

Using React

import { useReactive } from "@reactivedata/react";
import { store } from "."; // the store we defined above

export default function App() {
  const state = useReactive(store);

  return (
    <div>
      <p>Vehicles:</p>
      <ul>
        {state.vehicles
          .map((v) => {
            <li>{v.type}</li>;
          })}
      </ul>
      <input type="text" onKeyPress=((event) => {
        if (event.key === "Enter") {
            const target = event.target as HTMLInputElement;
            // Add a yellow vehicle using the type added in the textfield
            state.vehicles.push({ color: "yellow", type: target.value });
            target.value = "";
        }
      })>
    </div>
  );
}

View on CodeSandbox (coming soon)

Vue

Reactive CRDT works great with Vues reactive programming model. See the Vue Todo example for an example application. In short, just put an object returned by the crdt function on a Vue data() object:

import { useVueBindings } from "@reactivedata/reactive-crdt";
import * as Vue from "vue";
import { crdt, Y, useVueBindings } from "@reactivedata/reactive-crdt";
import { WebrtcProvider } from "y-webrtc";

// make reactive-crdt use Vuejs internally
useVueBindings(Vue);

// Setup Yjs
const doc = new Y.Doc();
new WebrtcProvider("id", doc); // sync via webrtc

export default Vue.defineComponent({
  data() {
    return {
      // synced with Reactive CRDT
      sharedData: crdt<{
        vehicles: Vehicle[];
      }>(doc),
      // untouched
      regularLocalString: "",
    }
  }
);

You can now use sharedData.vehicles in your Vue app and it will sync automatically.

Without framework

You don't have to use React or Vue, you can also use autorun from the Reactive library to observe changes:

import { reactive, autorun } from "@reactivedata/reactive";
import { store } from "."; // the store we defined above

const reactiveStore = reactive(store);

autorun(() => {
  reactiveStore.vehicles.forEach(v => {
    console.log(`A ${v.color} ${v.type}`);
  });
});

// This can be executed on a different connected device:
reactiveStore.vehicles.push({ type: "bike", color: "red" });
reactiveStore.vehicles.push({ type: "bus", color: "green" });

View on CodeSandbox (coming soon)

Motivation

Yjs is a very powerful CRDT, but it's API is mostly targeted to create high-performant data bindings for (rich text) editors.

I wanted to explore whether we can abstract the existing Yjs API away, and make it extremely easy to integrate it as a Collaborative Data Store into existing applications.

There were two major design decisions:

  • Instead of data types like Y.Map, and Y.Array, can we just use plain Javascript objects and arrays?
    • e.g.: store.outer.inner.property = value instead of doc.getMap("inner").getMap("outer").getMap("inner").get("value")
  • Instead of having to call .observe manually, can we integrate with a Reactive Functional Programming library to do this automatically?
    • e.g.: wrap your code in autorun or use useReactive (React), or Vue's reactive model and automatically observe all used values from the store.

Would love to hear your feedback!

Credits ❤️

Reactive CRDT builds directly on Yjs and Reactive. It's also inspired by and builds upon the amazing work by MobX and NX Observe.

reactive-crdt's People

Contributors

yousefed avatar

Stargazers

Roman avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.