jlongster / absurd-sql

sqlite3 in ur indexeddb (hopefully a better backend soon)
MIT License
4.15k stars 101 forks source link

Use cache api instead of indexeddb #52

Open rklaehn opened 2 years ago

rklaehn commented 2 years ago

I have worked with indexeddb several times. Every time it was nothing but pain and suffering. Last time I tried something demanding with indexeddb (implementing a blob store for in-browser ipfs), it completely broke. Not just the indexeddb I was working with, but also all other indexeddb based websites on the same browser.

I have been looking around for alternatives. Obviously local storage won't work, because it is too coarse grained and in any case limited to 5mb or so.

But there is the browser cache api which might work: https://developer.mozilla.org/en-US/docs/Web/API/Cache

At least according to the docs, you have complete control over when a user-generated cache is being purged. "An origin can have multiple, named Cache objects. You are responsible for implementing how your script (e.g. in a ServiceWorker) handles Cache updates. Items in a Cache do not get updated unless explicitly requested; they don't expire unless deleted. Use CacheStorage.open() to open a specific named Cache object and then call any of the Cache methods to maintain the Cache."

And it will be purged either all at once, or not at all. So kinda similar to indexeddb, but with less overhead and overall insanity. I did some experiments, and it seems to work quite well from wasm.

Browser caches are essential for functioning, so I think they are quite efficient. For example they are not using one file per cache entry. They offer a key value store interface without transactions, but it seems that you should be able to build a sqlite backend / emscripten compatible file system on top of it, similar to https://github.com/jlongster/absurd-sql/tree/master/src/indexeddb

One cache entry would correspond to a block of a file. Modifying would work by reading, modifying, writing. This is quite similar to how it seems to be done in the indexeddb backend.