v4 feedback/suggestions
See original GitHub issueFirst of all, great work on new API changes in v4! I spent some time trying out the new version today, and I didn’t run into any issue. I’m pretty sure we could migrate to this in Workbox once we move away from running our unit tests in a node-mock environment (where the IDB-mock library we use only supports IndexedDB v1).
Also, I really like the use of proxies to make things smaller, and having a weakmap-backed unwrap
function is a lot nicer than _request
, _cursor
, _index
, etc…
A few suggestions, which I think are definitely optional, but could provide some nice sugar and sensible defaults for folks that don’t necessarily know IndexedDB best practices.
Add some shorthand methods for common requests.
Some really common pattern with idb
are to do things like this:
// Get all entries in an object store matching a query
db.transaction('my-store').objectStore('my-store').getAll(query);
// Get the first entry in an object store via an index
db.transaction('my-store').objectStore('my-store').index('my-index').getAll(query, 1)
// Add an entry to an object store.
db.transaction('my-store', 'readwrite').objectStore('my-store').put({...});
There could be shorthand methods for these types of requests. E.g. something like from()
, and in()
, where the above would become:
// `.from(store)` is shorthand for `.transaction(store).objectStore(store)`
db.from('my-store').getAll(query);
// `.from(store, index)` is shorthand for `.transaction(store).objectStore(store).index(index)`
db.from('my-store', 'my-index').getAll(query);
// `.in(store)` is shorthand for `.transaction(store, 'readwrite').objectStore(store)`
db.in('my-store').put({...});
Add an open timeout
Due to this IndexedDB issue there are cases where the openDb()
promise will never resolve. While this is a bit of an edge case, when it does happen (which I’ve run into several times when running tests) it’s very difficult to debug.
How we solved this in our Workbox IndexedDB wrapper is to use a timeout that causes the promise to reject after 2 seconds (by default, the timeout is customizable).
I found this to be quite helpful when debugging tests, because seeing that error in the console made it much easier to spot issues.
Make the blocking
callback default to calling db.close()
Most developers (AFAIK) open connections to a database and then keep the connection open for the life of the page. While in general this is a good practice (opening can be slow), it does increase the risk that a newer version of the page in another tab will get blocked when trying to upgrade the DB.
If the blocking
callback could call db.close()
by default (when not set), this situation would be far less likely to occur. It’ll also make the above scenario far less likely as well.
The implication is now the old page will not be able to connect to the database, but this seems better than a brand new page not being able to connect.
Of course, if this behavior is not what a developer wants, they can provide their own blocking
callback. I think it’s fairly safe to assume that anyone who specifically doesn’t want the auto-close behavior is advanced enough to know how to use the blocking
callback to suit their site’s needs.
On the other hand, if you wanted to keep the core exports of idb
really small and as true to the IndexedDB spec as possible, the idb
library could come with another, separate module file that exports a wrapper class with some of the functionality I described above.
The wrapper could also include features like lazily opening a connection to a DB in idle periods or after the first request is made. We’ve found this to be really nice in service worker, where you don’t necessarily want to be opening IndexedDB connection eagerly every time the service worker starts up.
Anyway, again, nice work on the update! And I’d be happy to submit PRs for any of the features I suggested here.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:5 (3 by maintainers)
This feedback was really useful, thanks!
Of all the options discussed so far, I think my preference would be to “hoist” select
IDBObjectStore
methods ontoIDBDatabase
, and require that the first param be an object.An array may be a bit terser, but I think the explicitness of an object will make the code more readable, so that’s my slight preference.