The web API
fetch is superbly simple (compared to its predecessor:
XMLHttpRequest) but during development there's always a few concerns I have when making fetch requests: hitting 3rd party request limits, latency (since I want dev to be rapid) and the potential of going offline (aka: developing on trains).
Since the browser is a beautiful thing, I'm able to wrap the
fetch API with my own custom logic and circumvent those concerns, so I introduce to you: memfetch
What it does
Memfetch will, unobtrusively, wrap the fetch API, and cache any request and response so that if you have the exact same request again, it'll be served from local browser cache.
Importantly, there's no change to my code to make use of the cached version of the requests. This aspect is an important feature to me, because I see memfetch as a development tool that I should be able to remove without having to refactor code before production.
How to use it
Now all fetch requests will be cached, and subsequent requests will be served directly from the local browser's storage. Importantly, the requests are fingerprinted using the url and the init options passed to the
fetch. This means if there's an additional option passed to your request (such as adding
mode: 'cors'), memfetch will treat this as distinct.
Again, all fetch requests are cached, which includes
POST requests. I suspect in future I'll have some kind of
exclude configuration if there's demand for it.
To clear the local cache, there's a
seed property on the
fetch method, if it's set to a value that's different to the current value (i.e. changed from
a or from
b), the local cache will be completely erased:
Under the hood
Originally this library would wrap the
fetch API and return a
new Proxy that would allow memfetch capture that the code used the
.json method, or the
.blob method - but it turned out I could simplify the code and drop the use of proxies (as cool as they are).
fetch method is stored in an internal method and replaced with a wrapper.
When you code makes a request, the following are stored in IndexedDB (thanks to Jake Archibald's micro idb-keyval library):
- fetch options
- response headers
Using these values, memfetch constructs a
new Response and returns that instead of the original response.
Subsequent requests check if there's a cached value, and using the captured data points (above), it resolved with another
new Response - this way the authored code can call
.json or any other method implemented by the Response API (which meant memfetch didn't need to use a proxy object).