- A minimalist IndexedDB (IDB) wrapper and syncing solution for when your application disco(nnects) from the network.
- Lightweight with zero dependencies.
- Functionalities can be implemented via Service Workers with minimal modification to client side code
- Supports syncing IDB with NoSQL databases (MongoDB) with a unique keypath
- Promise based wrapper for IDB to perform local CRUD operations while offline to provide seamless UX
- Sync to main database via action queue with automatic network availability detection.
npm install disco-db
Assuming a bundler such as Webpack, Rollup, etc is used:
import { discoConnect, discoSyncToServer, discoSyncOffline, discoSyncOnline, onlineUrlArr, offlineUrlArr, dbGlobals, idbPromise } from 'discodb';
When registering the service worker, pass in an option object with property type:'module'
if("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.register("sw.js", {type: 'module'})
Our library requires some minimal configuration. In the root directory of the project, create a file labeled discodb.config.js
and update the values of the corresponding key property.
// discodb.config.js
const dbGlobals =
{
version: "IDB version",
databaseName: "IDB database name",
storeName: "IDB Object Store name",
syncQueue: "IDB Object Store Queue name",
keypath: "Primary key of main database table",
// Add all routes to be intercepted
onlineRoutes: [
{
url: "",
}
],
offlineRoutes: [
{
url: " ",
},
{
url: " ",
}
]
}
export { dbGlobals };
discoSyncOffline(method, url, clonedRequest)
-
discoSyncOffline
is a request reducer that intercepts fetch requests and implements CRUD operations on the passed in endpoints. -
discoSyncOffline
takes in three parameters, the method and url of theevent.request
as well as a clone of theevent.request
, utilizing the.clone()
method. -
Under the hood,
discoSyncOffline
will check the url, and perform a GET, DELETE, or PATCH operation with indexedDB and return a new Response object back to the client.
discoSyncOnline(method, url, clonedResponse)
-
discoSyncOnline
establishes a connection to indexedDB and populates the object store with your noSQL data. -
discoSyncOnline
takes in three paramaters, the method and url of theevent.request
as well as a clone of theresponse
that was sent back from the server. -
Under the hood,
discoSyncOnline
will check the url passed in and first clear indexedDB of any stale data, and repopulate with the response body that it received back from the server.
To initialize an idb with attributes passed into discodb.config.js
, invoke discoConnect()
when installing the service worker
self.addEventListener('install', event => {
discoConnect();
});
discoSyncOffline()
and discoSyncOnline()
require the following to be true:
- Network falling back to cache Service Worker strategy: Documentation
- Response and Request objects passed into
discoSyncOffline()
anddiscoSyncOnline()
respectively will need to be a cloned version.
onlineUrlArr
and offlineUrlArr
will include the onlineRoutes
and offlineRoutes
from discodb.config.js
respectively in an Array.
self.addEventListener('fetch', event => {
// clone the request
const reqClone = event.request.clone();
event.respondWith(
// network first approach
fetch(event.request)
.then((response) => {
// clone the response
const resCloneCache = response.clone();
const resCloneDB = response.clone()
// open caches and store resCloneCache
// ...
// intercept routes included in onlineUrlArr
if (onlineUrlArr.includes(url)){
discoSyncOnline(method, url, resCloneDB);
}
return response;
})
// Fallback to Cache
.catch((err) => {
//invoke offline reducer to perform RUD functions to indexedDB
if (offlineUrlArr.includes(url)){
return discoSyncOffline(method, url, reqClone);
}
// return cache
// ...
})
)
});
You can also use the synchronization queue separately from our reducers! Make sure to discoConnect()
to the IDB database and have your configuration file ready.
- Set up an event handler to listen for "sync" and a conditional to catch our tag, "discoSync".
- Request for a synchronization event by registering through the service worker through
discoRegisterSync()
. By default, the sync tag assigned to the request is 'discoSync'. - Once a sync request has been registered, we now can add an object containing the HTTP request to the Object Store Queue by invoking
discoAddToQueue(object)
.
- Object format must contain these properties
{ url: "Route URL", method: "HTTP Method", body: "data object from HTTP request" }
- Now that the Object Store Queue has been populated with HTTP requests, we can send them to the main server! Within the event handler for sync, invoke
discoSyncToServer()
.self.addEventListener('sync', (event) => { if(event.tag === 'discoSync'){ discoSyncToServer(); }; };
Our demostration application utilizing this library is a simple note taking app. The demo app relies on service workers intercepting all HTTP requests for both online and offline requests.
Fork and clone our repository onto your local repository and follow the README in the app.
We'd love for you to test this library out and submit any issues you encounter. Also feel free to fork to your own repo and submit pull requests!
DiscoDB is MIT licensed.