assuncaocharles / react-indexed-db

A service that wraps IndexedDB database in an Declarative way. It exposes very simple promises API to enable the usage of IndexedDB without most of it plumbing.
MIT License
110 stars 37 forks source link

Recreating missing object-stores #72

Open planetcrypton opened 3 months ago

planetcrypton commented 3 months ago

I'd like to follow up on #8 :

I think it would be beneficial if in function CreateObjectStore the check for and creation of object stores, would occur in onsuccess handler in stead of onupgradeneeded. This to ensure the check for object-stores will be made every time.

"Why?" you may ask: I experience (according to report from Sentry) errors (only using Safari) telling that an object-store is missing when performing an transaction. NotFoundError Failed to execute 'transaction' on 'IDBDatabase': One of the specified object-stores was not found

Safari erases IndexedDB, LocalStorage, Media keys, SessionStorage, and Service Worker registrations after seven days if the user does not interact with the associated website during this period. What I think happens is that object-stores are removed by Safari, but not the database itself. So next time initDB/CreateObjectStore is called, onupgradeneeded won't run and the object-stores that now are missing will not be re-created. If that functionality is moved to onsuccess handler in stead, we would be 100% sure that the (missing) object-stores are created.

planetcrypton commented 1 month ago

Two things about my suggestion and my assumption about Safari:

My suggestion does not seem to be an option since createObjectStore only is allowed in onupgradeneeded handlers and not in onsuccess as I suggested - that gives this error: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction

But I think my whole assumption about Safari erasing data might not the case. Lately Sentry reported a similar Failed to execute 'transaction' on 'IDBDatabase'-error with iOS mobile Chrome.

Perhaps the reason is that the object-stores have not been created yet, before the first query is executed. Since initDB is a synchronous function (as pointed out here #66) there is no way of telling when the DB is ready, and thus causing "Failed to execute 'transaction' on 'IDBDatabase'"-errors