Skip to content

Latest commit

 

History

History
221 lines (169 loc) · 6.2 KB

File metadata and controls

221 lines (169 loc) · 6.2 KB

Replicache JS SDK

Realtime Sync for Any Backend Stack

Node.js CI

👋 Quickstart

This document walks you through getting Replicache up and running in your own application, talking to your own backend.

🏃‍♂️ Create your Client View endpoint

Add a /replicache-client-view endpoint to your API server that responds to HTTP POST and with the data you want cached on the device, like so:

{
  "lastMutationID": 0,
  "clientView": {
    "/todo/1": {
      "title": "Take out the trash",
      "description": "Don't forget to pull it to the curb.",
      "done": false,
    },
    "/todo/2": {
      "title": "Pick up milk",
      "description": "2%",
      "done": true,
    }
  }
}

You can put any key/value pairs you want in the "clientView" section.

For more details on implementing your Client View, see Client View Setup.

You can also skip this step for now, and just use our sample backend instead. See replicache-echo-backend.

🛹 Install Replicache

In your web client root:

npm install replicache

🚗 User Interface

Now let's add a user interface to render the synced data.

If you use React:

  1. npm add replicache-react-util
  2. If you use webpack 4, follow this procedure to configure webpack to load wasm properly. If you use webpack 5, nothing special is needed. If you use another bundler, try it and let us know 😀.
  3. Then, add this code somewhere:
import React from 'react';
import ReactDOM from 'react-dom';
import {Replicache} from 'replicache';
import {useSubscribe} from 'replicache-react-util';

const rep = new Replicache({
  // The URL to pull from.
  pullURL: 'http://localhost:1234/pull',

  // Auth token required for your pull endpoint, if any.
  pullAuth: '<authtoken>',

  // The URL to push changes to
  pushURL: 'http://localhost:1234/push',

  // Auth token required for your pull endpoint, if any.
  pushAuth: '<authtoken>',

  // Path to where Replicache wasm module can be found.
  // Only needed if you use webpack 4.
  wasmModule: '/node_modules/replicache/out/replicache.wasm',
});

function MyApp() {
  const entries = useSubscribe(rep, async tx => await tx.scanAll(), []);

  return (
    <table border="1">
      <tbody>
        {entries.map(([k, v]) => (
          <tr key={k}>
            <td>{k}</td>
            <td>{JSON.stringify(v)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

var elm = document.createElement('div');
document.body.appendChild(elm);
ReactDOM.render(React.createElement(MyApp), elm);

Vanilla JS:

<script type="module">
  import {Replicache} from './node_modules/replicache/out/replicache.dev.js';

  const rep = new Replicache({
    // The URL to pull from.
    pullURL: 'http://localhost:1234/pull',

    // Auth token required for your pull endpoint, if any.
    pullAuth: '<authtoken>',

    // The URL to push changes to
    pushURL: 'http://localhost:1234/push',

    // Auth token required for your pull endpoint, if any.
    pushAuth: '<authtoken>',
  });

  rep.subscribe(async tx => await tx.scanAll(), {
    onData: result => {
      const tbody = document.querySelector('tbody');
      tbody.innerHTML = '';
      for (const [k, v] of result) {
        const row = document.createElement('tr');
        const td1 = document.createElement('td');
        const td2 = document.createElement('td');
        td1.textContent = k;
        td2.textContent = JSON.stringify(v);
        row.appendChild(td1);
        row.appendChild(td2);
        tbody.appendChild(row);
      }
    },
  });
</script>
<table border="1">
  <tbody></tbody>
</table>

Replicache polls your Client View on a timer and updates the UI automatically.

Notes:

  • In production, you can use our hosted Diff Server instead of a local one. See Create Hosted Diff Server Account for details.
  • You can adjust the frequency of the polling using the pullInterval property. However, polling is typically only used for development. In production, we recommend using a WebSocket poke to tell the client when to pull.

🏎 Batch Endpoint

If you are using replicache-echo-backend you can skip this step!

Otherwise, add a /replicache-batch endpoint to your API server that accepts and processes batches of mutations that look like this:

{
  "clientID": "CB94867E-94B7-48F3-A3C1-287871E1F7FD",
  "mutations": [
    {
      "id": 7,
      "name": "createItem",
      "args": {
        "key": "create-item-0.4420193",
        "value": "foo",
      }
    },
    {
      "id": 8,
      "name": "createItem",
      "args": {
        "key": "create-item-0.21301",
        "value": "bar",
      }
    },
  ]
}

See Replicache Upstream Sync for instructions on how to implement this endpoint.

🛫 Client-Side Mutations

Add the following code to the end of your script block in your UI.

const createItem = rep.register('createItem', async (tx, {key, value}) => {
  await tx.put(key, value);
});

var button = document.createElement('button');
button.textContent = 'New item...';
document.body.appendChild(button);
button.onclick = () => {
  createItem({key: `new-item-${Math.random()}`, value: 'foo'});
};

🚀 Server-Side Mutations

Wire up your batch handler:

const rep = new Replicache({
   ...
+  // The URL to your batch endpoint added above.
+  batchURL: 'http://localhost:3001/replicache-batch',
});

When you tap the button the change happens immediately on the client, but is momentarily later sent to the server. You can verify it by turning the network off in web inspector or slowing it down.

Next Steps

That's it! You've built a fully-functioning Replicache-powered app against your own backend. What will you do next?