Use cache before downloading?

Hi, there

I am developing an offline-first app that needs to be relatively fast, even on slow Internet or no Internet. RS.js’s offline capabilities are absolutely perfect for this (great job, devs), but I have one issue:

If I am connected to the Internet, every time I perform getObject/storeObject/etc. it performs a network request to get the data rather than just fetching the node stored in IndexedDB, making it really slow.

Is there some option I am missing to force the library to only query IndexedDB, and perform network requests only on sync?

Thanks

Yes, certainly. The get functions’ caching behaviour is adjustable and explained here: https://remotestoragejs.readthedocs.io/en/latest/js-api/base-client.html#caching-logic-for-read-operations

In your case, the short answer is: you can set maxAge to false in order to always get the object from cache, no matter when it was last checked for changes in the remote storage. For example:

baseClient.getObject('some-path', false)

There’s also an alternative option, which is to not use the get functions at all, and rely on change events to load the user data into memory. You can see this in action and code with the My Favorite Drinks example app: https://github.com/remotestorage/myfavoritedrinks

I’m new to remotestorage, but it looks very interesting and I have got some ideas to use it. There is only one thing about the caching behavior I don’t understand, even after reading all the documents. It seems that all local information in the indexDB is lost at the moment that I disconnect from the remote (5apps) server. First I thought I did something wrong, but I see the same behavior in the demo app myfavoritedrinks. When I reconnect everything synchronizes and works fine again, but I would expect to have/keep all the data when not connected. Could anyone please clarify?
Thanks!

Think of connecting a remote storage as logging in to your account on that client. Disconnecting means logging out of it, so all data will be purged then. You don’t have to disconnect on a device you use regularly. In fact, usually you’d almost never disconnect.

All data is stored offline (first), kept between sessions, and loaded on startup by default. Only if you disconnect your account, it will re-sync all data after the next connect/login, instead of just the new data from the remote.

Okay, it makes sense. Although it’s a bit confusing as it is not the case for an app like Laverna. But I suppose it’s worked out differently there.
Thanks for the quick reply.

I’m not sure what you mean. It should be the case for Laverna as well, and last time I used it that’s how it worked. You only disconnect from the settings page there, otherwise you stay connected.

I’ve altered my code to now use false as maxAge, and it is working (can’t believe I missed that in the documentation).

To make the sync only work periodically (download changes “lazily”), I thought that the backgroundSync interval would cause the program to automatically sync every 60 seconds, but it doesn’t seem to be doing that. How exactly does this work?

I tried using RemoteStorage.startSync(), but that doesn’t seem to do anything either. The only time my app wants to download objects is when BaseClient.getObject/getAll is used. It is uploading them on creation, though.

So my app is pushing, but not pulling. Any suggestions?

Thanks

Here’s a picture from the webconsole after disconnecting from 5apps (with the widget) and after refreshing IndexedDB.

Any paths, for which caching is enabled, will be checked for changes and synced automatically every 10 seconds by default (and every 60 seconds while the app/tab is in the background).

I’m not sure exactly what’s happening there, but I could reproduce it myself just now. It could be a bug with the version of remoteStorage.js they’re using, as it’s quite old, but I have never seen a bug report about this or seen it happening with an older version before. It could also be intentional for some reason.

It’s definitely not how both the widget and the disconnect function are intended to work. Disconnect should delete all user data of a connected account, as it does for all other apps and the current library and widget.

Sorry about that! Really not sure why it’s not the case with Laverna. Would be great if they would upgrade to rs.js 1.0.x, because it’s much more up-to-date and more stable than what they’re still using right now.

OK, thanks!

In each of my modules I’ve set privateClient.cache(’’, ‘ALL’);

Is this not how it should work?

EDIT:
I’ve now changed my code to use this.remoteStorage.caching.enable(path) and it works.

I am encountering an issue now though where cached objects are not being updated. The revision and timestamps are different for the objects, so I am not sure what is happening.

Glad it works now! Technically, moduleClient.cache('/', 'ALL') is the same as rs.caching.enable('modulename/').

Did you check the console when trying the path with an empty string? I’m pretty sure that would trigger a console error from this line. But also, if you just want to cache the module’s root with the default caching strategy, you can just use moduleClient.cache() without arguments.

Let’s keep this thread about caching, so it stays on topic. If you’re still having this issue, please start a new topic about it (or create an issue over on GitHub, if it looks like a bug). I’m sure we can sort out what’s happening there. Thank you!