Indexed Db
function _err(x) {
    throw new Error(x);
}
function DB(name) {
    this.name = name;
}
DB.prototype.delete = ()=>{
    return new Promise((r,_)=>{
        var con = indexedDB.deleteDatabase(this.name);
        con.onsuccess = e=>{
            r(this);
        };
        con.onerror = e=>{
            _(e);
        };
    });
}
DB.prototype.table = (storename)=>{
    this.storename = storename;
    return this;
}
DB.prototype.create = (primaryKey,...indexInfo)=>{//'id', {name: '', (path: '', unque: false)}
    return new Promise((r,_)=>{
        this.storename||_('You have to use "table" before using this method.');
        var con = indexedDB.open(this.name);
        var exist = true;
        con.onupgradeneeded = e=>{
            exist = false;
            var db = e.target.result;
            var store = db.createObjectStore(this.storename, {keyPath: primaryKey});
            indexInfo.forEach(v=>store.createIndex(v.name, v.path||v.name, {unique: v.unique||false}));
            r(this);
        }
        con.onsuccess = e=>exist&&_(`The table "${this.storename}" already exist.`);
        con.onerror =e=>_(e);
    });
}
DB.prototype.put = (...obj)=>{
    return new Promise((r,_)=>{
        this.storename||_('You have to use "table" before using this method.');
        var con = indexedDB.open(this.name);
        con.onsuccess = e=>{
            var db = e.target.result;
            var trans = db.transaction([this.storename], "readwrite");
            trans.oncomplete = e=>r(this);
            trans.onerror = e=>_(e);
            var store = trans.objectStore(this.storename);
            obj.forEach(v=>store.put(v));
        }
        con.onerror =e=>_(e);
    });
}
DB.prototype.add = (...obj)=>{
    return new Promise((r,_)=>{
        this.storename||_('You have to use "table" before using this method.');
        var con = indexedDB.open(this.name);
        con.onsuccess = e=>{
            var db = e.target.result;
            var trans = db.transaction([this.storename], "readwrite");
            trans.oncomplete = e=>r(this);
            trans.onerror = e=>_(e);
            var store = trans.objectStore(this.storename);
            obj.forEach(v=>store.add(v));
        }
        con.onerror =e=>_(e);
    });
}
DB.prototype.key = (key, f=(v=>v))=>{
    return new Promise((r,_)=>{
        this.storename||_('You have to use "table" before using this method.');
        var con = indexedDB.open(this.name);
        con.onsuccess = e=>{
            var db = e.target.result;
            var trans = db.transaction([this.storename], "readwrite");
            var store = trans.objectStore(this.storename);
            var req = store.get(key);
            req.onsuccess = e=>{
                var data = e.target.result;
                var upd = store.put(f(data));
                upd.onsuccess = e=>r(this);
                upd.onerror = e=>_(e);
            }
            req.onerror = e=>_(e);
        }
        con.onerror =e=>_(e);
    });
}
DB.prototype.getAll = ()=>{
    return new Promise((r,_)=>{
        var trans = this.db.transaction([this.storename], "readonly");
        var store = trans.objectStore(this.storename);
        var request = store.openCursor();
        var values = [];
        request.onsuccess = e=>{
            var data = e.target.result;
            (data && (values.push(data.value), data.continue(), data)) || r(values);
        };
        request.onerror = e=>_(e);
    });
}
 
(async()=>{
    var db = new DB('testDB');
    await db.delete();
    var table = db.table('testTable')
    await table.create('id',
        {name: 'name'},
        {name: 'contact', path: ['contact.email', 'contact.tel']}
    );
    await db.add(
        {id: 1, name: 'John'},
        {id: 2, name: 'Doe'},
        {id: 3, name: 'Taro'}
    );
    console.log(await db.getAll())
})();
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License