rocicorp / replicache

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

Mutations not showing up until received from pull #1004

Closed granmoe closed 2 years ago

granmoe commented 2 years ago

When I execute a mutation, let's say adding an item to a list via put, replicache.subscribe (which I'm using via useSubscribe) does not receive the change until after the next pull. Hopefully, it's just something simple that I'm doing wrong 🤔

https://user-images.githubusercontent.com/5620706/173198806-c6ff6cc6-140a-4717-9df6-b1393efcc2e0.mov

I created a repo here that serves as a minimal repro of the issue. Just run yarn dev or npm run dev to run the app and, of course, set the appropriate environment variables. (Note: I'm cheating a lot in this app just for convenience...it's not a legit implementation of a Replicache app, but it's legit enough to repro the issue.)

This file is probably the most relevant. As far as I can tell, I'm following all the patterns from the docs correctly.

Thank you for making Replicache! I can't wait to get past this issue so I can give my app to my first users 🙂

aboodman commented 2 years ago

Hi @granmoe I think what's happening here is that your mutator doesn't return a promise. Try return tx.put(...) instead of just tx.put(...). As a result the transaction closes before the put happens and the local state doesn't change.

aboodman commented 2 years ago

It's more typical actually to make the mutators async and await the put, but either way is fine as long as you return the promise that keeps the transaction open long enough for the change to happen.

aboodman commented 2 years ago

@arv perhaps MutatorDefs should require Promise return vals, not MaybePromise to prevent this error? https://doc.replicache.dev/api/#mutatordefs

granmoe commented 2 years ago

That worked! So, just to clarify my understanding, is the transaction updating Replicache state (in IDB or whatev) via a talking to a service worker and committing an IDB transaction?

Narrowing the type would def help in my case. Not sure if there's any case in which you'd want to not return a promise. Maybe add a quick note about this in the docs?

Thank you!

aboodman commented 2 years ago

No the transaction is just over in-memory state. It doesn't write to IDB immediately. We have the whole system async because occasionally things can go to disk. Replicache is generally in-memory but it pages in data from IDB as you read, and those paging in events can go to IDB and thus need to be async.

arv commented 2 years ago

The problem is that the transaction got closed before it finished put.

I agree, there is no legitimate reason to not require a mutator to return a Promise.