import { API } from 'api' export class NodeStore { constructor() {//{{{ if (!('indexedDB' in window)) { throw 'Missing IndexedDB' } this.db = null }//}}} async initializeDB() {//{{{ return new Promise((resolve, reject) => { const req = indexedDB.open('notes', 2) // Schema upgrades for IndexedDB. // These can start from different points depending on updates to Notes2 since a device was online. req.onupgradeneeded = (event) => { let store const db = event.target.result const trx = event.target.transaction for (let i = event.oldVersion + 1; i <= event.newVersion; i++) { console.log(`Upgrade to schema ${i}`) // The schema transformations. switch (i) { case 1: store = db.createObjectStore('nodes', { keyPath: 'ID' }) store.createIndex('nameIndex', 'Name', { unique: false }) break case 2: trx.objectStore('nodes').createIndex('parentIndex', 'ParentID', { unique: false }) break } } } req.onsuccess = (event) => { this.db = event.target.result resolve() } req.onerror = (event) => { reject(event.target.error) } }) }//}}} async add(records) {//{{{ return new Promise((resolve, reject) => { try { const t = this.db.transaction('nodes', 'readwrite') const nodeStore = t.objectStore('nodes') t.onerror = (event) => { console.log('transaction error', event.target.error) reject(event.target.error) } t.oncomplete = () => { resolve() } for (const record in records) { const addReq = nodeStore.put(record) addReq.onsuccess = () => { console.log('OK!', record.ID, record.Name) } addReq.onerror = (event) => { console.log('Error!', event.target.error, record.ID) } } } catch (e) { console.log(e) } }) }//}}} async get(id) {//{{{ return new Promise((resolve, reject) => { // Node is always returned from IndexedDB if existing there. // Otherwise an attempt to get it from backend is executed. const trx = this.db.transaction('nodes', 'readonly') const nodeStore = trx.objectStore('nodes') const getRequest = nodeStore.get(id) getRequest.onsuccess = (event) => { // Node found in IndexedDB and returned. if (event.target.result !== undefined) { resolve(event.target.result) return } // Node not found and a request to the backend is made. API.query("POST", `/node/retrieve/${id}`, {}) .then(res => { const trx = this.db.transaction('nodes', 'readwrite') const nodeStore = trx.objectStore('nodes') const putRequest = nodeStore.put(res.Node) putRequest.onsuccess = () => resolve(res.Node) putRequest.onerror = (event) => { reject(event.target.error) } }) .catch(e => reject(e)) } }) }//}}} async getTreeNodes() {//{{{ return new Promise((resolve, reject) => { const trx = this.db.transaction('nodes', 'readonly') const nodeStore = trx.objectStore('nodes') const req = nodeStore.getAll() req.onsuccess = (event) => resolve(event.target.result) req.onerror = (event) => reject(event.target.error) }) }//}}} } // vim: foldmethod=marker