PHP Classes

File: src/js/browser/adapters/UnicacheIndexedDb.js

Recommend this page to a friend!
  Classes of Nikos M.   Unicache   src/js/browser/adapters/UnicacheIndexedDb.js   Download  
File: src/js/browser/adapters/UnicacheIndexedDb.js
Role: Auxiliary data
Content typex: text/plain
Description: Auxiliary data
Class: Unicache
Store cached data in different storage types
Author: By
Last change:
Date: 2 months ago
Size: 10,308 bytes
 

Contents

Class file image Download
!function(UNICACHE) { "use strict"; var PROTO = 'prototype', _ = UNICACHE._, DB_NAME = 'unicache-indexeddb-cache-db', DB_VERSION = 1, // Use a long long for this value (don't use a float) DB_STORE_NAME = 'unicache_db_store_', ROOT = 'undefined' !== typeof window ? window : ('undefined' !== typeof self ? self : this), IDB = getIDB() ; // https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API // https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB function getIDB() { var idb = {db:null, transaction: {READ_WRITE:"readwrite"}, keyrange:null}; /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */ try { if (typeof ROOT.indexedDB !== 'undefined') { idb.db = ROOT.indexedDB; } else if (typeof ROOT.webkitIndexedDB !== 'undefined') { idb.db = ROOT.webkitIndexedDB; } else if (typeof ROOT.mozIndexedDB !== 'undefined') { idb.db = ROOT.mozIndexedDB; } else if (typeof ROOT.OIndexedDB !== 'undefined') { idb.db = ROOT.OIndexedDB; } else if (typeof ROOT.msIndexedDB !== 'undefined') { idb.db = ROOT.msIndexedDB; } } catch (e) { } try { if (typeof ROOT.IDBTransaction !== 'undefined') { idb.transaction = ROOT.IDBTransaction; } else if (typeof ROOT.webkitIDBTransaction !== 'undefined') { idb.transaction = ROOT.webkitIDBTransaction; } else if (typeof ROOT.msIDBTransaction !== 'undefined') { idb.transaction = ROOT.msIDBTransaction } } catch (e) { } try { if (typeof ROOT.IDBKeyRange !== 'undefined') { idb.keyrange = ROOT.IDBKeyRange; } else if (typeof ROOT.webkitIDBKeyRange !== 'undefined') { idb.keyrange = ROOT.webkitIDBKeyRange; } else if (typeof ROOT.msIDBKeyRange !== 'undefined') { idb.keyrange = ROOT.msIDBKeyRange } } catch (e) { } return idb; } var IndexedDbCache = UNICACHE.IndexedDbCache = function() { this.queue = []; }; function set(db, store, key, value, expires, cb) { var request = db.transaction([store], "readwrite").objectStore(store).put([_.time()+expires, value], key); request.onerror = function(event) { if ('function' === typeof cb) cb(new Error('Setting "'+key+'" failed!'), null); }; request.onsuccess = function(event) { if ('function' === typeof cb) cb(null, true); }; } function get(db, store, key, cb) { var request = db.transaction([store], "readonly").objectStore(store).get(key); request.onerror = function(event) { if ('function' === typeof cb) cb(new Error('Retrieving "'+key+'" failed!'), null); }; request.onsuccess = function(event) { if ('function' === typeof cb) cb(null, request.result); }; } function del(db, store, key, cb) { var request = db.transaction([store], "readwrite").objectStore(store).delete(key); request.onerror = function(event) { if ('function' === typeof cb) cb(new Error('Deleting "'+key+'" failed!'), null); }; request.onsuccess = function(event) { if ('function' === typeof cb) cb(null, true); }; } // extend UNICACHE.Cache class IndexedDbCache[PROTO] = Object.create(UNICACHE.Cache[PROTO]); IndexedDbCache.isSupported = function( ) { return !!IDB.db; }; IndexedDbCache[PROTO].request = null; IndexedDbCache[PROTO].db = null; IndexedDbCache[PROTO].queue = null; IndexedDbCache[PROTO].open = function(cb) { var self = this; if (!self.request) { if (self.queue && ('function' === typeof cb)) self.queue.push(cb); self.request = IDB.db.open(DB_NAME, DB_VERSION); self.request.onerror = function(event) { self.db = false; if (self.queue) { var err = new Error('IndexedDB Open Error with code '+self.request.errorCode); var queue = self.queue; self.queue = null; queue.map(function(cb) {cb(err, null);}); } }; self.request.onblocked = function(event) { // If some other tab is loaded with the database, then it needs to be closed // before we can proceed. console.warn("UNICACHE: Please close all other tabs with this site open!"); }; self.request.onupgradeneeded = function(event) { var db = event.target.result; // Create an objectStore to hold information about any javascript value even primitives. var objectStore = db.createObjectStore(DB_STORE_NAME + self.prefix); }; self.request.onsuccess = function(event) { self.db = event.target.result; self.db.onclose = function(event) { self.db = null; //alert("A new version of this page is ready. Please reload or close this tab!"); }; self.db.onversionchange = function(event) { self.db.close(); self.db = null; //alert("A new version of this page is ready. Please reload or close this tab!"); }; if (self.queue) { var queue = self.queue; self.queue = null; queue.map(function(cb) {cb(null, self.db);}); } }; } else if (null == self.db) { if (self.queue && ('function' === typeof cb)) self.queue.push(cb); } else if (false === self.db) { if ('function' === typeof cb) cb(new Error('IndexedDB cannot be opened'), null); } else if (self.db) { if ('function' === typeof cb) cb(null, self.db); } return this; }; IndexedDbCache[PROTO].close = function() { if (this.db) { this.db.close(); this.db = null; } return this; }; IndexedDbCache[PROTO].dispose = function() { this.close(); this.db = null; this.request = null; this.queue = null; return UNICACHE.Cache[PROTO].dispose.call(this); }; IndexedDbCache[PROTO].supportsSync = function() { return false; }; IndexedDbCache[PROTO].put = function(key, data, ttl, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); } else { set(db, DB_STORE_NAME + self.prefix, key, data, +ttl, function(err, res) { if ('function' === typeof cb) cb(err, res); }); } }); }; IndexedDbCache[PROTO].get = function(key, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); } else { get(db, DB_STORE_NAME + self.prefix, key, function(err, data) { if ('function' === typeof cb) { if (err) cb(err, null); else if (!data) cb(null, false); else if (data[0] < _.time()) { del(db, DB_STORE_NAME + self.prefix, key); cb(null, false); } else cb(null, data[1]); } else { if (!err && data && (data[0] < _.time())) { del(db, DB_STORE_NAME + self.prefix, key); } } }); } }); }; IndexedDbCache[PROTO].remove = function(key, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); } else { del(db, DB_STORE_NAME + self.prefix, key, function(err, res) { if ('function' === typeof cb) cb(err, res); }); } }); }; IndexedDbCache[PROTO].clear = function(cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); } else { var req = db.transaction(DB_STORE_NAME + self.prefix, "readwrite").objectStore(DB_STORE_NAME + self.prefix).clear(); req.onerror = function(event) { if ('function' === typeof cb) cb(new Error('Error clearing store ' + event.target.errorCode), null); }; req.onsuccess = function(event) { if ('function' === typeof cb) cb(null, true); }; } }); }; IndexedDbCache[PROTO].gc = function(maxlifetime, cb) { maxlifetime = +maxlifetime; var currenttime = _.time(), self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); } else { var cursor = db.transaction(DB_STORE_NAME + self.prefix, "readwrite").objectStore(DB_STORE_NAME + self.prefix).openCursor(); var todel = []; cursor.onerror = function(event) { if ('function' === typeof cb) cb(new Error('Error looping through store ' + event.target.errorCode), null); }; cursor.onsuccess = function(event) { var cursor = event.target.result; if (cursor) { var expires = cursor.value[0]; if (expires < currenttime-maxlifetime) todel.push(cursor.key); cursor.continue(); } else { // no more entries setTimeout(function() { todel.map(function(key) { del(db, DB_STORE_NAME + self.prefix, key); }); if ('function' === typeof cb) cb(null, true); }, 10); } }; } }); }; return IndexedDbCache; }(UNICACHE);