gr2m / milestones

A GitHub backed Milestone thingy
http://gr2m.github.io/milestones/
69 stars 14 forks source link

Make Hoodie play nicely with Service Worker #94

Open gr2m opened 8 years ago

gr2m commented 8 years ago

The new Hoodie still depends on localStorage for APIs like hoodie.store.hasLocalChanges() and hoodie.account.isSignedIn(). The thinking behind these APIs is Hoodie’s Dream Code Initiative: we always think about the simplest API imaginable first and then make it work backwards.

To check if a user is signed in or if a document has local changes is often needed to render applications in different ways, and having sync APIs makes that much, much simpler.

As Offline First is also at the core of Hoodie, making it work nicely with Service Worker become an important requirement recently. Service Worker has no access to localStorage, so we have to think about what to do about it.

This will require some research, there are many unknown unknowns here that we need to explore. The high-level requirements are:

The result will be a compromise, the question is how it will look like.

gr2m commented 8 years ago

I thought we probably will have to change our APIs to make them all async, I started implementing a .getLocalChanges() method here: https://github.com/hoodiehq/pouchdb-hoodie-sync/tree/get-local-changes as an alternative to the sync .hasLocalChanges() method that we currently have.

The other sync methods are on hoodie.account

But when I think about it, I don’t see why these methods would need to be able to run in ServiceWorker at all. If we need ServiceWorker only for syncing data (in the background), all we need is the PouchDB bits and we need to store the user’s session ID for authentication towards the server. And if that is all then the sync methods we currently have don’t make any sense it ServiceWorker anyway.

To sum it up, to play nicely with ServiceWorker, we would only put the PouchDB bits on ServiceWorker and make the hoodie client use the http adapter instead of using the IndexDB adapter

gr2m commented 8 years ago

I’m talking to @nolanlawson about this right now on our way to Cascadia Fest 👋

nolan-and-gregor

What we’d need to do is to implement a custom hoodie-store-client that does not work with PouchDB in the main thread, instead uses postMessage (or https://github.com/nolanlawson/promise-worker) to talk to ServiceWorker which is using PouchDB.

rmehner commented 8 years ago

@gr2m quick little discussion I've had with @espy this morning re profiles:

hoodie.profile.get()

is a sync method, whereas:

hoodie.profile.fetch()

is async. The difference between both is that get is local, whereas fetch fetches from remote first, but the result is the same (an object with the profile properties).

Maybe it makes sense to make both APIs behave the same in terms of sync/async so the user is not surprised and doesn't have to remember when to use which pattern.

Just as an additional input :)

xMartin commented 8 years ago

@gr2m We've used the postMessage approach in a project to run the Pouch in a worker and it has proven to be a good solution.

janl commented 8 years ago

I think there is a case to be made for having the hoodie.store API being available within the ServiceWorker as well: so Hoodie users can develop SW-logic with the familiar store interface.

For the current use-case, sync is enough though, and for that we need: a valid auth token and the current user’s Hoodie id (as that’s how we construct the target database on the server).

I’d be happy to split things up in two (or more if needed) phases of “Hoodie support for ServiceWorkers”:

And more levels as we progress down this path.

gr2m commented 8 years ago

Just adding to the gathering of use cases: people asked for Hoodie & Server Side rendering in the past, and rendering in ServiceWorker is something that will likely become more relevant in future. And for that we need the full Hoodie API to work outside the DOM.

gr2m commented 7 years ago

update: we will drop the usage localStorage within Hoodie via https://github.com/hoodiehq/hoodie-client/pull/110, it now uses PouchDB exclusively for persisting both data and state like the user’s session. With that we should be ready to look into an architecture that takes advantage of Service Worker. Exciting :)

The approach I have in mind right now is to bundle an alternate version of the Hoodie Client which only includes the http adapter and hence becomes much, much slimmer. Then we bundle a script which can be loaded within an existing Service Worker (or alternatively an entire Hoodie-specific Service Worker) which intercepts all http requests made by PouchDB and loads data from IndexedDB.

I’m sure there are other ideas out there :) looking forward to explore this more in future

gr2m commented 7 years ago

here is some discussion relevant to our interest: https://github.com/nolanlawson/pouchdb-with-service-workers