Storing Node objects in NodeStore for single instance objects

This commit is contained in:
Magnus Åhall 2024-12-19 22:28:13 +01:00
parent d0150145ed
commit 41952df764
5 changed files with 187 additions and 68 deletions

View file

@ -9,10 +9,11 @@ export class NodeStore {
}
this.db = null
this.nodes = {}
}//}}}
async initializeDB() {//{{{
return new Promise((resolve, reject) => {
const req = indexedDB.open('notes', 5)
const req = indexedDB.open('notes', 7)
// Schema upgrades for IndexedDB.
// These can start from different points depending on updates to Notes2 since a device was online.
@ -20,6 +21,7 @@ export class NodeStore {
let nodes
let appState
let sendQueue
let nodesHistory
const db = event.target.result
const trx = event.target.transaction
@ -30,11 +32,11 @@ export class NodeStore {
switch (i) {
case 1:
nodes = db.createObjectStore('nodes', { keyPath: 'UUID' })
nodes.createIndex('nameIndex', 'Name', { unique: false })
nodes.createIndex('byName', 'Name', { unique: false })
break
case 2:
trx.objectStore('nodes').createIndex('parentIndex', 'ParentUUID', { unique: false })
trx.objectStore('nodes').createIndex('byParent', 'ParentUUID', { unique: false })
break
case 3:
@ -42,13 +44,21 @@ export class NodeStore {
break
case 4:
trx.objectStore('nodes').createIndex('modifiedIndex', 'modified', { unique: false })
trx.objectStore('nodes').createIndex('byModified', 'modified', { unique: false })
break
case 5:
sendQueue = db.createObjectStore('send_queue', { keyPath: ['UUID', 'Updated'] })
sendQueue.createIndex('updated', 'Updated', { unique: false })
break
case 6:
nodesHistory = db.createObjectStore('nodes_history', { keyPath: ['UUID', 'Updated'] })
break
case 7:
trx.objectStore('nodes_history').createIndex('byUUID', 'UUID', { unique: false })
break
}
}
}
@ -83,6 +93,7 @@ export class NodeStore {
UUID: ROOT_NODE,
Name: 'Notes2',
Content: 'Hello, World!',
Updated: new Date().toISOString(),
})
putRequest.onsuccess = (event) => {
resolve(event.target.result)
@ -102,6 +113,13 @@ export class NodeStore {
return this.setAppState('client_uuid', clientUUID)
}//}}}
node(uuid, dataIfUndefined, newLevel) {//{{{
let n = this.node[uuid]
if (n === undefined && dataIfUndefined !== undefined)
n = this.node[uuid] = new Node(dataIfUndefined, newLevel)
return n
}//}}}
async getAppState(key) {//{{{
return new Promise((resolve, reject) => {
const trx = this.db.transaction('app_state', 'readonly')
@ -180,6 +198,25 @@ export class NodeStore {
}
})
}//}}}
async copyToNodesHistory(nodeToCopy) {//{{{
return new Promise((resolve, reject) => {
const t = this.db.transaction('nodes_history', 'readwrite')
const nodesHistory = t.objectStore('nodes_history')
t.oncomplete = () => {
resolve()
}
t.onerror = (event) => {
console.log('transaction error', event.target.error)
reject(event.target.error)
}
const historyReq = nodesHistory.put(nodeToCopy.data)
historyReq.onerror = (event) => {
console.log(`Error copying ${nodeToCopy.UUID}`, event.target.error)
reject(event.target.error)
}
})
}//}}}
async storeNode(node) {//{{{
return new Promise((resolve, reject) => {
const t = this.db.transaction('nodes', 'readwrite')
@ -245,12 +282,13 @@ export class NodeStore {
return new Promise((resolve, reject) => {
const trx = this.db.transaction('nodes', 'readonly')
const nodeStore = trx.objectStore('nodes')
const index = nodeStore.index('parentIndex')
const index = nodeStore.index('byParent')
const req = index.getAll(parent)
req.onsuccess = (event) => {
const nodes = []
for (const i in event.target.result) {
const node = new Node(event.target.result[i], newLevel)
const nodeData = event.target.result[i]
const node = this.node(nodeData.UUID, nodeData, newLevel)
nodes.push(node)
}
@ -259,6 +297,7 @@ export class NodeStore {
req.onerror = (event) => reject(event.target.error)
})
}//}}}
async add(records) {//{{{
return new Promise((resolve, reject) => {
try {
@ -299,8 +338,6 @@ export class NodeStore {
}//}}}
async get(uuid) {//{{{
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(uuid)
@ -310,11 +347,41 @@ export class NodeStore {
reject("No such node")
return
}
const node = new Node(event.target.result, -1)
const node = this.node(uuid, event.target.result, -1)
resolve(node)
}
})
}//}}}
async getNodeAncestry(node, accumulated) {//{{{
console.log('blaha')
return new Promise((resolve, reject) => {
const nodeParentIndex = this.db
.transaction('nodes', 'readonly')
.objectStore('nodes')
if (node.ParentUUID === '') {
resolve(accumulated)
return
}
const getRequest = nodeParentIndex.get(node.ParentUUID)
getRequest.onsuccess = (event) => {
// Node not found in IndexedDB.
// Not expected to happen.
const parentNodeData = event.target.result
if (parentNodeData === undefined) {
reject("No such node")
return
}
const parentNode = this.node(parentNodeData.UUID, parentNodeData, -1)
this.getNodeAncestry(parentNode, accumulated.concat(parentNode))
.then(accumulated => resolve(accumulated))
}
})
}//}}}
async nodeCount() {//{{{
return new Promise((resolve, reject) => {
const t = this.db.transaction('nodes', 'readwrite')