rocicorp / replicache

Realtime Sync for Any Backend Stack
https://doc.replicache.dev
1.04k stars 37 forks source link

Hello world in vanilla js? #998

Closed mashpie closed 2 years ago

mashpie commented 2 years ago

How about adding a minimal code sample without any framework requirements or abstractions?

Or let it be some express or fastify server side and svelte / vue client side.

What makes replicache so interesting to me is the fact that it should be easy to implement in custom on-premise projects. Sure, I've tried all provided examples, getting started, read and partially tried the Howto Integration own Backend. But to be honest: next adds so much noise around the key of syncing (and offline-first capabilties) that I got lost.

aboodman commented 2 years ago

Hi @mashpie - we have recently (like a few days ago did a bunch of work to the docs. Have you seen the latest "get started": https://doc.replicache.dev/ ? Was it light or dark background when you last looked. If dark, take another look through, we think it should be a lot easier.

Or let it be some express or fastify server

Replicache requires a server that understands the Replicache sync protocol. this is not a lot of work, but it's not trivial either. Think of it sort of like a GraphQL backend. The next backend we provide in the current get started is about as trivial as it possible gets. Putting it in express wouldn't change anything I don't think (the amount of Next.js in the backend dir is like the two endpoint entrypoints).

svelte / vue client side.

This would definitely be interesting for those more familiar with those frameworks, and a vanillajs one is interesting too. Thanks for the recommendation.

If you have any specific questions happy to answer here or discord. Sorry the docs seems confusing.

mashpie commented 2 years ago

Hi @aboodman, and thanks for the fast response. In the end, the backend is not my concern but the frontend. All examples I found are using:

import { useSubscribe } from "replicache-react";

To subscribe for changes. I could not find a way to subscribe to changes without it properly. If possible, to accomplish with RxJS, we were prepared for vanilla and vue (through https://vueuse.org/functions.html#category=%40RxJS). I think...

mashpie commented 2 years ago

Now! After poking around in your older repositories I managed to get some vue reactivity with:

<script setup>
import { ref } from 'vue'
import { Replicache } from 'replicache'

const list = ref([])

const rep = new Replicache({
  name: 'chat-user-id',
  licenseKey: '...',
  pushURL: '/api/replicache-push',
  pullURL: '/api/replicache-pull'
})

rep.subscribe((tx) => tx.scan({ prefix: 'message/' }).entries().toArray(), {
  onData(data) {
    list.value = data
  }
})
</script>

<template>
  <div>
    <pre>{{ list }}</pre>
  </div>
</template>

Could that be so simple?

aboodman commented 2 years ago

Yup! Sorry this was hard to find. We'll get a vanilla sample going soon.

arv commented 2 years ago

And vanilla:

index.html

<!DOCTYPE html>
<body>
  <button id="add-message">Add Message</button>
  <div id="list"></div>
</body>
<script type="module" src="index.js"></script>

index.js

import {
  Replicache,
  TEST_LICENSE_KEY,
} from 'https://cdn.skypack.dev/replicache';

function drawList(rep, parentNode) {
  rep.subscribe(
    async tx => tx.scan({ prefix: 'messages/' }).values().toArray(),
    {
      onData(data) {
        parentNode.replaceChildren(
          ...data.map(item => {
            const div = document.createElement('div');
            div.textContent = item;
            return div;
          }),
        );
      },
    },
  );
}

const rep = new Replicache({
  name: 'vanilla',
  licenseKey: TEST_LICENSE_KEY,
  mutators: {
    addData: async (tx, { key, value }) => {
      await tx.put(key, value);
    },
  },
});

const listContainer = document.getElementById('list');
drawList(rep, listContainer);

let count = 0;
const button = document.getElementById('add-message');
button.onclick = () =>
  rep.mutate.addData({
    key: `messages/${++count}`,
    value: `Hello world! ${count}`,
  });
mashpie commented 2 years ago

Nice, straight to the point. Thanks a lot for your support!