@urql/exchange-graphcache
Version:
A normalized and configurable cache exchange for urql
122 lines (117 loc) • 4.28 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var getRequestPromise = request => {
return new Promise((resolve, reject) => {
request.onerror = () => {
reject(request.error);
};
request.onsuccess = () => {
resolve(request.result);
};
});
};
var getTransactionPromise = transaction => {
return new Promise((resolve, reject) => {
transaction.onerror = () => {
reject(transaction.error);
};
transaction.oncomplete = resolve;
});
};
/** Sample storage adapter persisting to IndexedDB. */
/** Creates a default {@link StorageAdapter} which uses IndexedDB for storage.
*
* @param opts - A {@link StorageOptions} configuration object.
* @returns the created {@link StorageAdapter}.
*
* @remarks
* The default storage uses IndexedDB to persist the normalized cache for
* offline use. It demonstrates that the cache can be chunked by timestamps.
*
* Note: We have no data on stability of this storage and our Offline Support
* for large APIs or longterm use. Proceed with caution.
*/
var makeDefaultStorage = opts => {
if (!opts) opts = {};
var callback;
var DB_NAME = opts.idbName || 'graphcache-v4';
var ENTRIES_STORE_NAME = 'entries';
var METADATA_STORE_NAME = 'metadata';
var batch = Object.create(null);
var timestamp = Math.floor(new Date().valueOf() / (1000 * 60 * 60 * 24));
var maxAge = timestamp - (opts.maxAge || 7);
var req = indexedDB.open(DB_NAME, 1);
var database$ = getRequestPromise(req);
req.onupgradeneeded = () => {
req.result.createObjectStore(ENTRIES_STORE_NAME);
req.result.createObjectStore(METADATA_STORE_NAME);
};
return {
clear() {
return database$.then(database => {
var transaction = database.transaction([METADATA_STORE_NAME, ENTRIES_STORE_NAME], 'readwrite');
transaction.objectStore(METADATA_STORE_NAME).clear();
transaction.objectStore(ENTRIES_STORE_NAME).clear();
batch = Object.create(null);
return getTransactionPromise(transaction);
});
},
readMetadata() {
return database$.then(database => {
return getRequestPromise(database.transaction(METADATA_STORE_NAME, 'readonly').objectStore(METADATA_STORE_NAME).get(METADATA_STORE_NAME));
}, () => null);
},
writeMetadata(metadata) {
database$.then(database => {
return getRequestPromise(database.transaction(METADATA_STORE_NAME, 'readwrite').objectStore(METADATA_STORE_NAME).put(metadata, METADATA_STORE_NAME));
}, () => {
/* noop */
});
},
writeData(entries) {
Object.assign(batch, entries);
var toUndefined = () => undefined;
return database$.then(database => {
return getRequestPromise(database.transaction(ENTRIES_STORE_NAME, 'readwrite').objectStore(ENTRIES_STORE_NAME).put(batch, timestamp));
}).then(toUndefined, toUndefined);
},
readData() {
var data = {};
return database$.then(database => {
var transaction = database.transaction(ENTRIES_STORE_NAME, 'readwrite');
var store = transaction.objectStore(ENTRIES_STORE_NAME);
var request = (store.openKeyCursor || store.openCursor).call(store);
request.onsuccess = function () {
if (this.result) {
var {
key
} = this.result;
if (typeof key !== 'number' || key < maxAge) {
store.delete(key);
} else {
var _request = store.get(key);
_request.onsuccess = () => {
var result = _request.result;
if (key === timestamp) Object.assign(batch, result);
Object.assign(data, result);
};
}
this.result.continue();
}
};
return getTransactionPromise(transaction);
}).then(() => data, () => batch);
},
onCacheHydrated: opts.onCacheHydrated,
onOnline(cb) {
if (callback) {
window.removeEventListener('online', callback);
callback = undefined;
}
window.addEventListener('online', callback = () => {
cb();
});
}
};
};
exports.makeDefaultStorage = makeDefaultStorage;
//# sourceMappingURL=urql-exchange-graphcache-default-storage.js.map