import { API } from 'api' import { Node } from 'node' export class Sync { constructor() { this.foo = '' } static async nodes() { let duration = 0 const syncStart = Date.now() try { // The latest sync node value is used to retrieve the changes // from the backend. const state = await nodeStore.getAppState('latest_sync_node') const clientUUID = await nodeStore.getAppState('client_uuid') const oldMax = (state?.value ? state.value : 0) let currMax = oldMax let offset = 0 let res = { Continue: false } let batch = 0 do { batch++ res = await API.query('POST', `/sync/node/${oldMax}/${offset}`, { ClientUUID: clientUUID.value }) if (res.Nodes.length > 0) console.log(`Node sync batch #${batch}`) offset += res.Nodes.length currMax = Math.max(currMax, res.MaxSeq) /* Go through each node and determine if they are older than * the node in IndexedDB. If they are, they are just history * and can be ignored since history is currently not stored * in the browser. * * If the backed node is newer, the local node is stored in * a separate table in IndexedDB to at a later stage in the * sync be preserved in the backend. */ let backendNode = null for (const i in res.Nodes) { backendNode = new Node(res.Nodes[i], -1) await Sync.handleNode(backendNode) } } while (res.Continue) nodeStore.setAppState('latest_sync_node', currMax) } catch (e) { console.log('sync node tree', e) } finally { const syncEnd = Date.now() duration = (syncEnd - syncStart) / 1000 const count = await nodeStore.nodeCount() console.log(`Node sync took ${duration}s`, count) } return duration } static async handleNode(backendNode) { try { /* Retrieving the local copy of this node from IndexedDB. * The backend node can be discarded if it is older than * the local copy since it is considered history preserved * in the backend. */ return nodeStore.get(backendNode.UUID) .then(async localNode => { if (localNode.updated() >= backendNode.updated()) { console.log(`History from backend: ${backendNode.UUID}`) return } // local node is older than the backend node // and moved into the send_queue table for later sync to backend. return nodeStore.moveToSendQueue(localNode, backendNode) }) .catch(async e => { // Not found in IndexedDB - OK to just insert since it only exists in backend. return nodeStore.add([backendNode]) }) } catch (e) { console.error(e) } } }