To host this app, I’ll need the following things:

  • Something to host the static assets, e.g. the html/css/js.
  • Something to handle the state synchronization across clients

To host a site that would allow for multi-user alteration of the content, static assets alone won’t be enough, as we’ll need a way to synchronize our changes across users. While automerge has many ways to exchange changes – essentially anything that can faithfully transmit or store binary data – if we want an always-on node that can act as a post-office of sorts, we’ll need to build the code that takes the binary data and puts it on that node.

To that end, I want to explore the solutions Cloudflare has for storing and retrieving data.

Overview

I’m going to start with the assumption that we’ll use Cloudflare Pages to host the site. From this, it looks like there’s Pages Functions and Cloudflare Workers as options. The sites aren’t super clear on the differences, or when you’d use one over the other, but a quick look at the listed tutorials for both shows a chat demo for Workers and nothing similar for Functions.

That doesn’t mean Functions would be insufficient, but I wanted to note that as a strong signal that Workers is probably the right fit for what we’re looking for.

The demo uses Durable Objects – another Cloudflare tech – among some other things, so I suspect Durable Object will be in use no matter what.

What’s the difference between Functions and Workers?

The Functions overview page has this to say about Pages Functions

Pages Functions allows you to build full-stack applications by executing code on the Cloudflare network with Cloudflare Workers. With Functions, you can introduce application aspects such as authenticating, handling form submissions, or working with middleware. Use Functions to deploy server-side code to enable dynamic functionality without running a dedicated server.

My immediate read of this is that Functions is some more sugar on top of Workers, and is meant to offer something more than just what Workers can do, or simplify something about Workers, or perhaps is a name for integrating Workers into a Pages application. I’m not exactly sure, so we’ll keep digging.

Reading through the Functions getting-started doc, it’s sounding more and more like the primary functionality is that you add Workers function definitions in a special directory, and it can automagically sort out routing issues.

Luckily, by way of a semi-random click on a search link, I’ve found the following description from a refactoring how-to:

In this guide, you will learn how to refactor a Worker made to intake form submissions to a Pages Function that can be hosted on your Cloudflare Pages application. Pages Functions is a serverless function that lives within the same project directory as your application and is deployed with Cloudflare Pages. It enables you to run server-side code that adds dynamic functionality without running a dedicated server. You may want to refactor a Worker to a Pages Function for one of these reasons:

  1. If you manage a serverless function that your Pages application depends on and wish to ship the logic without managing a Worker as a separate service.
  2. If you are migrating your Worker to Pages Functions and want to use the routing and middleware capabilities of Pages Functions.

So that’s the summary I believe I was looking for. Before Pages Functions, I’d have to manage either the Workers service for both frontend and backend functionality, or both a Workers and a Pages service, but now I can have just a Pages service and ship server-side code that the Pages frontend code can use.

Sharing document changes between clients

So we’ll use Pages and Functions to serve the frontend and backend functionality, but now the question is: where do we store the automerge data?

Looking at the developer platform products, it looks like we should use either Workers KV, or Durable Objects.

From the Workers KV frontpage, we’ve got the following description:

Eventually consistent by design, KV caches data globally and is ideal for reference data or assets that don’t change frequently.

Reference data or assets that don't change frequently doesn’t sound quite like what we’re going for, since changes could, theoretically, occur frequently.

On the other hand, Durable Objects has the following to say:

Collaborative apps, like chat rooms, games, or whiteboards, require strong consistency of state to ensure everybody is working with the most up to date version. Durable Objects enables you to build and run stateful applications on Cloudflare’s global network.

Which both sounds exactly like what we need, and also matches with what the chat demo for Workers referenced above uses.

Synthesis

So from all of this, it sounds like our Cloudflare stack will be:

  • Pages, for the frontend functionality
  • Pages Functions, for the backend/durability functionality
  • Durable Objects, for the data synchronization between clients

Next up

Now that we know the foundational infrastructure tech we’re going to use, we can layer on top of that by exploring one of the following (or even something I haven’t foreseen yet):

  • How Pages Functions work, specifically, so we can understand how we tie the frontend and backend together.
  • How to deploy a basic CLJS app – frontend only – to Pages
  • How to add basic backend CLJS capabilities via Pages Functions

See you next time!